From 0691e7c3e63931a4580ac9196a1f5d5b12bf497d Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Tue, 1 Nov 2022 16:11:28 +0300 Subject: [PATCH 01/68] GO-469: add database import Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/converter/error.go | 2 +- core/block/import/importer.go | 4 +- core/block/import/importer_test.go | 14 +- core/block/import/markdown/import.go | 6 +- core/block/import/notion/api/block/blocks.go | 10 + core/block/import/notion/api/client/client.go | 44 + core/block/import/notion/api/client/error.go | 27 + core/block/import/notion/api/commonobjects.go | 107 + .../import/notion/api/database/database.go | 203 ++ .../notion/api/database/database_test.go | 52 + core/block/import/notion/converter.go | 51 + core/block/import/pb/converter.go | 4 +- core/block/import/pb/converter_test.go | 10 +- core/block/import/types.go | 1 + pb/commands.pb.go | 1765 ++++++++++------- pb/protos/commands.proto | 17 +- 16 files changed, 1540 insertions(+), 777 deletions(-) create mode 100644 core/block/import/notion/api/block/blocks.go create mode 100644 core/block/import/notion/api/client/client.go create mode 100644 core/block/import/notion/api/client/error.go create mode 100644 core/block/import/notion/api/commonobjects.go create mode 100644 core/block/import/notion/api/database/database.go create mode 100644 core/block/import/notion/api/database/database_test.go create mode 100644 core/block/import/notion/converter.go diff --git a/core/block/import/converter/error.go b/core/block/import/converter/error.go index 5c172e79e..dd07280d9 100644 --- a/core/block/import/converter/error.go +++ b/core/block/import/converter/error.go @@ -26,7 +26,7 @@ func (ce ConvertError) IsEmpty() bool { } func (ce ConvertError) Error() error { - var pattern = "file: %s, error: %s" + "\n" + var pattern = "source: %s, error: %s" + "\n" var errorString bytes.Buffer if ce.IsEmpty() { return nil diff --git a/core/block/import/importer.go b/core/block/import/importer.go index d7619c4a6..ee52cba8d 100644 --- a/core/block/import/importer.go +++ b/core/block/import/importer.go @@ -66,7 +66,7 @@ func (i *Import) Import(ctx *session.Context, req *pb.RpcObjectImportRequest) er return allErrors.Error() } } - if res.Snapshots == nil { + if len(res.Snapshots) == 0 { return fmt.Errorf("empty response from converter") } progress.SetProgressMessage("create blocks") @@ -91,7 +91,7 @@ func (i *Import) Import(ctx *session.Context, req *pb.RpcObjectImportRequest) er } return fmt.Errorf("snapshots are empty") } - return nil + return fmt.Errorf("unknown import type %s", req.Type) } func (s *Import) Name() string { diff --git a/core/block/import/importer_test.go b/core/block/import/importer_test.go index 4428bf0dc..fd395eddd 100644 --- a/core/block/import/importer_test.go +++ b/core/block/import/importer_test.go @@ -42,7 +42,7 @@ func Test_ImportSuccess(t *testing.T) { i.oc = creator err := i.Import(session.NewContext(), &pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfNotionParams{NotionParams: &pb.RpcObjectImportRequestNotionParams{Path: "bafybbbbruo3kqubijrbhr24zonagbz3ksxbrutwjjoczf37axdsusu4a.pb"}}, + Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "bafybbbbruo3kqubijrbhr24zonagbz3ksxbrutwjjoczf37axdsusu4a.pb"}}, UpdateExistingObjects: false, Type: 0, Mode: 0, @@ -67,7 +67,7 @@ func Test_ImportErrorFromConverter(t *testing.T) { i.oc = creator err := i.Import(session.NewContext(), &pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfNotionParams{NotionParams: &pb.RpcObjectImportRequestNotionParams{Path: "test"}}, + Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "test"}}, UpdateExistingObjects: false, Type: 0, Mode: 0, @@ -103,7 +103,7 @@ func Test_ImportErrorFromObjectCreator(t *testing.T) { i.oc = creator res := i.Import(session.NewContext(), &pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfNotionParams{NotionParams: &pb.RpcObjectImportRequestNotionParams{Path: "test"}}, + Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "test"}}, UpdateExistingObjects: false, Type: 0, Mode: 0, @@ -141,7 +141,7 @@ func Test_ImportIgnoreErrorMode(t *testing.T) { i.oc = creator res := i.Import(session.NewContext(), &pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfNotionParams{NotionParams: &pb.RpcObjectImportRequestNotionParams{Path: "test"}}, + Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "test"}}, UpdateExistingObjects: false, Type: 0, Mode: 1, @@ -179,7 +179,7 @@ func Test_ImportIgnoreErrorModeWithTwoErrorsPerFile(t *testing.T) { i.oc = creator res := i.Import(session.NewContext(), &pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfNotionParams{NotionParams: &pb.RpcObjectImportRequestNotionParams{Path: "test"}}, + Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "test"}}, UpdateExistingObjects: false, Type: 0, Mode: 1, @@ -226,7 +226,7 @@ func Test_ImportExternalPlugin(t *testing.T) { Params: nil, Snapshots: snapshots, UpdateExistingObjects: false, - Type: 1, + Type: 2, Mode: 2, }) assert.Nil(t, res) @@ -246,7 +246,7 @@ func Test_ImportExternalPluginError(t *testing.T) { Params: nil, Snapshots: nil, UpdateExistingObjects: false, - Type: 1, + Type: 2, Mode: 2, }) assert.NotNil(t, res) diff --git a/core/block/import/markdown/import.go b/core/block/import/markdown/import.go index e3bb48cbd..7685d70e6 100644 --- a/core/block/import/markdown/import.go +++ b/core/block/import/markdown/import.go @@ -42,7 +42,7 @@ type Markdown struct { blockConverter MarkdownToBlocksConverter } -const Name = "Notion" +const Name = "Markdown" func New(s core.Service) converter.Converter { return &Markdown{blockConverter: NewMarkdownToBlocks(s)} @@ -53,8 +53,8 @@ func (m *Markdown) Name() string { } func (m *Markdown) GetParams(params pb.IsRpcObjectImportRequestParams) (string, error) { - if p, ok := params.(*pb.RpcObjectImportRequestParamsOfNotionParams); ok { - return p.NotionParams.GetPath(), nil + if p, ok := params.(*pb.RpcObjectImportRequestParamsOfMarkdownParams); ok { + return p.MarkdownParams.GetPath(), nil } return "", errors.Wrap(errors.New("wrong parameters format"), "Markdown: GetParams") } diff --git a/core/block/import/notion/api/block/blocks.go b/core/block/import/notion/api/block/blocks.go new file mode 100644 index 000000000..ace67f4a1 --- /dev/null +++ b/core/block/import/notion/api/block/blocks.go @@ -0,0 +1,10 @@ +package block + +import "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + +type Image struct { + Caption []api.RichText `json:"caption,omitempty"` + Type api.FileType `json:"type"` + File *api.FileObject `json:"file,omitempty"` + External *api.FileObject `json:"external,omitempty"` +} \ No newline at end of file diff --git a/core/block/import/notion/api/client/client.go b/core/block/import/notion/api/client/client.go new file mode 100644 index 000000000..d0665161b --- /dev/null +++ b/core/block/import/notion/api/client/client.go @@ -0,0 +1,44 @@ +package client + +import ( + "bytes" + "context" + "fmt" + "net/http" + "time" +) + +const ( + notionUrl = "https://api.notion.com/v1" + apiVersion = "2022-06-28" +) + +type Client struct { + HttpClient *http.Client + BasePath string +} + +func NewClient() *Client { + c := &Client{ + HttpClient:&http.Client{Timeout: time.Minute}, + BasePath: notionUrl, + } + return c +} + +func (c *Client) PrepareRequest(ctx context.Context, apiKey, method, url string, body *bytes.Buffer) (*http.Request, error) { + resultUrl := c.BasePath + url + req, err := http.NewRequestWithContext(ctx, method, resultUrl, body) + if err != nil { + return nil, err + } + + req.Header.Set("Authorization", fmt.Sprintf("Bearer %v", apiKey)) + req.Header.Set("Notion-Version", apiVersion) + + if body != nil { + req.Header.Set("Content-Type", "application/json") + } + + return req, nil +} diff --git a/core/block/import/notion/api/client/error.go b/core/block/import/notion/api/client/error.go new file mode 100644 index 000000000..2ccaf34a0 --- /dev/null +++ b/core/block/import/notion/api/client/error.go @@ -0,0 +1,27 @@ +package client + +import ( + "encoding/json" + "fmt" + + "github.com/anytypeio/go-anytype-middleware/pkg/lib/logging" +) + +type NotionErrorResponse struct { + Status int `json:"status,omitempty"` + Code string `json:"code,omitempty"` + Message string `json:"message,omitempty"` +} + +func (ne *NotionErrorResponse) Error() error { + return fmt.Errorf("status: %d, code: %s, message: %s", ne.Status, ne.Code, ne.Message) +} + +func TransformHttpCodeToError(response []byte) *NotionErrorResponse { + var notionErr = NotionErrorResponse{} + if err := json.Unmarshal(response, ¬ionErr); err != nil { + logging.Logger("client").Error("failed to parse error response from notion %s", err) + return nil + } + return ¬ionErr +} diff --git a/core/block/import/notion/api/commonobjects.go b/core/block/import/notion/api/commonobjects.go new file mode 100644 index 000000000..885c45d16 --- /dev/null +++ b/core/block/import/notion/api/commonobjects.go @@ -0,0 +1,107 @@ +package api + +import ( + "bytes" + "time" +) + +type richTextType string + +const ( + Text richTextType = "text" + Mention richTextType = "mention" + Equation richTextType = "equation" +) + +type RichText struct { + Type richTextType `json:"type,omitempty"` + Text *TextObject `json:"text,omitempty"` + Annotations *Annotations `json:"annotations,omitempty"` + PlainText string `json:"plain_text,omitempty"` + Href string `json:"href,omitempty"` +} + +type TextObject struct { + Content string `json:"content"` + Link *Link `json:"link,omitempty"` +} + +type Link struct { + Url string `json:"url,omitempty"` +} + +type Color string + +const ( + DefaultColor Color = "default" + Gray Color = "gray" + Brown Color = "brown" + Orange Color = "orange" + Yellow Color = "yellow" + Green Color = "green" + Blue Color = "blue" + Purple Color = "purple" + Pink Color = "pink" + Red Color = "red" +) + +type Annotations struct { + Bold bool `json:"bold"` + Italic bool `json:"italic"` + Strikethrough bool `json:"strikethrough"` + Underline bool `json:"underline"` + Code bool `json:"code"` + Color string `json:"color"` +} + +type FileType string + +const ( + External FileType = "external" + File FileType = "file" +) + +type FileObject struct { + Name string `json:"name"` + Type FileType `json:"type"` + File *FileProperty `json:"file,omitempty"` + External *FileProperty `json:"external,omitempty"` +} + +type FileProperty struct { + URL string `json:"url,omitempty"` + ExpiryTime *time.Time `json:"expiry_time,omitempty"` +} + +type Icon struct { + Type FileType `json:"type"` + Emoji *string `json:"emoji,omitempty"` + File *FileObject `json:"file,omitempty"` + External *FileObject `json:"external,omitempty"` +} + +type userType string + +type User struct { + Object string `json:"object,omitempty"` + ID string `json:"id"` + Type userType `json:"type,omitempty"` + Name string `json:"name,omitempty"` + AvatarURL string `json:"avatar_url,omitempty"` + Person *Person `json:"person,omitempty"` + Bot *struct{} `json:"bot,omitempty"` +} + +type Person struct { + Email string `json:"email"` +} + +func RichTextToDescription(rt []RichText) string { + var description bytes.Buffer + + for _, text := range rt { + description.WriteString(text.PlainText) + description.WriteRune('\n') + } + return description.String() +} diff --git a/core/block/import/notion/api/database/database.go b/core/block/import/notion/api/database/database.go new file mode 100644 index 000000000..a690b2d63 --- /dev/null +++ b/core/block/import/notion/api/database/database.go @@ -0,0 +1,203 @@ +package database + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "time" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/block" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" + "github.com/anytypeio/go-anytype-middleware/pb" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/threads" + "github.com/anytypeio/go-anytype-middleware/util/pbtypes" + "github.com/gogo/protobuf/types" + "github.com/textileio/go-threads/core/thread" +) + +type DatabaseID string + +const ( + endpoint = "/search" + pageSize = 100 + objectType = "database" +) + +type DatabaseService struct { + client *client.Client +} + +func New() *DatabaseService { + return &DatabaseService{ + client: client.NewClient(), + } +} + +type Database struct { + Object string `json:"object"` + ID string `json:"id"` + CreatedTime time.Time `json:"created_time"` + LastEditedTime time.Time `json:"last_edited_time"` + CreatedBy api.User `json:"created_by,omitempty"` + LastEditedBy api.User `json:"last_edited_by,omitempty"` + Title []api.RichText `json:"title"` + Parent Parent `json:"parent"` + URL string `json:"url"` + Properties interface{} `json:"properties"` // can't support it for databases yet + Description []api.RichText `json:"description"` + IsInline bool `json:"is_inline"` + Archived bool `json:"archived"` + Icon *api.Icon `json:"icon,omitempty"` + Cover *block.Image `json:"cover,omitempty"` +} + +type Parent struct { + Type string `json:"type,omitempty"` + PageID string `json:"page_id"` +} + +type ListDatabasesResponse struct { + Results []Database `json:"results"` + HasMore bool `json:"has_more"` + NextCursor *string `json:"next_cursor"` +} + +func (ds *DatabaseService) GetDatabase(ctx context.Context, mode pb.RpcObjectImportRequestMode, apiKey string) *converter.Response { + var convereterError = converter.ConvertError{} + databases, notionErr, err := ds.listDatabases(ctx, apiKey, pageSize) + if err != nil { + convereterError.Add(endpoint, err) + return &converter.Response{Error: convereterError} + } + if notionErr != nil { + convereterError.Add(endpoint, notionErr.Error()) + return &converter.Response{Error: convereterError} + } + return ds.mapDatabasesToSnaphots(ctx, mode, databases, convereterError) +} + +func (ds *DatabaseService) listDatabases(ctx context.Context, apiKey string, pageSize int64) ([]Database, *client.NotionErrorResponse, error) { + var ( + hasMore = true + body = &bytes.Buffer{} + resultDatabases = make([]Database, 0) + startCursor int64 + ) + type Option struct { + PageSize int64 `json:"page_size,omitempty"` + StartCursor int64 `json:"start_cursor,omitempty"` + } + err := json.NewEncoder(body).Encode(&Option{PageSize: pageSize, StartCursor: startCursor}) + + if err != nil { + return nil, nil, fmt.Errorf("ListDatabases: %s", err) + } + + req, err := ds.client.PrepareRequest(ctx, apiKey, http.MethodPost, endpoint, body) + if err != nil { + return nil, nil, fmt.Errorf("ListDatabases: %s", err) + } + + for hasMore { + res, err := ds.client.HttpClient.Do(req) + if err != nil { + return nil, nil, fmt.Errorf("ListDatabases: %s", err) + } + defer res.Body.Close() + + b, err := ioutil.ReadAll(res.Body) + + if err != nil { + return nil, nil, err + } + var databases ListDatabasesResponse + if res.StatusCode != http.StatusOK { + notionErr := client.TransformHttpCodeToError(b) + if notionErr == nil { + return nil, nil, fmt.Errorf("failed http request, %d code", res.StatusCode) + } + return nil, notionErr, nil + } + + err = json.Unmarshal(b, &databases) + + if err != nil { + return nil, nil, err + } + + for _, d := range databases.Results { + if d.Object == objectType { + resultDatabases = append(resultDatabases, d) + } + } + + if !databases.HasMore { + hasMore = false + continue + } + + startCursor += pageSize + + } + return resultDatabases, nil, nil +} + +func (ds *DatabaseService) mapDatabasesToSnaphots(ctx context.Context, mode pb.RpcObjectImportRequestMode, databases []Database, convereterError converter.ConvertError) *converter.Response { + var allSnapshots = make([]*converter.Snapshot, 0) + for _, d := range databases { + tid, err := threads.ThreadCreateID(thread.AccessControlled, smartblock.SmartBlockTypePage) + if err != nil { + convereterError.Add(d.ID, err) + if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + return &converter.Response{Error: convereterError} + } else { + continue + } + } + snapshot := ds.transformDatabase(d) + + allSnapshots = append(allSnapshots, &converter.Snapshot{ + Id: tid.String(), + FileName: d.URL, + Snapshot: snapshot, + }) + } + if convereterError.IsEmpty() { + return &converter.Response{Snapshots: allSnapshots, Error: nil} + } + return &converter.Response{Snapshots: allSnapshots, Error: convereterError} +} + +func (ds *DatabaseService) transformDatabase(d Database) *model.SmartBlockSnapshotBase { + details := make(map[string]*types.Value, 0) + details[bundle.RelationKeySource.String()] = pbtypes.String(d.URL) + if len(d.Title) > 0{ + details[bundle.RelationKeyName.String()] = pbtypes.String(d.Title[0].PlainText) + } + if d.Icon != nil && d.Icon.Emoji != nil { + details[bundle.RelationKeyIconEmoji.String()] = pbtypes.String(*d.Icon.Emoji) + } + details[bundle.RelationKeyCreatedDate.String()] = pbtypes.String(d.CreatedTime.String()) + details[bundle.RelationKeyCreator.String()] = pbtypes.String(d.CreatedBy.Name) + details[bundle.RelationKeyIsArchived.String()] = pbtypes.Bool(d.Archived) + details[bundle.RelationKeyLastModifiedDate.String()] = pbtypes.String(d.LastEditedTime.String()) + details[bundle.RelationKeyLastModifiedBy.String()] = pbtypes.String(d.LastEditedBy.Name) + details[bundle.RelationKeyDescription.String()] = pbtypes.String(api.RichTextToDescription(d.Description)) + + snapshot := &model.SmartBlockSnapshotBase{ + Blocks: []*model.Block{}, + Details: &types.Struct{Fields: details}, + ObjectTypes: []string{bundle.TypeKeyPage.URL()}, + Collections: nil, + } + + return snapshot +} diff --git a/core/block/import/notion/api/database/database_test.go b/core/block/import/notion/api/database/database_test.go new file mode 100644 index 000000000..0c255e3e6 --- /dev/null +++ b/core/block/import/notion/api/database/database_test.go @@ -0,0 +1,52 @@ +package database + +import ( + "context" + "net/http" + "net/http/httptest" + "testing" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" + "github.com/anytypeio/go-anytype-middleware/pb" + "github.com/stretchr/testify/assert" +) + + + +func Test_GetDatabaseSuccess(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"object":"list","results":[{"object":"database","id":"072a11cb-684f-4f2b-9490-79592700c67e","cover":{"type":"external","external":{"url":"https://www.notion.so/images/page-cover/webb1.jpg"}},"icon":{"type":"emoji","emoji":"👜"},"created_time":"2022-10-25T11:44:00.000Z","created_by":{"object":"user","id":"60faafc6-0c5c-4479-a3f7-67d77cd8a56d"},"last_edited_by":{"object":"user","id":"60faafc6-0c5c-4479-a3f7-67d77cd8a56d"},"last_edited_time":"2022-10-31T10:16:00.000Z","title":[{"type":"text","text":{"content":"fsdfsdf","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"fsdfsdf","href":null}],"description":[{"type":"text","text":{"content":"lkjlkjlkjklj","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":true,"code":false,"color":"default"},"plain_text":"lkjlkjlkjklj","href":null},{"type":"text","text":{"content":" lkhlkjl;lk’ ","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":" lkhlkjl;lk’ ","href":null},{"type":"text","text":{"content":"lkjkn ;oj;lj;lk’;l\\\n","link":null},"annotations":{"bold":true,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"lkjkn ;oj;lj;lk’;l\\\n","href":null},{"type":"text","text":{"content":"nb","link":{"url":"/43b4db4f23b846f99909c783b033fb7d"}},"annotations":{"bold":true,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"nb","href":"/43b4db4f23b846f99909c783b033fb7d"},{"type":"text","text":{"content":". \n","link":null},"annotations":{"bold":true,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":". \n","href":null},{"type":"equation","equation":{"expression":"m;lm;’,"},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"m;lm;’,","href":null}],"is_inline":true,"properties":{"Select":{"id":"C%5E%7DO","name":"Select","type":"select","select":{"options":[{"id":"f56c757b-eb58-4a15-b528-055a0e3e85b4","name":"dddd","color":"red"}]}},"Text":{"id":"LwEA","name":"Text","type":"relation","relation":{"database_id":"48f51ca6-f1e3-40ee-97a5-953c2e5d8dda","type":"single_property","single_property":{}}},"ssss":{"id":"MeQJ","name":"ssss","type":"last_edited_time","last_edited_time":{}},"Date":{"id":"VwL%5B","name":"Date","type":"date","date":{}},"Status":{"id":"VwSP","name":"Status","type":"status","status":{"options":[{"id":"d553e1cf-a835-4608-9740-01335bc43a33","name":"Not started","color":"default"},{"id":"e4927bd2-4580-4e37-9095-eb0af45923bc","name":"In progress","color":"blue"},{"id":"631ae48b-ccbd-47fc-83a0-64388237cb90","name":"Done","color":"green"}],"groups":[{"id":"95be5bb3-f557-4e5f-bf80-bc0ba078a5ad","name":"To-do","color":"gray","option_ids":["d553e1cf-a835-4608-9740-01335bc43a33"]},{"id":"c3e8b669-177f-4f6a-a58b-998020b47992","name":"In progress","color":"blue","option_ids":["e4927bd2-4580-4e37-9095-eb0af45923bc"]},{"id":"fdbcab62-2699-49b6-9002-eb10a89806ad","name":"Complete","color":"green","option_ids":["631ae48b-ccbd-47fc-83a0-64388237cb90"]}]}},"Number":{"id":"WxBc","name":"Number","type":"number","number":{"format":"ruble"}},"Last edited time":{"id":"XDl%3D","name":"Last edited time","type":"last_edited_time","last_edited_time":{}},"ww":{"id":"Y%3B%3Bz","name":"ww","type":"rich_text","rich_text":{}},"Multi-select":{"id":"%5D%60%3FX","name":"Multi-select","type":"multi_select","multi_select":{"options":[{"id":"EgfK","name":"ddd","color":"default"},{"id":"QO[c","name":"AAA","color":"purple"},{"id":"UsL>","name":"Option","color":"orange"}]}},"ww (1)":{"id":"%60%3C%3DZ","name":"ww (1)","type":"checkbox","checkbox":{}},"Email":{"id":"bQRa","name":"Email","type":"email","email":{}},"Tags":{"id":"gOGx","name":"Tags","type":"multi_select","multi_select":{"options":[{"id":"21e940af-b7a0-4aae-985b-d3bb38a6ebeb","name":"JJJJ","color":"pink"}]}},"Test test":{"id":"nWZg","name":"Test test","type":"people","people":{}},"Checkbox":{"id":"qVHX","name":"Checkbox","type":"checkbox","checkbox":{}},"Status 1":{"id":"tlUB","name":"Status 1","type":"status","status":{"options":[{"id":"bc2cb10d-92da-40d1-b043-d3c5b52c789e","name":"Not started","color":"default"},{"id":"648b1e10-c0ac-4886-84e0-42d501d36e45","name":"In progress","color":"blue"},{"id":"6f1e3ce8-97db-40b5-8538-13269de69b7f","name":"Done","color":"green"}],"groups":[{"id":"cd0c5f4a-de4d-4662-a2ee-1c78fc0385cd","name":"To-do","color":"gray","option_ids":["bc2cb10d-92da-40d1-b043-d3c5b52c789e"]},{"id":"a341ea69-3102-4d56-b74a-fa3f1c47fa85","name":"In progress","color":"blue","option_ids":["648b1e10-c0ac-4886-84e0-42d501d36e45"]},{"id":"061c2c1f-faa2-49be-996e-f52d74a5b86e","name":"Complete","color":"green","option_ids":["6f1e3ce8-97db-40b5-8538-13269de69b7f"]}]}},"Formula":{"id":"%7Do%40%7B","name":"Formula","type":"formula","formula":{"expression":"log2(prop(\"Number\"))"}},"Name":{"id":"title","name":"Name","type":"title","title":{}}},"parent":{"type":"page_id","page_id":"d6917e78-3212-444d-ae46-97499c021f2d"},"url":"https://www.notion.so/072a11cb684f4f2b949079592700c67e","archived":false}],"next_cursor":null,"has_more":false,"type":"page_or_database","page_or_database":{}}`)) + })) + + defer s.Close() + c := client.NewClient() + c.BasePath = s.URL + ds := New() + ds.client = c + + databases := ds.GetDatabase(context.Background(), pb.RpcObjectImportRequest_ALL_OR_NOTHING, "key") + + assert.NotNil(t, databases) + assert.Len(t, databases.Snapshots, 1) + assert.Nil(t, databases.Error) +} + +func Test_GetDatabaseFailedRequest(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(`{"object":"error","status":400,"code":"validation_error","message":"path failed validation: path.database_id should be a valid uuid"}`)) + })) + defer s.Close() + + c := client.NewClient() + c.BasePath = s.URL + ds := New() + ds.client = c + + databases := ds.GetDatabase(context.Background(), pb.RpcObjectImportRequest_ALL_OR_NOTHING, "key") + + assert.NotNil(t, databases) + assert.Nil(t, databases.Snapshots) + assert.NotNil(t, databases.Error) + assert.Contains(t, databases.Error.Error().Error(), "path failed validation: path.database_id should be a valid uuid") +} \ No newline at end of file diff --git a/core/block/import/notion/converter.go b/core/block/import/notion/converter.go new file mode 100644 index 000000000..dc717b754 --- /dev/null +++ b/core/block/import/notion/converter.go @@ -0,0 +1,51 @@ +package notion + +import ( + "context" + "fmt" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/database" + "github.com/anytypeio/go-anytype-middleware/pb" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/core" +) + +const name = "Notion" + +func init() { + converter.RegisterFunc(New) +} + +type Notion struct { + database *database.DatabaseService +} + +func New(core.Service) converter.Converter { + return &Notion{ + database: database.New(), + } +} + +func (n *Notion) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Response { + ce := converter.NewError() + apiKey := n.getParams(req.Params) + if apiKey == "" { + ce.Add("apiKey", fmt.Errorf("failed to extract apikey")) + return &converter.Response{ + Error: ce, + } + } + return n.database.GetDatabase(context.TODO(), req.Mode, apiKey) +} + +func (n *Notion) getParams(param pb.IsRpcObjectImportRequestParams) string { + if p, ok := param.(*pb.RpcObjectImportRequestParamsOfNotionParams); ok { + return p.NotionParams.GetApiKey() + } + return "" +} + +func (n *Notion) Name() string { + return name +} + diff --git a/core/block/import/pb/converter.go b/core/block/import/pb/converter.go index d7309d817..d37b5bd54 100644 --- a/core/block/import/pb/converter.go +++ b/core/block/import/pb/converter.go @@ -107,8 +107,8 @@ func (p *Pb) GetImage() ([]byte, int64, int64, error) { } func (p *Pb) GetParams(params pb.IsRpcObjectImportRequestParams) (string, error) { - if p, ok := params.(*pb.RpcObjectImportRequestParamsOfNotionParams); ok { - return p.NotionParams.GetPath(), nil + if p, ok := params.(*pb.RpcObjectImportRequestParamsOfMarkdownParams); ok { + return p.MarkdownParams.GetPath(), nil } return "", errors.New("PB: GetParams wrong parameters format") } diff --git a/core/block/import/pb/converter_test.go b/core/block/import/pb/converter_test.go index d2e7e5564..e68dd2702 100644 --- a/core/block/import/pb/converter_test.go +++ b/core/block/import/pb/converter_test.go @@ -33,7 +33,7 @@ func Test_GetSnapshotsSuccess(t *testing.T) { p := &Pb{} res := p.GetSnapshots(&pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfNotionParams{NotionParams: &pb.RpcObjectImportRequestNotionParams{Path: wr.Path()}}, + Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: wr.Path()}}, UpdateExistingObjects: false, Type: 0, Mode: 0, @@ -59,7 +59,7 @@ func Test_GetSnapshotsFailedReadZip(t *testing.T) { p := &Pb{} res := p.GetSnapshots(&pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfNotionParams{NotionParams: &pb.RpcObjectImportRequestNotionParams{Path: "not exists"}}, + Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "not exists"}}, UpdateExistingObjects: false, Type: 0, Mode: 0, @@ -84,7 +84,7 @@ func Test_GetSnapshotsFailedToGetSnapshot(t *testing.T) { p := &Pb{} res := p.GetSnapshots(&pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfNotionParams{NotionParams: &pb.RpcObjectImportRequestNotionParams{Path: "notexist.zip"}}, + Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "notexist.zip"}}, UpdateExistingObjects: false, Type: 0, Mode: 0, @@ -118,7 +118,7 @@ func Test_GetSnapshotsFailedToGetSnapshotForTwoFiles(t *testing.T) { // ALL_OR_NOTHING mode res := p.GetSnapshots(&pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfNotionParams{NotionParams: &pb.RpcObjectImportRequestNotionParams{Path: wr.Path()}}, + Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: wr.Path()}}, UpdateExistingObjects: false, Type: 0, Mode: 0, @@ -130,7 +130,7 @@ func Test_GetSnapshotsFailedToGetSnapshotForTwoFiles(t *testing.T) { // IGNORE_ERRORS mode res = p.GetSnapshots(&pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfNotionParams{NotionParams: &pb.RpcObjectImportRequestNotionParams{Path: wr.Path()}}, + Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: wr.Path()}}, UpdateExistingObjects: false, Type: 0, Mode: 1, diff --git a/core/block/import/types.go b/core/block/import/types.go index 76b092bef..7ddf6d799 100644 --- a/core/block/import/types.go +++ b/core/block/import/types.go @@ -3,6 +3,7 @@ package importer import ( "github.com/anytypeio/go-anytype-middleware/app" _ "github.com/anytypeio/go-anytype-middleware/core/block/import/markdown" + _ "github.com/anytypeio/go-anytype-middleware/core/block/import/notion" _ "github.com/anytypeio/go-anytype-middleware/core/block/import/pb" "github.com/anytypeio/go-anytype-middleware/core/session" "github.com/anytypeio/go-anytype-middleware/pb" diff --git a/pb/commands.pb.go b/pb/commands.pb.go index ffe3fc877..406775021 100644 --- a/pb/commands.pb.go +++ b/pb/commands.pb.go @@ -2070,17 +2070,20 @@ type RpcObjectImportRequestType int32 const ( RpcObjectImportRequest_Notion RpcObjectImportRequestType = 0 - RpcObjectImportRequest_External RpcObjectImportRequestType = 1 + RpcObjectImportRequest_Markdown RpcObjectImportRequestType = 1 + RpcObjectImportRequest_External RpcObjectImportRequestType = 2 ) var RpcObjectImportRequestType_name = map[int32]string{ 0: "Notion", - 1: "External", + 1: "Markdown", + 2: "External", } var RpcObjectImportRequestType_value = map[string]int32{ "Notion": 0, - "External": 1, + "Markdown": 1, + "External": 2, } func (x RpcObjectImportRequestType) String() string { @@ -2156,15 +2159,18 @@ func (RpcObjectImportListResponseErrorCode) EnumDescriptor() ([]byte, []int) { type RpcObjectImportListImportResponseType int32 const ( - RpcObjectImportListImportResponse_Notion RpcObjectImportListImportResponseType = 0 + RpcObjectImportListImportResponse_Notion RpcObjectImportListImportResponseType = 0 + RpcObjectImportListImportResponse_Markdown RpcObjectImportListImportResponseType = 1 ) var RpcObjectImportListImportResponseType_name = map[int32]string{ 0: "Notion", + 1: "Markdown", } var RpcObjectImportListImportResponseType_value = map[string]int32{ - "Notion": 0, + "Notion": 0, + "Markdown": 1, } func (x RpcObjectImportListImportResponseType) String() string { @@ -17552,11 +17558,12 @@ type RpcObjectImportRequest struct { // Types that are valid to be assigned to Params: // *RpcObjectImportRequestParamsOfNotionParams // *RpcObjectImportRequestParamsOfBookmarksParams + // *RpcObjectImportRequestParamsOfMarkdownParams Params IsRpcObjectImportRequestParams `protobuf_oneof:"params"` - Snapshots []*RpcObjectImportRequestSnapshot `protobuf:"bytes,3,rep,name=snapshots,proto3" json:"snapshots,omitempty"` - UpdateExistingObjects bool `protobuf:"varint,4,opt,name=updateExistingObjects,proto3" json:"updateExistingObjects,omitempty"` - Type RpcObjectImportRequestType `protobuf:"varint,5,opt,name=type,proto3,enum=anytype.RpcObjectImportRequestType" json:"type,omitempty"` - Mode RpcObjectImportRequestMode `protobuf:"varint,6,opt,name=mode,proto3,enum=anytype.RpcObjectImportRequestMode" json:"mode,omitempty"` + Snapshots []*RpcObjectImportRequestSnapshot `protobuf:"bytes,4,rep,name=snapshots,proto3" json:"snapshots,omitempty"` + UpdateExistingObjects bool `protobuf:"varint,5,opt,name=updateExistingObjects,proto3" json:"updateExistingObjects,omitempty"` + Type RpcObjectImportRequestType `protobuf:"varint,6,opt,name=type,proto3,enum=anytype.RpcObjectImportRequestType" json:"type,omitempty"` + Mode RpcObjectImportRequestMode `protobuf:"varint,7,opt,name=mode,proto3,enum=anytype.RpcObjectImportRequestMode" json:"mode,omitempty"` } func (m *RpcObjectImportRequest) Reset() { *m = RpcObjectImportRequest{} } @@ -17604,9 +17611,13 @@ type RpcObjectImportRequestParamsOfNotionParams struct { type RpcObjectImportRequestParamsOfBookmarksParams struct { BookmarksParams *RpcObjectImportRequestBookmarksParams `protobuf:"bytes,2,opt,name=bookmarksParams,proto3,oneof" json:"bookmarksParams,omitempty"` } +type RpcObjectImportRequestParamsOfMarkdownParams struct { + MarkdownParams *RpcObjectImportRequestMarkdownParams `protobuf:"bytes,3,opt,name=markdownParams,proto3,oneof" json:"markdownParams,omitempty"` +} func (*RpcObjectImportRequestParamsOfNotionParams) IsRpcObjectImportRequestParams() {} func (*RpcObjectImportRequestParamsOfBookmarksParams) IsRpcObjectImportRequestParams() {} +func (*RpcObjectImportRequestParamsOfMarkdownParams) IsRpcObjectImportRequestParams() {} func (m *RpcObjectImportRequest) GetParams() IsRpcObjectImportRequestParams { if m != nil { @@ -17629,6 +17640,13 @@ func (m *RpcObjectImportRequest) GetBookmarksParams() *RpcObjectImportRequestBoo return nil } +func (m *RpcObjectImportRequest) GetMarkdownParams() *RpcObjectImportRequestMarkdownParams { + if x, ok := m.GetParams().(*RpcObjectImportRequestParamsOfMarkdownParams); ok { + return x.MarkdownParams + } + return nil +} + func (m *RpcObjectImportRequest) GetSnapshots() []*RpcObjectImportRequestSnapshot { if m != nil { return m.Snapshots @@ -17662,11 +17680,12 @@ func (*RpcObjectImportRequest) XXX_OneofWrappers() []interface{} { return []interface{}{ (*RpcObjectImportRequestParamsOfNotionParams)(nil), (*RpcObjectImportRequestParamsOfBookmarksParams)(nil), + (*RpcObjectImportRequestParamsOfMarkdownParams)(nil), } } type RpcObjectImportRequestNotionParams struct { - Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + ApiKey string `protobuf:"bytes,1,opt,name=apiKey,proto3" json:"apiKey,omitempty"` } func (m *RpcObjectImportRequestNotionParams) Reset() { *m = RpcObjectImportRequestNotionParams{} } @@ -17702,7 +17721,51 @@ func (m *RpcObjectImportRequestNotionParams) XXX_DiscardUnknown() { var xxx_messageInfo_RpcObjectImportRequestNotionParams proto.InternalMessageInfo -func (m *RpcObjectImportRequestNotionParams) GetPath() string { +func (m *RpcObjectImportRequestNotionParams) GetApiKey() string { + if m != nil { + return m.ApiKey + } + return "" +} + +type RpcObjectImportRequestMarkdownParams struct { + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` +} + +func (m *RpcObjectImportRequestMarkdownParams) Reset() { *m = RpcObjectImportRequestMarkdownParams{} } +func (m *RpcObjectImportRequestMarkdownParams) String() string { return proto.CompactTextString(m) } +func (*RpcObjectImportRequestMarkdownParams) ProtoMessage() {} +func (*RpcObjectImportRequestMarkdownParams) Descriptor() ([]byte, []int) { + return fileDescriptor_8261c968b2e6f45c, []int{0, 4, 39, 0, 1} +} +func (m *RpcObjectImportRequestMarkdownParams) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RpcObjectImportRequestMarkdownParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RpcObjectImportRequestMarkdownParams.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RpcObjectImportRequestMarkdownParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_RpcObjectImportRequestMarkdownParams.Merge(m, src) +} +func (m *RpcObjectImportRequestMarkdownParams) XXX_Size() int { + return m.Size() +} +func (m *RpcObjectImportRequestMarkdownParams) XXX_DiscardUnknown() { + xxx_messageInfo_RpcObjectImportRequestMarkdownParams.DiscardUnknown(m) +} + +var xxx_messageInfo_RpcObjectImportRequestMarkdownParams proto.InternalMessageInfo + +func (m *RpcObjectImportRequestMarkdownParams) GetPath() string { if m != nil { return m.Path } @@ -17717,7 +17780,7 @@ func (m *RpcObjectImportRequestBookmarksParams) Reset() { *m = RpcObject func (m *RpcObjectImportRequestBookmarksParams) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportRequestBookmarksParams) ProtoMessage() {} func (*RpcObjectImportRequestBookmarksParams) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 4, 39, 0, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 4, 39, 0, 2} } func (m *RpcObjectImportRequestBookmarksParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17762,7 +17825,7 @@ func (m *RpcObjectImportRequestSnapshot) Reset() { *m = RpcObjectImportR func (m *RpcObjectImportRequestSnapshot) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportRequestSnapshot) ProtoMessage() {} func (*RpcObjectImportRequestSnapshot) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 4, 39, 0, 2} + return fileDescriptor_8261c968b2e6f45c, []int{0, 4, 39, 0, 3} } func (m *RpcObjectImportRequestSnapshot) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -42599,6 +42662,7 @@ func init() { proto.RegisterType((*RpcObjectImport)(nil), "anytype.Rpc.Object.Import") proto.RegisterType((*RpcObjectImportRequest)(nil), "anytype.Rpc.Object.Import.Request") proto.RegisterType((*RpcObjectImportRequestNotionParams)(nil), "anytype.Rpc.Object.Import.Request.NotionParams") + proto.RegisterType((*RpcObjectImportRequestMarkdownParams)(nil), "anytype.Rpc.Object.Import.Request.MarkdownParams") proto.RegisterType((*RpcObjectImportRequestBookmarksParams)(nil), "anytype.Rpc.Object.Import.Request.BookmarksParams") proto.RegisterType((*RpcObjectImportRequestSnapshot)(nil), "anytype.Rpc.Object.Import.Request.Snapshot") proto.RegisterType((*RpcObjectImportResponse)(nil), "anytype.Rpc.Object.Import.Response") @@ -43089,738 +43153,742 @@ func init() { func init() { proto.RegisterFile("pb/protos/commands.proto", fileDescriptor_8261c968b2e6f45c) } var fileDescriptor_8261c968b2e6f45c = []byte{ - // 11691 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0xbd, 0x7b, 0x74, 0x23, 0xc7, - 0x75, 0x27, 0x3c, 0x40, 0xe3, 0x41, 0x5e, 0x0e, 0x39, 0xad, 0xce, 0x78, 0x44, 0x97, 0xa4, 0xb1, - 0x42, 0x3d, 0xac, 0x8c, 0x24, 0x4a, 0x1a, 0xf9, 0xa1, 0xd1, 0x1b, 0x04, 0x40, 0x12, 0x12, 0x09, - 0x30, 0x0d, 0x70, 0x26, 0xca, 0xf7, 0x65, 0xb9, 0x4d, 0xa0, 0x48, 0xb6, 0x06, 0x44, 0x23, 0x8d, - 0x26, 0x67, 0xe8, 0x73, 0x76, 0x13, 0x25, 0x71, 0xa4, 0x24, 0xc7, 0x76, 0xec, 0x38, 0x6b, 0x2b, - 0x5e, 0x5b, 0xb6, 0xfc, 0xb6, 0xe3, 0xd8, 0xf2, 0x73, 0x9d, 0xb5, 0x95, 0xf5, 0x2b, 0xc7, 0xf1, - 0x49, 0x2c, 0xc7, 0xef, 0x64, 0x6d, 0xc7, 0x96, 0xb3, 0x5e, 0x67, 0xd7, 0x5e, 0x1f, 0xe7, 0xec, - 0xae, 0xd7, 0xeb, 0x64, 0xbd, 0xa7, 0x1e, 0xfd, 0x28, 0x10, 0xdd, 0xe8, 0x06, 0xd1, 0xa0, 0xb2, - 0xf9, 0x0b, 0xa8, 0xea, 0x7a, 0xdc, 0xba, 0xbf, 0x5b, 0xb7, 0xaa, 0x6e, 0xdd, 0xaa, 0x82, 0xe9, - 0xf6, 0xfa, 0x4d, 0x6d, 0xd3, 0xb0, 0x8c, 0xce, 0x4d, 0x75, 0x63, 0x7b, 0x5b, 0x6b, 0x35, 0x3a, - 0xb3, 0x34, 0xac, 0x64, 0xb5, 0xd6, 0x9e, 0xb5, 0xd7, 0xc6, 0xe8, 0xea, 0xf6, 0xf9, 0xcd, 0x9b, - 0x9a, 0xfa, 0xfa, 0x4d, 0xed, 0xf5, 0x9b, 0xb6, 0x8d, 0x06, 0x6e, 0xda, 0x19, 0x68, 0x80, 0x27, - 0x47, 0xd7, 0xf9, 0xa5, 0x6a, 0x1a, 0x75, 0xad, 0xd9, 0xb1, 0x0c, 0x13, 0xf3, 0x94, 0x27, 0xdc, - 0x2a, 0xf1, 0x2e, 0x6e, 0x59, 0x76, 0x09, 0x97, 0x6f, 0x1a, 0xc6, 0x66, 0x13, 0xb3, 0x6f, 0xeb, - 0x3b, 0x1b, 0x37, 0x75, 0x2c, 0x73, 0xa7, 0x6e, 0xf1, 0xaf, 0x57, 0x76, 0x7f, 0x6d, 0xe0, 0x4e, - 0xdd, 0xd4, 0xdb, 0x96, 0x61, 0xb2, 0x14, 0x33, 0xef, 0xf9, 0x56, 0x0a, 0x24, 0xb5, 0x5d, 0x47, - 0x9f, 0x1d, 0x03, 0x29, 0xd7, 0x6e, 0xa3, 0x1f, 0x26, 0x01, 0x16, 0xb0, 0x75, 0x16, 0x9b, 0x1d, - 0xdd, 0x68, 0xa1, 0x71, 0xc8, 0xaa, 0xf8, 0x97, 0x77, 0x70, 0xc7, 0x42, 0x5f, 0x49, 0xc2, 0x98, - 0x8a, 0x3b, 0x6d, 0xa3, 0xd5, 0xc1, 0xca, 0xbd, 0x90, 0xc6, 0xa6, 0x69, 0x98, 0xd3, 0x89, 0x2b, - 0x13, 0xd7, 0x4d, 0x9c, 0x3e, 0x35, 0xcb, 0x1b, 0x3e, 0xab, 0xb6, 0xeb, 0xb3, 0xb9, 0x76, 0x7b, - 0xd6, 0x2d, 0x63, 0xd6, 0xce, 0x34, 0x5b, 0x24, 0x39, 0x54, 0x96, 0x51, 0x99, 0x86, 0xec, 0x2e, - 0x4b, 0x30, 0x9d, 0xbc, 0x32, 0x71, 0xdd, 0xb8, 0x6a, 0x07, 0xc9, 0x97, 0x06, 0xb6, 0x34, 0xbd, - 0xd9, 0x99, 0x96, 0xd8, 0x17, 0x1e, 0x44, 0x5f, 0x4c, 0x40, 0x9a, 0x16, 0xa2, 0xe4, 0x21, 0x55, - 0x37, 0x1a, 0x98, 0x56, 0x3f, 0x75, 0xfa, 0xa6, 0xf0, 0xd5, 0xcf, 0xe6, 0x8d, 0x06, 0x56, 0x69, - 0x66, 0xe5, 0x4a, 0x98, 0xb0, 0x19, 0xe2, 0x92, 0xe1, 0x8d, 0x9a, 0x69, 0x40, 0x8a, 0xa4, 0x57, - 0xc6, 0x20, 0x55, 0x5e, 0x5d, 0x5a, 0x92, 0x8f, 0x28, 0x97, 0xc0, 0xe4, 0x6a, 0xf9, 0xfe, 0x72, - 0xe5, 0x5c, 0x79, 0xad, 0xa8, 0xaa, 0x15, 0x55, 0x4e, 0x28, 0x93, 0x30, 0x3e, 0x97, 0x2b, 0xac, - 0x95, 0xca, 0x2b, 0xab, 0x35, 0x39, 0xa9, 0x1c, 0x07, 0xf9, 0x6c, 0x51, 0xad, 0x96, 0x2a, 0xe5, - 0xb5, 0x52, 0x75, 0xad, 0xb8, 0xbc, 0x52, 0x7b, 0x40, 0x96, 0x48, 0xa2, 0x72, 0xa5, 0xb6, 0x36, - 0x5f, 0x59, 0x2d, 0x17, 0x64, 0xac, 0x4c, 0x40, 0xb6, 0x56, 0x5a, 0x2e, 0x56, 0x56, 0x6b, 0xf2, - 0x06, 0x7a, 0xbf, 0x04, 0x53, 0x55, 0x6c, 0x15, 0xf0, 0xae, 0x5e, 0xc7, 0x55, 0x4b, 0xb3, 0x30, - 0x7a, 0x59, 0xc2, 0x61, 0xbc, 0xb2, 0x4a, 0xc8, 0x74, 0x3e, 0xf1, 0x26, 0xdf, 0xba, 0xaf, 0xc9, - 0x62, 0x09, 0xb3, 0x3c, 0xf7, 0xac, 0x27, 0x4e, 0xf5, 0x96, 0x33, 0x73, 0x23, 0x4c, 0x78, 0xbe, - 0x29, 0x53, 0x00, 0x73, 0xb9, 0xfc, 0xfd, 0x0b, 0x2a, 0xa5, 0xf0, 0x08, 0x09, 0xcf, 0x57, 0xd4, - 0x22, 0x0f, 0x27, 0xd0, 0xcb, 0xbc, 0xf0, 0x17, 0x44, 0xf8, 0x67, 0xfb, 0x13, 0xd3, 0x43, 0x04, - 0xd0, 0x47, 0x1c, 0x38, 0x17, 0x04, 0x38, 0x6f, 0x8d, 0x56, 0x5c, 0x34, 0x48, 0x17, 0x07, 0x83, - 0xb4, 0x5c, 0x29, 0x14, 0xd7, 0x08, 0x82, 0xd5, 0x5a, 0x4e, 0xad, 0x15, 0x0b, 0x32, 0x46, 0xaf, - 0x49, 0xc2, 0x58, 0x75, 0x6b, 0xc7, 0x6a, 0x18, 0x17, 0x84, 0x8e, 0xf2, 0xeb, 0x5e, 0x4e, 0xdd, - 0x2d, 0x72, 0xea, 0xba, 0xfd, 0x4d, 0xe3, 0x25, 0xf8, 0xf0, 0xe8, 0x83, 0x0e, 0x8f, 0x72, 0x02, - 0x8f, 0x6e, 0x0c, 0x5b, 0xd0, 0x61, 0x71, 0xe7, 0x4b, 0x93, 0x90, 0x39, 0xa7, 0x35, 0x9b, 0xd8, - 0x42, 0x7f, 0x9b, 0x84, 0x4c, 0xde, 0xc4, 0x44, 0xae, 0xaf, 0x77, 0xc5, 0x1a, 0xc1, 0x98, 0x69, - 0x18, 0xd6, 0x8a, 0x66, 0x6d, 0xd1, 0x36, 0x8d, 0xab, 0x4e, 0xf8, 0xf6, 0xd4, 0x23, 0xdf, 0x91, - 0x12, 0xe8, 0x0f, 0xbd, 0x8c, 0xbc, 0x47, 0x64, 0xe4, 0xcf, 0x09, 0xed, 0x67, 0x15, 0xcd, 0xb2, - 0x4a, 0x7c, 0x14, 0x0e, 0x82, 0xb1, 0xed, 0x16, 0xde, 0x36, 0x5a, 0x7a, 0x9d, 0xb7, 0xdc, 0x09, - 0xa3, 0x8f, 0x3b, 0x5c, 0x9e, 0x13, 0xb8, 0x3c, 0x1b, 0xba, 0x96, 0x68, 0x6c, 0xae, 0x0e, 0xc0, - 0xe6, 0xe7, 0xc0, 0x65, 0xf3, 0xb9, 0xd2, 0x52, 0xb1, 0xb0, 0x56, 0xab, 0xac, 0xe5, 0xd5, 0x62, - 0xae, 0x56, 0x5c, 0x5b, 0xaa, 0xe4, 0x73, 0x4b, 0x6b, 0x6a, 0x71, 0xa5, 0x22, 0x63, 0xf4, 0x9f, - 0x93, 0x84, 0xb9, 0x75, 0x63, 0x17, 0x9b, 0x68, 0x21, 0x14, 0x9f, 0x83, 0x78, 0xc2, 0x31, 0x78, - 0x45, 0x68, 0xad, 0xcf, 0xb9, 0xc3, 0x29, 0xf0, 0x11, 0xe7, 0x4f, 0x84, 0xd2, 0xe0, 0x81, 0x45, - 0x3d, 0x03, 0x38, 0xfd, 0xdf, 0x93, 0x90, 0xcd, 0x1b, 0xad, 0x5d, 0x6c, 0x5a, 0xe8, 0x1e, 0x81, - 0xd3, 0x0e, 0x37, 0x13, 0x22, 0x37, 0xc9, 0xa0, 0x86, 0x5b, 0x96, 0x69, 0xb4, 0xf7, 0xec, 0xe1, - 0x8e, 0x07, 0xd1, 0x5b, 0xa3, 0x72, 0x98, 0xd7, 0xec, 0x3f, 0xae, 0xf6, 0xae, 0x48, 0x20, 0x4f, - 0xea, 0xea, 0x00, 0x8f, 0x47, 0xc1, 0xa5, 0x37, 0x01, 0xd1, 0x70, 0x39, 0x1d, 0x1d, 0x17, 0xf4, - 0xf9, 0x24, 0x4c, 0xb2, 0xce, 0x57, 0xc5, 0x1d, 0x3a, 0x3d, 0xb9, 0x3e, 0x14, 0xf3, 0xb9, 0x28, - 0xff, 0x9e, 0x97, 0xd1, 0xf3, 0x22, 0xa3, 0x6f, 0xf6, 0xef, 0xe8, 0xbc, 0x2e, 0x1f, 0x76, 0x1f, - 0x87, 0xb4, 0x65, 0x9c, 0xc7, 0x76, 0x1b, 0x59, 0x00, 0xbd, 0xcd, 0x61, 0x67, 0x49, 0x60, 0xe7, - 0xf3, 0xa3, 0x56, 0x13, 0x3f, 0x53, 0xdf, 0x95, 0x84, 0xa3, 0xf9, 0xa6, 0xd1, 0x71, 0x78, 0xfa, - 0x1c, 0x97, 0xa7, 0x4e, 0xe3, 0x12, 0xde, 0xc6, 0xfd, 0x24, 0xe1, 0xe1, 0x63, 0x51, 0xe4, 0x63, - 0x6f, 0x79, 0xf1, 0x14, 0xef, 0xa3, 0x17, 0xde, 0xea, 0x30, 0x6c, 0x51, 0x60, 0xd8, 0xf3, 0x22, - 0x96, 0x17, 0x3f, 0xbf, 0x3e, 0xf8, 0xb3, 0x90, 0xcd, 0xd5, 0xeb, 0xc6, 0x4e, 0xcb, 0x42, 0x7f, - 0x93, 0x80, 0x4c, 0xde, 0x68, 0x6d, 0xe8, 0x9b, 0xca, 0xb5, 0x30, 0x85, 0x5b, 0xda, 0x7a, 0x13, - 0x17, 0x34, 0x4b, 0xdb, 0xd5, 0xf1, 0x05, 0xda, 0x80, 0x31, 0xb5, 0x2b, 0x96, 0x10, 0xc5, 0x63, - 0xf0, 0xfa, 0xce, 0x26, 0x25, 0x6a, 0x4c, 0xf5, 0x46, 0x29, 0xb7, 0xc1, 0xa5, 0x2c, 0xb8, 0x62, - 0x62, 0x13, 0x37, 0xb1, 0xd6, 0xc1, 0xf9, 0x2d, 0xad, 0xd5, 0xc2, 0x4d, 0xda, 0x6b, 0xc7, 0x54, - 0xbf, 0xcf, 0xca, 0x0c, 0x1c, 0x65, 0x9f, 0xaa, 0x6d, 0xad, 0x8e, 0x3b, 0xd3, 0x29, 0x9a, 0x5c, - 0x88, 0x53, 0x6e, 0x84, 0x34, 0xbe, 0x68, 0x99, 0xda, 0x74, 0x83, 0xe2, 0x75, 0xe9, 0x2c, 0x5b, - 0x22, 0xcc, 0xda, 0x4b, 0x84, 0xd9, 0x2a, 0x5d, 0x40, 0xa8, 0x2c, 0x15, 0xfa, 0x44, 0xc6, 0x19, - 0xba, 0xdf, 0xe0, 0x99, 0x92, 0x2a, 0x90, 0x6a, 0x69, 0xdb, 0x98, 0xcb, 0x05, 0xfd, 0xaf, 0x9c, - 0x82, 0x63, 0xda, 0xae, 0x66, 0x69, 0xe6, 0x12, 0x59, 0xbc, 0xd0, 0xe1, 0x86, 0xb2, 0x7c, 0xf1, - 0x88, 0xda, 0xfd, 0x41, 0xb9, 0x1c, 0xc6, 0xe9, 0xea, 0x86, 0xa6, 0x62, 0xba, 0xc8, 0x8d, 0x50, - 0xae, 0x83, 0x63, 0x5a, 0xb3, 0xbd, 0xa5, 0x95, 0x5a, 0xbb, 0xba, 0x85, 0x09, 0x42, 0xd3, 0xc7, - 0x69, 0x9a, 0xee, 0x68, 0xd6, 0xb1, 0xe7, 0xc6, 0x20, 0xc3, 0x2a, 0x40, 0xaf, 0x4c, 0x87, 0x5e, - 0xa3, 0x30, 0x08, 0x83, 0xa7, 0x0c, 0x37, 0x43, 0x56, 0x63, 0xe9, 0x68, 0x53, 0x26, 0x4e, 0x9f, - 0x70, 0xca, 0xa0, 0xcb, 0x35, 0xbb, 0x14, 0xd5, 0x4e, 0xa6, 0xdc, 0x0a, 0x99, 0x3a, 0x15, 0x08, - 0xda, 0xaa, 0x89, 0xd3, 0x97, 0xf5, 0xae, 0x94, 0x26, 0x51, 0x79, 0x52, 0xf4, 0x0d, 0x29, 0xd4, - 0xb2, 0x26, 0x88, 0xe2, 0x68, 0x72, 0xff, 0xfd, 0xe4, 0x00, 0xa3, 0xe2, 0x0d, 0x70, 0x5d, 0x2e, - 0x9f, 0xaf, 0xac, 0x96, 0x6b, 0x7c, 0x4c, 0x2c, 0xac, 0xcd, 0xad, 0xd6, 0xd6, 0xdc, 0x91, 0x92, - 0xce, 0xfd, 0xd6, 0xc8, 0x54, 0x50, 0x26, 0xd2, 0x70, 0x6d, 0x9f, 0xd4, 0xc5, 0xda, 0x5a, 0x39, - 0xb7, 0x5c, 0x94, 0x37, 0x42, 0x94, 0x5c, 0xac, 0xad, 0xe5, 0xce, 0xe6, 0x6a, 0x39, 0x55, 0xde, - 0x14, 0x47, 0xe7, 0x6a, 0xad, 0xb2, 0xb2, 0xa6, 0xae, 0x96, 0xcb, 0xa5, 0xf2, 0x02, 0xab, 0x9a, - 0x4c, 0x6a, 0x4e, 0xb8, 0x09, 0xce, 0xa9, 0xa5, 0x5a, 0x71, 0x2d, 0x5f, 0x29, 0xcf, 0x97, 0x16, - 0x64, 0xbd, 0xdf, 0xd0, 0xfe, 0xa0, 0x72, 0x1c, 0x8e, 0xb1, 0x46, 0x9f, 0x65, 0xf9, 0x0a, 0x45, - 0xf9, 0x37, 0xb2, 0xca, 0x14, 0x8c, 0x97, 0x8b, 0x35, 0xce, 0x99, 0x17, 0x67, 0x95, 0xcb, 0xe0, - 0x04, 0x09, 0xe7, 0x2b, 0xe5, 0x72, 0x31, 0x5f, 0x23, 0x4b, 0x3d, 0xb5, 0x38, 0xbf, 0x5a, 0x2d, - 0x16, 0xe4, 0xdf, 0xcc, 0x2a, 0x32, 0x4c, 0x90, 0x8f, 0x95, 0xf9, 0xf9, 0xa5, 0x52, 0xb9, 0x28, - 0x3f, 0x9c, 0x45, 0x6f, 0x4e, 0xb9, 0x33, 0x33, 0xcf, 0x42, 0xe1, 0xa5, 0x29, 0x8f, 0xb4, 0xe6, - 0x44, 0x69, 0xbd, 0xbe, 0x27, 0xf6, 0xc1, 0x93, 0xab, 0x27, 0x1d, 0x39, 0x2a, 0x08, 0x72, 0x74, - 0x73, 0x84, 0xb2, 0xa2, 0x09, 0xd2, 0x9f, 0x0f, 0x22, 0x48, 0xcf, 0x82, 0x4b, 0xca, 0x95, 0x35, - 0x8e, 0x78, 0xd5, 0x59, 0x12, 0x5f, 0x09, 0x97, 0x97, 0x8b, 0x0c, 0x18, 0xb5, 0x98, 0xaf, 0x9c, - 0x2d, 0xaa, 0x6b, 0xe7, 0x72, 0x4b, 0x4b, 0xc5, 0xda, 0xda, 0x7c, 0x49, 0xad, 0xd6, 0xe4, 0x8d, - 0x7e, 0xe0, 0x6d, 0x2a, 0x57, 0xc1, 0x73, 0xdc, 0xf0, 0x5a, 0xf1, 0x17, 0x4a, 0xd5, 0x5a, 0x95, - 0x8a, 0x52, 0xbe, 0xa2, 0xaa, 0xab, 0x2b, 0x64, 0x61, 0xb2, 0xa5, 0x9c, 0x00, 0xc5, 0x2d, 0x45, - 0x5d, 0x2d, 0x33, 0xb1, 0xd1, 0x49, 0xfd, 0xbc, 0x3e, 0xbb, 0x7a, 0xb2, 0xa0, 0x59, 0x29, 0xaa, - 0xf3, 0x15, 0x75, 0xb9, 0x58, 0x90, 0x1f, 0xec, 0x27, 0x79, 0xe7, 0x95, 0x6b, 0x61, 0x26, 0x57, - 0xae, 0xd4, 0x16, 0x8b, 0xea, 0x5a, 0xae, 0xfc, 0x40, 0xed, 0x81, 0x95, 0xe2, 0xda, 0x8a, 0x5a, - 0xc9, 0x17, 0xab, 0xd5, 0xb5, 0x52, 0xd5, 0x4e, 0x2c, 0x37, 0x09, 0x09, 0xb6, 0xc0, 0x97, 0xaa, - 0x6b, 0x85, 0xe2, 0x52, 0x91, 0x90, 0xb6, 0x8d, 0x5e, 0x22, 0x41, 0xa6, 0x80, 0x9b, 0xd8, 0xc2, - 0xe8, 0x67, 0x5d, 0x65, 0x7b, 0x02, 0x32, 0x26, 0x26, 0x13, 0x2e, 0x3e, 0xa4, 0xf0, 0x10, 0xfa, - 0x9b, 0x64, 0x54, 0x65, 0xc7, 0xca, 0xf6, 0x51, 0x76, 0xcf, 0x87, 0x4c, 0xc7, 0xd2, 0xac, 0x9d, - 0x0e, 0xd7, 0x75, 0x57, 0xf4, 0xd6, 0x75, 0xb3, 0x55, 0x9a, 0x48, 0xe5, 0x89, 0xd1, 0x5f, 0x25, - 0xa2, 0x28, 0xaf, 0x9e, 0x14, 0x44, 0x93, 0x39, 0x7d, 0x00, 0x91, 0x3b, 0x09, 0xc8, 0xc3, 0xf0, - 0xdc, 0x92, 0x5a, 0xcc, 0x15, 0x1e, 0x70, 0x18, 0x8f, 0x89, 0x48, 0x7a, 0xbf, 0xe7, 0x6b, 0xa5, - 0xb3, 0x45, 0x79, 0x03, 0x7d, 0x22, 0x0d, 0x99, 0x2a, 0x6e, 0xe2, 0xba, 0x85, 0xee, 0x70, 0xf1, - 0x98, 0x82, 0xa4, 0xde, 0xe0, 0x43, 0x5f, 0x52, 0x6f, 0x08, 0x0b, 0xac, 0x64, 0xcf, 0x85, 0xec, - 0x4f, 0x52, 0x51, 0x91, 0x62, 0xb5, 0x1e, 0xee, 0xb0, 0xf4, 0xa9, 0x48, 0xc3, 0x52, 0x4f, 0x8a, - 0xa3, 0x21, 0xfb, 0xc5, 0x64, 0x0c, 0x8b, 0xb5, 0x30, 0x4a, 0x61, 0xc3, 0x47, 0x29, 0x74, 0x0d, - 0x36, 0xf3, 0xa5, 0x72, 0x61, 0xcd, 0x91, 0x93, 0xf2, 0x7c, 0x45, 0xde, 0x52, 0x66, 0xe1, 0x94, - 0xa7, 0x74, 0xa2, 0x31, 0x78, 0x0d, 0xb9, 0x72, 0x61, 0x6d, 0xb9, 0x5c, 0x5c, 0xae, 0x94, 0x4b, - 0x79, 0x66, 0x1a, 0x29, 0xd6, 0x98, 0x96, 0xe9, 0xd2, 0x21, 0xd5, 0x62, 0x4e, 0xcd, 0x2f, 0x52, - 0x75, 0x53, 0x28, 0xca, 0x0f, 0x2a, 0xcf, 0x85, 0xab, 0x3c, 0xa4, 0x70, 0x55, 0xb4, 0xa2, 0x16, - 0x0b, 0xc5, 0xf9, 0x52, 0x99, 0x0c, 0x8d, 0x4b, 0x95, 0xfc, 0xfd, 0xd5, 0xf0, 0xda, 0x06, 0xfd, - 0xef, 0x24, 0xa4, 0xaa, 0x96, 0xd1, 0x46, 0x3f, 0xe7, 0xca, 0xf0, 0x49, 0x00, 0x13, 0x6f, 0x1b, - 0xbb, 0x74, 0x62, 0xca, 0xf5, 0x8a, 0x27, 0x06, 0xfd, 0x69, 0x78, 0x1b, 0x96, 0xa3, 0x16, 0x8c, - 0xb6, 0xcf, 0xb8, 0xf4, 0xe3, 0x70, 0x36, 0x2c, 0xff, 0x82, 0xa2, 0x89, 0xd1, 0x6f, 0x27, 0x06, - 0x10, 0x23, 0x04, 0x27, 0x3c, 0x1a, 0x80, 0xe0, 0x65, 0x33, 0x10, 0x2b, 0x97, 0xc2, 0xcf, 0x74, - 0x61, 0x46, 0xa1, 0xda, 0x50, 0x7e, 0x16, 0xae, 0xf0, 0x42, 0xb5, 0x5c, 0x39, 0x5b, 0x74, 0xe4, - 0xa3, 0x90, 0xab, 0xe5, 0xe4, 0x4d, 0xf4, 0x05, 0x09, 0x52, 0xcb, 0xc6, 0x2e, 0x46, 0x57, 0xb9, - 0xcc, 0x9f, 0x86, 0x6c, 0x0b, 0x5f, 0xf0, 0x18, 0x64, 0xec, 0x20, 0x7a, 0xb3, 0x14, 0x95, 0xed, - 0xa4, 0x6c, 0x1f, 0xb6, 0x7f, 0x35, 0x19, 0x85, 0xed, 0x3d, 0x0a, 0x8a, 0xc6, 0xf6, 0xbf, 0x1b, - 0x84, 0xed, 0x3e, 0xac, 0xc5, 0xca, 0x0c, 0x9c, 0x74, 0x3f, 0x94, 0x0a, 0xc5, 0x72, 0xad, 0x34, - 0xff, 0x80, 0xcb, 0xdc, 0x92, 0x1a, 0x8a, 0xfd, 0xfd, 0xb4, 0x43, 0xf0, 0x64, 0x71, 0x1a, 0x8e, - 0xbb, 0xdf, 0x16, 0xd8, 0x7c, 0x8f, 0x7c, 0x79, 0x10, 0xbd, 0x22, 0x0d, 0x47, 0x99, 0xb6, 0x5c, - 0x6d, 0x37, 0xc8, 0xe2, 0xe8, 0x1a, 0xc1, 0x10, 0x61, 0xe9, 0xdb, 0xf8, 0x17, 0x8d, 0x96, 0xbd, - 0x3e, 0x72, 0xc2, 0xe8, 0x73, 0xa1, 0x4d, 0x10, 0xa2, 0x4e, 0x66, 0xb5, 0xf8, 0xe0, 0xfc, 0x93, - 0x50, 0xc6, 0x86, 0x10, 0x05, 0x46, 0xc3, 0xfb, 0x37, 0x86, 0xdd, 0xcd, 0xfc, 0xa1, 0xd8, 0xf0, - 0x85, 0x62, 0x73, 0xe6, 0xe1, 0x24, 0x8c, 0xd7, 0xf4, 0x6d, 0xfc, 0x22, 0xa3, 0x85, 0x3b, 0x4a, - 0x16, 0xa4, 0x85, 0xe5, 0x9a, 0x7c, 0x84, 0xfc, 0x29, 0xe6, 0x6b, 0x72, 0x82, 0xfe, 0x29, 0x92, - 0xaa, 0xc9, 0x9f, 0x5c, 0x4d, 0x96, 0xc8, 0x9f, 0xe5, 0x62, 0x4d, 0x4e, 0x91, 0x3f, 0xe5, 0x62, - 0x4d, 0x4e, 0x93, 0x3f, 0x2b, 0x4b, 0x35, 0x39, 0x43, 0xfe, 0x94, 0xaa, 0x35, 0x39, 0x4b, 0xfe, - 0xcc, 0x55, 0x6b, 0xf2, 0x18, 0xf9, 0x73, 0xb6, 0x5a, 0x93, 0xc7, 0xc9, 0x9f, 0x7c, 0xad, 0x26, - 0x03, 0xf9, 0x73, 0x5f, 0xb5, 0x26, 0x4f, 0x90, 0x3f, 0xb9, 0x7c, 0x4d, 0x3e, 0x4a, 0xff, 0x14, - 0x6b, 0xf2, 0x24, 0xf9, 0x53, 0xad, 0xd6, 0xe4, 0x29, 0x5a, 0x72, 0xb5, 0x26, 0x1f, 0xa3, 0x75, - 0x95, 0x6a, 0xb2, 0x4c, 0xfe, 0x2c, 0x56, 0x6b, 0xf2, 0x25, 0x34, 0x71, 0xb5, 0x26, 0x2b, 0xb4, - 0xd2, 0x6a, 0x4d, 0xfe, 0x19, 0x9a, 0xa6, 0x5a, 0x93, 0x8f, 0xd3, 0x2a, 0xaa, 0x35, 0xf9, 0x59, - 0x94, 0x8c, 0x62, 0x4d, 0x3e, 0x41, 0xd3, 0xa8, 0x35, 0xf9, 0x52, 0xfa, 0xa9, 0x5c, 0x93, 0xa7, - 0x29, 0x61, 0xc5, 0x9a, 0xfc, 0x6c, 0xfa, 0x47, 0xad, 0xc9, 0x88, 0x7e, 0xca, 0xd5, 0xe4, 0xcb, - 0xd0, 0x15, 0x30, 0xbe, 0x80, 0x2d, 0x86, 0x2f, 0x92, 0x41, 0x5a, 0xc0, 0x96, 0x77, 0xb5, 0xf1, - 0xad, 0x63, 0x30, 0x7e, 0xce, 0x30, 0xcf, 0x77, 0xda, 0x5a, 0x1d, 0xa3, 0x0f, 0xb3, 0x7d, 0xbe, - 0xfc, 0x8e, 0x69, 0xe2, 0x96, 0x90, 0xee, 0xb1, 0xf0, 0x66, 0x32, 0xbb, 0xb4, 0x59, 0xb7, 0x24, - 0x9f, 0x29, 0xcb, 0x95, 0x30, 0x71, 0xc1, 0x4e, 0x5d, 0x6a, 0xd8, 0xe2, 0xe4, 0x89, 0x0a, 0x6b, - 0x32, 0xeb, 0x5f, 0x65, 0xfc, 0x26, 0xa0, 0x77, 0x27, 0x21, 0xb3, 0x80, 0xad, 0x5c, 0xb3, 0xe9, - 0xe5, 0xdb, 0xa3, 0x5e, 0xbe, 0xcd, 0x89, 0x7c, 0xbb, 0xc1, 0xbf, 0x11, 0xb9, 0x66, 0xd3, 0x87, - 0x67, 0x33, 0x70, 0xd4, 0xc3, 0x20, 0x32, 0x2d, 0x97, 0xae, 0x1b, 0x57, 0x85, 0x38, 0xf4, 0x26, - 0x87, 0x6b, 0x45, 0x81, 0x6b, 0xb7, 0x44, 0xa9, 0x30, 0x7e, 0x8e, 0x7d, 0xcc, 0xdd, 0x01, 0xba, - 0x22, 0xd0, 0x8a, 0x84, 0x5e, 0x35, 0x00, 0x17, 0x03, 0x6d, 0x38, 0xfd, 0x25, 0x2f, 0x2a, 0x0f, - 0x87, 0x60, 0x80, 0x19, 0x84, 0x87, 0xff, 0x35, 0x09, 0x72, 0x15, 0x5b, 0xa5, 0xce, 0xa2, 0xbe, - 0xb9, 0xd5, 0xd4, 0x37, 0xb7, 0x2c, 0xdc, 0x40, 0xf7, 0x0b, 0xe3, 0x8e, 0xb1, 0xfe, 0x20, 0xae, - 0x5b, 0x25, 0x7b, 0x71, 0xe2, 0x84, 0x95, 0xab, 0x61, 0x52, 0xf7, 0xe6, 0xe3, 0x76, 0x47, 0x31, - 0x12, 0xfd, 0x96, 0x97, 0xf7, 0x4b, 0x22, 0xef, 0x5f, 0xe0, 0xc3, 0x8c, 0x6e, 0x8a, 0x7c, 0xc6, - 0xa8, 0x3f, 0x72, 0x78, 0x5c, 0x11, 0x78, 0x7c, 0xc7, 0x60, 0xc5, 0x8e, 0xc4, 0x2c, 0x6e, 0x2f, - 0xfd, 0x3c, 0x9b, 0x0c, 0x5d, 0xc2, 0x94, 0xd8, 0x2f, 0x4c, 0xff, 0x23, 0x11, 0x5d, 0x7e, 0x83, - 0x16, 0x7b, 0x91, 0xa5, 0x73, 0x08, 0xeb, 0xb0, 0x41, 0xf8, 0xf5, 0xeb, 0x12, 0x64, 0x8a, 0x17, - 0xdb, 0x86, 0xb8, 0x23, 0xa6, 0x40, 0xaa, 0xed, 0x4e, 0x73, 0xe9, 0xff, 0x10, 0x1d, 0xf2, 0x43, - 0x03, 0xe8, 0x00, 0x56, 0xb7, 0x8f, 0x0e, 0xb0, 0xc9, 0x48, 0x7a, 0xc8, 0xb8, 0x01, 0xd2, 0xd4, - 0x93, 0x86, 0xaf, 0x88, 0xdd, 0x25, 0xb4, 0x5d, 0x44, 0x91, 0x7c, 0x55, 0x59, 0xa2, 0xc8, 0x28, - 0xf4, 0x24, 0x27, 0x7e, 0x14, 0x5e, 0xf7, 0xf2, 0x04, 0x64, 0x2a, 0xb4, 0xd7, 0xa3, 0xdf, 0x4a, - 0x41, 0xaa, 0xd2, 0xc6, 0x2d, 0xf4, 0x2e, 0x8f, 0xe1, 0xfe, 0x72, 0x18, 0xaf, 0x1b, 0x2d, 0x0b, - 0x5f, 0x74, 0xb5, 0x84, 0x1b, 0x21, 0xa8, 0x90, 0x64, 0x97, 0x0a, 0x99, 0x86, 0xac, 0x65, 0x32, - 0xc8, 0xb8, 0x57, 0x0e, 0x0f, 0x2a, 0x65, 0x98, 0xd1, 0x5b, 0xf5, 0xe6, 0x4e, 0x03, 0xab, 0xb8, - 0xa9, 0x11, 0xda, 0x3b, 0xb9, 0x4e, 0x01, 0xb7, 0x71, 0xab, 0x81, 0x5b, 0x16, 0xa3, 0xc6, 0xde, - 0x8c, 0x08, 0x91, 0x52, 0x9c, 0x24, 0xdf, 0x25, 0xc2, 0xff, 0x5c, 0x81, 0xdf, 0x2c, 0xc7, 0x2c, - 0x69, 0xa5, 0x0f, 0xf2, 0x67, 0x00, 0x58, 0x0b, 0xce, 0xea, 0xf8, 0x02, 0xb7, 0x96, 0x3c, 0xbb, - 0xcb, 0x5a, 0x52, 0x71, 0x12, 0xa8, 0x9e, 0xc4, 0xe8, 0xcf, 0x1c, 0xc8, 0xef, 0x15, 0x20, 0xbf, - 0x21, 0x24, 0x09, 0xd1, 0xd0, 0xfe, 0xff, 0x07, 0x98, 0x4c, 0x0b, 0x3e, 0x45, 0x92, 0xf2, 0x6c, - 0x78, 0x96, 0x6d, 0x07, 0x28, 0x17, 0x8b, 0x85, 0xea, 0xda, 0xea, 0xca, 0x82, 0x9a, 0x2b, 0x14, - 0x65, 0x40, 0x1f, 0x49, 0x42, 0x9a, 0xee, 0x9a, 0xa1, 0xfc, 0x10, 0x64, 0x01, 0x7d, 0x3f, 0x11, - 0x76, 0x99, 0xca, 0xd9, 0x43, 0xeb, 0xf6, 0x51, 0x70, 0xaf, 0x0f, 0x65, 0x1d, 0x08, 0x28, 0x28, - 0xfe, 0x6e, 0x45, 0xba, 0x52, 0x75, 0xcb, 0xb8, 0xf0, 0xff, 0x7e, 0x57, 0x22, 0xad, 0x3c, 0xe4, - 0xae, 0xd4, 0x83, 0x84, 0x67, 0x52, 0x57, 0x7a, 0x34, 0xe5, 0x4c, 0x65, 0x1f, 0xf3, 0x48, 0xc3, - 0x2d, 0xae, 0xd3, 0x62, 0x22, 0x78, 0x67, 0xd5, 0x4e, 0xa7, 0xe4, 0x60, 0x52, 0x6f, 0x59, 0xd8, - 0x6c, 0x69, 0xcd, 0xf9, 0xa6, 0xb6, 0xc9, 0x26, 0xf8, 0x5e, 0xdb, 0x2c, 0xe3, 0x69, 0xc9, 0x93, - 0x46, 0x15, 0x73, 0x28, 0x27, 0x01, 0x2c, 0xbc, 0xdd, 0x6e, 0x6a, 0x96, 0x2b, 0x4c, 0x9e, 0x18, - 0xf4, 0xbd, 0xd0, 0x1e, 0x54, 0x76, 0xff, 0xea, 0xe3, 0x41, 0xe5, 0xc8, 0xb4, 0xd4, 0x25, 0xd3, - 0xce, 0x70, 0x9a, 0x0a, 0x31, 0x9c, 0x7a, 0xb9, 0x95, 0x0e, 0xc7, 0x2d, 0xf4, 0x86, 0x50, 0x2e, - 0x5a, 0x41, 0xcd, 0x88, 0x5f, 0x4f, 0x3c, 0x26, 0xc1, 0x14, 0xab, 0x7a, 0xce, 0x30, 0xce, 0x6f, - 0x6b, 0xe6, 0x79, 0x74, 0xe7, 0x41, 0x44, 0x04, 0x7d, 0xd6, 0x8b, 0xdf, 0x82, 0x88, 0xdf, 0x2d, - 0xfe, 0x0d, 0xb7, 0x6b, 0x0f, 0x81, 0x63, 0xb7, 0x6e, 0xba, 0x45, 0x74, 0xbe, 0x0d, 0x43, 0xe4, - 0xdb, 0x1d, 0x64, 0xee, 0x13, 0x90, 0x79, 0x41, 0x64, 0x02, 0xe3, 0x47, 0xe8, 0x09, 0x07, 0x21, - 0x5b, 0x6d, 0x1e, 0x10, 0xa1, 0x6f, 0x0e, 0x86, 0x90, 0x5d, 0xfb, 0x00, 0x08, 0xc9, 0x20, 0x9d, - 0xc7, 0x7b, 0xbc, 0x03, 0x92, 0xbf, 0x5e, 0xb2, 0x53, 0xf1, 0x61, 0xe6, 0x43, 0xf2, 0x48, 0x30, - 0x3b, 0x2e, 0x92, 0x50, 0x69, 0x0f, 0x01, 0xb9, 0xbf, 0xf6, 0x22, 0xb7, 0x2c, 0x22, 0xf7, 0xc2, - 0xfe, 0x6c, 0x60, 0x34, 0x8c, 0xa6, 0x87, 0xbd, 0xdb, 0x41, 0x6b, 0x45, 0x40, 0xeb, 0xce, 0x01, - 0xc9, 0x8c, 0x1f, 0xb3, 0xaf, 0xa4, 0x60, 0xdc, 0xf6, 0x6b, 0xb3, 0xd0, 0x87, 0x12, 0xc2, 0x6e, - 0x76, 0xc7, 0xd8, 0x31, 0xeb, 0xa4, 0x0d, 0xd2, 0x75, 0xe3, 0x2a, 0x0f, 0x79, 0xd9, 0x92, 0x0c, - 0x39, 0x80, 0xf6, 0x19, 0xfd, 0xf6, 0x0f, 0xb0, 0xa9, 0xa8, 0x03, 0x2c, 0x7a, 0x99, 0x14, 0x76, - 0x29, 0x2a, 0x70, 0xbf, 0x8a, 0xad, 0x67, 0xe2, 0x18, 0xfa, 0xb1, 0x50, 0xab, 0xd8, 0x3e, 0x2d, - 0x89, 0x26, 0x3c, 0x95, 0x01, 0x26, 0x63, 0x97, 0xc1, 0xa5, 0x76, 0x8a, 0xca, 0xdc, 0x7d, 0xc5, - 0x7c, 0x6d, 0x8d, 0xce, 0xc4, 0x56, 0xd5, 0x25, 0x59, 0x42, 0x2f, 0x4e, 0x81, 0xcc, 0x48, 0x63, - 0x74, 0xd6, 0xf6, 0xda, 0x18, 0xfd, 0xca, 0x21, 0x4f, 0xc4, 0xd0, 0x0f, 0xbc, 0xca, 0xa4, 0x24, - 0xca, 0xc9, 0xad, 0xfe, 0xdc, 0x75, 0x9b, 0xe0, 0x23, 0x2e, 0x03, 0xf4, 0x8a, 0x00, 0x09, 0x43, - 0x9f, 0x76, 0x04, 0x60, 0x49, 0x10, 0x80, 0xdb, 0x06, 0x20, 0xf1, 0x90, 0xe5, 0xe0, 0x33, 0x49, - 0x98, 0xb4, 0xa7, 0x11, 0xf3, 0xd8, 0xaa, 0x6f, 0xa1, 0x33, 0x61, 0xd7, 0x66, 0x32, 0x48, 0x3b, - 0x66, 0x93, 0x53, 0x49, 0xfe, 0xa2, 0x7f, 0x4c, 0x84, 0xdd, 0xf3, 0xe0, 0xbc, 0x11, 0x6a, 0xf6, - 0x59, 0xd8, 0x86, 0xdb, 0xd1, 0x08, 0x51, 0x60, 0xfc, 0xea, 0xfa, 0xeb, 0x49, 0x80, 0x9a, 0xe1, - 0x4c, 0x5a, 0x0f, 0xc0, 0x49, 0xc1, 0xc9, 0x3a, 0x2f, 0x72, 0xb2, 0xe7, 0x8a, 0xde, 0xad, 0x36, - 0xfa, 0x58, 0x8a, 0xde, 0xec, 0xb0, 0x78, 0x5e, 0x60, 0xf1, 0xe9, 0x48, 0x35, 0xc5, 0xcf, 0xdf, - 0x8f, 0x24, 0x61, 0xbc, 0xb0, 0xd3, 0x6e, 0xea, 0x75, 0xb2, 0x6e, 0x7c, 0x6e, 0x48, 0xf6, 0xa2, - 0x17, 0x27, 0x23, 0x8e, 0x3e, 0x4e, 0x1d, 0x3e, 0xbc, 0x64, 0xae, 0x4b, 0x49, 0xdb, 0x75, 0x29, - 0xa4, 0x59, 0xb3, 0x4f, 0xe1, 0x23, 0x10, 0x4f, 0x09, 0x8e, 0x55, 0xda, 0xb8, 0x35, 0x67, 0x62, - 0xad, 0x51, 0x37, 0x77, 0xb6, 0xd7, 0x3b, 0x28, 0x17, 0x56, 0x46, 0x3d, 0xd6, 0x96, 0xa4, 0x60, - 0x6d, 0x41, 0xbf, 0xe9, 0x1d, 0xdc, 0x17, 0x45, 0xf6, 0x9e, 0xf6, 0xb3, 0xf2, 0x79, 0x68, 0x18, - 0x60, 0xf2, 0x17, 0xc9, 0xea, 0xdc, 0x65, 0x72, 0x49, 0x45, 0x31, 0xb9, 0xbc, 0xc3, 0x41, 0xf6, - 0x7e, 0x01, 0xd9, 0x17, 0x46, 0x6f, 0xd7, 0x48, 0x36, 0x0f, 0xa6, 0xaa, 0xd8, 0xf2, 0x81, 0xf7, - 0x6a, 0x98, 0x5c, 0x77, 0xbf, 0x38, 0x10, 0x8b, 0x91, 0x44, 0x15, 0xe9, 0xce, 0x26, 0x29, 0xf9, - 0x8b, 0xde, 0x15, 0x75, 0x69, 0x26, 0x92, 0xe0, 0x83, 0xae, 0x83, 0x60, 0x32, 0xcc, 0xbe, 0x41, - 0xa4, 0x75, 0x56, 0x60, 0xfd, 0xf1, 0xa3, 0xf0, 0x4e, 0x09, 0xa6, 0x4a, 0xdb, 0x6d, 0xc3, 0xb4, - 0x96, 0x35, 0xf3, 0x3c, 0x3d, 0xd5, 0xb8, 0x10, 0xb6, 0x93, 0x9d, 0x04, 0xd0, 0x69, 0x56, 0x8f, - 0x17, 0xa4, 0x27, 0x06, 0x3d, 0x15, 0x15, 0x0b, 0x91, 0x10, 0xff, 0xbd, 0x5d, 0xd3, 0x30, 0xac, - 0x25, 0xbd, 0x75, 0xde, 0xdd, 0x20, 0xf7, 0x46, 0x45, 0xdc, 0xe5, 0x89, 0x84, 0x56, 0x20, 0x85, - 0xf1, 0xa3, 0xf5, 0xc9, 0x24, 0x4c, 0x54, 0xb7, 0x34, 0x13, 0xcf, 0xed, 0x91, 0xc6, 0x76, 0x79, - 0x20, 0xf9, 0xed, 0x04, 0xa3, 0x97, 0x78, 0x81, 0x50, 0x20, 0xd5, 0xd4, 0x5b, 0xe7, 0xed, 0xed, - 0x39, 0xf2, 0xdf, 0x3d, 0xda, 0x9b, 0xec, 0x71, 0xb4, 0xd7, 0x31, 0xd1, 0x3a, 0xf5, 0xfa, 0xcc, - 0x7d, 0xde, 0x12, 0xea, 0x68, 0x6f, 0xdf, 0xe2, 0xe2, 0x67, 0xe3, 0x97, 0x93, 0x70, 0x2c, 0xd7, - 0x68, 0x9c, 0xd3, 0xad, 0xad, 0x8a, 0xcd, 0xa3, 0x7b, 0xc2, 0x6d, 0xaa, 0x4f, 0x43, 0xb6, 0xad, - 0xed, 0x35, 0x0d, 0xcd, 0x19, 0x58, 0x78, 0x10, 0x3d, 0x94, 0x8c, 0x38, 0xb0, 0x74, 0x51, 0xe0, - 0xc3, 0xd4, 0x48, 0x3a, 0x3d, 0xb8, 0xc8, 0xf8, 0x19, 0xfb, 0x17, 0x29, 0xc8, 0x54, 0xb1, 0x66, - 0xd6, 0xb7, 0xd0, 0x6b, 0x93, 0x2e, 0x43, 0xe7, 0x21, 0xbb, 0xa1, 0x37, 0x2d, 0x6c, 0x76, 0xe8, - 0xfa, 0xdf, 0x3b, 0x8f, 0x61, 0xe3, 0xd9, 0x5c, 0xd3, 0xa8, 0x9f, 0x9f, 0xcd, 0x13, 0xcd, 0xd2, - 0xb2, 0x66, 0xed, 0x73, 0x53, 0xb3, 0xf3, 0x34, 0x93, 0x6a, 0x67, 0x56, 0xee, 0x85, 0x74, 0xc7, - 0x30, 0x2d, 0x7b, 0xad, 0x76, 0x2a, 0x5c, 0x29, 0x55, 0xc3, 0xb4, 0x54, 0x96, 0x91, 0x40, 0xbb, - 0xb1, 0xd3, 0x6c, 0xd6, 0xf0, 0x45, 0xcb, 0x5e, 0x27, 0xd9, 0x61, 0xe5, 0x04, 0x64, 0x8c, 0x8d, - 0x8d, 0x0e, 0x66, 0x4b, 0xf1, 0xb4, 0xca, 0x43, 0xca, 0x71, 0x48, 0x37, 0xf5, 0x6d, 0xdd, 0xa2, - 0x2b, 0xee, 0xb4, 0xca, 0x02, 0xca, 0x29, 0x90, 0x0d, 0x67, 0x95, 0xc4, 0x08, 0x9d, 0xce, 0x50, - 0x5d, 0xb4, 0x2f, 0x9e, 0x74, 0xb9, 0xf3, 0x78, 0xaf, 0x33, 0x9d, 0xa5, 0xdf, 0xe9, 0x7f, 0xf4, - 0x78, 0x54, 0x2b, 0x3d, 0xe3, 0xab, 0xff, 0x92, 0xd1, 0xc4, 0x75, 0xc3, 0x6c, 0xd8, 0xbc, 0xf1, - 0x5f, 0x32, 0xf2, 0x74, 0xd1, 0x6c, 0xeb, 0x3d, 0x2b, 0x8f, 0x5f, 0x9e, 0x1e, 0xcf, 0x40, 0x7a, - 0xc1, 0xd4, 0xda, 0x5b, 0xe8, 0xad, 0x89, 0xe1, 0x8b, 0x93, 0x03, 0x6c, 0xb2, 0x1f, 0xb0, 0x52, - 0x1f, 0x60, 0x53, 0x1e, 0x60, 0x1f, 0x4d, 0x42, 0xaa, 0xd8, 0xd8, 0xc4, 0x82, 0xd1, 0x2b, 0xe1, - 0x31, 0x7a, 0x9d, 0x80, 0x8c, 0xa5, 0x99, 0x9b, 0xd8, 0xe2, 0x5c, 0xe2, 0x21, 0xc7, 0x33, 0x4a, - 0xf2, 0x9c, 0xaf, 0x7b, 0x21, 0xa4, 0x48, 0xbb, 0xa8, 0x44, 0x4e, 0x9d, 0xbe, 0xaa, 0x17, 0x34, - 0x94, 0x3f, 0xb3, 0xa4, 0xc6, 0x59, 0x42, 0x99, 0x4a, 0x33, 0x74, 0xe3, 0x91, 0xde, 0x87, 0x07, - 0x19, 0xdb, 0xf5, 0xba, 0xd1, 0x2a, 0x6d, 0x6b, 0x9b, 0x78, 0x3a, 0xc3, 0xc6, 0x76, 0x27, 0xc2, - 0xfe, 0x5a, 0xdc, 0x36, 0x1e, 0xd4, 0xa7, 0xb3, 0xee, 0x57, 0x1a, 0x41, 0x9a, 0xb0, 0xa5, 0x37, - 0x1a, 0xb8, 0x35, 0x3d, 0xc6, 0x4e, 0xa7, 0xb0, 0xd0, 0xcc, 0x49, 0x48, 0x11, 0x1a, 0x08, 0xc6, - 0x44, 0xb1, 0xcb, 0x47, 0x94, 0xa3, 0x44, 0xca, 0x99, 0x55, 0x52, 0x4e, 0xa0, 0xcf, 0x27, 0x23, - 0xee, 0x21, 0xb3, 0xc6, 0xf5, 0x96, 0xf9, 0x1b, 0x21, 0xdd, 0x32, 0x1a, 0xb8, 0xaf, 0xc4, 0xb3, - 0x54, 0xca, 0xf3, 0x20, 0x8d, 0x1b, 0x9b, 0xb8, 0x43, 0xc1, 0x9c, 0x38, 0x7d, 0x32, 0x98, 0x97, - 0x2a, 0x4b, 0x1c, 0x6d, 0xa3, 0xba, 0x17, 0xb5, 0xf1, 0x77, 0x92, 0xff, 0x95, 0x81, 0x63, 0xac, - 0x7f, 0x56, 0x77, 0xd6, 0x49, 0x51, 0xeb, 0x18, 0xbd, 0x5c, 0x12, 0x0e, 0xf4, 0x76, 0x76, 0xd6, - 0x9d, 0xb1, 0x8c, 0x05, 0xbc, 0x9d, 0x28, 0x39, 0x14, 0x9d, 0x2c, 0x0d, 0xaa, 0x93, 0x05, 0xfd, - 0x2a, 0xd9, 0xdd, 0xd0, 0xd5, 0xc6, 0x19, 0x1a, 0x6d, 0x6b, 0xe3, 0x1e, 0xba, 0x94, 0x0c, 0xca, - 0xda, 0x86, 0x85, 0xcd, 0x52, 0x83, 0xca, 0xe3, 0xb8, 0x6a, 0x07, 0x89, 0xbe, 0x5f, 0xc7, 0x1b, - 0x86, 0x49, 0x16, 0x82, 0xe3, 0x4c, 0xdf, 0xdb, 0x61, 0x4f, 0xff, 0x04, 0xc1, 0x28, 0x7d, 0x1d, - 0x1c, 0xd3, 0x37, 0x5b, 0x86, 0x89, 0x1d, 0xcf, 0x9e, 0xe9, 0xa3, 0xec, 0x24, 0x6a, 0x57, 0xb4, - 0x72, 0x03, 0x5c, 0xd2, 0x32, 0x0a, 0xb8, 0xcd, 0xf9, 0xce, 0x50, 0x9d, 0xa4, 0x3d, 0x62, 0xff, - 0x07, 0xf4, 0xb9, 0xa8, 0x2b, 0xcf, 0x2e, 0x50, 0x87, 0xa6, 0xfa, 0x95, 0x3b, 0xe0, 0x68, 0x83, - 0x7b, 0x0d, 0xd4, 0x75, 0xa7, 0x47, 0xf8, 0xe6, 0x13, 0x12, 0xbb, 0xe2, 0x94, 0xf2, 0x8a, 0xd3, - 0x02, 0x8c, 0x51, 0x57, 0x73, 0x22, 0x4f, 0xe9, 0xae, 0xc3, 0x8c, 0x74, 0xba, 0xed, 0x34, 0xca, - 0xc3, 0x92, 0xd9, 0x3c, 0xcf, 0xa2, 0x3a, 0x99, 0xa3, 0xcd, 0x77, 0x82, 0x39, 0x14, 0x7f, 0xd7, - 0xfb, 0x5b, 0x09, 0x4e, 0xd8, 0xea, 0x8d, 0xd1, 0x52, 0xd0, 0x3b, 0x96, 0xde, 0xaa, 0x5b, 0xa8, - 0x23, 0x38, 0x10, 0x9a, 0x3c, 0xd1, 0xfd, 0x78, 0xcf, 0x76, 0x20, 0xf4, 0x44, 0x0d, 0xab, 0x33, - 0xa2, 0x2f, 0x7a, 0xf5, 0x6b, 0x45, 0x14, 0xb1, 0x33, 0xbd, 0x18, 0xd8, 0x9b, 0x78, 0x1f, 0x49, - 0xcb, 0x43, 0x66, 0xd3, 0x34, 0x76, 0xda, 0x36, 0x91, 0xd7, 0x87, 0x23, 0x72, 0x81, 0xe4, 0x51, - 0x79, 0x56, 0xf4, 0x84, 0x83, 0xaf, 0x2a, 0xe0, 0x7b, 0xf7, 0xc0, 0xe4, 0x8d, 0xc0, 0x54, 0x91, - 0x82, 0xa3, 0x8e, 0x90, 0x95, 0x1a, 0x1d, 0x64, 0xf4, 0xd3, 0xae, 0xfb, 0x0c, 0x13, 0x8e, 0xde, - 0x92, 0x3c, 0x7a, 0xab, 0x87, 0xa6, 0x99, 0xe8, 0xa9, 0x69, 0xd0, 0x43, 0x52, 0xd8, 0xeb, 0x17, - 0xc4, 0x6e, 0x46, 0xc9, 0x7d, 0x26, 0x2b, 0x8e, 0x90, 0x97, 0x40, 0xf4, 0x6f, 0x55, 0xfc, 0x52, - 0xf0, 0x64, 0x12, 0x2e, 0x61, 0x82, 0xb8, 0xda, 0xea, 0x38, 0x23, 0xad, 0x78, 0x66, 0x97, 0xb6, - 0xa9, 0xe3, 0xec, 0x72, 0xd2, 0x90, 0x68, 0xd1, 0xbd, 0x4f, 0x04, 0xef, 0x79, 0xfe, 0x6a, 0xcd, - 0x53, 0x8b, 0xcf, 0xda, 0xf0, 0x0f, 0x1d, 0xde, 0x2d, 0x0b, 0xbc, 0x3b, 0x33, 0x48, 0xa1, 0xf1, - 0x33, 0xf0, 0x95, 0x12, 0x8c, 0x57, 0xb1, 0xb5, 0xa4, 0xed, 0x19, 0x3b, 0x16, 0xd2, 0xc2, 0x9a, - 0x99, 0x6e, 0x83, 0x4c, 0x93, 0x66, 0xa1, 0x33, 0xe3, 0xa9, 0xd3, 0x57, 0xf6, 0x34, 0x86, 0xd2, - 0xcd, 0x2a, 0x56, 0xb4, 0xca, 0xd3, 0xa3, 0x37, 0x46, 0x35, 0xa5, 0x3b, 0xd4, 0x0d, 0xc5, 0x0e, - 0x18, 0xc9, 0xd0, 0xee, 0x57, 0x75, 0xfc, 0xb0, 0xfc, 0xa6, 0x04, 0x93, 0xd4, 0xf5, 0x7e, 0x5e, - 0xdb, 0x35, 0x4c, 0xdd, 0xc2, 0xd1, 0x2c, 0x80, 0x4e, 0x36, 0x7e, 0xbe, 0xc0, 0x13, 0x83, 0xde, - 0x99, 0x8c, 0xb8, 0xc5, 0x26, 0xd0, 0x31, 0x14, 0x10, 0x22, 0x6d, 0xc8, 0x05, 0x55, 0x3f, 0x42, - 0x20, 0x72, 0x66, 0x7d, 0x4b, 0xdf, 0xc5, 0x8d, 0x88, 0x40, 0xd8, 0xd9, 0x5c, 0x20, 0x9c, 0x82, - 0x06, 0x03, 0xc2, 0xce, 0x7e, 0x48, 0x40, 0xf8, 0x54, 0x1f, 0x3f, 0x10, 0x6f, 0x67, 0x40, 0x78, - 0x7c, 0x0d, 0x96, 0xc3, 0x02, 0x71, 0x35, 0x4c, 0xba, 0x56, 0x82, 0x55, 0xb3, 0xc9, 0x57, 0xf3, - 0x62, 0x24, 0xfa, 0xf4, 0x00, 0x70, 0xf4, 0x75, 0x1b, 0x88, 0x06, 0xc7, 0xa7, 0x22, 0xc2, 0xf1, - 0x4c, 0x75, 0x09, 0x78, 0x4a, 0x62, 0x27, 0xa4, 0x04, 0xcf, 0x8c, 0x07, 0xc3, 0xc2, 0xb5, 0xcf, - 0x0b, 0x24, 0x1b, 0xd9, 0x0b, 0xe4, 0xb3, 0x51, 0xbd, 0x40, 0xba, 0xa9, 0x1d, 0x0a, 0x9c, 0x91, - 0x9c, 0x3c, 0xfa, 0x50, 0x70, 0xc8, 0x88, 0x7e, 0x57, 0x02, 0xa0, 0x77, 0x7f, 0x32, 0xff, 0xa5, - 0x45, 0xc8, 0xb0, 0xbf, 0xb6, 0x13, 0x64, 0xc2, 0x75, 0x82, 0xbc, 0x01, 0xd2, 0xbb, 0x5a, 0x73, - 0x07, 0x3b, 0x3c, 0xea, 0x9e, 0x88, 0x9e, 0x25, 0x5f, 0x55, 0x96, 0x08, 0x6d, 0x85, 0x95, 0x8a, - 0x7b, 0xbc, 0x0e, 0x38, 0x44, 0x1e, 0xae, 0xf1, 0xe1, 0x22, 0xa7, 0x71, 0x96, 0xfd, 0xba, 0x3e, - 0x57, 0x6f, 0x8e, 0xea, 0x10, 0xe1, 0x29, 0x6b, 0x18, 0xd2, 0x10, 0xc9, 0x45, 0xc2, 0xb7, 0xee, - 0xf8, 0x15, 0xed, 0x67, 0x93, 0x90, 0xae, 0x19, 0x55, 0x2c, 0x9c, 0x1f, 0x0b, 0xc6, 0xc6, 0xb5, - 0xda, 0x24, 0xbd, 0x56, 0x9b, 0x08, 0x17, 0xb0, 0x3a, 0x9e, 0x21, 0xfe, 0x0e, 0x7b, 0x64, 0xa9, - 0x82, 0xdd, 0xad, 0x7c, 0x16, 0x88, 0x66, 0x0b, 0xec, 0x55, 0x7c, 0xfc, 0x0c, 0x3d, 0x03, 0xc7, - 0x56, 0x5b, 0x0d, 0x43, 0xc5, 0x0d, 0x83, 0xdb, 0x56, 0xc8, 0xc2, 0x73, 0xa7, 0xd5, 0x30, 0x28, - 0xad, 0x69, 0x95, 0xfe, 0x27, 0x71, 0x26, 0x6e, 0x18, 0xdc, 0xf0, 0x4d, 0xff, 0xa3, 0xd7, 0x49, - 0x90, 0x22, 0x79, 0xc3, 0x7b, 0xaa, 0x7c, 0x2f, 0xea, 0x41, 0x13, 0x52, 0xfc, 0x30, 0xe4, 0x5b, - 0xb9, 0xc7, 0x63, 0x6d, 0x62, 0x9b, 0xbc, 0x57, 0xf9, 0xd5, 0xe7, 0x61, 0x85, 0xc7, 0xca, 0xf4, - 0x44, 0x94, 0xc3, 0x29, 0x3d, 0xc8, 0x8e, 0x86, 0x64, 0x61, 0x00, 0x15, 0x29, 0xc3, 0xd1, 0x7c, - 0xae, 0x4c, 0x6f, 0x4b, 0x58, 0xae, 0x9c, 0x2d, 0xca, 0x12, 0x05, 0x88, 0xb4, 0x26, 0x46, 0x80, - 0x48, 0xf1, 0xff, 0x04, 0x01, 0xea, 0x41, 0xf6, 0x61, 0x00, 0xf4, 0x99, 0x24, 0x4c, 0x2e, 0xe9, - 0x1d, 0xcb, 0xcf, 0xe9, 0xcb, 0xde, 0x44, 0xb6, 0xed, 0x03, 0x6e, 0x84, 0x78, 0xd1, 0x76, 0x98, - 0x09, 0xa1, 0x50, 0x8f, 0x0f, 0x64, 0xfb, 0xbd, 0x63, 0x22, 0xcd, 0xc1, 0x83, 0xaa, 0x18, 0x8d, - 0x77, 0x22, 0xa5, 0x80, 0x5d, 0x8d, 0x16, 0x9a, 0x93, 0x91, 0x87, 0x5e, 0xb7, 0x92, 0xd1, 0x0f, - 0xbd, 0xbe, 0x75, 0x8f, 0xc0, 0x74, 0x9d, 0x84, 0x4b, 0x48, 0xf5, 0x41, 0x0b, 0x4e, 0x7f, 0x36, - 0xf7, 0x5d, 0x70, 0x46, 0xb6, 0x79, 0xed, 0xa3, 0x65, 0x18, 0x36, 0xaf, 0x7e, 0x85, 0x8e, 0x98, - 0xcd, 0x3e, 0x06, 0x96, 0x7e, 0x6c, 0x0e, 0x30, 0xb0, 0x0c, 0xce, 0xe6, 0x60, 0x23, 0xcb, 0x80, - 0x6c, 0x3e, 0x34, 0xd3, 0xc9, 0x57, 0x93, 0x30, 0x99, 0x6b, 0xb7, 0x9b, 0x7b, 0x35, 0x7e, 0x12, - 0x24, 0x92, 0xe9, 0xc4, 0x73, 0xa0, 0x24, 0xb9, 0xef, 0x38, 0x65, 0x64, 0x37, 0x71, 0x81, 0x8e, - 0x61, 0xb8, 0x89, 0x07, 0x15, 0x18, 0x3f, 0x6b, 0x5f, 0x92, 0x66, 0x8a, 0x98, 0x5f, 0xf4, 0xf0, - 0xe5, 0x44, 0xf0, 0x4d, 0x0f, 0x82, 0x3c, 0x27, 0xbb, 0xe5, 0xf9, 0x2e, 0xc8, 0x6c, 0x18, 0xe6, - 0xb6, 0x66, 0xdb, 0x72, 0xaf, 0xf1, 0x13, 0x27, 0x7e, 0x97, 0xc2, 0x3c, 0x4d, 0xac, 0xf2, 0x4c, - 0x64, 0x44, 0x7b, 0x91, 0xde, 0xe6, 0x67, 0xa1, 0xc9, 0x5f, 0x7a, 0xc9, 0x09, 0x3b, 0x12, 0x5d, - 0xc6, 0x1d, 0x0b, 0x37, 0xe8, 0xe6, 0xe3, 0x98, 0x2a, 0x46, 0x2a, 0x33, 0x70, 0x94, 0x47, 0xcc, - 0xeb, 0x4d, 0xdc, 0xa1, 0x5b, 0xca, 0x63, 0xaa, 0x10, 0x87, 0xbe, 0x30, 0xc8, 0xc0, 0x11, 0xf9, - 0x06, 0x8a, 0x69, 0xc8, 0x76, 0x76, 0xea, 0x75, 0x8c, 0x1b, 0xdc, 0xcb, 0xc8, 0x0e, 0x46, 0xf4, - 0x5a, 0x8c, 0x3c, 0xcc, 0x1c, 0xce, 0xe5, 0x14, 0x33, 0x2b, 0x90, 0x61, 0x18, 0x2a, 0x47, 0x61, - 0xcc, 0xf6, 0x9b, 0x64, 0x7e, 0x21, 0x2b, 0x7c, 0x91, 0x2e, 0x27, 0x48, 0x89, 0xf7, 0x55, 0x2b, - 0x65, 0x76, 0x61, 0x57, 0xa1, 0xc2, 0x2f, 0xec, 0xaa, 0x9e, 0x5d, 0x90, 0x53, 0xca, 0x14, 0xc0, - 0x82, 0x9a, 0x5b, 0x59, 0x5c, 0xa3, 0x29, 0xd2, 0xe8, 0xa9, 0x2c, 0x64, 0x98, 0x1b, 0x26, 0x7a, - 0x32, 0xed, 0x7d, 0x30, 0xe5, 0x68, 0xcb, 0x20, 0x64, 0xae, 0x68, 0xa6, 0xb6, 0xdd, 0x09, 0xda, - 0x1b, 0x63, 0xb9, 0x9d, 0xc7, 0x52, 0xca, 0x9e, 0x6c, 0x8b, 0x47, 0x54, 0xa1, 0x18, 0xe5, 0x5f, - 0xc0, 0xb1, 0x75, 0x7e, 0x80, 0xa0, 0xc3, 0x4b, 0x4e, 0xfa, 0xef, 0xd8, 0x77, 0x95, 0x3c, 0x27, - 0xe6, 0x5c, 0x3c, 0xa2, 0x76, 0x17, 0xa6, 0x94, 0x60, 0xbc, 0xd3, 0xd2, 0xda, 0x9d, 0x2d, 0xc3, - 0x71, 0xa1, 0xb8, 0x3e, 0x44, 0xc9, 0x55, 0x9e, 0x47, 0x75, 0x73, 0x2b, 0xcf, 0x83, 0x67, 0xed, - 0xd0, 0x1b, 0xde, 0x8a, 0x17, 0xe9, 0x46, 0xe9, 0xa6, 0x78, 0x75, 0x40, 0xef, 0x8f, 0xca, 0x1d, - 0xdc, 0xc3, 0x28, 0x4d, 0xc5, 0xe7, 0xb9, 0x21, 0xea, 0xf6, 0x78, 0x19, 0xdd, 0x01, 0xa9, 0x6d, - 0x22, 0x7b, 0x99, 0xd0, 0x99, 0x97, 0xa9, 0xc0, 0x91, 0x4c, 0x68, 0x06, 0x8e, 0x7a, 0x59, 0xdf, - 0x4b, 0x9b, 0xa0, 0xab, 0xe0, 0x58, 0x17, 0x13, 0xed, 0xe3, 0x27, 0x09, 0xf7, 0xf8, 0xc9, 0x2f, - 0xc1, 0x98, 0xcd, 0x8f, 0x7d, 0xf7, 0xb4, 0xe6, 0x60, 0xcc, 0xe6, 0x10, 0x07, 0xee, 0x9a, 0x2e, - 0xdb, 0x5e, 0x75, 0x5b, 0x33, 0x2d, 0xba, 0x75, 0x6d, 0x17, 0x32, 0xa7, 0x75, 0xb0, 0xea, 0x64, - 0x9b, 0xb9, 0x11, 0x52, 0x84, 0x6a, 0x45, 0x81, 0xa9, 0xdc, 0xd2, 0xd2, 0x5a, 0x85, 0xde, 0x11, - 0xbc, 0x58, 0x2a, 0x2f, 0xb0, 0x0e, 0x50, 0x5a, 0x28, 0x57, 0xd4, 0x22, 0x93, 0xff, 0xaa, 0x9c, - 0x98, 0xb9, 0x92, 0xfb, 0x40, 0x01, 0x64, 0x58, 0xf3, 0x98, 0xb4, 0x17, 0x2f, 0x32, 0x83, 0x9b, - 0x4c, 0xaf, 0x2e, 0x6f, 0xd3, 0xb6, 0x88, 0x46, 0x8b, 0x30, 0x4e, 0x80, 0x0e, 0x37, 0x7b, 0x0d, - 0x2a, 0x1f, 0x88, 0xe2, 0xd1, 0xd7, 0xb3, 0xa4, 0x68, 0xfa, 0x60, 0x7e, 0x9f, 0x3e, 0x50, 0x60, - 0xaa, 0x54, 0xae, 0x15, 0xd5, 0x72, 0x6e, 0xc9, 0x51, 0x08, 0xfb, 0x74, 0x44, 0x52, 0xd4, 0x11, - 0x12, 0xfa, 0x86, 0x04, 0xc0, 0xc8, 0x21, 0x8a, 0xca, 0x7b, 0xbd, 0xda, 0x97, 0xa3, 0xea, 0x64, - 0xb7, 0x18, 0x1f, 0x9d, 0x5c, 0x82, 0x31, 0x93, 0x7f, 0xe0, 0xb6, 0xbd, 0x7e, 0xe5, 0xb0, 0xbf, - 0x76, 0x69, 0xaa, 0x93, 0x1d, 0x7d, 0x38, 0x8a, 0x0a, 0xf6, 0x25, 0xec, 0x70, 0x58, 0xde, 0xb4, - 0xbd, 0xfe, 0x3d, 0x33, 0x1b, 0xa6, 0x07, 0xc2, 0xb5, 0x41, 0xcc, 0xec, 0x51, 0x09, 0x33, 0xca, - 0x7e, 0xf1, 0x47, 0x1f, 0x3f, 0x06, 0x53, 0xac, 0x0c, 0xe7, 0x00, 0xfe, 0x3f, 0x24, 0x41, 0xca, - 0x35, 0x84, 0xbb, 0xcc, 0x82, 0xa7, 0x69, 0x33, 0x70, 0xd4, 0xe3, 0x31, 0xe3, 0x5c, 0x8c, 0xe7, - 0x8d, 0x13, 0x5f, 0x55, 0x09, 0x7c, 0xae, 0x4a, 0xa4, 0x66, 0x36, 0xd7, 0x18, 0xce, 0x1e, 0x57, - 0x14, 0x0f, 0xf8, 0x80, 0xca, 0x47, 0x73, 0x73, 0x17, 0x5f, 0x59, 0x97, 0xc2, 0x22, 0xd0, 0xe5, - 0xc6, 0x94, 0xdc, 0xe7, 0xc6, 0x14, 0xf9, 0xf0, 0x8d, 0xc3, 0x82, 0x70, 0xeb, 0xef, 0xa1, 0x1f, - 0xe7, 0x08, 0xae, 0x3f, 0x7e, 0x14, 0x7e, 0xca, 0x0d, 0x46, 0xb9, 0x5d, 0x4d, 0x6f, 0x6a, 0xeb, - 0xcd, 0x08, 0xa7, 0x04, 0x3f, 0xe9, 0x65, 0x75, 0x59, 0x64, 0xf5, 0x6d, 0x41, 0x4d, 0x15, 0xea, - 0xf3, 0xbd, 0x15, 0x7e, 0xdc, 0x86, 0xd5, 0xf5, 0x0d, 0x12, 0x47, 0x4d, 0xbb, 0x3c, 0xd5, 0x4d, - 0x89, 0xde, 0xe3, 0xb0, 0xfe, 0xe7, 0x05, 0xd6, 0xdf, 0x35, 0x28, 0x3d, 0xf1, 0x23, 0xf0, 0x52, - 0x09, 0x26, 0x72, 0x8d, 0xc6, 0x3c, 0xd6, 0xac, 0x1d, 0x13, 0x37, 0x50, 0x31, 0x6c, 0x67, 0xb8, - 0xbc, 0x9b, 0x45, 0xe3, 0x5e, 0x4e, 0x7c, 0x28, 0xf4, 0xa5, 0x8a, 0xfb, 0x75, 0x81, 0x4d, 0xcb, - 0x50, 0x14, 0x52, 0xb8, 0x2b, 0x18, 0x43, 0x13, 0x11, 0x3f, 0x20, 0xaf, 0x92, 0x60, 0x4a, 0xa5, - 0x57, 0x92, 0x0f, 0x1b, 0x93, 0x8f, 0x46, 0xf4, 0x8d, 0xf4, 0x5c, 0x7d, 0xe2, 0x25, 0x67, 0x28, - 0xb0, 0x44, 0x71, 0x82, 0x0c, 0x47, 0x47, 0xfc, 0xc8, 0x7c, 0x1f, 0x00, 0x3c, 0x1e, 0x11, 0xdf, - 0x00, 0xd7, 0xb3, 0x1f, 0x7d, 0x56, 0x62, 0xa3, 0x79, 0x55, 0x38, 0xc0, 0x29, 0x3a, 0x42, 0x24, - 0x7a, 0x38, 0x42, 0x84, 0x1a, 0xd5, 0x7f, 0x18, 0x71, 0x83, 0x9d, 0xfb, 0x28, 0xf4, 0x1d, 0xda, - 0x07, 0xd4, 0x72, 0x4f, 0x47, 0xd8, 0x69, 0xef, 0x47, 0x4a, 0xfc, 0x8f, 0x60, 0x04, 0xed, 0xb4, - 0x2b, 0xd3, 0x70, 0x5c, 0x2d, 0xe6, 0x0a, 0x95, 0xf2, 0xd2, 0x03, 0xde, 0xaf, 0x72, 0x0a, 0xbd, - 0x5e, 0x82, 0x0c, 0x93, 0xb7, 0x78, 0x30, 0xfd, 0x0f, 0x11, 0x15, 0xa4, 0xc8, 0x48, 0x46, 0x99, - 0xcf, 0x2a, 0xe8, 0x3f, 0x45, 0x50, 0x79, 0x21, 0x8a, 0x7d, 0xc6, 0x42, 0xf4, 0x75, 0x09, 0x52, - 0x74, 0xbd, 0xb4, 0x13, 0x15, 0xa0, 0x02, 0x5c, 0xa1, 0xb5, 0xdb, 0xb8, 0xd5, 0x70, 0x6e, 0x11, - 0x9c, 0x37, 0x8d, 0xed, 0x8a, 0xb5, 0x85, 0x4d, 0x92, 0xa4, 0xc3, 0xed, 0xcc, 0xc1, 0x89, 0xd0, - 0xd7, 0x23, 0x9a, 0x9e, 0x45, 0x5e, 0x07, 0x2c, 0xd1, 0xce, 0xec, 0xef, 0x97, 0x97, 0xf9, 0xf4, - 0xcb, 0x25, 0xbd, 0x75, 0xde, 0xdb, 0x37, 0xff, 0x2c, 0x82, 0xd5, 0xba, 0x2f, 0x3d, 0x87, 0xec, - 0x06, 0xf3, 0x50, 0xc6, 0xa3, 0x60, 0x7f, 0x4b, 0x02, 0x99, 0x90, 0xc8, 0x44, 0x94, 0x5f, 0x85, - 0x55, 0x11, 0x77, 0x11, 0x68, 0xa4, 0x77, 0x17, 0xc1, 0x8e, 0x50, 0xae, 0x85, 0xa9, 0xfa, 0x16, - 0xae, 0x9f, 0x2f, 0xb5, 0x6c, 0x93, 0x10, 0x43, 0xb8, 0x2b, 0x56, 0xf4, 0x97, 0xbd, 0x5f, 0x84, - 0x54, 0xb4, 0x4c, 0x0b, 0x7c, 0xf3, 0x12, 0xe5, 0xd3, 0x29, 0x5d, 0x60, 0xca, 0x02, 0x30, 0xb7, - 0x0f, 0x54, 0x6a, 0x34, 0x64, 0xca, 0x83, 0x3d, 0x59, 0x50, 0x59, 0xa1, 0x6f, 0x7c, 0xad, 0x56, - 0x8b, 0x85, 0xb5, 0x39, 0xbb, 0xf3, 0x55, 0x65, 0x09, 0x7d, 0x37, 0x09, 0x59, 0x46, 0x56, 0xa7, - 0xeb, 0x9a, 0xe8, 0xe0, 0x53, 0x1e, 0xe8, 0xdd, 0xa1, 0xdd, 0x91, 0x1d, 0x46, 0xf0, 0x7a, 0x7c, - 0x7a, 0xca, 0x6d, 0x90, 0x65, 0x20, 0xdb, 0x46, 0xc9, 0x93, 0x3e, 0xfd, 0x84, 0x17, 0xa3, 0xda, - 0xc9, 0x43, 0xba, 0x26, 0xf7, 0x21, 0x23, 0xfe, 0x39, 0xc7, 0x5b, 0x26, 0x20, 0xbb, 0xa8, 0x77, - 0x2c, 0xc3, 0xdc, 0x43, 0x6f, 0x4e, 0x40, 0x96, 0x3f, 0xef, 0xbd, 0xcf, 0xca, 0x77, 0x25, 0x4c, - 0xb4, 0x4d, 0xbc, 0xab, 0x1b, 0x3b, 0x1d, 0xcf, 0x9d, 0x00, 0x9e, 0x28, 0x05, 0xc1, 0x98, 0xb6, - 0x63, 0x6d, 0x19, 0xa6, 0x7b, 0x41, 0x92, 0x1d, 0x56, 0x4e, 0x02, 0xb0, 0xff, 0x65, 0x6d, 0x1b, - 0xf3, 0xd3, 0x09, 0x9e, 0x18, 0x45, 0x81, 0x94, 0xa5, 0x6f, 0x63, 0x7e, 0x3e, 0x8d, 0xfe, 0x57, - 0xa6, 0x21, 0x4b, 0x0f, 0xb4, 0x94, 0x1a, 0xfc, 0x7c, 0x9a, 0x1d, 0x44, 0x6f, 0x93, 0x60, 0xc2, - 0x7d, 0x89, 0xbc, 0xe3, 0xf5, 0x73, 0xef, 0x73, 0x5b, 0x7b, 0x53, 0xeb, 0xd8, 0xd9, 0x9c, 0x9d, - 0x28, 0x31, 0xd2, 0x3d, 0x2b, 0x27, 0x79, 0x8e, 0xac, 0xa2, 0x0f, 0x24, 0xc3, 0x9e, 0x0e, 0xe1, - 0xcc, 0xf4, 0x3c, 0x95, 0xee, 0x2f, 0x5b, 0x63, 0xfc, 0x6d, 0x76, 0x5b, 0x09, 0x5f, 0xde, 0xb3, - 0x24, 0x5e, 0x8c, 0xea, 0xa4, 0x0e, 0x79, 0xa2, 0xa3, 0x3f, 0x25, 0xf1, 0x8b, 0xd7, 0x8f, 0x24, - 0x98, 0xa8, 0x6e, 0x19, 0x17, 0xec, 0x87, 0xef, 0x7f, 0x29, 0x1c, 0x54, 0x97, 0xc3, 0xf8, 0x6e, - 0x17, 0x4c, 0x6e, 0x84, 0xff, 0x45, 0xbf, 0xe8, 0x11, 0x29, 0x2a, 0x4c, 0x1e, 0xe2, 0x86, 0x7e, - 0x41, 0xaf, 0xf2, 0x02, 0xf7, 0x31, 0x7e, 0x66, 0x59, 0x09, 0x06, 0xd8, 0xfb, 0x54, 0xbf, 0xdd, - 0xc0, 0x94, 0xd8, 0xc0, 0x68, 0xc8, 0xfb, 0x37, 0x6e, 0x04, 0x17, 0x15, 0x24, 0xa9, 0x8f, 0xa9, - 0x0d, 0x7c, 0x7e, 0x08, 0xc0, 0xa3, 0x1f, 0x27, 0xc2, 0x5a, 0x1f, 0x1d, 0x0e, 0x38, 0x14, 0x1c, - 0xe8, 0x46, 0x8d, 0xbe, 0xc5, 0xc5, 0xcf, 0xcf, 0x5f, 0xbb, 0x04, 0x52, 0xf3, 0x7a, 0x13, 0x93, - 0xf5, 0x7b, 0xb6, 0xb2, 0xb1, 0x41, 0x6f, 0xc4, 0x28, 0xfa, 0x3f, 0x9f, 0x77, 0x0a, 0x64, 0x7b, - 0x87, 0xd6, 0xb0, 0x56, 0xf4, 0x56, 0xcb, 0x71, 0x22, 0xd9, 0x17, 0x2f, 0x9a, 0xba, 0x02, 0x3d, - 0x3b, 0x09, 0x05, 0xb3, 0xbc, 0x76, 0x9f, 0xfe, 0x72, 0x2d, 0x4c, 0xad, 0xef, 0x59, 0xb8, 0xc3, - 0x53, 0xf1, 0x6a, 0x53, 0x6a, 0x57, 0x2c, 0x7a, 0x2a, 0x94, 0xaf, 0x67, 0x40, 0x85, 0xd1, 0x78, - 0xae, 0x0d, 0xe9, 0x09, 0xfe, 0x4d, 0xfa, 0xb8, 0x56, 0x69, 0x89, 0xc5, 0x3e, 0x50, 0xac, 0xad, - 0xad, 0x94, 0xca, 0xe5, 0x62, 0x41, 0xde, 0x42, 0x1f, 0x91, 0x60, 0x82, 0xcc, 0xab, 0x6c, 0x74, - 0x2a, 0xc2, 0xdb, 0x64, 0x46, 0xab, 0xb9, 0xe7, 0xce, 0x1d, 0xed, 0x60, 0x24, 0x9c, 0xfe, 0x63, - 0xe8, 0xe9, 0x0d, 0x65, 0x9b, 0x87, 0x16, 0x7f, 0xac, 0x36, 0xf4, 0x66, 0x37, 0x56, 0x69, 0xb5, - 0x2b, 0xb6, 0x07, 0xa6, 0x52, 0x4f, 0x4c, 0xff, 0x38, 0xd4, 0xa4, 0xa7, 0x0f, 0x71, 0xd1, 0x70, - 0x5d, 0x1c, 0x16, 0xae, 0xe8, 0x07, 0x12, 0x64, 0x56, 0xdb, 0x14, 0xb9, 0xa7, 0x3d, 0x2e, 0x18, - 0xfb, 0x76, 0x43, 0x89, 0x92, 0x6a, 0x8a, 0x8f, 0x31, 0xab, 0x6e, 0x84, 0x72, 0x3b, 0xdf, 0xe6, - 0x61, 0xee, 0x17, 0xd7, 0x06, 0x9e, 0xe0, 0xa5, 0x9c, 0xf0, 0xec, 0xf6, 0xde, 0x00, 0x97, 0x34, - 0xf4, 0x8e, 0xb6, 0xde, 0xc4, 0xc5, 0x56, 0xdd, 0xdc, 0x63, 0x8d, 0x66, 0x9b, 0xcb, 0xfb, 0x3f, - 0x28, 0x77, 0x41, 0xba, 0x63, 0xed, 0x35, 0xf7, 0xef, 0x2c, 0xfb, 0x56, 0x55, 0x25, 0xc9, 0x55, - 0x96, 0x0b, 0xfd, 0x34, 0x11, 0xd6, 0x77, 0x95, 0xe6, 0x65, 0xac, 0xf1, 0x77, 0xc4, 0xd8, 0xd2, - 0x3a, 0x8e, 0x23, 0x06, 0xf9, 0x8f, 0x1e, 0x0b, 0xe5, 0x60, 0xea, 0x5f, 0x76, 0xfc, 0x3a, 0xf5, - 0x6b, 0x49, 0x18, 0x2b, 0x18, 0x17, 0x5a, 0x14, 0xf3, 0x5b, 0x04, 0xaf, 0x1b, 0xda, 0x9a, 0x84, - 0xdb, 0x9a, 0x5e, 0xae, 0x26, 0xe8, 0xdf, 0x86, 0xde, 0x5c, 0xa6, 0xad, 0xb4, 0xab, 0xf2, 0xe1, - 0x61, 0xa0, 0x58, 0x79, 0x4c, 0xff, 0x41, 0x5b, 0xcf, 0x41, 0xf5, 0x44, 0xe3, 0x67, 0xee, 0xc0, - 0xd7, 0xfd, 0xa3, 0xa7, 0x24, 0x48, 0x15, 0x4c, 0xa3, 0x8d, 0xfe, 0x28, 0x11, 0x61, 0x0f, 0xb2, - 0x61, 0x1a, 0xed, 0x1a, 0xbd, 0xaf, 0xc5, 0x99, 0x02, 0x08, 0x71, 0xca, 0x19, 0x18, 0x6b, 0x1b, - 0x1d, 0xdd, 0xb2, 0xa7, 0x55, 0x53, 0xfb, 0xde, 0xd4, 0x65, 0x92, 0xbf, 0xc2, 0x13, 0xa9, 0x4e, - 0x72, 0xa2, 0xc7, 0x28, 0x47, 0x09, 0x9b, 0x08, 0x57, 0xed, 0x7b, 0x65, 0xba, 0x62, 0xd1, 0xef, - 0x7b, 0x81, 0xbd, 0x43, 0x04, 0xf6, 0x9a, 0x1e, 0x0c, 0x37, 0xfd, 0x1e, 0xe9, 0x8c, 0x68, 0xb5, - 0x7e, 0xad, 0x03, 0xf2, 0xdd, 0x02, 0xc8, 0xa7, 0x42, 0xd5, 0x19, 0x7f, 0x87, 0xf9, 0x5e, 0x16, - 0xa0, 0xac, 0xed, 0xea, 0x9b, 0xcc, 0x66, 0xf2, 0x15, 0x7b, 0xc0, 0xe3, 0xd6, 0x8d, 0x97, 0x7a, - 0x70, 0x3e, 0x03, 0x59, 0x0e, 0x2b, 0x6f, 0xc3, 0x73, 0x84, 0x36, 0xb8, 0xa5, 0x30, 0x0d, 0x75, - 0xd1, 0x52, 0xed, 0xf4, 0xc2, 0x15, 0x52, 0xc9, 0xae, 0x2b, 0xa4, 0x7a, 0x2e, 0xcf, 0xfc, 0x2e, - 0x96, 0x42, 0x1f, 0x0c, 0x7d, 0x63, 0x98, 0x87, 0x1e, 0x4f, 0x8b, 0x7c, 0x40, 0xbd, 0x15, 0xb2, - 0x86, 0x63, 0xe6, 0x91, 0x7c, 0xd7, 0x03, 0xa5, 0xd6, 0x86, 0xa1, 0xda, 0x29, 0x43, 0x5e, 0xbb, - 0x11, 0x8a, 0x8e, 0xf8, 0x81, 0xfe, 0x9c, 0x04, 0x27, 0x16, 0xec, 0x23, 0x89, 0xa4, 0x1d, 0xe7, - 0x74, 0x6b, 0x6b, 0x49, 0x6f, 0x9d, 0xef, 0xa0, 0x7f, 0x19, 0x6e, 0x26, 0xef, 0xc1, 0x3f, 0x19, - 0x0d, 0x7f, 0xd1, 0x4f, 0xb0, 0x2a, 0xa2, 0x76, 0x97, 0x5f, 0x29, 0xbd, 0xa9, 0xf5, 0x01, 0xf0, - 0x76, 0xc8, 0x30, 0x42, 0x79, 0xb7, 0x9c, 0xf1, 0xc5, 0xcf, 0x29, 0x49, 0xe5, 0x39, 0x3c, 0x3e, - 0x40, 0x67, 0x05, 0x1c, 0xe7, 0x0e, 0x44, 0x59, 0xfc, 0x7e, 0x82, 0xb7, 0x40, 0x96, 0x73, 0x5a, - 0x99, 0xf2, 0xf6, 0x62, 0xf9, 0x88, 0x02, 0x90, 0x59, 0x36, 0x76, 0x71, 0xcd, 0x90, 0x13, 0xe4, - 0x3f, 0xa1, 0xaf, 0x66, 0xc8, 0x49, 0xf4, 0x5f, 0x00, 0xc6, 0x1c, 0x77, 0xdf, 0x2f, 0x25, 0xed, - 0x1b, 0xc2, 0xa9, 0x99, 0x9a, 0x31, 0x23, 0xf4, 0x6e, 0xfa, 0xab, 0x42, 0x1b, 0x3e, 0x1d, 0x37, - 0xdc, 0xee, 0xca, 0x42, 0x5e, 0xbe, 0xfb, 0xae, 0x50, 0x86, 0xd0, 0xb0, 0xb5, 0xc4, 0xdf, 0xd5, - 0xbe, 0x9d, 0xb4, 0xdf, 0x61, 0x70, 0x89, 0xa0, 0xfb, 0x7f, 0xe2, 0xbb, 0xd2, 0xee, 0x06, 0x03, - 0x67, 0xae, 0x27, 0x46, 0x7c, 0x5c, 0x34, 0x70, 0xe7, 0xd5, 0xb7, 0xdd, 0x01, 0xc7, 0x9e, 0xbb, - 0x39, 0x1c, 0x6e, 0x6f, 0x35, 0x4a, 0x4d, 0xf1, 0x73, 0xf9, 0xfd, 0xec, 0xa9, 0xae, 0x56, 0x04, - 0x07, 0x10, 0xe1, 0xba, 0xc9, 0xc0, 0xe7, 0xe5, 0xdd, 0xa6, 0x92, 0x1a, 0x42, 0x72, 0xf1, 0xf1, - 0x50, 0x2f, 0xfc, 0x07, 0x16, 0x1d, 0x3f, 0xdb, 0xbe, 0x9b, 0x84, 0x71, 0xe6, 0xd7, 0x9c, 0x6b, - 0x36, 0xbb, 0x1e, 0x19, 0xdd, 0xe7, 0x4a, 0xfa, 0xef, 0x43, 0x3b, 0x87, 0x39, 0xad, 0x72, 0xca, - 0x8e, 0xed, 0x89, 0xc1, 0x70, 0x06, 0x9e, 0xbe, 0x04, 0x8d, 0xe4, 0xca, 0xd4, 0x09, 0xa2, 0x79, - 0x57, 0x4c, 0xbc, 0xab, 0xe3, 0x0b, 0xe8, 0xb2, 0x80, 0x25, 0x28, 0x7a, 0x7b, 0xe8, 0x73, 0x87, - 0x9e, 0x22, 0x7d, 0x78, 0x7c, 0x27, 0x4c, 0x34, 0xdd, 0x44, 0x7c, 0x44, 0x44, 0x5d, 0x23, 0xa2, - 0xa7, 0x18, 0xd5, 0x9b, 0x3c, 0xe4, 0x2a, 0xcf, 0x9f, 0x8a, 0xf8, 0x19, 0xfb, 0x9d, 0x0c, 0x8c, - 0xad, 0xb6, 0x3a, 0xed, 0x26, 0x59, 0x94, 0xfe, 0x83, 0xe4, 0xdc, 0x9f, 0xfa, 0x7c, 0xe1, 0x8a, - 0xa9, 0x5f, 0xde, 0xc1, 0xa6, 0xbd, 0xa7, 0xc4, 0x02, 0xbd, 0x6f, 0xaf, 0x44, 0x7f, 0xec, 0xb5, - 0x31, 0xe7, 0x44, 0xd6, 0x8b, 0x8e, 0xe5, 0x76, 0xa5, 0xc1, 0x17, 0x8b, 0x96, 0x60, 0xac, 0xad, - 0xd7, 0xad, 0x1d, 0xd3, 0xb9, 0x67, 0xf1, 0xc6, 0x70, 0xa5, 0xac, 0xb0, 0x5c, 0xaa, 0x93, 0x1d, - 0x69, 0x90, 0xe5, 0x91, 0xfb, 0xcc, 0x81, 0xfb, 0x9e, 0x14, 0x20, 0x73, 0x66, 0xcd, 0xb4, 0xf4, - 0x8e, 0x7d, 0x4d, 0x2b, 0x0f, 0x11, 0xa5, 0xc8, 0xfe, 0xad, 0x9a, 0x4d, 0x6e, 0x7e, 0x76, 0x23, - 0xd0, 0x47, 0x1c, 0xb8, 0x0b, 0x02, 0xdc, 0x37, 0x47, 0x68, 0x79, 0x34, 0xc8, 0xef, 0x1f, 0xec, - 0xfd, 0x7b, 0x95, 0xbe, 0x49, 0x5f, 0x5a, 0x2e, 0xd5, 0xd6, 0x8a, 0xbf, 0x90, 0x2f, 0x16, 0x0b, - 0xc5, 0x82, 0xdc, 0xa0, 0xaf, 0x13, 0x39, 0x2b, 0x7e, 0x71, 0x24, 0xe0, 0x5c, 0x74, 0x47, 0x02, - 0x27, 0x02, 0xbd, 0x29, 0xb4, 0x93, 0xb4, 0xd3, 0xf0, 0x3e, 0x6b, 0xfd, 0x5e, 0xf6, 0x92, 0x27, - 0x43, 0x79, 0x3b, 0xf7, 0xab, 0xe1, 0x10, 0x99, 0xfb, 0xad, 0x55, 0x48, 0xd3, 0xa5, 0x37, 0x7a, - 0x2f, 0xbd, 0x1c, 0xb3, 0xdd, 0xd4, 0xea, 0x18, 0x6d, 0x47, 0x78, 0x51, 0x60, 0x9d, 0xe4, 0x76, - 0x5f, 0x14, 0xe0, 0x41, 0xe5, 0x14, 0xa4, 0xe9, 0x5f, 0xae, 0xf1, 0x8f, 0xf7, 0x5a, 0xee, 0xab, - 0x2c, 0x89, 0xe8, 0x18, 0x18, 0x68, 0x93, 0x61, 0x56, 0x02, 0x4e, 0xa6, 0x0f, 0x4e, 0xfe, 0x34, - 0x45, 0x1b, 0x85, 0xc2, 0x5d, 0x05, 0x1c, 0x44, 0x51, 0xfc, 0x7a, 0xf2, 0xaf, 0x53, 0x90, 0xae, - 0xb6, 0x9b, 0xba, 0x85, 0xfe, 0x20, 0x39, 0x14, 0xcc, 0x4c, 0xad, 0xb5, 0x89, 0x7d, 0x30, 0x53, - 0xc9, 0x37, 0x95, 0x25, 0x71, 0x0d, 0x99, 0xa9, 0x10, 0x86, 0xcc, 0x1a, 0xbe, 0x68, 0x09, 0x86, - 0x4c, 0xe5, 0x0c, 0x3f, 0x23, 0x93, 0xee, 0x71, 0xe0, 0x8d, 0xe5, 0xa5, 0xcd, 0xea, 0x71, 0x42, - 0x66, 0xe6, 0x16, 0x7e, 0xf2, 0x04, 0x20, 0x33, 0x57, 0xa9, 0xd5, 0x2a, 0xcb, 0xf2, 0x11, 0x25, - 0x0b, 0x52, 0xad, 0xb2, 0x22, 0x27, 0x94, 0x71, 0x48, 0x97, 0xca, 0xe5, 0xa2, 0x2a, 0x27, 0xc9, - 0xdf, 0x5a, 0xa9, 0xb6, 0x54, 0x94, 0x25, 0xf4, 0xbe, 0xd0, 0x43, 0xaf, 0x58, 0x77, 0x9c, 0xe2, - 0x15, 0x6e, 0x10, 0xf6, 0xa7, 0x27, 0x7e, 0xe1, 0xfa, 0x37, 0x12, 0xa4, 0x97, 0xb1, 0xb9, 0x89, - 0xd1, 0x2f, 0x47, 0xb0, 0x05, 0x6e, 0xe8, 0x66, 0x87, 0x9d, 0x1c, 0x72, 0x6d, 0x81, 0xde, 0x38, - 0xe5, 0x6a, 0x98, 0xec, 0xe0, 0xba, 0xd1, 0x6a, 0xd8, 0x89, 0xf8, 0x65, 0x50, 0x42, 0x24, 0x7a, - 0x34, 0x22, 0x64, 0x94, 0xd0, 0xa1, 0x18, 0xf4, 0xa2, 0x00, 0xd3, 0xab, 0xd6, 0xf8, 0x81, 0xf9, - 0x9f, 0x12, 0xc9, 0xd4, 0xde, 0x43, 0x8f, 0x86, 0x36, 0xd2, 0xde, 0x00, 0x19, 0x2a, 0xa6, 0xf6, - 0x7c, 0xa5, 0xb7, 0x3e, 0xe6, 0x69, 0x94, 0x39, 0xb8, 0xa4, 0x43, 0x1f, 0x4f, 0xc7, 0x0d, 0xd2, - 0x75, 0xd5, 0xbe, 0x4a, 0x61, 0x7f, 0x72, 0xf4, 0x97, 0x5e, 0x00, 0xef, 0x14, 0x01, 0xbc, 0xb6, - 0x07, 0x2b, 0x49, 0x83, 0xfc, 0x9f, 0x91, 0x21, 0xcd, 0xa8, 0x36, 0x0d, 0xc7, 0xb8, 0x68, 0x87, - 0xc9, 0xb7, 0x2d, 0x6b, 0xbb, 0x49, 0xbf, 0x71, 0x17, 0x16, 0x3b, 0xac, 0xcc, 0x42, 0x56, 0x6b, - 0xed, 0xd1, 0x4f, 0xa9, 0x80, 0x56, 0xdb, 0x89, 0xd0, 0xeb, 0x1c, 0xe4, 0xef, 0x11, 0x90, 0xbf, - 0x3e, 0x1c, 0xb9, 0xf1, 0x03, 0xff, 0xf7, 0x19, 0x48, 0xaf, 0x68, 0x1d, 0x0b, 0xa3, 0x6f, 0x48, - 0x61, 0x91, 0xbf, 0x16, 0xa6, 0x36, 0x8c, 0xfa, 0x4e, 0x07, 0x37, 0xc4, 0x4e, 0xd9, 0x15, 0x3b, - 0x0c, 0xcc, 0x95, 0x53, 0x20, 0xdb, 0x91, 0xbc, 0x58, 0xdb, 0x5a, 0xbf, 0x2f, 0x9e, 0x9e, 0x51, - 0xee, 0xac, 0x68, 0xa6, 0x55, 0xd9, 0xa0, 0x71, 0xce, 0x19, 0x65, 0x6f, 0xa4, 0x00, 0x7d, 0x26, - 0x00, 0xfa, 0xac, 0x3f, 0xf4, 0x63, 0x21, 0xa0, 0x57, 0x72, 0x30, 0xb6, 0xa1, 0x37, 0x31, 0xcd, - 0x30, 0xde, 0xe3, 0x76, 0x2b, 0xbe, 0x3d, 0x41, 0x78, 0xef, 0x8c, 0x49, 0xf3, 0x7a, 0x13, 0xab, - 0x4e, 0x36, 0xb4, 0xc4, 0x36, 0xfb, 0x9d, 0x1b, 0xeb, 0x13, 0x9e, 0x1b, 0xeb, 0x15, 0x48, 0x35, - 0x34, 0x4b, 0xa3, 0xac, 0x3f, 0xaa, 0xd2, 0xff, 0xe2, 0xde, 0x91, 0xd4, 0xbd, 0x77, 0xf4, 0xb0, - 0x14, 0x4d, 0xff, 0xd9, 0xa4, 0xf9, 0xf4, 0x9f, 0x75, 0x1b, 0x0e, 0xe6, 0x05, 0xe6, 0x84, 0x09, - 0x0c, 0x75, 0xcd, 0xc4, 0xd6, 0x8a, 0x77, 0x7b, 0x26, 0xad, 0x8a, 0x91, 0x74, 0xc7, 0xbb, 0x53, - 0xd5, 0xb6, 0x31, 0xad, 0x2c, 0x4f, 0xbe, 0xf1, 0x3d, 0xce, 0x7d, 0xf1, 0xae, 0xb6, 0x4d, 0x0f, - 0x5b, 0xdb, 0xf6, 0x6a, 0x63, 0xfc, 0x9d, 0xee, 0x0d, 0x29, 0x90, 0xf2, 0x3b, 0xd6, 0x33, 0x5a, - 0xd9, 0xfe, 0x63, 0xe8, 0xcd, 0x2f, 0xae, 0xbd, 0x76, 0xac, 0xc3, 0xd5, 0xb5, 0x11, 0xa5, 0x24, - 0xdc, 0x26, 0x9b, 0x5f, 0xdb, 0x46, 0x72, 0x40, 0xc7, 0xf6, 0x43, 0x30, 0x0e, 0x3e, 0x0f, 0x47, - 0x4c, 0x19, 0x79, 0x14, 0x83, 0x13, 0xb6, 0x8d, 0x02, 0x29, 0xd7, 0xae, 0xf4, 0x9a, 0xd0, 0x9e, - 0x40, 0x8c, 0x3f, 0x81, 0x4e, 0x01, 0xd1, 0xa6, 0x4a, 0xe1, 0xee, 0x7e, 0x0b, 0xa8, 0x36, 0x7e, - 0x64, 0x7e, 0xe0, 0xb5, 0x1e, 0xe4, 0x0e, 0x8c, 0x8d, 0x68, 0xb6, 0x0f, 0xb4, 0x30, 0xb3, 0x66, - 0xf7, 0x31, 0x2a, 0x44, 0xe3, 0x77, 0x38, 0xfb, 0x73, 0x60, 0xc5, 0x23, 0x38, 0x12, 0x25, 0x41, - 0x86, 0xed, 0x1f, 0xa0, 0x77, 0x84, 0x56, 0x99, 0x44, 0xed, 0x88, 0x0e, 0x04, 0x4e, 0x38, 0x8a, - 0x29, 0x41, 0x70, 0x34, 0x48, 0x45, 0x72, 0x34, 0x10, 0xfd, 0x85, 0x43, 0xf4, 0xa3, 0x9e, 0x2f, - 0xeb, 0x0f, 0x7b, 0x95, 0x18, 0xa5, 0x87, 0x1d, 0xd2, 0x53, 0xff, 0x3f, 0x12, 0xef, 0x24, 0xcb, - 0x47, 0x80, 0xdc, 0x6f, 0x56, 0x12, 0xe1, 0x8e, 0x72, 0xd6, 0xf4, 0x21, 0x5f, 0x57, 0x16, 0xee, - 0x20, 0x40, 0x9f, 0xaa, 0xe3, 0xe7, 0xfc, 0x1b, 0xd9, 0xd5, 0xf1, 0xf3, 0x3a, 0x6e, 0x36, 0x3a, - 0xc8, 0x3c, 0xf8, 0xc0, 0x73, 0x13, 0x64, 0x36, 0x68, 0x61, 0xfd, 0xde, 0x63, 0xe7, 0xc9, 0xd0, - 0x1b, 0x92, 0x61, 0x0d, 0xeb, 0xdc, 0x90, 0x61, 0x53, 0x3b, 0x14, 0x98, 0xde, 0x18, 0xca, 0xb0, - 0x1d, 0x5c, 0x73, 0xfc, 0x28, 0xbd, 0x5b, 0x82, 0xa3, 0xfc, 0x2e, 0xb0, 0x5c, 0x53, 0xdf, 0x6c, - 0x79, 0x8f, 0xa6, 0x0d, 0xdc, 0x43, 0x94, 0x9b, 0x21, 0xad, 0x91, 0xd2, 0xb8, 0x3b, 0x15, 0xea, - 0xa9, 0xe5, 0x68, 0x7d, 0x2a, 0x4b, 0x18, 0xe1, 0x1e, 0x08, 0x57, 0xb0, 0x6d, 0x9a, 0x47, 0x78, - 0x0f, 0x44, 0xdf, 0xca, 0xe3, 0x47, 0xec, 0x9b, 0x12, 0x1c, 0xe7, 0x04, 0x9c, 0xc5, 0xa6, 0xa5, - 0xd7, 0xb5, 0x26, 0x43, 0xee, 0x25, 0x89, 0x61, 0x40, 0xb7, 0x08, 0x93, 0xbb, 0xde, 0x62, 0x39, - 0x84, 0x33, 0x3d, 0x21, 0x14, 0x08, 0x50, 0xc5, 0x8c, 0x11, 0x4e, 0xd4, 0x0b, 0x5c, 0x15, 0xca, - 0x1c, 0xe1, 0x89, 0xfa, 0xd0, 0x44, 0xc4, 0x0f, 0xf1, 0xef, 0xa7, 0xd8, 0x25, 0x13, 0xae, 0xfa, - 0xfc, 0x4a, 0x68, 0x6c, 0x57, 0x61, 0x82, 0x62, 0xc9, 0x32, 0xf2, 0x35, 0x5e, 0x80, 0x10, 0x3b, - 0x7a, 0x87, 0xdf, 0x7f, 0xe5, 0xe4, 0x55, 0xbd, 0xe5, 0xa0, 0x73, 0x00, 0xee, 0x27, 0xaf, 0x92, - 0x4e, 0xf8, 0x29, 0xe9, 0x64, 0x38, 0x25, 0xfd, 0xf6, 0xd0, 0x07, 0xa1, 0x7a, 0x93, 0x7d, 0x70, - 0xf1, 0x08, 0x77, 0x04, 0xa6, 0x7f, 0xed, 0xf1, 0xcb, 0xc5, 0xeb, 0x52, 0xdd, 0xb7, 0xd5, 0x7e, - 0x72, 0x28, 0x73, 0x58, 0xaf, 0x3e, 0x90, 0xba, 0xf4, 0xc1, 0xe0, 0x73, 0x56, 0xe5, 0x3a, 0x38, - 0xc6, 0xaa, 0xc8, 0x3b, 0x64, 0xb1, 0x47, 0x0d, 0xbb, 0xa3, 0xd1, 0xa7, 0x06, 0x10, 0x82, 0x7e, - 0x57, 0xe9, 0x06, 0x29, 0xb9, 0x68, 0xd3, 0xdc, 0xa8, 0x02, 0x72, 0x78, 0x37, 0xf0, 0x7e, 0x37, - 0xc5, 0x66, 0xbb, 0xab, 0xf4, 0xde, 0x38, 0xf4, 0x57, 0xa9, 0x61, 0x8c, 0x08, 0xf7, 0x42, 0xca, - 0xb2, 0x1f, 0x5f, 0xed, 0xbd, 0x8c, 0x74, 0xab, 0x74, 0x6f, 0x9c, 0xc3, 0x17, 0xad, 0xc5, 0x23, - 0x2a, 0xcd, 0xa9, 0x9c, 0x82, 0x63, 0xeb, 0x5a, 0xfd, 0xfc, 0xa6, 0x69, 0xec, 0xb4, 0x1a, 0x79, - 0xa3, 0x69, 0x98, 0xcc, 0x44, 0x40, 0x6f, 0xd7, 0x13, 0x3f, 0x28, 0xa7, 0xed, 0xa9, 0x43, 0xba, - 0xdf, 0xd4, 0x61, 0xf1, 0x08, 0x9f, 0x3c, 0x28, 0xb7, 0x38, 0x4a, 0x27, 0x13, 0xa8, 0x74, 0x16, - 0x8f, 0xd8, 0x6a, 0x47, 0x29, 0xc0, 0x58, 0x43, 0xdf, 0xa5, 0xbb, 0x7e, 0xd4, 0x3c, 0xdb, 0xef, - 0x60, 0x45, 0x41, 0xdf, 0x65, 0x7b, 0x84, 0x8b, 0x47, 0x54, 0x27, 0xa7, 0xb2, 0x00, 0xe3, 0xd4, - 0xc2, 0x4a, 0x8b, 0x19, 0x8b, 0x74, 0x68, 0x62, 0xf1, 0x88, 0xea, 0xe6, 0x25, 0xb3, 0x8f, 0x14, - 0x75, 0x47, 0xbe, 0xc7, 0xde, 0xb9, 0x4c, 0x44, 0xda, 0xb9, 0x24, 0xbc, 0x60, 0x7b, 0x97, 0x27, - 0x20, 0x5d, 0xa7, 0x1c, 0x4e, 0x72, 0x0e, 0xb3, 0xa0, 0x72, 0x27, 0xa4, 0xb6, 0x35, 0xd3, 0x5e, - 0xa6, 0x5e, 0xdb, 0xbf, 0xdc, 0x65, 0xcd, 0x3c, 0x4f, 0x10, 0x24, 0xb9, 0xe6, 0xb2, 0x90, 0xa6, - 0x8c, 0x73, 0xfe, 0xa0, 0xa7, 0xf8, 0x34, 0x24, 0x6f, 0xb4, 0xc8, 0xb0, 0x5f, 0x33, 0x6c, 0x9f, - 0xed, 0xfa, 0x30, 0x64, 0x4e, 0xf4, 0x4f, 0x94, 0xf6, 0xf9, 0x27, 0xfe, 0xe5, 0x00, 0x73, 0x8b, - 0x6e, 0x4a, 0xfd, 0x17, 0xc7, 0x4d, 0xe1, 0xa1, 0x72, 0x3b, 0x18, 0x51, 0x6b, 0x44, 0x9d, 0x75, - 0xf4, 0x21, 0x6f, 0x04, 0xef, 0xca, 0xa7, 0x60, 0x9a, 0x10, 0xc2, 0x3c, 0x77, 0xc5, 0x4b, 0x27, - 0xd1, 0x9f, 0x0f, 0x65, 0x72, 0xd9, 0x63, 0x44, 0x90, 0x7a, 0x8e, 0x08, 0xfb, 0xce, 0x6d, 0xa4, - 0xfa, 0x9c, 0xdb, 0x48, 0x47, 0x33, 0xa7, 0xfc, 0x89, 0x57, 0x7e, 0x56, 0x44, 0xf9, 0xb9, 0xdd, - 0x07, 0xa0, 0x5e, 0x7c, 0x19, 0xca, 0x04, 0xe4, 0xbd, 0x8e, 0xa4, 0x54, 0x05, 0x49, 0xb9, 0x67, - 0x70, 0x42, 0xe2, 0x97, 0x96, 0x8f, 0xa6, 0xe0, 0x67, 0x5c, 0x62, 0xca, 0xf8, 0x02, 0x17, 0x94, - 0x2f, 0x0d, 0x45, 0x50, 0x6e, 0x71, 0x9f, 0x73, 0xe9, 0xb3, 0xd8, 0xb7, 0xd3, 0xc5, 0x2d, 0x31, - 0x7f, 0x11, 0xda, 0xdf, 0xbc, 0x1b, 0x28, 0x87, 0x37, 0x3e, 0xc2, 0x72, 0x02, 0x32, 0x4c, 0xc3, - 0xd8, 0x8f, 0x4b, 0xb3, 0x50, 0x44, 0x75, 0x13, 0xce, 0x4b, 0x3d, 0x2c, 0x6d, 0x23, 0x90, 0x1f, - 0x6e, 0x78, 0xa8, 0xed, 0x98, 0xad, 0x52, 0xcb, 0x32, 0xd0, 0xaf, 0x0d, 0x45, 0x70, 0x1c, 0xcf, - 0x1f, 0x69, 0x10, 0xcf, 0x9f, 0x81, 0xcc, 0x10, 0x76, 0x0b, 0x0e, 0xc5, 0x0c, 0xe1, 0x53, 0x79, - 0xfc, 0xf8, 0x3d, 0x21, 0xc1, 0x09, 0xbe, 0x1a, 0x9a, 0x13, 0xa7, 0x70, 0xe8, 0x81, 0x61, 0x00, - 0x79, 0xdc, 0x9e, 0xc7, 0xb0, 0x01, 0x82, 0x05, 0x44, 0x8f, 0xf0, 0xc0, 0x3b, 0x14, 0x85, 0xf5, - 0x5a, 0x17, 0x85, 0x43, 0x41, 0x2a, 0xdc, 0xd5, 0x89, 0x11, 0xc8, 0x88, 0x1f, 0xb3, 0x97, 0x4b, - 0x90, 0xe1, 0x77, 0xc2, 0xaf, 0xc6, 0xb2, 0x5d, 0x2c, 0xde, 0x97, 0x13, 0x62, 0x9b, 0x22, 0xf2, - 0x65, 0xec, 0xf1, 0x6d, 0x50, 0x1c, 0xce, 0x6d, 0xeb, 0xe8, 0x51, 0x89, 0x5b, 0x56, 0x96, 0x34, - 0x0b, 0x5f, 0x44, 0xbf, 0x2d, 0x41, 0xb6, 0x8a, 0x2d, 0xa2, 0x99, 0xc2, 0x63, 0xe4, 0x6f, 0x33, - 0x57, 0x3c, 0x6b, 0xb7, 0x71, 0xb6, 0x1a, 0x8b, 0xaa, 0xe3, 0x28, 0x5d, 0xb3, 0x9c, 0xa6, 0x51, - 0xeb, 0xb8, 0xa0, 0xca, 0x47, 0x70, 0x3a, 0xf5, 0x6a, 0x18, 0xa7, 0x64, 0x50, 0x38, 0x3e, 0xed, - 0x81, 0xe6, 0x95, 0x89, 0x58, 0xb0, 0x21, 0xc3, 0x17, 0xbd, 0x38, 0x9d, 0xce, 0x5e, 0x26, 0xc2, - 0x0c, 0x5f, 0x64, 0x99, 0xd6, 0x51, 0x59, 0xae, 0x08, 0x2f, 0xe9, 0x38, 0xcd, 0x1a, 0x2a, 0xb2, - 0xe1, 0x9e, 0x38, 0xe8, 0x57, 0xf7, 0x08, 0x1e, 0xc8, 0x90, 0x60, 0xac, 0x4a, 0x96, 0x1b, 0x64, - 0x4c, 0x39, 0x77, 0x70, 0x28, 0x7b, 0x0f, 0x56, 0x11, 0x3b, 0x9a, 0xcd, 0x91, 0xe1, 0x0d, 0x51, - 0x11, 0x3a, 0x5a, 0x50, 0xe5, 0xf1, 0xe3, 0xf1, 0x3e, 0x86, 0x07, 0x95, 0x65, 0xf4, 0x16, 0x09, - 0xa4, 0x05, 0x6c, 0x0d, 0xc9, 0xcf, 0x3f, 0xac, 0xcf, 0xb8, 0x38, 0x74, 0x05, 0x1e, 0xed, 0x16, - 0x18, 0x46, 0x69, 0x9e, 0x5d, 0xc0, 0xc3, 0xe9, 0x40, 0xe1, 0xce, 0x74, 0x87, 0x22, 0x20, 0x7e, - 0xd4, 0x3e, 0xc4, 0x50, 0x63, 0x16, 0xac, 0x5f, 0x1d, 0x82, 0x46, 0x1c, 0xed, 0xe4, 0xdd, 0x66, - 0x20, 0x2d, 0xe3, 0xb0, 0xfa, 0x5b, 0xaf, 0xca, 0x47, 0xe2, 0x11, 0x06, 0xa4, 0xb3, 0x6f, 0xe1, - 0xfa, 0x79, 0xdc, 0x40, 0xff, 0xdf, 0xc1, 0xa1, 0x9b, 0x86, 0x6c, 0x9d, 0x95, 0x46, 0xc1, 0x1b, - 0x53, 0xed, 0x60, 0x84, 0x77, 0xac, 0x45, 0x45, 0xc4, 0xb2, 0x8f, 0xf0, 0x1d, 0xeb, 0x10, 0xd5, - 0xc7, 0x8f, 0xcc, 0x7b, 0xd8, 0x24, 0xa3, 0x54, 0x37, 0x5a, 0xe8, 0x5f, 0x1d, 0x1c, 0x96, 0xcb, - 0x61, 0x5c, 0xaf, 0x1b, 0xad, 0xd2, 0xb6, 0xb6, 0x69, 0x9b, 0x51, 0xdd, 0x08, 0xfb, 0x6b, 0x71, - 0xdb, 0x78, 0x50, 0xe7, 0x5b, 0x33, 0x6e, 0xc4, 0xa0, 0x93, 0x09, 0x42, 0xfa, 0x61, 0x4d, 0x26, - 0x7a, 0xd4, 0x1d, 0x3f, 0x64, 0x9f, 0x72, 0x5d, 0x28, 0x98, 0x2a, 0x7c, 0x46, 0x58, 0x32, 0x06, - 0x19, 0xce, 0xbc, 0xad, 0x38, 0x94, 0xe1, 0x2c, 0x80, 0x80, 0xf8, 0x71, 0x7c, 0x8d, 0x8b, 0x63, - 0xec, 0x76, 0x8c, 0x03, 0xa0, 0x33, 0xbc, 0xe9, 0xe1, 0x80, 0xe8, 0x1c, 0xce, 0x14, 0xf1, 0x49, - 0x7e, 0x35, 0x10, 0x9f, 0xf1, 0xa0, 0x5f, 0x19, 0x06, 0x38, 0xb7, 0x0f, 0xb2, 0x29, 0xc6, 0xb6, - 0xc4, 0x22, 0xbc, 0x9c, 0xb2, 0x8f, 0x83, 0xa4, 0x94, 0xa1, 0x20, 0x18, 0xee, 0xe5, 0x94, 0x30, - 0xf5, 0xc7, 0x0f, 0xe0, 0xef, 0x48, 0x30, 0x45, 0xf7, 0xb9, 0x9a, 0x58, 0x33, 0x99, 0xa2, 0x1c, - 0x8a, 0x37, 0xe6, 0xfb, 0x42, 0x5f, 0x6a, 0x2e, 0xf2, 0xc1, 0xa5, 0x63, 0x28, 0x50, 0x84, 0x7b, - 0x7d, 0x33, 0x24, 0x09, 0x23, 0x31, 0x05, 0xca, 0x0e, 0x09, 0x5c, 0xc4, 0x87, 0x83, 0x47, 0x44, - 0xb7, 0x2f, 0x91, 0x19, 0x76, 0x67, 0x1b, 0xb1, 0xdb, 0x57, 0x18, 0x22, 0x46, 0x70, 0x75, 0xf6, - 0xcd, 0xdc, 0x14, 0x58, 0xa3, 0x0f, 0x0b, 0x3d, 0x96, 0x72, 0x5c, 0xd5, 0x3f, 0x3f, 0x14, 0x37, - 0x9f, 0x03, 0xdc, 0x73, 0xa7, 0x40, 0xca, 0x34, 0x2e, 0x30, 0xb3, 0xd4, 0xa4, 0x4a, 0xff, 0xd3, - 0x29, 0xbf, 0xd1, 0xdc, 0xd9, 0x6e, 0x75, 0xe8, 0xdc, 0x71, 0x52, 0xb5, 0x83, 0xca, 0xd5, 0x30, - 0x79, 0x41, 0xb7, 0xb6, 0x16, 0xb1, 0xd6, 0xc0, 0xa6, 0x6a, 0x5c, 0xe0, 0x8f, 0x77, 0x8a, 0x91, - 0xe2, 0x1e, 0x6c, 0x88, 0xf9, 0x25, 0x7d, 0x6d, 0x68, 0x24, 0x7e, 0xed, 0x51, 0x66, 0x9e, 0xfe, - 0x54, 0xc5, 0x2f, 0x30, 0x1f, 0x96, 0x60, 0x5c, 0x35, 0x2e, 0x70, 0x21, 0xf9, 0xd7, 0x87, 0x2b, - 0x23, 0x91, 0x17, 0x7a, 0xec, 0xf5, 0x28, 0x9b, 0xfc, 0x91, 0x2f, 0xf4, 0x02, 0xab, 0x1f, 0x89, - 0x7b, 0xfc, 0x51, 0xd5, 0xb8, 0x50, 0xc5, 0x16, 0xeb, 0x11, 0x68, 0x6d, 0x48, 0x9e, 0x7c, 0x7a, - 0x87, 0x15, 0xc8, 0xd7, 0xe1, 0x4e, 0x18, 0x3d, 0x11, 0xfa, 0x51, 0x1e, 0x91, 0x41, 0x0e, 0x89, - 0x43, 0x81, 0xe8, 0x9d, 0xa1, 0xde, 0xe2, 0x09, 0x47, 0x41, 0xfc, 0x28, 0xfd, 0x86, 0x04, 0x13, - 0xaa, 0x71, 0x81, 0x0c, 0x0d, 0xf3, 0x7a, 0xb3, 0x39, 0x9c, 0x11, 0x32, 0xea, 0xe4, 0xdf, 0x66, - 0x83, 0x4d, 0xc5, 0xc8, 0x27, 0xff, 0x7d, 0x08, 0x88, 0x1f, 0x86, 0x87, 0x59, 0x67, 0xb1, 0x47, - 0xe8, 0xd6, 0x70, 0x70, 0x18, 0xb4, 0x43, 0x38, 0x64, 0x1c, 0x5a, 0x87, 0xf0, 0xa3, 0x60, 0x24, - 0x3b, 0x27, 0x53, 0x79, 0x3a, 0xcc, 0x0f, 0xb7, 0x4f, 0x7c, 0x20, 0x9a, 0x7b, 0x0d, 0x1f, 0x76, - 0x05, 0x42, 0x86, 0x82, 0x46, 0x04, 0x37, 0x9a, 0x10, 0x34, 0xc4, 0x8f, 0xc7, 0xc7, 0x25, 0x38, - 0xca, 0x48, 0x78, 0x86, 0xcc, 0x02, 0x06, 0xea, 0x54, 0xde, 0x16, 0x1c, 0x4e, 0xa7, 0x0a, 0xa0, - 0x20, 0x7e, 0x10, 0xff, 0x4f, 0x92, 0xce, 0xe3, 0x06, 0x38, 0xa3, 0xe8, 0x87, 0xe0, 0xc0, 0x93, - 0xb1, 0x21, 0x9e, 0x53, 0x1c, 0x64, 0x32, 0x76, 0x48, 0x67, 0x15, 0x1f, 0x76, 0x7a, 0xd1, 0x30, - 0x31, 0x38, 0x40, 0x57, 0x18, 0x22, 0x0c, 0x03, 0x76, 0x85, 0x43, 0x42, 0xe2, 0x5b, 0x12, 0x00, - 0x23, 0x60, 0xd9, 0xd8, 0xc5, 0xe8, 0xf1, 0xa1, 0x2c, 0x7c, 0xbb, 0x5d, 0x43, 0xa5, 0x3e, 0xae, - 0xa1, 0x11, 0xcf, 0x66, 0x47, 0xb5, 0x04, 0x7a, 0xb8, 0xbc, 0xec, 0xfb, 0x28, 0x62, 0x8c, 0x96, - 0xc0, 0xe0, 0xfa, 0xe3, 0xc7, 0xf8, 0xeb, 0x6c, 0x36, 0xe7, 0x9e, 0x62, 0x7a, 0xf5, 0x50, 0x50, - 0xf6, 0xac, 0xfe, 0x25, 0x71, 0xf5, 0x7f, 0x00, 0x6c, 0x07, 0x9d, 0x23, 0xf6, 0x3b, 0x9d, 0x14, - 0xff, 0x1c, 0xf1, 0xf0, 0x4e, 0x21, 0xfd, 0x6a, 0x0a, 0x8e, 0x71, 0x25, 0xf2, 0x4f, 0x01, 0xe2, - 0x88, 0x67, 0x49, 0x04, 0x25, 0xd9, 0x07, 0xe5, 0x61, 0x19, 0xa4, 0xa2, 0x98, 0x32, 0x43, 0x90, - 0x37, 0x12, 0xeb, 0x46, 0xa6, 0x78, 0xb1, 0xad, 0xb5, 0x1a, 0xe1, 0xaf, 0xe7, 0xeb, 0x03, 0xbc, - 0x6d, 0x6b, 0x94, 0x44, 0x5b, 0x63, 0x0f, 0xcb, 0x64, 0xe4, 0x9d, 0x6b, 0xca, 0x32, 0x46, 0xee, - 0xc8, 0x77, 0xae, 0xfd, 0xeb, 0x8e, 0x1f, 0xa5, 0x0f, 0x48, 0x90, 0xaa, 0x1a, 0xa6, 0x85, 0x1e, - 0x89, 0xd2, 0x3b, 0x19, 0xe7, 0x5d, 0x90, 0xec, 0xb0, 0x92, 0x17, 0x1e, 0x2a, 0xba, 0x29, 0xf8, - 0x3c, 0x9d, 0x66, 0x69, 0xf4, 0xf2, 0x66, 0x52, 0xbf, 0xe7, 0xc5, 0xa2, 0xa8, 0x97, 0x36, 0x30, - 0xfe, 0x55, 0xfd, 0x9d, 0x88, 0x63, 0xbb, 0xb4, 0xc1, 0xb7, 0xe6, 0x11, 0xd8, 0x7d, 0x27, 0xb8, - 0x5f, 0x2a, 0x7d, 0xbf, 0xed, 0x11, 0xe6, 0x32, 0x52, 0xd6, 0xb6, 0xf1, 0x90, 0x5c, 0x86, 0xe9, - 0x0d, 0x71, 0x92, 0x7b, 0x43, 0x5c, 0xd4, 0x0e, 0xc5, 0x4e, 0x39, 0x32, 0x92, 0x46, 0xdd, 0xa1, - 0x02, 0xea, 0x8e, 0x1f, 0x98, 0xaf, 0x92, 0x91, 0x8f, 0xae, 0x21, 0x73, 0xad, 0x06, 0xbf, 0x72, - 0xeb, 0xef, 0x0f, 0x7b, 0xef, 0x66, 0xdf, 0xa5, 0x5c, 0xe2, 0xe5, 0x7e, 0xe9, 0xee, 0xf7, 0xc6, - 0xe6, 0xd8, 0x05, 0x5f, 0xf4, 0xe4, 0x65, 0x26, 0xd2, 0x9b, 0x63, 0x4e, 0x3e, 0xf4, 0x54, 0x34, - 0x73, 0x0e, 0x2d, 0xa2, 0x8b, 0x71, 0x31, 0x0f, 0xa9, 0x11, 0x0c, 0x3d, 0x21, 0xa8, 0xfb, 0xe7, - 0xe1, 0x65, 0xb4, 0xff, 0xc9, 0xb7, 0x88, 0xa6, 0x6c, 0xe7, 0xa1, 0xbe, 0xc3, 0xf2, 0x32, 0xea, - 0x47, 0x40, 0xfc, 0x38, 0x3e, 0x95, 0xe6, 0x9b, 0xbc, 0xd4, 0x05, 0x0f, 0x7d, 0x2d, 0x19, 0xbb, - 0xf2, 0x0e, 0xff, 0xc8, 0xa9, 0x4b, 0x57, 0xb0, 0xf6, 0x8e, 0xe2, 0xe8, 0x1a, 0x54, 0xdc, 0x08, - 0xcc, 0x09, 0x49, 0xea, 0xa2, 0x7c, 0x4e, 0x6f, 0x58, 0x5b, 0x43, 0x72, 0xf4, 0xbf, 0x40, 0xca, - 0xb2, 0x5f, 0x0b, 0xa3, 0x01, 0xf4, 0x93, 0x44, 0xa4, 0xeb, 0x2b, 0x1c, 0x96, 0x50, 0xb2, 0x7c, - 0x58, 0x1c, 0xe1, 0xd2, 0x89, 0xc0, 0xf2, 0x46, 0x28, 0xd1, 0x67, 0xf5, 0x06, 0x36, 0x9e, 0x81, - 0x12, 0x4d, 0xe9, 0x1a, 0x9e, 0x44, 0x07, 0x15, 0xf7, 0xcf, 0x54, 0xa2, 0x1d, 0x96, 0x0c, 0x49, - 0xa2, 0x03, 0xcb, 0x1b, 0xc1, 0x4d, 0xd6, 0xc0, 0xe7, 0xd7, 0x4b, 0x7a, 0xeb, 0x3c, 0xfa, 0x4c, - 0xda, 0x7e, 0xa7, 0xec, 0x9c, 0x6e, 0x6d, 0xf1, 0x63, 0xee, 0x9f, 0x0a, 0xfd, 0xa2, 0xc1, 0x00, - 0x47, 0xd9, 0x4f, 0x02, 0x58, 0xfc, 0xfd, 0x20, 0xe7, 0xce, 0x1c, 0x4f, 0x8c, 0x92, 0x83, 0x49, - 0xbd, 0x65, 0x61, 0xb3, 0xa5, 0x35, 0xe7, 0x9b, 0xda, 0x66, 0x67, 0x3a, 0x4b, 0x8f, 0x66, 0x5e, - 0xd6, 0x35, 0x78, 0x97, 0x3c, 0x69, 0x54, 0x31, 0x47, 0xe8, 0xb9, 0x66, 0xc4, 0x2b, 0x7f, 0x6e, - 0x0a, 0x79, 0x13, 0x8b, 0x73, 0xfd, 0xd3, 0xf7, 0xa3, 0x19, 0x5f, 0x08, 0x20, 0xb3, 0xdd, 0x60, - 0x44, 0x9e, 0x29, 0x7a, 0x1b, 0x2f, 0x75, 0x35, 0xde, 0x99, 0x7a, 0xa4, 0x86, 0x6c, 0x98, 0x09, - 0x43, 0xfa, 0x08, 0x4e, 0x7e, 0xa4, 0xe1, 0x12, 0xfb, 0xfa, 0xba, 0x76, 0x1b, 0x6b, 0xa6, 0xd6, - 0xaa, 0xe3, 0x08, 0xd2, 0x1c, 0x34, 0x97, 0x9c, 0x87, 0x31, 0xbd, 0x6e, 0xb4, 0xaa, 0xfa, 0x8b, - 0xec, 0x87, 0x37, 0x4e, 0x05, 0x4e, 0x27, 0x29, 0x47, 0x4a, 0x3c, 0x87, 0xea, 0xe4, 0x55, 0x4a, - 0x30, 0x5e, 0xd7, 0xcc, 0x46, 0xd5, 0xf3, 0x14, 0xf1, 0xf5, 0xfd, 0x0b, 0xca, 0xdb, 0x59, 0x54, - 0x37, 0xb7, 0x52, 0x11, 0x99, 0x98, 0xe9, 0x3a, 0xfd, 0xeb, 0x5b, 0x58, 0xc1, 0xcd, 0x24, 0xf0, - 0x9c, 0x70, 0xc7, 0xc4, 0x4d, 0xfa, 0xce, 0x21, 0xeb, 0x76, 0xe3, 0xaa, 0x1b, 0x81, 0x3e, 0xec, - 0x95, 0xe6, 0x65, 0x51, 0x9a, 0x5f, 0xe8, 0x23, 0x12, 0xfb, 0xd0, 0x18, 0xca, 0x9c, 0xf8, 0xdd, - 0x8e, 0x60, 0xae, 0x08, 0x82, 0x79, 0xe7, 0x80, 0x54, 0xc4, 0x2f, 0x99, 0xef, 0xcd, 0xc0, 0x24, - 0x3b, 0x4c, 0xce, 0xd9, 0x89, 0x7e, 0x87, 0x3e, 0xad, 0x65, 0xdd, 0x8f, 0xf7, 0x50, 0xf5, 0xe0, - 0x03, 0x9d, 0x0c, 0xd2, 0x79, 0xbc, 0xc7, 0xfb, 0x3b, 0xf9, 0x1b, 0x75, 0x8f, 0xd4, 0xa6, 0x6b, - 0x96, 0xd1, 0x34, 0xea, 0x3d, 0xd2, 0xe0, 0xea, 0xe3, 0xc7, 0xe7, 0x15, 0x12, 0x48, 0xb9, 0x46, - 0x23, 0xfc, 0xfd, 0x4e, 0xfe, 0x50, 0x5c, 0x09, 0x13, 0x76, 0x9f, 0xb9, 0xdf, 0x81, 0xc4, 0x1b, - 0x15, 0xd5, 0xe0, 0xe4, 0xf0, 0x26, 0xd7, 0x18, 0xb9, 0x05, 0x37, 0xa0, 0xee, 0xf8, 0x41, 0x79, - 0x75, 0x96, 0x77, 0x9a, 0x39, 0xc3, 0x38, 0x4f, 0x8f, 0x25, 0x3c, 0x22, 0x41, 0x7a, 0x1e, 0x5b, - 0xf5, 0xad, 0x21, 0xf5, 0x99, 0x1d, 0xb3, 0x69, 0xf7, 0x99, 0x7d, 0xef, 0x04, 0xf6, 0x9f, 0x18, - 0xda, 0x64, 0xcd, 0x52, 0x92, 0x46, 0x7d, 0x5d, 0x63, 0x60, 0xed, 0xf1, 0x83, 0xf3, 0x13, 0x09, - 0xa6, 0x1c, 0xb3, 0x11, 0xc3, 0xe4, 0x77, 0x9f, 0x71, 0xc6, 0x40, 0xf4, 0xa5, 0x68, 0x57, 0xaa, - 0x38, 0x3c, 0x15, 0x5b, 0x16, 0xb3, 0xb5, 0x2e, 0xc2, 0x65, 0x2b, 0xe1, 0x08, 0x1c, 0xc1, 0xb2, - 0x58, 0x82, 0x31, 0x4a, 0x50, 0x41, 0xdf, 0xa5, 0x6e, 0x5a, 0x82, 0xf5, 0xee, 0xa1, 0xa1, 0x58, - 0xef, 0xee, 0x14, 0xad, 0x77, 0x21, 0xaf, 0x30, 0xb4, 0x8d, 0x77, 0x11, 0xfd, 0x16, 0x48, 0xfe, - 0xa1, 0xdb, 0xee, 0x22, 0xf8, 0x2d, 0xf4, 0xa9, 0x7f, 0x04, 0x0f, 0xaa, 0x9e, 0xe2, 0xca, 0xd6, - 0xde, 0xbc, 0x42, 0x0f, 0x29, 0x90, 0x3a, 0x4b, 0xfe, 0x7c, 0xcd, 0x7d, 0x56, 0xe0, 0xa1, 0x21, - 0x1c, 0x84, 0xbf, 0x1b, 0x52, 0xf4, 0xe9, 0xd4, 0x54, 0xd7, 0x95, 0x9b, 0x81, 0x3b, 0x69, 0x84, - 0x10, 0x95, 0xe6, 0x8b, 0x7a, 0x59, 0x99, 0x50, 0xc4, 0xec, 0xf0, 0xdc, 0xf0, 0x94, 0x13, 0x90, - 0x21, 0xe5, 0x3a, 0xcb, 0x2c, 0x1e, 0x8a, 0x62, 0x7c, 0x0f, 0x41, 0x5b, 0xfc, 0xc8, 0x7f, 0x8d, - 0xbe, 0xa0, 0x42, 0xef, 0x54, 0x7d, 0x74, 0x08, 0xf0, 0xfa, 0xb0, 0xe5, 0xc0, 0xb0, 0x7f, 0xe0, - 0x20, 0xb0, 0x3b, 0x17, 0xb8, 0x8e, 0xd4, 0x89, 0x36, 0x04, 0x0d, 0x23, 0x39, 0xf9, 0x9b, 0xe1, - 0x8e, 0x7f, 0x0f, 0x0c, 0x13, 0xdd, 0x94, 0x20, 0xf4, 0x07, 0x42, 0x67, 0x88, 0x0e, 0x81, 0x03, - 0xa3, 0x73, 0x48, 0x2e, 0x81, 0x7f, 0x2a, 0xc1, 0x44, 0xd5, 0x7d, 0xee, 0x2b, 0xfc, 0x0b, 0x05, - 0x91, 0x21, 0x22, 0x63, 0xad, 0x70, 0x3f, 0xe4, 0xe4, 0xe0, 0x57, 0x86, 0x8a, 0xac, 0xf3, 0xd0, - 0x3f, 0xea, 0x2b, 0x43, 0xc3, 0x12, 0x12, 0x3f, 0x90, 0x5f, 0x60, 0x2f, 0x82, 0xe4, 0xea, 0x96, - 0xbe, 0x8b, 0xd1, 0xc3, 0x31, 0x2a, 0xd2, 0x13, 0x90, 0x31, 0x36, 0x36, 0x3a, 0xfc, 0x1d, 0xb8, - 0x49, 0x95, 0x87, 0xdc, 0x07, 0xb8, 0x19, 0xb8, 0xfc, 0x01, 0xee, 0x88, 0x97, 0x0a, 0xee, 0x63, - 0x28, 0x6b, 0xd0, 0xa8, 0x2f, 0x15, 0x0c, 0x47, 0xc6, 0x08, 0xae, 0x0d, 0x06, 0xc2, 0x3d, 0x6e, - 0xb2, 0x79, 0x0b, 0x37, 0x12, 0xe0, 0x83, 0x63, 0x3b, 0x03, 0x47, 0x3d, 0x16, 0x01, 0xfb, 0x62, - 0x7a, 0x21, 0x2e, 0xea, 0x59, 0x63, 0x87, 0x65, 0x43, 0xb7, 0x17, 0x44, 0xb0, 0x03, 0x87, 0x21, - 0x62, 0x24, 0xef, 0xbe, 0xd8, 0x43, 0xde, 0x88, 0xb0, 0xfa, 0xa8, 0x17, 0xab, 0x8a, 0x88, 0xd5, - 0x99, 0x30, 0x6c, 0x0a, 0x37, 0x04, 0x86, 0x5a, 0x4e, 0x3e, 0xe1, 0xc0, 0xa5, 0x0a, 0x70, 0xdd, - 0x3d, 0x30, 0x1d, 0xf1, 0x23, 0xf6, 0x09, 0x89, 0x3d, 0xfe, 0x90, 0xdb, 0xd5, 0xf4, 0x26, 0x3d, - 0x20, 0x3e, 0x84, 0x07, 0xe3, 0xfe, 0x9b, 0x17, 0x94, 0xb3, 0x22, 0x28, 0xf7, 0x86, 0x61, 0x86, - 0x40, 0x91, 0x0f, 0x36, 0xcf, 0xf7, 0xda, 0xcc, 0xd9, 0x2d, 0xa2, 0x97, 0x76, 0xdf, 0xc4, 0xc6, - 0xbf, 0x7b, 0x8d, 0xe9, 0x9f, 0x77, 0x40, 0x7a, 0x40, 0x00, 0xa9, 0x78, 0x50, 0xba, 0xa2, 0x61, - 0xb5, 0x34, 0xc0, 0x8b, 0xf6, 0xd3, 0x70, 0xbc, 0x5c, 0xa9, 0xad, 0xe5, 0xd6, 0x0a, 0xb9, 0x5a, - 0xee, 0x6c, 0xa9, 0x78, 0x6e, 0x6d, 0x6e, 0xa9, 0x92, 0xbf, 0x5f, 0x96, 0xd0, 0x1f, 0xb0, 0x31, - 0xb0, 0x6a, 0xec, 0x98, 0xf5, 0x61, 0xcd, 0x36, 0x3b, 0xb4, 0x30, 0xde, 0xe9, 0x78, 0x28, 0xaa, - 0xe3, 0xba, 0xeb, 0x8f, 0x69, 0x13, 0xd7, 0xaf, 0xa3, 0xa5, 0x86, 0xec, 0xb8, 0xde, 0x97, 0x82, - 0xf8, 0xbb, 0xd8, 0x0f, 0x25, 0x80, 0x05, 0xd3, 0xd8, 0x69, 0x57, 0xcc, 0x06, 0x36, 0xd1, 0xd3, - 0xee, 0xaa, 0xef, 0xf7, 0x86, 0x30, 0x59, 0x59, 0x01, 0xd8, 0x74, 0x0a, 0xe7, 0x7a, 0xea, 0xe6, - 0x70, 0x6b, 0x3c, 0x97, 0x28, 0xd5, 0x53, 0x06, 0xfa, 0x98, 0x17, 0xe3, 0x9f, 0x17, 0x31, 0x0e, - 0x1a, 0x79, 0xdc, 0xe2, 0x86, 0xb9, 0xea, 0x7b, 0x9f, 0x83, 0x75, 0x4d, 0xc0, 0xfa, 0xde, 0x03, - 0x50, 0x12, 0x3f, 0xe6, 0x3f, 0x96, 0x60, 0x82, 0xed, 0xc5, 0x32, 0x9e, 0xfe, 0x9d, 0x0b, 0xfa, - 0xab, 0x87, 0x00, 0xfa, 0x2a, 0x1c, 0x35, 0xdc, 0xd2, 0xd9, 0xc8, 0xe8, 0xb5, 0xae, 0x05, 0xc2, - 0xee, 0xa1, 0x4b, 0x15, 0x8a, 0x41, 0x9f, 0xf0, 0x22, 0xaf, 0x8a, 0xc8, 0xdf, 0x19, 0xc0, 0x6f, - 0x4f, 0x89, 0xc3, 0x84, 0xfe, 0xfd, 0x0e, 0xf4, 0xab, 0x02, 0xf4, 0xb9, 0x83, 0x90, 0x12, 0x3f, - 0xf6, 0x2f, 0x76, 0x0c, 0xf4, 0xce, 0xf6, 0x49, 0x2c, 0x9b, 0x26, 0xaf, 0x1d, 0x70, 0x81, 0x21, - 0xd2, 0xe6, 0x83, 0xd4, 0x14, 0x24, 0x75, 0x9b, 0x86, 0xa4, 0xde, 0x18, 0x68, 0x09, 0x11, 0x58, - 0x51, 0xfc, 0x38, 0xbc, 0xe9, 0xd9, 0x90, 0x2e, 0xe0, 0xf5, 0x9d, 0x4d, 0xf4, 0x76, 0x09, 0xb2, - 0x4d, 0x63, 0xb3, 0xd4, 0xda, 0x30, 0x78, 0xc3, 0x12, 0x76, 0xc3, 0x14, 0x05, 0x52, 0x5b, 0x58, - 0xb3, 0x9b, 0x4a, 0xff, 0x2b, 0xd7, 0xc2, 0x14, 0xf9, 0xb5, 0x9f, 0x93, 0x75, 0x6e, 0x9f, 0xec, - 0x8a, 0x25, 0x13, 0x54, 0xcb, 0xb0, 0xb4, 0xa6, 0x8a, 0xeb, 0x86, 0xd9, 0x60, 0xa7, 0x45, 0xd2, - 0xaa, 0x10, 0x47, 0xf0, 0xa6, 0x61, 0xea, 0xbf, 0x90, 0xa6, 0x09, 0xdc, 0x08, 0xe5, 0x6a, 0x98, - 0xdc, 0xd0, 0xcd, 0x8e, 0xc5, 0x52, 0xd7, 0x98, 0x83, 0x4b, 0x5a, 0x15, 0x23, 0xe9, 0x7b, 0xf6, - 0x6e, 0xc4, 0x59, 0x6c, 0xd2, 0xc7, 0x85, 0xd2, 0x6a, 0x57, 0x2c, 0xa1, 0xa7, 0xa9, 0x79, 0x0a, - 0x1b, 0x63, 0xf4, 0x78, 0xe3, 0x48, 0x8d, 0x6e, 0x98, 0x14, 0x35, 0xce, 0x6a, 0x14, 0x22, 0x49, - 0x8d, 0x24, 0x62, 0x65, 0xa7, 0xd9, 0xac, 0xe2, 0x7a, 0x6e, 0xd3, 0x98, 0x06, 0x56, 0xa3, 0x18, - 0xab, 0x20, 0x18, 0xdb, 0x69, 0x57, 0x2d, 0xcd, 0xda, 0xe9, 0x4c, 0x4f, 0xb0, 0xfd, 0x24, 0x3b, - 0xac, 0x9c, 0x04, 0x68, 0x18, 0x17, 0x5a, 0xfc, 0xeb, 0x51, 0xe6, 0x6f, 0xe4, 0xc6, 0x90, 0x65, - 0x33, 0x13, 0xd9, 0x49, 0x76, 0x87, 0x1d, 0xf3, 0xe7, 0xfa, 0xa2, 0x04, 0x60, 0x6d, 0x99, 0x58, - 0x6b, 0xf4, 0x84, 0xeb, 0x05, 0x70, 0xa2, 0x69, 0x6c, 0x76, 0xce, 0xe9, 0xd6, 0x96, 0x0b, 0xc4, - 0xa2, 0x0d, 0x60, 0x5a, 0xf5, 0xf9, 0xaa, 0xdc, 0x0b, 0x97, 0xd9, 0x5f, 0xce, 0x6d, 0x19, 0x4d, - 0x5c, 0x33, 0x31, 0xee, 0xc2, 0x37, 0xad, 0x06, 0x25, 0x51, 0x66, 0x21, 0x45, 0x3e, 0xf3, 0xa7, - 0xbe, 0x91, 0x20, 0xf7, 0x54, 0xcc, 0x66, 0xb9, 0x88, 0xa9, 0x34, 0x9d, 0x72, 0x1b, 0x5c, 0x6a, - 0x5c, 0x68, 0x2d, 0x19, 0x9b, 0x8b, 0x5a, 0x27, 0xaf, 0x6d, 0x60, 0x15, 0xb3, 0x63, 0x53, 0x86, - 0xc9, 0x9f, 0xfd, 0xf7, 0xfb, 0xac, 0xcc, 0x82, 0x52, 0xd7, 0x36, 0xf0, 0x92, 0x08, 0x00, 0x93, - 0x8c, 0x1e, 0x5f, 0x08, 0xec, 0x24, 0x76, 0xd5, 0x06, 0x22, 0xcb, 0x0e, 0xa2, 0x7a, 0xe3, 0x08, - 0xa0, 0x24, 0x5c, 0x70, 0x01, 0x19, 0xa3, 0xa9, 0xba, 0x62, 0xf7, 0x89, 0xf4, 0x78, 0x3f, 0x91, - 0x86, 0x6e, 0x91, 0x76, 0x60, 0x9d, 0xf0, 0xc2, 0xfa, 0x95, 0x34, 0xa4, 0xaa, 0x7b, 0xad, 0x3a, - 0x7a, 0xa3, 0x67, 0xf8, 0x3b, 0x0d, 0xc7, 0x4d, 0x56, 0x66, 0xcd, 0xd4, 0x76, 0xb1, 0xd9, 0xc1, - 0x4b, 0xd4, 0x8e, 0x92, 0xa0, 0x65, 0xf6, 0xfc, 0x46, 0xe4, 0xb7, 0x73, 0x5e, 0x6f, 0x17, 0xb7, - 0xdb, 0xd6, 0xde, 0x12, 0xc1, 0x23, 0xc9, 0x6e, 0x81, 0x12, 0x22, 0x95, 0xbb, 0x01, 0x59, 0xe6, - 0x5e, 0xcd, 0xb0, 0xf1, 0x53, 0xf1, 0xb6, 0x61, 0x61, 0xbb, 0x51, 0xac, 0x37, 0x07, 0xa4, 0x40, - 0x6f, 0x4b, 0x79, 0x74, 0xeb, 0x9d, 0xa2, 0x6e, 0xbd, 0xb6, 0x07, 0xf4, 0xa4, 0x69, 0x3e, 0x9a, - 0xf4, 0x85, 0x90, 0x65, 0xf2, 0x6c, 0xaf, 0x52, 0xae, 0xe8, 0x91, 0xdf, 0x95, 0x78, 0xd5, 0x4e, - 0x4d, 0xfa, 0x56, 0x03, 0xef, 0xea, 0x75, 0xec, 0xfa, 0x93, 0xd9, 0x61, 0x07, 0xa6, 0x1a, 0x2f, - 0xd9, 0xab, 0x79, 0x78, 0x1c, 0xe5, 0x01, 0xfb, 0x4b, 0x44, 0xda, 0xd8, 0xb1, 0x88, 0x88, 0x95, - 0x5a, 0x15, 0x2a, 0x75, 0x5c, 0x15, 0x05, 0xa4, 0x50, 0xe6, 0xe0, 0x72, 0xf1, 0xeb, 0xa2, 0xa8, - 0x13, 0x99, 0x40, 0x06, 0xa6, 0xd9, 0x27, 0x4e, 0xd9, 0x7e, 0xe2, 0x34, 0xd6, 0x25, 0x4e, 0xe8, - 0x75, 0xce, 0xc0, 0x73, 0x8f, 0x30, 0xf0, 0x5c, 0x1f, 0x0e, 0x85, 0x91, 0x5c, 0x97, 0x95, 0x61, - 0x2c, 0x47, 0xbf, 0xe3, 0x91, 0x6d, 0x04, 0x63, 0x1c, 0x54, 0x5b, 0x7d, 0x39, 0xe1, 0x11, 0xc9, - 0xf0, 0xeb, 0x43, 0xbf, 0x9a, 0xc1, 0xb8, 0xc7, 0x1a, 0xe1, 0x23, 0xc5, 0xb7, 0x40, 0x4a, 0x6f, - 0x6d, 0x18, 0x7c, 0xe2, 0xd6, 0x47, 0x84, 0x69, 0xd2, 0x90, 0xcf, 0x64, 0x04, 0xd4, 0x1d, 0x3f, - 0x76, 0x2f, 0x93, 0x20, 0x45, 0xd4, 0xbc, 0xf7, 0xde, 0x4f, 0x04, 0x63, 0x6c, 0x52, 0xec, 0x02, - 0x67, 0x87, 0x7b, 0xbe, 0x1d, 0x32, 0x03, 0x47, 0x77, 0x5a, 0x5a, 0xcb, 0x68, 0xed, 0x6d, 0xeb, - 0x2f, 0x72, 0xa6, 0x0a, 0x42, 0x1c, 0xa1, 0x7e, 0x13, 0xb7, 0xb0, 0xa9, 0x59, 0xb8, 0xba, 0xbb, - 0x49, 0x7b, 0xeb, 0x98, 0xea, 0x8d, 0x42, 0x2f, 0x4e, 0x46, 0x53, 0x38, 0x84, 0x6a, 0xff, 0x27, - 0x2a, 0x37, 0xf4, 0x26, 0xa6, 0xfe, 0xed, 0xdc, 0xc7, 0xc3, 0x0e, 0x47, 0xea, 0x4d, 0x3d, 0xaa, - 0x18, 0x09, 0x22, 0x32, 0x7b, 0x33, 0x65, 0xc9, 0xa8, 0x6b, 0xcd, 0x8e, 0x65, 0x98, 0x18, 0x3d, - 0xdf, 0x45, 0xc7, 0x46, 0x20, 0xe1, 0x41, 0xe0, 0x04, 0x64, 0x1a, 0x46, 0xdd, 0xf5, 0x64, 0xe0, - 0x21, 0x71, 0x39, 0x13, 0x78, 0x8c, 0x88, 0x35, 0xb8, 0xbb, 0xde, 0xd8, 0x1e, 0x90, 0x09, 0x77, - 0xb4, 0x28, 0x14, 0x51, 0x23, 0xb8, 0x57, 0x21, 0x09, 0xa9, 0x15, 0xbd, 0xb5, 0xe9, 0x5d, 0xc4, - 0x1c, 0x87, 0xb4, 0xde, 0x6a, 0xe0, 0x8b, 0x7c, 0xa4, 0x66, 0x01, 0x32, 0x9c, 0xb7, 0x76, 0xb6, - 0xd7, 0xb1, 0x59, 0xd9, 0xa0, 0xcd, 0xed, 0xd4, 0x8c, 0x2a, 0x6e, 0xd9, 0x33, 0xb3, 0x9e, 0xdf, - 0xd0, 0x4f, 0x13, 0xd1, 0xe4, 0x9e, 0x50, 0xe2, 0x83, 0x8b, 0x43, 0x54, 0xd2, 0x43, 0x54, 0x24, - 0x89, 0xef, 0x51, 0x78, 0xfc, 0xfc, 0xfd, 0x4c, 0x12, 0xb2, 0xcb, 0xd8, 0x32, 0xf5, 0x7a, 0x07, - 0x3d, 0x99, 0x84, 0xc9, 0x2a, 0xb6, 0x56, 0x34, 0x53, 0xdb, 0xc6, 0x16, 0x59, 0x92, 0x5f, 0x2f, - 0x28, 0xa6, 0x76, 0x53, 0xb3, 0x36, 0x0c, 0x73, 0xdb, 0x56, 0x4c, 0x76, 0xf8, 0xf6, 0xd4, 0x23, - 0xdf, 0x91, 0x12, 0x22, 0x33, 0x03, 0x5d, 0x6f, 0x78, 0x85, 0xb3, 0x42, 0x65, 0x3e, 0x27, 0x2c, - 0xc2, 0x39, 0xd3, 0x84, 0x29, 0x31, 0x7e, 0x66, 0xfe, 0x89, 0x04, 0xd2, 0x92, 0xb1, 0x89, 0x3e, - 0x24, 0x41, 0x8a, 0xca, 0xd7, 0x3b, 0x3c, 0x43, 0xf2, 0x34, 0x64, 0xb7, 0x71, 0xa7, 0xa3, 0x6d, - 0x62, 0xfb, 0x7d, 0x69, 0x1e, 0x54, 0xce, 0x40, 0xba, 0x89, 0x77, 0x71, 0x93, 0x92, 0x31, 0x75, - 0xfa, 0x2a, 0xa1, 0x65, 0x4b, 0xc6, 0xe6, 0x2c, 0x29, 0xcb, 0x79, 0x85, 0x76, 0x89, 0x24, 0x55, - 0x59, 0x8e, 0x99, 0xfb, 0x20, 0x4d, 0xc3, 0xca, 0x38, 0xa4, 0x0b, 0xc5, 0xb9, 0xd5, 0x05, 0xf9, - 0x08, 0xf9, 0x6b, 0xd3, 0x37, 0x0e, 0xe9, 0xf9, 0x5c, 0x2d, 0xb7, 0x24, 0x27, 0x49, 0x3b, 0x4a, - 0xe5, 0xf9, 0x8a, 0x2c, 0x91, 0xc8, 0x95, 0x5c, 0xb9, 0x94, 0x97, 0x53, 0xca, 0x04, 0x64, 0xcf, - 0xe5, 0xd4, 0x72, 0xa9, 0xbc, 0x20, 0xa7, 0xd1, 0x43, 0x5e, 0x85, 0x75, 0xbb, 0x88, 0xdf, 0xd5, - 0x7e, 0x34, 0xf5, 0x82, 0xec, 0xdf, 0x39, 0x90, 0xdd, 0x25, 0x40, 0xf6, 0x73, 0x61, 0x0a, 0x89, - 0x86, 0x52, 0x79, 0x00, 0x43, 0xf6, 0x24, 0x8c, 0x97, 0x2b, 0xb5, 0xb5, 0xf9, 0xca, 0x6a, 0xb9, - 0x20, 0x63, 0xc2, 0x83, 0x5a, 0x69, 0xb9, 0x58, 0x59, 0xad, 0xc9, 0x1b, 0xe8, 0x8d, 0x49, 0xc8, - 0xae, 0x98, 0x46, 0x1d, 0x77, 0x3a, 0xe8, 0x55, 0x49, 0xc8, 0xe4, 0xb5, 0x56, 0x1d, 0x37, 0xd1, - 0xb3, 0x5d, 0x18, 0xbb, 0x96, 0x84, 0xe8, 0x87, 0x5e, 0xa9, 0xbf, 0x57, 0xe4, 0x9a, 0xf8, 0xae, - 0x30, 0x2f, 0x77, 0x96, 0x95, 0xe9, 0xc3, 0xbb, 0xc7, 0x1d, 0xde, 0xe5, 0x05, 0xde, 0xdd, 0x14, - 0xbe, 0xa8, 0xf8, 0xe5, 0xfc, 0x47, 0x09, 0x38, 0xbe, 0x40, 0xa6, 0x0f, 0x7a, 0x9d, 0x11, 0x6f, - 0xb7, 0xff, 0x2e, 0xb1, 0xfd, 0xcf, 0x15, 0x88, 0xee, 0x95, 0x43, 0x6c, 0xfc, 0x63, 0x4e, 0xe3, - 0xef, 0x15, 0x1a, 0x7f, 0x43, 0xc8, 0x72, 0x62, 0x6f, 0xf9, 0x4c, 0x16, 0xd2, 0x74, 0x8a, 0x3c, - 0x73, 0x0d, 0x4c, 0x56, 0x2d, 0x13, 0x6b, 0xdb, 0x9e, 0x41, 0xc9, 0x32, 0xce, 0xe3, 0x16, 0x17, - 0x0d, 0x16, 0xb8, 0xfd, 0x0c, 0x64, 0x5b, 0xc6, 0x9a, 0xb6, 0x63, 0x6d, 0x29, 0xcf, 0xd9, 0x77, - 0x6c, 0x68, 0x99, 0xf5, 0xff, 0x4a, 0x9b, 0xed, 0x22, 0x7d, 0xeb, 0x4e, 0x3a, 0x31, 0xcb, 0xb4, - 0x8c, 0xdc, 0x8e, 0xb5, 0x35, 0x77, 0xf9, 0xa7, 0x9f, 0x3e, 0x99, 0xf8, 0xdc, 0xd3, 0x27, 0x13, - 0xdf, 0x7c, 0xfa, 0x64, 0xe2, 0x77, 0xbf, 0x7d, 0xf2, 0xc8, 0xe7, 0xbe, 0x7d, 0xf2, 0xc8, 0x57, - 0xbf, 0x7d, 0xf2, 0xc8, 0x2f, 0x26, 0xdb, 0xeb, 0xeb, 0x19, 0x5a, 0xca, 0xad, 0xff, 0x37, 0x00, - 0x00, 0xff, 0xff, 0x27, 0x0e, 0xb6, 0xed, 0x10, 0x32, 0x01, 0x00, + // 11754 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x7d, 0x79, 0x74, 0x23, 0xc7, + 0x79, 0xe7, 0x00, 0x8d, 0x83, 0xfc, 0x38, 0xe4, 0xb4, 0x3a, 0xe3, 0x11, 0x5d, 0x92, 0xc6, 0x0a, + 0x25, 0x8d, 0x95, 0x91, 0x44, 0x49, 0x23, 0x1f, 0x1a, 0xdd, 0x20, 0x00, 0x92, 0x90, 0x48, 0x80, + 0x69, 0x80, 0x33, 0x51, 0xb2, 0x59, 0x6e, 0x13, 0x28, 0x92, 0xad, 0x01, 0xd1, 0x48, 0xa3, 0xc9, + 0x19, 0xfa, 0xbd, 0xdd, 0x44, 0x49, 0x1c, 0x29, 0xc9, 0x73, 0x9c, 0x38, 0xce, 0xda, 0x8a, 0xd7, + 0x96, 0x2d, 0xdf, 0x76, 0x1c, 0x47, 0x3e, 0xd7, 0x59, 0xdb, 0x59, 0x5f, 0x79, 0x8e, 0x5f, 0x62, + 0x39, 0xbe, 0x93, 0xb5, 0x1d, 0x5b, 0xf6, 0x7a, 0x9d, 0x5d, 0x7b, 0xfd, 0x9c, 0xb7, 0xbb, 0x59, + 0xaf, 0x93, 0xf5, 0xbe, 0x3a, 0xfa, 0x28, 0x10, 0xdd, 0xe8, 0x06, 0xd1, 0xa0, 0xb2, 0xf9, 0x0b, + 0xa8, 0xea, 0x3a, 0xbe, 0xfa, 0x7e, 0x5f, 0x7d, 0x55, 0xf5, 0xd5, 0x57, 0x55, 0x30, 0xdd, 0x5e, + 0xbf, 0xb9, 0x6d, 0x1a, 0x96, 0xd1, 0xb9, 0xb9, 0x6e, 0x6c, 0x6f, 0x6b, 0xad, 0x46, 0x67, 0x96, + 0x86, 0x95, 0xac, 0xd6, 0xda, 0xb3, 0xf6, 0xda, 0x18, 0x5d, 0xdb, 0xbe, 0xb0, 0x79, 0x73, 0x53, + 0x5f, 0xbf, 0xb9, 0xbd, 0x7e, 0xf3, 0xb6, 0xd1, 0xc0, 0x4d, 0x3b, 0x03, 0x0d, 0xf0, 0xe4, 0xe8, + 0x7a, 0xbf, 0x54, 0x4d, 0xa3, 0xae, 0x35, 0x3b, 0x96, 0x61, 0x62, 0x9e, 0xf2, 0x84, 0x5b, 0x25, + 0xde, 0xc5, 0x2d, 0xcb, 0x2e, 0xe1, 0xca, 0x4d, 0xc3, 0xd8, 0x6c, 0x62, 0xf6, 0x6d, 0x7d, 0x67, + 0xe3, 0xe6, 0x8e, 0x65, 0xee, 0xd4, 0x2d, 0xfe, 0xf5, 0xea, 0xee, 0xaf, 0x0d, 0xdc, 0xa9, 0x9b, + 0x7a, 0xdb, 0x32, 0x4c, 0x96, 0x62, 0xe6, 0x73, 0x4f, 0xa7, 0x40, 0x52, 0xdb, 0x75, 0xf4, 0xe9, + 0x31, 0x90, 0x72, 0xed, 0x36, 0xfa, 0x41, 0x12, 0x60, 0x01, 0x5b, 0xe7, 0xb0, 0xd9, 0xd1, 0x8d, + 0x16, 0x1a, 0x87, 0xac, 0x8a, 0x7f, 0x61, 0x07, 0x77, 0x2c, 0xf4, 0xa5, 0x24, 0x8c, 0xa9, 0xb8, + 0xd3, 0x36, 0x5a, 0x1d, 0xac, 0xdc, 0x07, 0x69, 0x6c, 0x9a, 0x86, 0x39, 0x9d, 0xb8, 0x3a, 0x71, + 0xfd, 0xc4, 0x99, 0xd3, 0xb3, 0xbc, 0xe1, 0xb3, 0x6a, 0xbb, 0x3e, 0x9b, 0x6b, 0xb7, 0x67, 0xdd, + 0x32, 0x66, 0xed, 0x4c, 0xb3, 0x45, 0x92, 0x43, 0x65, 0x19, 0x95, 0x69, 0xc8, 0xee, 0xb2, 0x04, + 0xd3, 0xc9, 0xab, 0x13, 0xd7, 0x8f, 0xab, 0x76, 0x90, 0x7c, 0x69, 0x60, 0x4b, 0xd3, 0x9b, 0x9d, + 0x69, 0x89, 0x7d, 0xe1, 0x41, 0xf4, 0xf9, 0x04, 0xa4, 0x69, 0x21, 0x4a, 0x1e, 0x52, 0x75, 0xa3, + 0x81, 0x69, 0xf5, 0x53, 0x67, 0x6e, 0x0e, 0x5f, 0xfd, 0x6c, 0xde, 0x68, 0x60, 0x95, 0x66, 0x56, + 0xae, 0x86, 0x09, 0x9b, 0x21, 0x2e, 0x19, 0xde, 0xa8, 0x99, 0x06, 0xa4, 0x48, 0x7a, 0x65, 0x0c, + 0x52, 0xe5, 0xd5, 0xa5, 0x25, 0xf9, 0x88, 0x72, 0x19, 0x4c, 0xae, 0x96, 0x1f, 0x28, 0x57, 0xce, + 0x97, 0xd7, 0x8a, 0xaa, 0x5a, 0x51, 0xe5, 0x84, 0x32, 0x09, 0xe3, 0x73, 0xb9, 0xc2, 0x5a, 0xa9, + 0xbc, 0xb2, 0x5a, 0x93, 0x93, 0xca, 0x71, 0x90, 0xcf, 0x15, 0xd5, 0x6a, 0xa9, 0x52, 0x5e, 0x2b, + 0x55, 0xd7, 0x8a, 0xcb, 0x2b, 0xb5, 0x07, 0x65, 0x89, 0x24, 0x2a, 0x57, 0x6a, 0x6b, 0xf3, 0x95, + 0xd5, 0x72, 0x41, 0xc6, 0xca, 0x04, 0x64, 0x6b, 0xa5, 0xe5, 0x62, 0x65, 0xb5, 0x26, 0x6f, 0xa0, + 0xf7, 0x48, 0x30, 0x55, 0xc5, 0x56, 0x01, 0xef, 0xea, 0x75, 0x5c, 0xb5, 0x34, 0x0b, 0xa3, 0x97, + 0x26, 0x1c, 0xc6, 0x2b, 0xab, 0x84, 0x4c, 0xe7, 0x13, 0x6f, 0xf2, 0x6d, 0xfb, 0x9a, 0x2c, 0x96, + 0x30, 0xcb, 0x73, 0xcf, 0x7a, 0xe2, 0x54, 0x6f, 0x39, 0x33, 0x37, 0xc1, 0x84, 0xe7, 0x9b, 0x32, + 0x05, 0x30, 0x97, 0xcb, 0x3f, 0xb0, 0xa0, 0x52, 0x0a, 0x8f, 0x90, 0xf0, 0x7c, 0x45, 0x2d, 0xf2, + 0x70, 0x02, 0xbd, 0xd4, 0x0b, 0x7f, 0x41, 0x84, 0x7f, 0xb6, 0x3f, 0x31, 0x3d, 0x44, 0x00, 0x7d, + 0xd0, 0x81, 0x73, 0x41, 0x80, 0xf3, 0xb6, 0x68, 0xc5, 0x45, 0x83, 0x74, 0x71, 0x30, 0x48, 0xcb, + 0x95, 0x42, 0x71, 0x8d, 0x20, 0x58, 0xad, 0xe5, 0xd4, 0x5a, 0xb1, 0x20, 0x63, 0xf4, 0xaa, 0x24, + 0x8c, 0x55, 0xb7, 0x76, 0xac, 0x86, 0x71, 0x51, 0xe8, 0x28, 0xbf, 0xe2, 0xe5, 0xd4, 0x3d, 0x22, + 0xa7, 0xae, 0xdf, 0xdf, 0x34, 0x5e, 0x82, 0x0f, 0x8f, 0xde, 0xe7, 0xf0, 0x28, 0x27, 0xf0, 0xe8, + 0xa6, 0xb0, 0x05, 0x1d, 0x16, 0x77, 0xbe, 0x30, 0x09, 0x99, 0xf3, 0x5a, 0xb3, 0x89, 0x2d, 0xf4, + 0xad, 0x24, 0x64, 0xf2, 0x26, 0x26, 0x72, 0x7d, 0x83, 0x2b, 0xd6, 0x08, 0xc6, 0x4c, 0xc3, 0xb0, + 0x56, 0x34, 0x6b, 0x8b, 0xb6, 0x69, 0x5c, 0x75, 0xc2, 0x77, 0xa4, 0x1e, 0xfd, 0xb6, 0x94, 0x40, + 0x7f, 0xe0, 0x65, 0xe4, 0xbd, 0x22, 0x23, 0x7f, 0x4a, 0x68, 0x3f, 0xab, 0x68, 0x96, 0x55, 0xe2, + 0xa3, 0x70, 0x10, 0x8c, 0x6d, 0xb7, 0xf0, 0xb6, 0xd1, 0xd2, 0xeb, 0xbc, 0xe5, 0x4e, 0x18, 0x7d, + 0xd4, 0xe1, 0xf2, 0x9c, 0xc0, 0xe5, 0xd9, 0xd0, 0xb5, 0x44, 0x63, 0x73, 0x75, 0x00, 0x36, 0x3f, + 0x07, 0xae, 0x98, 0xcf, 0x95, 0x96, 0x8a, 0x85, 0xb5, 0x5a, 0x65, 0x2d, 0xaf, 0x16, 0x73, 0xb5, + 0xe2, 0xda, 0x52, 0x25, 0x9f, 0x5b, 0x5a, 0x53, 0x8b, 0x2b, 0x15, 0x19, 0xa3, 0xff, 0x92, 0x24, + 0xcc, 0xad, 0x1b, 0xbb, 0xd8, 0x44, 0x0b, 0xa1, 0xf8, 0x1c, 0xc4, 0x13, 0x8e, 0xc1, 0xcb, 0x42, + 0x6b, 0x7d, 0xce, 0x1d, 0x4e, 0x81, 0x8f, 0x38, 0x7f, 0x2c, 0x94, 0x06, 0x0f, 0x2c, 0xea, 0x19, + 0xc0, 0xe9, 0xff, 0x91, 0x84, 0x6c, 0xde, 0x68, 0xed, 0x62, 0xd3, 0x42, 0xf7, 0x0a, 0x9c, 0x76, + 0xb8, 0x99, 0x10, 0xb9, 0x49, 0x06, 0x35, 0xdc, 0xb2, 0x4c, 0xa3, 0xbd, 0x67, 0x0f, 0x77, 0x3c, + 0x88, 0xde, 0x1c, 0x95, 0xc3, 0xbc, 0x66, 0xff, 0x71, 0xb5, 0x77, 0x45, 0x02, 0x79, 0x52, 0x57, + 0x07, 0x78, 0x22, 0x0a, 0x2e, 0xbd, 0x09, 0x88, 0x86, 0xcb, 0x99, 0xe8, 0xb8, 0xa0, 0xcf, 0x26, + 0x61, 0x92, 0x75, 0xbe, 0x2a, 0xee, 0xd0, 0xe9, 0xc9, 0x0d, 0xa1, 0x98, 0xcf, 0x45, 0xf9, 0x77, + 0xbd, 0x8c, 0x9e, 0x17, 0x19, 0x7d, 0x8b, 0x7f, 0x47, 0xe7, 0x75, 0xf9, 0xb0, 0xfb, 0x38, 0xa4, + 0x2d, 0xe3, 0x02, 0xb6, 0xdb, 0xc8, 0x02, 0xe8, 0x2d, 0x0e, 0x3b, 0x4b, 0x02, 0x3b, 0x9f, 0x1f, + 0xb5, 0x9a, 0xf8, 0x99, 0xfa, 0x8e, 0x24, 0x1c, 0xcd, 0x37, 0x8d, 0x8e, 0xc3, 0xd3, 0xe7, 0xb8, + 0x3c, 0x75, 0x1a, 0x97, 0xf0, 0x36, 0xee, 0x47, 0x09, 0x0f, 0x1f, 0x8b, 0x22, 0x1f, 0x7b, 0xcb, + 0x8b, 0xa7, 0x78, 0x1f, 0xbd, 0xf0, 0x66, 0x87, 0x61, 0x8b, 0x02, 0xc3, 0x9e, 0x17, 0xb1, 0xbc, + 0xf8, 0xf9, 0xf5, 0xbe, 0x9f, 0x84, 0x6c, 0xae, 0x5e, 0x37, 0x76, 0x5a, 0x16, 0xfa, 0x9b, 0x04, + 0x64, 0xf2, 0x46, 0x6b, 0x43, 0xdf, 0x54, 0x4e, 0xc1, 0x14, 0x6e, 0x69, 0xeb, 0x4d, 0x5c, 0xd0, + 0x2c, 0x6d, 0x57, 0xc7, 0x17, 0x69, 0x03, 0xc6, 0xd4, 0xae, 0x58, 0x42, 0x14, 0x8f, 0xc1, 0xeb, + 0x3b, 0x9b, 0x94, 0xa8, 0x31, 0xd5, 0x1b, 0xa5, 0xdc, 0x0e, 0x97, 0xb3, 0xe0, 0x8a, 0x89, 0x4d, + 0xdc, 0xc4, 0x5a, 0x07, 0xe7, 0xb7, 0xb4, 0x56, 0x0b, 0x37, 0x69, 0xaf, 0x1d, 0x53, 0xfd, 0x3e, + 0x2b, 0x33, 0x70, 0x94, 0x7d, 0xaa, 0xb6, 0xb5, 0x3a, 0xee, 0x4c, 0xa7, 0x68, 0x72, 0x21, 0x4e, + 0xb9, 0x09, 0xd2, 0xf8, 0x92, 0x65, 0x6a, 0xd3, 0x0d, 0x8a, 0xd7, 0xe5, 0xb3, 0x6c, 0x89, 0x30, + 0x6b, 0x2f, 0x11, 0x66, 0xab, 0x74, 0x01, 0xa1, 0xb2, 0x54, 0xe8, 0x63, 0x19, 0x67, 0xe8, 0x7e, + 0x9d, 0x67, 0x4a, 0xaa, 0x40, 0xaa, 0xa5, 0x6d, 0x63, 0x2e, 0x17, 0xf4, 0xbf, 0x72, 0x1a, 0x8e, + 0x69, 0xbb, 0x9a, 0xa5, 0x99, 0x4b, 0x64, 0xf1, 0x42, 0x87, 0x1b, 0xca, 0xf2, 0xc5, 0x23, 0x6a, + 0xf7, 0x07, 0xe5, 0x4a, 0x18, 0xa7, 0xab, 0x1b, 0x9a, 0x8a, 0xe9, 0x22, 0x37, 0x42, 0xb9, 0x1e, + 0x8e, 0x69, 0xcd, 0xf6, 0x96, 0x56, 0x6a, 0xed, 0xea, 0x16, 0x26, 0x08, 0x4d, 0x1f, 0xa7, 0x69, + 0xba, 0xa3, 0x59, 0xc7, 0x9e, 0x1b, 0x83, 0x0c, 0xab, 0x00, 0xbd, 0x3c, 0x1d, 0x7a, 0x8d, 0xc2, + 0x20, 0x0c, 0x9e, 0x32, 0xdc, 0x02, 0x59, 0x8d, 0xa5, 0xa3, 0x4d, 0x99, 0x38, 0x73, 0xc2, 0x29, + 0x83, 0x2e, 0xd7, 0xec, 0x52, 0x54, 0x3b, 0x99, 0x72, 0x1b, 0x64, 0xea, 0x54, 0x20, 0x68, 0xab, + 0x26, 0xce, 0x5c, 0xd1, 0xbb, 0x52, 0x9a, 0x44, 0xe5, 0x49, 0xd1, 0xd7, 0xa4, 0x50, 0xcb, 0x9a, + 0x20, 0x8a, 0xa3, 0xc9, 0xfd, 0xf7, 0x92, 0x03, 0x8c, 0x8a, 0x37, 0xc2, 0xf5, 0xb9, 0x7c, 0xbe, + 0xb2, 0x5a, 0xae, 0xf1, 0x31, 0xb1, 0xb0, 0x36, 0xb7, 0x5a, 0x5b, 0x73, 0x47, 0x4a, 0x3a, 0xf7, + 0x5b, 0x23, 0x53, 0x41, 0x99, 0x48, 0xc3, 0xa9, 0x3e, 0xa9, 0x8b, 0xb5, 0xb5, 0x72, 0x6e, 0xb9, + 0x28, 0x6f, 0x84, 0x28, 0xb9, 0x58, 0x5b, 0xcb, 0x9d, 0xcb, 0xd5, 0x72, 0xaa, 0xbc, 0x29, 0x8e, + 0xce, 0xd5, 0x5a, 0x65, 0x65, 0x4d, 0x5d, 0x2d, 0x97, 0x4b, 0xe5, 0x05, 0x56, 0x35, 0x99, 0xd4, + 0x9c, 0x70, 0x13, 0x9c, 0x57, 0x4b, 0xb5, 0xe2, 0x5a, 0xbe, 0x52, 0x9e, 0x2f, 0x2d, 0xc8, 0x7a, + 0xbf, 0xa1, 0xfd, 0x21, 0xe5, 0x38, 0x1c, 0x63, 0x8d, 0x3e, 0xc7, 0xf2, 0x15, 0x8a, 0xf2, 0xaf, + 0x66, 0x95, 0x29, 0x18, 0x2f, 0x17, 0x6b, 0x9c, 0x33, 0x2f, 0xce, 0x2a, 0x57, 0xc0, 0x09, 0x12, + 0xce, 0x57, 0xca, 0xe5, 0x62, 0xbe, 0x46, 0x96, 0x7a, 0x6a, 0x71, 0x7e, 0xb5, 0x5a, 0x2c, 0xc8, + 0xbf, 0x96, 0x55, 0x64, 0x98, 0x20, 0x1f, 0x2b, 0xf3, 0xf3, 0x4b, 0xa5, 0x72, 0x51, 0x7e, 0x24, + 0x8b, 0xde, 0x98, 0x72, 0x67, 0x66, 0x9e, 0x85, 0xc2, 0x6f, 0xa5, 0x3c, 0xd2, 0x9a, 0x13, 0xa5, + 0xf5, 0x86, 0x9e, 0xd8, 0x07, 0x4f, 0xae, 0x3e, 0xec, 0xc8, 0x51, 0x41, 0x90, 0xa3, 0x5b, 0x22, + 0x94, 0x15, 0x4d, 0x90, 0xfe, 0x7c, 0x10, 0x41, 0x7a, 0x16, 0x5c, 0x56, 0xae, 0xac, 0x71, 0xc4, + 0xab, 0xce, 0x92, 0xf8, 0x6a, 0xb8, 0xb2, 0x5c, 0x64, 0xc0, 0xa8, 0xc5, 0x7c, 0xe5, 0x5c, 0x51, + 0x5d, 0x3b, 0x9f, 0x5b, 0x5a, 0x2a, 0xd6, 0xd6, 0xe6, 0x4b, 0x6a, 0xb5, 0x26, 0x6f, 0xf4, 0x03, + 0x6f, 0x53, 0xb9, 0x06, 0x9e, 0xe3, 0x86, 0xd7, 0x8a, 0x3f, 0x53, 0xaa, 0xd6, 0xaa, 0x54, 0x94, + 0xf2, 0x15, 0x55, 0x5d, 0x5d, 0x21, 0x0b, 0x93, 0x2d, 0xe5, 0x04, 0x28, 0x6e, 0x29, 0xea, 0x6a, + 0x99, 0x89, 0x8d, 0x4e, 0xea, 0xe7, 0xf5, 0xd9, 0xd5, 0x93, 0x05, 0xcd, 0x4a, 0x51, 0x9d, 0xaf, + 0xa8, 0xcb, 0xc5, 0x82, 0xfc, 0x50, 0x3f, 0xc9, 0xbb, 0xa0, 0x9c, 0x82, 0x99, 0x5c, 0xb9, 0x52, + 0x5b, 0x2c, 0xaa, 0x6b, 0xb9, 0xf2, 0x83, 0xb5, 0x07, 0x57, 0x8a, 0x6b, 0x2b, 0x6a, 0x25, 0x5f, + 0xac, 0x56, 0xd7, 0x4a, 0x55, 0x3b, 0xb1, 0xdc, 0x24, 0x24, 0xd8, 0x02, 0x5f, 0xaa, 0xae, 0x15, + 0x8a, 0x4b, 0x45, 0x42, 0xda, 0x36, 0x7a, 0x89, 0x04, 0x99, 0x02, 0x6e, 0x62, 0x0b, 0xa3, 0x9f, + 0x74, 0x95, 0xed, 0x09, 0xc8, 0x98, 0x98, 0x4c, 0xb8, 0xf8, 0x90, 0xc2, 0x43, 0xe8, 0x6f, 0x92, + 0x51, 0x95, 0x1d, 0x2b, 0xdb, 0x47, 0xd9, 0x3d, 0x1f, 0x32, 0x1d, 0x4b, 0xb3, 0x76, 0x3a, 0x5c, + 0xd7, 0x5d, 0xd5, 0x5b, 0xd7, 0xcd, 0x56, 0x69, 0x22, 0x95, 0x27, 0x46, 0x7f, 0x95, 0x88, 0xa2, + 0xbc, 0x7a, 0x52, 0x10, 0x4d, 0xe6, 0xf4, 0x01, 0x44, 0xee, 0x24, 0x20, 0x0f, 0xc3, 0x73, 0x4b, + 0x6a, 0x31, 0x57, 0x78, 0xd0, 0x61, 0x3c, 0x26, 0x22, 0xe9, 0xfd, 0x9e, 0xaf, 0x95, 0xce, 0x15, + 0xe5, 0x0d, 0xf4, 0xb1, 0x34, 0x64, 0xaa, 0xb8, 0x89, 0xeb, 0x16, 0xba, 0xd3, 0xc5, 0x63, 0x0a, + 0x92, 0x7a, 0x83, 0x0f, 0x7d, 0x49, 0xbd, 0x21, 0x2c, 0xb0, 0x92, 0x3d, 0x17, 0xb2, 0x3f, 0x4a, + 0x45, 0x45, 0x8a, 0xd5, 0x7a, 0xb8, 0xc3, 0xd2, 0x27, 0x22, 0x0d, 0x4b, 0x3d, 0x29, 0x8e, 0x86, + 0xec, 0xe7, 0x93, 0x31, 0x2c, 0xd6, 0xc2, 0x28, 0x85, 0x0d, 0x1f, 0xa5, 0xd0, 0x35, 0xd8, 0xcc, + 0x97, 0xca, 0x85, 0x35, 0x47, 0x4e, 0xca, 0xf3, 0x15, 0x79, 0x4b, 0x99, 0x85, 0xd3, 0x9e, 0xd2, + 0x89, 0xc6, 0xe0, 0x35, 0xe4, 0xca, 0x85, 0xb5, 0xe5, 0x72, 0x71, 0xb9, 0x52, 0x2e, 0xe5, 0x99, + 0x69, 0xa4, 0x58, 0x63, 0x5a, 0xa6, 0x4b, 0x87, 0x54, 0x8b, 0x39, 0x35, 0xbf, 0x48, 0xd5, 0x4d, + 0xa1, 0x28, 0x3f, 0xa4, 0x3c, 0x17, 0xae, 0xf1, 0x90, 0xc2, 0x55, 0xd1, 0x8a, 0x5a, 0x2c, 0x14, + 0xe7, 0x4b, 0x65, 0x32, 0x34, 0x2e, 0x55, 0xf2, 0x0f, 0x54, 0xc3, 0x6b, 0x1b, 0xf4, 0x7f, 0x92, + 0x90, 0xaa, 0x5a, 0x46, 0x1b, 0xfd, 0x94, 0x2b, 0xc3, 0x27, 0x01, 0x4c, 0xbc, 0x6d, 0xec, 0xd2, + 0x89, 0x29, 0xd7, 0x2b, 0x9e, 0x18, 0xf4, 0xa7, 0xe1, 0x6d, 0x58, 0x8e, 0x5a, 0x30, 0xda, 0x3e, + 0xe3, 0xd2, 0x0f, 0xc3, 0xd9, 0xb0, 0xfc, 0x0b, 0x8a, 0x26, 0x46, 0xbf, 0x91, 0x18, 0x40, 0x8c, + 0x10, 0x9c, 0xf0, 0x68, 0x00, 0x82, 0x97, 0xcd, 0x40, 0xac, 0x5c, 0x0e, 0x3f, 0xd1, 0x85, 0x19, + 0x85, 0x6a, 0x43, 0xf9, 0x49, 0xb8, 0xca, 0x0b, 0xd5, 0x72, 0xe5, 0x5c, 0xd1, 0x91, 0x8f, 0x42, + 0xae, 0x96, 0x93, 0x37, 0xd1, 0xe7, 0x24, 0x48, 0x2d, 0x1b, 0xbb, 0x18, 0x5d, 0xe3, 0x32, 0x7f, + 0x1a, 0xb2, 0x2d, 0x7c, 0xd1, 0x63, 0x90, 0xb1, 0x83, 0xe8, 0x8d, 0x52, 0x54, 0xb6, 0x93, 0xb2, + 0x7d, 0xd8, 0xfe, 0xe5, 0x64, 0x14, 0xb6, 0xf7, 0x28, 0x28, 0x1a, 0xdb, 0xff, 0x76, 0x10, 0xb6, + 0xfb, 0xb0, 0x16, 0x2b, 0x33, 0x70, 0xd2, 0xfd, 0x50, 0x2a, 0x14, 0xcb, 0xb5, 0xd2, 0xfc, 0x83, + 0x2e, 0x73, 0x4b, 0x6a, 0x28, 0xf6, 0xf7, 0xd3, 0x0e, 0xc1, 0x93, 0xc5, 0x69, 0x38, 0xee, 0x7e, + 0x5b, 0x60, 0xf3, 0x3d, 0xf2, 0xe5, 0x21, 0xf4, 0xb2, 0x34, 0x1c, 0x65, 0xda, 0x72, 0xb5, 0xdd, + 0x20, 0x8b, 0xa3, 0xeb, 0x04, 0x43, 0x84, 0xa5, 0x6f, 0xe3, 0x9f, 0x35, 0x5a, 0xf6, 0xfa, 0xc8, + 0x09, 0xa3, 0xcf, 0x84, 0x36, 0x41, 0x88, 0x3a, 0x99, 0xd5, 0xe2, 0x83, 0xf3, 0x8f, 0x42, 0x19, + 0x1b, 0x42, 0x14, 0x18, 0x0d, 0xef, 0x5f, 0x1d, 0x76, 0x37, 0xf3, 0x87, 0x62, 0xc3, 0x17, 0x8a, + 0xcd, 0x99, 0x47, 0x92, 0x30, 0x5e, 0xd3, 0xb7, 0xf1, 0x8b, 0x8c, 0x16, 0xee, 0x28, 0x59, 0x90, + 0x16, 0x96, 0x6b, 0xf2, 0x11, 0xf2, 0xa7, 0x98, 0xaf, 0xc9, 0x09, 0xfa, 0xa7, 0x48, 0xaa, 0x26, + 0x7f, 0x72, 0x35, 0x59, 0x22, 0x7f, 0x96, 0x8b, 0x35, 0x39, 0x45, 0xfe, 0x94, 0x8b, 0x35, 0x39, + 0x4d, 0xfe, 0xac, 0x2c, 0xd5, 0xe4, 0x0c, 0xf9, 0x53, 0xaa, 0xd6, 0xe4, 0x2c, 0xf9, 0x33, 0x57, + 0xad, 0xc9, 0x63, 0xe4, 0xcf, 0xb9, 0x6a, 0x4d, 0x1e, 0x27, 0x7f, 0xf2, 0xb5, 0x9a, 0x0c, 0xe4, + 0xcf, 0xfd, 0xd5, 0x9a, 0x3c, 0x41, 0xfe, 0xe4, 0xf2, 0x35, 0xf9, 0x28, 0xfd, 0x53, 0xac, 0xc9, + 0x93, 0xe4, 0x4f, 0xb5, 0x5a, 0x93, 0xa7, 0x68, 0xc9, 0xd5, 0x9a, 0x7c, 0x8c, 0xd6, 0x55, 0xaa, + 0xc9, 0x32, 0xf9, 0xb3, 0x58, 0xad, 0xc9, 0x97, 0xd1, 0xc4, 0xd5, 0x9a, 0xac, 0xd0, 0x4a, 0xab, + 0x35, 0xf9, 0x27, 0x68, 0x9a, 0x6a, 0x4d, 0x3e, 0x4e, 0xab, 0xa8, 0xd6, 0xe4, 0x67, 0x51, 0x32, + 0x8a, 0x35, 0xf9, 0x04, 0x4d, 0xa3, 0xd6, 0xe4, 0xcb, 0xe9, 0xa7, 0x72, 0x4d, 0x9e, 0xa6, 0x84, + 0x15, 0x6b, 0xf2, 0xb3, 0xe9, 0x1f, 0xb5, 0x26, 0x23, 0xfa, 0x29, 0x57, 0x93, 0xaf, 0x40, 0x57, + 0xc1, 0xf8, 0x02, 0xb6, 0x18, 0xbe, 0x48, 0x06, 0x69, 0x01, 0x5b, 0xde, 0xd5, 0xc6, 0x37, 0x8e, + 0xc1, 0xf8, 0x79, 0xc3, 0xbc, 0xd0, 0x69, 0x6b, 0x75, 0x8c, 0x3e, 0xc0, 0xf6, 0xf9, 0xf2, 0x3b, + 0xa6, 0x89, 0x5b, 0x42, 0xba, 0xc7, 0xc3, 0x9b, 0xc9, 0xec, 0xd2, 0x66, 0xdd, 0x92, 0x7c, 0xa6, + 0x2c, 0x57, 0xc3, 0xc4, 0x45, 0x3b, 0x75, 0xa9, 0x61, 0x8b, 0x93, 0x27, 0x2a, 0xac, 0xc9, 0xac, + 0x7f, 0x95, 0xf1, 0x9b, 0x80, 0xde, 0x99, 0x84, 0xcc, 0x02, 0xb6, 0x72, 0xcd, 0xa6, 0x97, 0x6f, + 0x8f, 0x79, 0xf9, 0x36, 0x27, 0xf2, 0xed, 0x46, 0xff, 0x46, 0xe4, 0x9a, 0x4d, 0x1f, 0x9e, 0xcd, + 0xc0, 0x51, 0x0f, 0x83, 0xc8, 0xb4, 0x5c, 0xba, 0x7e, 0x5c, 0x15, 0xe2, 0xd0, 0x1b, 0x1c, 0xae, + 0x15, 0x05, 0xae, 0xdd, 0x1a, 0xa5, 0xc2, 0xf8, 0x39, 0xf6, 0x11, 0x77, 0x07, 0xe8, 0xaa, 0x40, + 0x2b, 0x12, 0x7a, 0xc5, 0x00, 0x5c, 0x0c, 0xb4, 0xe1, 0xf4, 0x97, 0xbc, 0xa8, 0x3c, 0x1c, 0x82, + 0x01, 0x66, 0x10, 0x1e, 0xfe, 0xb7, 0x24, 0xc8, 0x55, 0x6c, 0x95, 0x3a, 0x8b, 0xfa, 0xe6, 0x56, + 0x53, 0xdf, 0xdc, 0xb2, 0x70, 0x03, 0x3d, 0x20, 0x8c, 0x3b, 0xc6, 0xfa, 0x43, 0xb8, 0x6e, 0x95, + 0xec, 0xc5, 0x89, 0x13, 0x56, 0xae, 0x85, 0x49, 0xdd, 0x9b, 0x8f, 0xdb, 0x1d, 0xc5, 0x48, 0xf4, + 0xeb, 0x5e, 0xde, 0x2f, 0x89, 0xbc, 0x7f, 0x81, 0x0f, 0x33, 0xba, 0x29, 0xf2, 0x19, 0xa3, 0xfe, + 0xd0, 0xe1, 0x71, 0x45, 0xe0, 0xf1, 0x9d, 0x83, 0x15, 0x3b, 0x12, 0xb3, 0xb8, 0xbd, 0xf4, 0xf3, + 0x6c, 0x32, 0x74, 0x09, 0x53, 0x62, 0xbf, 0x30, 0xfd, 0xcf, 0x44, 0x74, 0xf9, 0x0d, 0x5a, 0xec, + 0x45, 0x96, 0xce, 0x21, 0xac, 0xc3, 0x06, 0xe1, 0xd7, 0xaf, 0x48, 0x90, 0x29, 0x5e, 0x6a, 0x1b, + 0xe2, 0x8e, 0x98, 0x02, 0xa9, 0xb6, 0x3b, 0xcd, 0xa5, 0xff, 0x43, 0x74, 0xc8, 0xf7, 0x0f, 0xa0, + 0x03, 0x58, 0xdd, 0x3e, 0x3a, 0xc0, 0x26, 0x23, 0xe9, 0x21, 0xe3, 0x46, 0x48, 0x53, 0x4f, 0x1a, + 0xbe, 0x22, 0x76, 0x97, 0xd0, 0x76, 0x11, 0x45, 0xf2, 0x55, 0x65, 0x89, 0x22, 0xa3, 0xd0, 0x93, + 0x9c, 0x11, 0xe8, 0xd9, 0x97, 0x25, 0x20, 0x53, 0xa1, 0xbd, 0x1e, 0xfd, 0x7a, 0x0a, 0x52, 0x95, + 0x36, 0x6e, 0xa1, 0x77, 0x78, 0x0c, 0xf7, 0x57, 0xc2, 0x78, 0xdd, 0x68, 0x59, 0xf8, 0x92, 0xab, + 0x25, 0xdc, 0x08, 0x41, 0x85, 0x24, 0xbb, 0x54, 0xc8, 0x34, 0x64, 0x2d, 0x93, 0x41, 0xc6, 0xbd, + 0x72, 0x78, 0x50, 0x29, 0xc3, 0x8c, 0xde, 0xaa, 0x37, 0x77, 0x1a, 0x58, 0xc5, 0x4d, 0x8d, 0xd0, + 0xde, 0xc9, 0x75, 0x0a, 0xb8, 0x8d, 0x5b, 0x0d, 0xdc, 0xb2, 0x18, 0x35, 0xf6, 0x66, 0x44, 0x88, + 0x94, 0xe2, 0x24, 0xf9, 0x6e, 0x11, 0xfe, 0xe7, 0x0a, 0xfc, 0x66, 0x39, 0x66, 0x49, 0x2b, 0x7d, + 0x90, 0x3f, 0x0b, 0xc0, 0x5a, 0x70, 0x4e, 0xc7, 0x17, 0xb9, 0xb5, 0xe4, 0xd9, 0x5d, 0xd6, 0x92, + 0x8a, 0x93, 0x40, 0xf5, 0x24, 0x46, 0x7f, 0xe6, 0x40, 0x7e, 0x9f, 0x00, 0xf9, 0x8d, 0x21, 0x49, + 0x88, 0x86, 0xf6, 0xbf, 0x18, 0x60, 0x32, 0x2d, 0xf8, 0x14, 0x49, 0xca, 0xb3, 0xe1, 0x59, 0xb6, + 0x1d, 0xa0, 0x5c, 0x2c, 0x16, 0xaa, 0x6b, 0xab, 0x2b, 0x0b, 0x6a, 0xae, 0x50, 0x94, 0x01, 0x7d, + 0x30, 0x09, 0x69, 0xba, 0x6b, 0x86, 0xf2, 0x43, 0x90, 0x05, 0xf4, 0xbd, 0x44, 0xd8, 0x65, 0x2a, + 0x67, 0x0f, 0xad, 0xdb, 0x47, 0xc1, 0xbd, 0x36, 0x94, 0x75, 0x20, 0xa0, 0xa0, 0xf8, 0xbb, 0x15, + 0xe9, 0x4a, 0xd5, 0x2d, 0xe3, 0xe2, 0xff, 0xff, 0x5d, 0x89, 0xb4, 0xf2, 0x90, 0xbb, 0x52, 0x0f, + 0x12, 0x9e, 0x49, 0x5d, 0xe9, 0xb1, 0x94, 0x33, 0x95, 0x7d, 0xdc, 0x23, 0x0d, 0xb7, 0xba, 0x4e, + 0x8b, 0x89, 0xe0, 0x9d, 0x55, 0x3b, 0x9d, 0x92, 0x83, 0x49, 0xbd, 0x65, 0x61, 0xb3, 0xa5, 0x35, + 0xe7, 0x9b, 0xda, 0x26, 0x9b, 0xe0, 0x7b, 0x6d, 0xb3, 0x8c, 0xa7, 0x25, 0x4f, 0x1a, 0x55, 0xcc, + 0xa1, 0x9c, 0x04, 0xb0, 0xf0, 0x76, 0xbb, 0xa9, 0x59, 0xae, 0x30, 0x79, 0x62, 0xd0, 0x77, 0x43, + 0x7b, 0x50, 0xd9, 0xfd, 0xab, 0x8f, 0x07, 0x95, 0x23, 0xd3, 0x52, 0x97, 0x4c, 0x3b, 0xc3, 0x69, + 0x2a, 0xc4, 0x70, 0xea, 0xe5, 0x56, 0x3a, 0x1c, 0xb7, 0xd0, 0xeb, 0x42, 0xb9, 0x68, 0x05, 0x35, + 0x23, 0x7e, 0x3d, 0xf1, 0xb8, 0x04, 0x53, 0xac, 0xea, 0x39, 0xc3, 0xb8, 0xb0, 0xad, 0x99, 0x17, + 0xd0, 0x5d, 0x07, 0x11, 0x11, 0xf4, 0x69, 0x2f, 0x7e, 0x0b, 0x22, 0x7e, 0xb7, 0xfa, 0x37, 0xdc, + 0xae, 0x3d, 0x04, 0x8e, 0xdd, 0xba, 0xe9, 0x56, 0xd1, 0xf9, 0x36, 0x0c, 0x91, 0x6f, 0x75, 0x90, + 0xb9, 0x5f, 0x40, 0xe6, 0x05, 0x91, 0x09, 0x8c, 0x1f, 0xa1, 0x27, 0x1d, 0x84, 0x6c, 0xb5, 0x79, + 0x40, 0x84, 0xbe, 0x3e, 0x18, 0x42, 0x76, 0xed, 0x03, 0x20, 0x24, 0x83, 0x74, 0x01, 0xef, 0xf1, + 0x0e, 0x48, 0xfe, 0x7a, 0xc9, 0x4e, 0xc5, 0x87, 0x99, 0x0f, 0xc9, 0x23, 0xc1, 0xec, 0xb8, 0x48, + 0x42, 0xa5, 0x3d, 0x04, 0xe4, 0xfe, 0xda, 0x8b, 0xdc, 0xb2, 0x88, 0xdc, 0x0b, 0xfb, 0xb3, 0x81, + 0xd1, 0x30, 0x9a, 0x1e, 0xf6, 0x4e, 0x07, 0xad, 0x15, 0x01, 0xad, 0xbb, 0x06, 0x24, 0x33, 0x7e, + 0xcc, 0xbe, 0x94, 0x82, 0x71, 0xdb, 0xaf, 0xcd, 0x42, 0xef, 0x4f, 0x08, 0xbb, 0xd9, 0x1d, 0x63, + 0xc7, 0xac, 0x93, 0x36, 0x48, 0xd7, 0x8f, 0xab, 0x3c, 0xe4, 0x65, 0x4b, 0x32, 0xe4, 0x00, 0xda, + 0x67, 0xf4, 0xdb, 0x3f, 0xc0, 0xa6, 0xa2, 0x0e, 0xb0, 0xe8, 0xa5, 0x52, 0xd8, 0xa5, 0xa8, 0xc0, + 0xfd, 0x2a, 0xb6, 0x9e, 0x89, 0x63, 0xe8, 0x47, 0x42, 0xad, 0x62, 0xfb, 0xb4, 0x24, 0x9a, 0xf0, + 0x54, 0x06, 0x98, 0x8c, 0x5d, 0x01, 0x97, 0xdb, 0x29, 0x2a, 0x73, 0xf7, 0x17, 0xf3, 0xb5, 0x35, + 0x3a, 0x13, 0x5b, 0x55, 0x97, 0x64, 0x09, 0xbd, 0x38, 0x05, 0x32, 0x23, 0x8d, 0xd1, 0x59, 0xdb, + 0x6b, 0x63, 0xf4, 0x8b, 0x87, 0x3c, 0x11, 0x43, 0xdf, 0xf7, 0x2a, 0x93, 0x92, 0x28, 0x27, 0xb7, + 0xf9, 0x73, 0xd7, 0x6d, 0x82, 0x8f, 0xb8, 0x0c, 0xd0, 0x2b, 0x02, 0x24, 0x0c, 0x7d, 0xd2, 0x11, + 0x80, 0x25, 0x41, 0x00, 0x6e, 0x1f, 0x80, 0xc4, 0x43, 0x96, 0x83, 0x4f, 0x25, 0x61, 0xd2, 0x9e, + 0x46, 0xcc, 0x63, 0xab, 0xbe, 0x85, 0xce, 0x86, 0x5d, 0x9b, 0xc9, 0x20, 0xed, 0x98, 0x4d, 0x4e, + 0x25, 0xf9, 0x8b, 0xfe, 0x31, 0x11, 0x76, 0xcf, 0x83, 0xf3, 0x46, 0xa8, 0xd9, 0x67, 0x61, 0x1b, + 0x6e, 0x47, 0x23, 0x44, 0x81, 0xf1, 0xab, 0xeb, 0xaf, 0x26, 0x01, 0x6a, 0x86, 0x33, 0x69, 0x3d, + 0x00, 0x27, 0x05, 0x27, 0xeb, 0xbc, 0xc8, 0xc9, 0x9e, 0x2b, 0x7a, 0xb7, 0xda, 0xe8, 0x63, 0x29, + 0x7a, 0xa3, 0xc3, 0xe2, 0x79, 0x81, 0xc5, 0x67, 0x22, 0xd5, 0x14, 0x3f, 0x7f, 0x3f, 0x98, 0x84, + 0xf1, 0xc2, 0x4e, 0xbb, 0xa9, 0xd7, 0xc9, 0xba, 0xf1, 0xb9, 0x21, 0xd9, 0x8b, 0x5e, 0x9c, 0x8c, + 0x38, 0xfa, 0x38, 0x75, 0xf8, 0xf0, 0x92, 0xb9, 0x2e, 0x25, 0x6d, 0xd7, 0xa5, 0x90, 0x66, 0xcd, + 0x3e, 0x85, 0x8f, 0x40, 0x3c, 0x25, 0x38, 0x56, 0x69, 0xe3, 0xd6, 0x9c, 0x89, 0xb5, 0x46, 0xdd, + 0xdc, 0xd9, 0x5e, 0xef, 0xa0, 0x5c, 0x58, 0x19, 0xf5, 0x58, 0x5b, 0x92, 0x82, 0xb5, 0x05, 0xfd, + 0x9a, 0x77, 0x70, 0x5f, 0x14, 0xd9, 0x7b, 0xc6, 0xcf, 0xca, 0xe7, 0xa1, 0x61, 0x80, 0xc9, 0x5f, + 0x24, 0xab, 0x73, 0x97, 0xc9, 0x25, 0x15, 0xc5, 0xe4, 0xf2, 0x36, 0x07, 0xd9, 0x07, 0x04, 0x64, + 0x5f, 0x18, 0xbd, 0x5d, 0x23, 0xd9, 0x3c, 0x98, 0xaa, 0x62, 0xcb, 0x07, 0xde, 0x6b, 0x61, 0x72, + 0xdd, 0xfd, 0xe2, 0x40, 0x2c, 0x46, 0x12, 0x55, 0xa4, 0x3b, 0x9b, 0xa4, 0xe4, 0x2f, 0x7a, 0x47, + 0xd4, 0xa5, 0x99, 0x48, 0x82, 0x0f, 0xba, 0x0e, 0x82, 0xc9, 0x30, 0xfb, 0x06, 0x91, 0xd6, 0x59, + 0x81, 0xf5, 0xc7, 0x8f, 0xc2, 0xdb, 0x25, 0x98, 0x2a, 0x6d, 0xb7, 0x0d, 0xd3, 0x5a, 0xd6, 0xcc, + 0x0b, 0xf4, 0x54, 0xe3, 0x42, 0xd8, 0x4e, 0x76, 0x12, 0x40, 0xa7, 0x59, 0x3d, 0x5e, 0x90, 0x9e, + 0x18, 0xf4, 0x54, 0x54, 0x2c, 0x44, 0x42, 0xfc, 0xf7, 0x76, 0x4d, 0xc3, 0xb0, 0x96, 0xf4, 0xd6, + 0x05, 0x77, 0x83, 0xdc, 0x1b, 0x15, 0x71, 0x97, 0x27, 0x12, 0x5a, 0x81, 0x14, 0xc6, 0x8f, 0xd6, + 0xc7, 0x93, 0x30, 0x51, 0xdd, 0xd2, 0x4c, 0x3c, 0xb7, 0x47, 0x1a, 0xdb, 0xe5, 0x81, 0xe4, 0xb7, + 0x13, 0x8c, 0x5e, 0xe2, 0x05, 0x42, 0x81, 0x54, 0x53, 0x6f, 0x5d, 0xb0, 0xb7, 0xe7, 0xc8, 0x7f, + 0xf7, 0x68, 0x6f, 0xb2, 0xc7, 0xd1, 0x5e, 0xc7, 0x44, 0xeb, 0xd4, 0xeb, 0x33, 0xf7, 0x79, 0x53, + 0xa8, 0xa3, 0xbd, 0x7d, 0x8b, 0x8b, 0x9f, 0x8d, 0x5f, 0x4c, 0xc2, 0xb1, 0x5c, 0xa3, 0x71, 0x5e, + 0xb7, 0xb6, 0x2a, 0x36, 0x8f, 0xee, 0x0d, 0xb7, 0xa9, 0x3e, 0x0d, 0xd9, 0xb6, 0xb6, 0xd7, 0x34, + 0x34, 0x67, 0x60, 0xe1, 0x41, 0xf4, 0x70, 0x32, 0xe2, 0xc0, 0xd2, 0x45, 0x81, 0x0f, 0x53, 0x23, + 0xe9, 0xf4, 0xe0, 0x22, 0xe3, 0x67, 0xec, 0x5f, 0xa4, 0x20, 0x53, 0xc5, 0x9a, 0x59, 0xdf, 0x42, + 0xaf, 0x4e, 0xba, 0x0c, 0x9d, 0x87, 0xec, 0x86, 0xde, 0xb4, 0xb0, 0xd9, 0xa1, 0xeb, 0x7f, 0xef, + 0x3c, 0x86, 0x8d, 0x67, 0x73, 0x4d, 0xa3, 0x7e, 0x61, 0x36, 0x4f, 0x34, 0x4b, 0xcb, 0x9a, 0xb5, + 0xcf, 0x4d, 0xcd, 0xce, 0xd3, 0x4c, 0xaa, 0x9d, 0x59, 0xb9, 0x0f, 0xd2, 0x1d, 0xc3, 0xb4, 0xec, + 0xb5, 0xda, 0xe9, 0x70, 0xa5, 0x54, 0x0d, 0xd3, 0x52, 0x59, 0x46, 0x02, 0xed, 0xc6, 0x4e, 0xb3, + 0x59, 0xc3, 0x97, 0x2c, 0x7b, 0x9d, 0x64, 0x87, 0x95, 0x13, 0x90, 0x31, 0x36, 0x36, 0x3a, 0x98, + 0x2d, 0xc5, 0xd3, 0x2a, 0x0f, 0x29, 0xc7, 0x21, 0xdd, 0xd4, 0xb7, 0x75, 0x8b, 0xae, 0xb8, 0xd3, + 0x2a, 0x0b, 0x28, 0xa7, 0x41, 0x36, 0x9c, 0x55, 0x12, 0x23, 0x74, 0x3a, 0x43, 0x75, 0xd1, 0xbe, + 0x78, 0xd2, 0xe5, 0x2e, 0xe0, 0xbd, 0xce, 0x74, 0x96, 0x7e, 0xa7, 0xff, 0xd1, 0x13, 0x51, 0xad, + 0xf4, 0x8c, 0xaf, 0xfe, 0x4b, 0x46, 0x13, 0xd7, 0x0d, 0xb3, 0x61, 0xf3, 0xc6, 0x7f, 0xc9, 0xc8, + 0xd3, 0x45, 0xb3, 0xad, 0xf7, 0xac, 0x3c, 0x7e, 0x79, 0x7a, 0x22, 0x03, 0xe9, 0x05, 0x53, 0x6b, + 0x6f, 0xa1, 0x37, 0x27, 0x86, 0x2f, 0x4e, 0x0e, 0xb0, 0xc9, 0x7e, 0xc0, 0x4a, 0x7d, 0x80, 0x4d, + 0x79, 0x80, 0x7d, 0x2c, 0x09, 0xa9, 0x62, 0x63, 0x13, 0x0b, 0x46, 0xaf, 0x84, 0xc7, 0xe8, 0x75, + 0x02, 0x32, 0x96, 0x66, 0x6e, 0x62, 0x8b, 0x73, 0x89, 0x87, 0x1c, 0xcf, 0x28, 0xc9, 0x73, 0xbe, + 0xee, 0x85, 0x90, 0x22, 0xed, 0xa2, 0x12, 0x39, 0x75, 0xe6, 0x9a, 0x5e, 0xd0, 0x50, 0xfe, 0xcc, + 0x92, 0x1a, 0x67, 0x09, 0x65, 0x2a, 0xcd, 0xd0, 0x8d, 0x47, 0x7a, 0x1f, 0x1e, 0x64, 0x6c, 0xd7, + 0xeb, 0x46, 0xab, 0xb4, 0xad, 0x6d, 0xe2, 0xe9, 0x0c, 0x1b, 0xdb, 0x9d, 0x08, 0xfb, 0x6b, 0x71, + 0xdb, 0x78, 0x48, 0x9f, 0xce, 0xba, 0x5f, 0x69, 0x04, 0x69, 0xc2, 0x96, 0xde, 0x68, 0xe0, 0xd6, + 0xf4, 0x18, 0x3b, 0x9d, 0xc2, 0x42, 0x33, 0x27, 0x21, 0x45, 0x68, 0x20, 0x18, 0x13, 0xc5, 0x2e, + 0x1f, 0x51, 0x8e, 0x12, 0x29, 0x67, 0x56, 0x49, 0x39, 0x81, 0x3e, 0x9b, 0x8c, 0xb8, 0x87, 0xcc, + 0x1a, 0xd7, 0x5b, 0xe6, 0x6f, 0x82, 0x74, 0xcb, 0x68, 0xe0, 0xbe, 0x12, 0xcf, 0x52, 0x29, 0xcf, + 0x83, 0x34, 0x6e, 0x6c, 0xe2, 0x0e, 0x05, 0x73, 0xe2, 0xcc, 0xc9, 0x60, 0x5e, 0xaa, 0x2c, 0x71, + 0xb4, 0x8d, 0xea, 0x5e, 0xd4, 0xc6, 0xdf, 0x49, 0xfe, 0x77, 0x06, 0x8e, 0xb1, 0xfe, 0x59, 0xdd, + 0x59, 0x27, 0x45, 0xad, 0x63, 0xf4, 0x3b, 0x92, 0x70, 0xa0, 0xb7, 0xb3, 0xb3, 0xee, 0x8c, 0x65, + 0x2c, 0xe0, 0xed, 0x44, 0xc9, 0xa1, 0xe8, 0x64, 0x69, 0x50, 0x9d, 0x2c, 0xe8, 0x57, 0xc9, 0xee, + 0x86, 0xae, 0x36, 0xce, 0xd0, 0x68, 0x5b, 0x1b, 0xf7, 0xd0, 0xa5, 0x64, 0x50, 0xd6, 0x36, 0x2c, + 0x6c, 0x96, 0x1a, 0x54, 0x1e, 0xc7, 0x55, 0x3b, 0x48, 0xf4, 0xfd, 0x3a, 0xde, 0x30, 0x4c, 0xb2, + 0x10, 0x1c, 0x67, 0xfa, 0xde, 0x0e, 0x7b, 0xfa, 0x27, 0x08, 0x46, 0xe9, 0xeb, 0xe1, 0x98, 0xbe, + 0xd9, 0x32, 0x4c, 0xec, 0x78, 0xf6, 0x4c, 0x1f, 0x65, 0x27, 0x51, 0xbb, 0xa2, 0x95, 0x1b, 0xe1, + 0xb2, 0x96, 0x51, 0xc0, 0x6d, 0xce, 0x77, 0x86, 0xea, 0x24, 0xed, 0x11, 0xfb, 0x3f, 0xa0, 0xcf, + 0x44, 0x5d, 0x79, 0x76, 0x81, 0x3a, 0x34, 0xd5, 0xaf, 0xdc, 0x09, 0x47, 0x1b, 0xdc, 0x6b, 0xa0, + 0xae, 0x3b, 0x3d, 0xc2, 0x37, 0x9f, 0x90, 0xd8, 0x15, 0xa7, 0x94, 0x57, 0x9c, 0x16, 0x60, 0x8c, + 0xba, 0x9a, 0x13, 0x79, 0x4a, 0x77, 0x1d, 0x66, 0xa4, 0xd3, 0x6d, 0xa7, 0x51, 0x1e, 0x96, 0xcc, + 0xe6, 0x79, 0x16, 0xd5, 0xc9, 0x1c, 0x6d, 0xbe, 0x13, 0xcc, 0xa1, 0xf8, 0xbb, 0xde, 0xb7, 0x24, + 0x38, 0x61, 0xab, 0x37, 0x46, 0x4b, 0x41, 0xef, 0x58, 0x7a, 0xab, 0x6e, 0xa1, 0x8e, 0xe0, 0x40, + 0x68, 0xf2, 0x44, 0x0f, 0xe0, 0x3d, 0xdb, 0x81, 0xd0, 0x13, 0x35, 0xac, 0xce, 0x88, 0x3e, 0xef, + 0xd5, 0xaf, 0x15, 0x51, 0xc4, 0xce, 0xf6, 0x62, 0x60, 0x6f, 0xe2, 0x7d, 0x24, 0x2d, 0x0f, 0x99, + 0x4d, 0xd3, 0xd8, 0x69, 0xdb, 0x44, 0xde, 0x10, 0x8e, 0xc8, 0x05, 0x92, 0x47, 0xe5, 0x59, 0xd1, + 0x93, 0x0e, 0xbe, 0xaa, 0x80, 0xef, 0x3d, 0x03, 0x93, 0x37, 0x02, 0x53, 0x45, 0x0a, 0x8e, 0x3a, + 0x42, 0x56, 0x6a, 0x74, 0x90, 0xd1, 0x4f, 0xbb, 0xee, 0x33, 0x4c, 0x38, 0x7a, 0x4b, 0xf2, 0xe8, + 0xad, 0x1e, 0x9a, 0x66, 0xa2, 0xa7, 0xa6, 0x41, 0x0f, 0x4b, 0x61, 0xaf, 0x5f, 0x10, 0xbb, 0x19, + 0x25, 0xf7, 0x99, 0xac, 0x38, 0x42, 0x5e, 0x02, 0xd1, 0xbf, 0x55, 0xf1, 0x4b, 0xc1, 0x87, 0x93, + 0x70, 0x19, 0x13, 0xc4, 0xd5, 0x56, 0xc7, 0x19, 0x69, 0xc5, 0x33, 0xbb, 0xb4, 0x4d, 0x1d, 0x67, + 0x97, 0x93, 0x86, 0x44, 0x8b, 0xee, 0xfd, 0x22, 0x78, 0xcf, 0xf3, 0x57, 0x6b, 0x9e, 0x5a, 0x7c, + 0xd6, 0x86, 0x7f, 0xe0, 0xf0, 0x6e, 0x59, 0xe0, 0xdd, 0xd9, 0x41, 0x0a, 0x8d, 0x9f, 0x81, 0x2f, + 0x97, 0x60, 0xbc, 0x8a, 0xad, 0x25, 0x6d, 0xcf, 0xd8, 0xb1, 0x90, 0x16, 0xd6, 0xcc, 0x74, 0x3b, + 0x64, 0x9a, 0x34, 0x0b, 0x9d, 0x19, 0x4f, 0x9d, 0xb9, 0xba, 0xa7, 0x31, 0x94, 0x6e, 0x56, 0xb1, + 0xa2, 0x55, 0x9e, 0x1e, 0xbd, 0x3e, 0xaa, 0x29, 0xdd, 0xa1, 0x6e, 0x28, 0x76, 0xc0, 0x48, 0x86, + 0x76, 0xbf, 0xaa, 0xe3, 0x87, 0xe5, 0xd7, 0x24, 0x98, 0xa4, 0xae, 0xf7, 0xf3, 0xda, 0xae, 0x61, + 0xea, 0x16, 0x8e, 0x66, 0x01, 0x74, 0xb2, 0xf1, 0xf3, 0x05, 0x9e, 0x18, 0xf4, 0xf6, 0x64, 0xc4, + 0x2d, 0x36, 0x81, 0x8e, 0xa1, 0x80, 0x10, 0x69, 0x43, 0x2e, 0xa8, 0xfa, 0x11, 0x02, 0x91, 0x33, + 0xeb, 0x5b, 0xfa, 0x2e, 0x6e, 0x44, 0x04, 0xc2, 0xce, 0xe6, 0x02, 0xe1, 0x14, 0x34, 0x18, 0x10, + 0x76, 0xf6, 0x43, 0x02, 0xc2, 0xa7, 0xfa, 0xf8, 0x81, 0x78, 0x2b, 0x03, 0xc2, 0xe3, 0x6b, 0xb0, + 0x1c, 0x16, 0x88, 0x6b, 0x61, 0xd2, 0xb5, 0x12, 0xac, 0x9a, 0x4d, 0xbe, 0x9a, 0x17, 0x23, 0xd1, + 0x27, 0x07, 0x80, 0xa3, 0xaf, 0xdb, 0x40, 0x34, 0x38, 0x3e, 0x11, 0x11, 0x8e, 0x67, 0xaa, 0x4b, + 0xc0, 0x53, 0x12, 0x3b, 0x21, 0x25, 0x78, 0x66, 0x3c, 0x14, 0x16, 0xae, 0x7d, 0x5e, 0x20, 0xd9, + 0xc8, 0x5e, 0x20, 0x9f, 0x8e, 0xea, 0x05, 0xd2, 0x4d, 0xed, 0x50, 0xe0, 0x8c, 0xe4, 0xe4, 0xd1, + 0x87, 0x82, 0x43, 0x46, 0xf4, 0x3b, 0x12, 0x00, 0xbd, 0xfb, 0x93, 0xf9, 0x2f, 0x2d, 0x42, 0x86, + 0xfd, 0xb5, 0x9d, 0x20, 0x13, 0xae, 0x13, 0xe4, 0x8d, 0x90, 0xde, 0xd5, 0x9a, 0x3b, 0xd8, 0xe1, + 0x51, 0xf7, 0x44, 0xf4, 0x1c, 0xf9, 0xaa, 0xb2, 0x44, 0x68, 0x2b, 0xac, 0x54, 0xdc, 0xeb, 0x75, + 0xc0, 0x21, 0xf2, 0x70, 0x9d, 0x0f, 0x17, 0x39, 0x8d, 0xb3, 0xec, 0xd7, 0xf5, 0xb9, 0x7a, 0x63, + 0x54, 0x87, 0x08, 0x4f, 0x59, 0xc3, 0x90, 0x86, 0x48, 0x2e, 0x12, 0xbe, 0x75, 0xc7, 0xaf, 0x68, + 0x3f, 0x9d, 0x84, 0x74, 0xcd, 0xa8, 0x62, 0xe1, 0xfc, 0x58, 0x30, 0x36, 0xae, 0xd5, 0x26, 0xe9, + 0xb5, 0xda, 0x44, 0xb8, 0x80, 0xd5, 0xf1, 0x0c, 0xf1, 0x77, 0xd8, 0x23, 0x4b, 0x15, 0xec, 0x6e, + 0xe5, 0xb3, 0x40, 0x34, 0x5b, 0x60, 0xaf, 0xe2, 0xe3, 0x67, 0xe8, 0x59, 0x38, 0xb6, 0xda, 0x6a, + 0x18, 0x2a, 0x6e, 0x18, 0xdc, 0xb6, 0x42, 0x16, 0x9e, 0x3b, 0xad, 0x86, 0x41, 0x69, 0x4d, 0xab, + 0xf4, 0x3f, 0x89, 0x33, 0x71, 0xc3, 0xe0, 0x86, 0x6f, 0xfa, 0x1f, 0xbd, 0x46, 0x82, 0x14, 0xc9, + 0x1b, 0xde, 0x53, 0xe5, 0xbb, 0x51, 0x0f, 0x9a, 0x90, 0xe2, 0x87, 0x21, 0xdf, 0xca, 0xbd, 0x1e, + 0x6b, 0x13, 0xdb, 0xe4, 0xbd, 0xc6, 0xaf, 0x3e, 0x0f, 0x2b, 0x3c, 0x56, 0xa6, 0x27, 0xa3, 0x1c, + 0x4e, 0xe9, 0x41, 0x76, 0x34, 0x24, 0x0b, 0x03, 0xa8, 0x48, 0x19, 0x8e, 0xe6, 0x73, 0x65, 0x7a, + 0x5b, 0xc2, 0x72, 0xe5, 0x5c, 0x51, 0x96, 0x28, 0x40, 0xa4, 0x35, 0x31, 0x02, 0x44, 0x8a, 0xff, + 0x27, 0x08, 0x50, 0x0f, 0xb2, 0x0f, 0x03, 0xa0, 0x4f, 0x25, 0x61, 0x72, 0x49, 0xef, 0x58, 0x7e, + 0x4e, 0x5f, 0xf6, 0x26, 0xb2, 0x6d, 0x1f, 0x70, 0x23, 0xc4, 0x8b, 0xb6, 0xc3, 0x4c, 0x08, 0x85, + 0x7a, 0x7c, 0x20, 0xdb, 0xef, 0x1d, 0x13, 0x69, 0x0e, 0x1e, 0x54, 0xc5, 0x68, 0xbc, 0x13, 0x29, + 0x05, 0xec, 0x6a, 0xb4, 0xd0, 0x9c, 0x8c, 0x3c, 0xf4, 0xba, 0x95, 0x8c, 0x7e, 0xe8, 0xf5, 0xad, + 0x7b, 0x04, 0xa6, 0xeb, 0x24, 0x5c, 0x46, 0xaa, 0x0f, 0x5a, 0x70, 0xfa, 0xb3, 0xb9, 0xef, 0x82, + 0x33, 0xb2, 0xcd, 0x6b, 0x1f, 0x2d, 0xc3, 0xb0, 0x79, 0xf5, 0x2b, 0x74, 0xc4, 0x6c, 0xf6, 0x31, + 0xb0, 0xf4, 0x63, 0x73, 0x80, 0x81, 0x65, 0x70, 0x36, 0x07, 0x1b, 0x59, 0x06, 0x64, 0xf3, 0xa1, + 0x99, 0x4e, 0xbe, 0x9c, 0x84, 0xc9, 0x5c, 0xbb, 0xdd, 0xdc, 0xab, 0xf1, 0x93, 0x20, 0x91, 0x4c, + 0x27, 0x9e, 0x03, 0x25, 0xc9, 0x7d, 0xc7, 0x29, 0x23, 0xbb, 0x89, 0x0b, 0x74, 0x0c, 0xc3, 0x4d, + 0x3c, 0xa8, 0xc0, 0xf8, 0x59, 0xfb, 0x92, 0x34, 0x53, 0xc4, 0xfc, 0xa2, 0x87, 0x2f, 0x26, 0x82, + 0x6f, 0x7a, 0x10, 0xe4, 0x39, 0xd9, 0x2d, 0xcf, 0x77, 0x43, 0x66, 0xc3, 0x30, 0xb7, 0x35, 0xdb, + 0x96, 0x7b, 0x9d, 0x9f, 0x38, 0xf1, 0xbb, 0x14, 0xe6, 0x69, 0x62, 0x95, 0x67, 0x22, 0x23, 0xda, + 0x8b, 0xf4, 0x36, 0x3f, 0x0b, 0x4d, 0xfe, 0xd2, 0x4b, 0x4e, 0xd8, 0x91, 0xe8, 0x32, 0xee, 0x58, + 0xb8, 0x41, 0x37, 0x1f, 0xc7, 0x54, 0x31, 0x52, 0x99, 0x81, 0xa3, 0x3c, 0x62, 0x5e, 0x6f, 0xe2, + 0x0e, 0xdd, 0x52, 0x1e, 0x53, 0x85, 0x38, 0xf4, 0xb9, 0x41, 0x06, 0x8e, 0xc8, 0x37, 0x50, 0x4c, + 0x43, 0xb6, 0xb3, 0x53, 0xaf, 0x63, 0xdc, 0xe0, 0x5e, 0x46, 0x76, 0x30, 0xa2, 0xd7, 0x62, 0xe4, + 0x61, 0xe6, 0x70, 0x2e, 0xa7, 0x98, 0x59, 0x81, 0x0c, 0xc3, 0x50, 0x39, 0x0a, 0x63, 0xb6, 0xdf, + 0x24, 0xf3, 0x0b, 0x59, 0xe1, 0x8b, 0x74, 0x39, 0x41, 0x4a, 0xbc, 0xbf, 0x5a, 0x29, 0xb3, 0x0b, + 0xbb, 0x0a, 0x15, 0x7e, 0x61, 0x57, 0xf5, 0xdc, 0x82, 0x9c, 0x52, 0xa6, 0x00, 0x16, 0xd4, 0xdc, + 0xca, 0xe2, 0x1a, 0x4d, 0x91, 0x46, 0xdf, 0x1a, 0x83, 0x0c, 0x73, 0xc3, 0x44, 0x9f, 0xcb, 0x78, + 0x1f, 0x4c, 0x39, 0xda, 0x32, 0x08, 0x99, 0x2b, 0x9a, 0xa9, 0x6d, 0x77, 0x82, 0xf6, 0xc6, 0x58, + 0x6e, 0xe7, 0xb1, 0x94, 0xb2, 0x27, 0xdb, 0xe2, 0x11, 0x55, 0x28, 0x46, 0xf9, 0x97, 0x70, 0x6c, + 0x9d, 0x1f, 0x20, 0xe8, 0xf0, 0x92, 0x93, 0xfe, 0x3b, 0xf6, 0x5d, 0x25, 0xcf, 0x89, 0x39, 0x17, + 0x8f, 0xa8, 0xdd, 0x85, 0x29, 0x3f, 0x07, 0x53, 0xdb, 0x9c, 0x2b, 0xbc, 0x78, 0xa9, 0x9f, 0x7f, + 0xac, 0x53, 0xfc, 0xb2, 0x90, 0x71, 0xf1, 0x88, 0xda, 0x55, 0x94, 0x52, 0x82, 0xf1, 0x4e, 0x4b, + 0x6b, 0x77, 0xb6, 0x0c, 0xcb, 0x3e, 0x07, 0x77, 0x43, 0x88, 0x72, 0xab, 0x3c, 0x8f, 0xea, 0xe6, + 0x56, 0x9e, 0x07, 0xcf, 0xda, 0xa1, 0xd7, 0xc7, 0x15, 0x2f, 0xd1, 0x5d, 0xd8, 0x4d, 0xfb, 0x5e, + 0x02, 0xd6, 0xdf, 0x7a, 0x7f, 0x54, 0xee, 0xe4, 0xee, 0x4b, 0x19, 0x2a, 0x9b, 0xcf, 0x0d, 0x51, + 0xb7, 0xc7, 0x85, 0xe9, 0x4e, 0x48, 0x6d, 0x13, 0xc1, 0xce, 0x86, 0xce, 0xbc, 0x4c, 0xa5, 0x99, + 0x64, 0x42, 0xa7, 0xe0, 0xa8, 0x17, 0x57, 0xe5, 0x04, 0x64, 0xb4, 0xb6, 0xee, 0x6e, 0xbf, 0xf3, + 0x10, 0xba, 0x16, 0xa6, 0x44, 0x36, 0xf6, 0x52, 0x6a, 0xe8, 0x1a, 0x38, 0xd6, 0x85, 0xa5, 0x7d, + 0x0a, 0x26, 0xe1, 0x9e, 0x82, 0xf9, 0x79, 0x18, 0xb3, 0x39, 0xb7, 0xef, 0xba, 0xd8, 0x1c, 0x8c, + 0xd9, 0xbc, 0xe4, 0xf2, 0x73, 0x5d, 0x97, 0x89, 0xb1, 0xba, 0xad, 0x99, 0x16, 0xdd, 0x41, 0xb7, + 0x0b, 0x99, 0xd3, 0x3a, 0x58, 0x75, 0xb2, 0xcd, 0xdc, 0x04, 0x29, 0xd2, 0x3e, 0x45, 0x81, 0xa9, + 0xdc, 0xd2, 0xd2, 0x5a, 0x85, 0x5e, 0x55, 0xbc, 0x58, 0x2a, 0x2f, 0xb0, 0x7e, 0x58, 0x5a, 0x28, + 0x57, 0xd4, 0x22, 0xeb, 0x86, 0x55, 0x39, 0x31, 0x33, 0xcb, 0x5d, 0xb1, 0x00, 0x32, 0x8c, 0x11, + 0xac, 0xd3, 0x39, 0x5d, 0x30, 0x41, 0x42, 0xc5, 0x4b, 0xcc, 0x0a, 0x28, 0x27, 0xe7, 0xc6, 0x20, + 0xd3, 0xa6, 0x2d, 0x13, 0x2d, 0x29, 0x61, 0x3c, 0x13, 0x1d, 0x14, 0x7a, 0x8d, 0x74, 0xef, 0x8d, + 0xe2, 0x66, 0xd8, 0xb3, 0xa4, 0x68, 0x4a, 0x6a, 0x7e, 0x9f, 0x92, 0x52, 0x60, 0xaa, 0x54, 0xae, + 0x15, 0xd5, 0x72, 0x6e, 0xc9, 0xd1, 0x52, 0xfb, 0x14, 0x57, 0x52, 0x54, 0x5c, 0x12, 0xfa, 0xae, + 0x04, 0xc0, 0xc8, 0x21, 0xda, 0xd3, 0x7b, 0xe7, 0xdb, 0x17, 0xa3, 0x0e, 0x14, 0x6e, 0x31, 0x3e, + 0x03, 0x45, 0x09, 0xc6, 0x4c, 0xfe, 0x81, 0x1b, 0x1c, 0xfb, 0x95, 0xc3, 0xfe, 0xda, 0xa5, 0xa9, + 0x4e, 0x76, 0xf4, 0x81, 0x28, 0xe3, 0x82, 0x2f, 0x61, 0x87, 0xc3, 0xf2, 0x17, 0xd9, 0x47, 0x11, + 0x3c, 0xd3, 0x2d, 0xa6, 0x3f, 0xc2, 0xb5, 0x41, 0xcc, 0xec, 0x51, 0x25, 0x33, 0x57, 0xf7, 0xeb, + 0x0c, 0xe8, 0xa3, 0xc7, 0x60, 0x8a, 0x95, 0xe8, 0xdc, 0x11, 0xf0, 0x0f, 0x49, 0x90, 0x72, 0x0d, + 0xe1, 0xba, 0xb5, 0xe0, 0x99, 0xe4, 0x0c, 0x1c, 0xf5, 0x38, 0xf5, 0x38, 0x77, 0xf7, 0x79, 0xe3, + 0xc4, 0x87, 0x5f, 0x02, 0x5f, 0xd4, 0x12, 0xa9, 0x99, 0xcd, 0x35, 0x86, 0xb3, 0x0d, 0x17, 0xc5, + 0x49, 0x3f, 0xa0, 0xf2, 0xd1, 0x5c, 0x2e, 0xc6, 0x17, 0xff, 0xa5, 0xb0, 0x08, 0x74, 0x79, 0x5a, + 0x25, 0xf7, 0x79, 0x5a, 0x45, 0x3e, 0x1f, 0xe4, 0xb0, 0x20, 0x9c, 0x89, 0x60, 0xe8, 0x27, 0x4e, + 0x82, 0xeb, 0x8f, 0x1f, 0x85, 0x1f, 0x73, 0x9b, 0x56, 0x6e, 0x57, 0xd3, 0x9b, 0xda, 0x7a, 0x33, + 0xc2, 0x41, 0xc6, 0x8f, 0x7b, 0x59, 0x5d, 0x16, 0x59, 0x7d, 0x7b, 0x50, 0x53, 0x85, 0xfa, 0x7c, + 0x2f, 0xae, 0x1f, 0xb7, 0x61, 0x75, 0xdd, 0x97, 0xc4, 0x11, 0xd5, 0x2e, 0x4f, 0x75, 0x53, 0xa2, + 0x3f, 0x72, 0x58, 0xff, 0xd3, 0x02, 0xeb, 0xef, 0x1e, 0x94, 0x9e, 0xf8, 0x11, 0xf8, 0x2d, 0x09, + 0x26, 0x72, 0x8d, 0xc6, 0x3c, 0xd6, 0xac, 0x1d, 0x13, 0x37, 0x50, 0x31, 0x6c, 0x67, 0xb8, 0xb2, + 0x9b, 0x45, 0xe3, 0x5e, 0x4e, 0xbc, 0x3f, 0xf4, 0xbd, 0x8f, 0xfb, 0x75, 0x81, 0x4d, 0xcb, 0x50, + 0x14, 0x52, 0xb8, 0x5b, 0x22, 0x43, 0x13, 0x11, 0x3f, 0x20, 0xaf, 0x90, 0x60, 0x4a, 0xa5, 0xb7, + 0xa6, 0x0f, 0x1b, 0x93, 0x0f, 0x45, 0x74, 0xdf, 0xf4, 0xdc, 0xce, 0xe2, 0x25, 0x67, 0x28, 0xb0, + 0x44, 0xf1, 0xd3, 0x0c, 0x47, 0x47, 0xfc, 0xc8, 0x7c, 0x0f, 0x00, 0x3c, 0x4e, 0x1b, 0x5f, 0x03, + 0xf7, 0xf0, 0x01, 0xfa, 0xb4, 0xc4, 0x46, 0xf3, 0xaa, 0x70, 0xc6, 0x54, 0xf4, 0xd5, 0x48, 0xf4, + 0xf0, 0xd5, 0x08, 0x35, 0xaa, 0xff, 0x20, 0xa2, 0x0f, 0x00, 0x77, 0xa3, 0xe8, 0x3b, 0xb4, 0x0f, + 0xa8, 0xe5, 0x9e, 0x8e, 0xe0, 0x0c, 0xd0, 0x8f, 0x94, 0xf8, 0xdf, 0xe9, 0x08, 0x72, 0x06, 0x50, + 0xa6, 0xe1, 0xb8, 0x5a, 0xcc, 0x15, 0x2a, 0xe5, 0xa5, 0x07, 0xbd, 0x5f, 0xe5, 0x14, 0x7a, 0xad, + 0x04, 0x19, 0x26, 0x6f, 0xf1, 0x60, 0xfa, 0x1f, 0x23, 0x2a, 0x48, 0x91, 0x91, 0x8c, 0x32, 0x9f, + 0x35, 0xd1, 0x7f, 0x8e, 0xa0, 0xf2, 0x42, 0x14, 0xfb, 0x8c, 0x85, 0xe8, 0xab, 0x12, 0xa4, 0xe8, + 0xea, 0x69, 0x27, 0x2a, 0x40, 0x05, 0xb8, 0x4a, 0x6b, 0xb7, 0x71, 0xab, 0xe1, 0x5c, 0x74, 0x38, + 0x6f, 0x1a, 0xdb, 0x15, 0x6b, 0x0b, 0x9b, 0x24, 0x49, 0x87, 0x9b, 0xc2, 0x83, 0x13, 0xa1, 0xaf, + 0x46, 0xb4, 0x8e, 0x8b, 0xbc, 0x0e, 0x58, 0xb0, 0x9d, 0xdd, 0xdf, 0x2f, 0xaf, 0xf0, 0xe9, 0x97, + 0x4b, 0x7a, 0xeb, 0x82, 0xb7, 0x6f, 0xfe, 0x59, 0x04, 0xc3, 0x7a, 0x5f, 0x7a, 0x0e, 0xd9, 0x53, + 0xe7, 0xe1, 0x8c, 0x47, 0xc1, 0xfe, 0xba, 0x04, 0x32, 0x21, 0x91, 0x89, 0x28, 0xbf, 0xad, 0xab, + 0x22, 0x6e, 0x74, 0xd0, 0x48, 0xef, 0x46, 0x87, 0x1d, 0xa1, 0x9c, 0x82, 0xa9, 0xfa, 0x16, 0xae, + 0x5f, 0x28, 0xb5, 0x6c, 0xc3, 0x12, 0x43, 0xb8, 0x2b, 0x56, 0x74, 0xe9, 0x7d, 0x40, 0x84, 0x54, + 0x34, 0x9e, 0x0b, 0x7c, 0xf3, 0x12, 0xe5, 0xd3, 0x29, 0x5d, 0x60, 0xca, 0x02, 0x30, 0x77, 0x0c, + 0x54, 0x6a, 0x34, 0x64, 0xca, 0x83, 0xbd, 0xaa, 0x50, 0x59, 0xa1, 0xcf, 0x90, 0xad, 0x56, 0x8b, + 0x85, 0xb5, 0x39, 0xbb, 0xf3, 0x55, 0x65, 0x09, 0x7d, 0x27, 0x09, 0x59, 0x46, 0x56, 0xa7, 0xeb, + 0x26, 0xeb, 0xe0, 0x83, 0x28, 0xe8, 0x9d, 0xa1, 0x3d, 0xa6, 0x1d, 0x46, 0xf0, 0x7a, 0x7c, 0x7a, + 0xca, 0xed, 0x90, 0x65, 0x20, 0xdb, 0x76, 0xd3, 0x93, 0x3e, 0xfd, 0x84, 0x17, 0xa3, 0xda, 0xc9, + 0x43, 0x7a, 0x4f, 0xf7, 0x21, 0x23, 0xfe, 0x39, 0xc7, 0x9b, 0x26, 0x20, 0xbb, 0xa8, 0x77, 0x2c, + 0xc3, 0xdc, 0x43, 0x6f, 0x4c, 0x40, 0x96, 0xbf, 0x40, 0xbe, 0xcf, 0x02, 0x78, 0x35, 0x4c, 0xb4, + 0x4d, 0xbc, 0xab, 0x1b, 0x3b, 0x1d, 0xcf, 0xb5, 0x05, 0x9e, 0x28, 0x05, 0xc1, 0x98, 0xb6, 0x63, + 0x6d, 0x19, 0xa6, 0x7b, 0x87, 0x93, 0x1d, 0x56, 0x4e, 0x02, 0xb0, 0xff, 0x65, 0x6d, 0x1b, 0xf3, + 0x03, 0x14, 0x9e, 0x18, 0x45, 0x81, 0x94, 0xa5, 0x6f, 0x63, 0x7e, 0x84, 0x8e, 0xfe, 0x57, 0xa6, + 0x21, 0x4b, 0xcf, 0xdc, 0x94, 0x1a, 0xfc, 0x08, 0x9d, 0x1d, 0x44, 0x6f, 0x91, 0x60, 0xc2, 0x7d, + 0x2c, 0xbd, 0xe3, 0x75, 0xc5, 0xef, 0x73, 0xa1, 0x7c, 0x53, 0xeb, 0xd8, 0xd9, 0x9c, 0xcd, 0x32, + 0x31, 0xd2, 0x3d, 0xce, 0x27, 0x79, 0x4e, 0xd5, 0xa2, 0xf7, 0x26, 0xc3, 0x1e, 0x60, 0xe1, 0xcc, + 0xf4, 0xbc, 0xe6, 0xee, 0x2f, 0x5b, 0x63, 0xfc, 0xf9, 0x78, 0x5b, 0x09, 0x5f, 0xd9, 0xb3, 0x24, + 0x5e, 0x8c, 0xea, 0xa4, 0x0e, 0x79, 0xe8, 0xa4, 0x3f, 0x25, 0xf1, 0x8b, 0xd7, 0xdf, 0x4b, 0x30, + 0x51, 0xdd, 0x32, 0x2e, 0xda, 0x6f, 0xf3, 0xff, 0x7c, 0x38, 0xa8, 0xae, 0x84, 0xf1, 0xdd, 0x2e, + 0x98, 0xdc, 0x08, 0xff, 0xbb, 0x88, 0xd1, 0xa3, 0x52, 0x54, 0x98, 0x3c, 0xc4, 0x0d, 0xfd, 0x0e, + 0x61, 0xe5, 0x05, 0x90, 0xe5, 0x54, 0x73, 0xcb, 0x4a, 0x30, 0xc0, 0x76, 0x62, 0x6f, 0x03, 0x53, + 0x62, 0x03, 0xa3, 0x21, 0xef, 0xdf, 0xb8, 0x11, 0xdc, 0xa5, 0x90, 0xa4, 0x6e, 0xb0, 0x36, 0xf0, + 0xf9, 0x21, 0x00, 0x8f, 0x7e, 0x98, 0x08, 0x6b, 0x7d, 0x74, 0x38, 0xe0, 0x50, 0x70, 0xa0, 0x4b, + 0x3f, 0xfa, 0x16, 0x17, 0x3f, 0x3f, 0x7f, 0xf9, 0x32, 0x48, 0xcd, 0xeb, 0x4d, 0x4c, 0xd6, 0xef, + 0xd9, 0xca, 0xc6, 0x06, 0xbd, 0xb4, 0xa3, 0xe8, 0xff, 0xc2, 0xdf, 0x69, 0x90, 0xed, 0x4d, 0x64, + 0xc3, 0x5a, 0xd1, 0x5b, 0x2d, 0xc7, 0xcf, 0x65, 0x5f, 0xbc, 0x68, 0xea, 0x0a, 0x74, 0x3e, 0x25, + 0x14, 0xcc, 0xf2, 0xda, 0x7d, 0xfa, 0xcb, 0x29, 0x98, 0x5a, 0xdf, 0xb3, 0x70, 0x87, 0xa7, 0xe2, + 0xd5, 0xa6, 0xd4, 0xae, 0x58, 0xf4, 0x54, 0x28, 0x77, 0xd4, 0x80, 0x0a, 0xa3, 0xf1, 0x5c, 0x1b, + 0x60, 0x8e, 0x72, 0x1c, 0xe4, 0x72, 0xa5, 0x50, 0x64, 0x4f, 0xe1, 0xd5, 0x72, 0x6a, 0xad, 0x58, + 0x90, 0x37, 0xe9, 0xfb, 0x5f, 0xa5, 0x25, 0x16, 0xfb, 0x60, 0xb1, 0xb6, 0xb6, 0x52, 0x2a, 0x97, + 0x8b, 0x05, 0x79, 0x0b, 0x7d, 0x50, 0x82, 0x09, 0x32, 0xaf, 0xb2, 0xd1, 0xa9, 0x08, 0xcf, 0xa7, + 0x19, 0xad, 0xe6, 0x9e, 0x3b, 0x77, 0xb4, 0x83, 0x91, 0x70, 0xfa, 0x4f, 0xa1, 0xa7, 0x37, 0x94, + 0x6d, 0x1e, 0x5a, 0xfc, 0xb1, 0xda, 0xd0, 0x9b, 0xdd, 0x58, 0xa5, 0xd5, 0xae, 0xd8, 0x1e, 0x98, + 0x4a, 0x3d, 0x31, 0xfd, 0xe3, 0x50, 0x93, 0x9e, 0x3e, 0xc4, 0x45, 0xc3, 0x75, 0x71, 0x58, 0xb8, + 0xa2, 0xef, 0x4b, 0x90, 0x59, 0x6d, 0x53, 0xe4, 0x9e, 0xf6, 0x78, 0x89, 0xec, 0xdb, 0x29, 0x25, + 0x4a, 0xaa, 0x29, 0xbe, 0x17, 0xad, 0xba, 0x11, 0xca, 0x1d, 0x7c, 0xd3, 0x87, 0x79, 0x88, 0x9c, + 0x0a, 0x3c, 0x64, 0x4c, 0x39, 0xe1, 0xd9, 0x33, 0xbe, 0x11, 0x2e, 0x6b, 0xe8, 0x1d, 0x6d, 0xbd, + 0x89, 0x8b, 0xad, 0xba, 0xb9, 0xc7, 0x1a, 0xcd, 0xdc, 0x45, 0xf6, 0x7f, 0x50, 0xee, 0x86, 0x74, + 0xc7, 0xda, 0x6b, 0xb2, 0x69, 0x93, 0x77, 0x8b, 0xd9, 0xb7, 0xaa, 0x2a, 0x49, 0xae, 0xb2, 0x5c, + 0xe8, 0xc7, 0x89, 0xb0, 0xee, 0xb5, 0x34, 0x2f, 0x63, 0x8d, 0xbf, 0xaf, 0xc8, 0x96, 0xd6, 0x71, + 0x7c, 0x45, 0xc8, 0x7f, 0xf4, 0x78, 0x28, 0x1f, 0x58, 0xff, 0xb2, 0xe3, 0xd7, 0xa9, 0x5f, 0x49, + 0xc2, 0x58, 0xc1, 0xb8, 0xd8, 0xa2, 0x98, 0xdf, 0x2a, 0x38, 0x06, 0xd1, 0xd6, 0x24, 0xdc, 0xd6, + 0xf4, 0xf2, 0x86, 0x41, 0xff, 0x2e, 0xf4, 0x56, 0x33, 0x6d, 0xa5, 0x5d, 0x95, 0x0f, 0x0f, 0x03, + 0xc5, 0xca, 0x63, 0xfa, 0x0f, 0xda, 0x88, 0x0e, 0xaa, 0x27, 0x1a, 0x3f, 0x73, 0x07, 0x7e, 0x91, + 0x00, 0x3d, 0x25, 0x41, 0xaa, 0x60, 0x1a, 0x6d, 0xf4, 0x87, 0x89, 0x08, 0x7b, 0x90, 0x0d, 0xd3, + 0x68, 0xd7, 0xe8, 0x95, 0x32, 0xce, 0x14, 0x40, 0x88, 0x53, 0xce, 0xc2, 0x58, 0xdb, 0xe8, 0xe8, + 0x96, 0x3d, 0xad, 0x9a, 0xda, 0xf7, 0xec, 0x2f, 0x93, 0xfc, 0x15, 0x9e, 0x48, 0x75, 0x92, 0x13, + 0x3d, 0x46, 0x39, 0x4a, 0xd8, 0x44, 0xb8, 0x6a, 0x5f, 0x7d, 0xd3, 0x15, 0x8b, 0x7e, 0xcf, 0x0b, + 0xec, 0x9d, 0x22, 0xb0, 0xd7, 0xf5, 0x60, 0xb8, 0xe9, 0xf7, 0x8e, 0x68, 0x44, 0xab, 0xf5, 0xab, + 0x1d, 0x90, 0xef, 0x11, 0x40, 0x3e, 0x1d, 0xaa, 0xce, 0xf8, 0x3b, 0xcc, 0x77, 0xb3, 0x00, 0x65, + 0x6d, 0x57, 0xdf, 0x64, 0x36, 0x93, 0x2f, 0xd9, 0x03, 0x1e, 0xb7, 0x6e, 0xfc, 0x96, 0x07, 0xe7, + 0xb3, 0x90, 0xe5, 0xb0, 0xf2, 0x36, 0x3c, 0x47, 0x68, 0x83, 0x5b, 0x0a, 0xd3, 0x50, 0x97, 0x2c, + 0xd5, 0x4e, 0x2f, 0xdc, 0x72, 0x95, 0xec, 0xba, 0xe5, 0xaa, 0xe7, 0xf2, 0xcc, 0xef, 0xee, 0x2b, + 0xf4, 0xbe, 0xd0, 0x97, 0x9a, 0x79, 0xe8, 0xf1, 0xb4, 0xc8, 0x07, 0xd4, 0xdb, 0x20, 0x6b, 0x38, + 0x66, 0x1e, 0xc9, 0x77, 0x3d, 0x50, 0x6a, 0x6d, 0x18, 0xaa, 0x9d, 0x32, 0xe4, 0xcd, 0x20, 0xa1, + 0xe8, 0x88, 0x1f, 0xe8, 0xcf, 0x48, 0x70, 0x62, 0xc1, 0x3e, 0x35, 0x49, 0xda, 0x71, 0x5e, 0xb7, + 0xb6, 0x96, 0xf4, 0xd6, 0x85, 0x0e, 0xfa, 0x57, 0xe1, 0x66, 0xf2, 0x1e, 0xfc, 0x93, 0xd1, 0xf0, + 0x17, 0x5d, 0x19, 0xab, 0x22, 0x6a, 0x77, 0xfb, 0x95, 0xd2, 0x9b, 0x5a, 0x1f, 0x00, 0xef, 0x80, + 0x0c, 0x23, 0x94, 0x77, 0xcb, 0x19, 0x5f, 0xfc, 0x9c, 0x92, 0x54, 0x9e, 0xc3, 0xe3, 0x11, 0x74, + 0x4e, 0xc0, 0x71, 0xee, 0x40, 0x94, 0xc5, 0xef, 0xca, 0x78, 0x2b, 0x64, 0x39, 0xa7, 0x95, 0x29, + 0x6f, 0x2f, 0x96, 0x8f, 0x28, 0x00, 0x99, 0x65, 0x63, 0x17, 0xd7, 0x0c, 0x39, 0x41, 0xfe, 0x13, + 0xfa, 0x6a, 0x86, 0x9c, 0x44, 0xff, 0x15, 0x60, 0xcc, 0xf1, 0x48, 0xfe, 0x42, 0xd2, 0xbe, 0xc4, + 0x9c, 0x9a, 0xa9, 0x19, 0x33, 0x42, 0xef, 0xa6, 0xbf, 0x22, 0xb4, 0xe1, 0xd3, 0xf1, 0x14, 0xee, + 0xae, 0x2c, 0xe4, 0xfd, 0xc0, 0xef, 0x08, 0x65, 0x08, 0x0d, 0x5b, 0x4b, 0xfc, 0x5d, 0xed, 0x9b, + 0x49, 0xfb, 0xa9, 0x08, 0x97, 0x08, 0xba, 0xff, 0x27, 0x3e, 0x7d, 0xed, 0x6e, 0x30, 0x70, 0xe6, + 0x7a, 0x62, 0xc4, 0xf7, 0x4f, 0x03, 0x77, 0x5e, 0x7d, 0xdb, 0x1d, 0x70, 0x32, 0xbb, 0x9b, 0xc3, + 0xe1, 0xf6, 0x56, 0xa3, 0xd4, 0x14, 0x3f, 0x97, 0xdf, 0xc3, 0x5e, 0x13, 0x6b, 0x45, 0x70, 0x00, + 0x11, 0x6e, 0xc4, 0x0c, 0x7c, 0x01, 0xdf, 0x6d, 0x2a, 0xa9, 0x21, 0x24, 0x17, 0x9f, 0x48, 0x84, + 0x79, 0xaa, 0x3e, 0xb0, 0xe8, 0xf8, 0xd9, 0xf6, 0x9d, 0x24, 0x8c, 0x33, 0xd7, 0xeb, 0x5c, 0xb3, + 0xd9, 0xf5, 0x0e, 0xea, 0x3e, 0x37, 0xd3, 0xff, 0x10, 0xda, 0x39, 0xcc, 0x69, 0x95, 0x53, 0x76, + 0x6c, 0xaf, 0x20, 0x86, 0x33, 0xf0, 0xf4, 0x25, 0x68, 0x24, 0xb7, 0xba, 0x4e, 0x10, 0xcd, 0xbb, + 0x62, 0xe2, 0x5d, 0x1d, 0x5f, 0x44, 0x57, 0x04, 0x2c, 0x41, 0xd1, 0x5b, 0x43, 0x1f, 0x8d, 0xf4, + 0x14, 0xe9, 0xc3, 0xe3, 0xbb, 0x60, 0xa2, 0xe9, 0x26, 0xe2, 0x23, 0x22, 0xea, 0x1a, 0x11, 0x3d, + 0xc5, 0xa8, 0xde, 0xe4, 0x21, 0x57, 0x79, 0xfe, 0x54, 0xc4, 0xcf, 0xd8, 0x6f, 0x67, 0x60, 0x6c, + 0xb5, 0xd5, 0x69, 0x37, 0xc9, 0xa2, 0xf4, 0x1f, 0x24, 0xe7, 0x8a, 0xd7, 0xe7, 0x0b, 0xb7, 0x60, + 0xfd, 0xc2, 0x0e, 0x36, 0xed, 0x3d, 0x25, 0x16, 0xe8, 0x7d, 0xc1, 0x26, 0xfa, 0x63, 0xaf, 0x8d, + 0x39, 0x27, 0xb2, 0x5e, 0x74, 0x4f, 0xb7, 0x2b, 0x0d, 0xbe, 0xfb, 0xb4, 0x04, 0x63, 0x6d, 0xbd, + 0x6e, 0xed, 0x98, 0xce, 0x55, 0x90, 0x37, 0x85, 0x2b, 0x65, 0x85, 0xe5, 0x52, 0x9d, 0xec, 0x48, + 0x83, 0x2c, 0x8f, 0xdc, 0x67, 0x0e, 0xdc, 0xf7, 0xea, 0x01, 0x75, 0x29, 0x37, 0x2d, 0xbd, 0x63, + 0xdf, 0x24, 0xcb, 0x43, 0x44, 0x29, 0xb2, 0x7f, 0xab, 0x66, 0x93, 0x9b, 0x9f, 0xdd, 0x08, 0xf4, + 0x41, 0x07, 0xee, 0x82, 0x00, 0xf7, 0x2d, 0x11, 0x5a, 0x1e, 0x0d, 0xf2, 0x07, 0x06, 0x7b, 0xa2, + 0x5f, 0xa5, 0xcf, 0xe6, 0x97, 0x96, 0x4b, 0xb5, 0xb5, 0xe2, 0xcf, 0xe4, 0x8b, 0xc5, 0x42, 0xb1, + 0x20, 0x37, 0xe8, 0x03, 0x4a, 0xce, 0x8a, 0x5f, 0x1c, 0x09, 0x38, 0x17, 0xdd, 0x91, 0xc0, 0x89, + 0x40, 0x6f, 0x08, 0xed, 0x32, 0xed, 0x34, 0xbc, 0xcf, 0x5a, 0xbf, 0x97, 0xbd, 0xe4, 0xc3, 0xa1, + 0x7c, 0x9f, 0xfb, 0xd5, 0x70, 0x88, 0xcc, 0xfd, 0xc6, 0x2a, 0xa4, 0xe9, 0xd2, 0x1b, 0xbd, 0x8b, + 0xde, 0xdf, 0xd9, 0x6e, 0x6a, 0x75, 0x8c, 0xb6, 0x23, 0x3c, 0x7a, 0xb0, 0x4e, 0x72, 0xbb, 0x8f, + 0x1e, 0xf0, 0xa0, 0x72, 0x1a, 0xd2, 0xf4, 0x2f, 0xd7, 0xf8, 0xc7, 0x7b, 0x2d, 0xf7, 0x55, 0x96, + 0x44, 0x74, 0x0c, 0x0c, 0xb4, 0xc9, 0x30, 0x2b, 0x01, 0x27, 0xd3, 0x07, 0x27, 0x7f, 0x9a, 0xa2, + 0x8d, 0x42, 0xe1, 0x6e, 0x2b, 0x0e, 0xa2, 0x28, 0x7e, 0x3d, 0xf9, 0xd7, 0x29, 0x48, 0x57, 0xdb, + 0x4d, 0xdd, 0x42, 0xbf, 0x9f, 0x1c, 0x0a, 0x66, 0xa6, 0xd6, 0xda, 0xc4, 0x3e, 0x98, 0xa9, 0xe4, + 0x9b, 0xca, 0x92, 0xb8, 0x86, 0xcc, 0x54, 0x08, 0x43, 0x66, 0x0d, 0x5f, 0xb2, 0x04, 0x43, 0xa6, + 0x72, 0x96, 0x9f, 0xb4, 0x49, 0xf7, 0x38, 0x93, 0xc7, 0xf2, 0xd2, 0x66, 0xf5, 0x38, 0x67, 0x33, + 0x73, 0x2b, 0x3f, 0x95, 0x02, 0x90, 0x99, 0xab, 0xd4, 0x6a, 0x95, 0x65, 0xf9, 0x88, 0x92, 0x05, + 0xa9, 0x56, 0x59, 0x91, 0x13, 0xca, 0x38, 0xa4, 0x4b, 0xe5, 0x72, 0x51, 0x95, 0x93, 0xe4, 0x6f, + 0xad, 0x54, 0x5b, 0x2a, 0xca, 0x12, 0x7a, 0x77, 0xe8, 0xa1, 0x57, 0xac, 0x3b, 0x4e, 0xf1, 0x0a, + 0x37, 0x08, 0xfb, 0xd3, 0x13, 0xbf, 0x70, 0xfd, 0x5b, 0x09, 0xd2, 0xcb, 0xd8, 0xdc, 0xc4, 0xe8, + 0x17, 0x22, 0xd8, 0x02, 0x37, 0x74, 0xb3, 0xc3, 0x4e, 0x15, 0xb9, 0xb6, 0x40, 0x6f, 0x9c, 0x72, + 0x2d, 0x4c, 0x76, 0x70, 0xdd, 0x68, 0x35, 0xec, 0x44, 0xfc, 0xbe, 0x2a, 0x21, 0x12, 0x3d, 0x16, + 0x11, 0x32, 0x4a, 0xe8, 0x50, 0x0c, 0x7a, 0x51, 0x80, 0xe9, 0x55, 0x6b, 0xfc, 0xc0, 0xfc, 0x2f, + 0x89, 0x64, 0x6a, 0xef, 0xa1, 0xc7, 0x42, 0x1b, 0x69, 0x6f, 0x84, 0x0c, 0x15, 0x53, 0x7b, 0xbe, + 0xd2, 0x5b, 0x1f, 0xf3, 0x34, 0xca, 0x1c, 0x5c, 0xd6, 0xa1, 0xef, 0xbb, 0xe3, 0x06, 0xe9, 0xba, + 0x6a, 0x5f, 0xa5, 0xb0, 0x3f, 0x39, 0xfa, 0x4b, 0x2f, 0x80, 0x77, 0x89, 0x00, 0x9e, 0xea, 0xc1, + 0x4a, 0xd2, 0x20, 0xff, 0x97, 0x6e, 0x48, 0x33, 0xaa, 0x4d, 0xc3, 0x31, 0x2e, 0xda, 0x61, 0xf2, + 0x6d, 0xcb, 0xda, 0x6e, 0xd2, 0x6f, 0xdc, 0x85, 0xc5, 0x0e, 0x2b, 0xb3, 0x90, 0xd5, 0x5a, 0x7b, + 0xf4, 0x53, 0x2a, 0xa0, 0xd5, 0x76, 0x22, 0xf4, 0x1a, 0x07, 0xf9, 0x7b, 0x05, 0xe4, 0x6f, 0x08, + 0x47, 0x6e, 0xfc, 0xc0, 0xff, 0x5d, 0x06, 0xd2, 0x2b, 0x5a, 0xc7, 0xc2, 0xe8, 0x6b, 0x52, 0x58, + 0xe4, 0x4f, 0xc1, 0xd4, 0x86, 0x51, 0xdf, 0xe9, 0xe0, 0x86, 0xd8, 0x29, 0xbb, 0x62, 0x87, 0x81, + 0xb9, 0x72, 0x1a, 0x64, 0x3b, 0x92, 0x17, 0x6b, 0x5b, 0xeb, 0xf7, 0xc5, 0xd3, 0x63, 0xd4, 0x9d, + 0x15, 0xcd, 0xb4, 0x2a, 0x1b, 0x34, 0xce, 0x39, 0x46, 0xed, 0x8d, 0x14, 0xa0, 0xcf, 0x04, 0x40, + 0x9f, 0xf5, 0x87, 0x7e, 0x2c, 0x04, 0xf4, 0x4a, 0x0e, 0xc6, 0x36, 0xf4, 0x26, 0xa6, 0x19, 0xc6, + 0x7b, 0x5c, 0xc0, 0xc5, 0xb7, 0x27, 0x08, 0xef, 0x9d, 0x31, 0x69, 0x5e, 0x6f, 0x62, 0xd5, 0xc9, + 0x86, 0x96, 0xd8, 0x66, 0xbf, 0x73, 0xa9, 0x7e, 0xc2, 0x73, 0xa9, 0xbe, 0x02, 0xa9, 0x86, 0x66, + 0x69, 0x94, 0xf5, 0x47, 0x55, 0xfa, 0x5f, 0xdc, 0x3b, 0x92, 0xba, 0xf7, 0x8e, 0x1e, 0x91, 0xa2, + 0xe9, 0x3f, 0x9b, 0x34, 0x9f, 0xfe, 0xb3, 0x6e, 0xc3, 0xc1, 0xbc, 0xc0, 0x9c, 0x30, 0x81, 0xa1, + 0xae, 0x99, 0xd8, 0x5a, 0xf1, 0x6e, 0xcf, 0xa4, 0x55, 0x31, 0x92, 0xee, 0x78, 0x77, 0xaa, 0xda, + 0x36, 0xa6, 0x95, 0xe5, 0xc9, 0x37, 0xbe, 0xc7, 0xb9, 0x2f, 0xde, 0xd5, 0xb6, 0xe9, 0x61, 0x6b, + 0xdb, 0x5e, 0x6d, 0x8c, 0xbf, 0xd3, 0xbd, 0x2e, 0x05, 0x52, 0x7e, 0xc7, 0x7a, 0x46, 0x2b, 0xdb, + 0x7f, 0x0c, 0xbd, 0xf9, 0xc5, 0xb5, 0xd7, 0x8e, 0x75, 0xb8, 0xba, 0x36, 0xa2, 0x94, 0x84, 0xdb, + 0x64, 0xf3, 0x6b, 0xdb, 0x48, 0x0e, 0xe8, 0xd8, 0x7e, 0x08, 0xc6, 0xc1, 0xe7, 0xe1, 0x88, 0x29, + 0x23, 0x8f, 0x62, 0x70, 0xc2, 0xb6, 0x51, 0x20, 0xe5, 0xda, 0x95, 0x5e, 0x15, 0xda, 0x13, 0x88, + 0xf1, 0x27, 0xd0, 0x29, 0x20, 0xda, 0x54, 0x29, 0xdc, 0xf5, 0x74, 0x01, 0xd5, 0xc6, 0x8f, 0xcc, + 0xf7, 0xbd, 0xd6, 0x83, 0xdc, 0x81, 0xb1, 0x11, 0xcd, 0xf6, 0x81, 0x16, 0x66, 0xd6, 0xec, 0x3e, + 0x46, 0x85, 0x68, 0xfc, 0x0e, 0x67, 0x7f, 0x0e, 0xac, 0x78, 0x04, 0x47, 0xa2, 0x24, 0xc8, 0xb0, + 0xfd, 0x03, 0xf4, 0xb6, 0xd0, 0x2a, 0x93, 0xa8, 0x1d, 0xd1, 0x81, 0xc0, 0x09, 0x47, 0x31, 0x25, + 0x08, 0x8e, 0x06, 0xa9, 0x48, 0x8e, 0x06, 0xa2, 0xbf, 0x70, 0x88, 0x7e, 0xd4, 0xf3, 0xf1, 0xff, + 0x61, 0xaf, 0x12, 0xa3, 0xf4, 0xb0, 0x9e, 0x04, 0x8d, 0xc0, 0x5f, 0x58, 0xbc, 0x36, 0x2d, 0x1f, + 0x01, 0x72, 0xbf, 0x59, 0x49, 0x84, 0x6b, 0xd4, 0x59, 0xd3, 0x87, 0x7c, 0xa3, 0x5a, 0xb8, 0x83, + 0x00, 0x7d, 0xaa, 0x8e, 0x9f, 0xf3, 0xaf, 0x67, 0xb7, 0xdb, 0xcf, 0xeb, 0xb8, 0xd9, 0xe8, 0x20, + 0xf3, 0xe0, 0x03, 0xcf, 0xcd, 0x90, 0xd9, 0xa0, 0x85, 0xf5, 0x7b, 0x32, 0x9e, 0x27, 0x43, 0xaf, + 0x4b, 0x86, 0x35, 0xac, 0x73, 0x43, 0x86, 0x4d, 0xed, 0x50, 0x60, 0x7a, 0x7d, 0x28, 0xc3, 0x76, + 0x70, 0xcd, 0xf1, 0xa3, 0xf4, 0x4e, 0x09, 0x8e, 0xf2, 0xeb, 0xca, 0x72, 0x4d, 0x7d, 0xb3, 0xe5, + 0x3d, 0x9a, 0x36, 0x70, 0x0f, 0x51, 0x6e, 0x81, 0xb4, 0x46, 0x4a, 0xe3, 0xee, 0x54, 0xa8, 0xa7, + 0x96, 0xa3, 0xf5, 0xa9, 0x2c, 0x61, 0x84, 0x7b, 0x20, 0x5c, 0xc1, 0xb6, 0x69, 0x1e, 0xe1, 0x3d, + 0x10, 0x7d, 0x2b, 0x8f, 0x1f, 0xb1, 0xaf, 0x4b, 0x70, 0x9c, 0x13, 0x70, 0x0e, 0x9b, 0x96, 0x5e, + 0xd7, 0x9a, 0x0c, 0xb9, 0x97, 0x24, 0x86, 0x01, 0xdd, 0x22, 0x4c, 0xee, 0x7a, 0x8b, 0xe5, 0x10, + 0xce, 0xf4, 0x84, 0x50, 0x20, 0x40, 0x15, 0x33, 0x46, 0x38, 0x51, 0x2f, 0x70, 0x55, 0x28, 0x73, + 0x84, 0x27, 0xea, 0x43, 0x13, 0x11, 0x3f, 0xc4, 0xbf, 0x97, 0x62, 0x97, 0x4c, 0xb8, 0xea, 0xf3, + 0x4b, 0xa1, 0xb1, 0x5d, 0x85, 0x09, 0x8a, 0x25, 0xcb, 0xc8, 0xd7, 0x78, 0x01, 0x42, 0xec, 0xe8, + 0x1d, 0x7e, 0x45, 0x97, 0x93, 0x57, 0xf5, 0x96, 0x83, 0xce, 0x03, 0xb8, 0x9f, 0xbc, 0x4a, 0x3a, + 0xe1, 0xa7, 0xa4, 0x93, 0xe1, 0x94, 0xf4, 0x5b, 0x43, 0x1f, 0x84, 0xea, 0x4d, 0xf6, 0xc1, 0xc5, + 0x23, 0xdc, 0x11, 0x98, 0xfe, 0xb5, 0xc7, 0x2f, 0x17, 0xaf, 0x49, 0x75, 0x5f, 0xa8, 0xfb, 0xf1, + 0xa1, 0xcc, 0x61, 0xbd, 0xfa, 0x40, 0xea, 0xd2, 0x07, 0x83, 0xcf, 0x59, 0x95, 0xeb, 0xe1, 0x18, + 0xab, 0x22, 0xef, 0x90, 0xc5, 0xde, 0x5d, 0xec, 0x8e, 0x46, 0x9f, 0x18, 0x40, 0x08, 0xfa, 0xdd, + 0xf6, 0x1b, 0xa4, 0xe4, 0xa2, 0x4d, 0x73, 0xa3, 0x0a, 0xc8, 0xe1, 0x5d, 0x12, 0xfc, 0x9d, 0x14, + 0x9b, 0xed, 0xae, 0xd2, 0xdb, 0xe7, 0xd0, 0x5f, 0xa5, 0x86, 0x31, 0x22, 0xdc, 0x07, 0x29, 0xcb, + 0x7e, 0x1f, 0xb6, 0xf7, 0x32, 0xd2, 0xad, 0xd2, 0xbd, 0xb7, 0x0e, 0x5f, 0xb2, 0x16, 0x8f, 0xa8, + 0x34, 0xa7, 0x72, 0x1a, 0x8e, 0xad, 0x6b, 0xf5, 0x0b, 0x9b, 0xa6, 0xb1, 0xd3, 0x6a, 0xe4, 0x8d, + 0xa6, 0x61, 0x32, 0x13, 0x01, 0xbd, 0x00, 0x50, 0xfc, 0xa0, 0x9c, 0xb1, 0xa7, 0x0e, 0xe9, 0x7e, + 0x53, 0x87, 0xc5, 0x23, 0x7c, 0xf2, 0xa0, 0xdc, 0xea, 0x28, 0x9d, 0x4c, 0xa0, 0xd2, 0x59, 0x3c, + 0x62, 0xab, 0x1d, 0xa5, 0x00, 0x63, 0x0d, 0x7d, 0x97, 0xee, 0xfa, 0xf1, 0x0b, 0xf5, 0x82, 0x0f, + 0x56, 0x14, 0xf4, 0x5d, 0xb6, 0x47, 0xb8, 0x78, 0x44, 0x75, 0x72, 0x2a, 0x0b, 0x30, 0x4e, 0x2d, + 0xac, 0xb4, 0x98, 0xb1, 0x48, 0x87, 0x26, 0x16, 0x8f, 0xa8, 0x6e, 0x5e, 0x32, 0xfb, 0x48, 0x51, + 0x77, 0xe4, 0x7b, 0xed, 0x9d, 0xcb, 0x44, 0xa4, 0x9d, 0x4b, 0xc2, 0x0b, 0xb6, 0x77, 0x79, 0x02, + 0xd2, 0x75, 0xca, 0xe1, 0x24, 0xe7, 0x30, 0x0b, 0x2a, 0x77, 0x41, 0x6a, 0x5b, 0x33, 0xed, 0x65, + 0xea, 0xa9, 0xfe, 0xe5, 0x2e, 0x6b, 0xe6, 0x05, 0x82, 0x20, 0xc9, 0x35, 0x97, 0x85, 0x34, 0x65, + 0x9c, 0xf3, 0x07, 0x3d, 0xc5, 0xa7, 0x21, 0x79, 0xa3, 0x45, 0x86, 0xfd, 0x9a, 0x61, 0xfb, 0x6c, + 0xd7, 0x87, 0x21, 0x73, 0xa2, 0x7f, 0xa2, 0xb4, 0xcf, 0x3f, 0xf1, 0x2f, 0x07, 0x98, 0x5b, 0x74, + 0x53, 0xea, 0xbf, 0x38, 0x6e, 0x0a, 0x6f, 0xa9, 0xdb, 0xc1, 0x88, 0x5a, 0x23, 0xea, 0xac, 0xa3, + 0x0f, 0x79, 0x23, 0x78, 0xfa, 0x3e, 0x05, 0xd3, 0x84, 0x10, 0xe6, 0xb9, 0x2b, 0x5e, 0x5d, 0x89, + 0xfe, 0x7c, 0x28, 0x93, 0xcb, 0x1e, 0x23, 0x82, 0xd4, 0x73, 0x44, 0xd8, 0x77, 0x6e, 0x23, 0xd5, + 0xe7, 0xdc, 0x46, 0x3a, 0x9a, 0x39, 0xe5, 0x4f, 0xbc, 0xf2, 0xb3, 0x22, 0xca, 0xcf, 0x1d, 0x3e, + 0x00, 0xf5, 0xe2, 0xcb, 0x50, 0x26, 0x20, 0xef, 0x72, 0x24, 0xa5, 0x2a, 0x48, 0xca, 0xbd, 0x83, + 0x13, 0x12, 0xbf, 0xb4, 0x7c, 0x28, 0x05, 0x3f, 0xe1, 0x12, 0x53, 0xc6, 0x17, 0xb9, 0xa0, 0x7c, + 0x61, 0x28, 0x82, 0x72, 0xab, 0xfb, 0xe2, 0x4c, 0x9f, 0xc5, 0xbe, 0x9d, 0x2e, 0x6e, 0x89, 0xf9, + 0x8b, 0xd0, 0xfe, 0xe6, 0xdd, 0x40, 0x39, 0xbc, 0xf1, 0x11, 0x96, 0x13, 0x90, 0x61, 0x1a, 0xc6, + 0x7e, 0xff, 0x9a, 0x85, 0x22, 0xaa, 0x9b, 0x70, 0x5e, 0xea, 0x61, 0x69, 0x1b, 0x81, 0xfc, 0x70, + 0xc3, 0x43, 0x6d, 0xc7, 0x6c, 0x95, 0x5a, 0x96, 0x81, 0x7e, 0x79, 0x28, 0x82, 0xe3, 0x78, 0xfe, + 0x48, 0x83, 0x78, 0xfe, 0x0c, 0x64, 0x86, 0xb0, 0x5b, 0x70, 0x28, 0x66, 0x08, 0x9f, 0xca, 0xe3, + 0xc7, 0xef, 0x49, 0x09, 0x4e, 0xf0, 0xd5, 0xd0, 0x9c, 0x38, 0x85, 0x43, 0x0f, 0x0e, 0x03, 0xc8, + 0xe3, 0xf6, 0x3c, 0x86, 0x0d, 0x10, 0x2c, 0x20, 0x7a, 0x84, 0x07, 0xde, 0xa1, 0x28, 0xac, 0xd7, + 0xba, 0x28, 0x1c, 0x0a, 0x52, 0xe1, 0xae, 0x4e, 0x8c, 0x40, 0x46, 0xfc, 0x98, 0xfd, 0x8e, 0x04, + 0x19, 0x7e, 0x6d, 0xfd, 0x6a, 0x2c, 0xdb, 0xc5, 0xe2, 0x7d, 0x39, 0x21, 0xb6, 0x29, 0x22, 0xdf, + 0x17, 0x1f, 0xdf, 0x06, 0xc5, 0xe1, 0x5c, 0x08, 0x8f, 0x1e, 0x93, 0xb8, 0x65, 0x65, 0x49, 0xb3, + 0xf0, 0x25, 0xf4, 0x1b, 0x12, 0x64, 0xab, 0xd8, 0x22, 0x9a, 0x29, 0x3c, 0x46, 0xfe, 0x36, 0x73, + 0xc5, 0xb3, 0x76, 0x1b, 0x67, 0xab, 0xb1, 0xa8, 0x3a, 0x8e, 0xd2, 0x35, 0xcb, 0x69, 0x1a, 0xb5, + 0x8e, 0x0b, 0xaa, 0x7c, 0x04, 0xa7, 0x53, 0xaf, 0x85, 0x71, 0x4a, 0x06, 0x85, 0xe3, 0x93, 0x1e, + 0x68, 0x5e, 0x9e, 0x88, 0x05, 0x1b, 0x32, 0x7c, 0xd1, 0x4b, 0xd5, 0xe9, 0xec, 0x65, 0x22, 0xcc, + 0xf0, 0x45, 0x96, 0x69, 0x1d, 0x95, 0xe5, 0x8a, 0xf0, 0xd8, 0x8f, 0xd3, 0xac, 0xa1, 0x22, 0x1b, + 0xee, 0x15, 0x86, 0x7e, 0x75, 0x8f, 0xe0, 0x0d, 0x0f, 0x09, 0xc6, 0xaa, 0x64, 0xb9, 0x41, 0xc6, + 0x94, 0xf3, 0x07, 0x87, 0xb2, 0xf7, 0x60, 0x15, 0xb1, 0xa3, 0xd9, 0x1c, 0x19, 0xde, 0x10, 0x15, + 0xa1, 0xa3, 0x05, 0x55, 0x1e, 0x3f, 0x1e, 0xef, 0x66, 0x78, 0x50, 0x59, 0x46, 0x6f, 0x92, 0x40, + 0x5a, 0xc0, 0xd6, 0x90, 0xfc, 0xfc, 0xc3, 0xfa, 0x8c, 0x8b, 0x43, 0x57, 0xe0, 0xd1, 0x6e, 0x81, + 0x61, 0x94, 0xe6, 0xd9, 0x05, 0x3c, 0x9c, 0x0e, 0x14, 0xee, 0x4c, 0x77, 0x28, 0x02, 0xe2, 0x47, + 0xed, 0xfd, 0x0c, 0x35, 0x66, 0xc1, 0xfa, 0xa5, 0x21, 0x68, 0xc4, 0xd1, 0x4e, 0xde, 0x6d, 0x06, + 0xd2, 0x32, 0x0e, 0xab, 0xbf, 0xf5, 0xaa, 0x7c, 0x24, 0x1e, 0x61, 0x40, 0x3a, 0xfb, 0x16, 0xae, + 0x5f, 0xc0, 0x0d, 0xf4, 0x73, 0x07, 0x87, 0x6e, 0x1a, 0xb2, 0x75, 0x56, 0x1a, 0x05, 0x6f, 0x4c, + 0xb5, 0x83, 0x11, 0x9e, 0xda, 0x16, 0x15, 0x11, 0xcb, 0x3e, 0xc2, 0xa7, 0xb6, 0x43, 0x54, 0x1f, + 0x3f, 0x32, 0x7f, 0xc4, 0x26, 0x19, 0xa5, 0xba, 0xd1, 0x42, 0xff, 0xfa, 0xe0, 0xb0, 0x5c, 0x09, + 0xe3, 0x7a, 0xdd, 0x68, 0x95, 0xb6, 0xb5, 0x4d, 0xdb, 0x8c, 0xea, 0x46, 0xd8, 0x5f, 0x8b, 0xdb, + 0xc6, 0x43, 0x3a, 0xdf, 0x9a, 0x71, 0x23, 0x06, 0x9d, 0x4c, 0x10, 0xd2, 0x0f, 0x6b, 0x32, 0xd1, + 0xa3, 0xee, 0xf8, 0x21, 0xfb, 0x84, 0xeb, 0x42, 0xc1, 0x54, 0xe1, 0x33, 0xc2, 0x92, 0x31, 0xc8, + 0x70, 0xe6, 0x6d, 0xc5, 0xa1, 0x0c, 0x67, 0x01, 0x04, 0xc4, 0x8f, 0xe3, 0xab, 0x5c, 0x1c, 0x63, + 0xb7, 0x63, 0x1c, 0x00, 0x9d, 0xe1, 0x4d, 0x0f, 0x07, 0x44, 0xe7, 0x70, 0xa6, 0x88, 0x1f, 0xe6, + 0x57, 0x03, 0xf1, 0x19, 0x0f, 0xfa, 0xc5, 0x61, 0x80, 0x73, 0xc7, 0x20, 0x9b, 0x62, 0x6c, 0x4b, + 0x2c, 0xc2, 0xcb, 0x29, 0xfb, 0x38, 0x48, 0x4a, 0x19, 0x0a, 0x82, 0xe1, 0x5e, 0x4e, 0x09, 0x53, + 0x7f, 0xfc, 0x00, 0xfe, 0xa6, 0x04, 0x53, 0x74, 0x9f, 0xab, 0x89, 0x35, 0x93, 0x29, 0xca, 0xa1, + 0x78, 0x63, 0xbe, 0x3b, 0xf4, 0xa5, 0xe6, 0x22, 0x1f, 0x5c, 0x3a, 0x86, 0x02, 0x45, 0xb8, 0x07, + 0x42, 0x43, 0x92, 0x30, 0x12, 0x53, 0xa0, 0xec, 0x90, 0xc0, 0x45, 0x7c, 0x38, 0x78, 0x44, 0x74, + 0xfb, 0x12, 0x99, 0x61, 0x77, 0xb6, 0x11, 0xbb, 0x7d, 0x85, 0x21, 0x62, 0x04, 0x57, 0x67, 0xdf, + 0xc2, 0x4d, 0x81, 0x35, 0xfa, 0xb0, 0xd0, 0xe3, 0x29, 0xc7, 0x55, 0xfd, 0xb3, 0x43, 0x71, 0xf3, + 0x39, 0xc0, 0x3d, 0x77, 0x0a, 0xa4, 0x4c, 0xe3, 0x22, 0x33, 0x4b, 0x4d, 0xaa, 0xf4, 0x3f, 0x9d, + 0xf2, 0x1b, 0xcd, 0x9d, 0xed, 0x16, 0x7b, 0xf4, 0x70, 0x52, 0xb5, 0x83, 0xca, 0xb5, 0x30, 0x79, + 0x51, 0xb7, 0xb6, 0x16, 0xb1, 0xd6, 0xc0, 0xa6, 0x6a, 0x5c, 0xe4, 0xef, 0x8b, 0x8a, 0x91, 0xe2, + 0x1e, 0x6c, 0x88, 0xf9, 0x25, 0x7d, 0x6d, 0x68, 0x24, 0x7e, 0xed, 0x51, 0x66, 0x9e, 0xfe, 0x54, + 0xc5, 0x2f, 0x30, 0x1f, 0x90, 0x60, 0x5c, 0x35, 0x2e, 0x72, 0x21, 0xf9, 0x37, 0x87, 0x2b, 0x23, + 0x91, 0x17, 0x7a, 0xec, 0xf5, 0x28, 0x9b, 0xfc, 0x91, 0x2f, 0xf4, 0x02, 0xab, 0x1f, 0x89, 0x7b, + 0xfc, 0x51, 0xd5, 0xb8, 0x58, 0xc5, 0x16, 0xeb, 0x11, 0x68, 0x6d, 0x48, 0x9e, 0x7c, 0x7a, 0x87, + 0x15, 0xc8, 0xd7, 0xe1, 0x4e, 0x18, 0x3d, 0x19, 0xfa, 0x51, 0x1e, 0x91, 0x41, 0x0e, 0x89, 0x43, + 0x81, 0xe8, 0xed, 0xa1, 0xde, 0xe2, 0x09, 0x47, 0x41, 0xfc, 0x28, 0xfd, 0xaa, 0x04, 0x13, 0xaa, + 0x71, 0x91, 0x0c, 0x0d, 0xf3, 0x7a, 0xb3, 0x39, 0x9c, 0x11, 0x32, 0xea, 0xe4, 0xdf, 0x66, 0x83, + 0x4d, 0xc5, 0xc8, 0x27, 0xff, 0x7d, 0x08, 0x88, 0x1f, 0x86, 0x47, 0x58, 0x67, 0xb1, 0x47, 0xe8, + 0xd6, 0x70, 0x70, 0x18, 0xb4, 0x43, 0x38, 0x64, 0x1c, 0x5a, 0x87, 0xf0, 0xa3, 0x60, 0x24, 0x3b, + 0x27, 0x53, 0x79, 0x3a, 0xcc, 0x0f, 0xb7, 0x4f, 0xbc, 0x37, 0x9a, 0x7b, 0x0d, 0x1f, 0x76, 0x05, + 0x42, 0x86, 0x82, 0x46, 0x04, 0x37, 0x9a, 0x10, 0x34, 0xc4, 0x8f, 0xc7, 0x47, 0x25, 0x38, 0xca, + 0x48, 0x78, 0x86, 0xcc, 0x02, 0x06, 0xea, 0x54, 0xde, 0x16, 0x1c, 0x4e, 0xa7, 0x0a, 0xa0, 0x20, + 0x7e, 0x10, 0xff, 0x6f, 0x92, 0xce, 0xe3, 0x06, 0x38, 0xa3, 0xe8, 0x87, 0xe0, 0xc0, 0x93, 0xb1, + 0x21, 0x9e, 0x53, 0x1c, 0x64, 0x32, 0x76, 0x48, 0x67, 0x15, 0x1f, 0x71, 0x7a, 0xd1, 0x30, 0x31, + 0x38, 0x40, 0x57, 0x18, 0x22, 0x0c, 0x03, 0x76, 0x85, 0x43, 0x42, 0xe2, 0x1b, 0x12, 0x00, 0x23, + 0x60, 0xd9, 0xd8, 0xc5, 0xe8, 0x89, 0xa1, 0x2c, 0x7c, 0xbb, 0x5d, 0x43, 0xa5, 0x3e, 0xae, 0xa1, + 0x11, 0xcf, 0x66, 0x47, 0xb5, 0x04, 0x7a, 0xb8, 0xbc, 0xec, 0xfb, 0x28, 0x62, 0x8c, 0x96, 0xc0, + 0xe0, 0xfa, 0xe3, 0xc7, 0xf8, 0xab, 0x6c, 0x36, 0xe7, 0x9e, 0x62, 0x7a, 0xe5, 0x50, 0x50, 0xf6, + 0xac, 0xfe, 0x25, 0x71, 0xf5, 0x7f, 0x00, 0x6c, 0x07, 0x9d, 0x23, 0xf6, 0x3b, 0x9d, 0x14, 0xff, + 0x1c, 0xf1, 0xf0, 0x4e, 0x21, 0xfd, 0x52, 0x0a, 0x8e, 0x71, 0x25, 0xf2, 0x4f, 0x01, 0xe2, 0x88, + 0x67, 0x49, 0x04, 0x25, 0xd9, 0x07, 0xe5, 0x61, 0x19, 0xa4, 0xa2, 0x98, 0x32, 0x43, 0x90, 0x37, + 0x12, 0xeb, 0x46, 0xa6, 0x78, 0xa9, 0xad, 0xb5, 0x1a, 0xe1, 0xaf, 0xe7, 0xeb, 0x03, 0xbc, 0x6d, + 0x6b, 0x94, 0x44, 0x5b, 0x63, 0x0f, 0xcb, 0x64, 0xe4, 0x9d, 0x6b, 0xca, 0x32, 0x46, 0xee, 0xc8, + 0x77, 0xae, 0xfd, 0xeb, 0x8e, 0x1f, 0xa5, 0xf7, 0x4a, 0x90, 0xaa, 0x1a, 0xa6, 0x85, 0x1e, 0x8d, + 0xd2, 0x3b, 0x19, 0xe7, 0x5d, 0x90, 0xec, 0xb0, 0x92, 0x17, 0x1e, 0x2a, 0xba, 0x39, 0xf8, 0x3c, + 0x9d, 0x66, 0x69, 0xf4, 0xf2, 0x66, 0x52, 0xbf, 0xe7, 0xc5, 0xa2, 0xa8, 0x97, 0x36, 0x30, 0xfe, + 0x55, 0xfd, 0x9d, 0x88, 0x63, 0xbb, 0xb4, 0xc1, 0xb7, 0xe6, 0x11, 0xd8, 0x7d, 0x27, 0xb8, 0x5f, + 0x2a, 0x7d, 0xbf, 0xed, 0x51, 0xe6, 0x32, 0x52, 0xd6, 0xb6, 0xf1, 0x90, 0x5c, 0x86, 0xe9, 0x0d, + 0x71, 0x92, 0x7b, 0x43, 0x5c, 0xd4, 0x0e, 0xc5, 0x4e, 0x39, 0x32, 0x92, 0x46, 0xdd, 0xa1, 0x02, + 0xea, 0x8e, 0x1f, 0x98, 0x2f, 0x93, 0x91, 0x8f, 0xae, 0x21, 0x73, 0xad, 0x06, 0xbf, 0x72, 0xeb, + 0xef, 0x0e, 0x7b, 0xef, 0x66, 0xdf, 0xa5, 0x5c, 0xe2, 0xe5, 0x7e, 0xe9, 0xee, 0xf7, 0xc6, 0xe6, + 0xd8, 0x05, 0x5f, 0xf4, 0xe4, 0x65, 0x26, 0xd2, 0x9b, 0x63, 0x4e, 0x3e, 0xf4, 0x54, 0x34, 0x73, + 0x0e, 0x2d, 0xa2, 0x8b, 0x71, 0x31, 0x0f, 0xa9, 0x11, 0x0c, 0x3d, 0x21, 0xa8, 0xfb, 0xe7, 0xe1, + 0x65, 0xb4, 0xff, 0xc9, 0xb7, 0x88, 0xa6, 0x6c, 0xe7, 0xa1, 0xbe, 0xc3, 0xf2, 0x32, 0xea, 0x47, + 0x40, 0xfc, 0x38, 0x3e, 0x95, 0xe6, 0x9b, 0xbc, 0xd4, 0x05, 0x0f, 0x7d, 0x25, 0x19, 0xbb, 0xf2, + 0x0e, 0xff, 0xc8, 0xa9, 0x4b, 0x57, 0xb0, 0xf6, 0x8e, 0xe2, 0xe8, 0x1a, 0x54, 0xdc, 0x08, 0xcc, + 0x09, 0x49, 0xea, 0xa2, 0x7c, 0x5e, 0x6f, 0x58, 0x5b, 0x43, 0x72, 0xf4, 0xbf, 0x48, 0xca, 0xb2, + 0x5f, 0x0b, 0xa3, 0x01, 0xf4, 0xa3, 0x44, 0xa4, 0xeb, 0x2b, 0x1c, 0x96, 0x50, 0xb2, 0x7c, 0x58, + 0x1c, 0xe1, 0xd2, 0x89, 0xc0, 0xf2, 0x46, 0x28, 0xd1, 0xe7, 0xf4, 0x06, 0x36, 0x9e, 0x81, 0x12, + 0x4d, 0xe9, 0x1a, 0x9e, 0x44, 0x07, 0x15, 0xf7, 0xcf, 0x54, 0xa2, 0x1d, 0x96, 0x0c, 0x49, 0xa2, + 0x03, 0xcb, 0x1b, 0xc1, 0x4d, 0xd6, 0xc0, 0xe7, 0xd7, 0x4b, 0x7a, 0xeb, 0x02, 0xfa, 0x54, 0xda, + 0x7e, 0xa7, 0xec, 0xbc, 0x6e, 0x6d, 0xf1, 0x63, 0xee, 0x9f, 0x08, 0xfd, 0xa2, 0xc1, 0x00, 0x47, + 0xd9, 0x4f, 0x02, 0x58, 0xfc, 0xfd, 0x20, 0xe7, 0xce, 0x1c, 0x4f, 0x8c, 0x92, 0x83, 0x49, 0xbd, + 0x65, 0x61, 0xb3, 0xa5, 0x35, 0xe7, 0x9b, 0xda, 0x66, 0x67, 0x3a, 0x4b, 0x8f, 0x66, 0x5e, 0xd1, + 0x35, 0x78, 0x97, 0x3c, 0x69, 0x54, 0x31, 0x47, 0xe8, 0xb9, 0x66, 0xc4, 0x2b, 0x7f, 0x6e, 0x0e, + 0x79, 0x13, 0x8b, 0x73, 0xfd, 0xd3, 0xf7, 0xa2, 0x19, 0x5f, 0x08, 0x20, 0xb3, 0xdd, 0x60, 0x44, + 0x9e, 0x29, 0x7a, 0x1b, 0x2f, 0x75, 0x35, 0xde, 0x99, 0x7a, 0xa4, 0x86, 0x6c, 0x98, 0x09, 0x43, + 0xfa, 0x08, 0x4e, 0x7e, 0xa4, 0xe1, 0x32, 0xfb, 0xfa, 0xba, 0x76, 0x1b, 0x6b, 0xa6, 0xd6, 0xaa, + 0xe3, 0x08, 0xd2, 0x1c, 0x34, 0x97, 0x9c, 0x87, 0x31, 0xbd, 0x6e, 0xb4, 0xaa, 0xfa, 0x8b, 0xec, + 0x87, 0x37, 0x4e, 0x07, 0x4e, 0x27, 0x29, 0x47, 0x4a, 0x3c, 0x87, 0xea, 0xe4, 0x55, 0x4a, 0x30, + 0x5e, 0xd7, 0xcc, 0x46, 0xd5, 0xf3, 0x14, 0xf1, 0x0d, 0xfd, 0x0b, 0xca, 0xdb, 0x59, 0x54, 0x37, + 0xb7, 0x52, 0x11, 0x99, 0x98, 0xe9, 0x3a, 0xfd, 0xeb, 0x5b, 0x58, 0xc1, 0xcd, 0x24, 0xf0, 0x9c, + 0x70, 0xc7, 0xc4, 0x4d, 0xfa, 0xce, 0x21, 0xeb, 0x76, 0xe3, 0xaa, 0x1b, 0x81, 0x3e, 0xe0, 0x95, + 0xe6, 0x65, 0x51, 0x9a, 0x5f, 0xe8, 0x23, 0x12, 0xfb, 0xd0, 0x18, 0xca, 0x9c, 0xf8, 0x9d, 0x8e, + 0x60, 0xae, 0x08, 0x82, 0x79, 0xd7, 0x80, 0x54, 0xc4, 0x2f, 0x99, 0xef, 0xca, 0xc0, 0x24, 0x3b, + 0x4c, 0xce, 0xd9, 0x89, 0x7e, 0x93, 0x3e, 0xad, 0x65, 0x3d, 0x80, 0xf7, 0x50, 0xf5, 0xe0, 0x03, + 0x9d, 0x0c, 0xd2, 0x05, 0xbc, 0xc7, 0xfb, 0x3b, 0xf9, 0x1b, 0x75, 0x8f, 0xd4, 0xa6, 0x6b, 0x96, + 0xd1, 0x34, 0xea, 0x3d, 0xd2, 0xe0, 0xea, 0xe3, 0xc7, 0xe7, 0x65, 0x12, 0x48, 0xb9, 0x46, 0x23, + 0xfc, 0xfd, 0x4e, 0xfe, 0x50, 0x5c, 0x0d, 0x13, 0x76, 0x9f, 0x79, 0xc0, 0x81, 0xc4, 0x1b, 0x15, + 0xd5, 0xe0, 0xe4, 0xf0, 0x26, 0xd7, 0x18, 0xb9, 0x05, 0x37, 0xa0, 0xee, 0xf8, 0x41, 0x79, 0x65, + 0x96, 0x77, 0x9a, 0x39, 0xc3, 0xb8, 0x40, 0x8f, 0x25, 0x3c, 0x2a, 0x41, 0x7a, 0x1e, 0x5b, 0xf5, + 0xad, 0x21, 0xf5, 0x99, 0x1d, 0xb3, 0x69, 0xf7, 0x99, 0x7d, 0xef, 0x04, 0xf6, 0x9f, 0x18, 0xda, + 0x64, 0xcd, 0x52, 0x92, 0x46, 0x7d, 0x5d, 0x63, 0x60, 0xed, 0xf1, 0x83, 0xf3, 0x23, 0x09, 0xa6, + 0x1c, 0xb3, 0x11, 0xc3, 0xe4, 0xb7, 0x9f, 0x71, 0xc6, 0x40, 0xf4, 0x85, 0x68, 0x57, 0xaa, 0x38, + 0x3c, 0x15, 0x5b, 0x16, 0xb3, 0xb5, 0x2e, 0xc2, 0x65, 0x2b, 0xe1, 0x08, 0x1c, 0xc1, 0xb2, 0x58, + 0x82, 0x31, 0x4a, 0x50, 0x41, 0xdf, 0xa5, 0x6e, 0x5a, 0x82, 0xf5, 0xee, 0xe1, 0xa1, 0x58, 0xef, + 0xee, 0x12, 0xad, 0x77, 0x21, 0xaf, 0x30, 0xb4, 0x8d, 0x77, 0x11, 0xfd, 0x16, 0x48, 0xfe, 0xa1, + 0xdb, 0xee, 0x22, 0xf8, 0x2d, 0xf4, 0xa9, 0x7f, 0x04, 0x0f, 0xaa, 0x9e, 0xe6, 0xca, 0xd6, 0xde, + 0xbc, 0x42, 0x0f, 0x2b, 0x90, 0x3a, 0x47, 0xfe, 0x7c, 0xc5, 0x7d, 0x56, 0xe0, 0xe1, 0x21, 0x1c, + 0x84, 0xbf, 0x07, 0x52, 0xf4, 0xe9, 0xd4, 0x54, 0xd7, 0x95, 0x9b, 0x81, 0x3b, 0x69, 0x84, 0x10, + 0x95, 0xe6, 0x8b, 0x7a, 0x59, 0x99, 0x50, 0xc4, 0xec, 0xf0, 0xdc, 0xf0, 0x94, 0x13, 0x90, 0x21, + 0xe5, 0x3a, 0xcb, 0x2c, 0x1e, 0x8a, 0x62, 0x7c, 0x0f, 0x41, 0x5b, 0xfc, 0xc8, 0x7f, 0x85, 0xbe, + 0xa0, 0x42, 0xef, 0x54, 0x7d, 0x6c, 0x08, 0xf0, 0xfa, 0xb0, 0xe5, 0xc0, 0xb0, 0xbf, 0xf7, 0x20, + 0xb0, 0x3b, 0x17, 0xb8, 0x8e, 0xd4, 0x89, 0x36, 0x04, 0x0d, 0x23, 0x39, 0xf9, 0x9b, 0xe1, 0x8e, + 0x7f, 0x0f, 0x0e, 0x13, 0xdd, 0x94, 0x20, 0xf4, 0x07, 0x42, 0x67, 0x88, 0x0e, 0x81, 0x03, 0xa3, + 0x73, 0x48, 0x2e, 0x81, 0x7f, 0x2a, 0xc1, 0x44, 0xd5, 0x7d, 0xee, 0x2b, 0xfc, 0x0b, 0x05, 0x91, + 0x21, 0x22, 0x63, 0xad, 0x70, 0x3f, 0xe4, 0xe4, 0xe0, 0x57, 0x86, 0x8a, 0xac, 0xf3, 0xd0, 0x3f, + 0xea, 0x2b, 0x43, 0xc3, 0x12, 0x12, 0x3f, 0x90, 0x9f, 0x63, 0x2f, 0x82, 0xe4, 0xea, 0x96, 0xbe, + 0x8b, 0xd1, 0x23, 0x31, 0x2a, 0xd2, 0x13, 0x90, 0x31, 0x36, 0x36, 0x3a, 0xfc, 0x1d, 0xb8, 0x49, + 0x95, 0x87, 0xdc, 0x07, 0xb8, 0x19, 0xb8, 0xfc, 0x01, 0xee, 0x88, 0x97, 0x0a, 0xee, 0x63, 0x28, + 0x6b, 0xd0, 0xa8, 0x2f, 0x15, 0x0c, 0x47, 0xc6, 0x08, 0xae, 0x0d, 0x06, 0xc2, 0x3d, 0x6e, 0xb2, + 0x79, 0x13, 0x37, 0x12, 0xe0, 0x83, 0x63, 0x3b, 0x03, 0x47, 0x3d, 0x16, 0x01, 0xfb, 0x62, 0x7a, + 0x21, 0x2e, 0xea, 0x59, 0x63, 0x87, 0x65, 0x43, 0xb7, 0x17, 0x44, 0xb0, 0x03, 0x87, 0x21, 0x62, + 0x24, 0xef, 0xbe, 0xd8, 0x43, 0xde, 0x88, 0xb0, 0xfa, 0x90, 0x17, 0xab, 0x8a, 0x88, 0xd5, 0xd9, + 0x30, 0x6c, 0x0a, 0x37, 0x04, 0x86, 0x5a, 0x4e, 0x3e, 0xe9, 0xc0, 0xa5, 0x0a, 0x70, 0xdd, 0x33, + 0x30, 0x1d, 0xf1, 0x23, 0xf6, 0x31, 0x89, 0x3d, 0xfe, 0x90, 0xdb, 0xd5, 0xf4, 0x26, 0x3d, 0x20, + 0x3e, 0x84, 0x07, 0xe3, 0xfe, 0xbb, 0x17, 0x94, 0x73, 0x22, 0x28, 0xf7, 0x85, 0x61, 0x86, 0x40, + 0x91, 0x0f, 0x36, 0xcf, 0xf7, 0xda, 0xcc, 0xd9, 0x2d, 0xa2, 0x97, 0x77, 0xdf, 0xc4, 0xc6, 0xbf, + 0x7b, 0x8d, 0xe9, 0x9f, 0x75, 0x40, 0x7a, 0x50, 0x00, 0xa9, 0x78, 0x50, 0xba, 0xa2, 0x61, 0xb5, + 0x34, 0xc0, 0x8b, 0xf6, 0xd3, 0x70, 0xbc, 0x5c, 0xa9, 0xad, 0xe5, 0xd6, 0x0a, 0xb9, 0x5a, 0xee, + 0x5c, 0xa9, 0x78, 0x7e, 0x6d, 0x6e, 0xa9, 0x92, 0x7f, 0x40, 0x96, 0xd0, 0xef, 0xb3, 0x31, 0xb0, + 0x6a, 0xec, 0x98, 0xf5, 0x61, 0xcd, 0x36, 0x3b, 0xb4, 0x30, 0xde, 0xe9, 0x78, 0x28, 0xaa, 0xe3, + 0xba, 0xeb, 0x8f, 0x69, 0x13, 0xd7, 0xaf, 0xa3, 0xa5, 0x86, 0xec, 0xb8, 0xde, 0x97, 0x82, 0xf8, + 0xbb, 0xd8, 0x0f, 0x24, 0x80, 0x05, 0xd3, 0xd8, 0x69, 0x57, 0xcc, 0x06, 0x36, 0xd1, 0xd3, 0xee, + 0xaa, 0xef, 0x77, 0x87, 0x30, 0x59, 0x59, 0x01, 0xd8, 0x74, 0x0a, 0xe7, 0x7a, 0xea, 0x96, 0x70, + 0x6b, 0x3c, 0x97, 0x28, 0xd5, 0x53, 0x06, 0xfa, 0x88, 0x17, 0xe3, 0x9f, 0x16, 0x31, 0x0e, 0x1a, + 0x79, 0xdc, 0xe2, 0x86, 0xb9, 0xea, 0x7b, 0xb7, 0x83, 0x75, 0x4d, 0xc0, 0xfa, 0xbe, 0x03, 0x50, + 0x12, 0x3f, 0xe6, 0x3f, 0x94, 0x60, 0x82, 0xed, 0xc5, 0x32, 0x9e, 0xfe, 0xad, 0x0b, 0xfa, 0x2b, + 0x87, 0x00, 0xfa, 0x2a, 0x1c, 0x35, 0xdc, 0xd2, 0xd9, 0xc8, 0xe8, 0xb5, 0xae, 0x05, 0xc2, 0xee, + 0xa1, 0x4b, 0x15, 0x8a, 0x41, 0x1f, 0xf3, 0x22, 0xaf, 0x8a, 0xc8, 0xdf, 0x15, 0xc0, 0x6f, 0x4f, + 0x89, 0xc3, 0x84, 0xfe, 0x3d, 0x0e, 0xf4, 0xab, 0x02, 0xf4, 0xb9, 0x83, 0x90, 0x12, 0x3f, 0xf6, + 0x2f, 0x76, 0x0c, 0xf4, 0xce, 0xf6, 0x49, 0x2c, 0x9b, 0x26, 0xaf, 0x1e, 0x70, 0x81, 0x21, 0xd2, + 0xe6, 0x83, 0xd4, 0x14, 0x24, 0x75, 0x9b, 0x86, 0xa4, 0xde, 0x18, 0x68, 0x09, 0x11, 0x58, 0x51, + 0xfc, 0x38, 0xbc, 0xe1, 0xd9, 0x90, 0x2e, 0xe0, 0xf5, 0x9d, 0x4d, 0xf4, 0x56, 0x09, 0xb2, 0x4d, + 0x63, 0xb3, 0xd4, 0xda, 0x30, 0x78, 0xc3, 0x12, 0x76, 0xc3, 0x14, 0x05, 0x52, 0x5b, 0x58, 0xb3, + 0x9b, 0x4a, 0xff, 0x2b, 0xa7, 0x60, 0x8a, 0xfc, 0xda, 0xcf, 0xc9, 0x3a, 0xb7, 0x4f, 0x76, 0xc5, + 0x92, 0x09, 0xaa, 0x65, 0x58, 0x5a, 0x53, 0xc5, 0x75, 0xc3, 0x6c, 0xb0, 0xd3, 0x22, 0x69, 0x55, + 0x88, 0x23, 0x78, 0xd3, 0x30, 0xf5, 0x5f, 0x48, 0xd3, 0x04, 0x6e, 0x84, 0x72, 0x2d, 0x4c, 0x6e, + 0xe8, 0x66, 0xc7, 0x62, 0xa9, 0x6b, 0xcc, 0xc1, 0x25, 0xad, 0x8a, 0x91, 0xf4, 0x3d, 0x7b, 0x37, + 0xe2, 0x1c, 0x36, 0xe9, 0xe3, 0x42, 0x69, 0xb5, 0x2b, 0x96, 0xd0, 0xd3, 0xd4, 0x3c, 0x85, 0x8d, + 0x31, 0x7a, 0xbc, 0x71, 0xa4, 0x46, 0x37, 0x4c, 0x8a, 0x1a, 0x67, 0x35, 0x0a, 0x91, 0xa4, 0x46, + 0x12, 0xb1, 0xb2, 0xd3, 0x6c, 0x56, 0x71, 0x3d, 0xb7, 0x69, 0x4c, 0x03, 0xab, 0x51, 0x8c, 0x55, + 0x10, 0x8c, 0xed, 0xb4, 0xab, 0x96, 0x66, 0xed, 0x74, 0xa6, 0x27, 0xd8, 0x7e, 0x92, 0x1d, 0x56, + 0x4e, 0x02, 0x34, 0x8c, 0x8b, 0x2d, 0xfe, 0xf5, 0x28, 0xf3, 0x37, 0x72, 0x63, 0xc8, 0xb2, 0x99, + 0x89, 0xec, 0x24, 0xbb, 0xc3, 0x8e, 0xf9, 0x73, 0x7d, 0x5e, 0x02, 0xb0, 0xb6, 0x4c, 0xac, 0x35, + 0x7a, 0xc2, 0xf5, 0x02, 0x38, 0xd1, 0x34, 0x36, 0x3b, 0xe7, 0x75, 0x6b, 0xcb, 0x05, 0x62, 0xd1, + 0x06, 0x30, 0xad, 0xfa, 0x7c, 0x55, 0xee, 0x83, 0x2b, 0xec, 0x2f, 0xe7, 0xb7, 0x8c, 0x26, 0xae, + 0x99, 0x18, 0x77, 0xe1, 0x9b, 0x56, 0x83, 0x92, 0x28, 0xb3, 0x90, 0x22, 0x9f, 0xf9, 0x53, 0xdf, + 0x48, 0x90, 0x7b, 0x2a, 0x66, 0xb3, 0x5c, 0xc4, 0x54, 0x9a, 0x4e, 0xb9, 0x1d, 0x2e, 0x37, 0x2e, + 0xb6, 0x96, 0x8c, 0xcd, 0x45, 0xad, 0x93, 0xd7, 0x36, 0xb0, 0x8a, 0xd9, 0xb1, 0x29, 0xc3, 0xe4, + 0xcf, 0xfe, 0xfb, 0x7d, 0x56, 0x66, 0x41, 0xa9, 0x6b, 0x1b, 0x78, 0x49, 0x04, 0x80, 0x49, 0x46, + 0x8f, 0x2f, 0x04, 0x76, 0x12, 0xbb, 0x6a, 0x03, 0x91, 0x65, 0x07, 0x51, 0xbd, 0x71, 0x04, 0x50, + 0x12, 0x2e, 0xb8, 0x80, 0x8c, 0xd1, 0x54, 0x5d, 0xb1, 0xfb, 0x44, 0x7a, 0xbc, 0x9f, 0x48, 0x43, + 0xb7, 0x48, 0x3b, 0xb0, 0x4e, 0x78, 0x61, 0xfd, 0x52, 0x1a, 0x52, 0xd5, 0xbd, 0x56, 0x1d, 0xbd, + 0xde, 0x33, 0xfc, 0x9d, 0x81, 0xe3, 0x26, 0x2b, 0xb3, 0x66, 0x6a, 0xbb, 0xd8, 0xec, 0xe0, 0x25, + 0x6a, 0x47, 0x49, 0xd0, 0x32, 0x7b, 0x7e, 0x23, 0xf2, 0xdb, 0xb9, 0xa0, 0xb7, 0x8b, 0xdb, 0x6d, + 0x6b, 0x6f, 0x89, 0xe0, 0x91, 0x64, 0xb7, 0x40, 0x09, 0x91, 0xca, 0x3d, 0x80, 0x2c, 0x73, 0xaf, + 0x66, 0xd8, 0xf8, 0xa9, 0x78, 0xdb, 0xb0, 0xb0, 0xdd, 0x28, 0xd6, 0x9b, 0x03, 0x52, 0xa0, 0xb7, + 0xa4, 0x3c, 0xba, 0xf5, 0x2e, 0x51, 0xb7, 0x9e, 0xea, 0x01, 0x3d, 0x69, 0x9a, 0x8f, 0x26, 0x7d, + 0x21, 0x64, 0x99, 0x3c, 0xdb, 0xab, 0x94, 0xab, 0x7a, 0xe4, 0x77, 0x25, 0x5e, 0xb5, 0x53, 0x93, + 0xbe, 0xd5, 0xc0, 0xbb, 0x7a, 0x1d, 0xbb, 0xfe, 0x64, 0x76, 0xd8, 0x81, 0xa9, 0xc6, 0x4b, 0xf6, + 0x6a, 0x1e, 0x1e, 0x47, 0x79, 0xc0, 0xfe, 0x12, 0x91, 0x36, 0x76, 0x2c, 0x22, 0x62, 0xa5, 0x56, + 0x85, 0x4a, 0x1d, 0x57, 0x45, 0x01, 0x29, 0x94, 0x39, 0xb8, 0x52, 0xfc, 0xba, 0x28, 0xea, 0x44, + 0x26, 0x90, 0x81, 0x69, 0xf6, 0x89, 0x53, 0xb6, 0x9f, 0x38, 0x8d, 0x75, 0x89, 0x13, 0x7a, 0x8d, + 0x33, 0xf0, 0xdc, 0x2b, 0x0c, 0x3c, 0x37, 0x84, 0x43, 0x61, 0x24, 0xd7, 0x65, 0x65, 0x18, 0xcb, + 0xd1, 0x6f, 0x7a, 0x64, 0x1b, 0xc1, 0x18, 0x07, 0xd5, 0x56, 0x5f, 0x4e, 0x78, 0x44, 0x32, 0xfc, + 0xda, 0xd0, 0xaf, 0x66, 0x30, 0xee, 0xb1, 0x46, 0xf8, 0x48, 0xf1, 0xad, 0x90, 0xd2, 0x5b, 0x1b, + 0x06, 0x9f, 0xb8, 0xf5, 0x11, 0x61, 0x9a, 0x34, 0xe4, 0x33, 0x19, 0x01, 0x75, 0xc7, 0x8f, 0xdd, + 0x4b, 0x25, 0x48, 0x11, 0x35, 0xef, 0xbd, 0xf7, 0x13, 0xc1, 0x18, 0x9b, 0x14, 0xbb, 0xc0, 0xd9, + 0xe1, 0x9e, 0x6f, 0x87, 0xcc, 0xc0, 0xd1, 0x9d, 0x96, 0xd6, 0x32, 0x5a, 0x7b, 0xdb, 0xfa, 0x8b, + 0x9c, 0xa9, 0x82, 0x10, 0x47, 0xa8, 0xdf, 0xc4, 0x2d, 0x6c, 0x6a, 0x16, 0xae, 0xee, 0x6e, 0xd2, + 0xde, 0x3a, 0xa6, 0x7a, 0xa3, 0xd0, 0x8b, 0x93, 0xd1, 0x14, 0x0e, 0xa1, 0xda, 0xff, 0x89, 0xca, + 0x0d, 0xbd, 0x89, 0xa9, 0x7f, 0x3b, 0xf7, 0xf1, 0xb0, 0xc3, 0x91, 0x7a, 0x53, 0x8f, 0x2a, 0x46, + 0x82, 0x88, 0xcc, 0xde, 0x4c, 0x59, 0x32, 0xea, 0x5a, 0xb3, 0x63, 0x19, 0x26, 0x46, 0xcf, 0x77, + 0xd1, 0xb1, 0x11, 0x48, 0x78, 0x10, 0x38, 0x01, 0x99, 0x86, 0x51, 0x77, 0x3d, 0x19, 0x78, 0x48, + 0x5c, 0xce, 0x04, 0x1e, 0x23, 0x62, 0x0d, 0xee, 0xae, 0x37, 0xb6, 0x07, 0x64, 0xc2, 0x1d, 0x2d, + 0x0a, 0x45, 0xd4, 0x08, 0xee, 0x55, 0x48, 0x42, 0x6a, 0x45, 0x6f, 0x6d, 0x7a, 0x17, 0x31, 0xc7, + 0x21, 0xad, 0xb7, 0x1a, 0xf8, 0x12, 0x1f, 0xa9, 0x59, 0x80, 0x0c, 0xe7, 0xad, 0x9d, 0xed, 0x75, + 0x6c, 0x56, 0x36, 0x68, 0x73, 0x3b, 0x35, 0xa3, 0x8a, 0x5b, 0xf6, 0xcc, 0xac, 0xe7, 0x37, 0xf4, + 0xe3, 0x44, 0x34, 0xb9, 0x27, 0x94, 0xf8, 0xe0, 0xe2, 0x10, 0x95, 0xf4, 0x10, 0x15, 0x49, 0xe2, + 0x7b, 0x14, 0x1e, 0x3f, 0x7f, 0x3f, 0x95, 0x84, 0xec, 0x32, 0xb6, 0x4c, 0xbd, 0xde, 0x41, 0x1f, + 0x4e, 0xc2, 0x64, 0x15, 0x5b, 0x2b, 0x9a, 0xa9, 0x6d, 0x63, 0x8b, 0x2c, 0xc9, 0x6f, 0x10, 0x14, + 0x53, 0xbb, 0xa9, 0x59, 0x1b, 0x86, 0xb9, 0x6d, 0x2b, 0x26, 0x3b, 0x7c, 0x47, 0xea, 0xd1, 0x6f, + 0x4b, 0x09, 0x91, 0x99, 0x81, 0xae, 0x37, 0xbc, 0xc2, 0x59, 0xa1, 0x32, 0x9f, 0x13, 0x16, 0xe1, + 0x9c, 0x69, 0xc2, 0x94, 0x18, 0x3f, 0x33, 0xff, 0x44, 0x02, 0x69, 0xc9, 0xd8, 0x44, 0xef, 0x97, + 0x20, 0x45, 0xe5, 0xeb, 0x6d, 0x9e, 0x21, 0x79, 0x1a, 0xb2, 0xdb, 0xb8, 0xd3, 0xd1, 0x36, 0xb1, + 0xfd, 0xbe, 0x34, 0x0f, 0x2a, 0x67, 0x21, 0xdd, 0xc4, 0xbb, 0xb8, 0x49, 0xc9, 0x98, 0x3a, 0x73, + 0x8d, 0xd0, 0xb2, 0x25, 0x63, 0x73, 0x96, 0x94, 0xe5, 0xbc, 0x42, 0xbb, 0x44, 0x92, 0xaa, 0x2c, + 0xc7, 0xcc, 0xfd, 0x90, 0xa6, 0x61, 0x65, 0x1c, 0xd2, 0x85, 0xe2, 0xdc, 0xea, 0x82, 0x7c, 0x84, + 0xfc, 0xb5, 0xe9, 0x1b, 0x87, 0xf4, 0x7c, 0xae, 0x96, 0x5b, 0x92, 0x93, 0xa4, 0x1d, 0xa5, 0xf2, + 0x7c, 0x45, 0x96, 0x48, 0xe4, 0x4a, 0xae, 0x5c, 0xca, 0xcb, 0x29, 0x65, 0x02, 0xb2, 0xe7, 0x73, + 0x6a, 0xb9, 0x54, 0x5e, 0x90, 0xd3, 0xe8, 0x61, 0xaf, 0xc2, 0xba, 0x43, 0xc4, 0xef, 0x5a, 0x3f, + 0x9a, 0x7a, 0x41, 0xf6, 0xef, 0x1d, 0xc8, 0xee, 0x16, 0x20, 0xfb, 0xa9, 0x30, 0x85, 0x44, 0x43, + 0xa9, 0x3c, 0x80, 0x21, 0x7b, 0x12, 0xc6, 0xcb, 0x95, 0xda, 0xda, 0x7c, 0x65, 0xb5, 0x5c, 0x90, + 0x31, 0xe1, 0x41, 0xad, 0xb4, 0x5c, 0xac, 0xac, 0xd6, 0xe4, 0x0d, 0xf4, 0xfa, 0x24, 0x64, 0x57, + 0x4c, 0xa3, 0x8e, 0x3b, 0x1d, 0xf4, 0x8a, 0x24, 0x64, 0xf2, 0x5a, 0xab, 0x8e, 0x9b, 0xe8, 0xd9, + 0x2e, 0x8c, 0x5d, 0x4b, 0x42, 0xf4, 0x03, 0xaf, 0xd4, 0xdf, 0x27, 0x72, 0x4d, 0x7c, 0x57, 0x98, + 0x97, 0x3b, 0xcb, 0xca, 0xf4, 0xe1, 0xdd, 0x13, 0x0e, 0xef, 0xf2, 0x02, 0xef, 0x6e, 0x0e, 0x5f, + 0x54, 0xfc, 0x72, 0xfe, 0xf7, 0x09, 0x38, 0xbe, 0x40, 0xa6, 0x0f, 0x7a, 0x9d, 0x11, 0x6f, 0xb7, + 0xff, 0x6e, 0xb1, 0xfd, 0xcf, 0x15, 0x88, 0xee, 0x95, 0x43, 0x6c, 0xfc, 0xe3, 0x4e, 0xe3, 0xef, + 0x13, 0x1a, 0x7f, 0x63, 0xc8, 0x72, 0x62, 0x6f, 0xf9, 0x4c, 0x16, 0xd2, 0x74, 0x8a, 0x3c, 0x73, + 0x1d, 0x4c, 0x56, 0x2d, 0x13, 0x6b, 0xdb, 0x9e, 0x41, 0xc9, 0x32, 0x2e, 0xe0, 0x16, 0x17, 0x0d, + 0x16, 0xb8, 0xe3, 0x2c, 0x64, 0x5b, 0xc6, 0x9a, 0xb6, 0x63, 0x6d, 0x29, 0xcf, 0xd9, 0x77, 0x6c, + 0x68, 0x99, 0xf5, 0xff, 0x4a, 0x9b, 0xed, 0x22, 0x7d, 0xe3, 0x2e, 0x3a, 0x31, 0xcb, 0xb4, 0x8c, + 0xdc, 0x8e, 0xb5, 0x35, 0x77, 0xe5, 0x27, 0x9f, 0x3e, 0x99, 0xf8, 0xcc, 0xd3, 0x27, 0x13, 0x5f, + 0x7f, 0xfa, 0x64, 0xe2, 0xb7, 0xbf, 0x79, 0xf2, 0xc8, 0x67, 0xbe, 0x79, 0xf2, 0xc8, 0x97, 0xbf, + 0x79, 0xf2, 0xc8, 0xcf, 0x26, 0xdb, 0xeb, 0xeb, 0x19, 0x5a, 0xca, 0x6d, 0xff, 0x2f, 0x00, 0x00, + 0xff, 0xff, 0x72, 0x07, 0xac, 0x64, 0xb3, 0x32, 0x01, 0x00, } func (m *Rpc) Marshal() (dAtA []byte, err error) { @@ -52875,12 +52943,12 @@ func (m *RpcObjectImportRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) if m.Mode != 0 { i = encodeVarintCommands(dAtA, i, uint64(m.Mode)) i-- - dAtA[i] = 0x30 + dAtA[i] = 0x38 } if m.Type != 0 { i = encodeVarintCommands(dAtA, i, uint64(m.Type)) i-- - dAtA[i] = 0x28 + dAtA[i] = 0x30 } if m.UpdateExistingObjects { i-- @@ -52890,7 +52958,7 @@ func (m *RpcObjectImportRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) dAtA[i] = 0 } i-- - dAtA[i] = 0x20 + dAtA[i] = 0x28 } if len(m.Snapshots) > 0 { for iNdEx := len(m.Snapshots) - 1; iNdEx >= 0; iNdEx-- { @@ -52903,7 +52971,7 @@ func (m *RpcObjectImportRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) i = encodeVarintCommands(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1a + dAtA[i] = 0x22 } } if m.Params != nil { @@ -52960,6 +53028,27 @@ func (m *RpcObjectImportRequestParamsOfBookmarksParams) MarshalToSizedBuffer(dAt } return len(dAtA) - i, nil } +func (m *RpcObjectImportRequestParamsOfMarkdownParams) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RpcObjectImportRequestParamsOfMarkdownParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.MarkdownParams != nil { + { + size, err := m.MarkdownParams.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommands(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + return len(dAtA) - i, nil +} func (m *RpcObjectImportRequestNotionParams) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -52976,6 +53065,36 @@ func (m *RpcObjectImportRequestNotionParams) MarshalTo(dAtA []byte) (int, error) } func (m *RpcObjectImportRequestNotionParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ApiKey) > 0 { + i -= len(m.ApiKey) + copy(dAtA[i:], m.ApiKey) + i = encodeVarintCommands(dAtA, i, uint64(len(m.ApiKey))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RpcObjectImportRequestMarkdownParams) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RpcObjectImportRequestMarkdownParams) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RpcObjectImportRequestMarkdownParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -74876,7 +74995,32 @@ func (m *RpcObjectImportRequestParamsOfBookmarksParams) Size() (n int) { } return n } +func (m *RpcObjectImportRequestParamsOfMarkdownParams) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.MarkdownParams != nil { + l = m.MarkdownParams.Size() + n += 1 + l + sovCommands(uint64(l)) + } + return n +} func (m *RpcObjectImportRequestNotionParams) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ApiKey) + if l > 0 { + n += 1 + l + sovCommands(uint64(l)) + } + return n +} + +func (m *RpcObjectImportRequestMarkdownParams) Size() (n int) { if m == nil { return 0 } @@ -106711,6 +106855,41 @@ func (m *RpcObjectImportRequest) Unmarshal(dAtA []byte) error { m.Params = &RpcObjectImportRequestParamsOfBookmarksParams{v} iNdEx = postIndex case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MarkdownParams", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &RpcObjectImportRequestMarkdownParams{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Params = &RpcObjectImportRequestParamsOfMarkdownParams{v} + iNdEx = postIndex + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Snapshots", wireType) } @@ -106744,7 +106923,7 @@ func (m *RpcObjectImportRequest) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 4: + case 5: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field UpdateExistingObjects", wireType) } @@ -106764,7 +106943,7 @@ func (m *RpcObjectImportRequest) Unmarshal(dAtA []byte) error { } } m.UpdateExistingObjects = bool(v != 0) - case 5: + case 6: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) } @@ -106783,7 +106962,7 @@ func (m *RpcObjectImportRequest) Unmarshal(dAtA []byte) error { break } } - case 6: + case 7: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Mode", wireType) } @@ -106852,6 +107031,88 @@ func (m *RpcObjectImportRequestNotionParams) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: NotionParams: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ApiKey", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ApiKey = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcObjectImportRequestMarkdownParams) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + 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) + if wireType == 4 { + return fmt.Errorf("proto: MarkdownParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MarkdownParams: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { case 1: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) diff --git a/pb/protos/commands.proto b/pb/protos/commands.proto index 8a5bb32f2..acce518a7 100644 --- a/pb/protos/commands.proto +++ b/pb/protos/commands.proto @@ -1685,13 +1685,18 @@ message Rpc { oneof params { NotionParams notionParams = 1; BookmarksParams bookmarksParams = 2; + MarkdownParams markdownParams = 3; } - repeated Snapshot snapshots = 3; // optional, for external developers usage - bool updateExistingObjects = 4; - Type type = 5; - Mode mode = 6; + repeated Snapshot snapshots = 4; // optional, for external developers usage + bool updateExistingObjects = 5; + Type type = 6; + Mode mode = 7; message NotionParams { + string apiKey = 1; + } + + message MarkdownParams { string path = 1; } @@ -1710,7 +1715,8 @@ message Rpc { }; enum Type { Notion = 0; - External = 1; // external developers use it + Markdown = 1; + External = 2; // external developers use it }; } @@ -1755,6 +1761,7 @@ message Rpc { Type type = 1; enum Type { Notion = 0; + Markdown = 1; }; } } From 385d17d35dfc79f204be5ba6cd120c11d45dff89 Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Thu, 3 Nov 2022 12:21:29 +0300 Subject: [PATCH 02/68] GO-469: fix comments Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/markdown/import.go | 19 +++++-------- core/block/import/notion/api/client/error.go | 10 ++----- .../import/notion/api/database/database.go | 28 +++++++++---------- core/block/import/notion/converter.go | 8 +++--- 4 files changed, 27 insertions(+), 38 deletions(-) diff --git a/core/block/import/markdown/import.go b/core/block/import/markdown/import.go index 7685d70e6..0ceb767bd 100644 --- a/core/block/import/markdown/import.go +++ b/core/block/import/markdown/import.go @@ -19,7 +19,6 @@ import ( "github.com/anytypeio/go-anytype-middleware/util/slice" "github.com/globalsign/mgo/bson" "github.com/gogo/protobuf/types" - "github.com/pkg/errors" "github.com/textileio/go-threads/core/thread" ) @@ -52,11 +51,11 @@ func (m *Markdown) Name() string { return Name } -func (m *Markdown) GetParams(params pb.IsRpcObjectImportRequestParams) (string, error) { - if p, ok := params.(*pb.RpcObjectImportRequestParamsOfMarkdownParams); ok { - return p.MarkdownParams.GetPath(), nil - } - return "", errors.Wrap(errors.New("wrong parameters format"), "Markdown: GetParams") +func (m *Markdown) GetParams(req *pb.RpcObjectImportRequest) string { + if p := req.GetMarkdownParams(); p != nil { + return p.Path + } + return "" } func (m *Markdown) GetImage() ([]byte, int64, int64, error) { @@ -64,12 +63,7 @@ func (m *Markdown) GetImage() ([]byte, int64, int64, error) { } func (m *Markdown) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Response { - path, err := m.GetParams(req.Params) - allErrors := converter.NewError() - if err != nil { - allErrors.Add(path, err) - return &converter.Response{Error: allErrors} - } + path := m.GetParams(req) files, allErrors := m.blockConverter.MarkdownToBlocks(path, req.GetMode().String()) if !allErrors.IsEmpty() && req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING{ if req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { @@ -192,6 +186,7 @@ func (m *Markdown) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Respo for name, file := range files { if file.IsRootFile && strings.EqualFold(filepath.Ext(name), ".csv") { file.ParsedBlocks = m.convertCsvToLinks(name, files) + details[name].Fields[bundle.RelationKeyIsFavorite.String()] = pbtypes.Bool(true) } if file.PageID == "" { diff --git a/core/block/import/notion/api/client/error.go b/core/block/import/notion/api/client/error.go index 2ccaf34a0..8ce2c49c1 100644 --- a/core/block/import/notion/api/client/error.go +++ b/core/block/import/notion/api/client/error.go @@ -13,15 +13,11 @@ type NotionErrorResponse struct { Message string `json:"message,omitempty"` } -func (ne *NotionErrorResponse) Error() error { - return fmt.Errorf("status: %d, code: %s, message: %s", ne.Status, ne.Code, ne.Message) -} - -func TransformHttpCodeToError(response []byte) *NotionErrorResponse { - var notionErr = NotionErrorResponse{} +func TransformHttpCodeToError(response []byte) error { + var notionErr NotionErrorResponse if err := json.Unmarshal(response, ¬ionErr); err != nil { logging.Logger("client").Error("failed to parse error response from notion %s", err) return nil } - return ¬ionErr + return fmt.Errorf("status: %d, code: %s, message: %s", notionErr.Status, notionErr.Code, notionErr.Message) } diff --git a/core/block/import/notion/api/database/database.go b/core/block/import/notion/api/database/database.go index a690b2d63..91bd299c6 100644 --- a/core/block/import/notion/api/database/database.go +++ b/core/block/import/notion/api/database/database.go @@ -72,19 +72,15 @@ type ListDatabasesResponse struct { func (ds *DatabaseService) GetDatabase(ctx context.Context, mode pb.RpcObjectImportRequestMode, apiKey string) *converter.Response { var convereterError = converter.ConvertError{} - databases, notionErr, err := ds.listDatabases(ctx, apiKey, pageSize) + databases, err := ds.listDatabases(ctx, apiKey, pageSize) if err != nil { convereterError.Add(endpoint, err) return &converter.Response{Error: convereterError} } - if notionErr != nil { - convereterError.Add(endpoint, notionErr.Error()) - return &converter.Response{Error: convereterError} - } return ds.mapDatabasesToSnaphots(ctx, mode, databases, convereterError) } -func (ds *DatabaseService) listDatabases(ctx context.Context, apiKey string, pageSize int64) ([]Database, *client.NotionErrorResponse, error) { +func (ds *DatabaseService) listDatabases(ctx context.Context, apiKey string, pageSize int64) ([]Database, error) { var ( hasMore = true body = &bytes.Buffer{} @@ -98,41 +94,42 @@ func (ds *DatabaseService) listDatabases(ctx context.Context, apiKey string, pag err := json.NewEncoder(body).Encode(&Option{PageSize: pageSize, StartCursor: startCursor}) if err != nil { - return nil, nil, fmt.Errorf("ListDatabases: %s", err) + return nil, fmt.Errorf("ListDatabases: %s", err) } req, err := ds.client.PrepareRequest(ctx, apiKey, http.MethodPost, endpoint, body) + if err != nil { - return nil, nil, fmt.Errorf("ListDatabases: %s", err) + return nil, fmt.Errorf("ListDatabases: %s", err) } for hasMore { res, err := ds.client.HttpClient.Do(req) + if err != nil { - return nil, nil, fmt.Errorf("ListDatabases: %s", err) + return nil, fmt.Errorf("ListDatabases: %s", err) } defer res.Body.Close() b, err := ioutil.ReadAll(res.Body) if err != nil { - return nil, nil, err + return nil, err } var databases ListDatabasesResponse if res.StatusCode != http.StatusOK { notionErr := client.TransformHttpCodeToError(b) if notionErr == nil { - return nil, nil, fmt.Errorf("failed http request, %d code", res.StatusCode) + return nil, fmt.Errorf("failed http request, %d code", res.StatusCode) } - return nil, notionErr, nil + return nil, notionErr } err = json.Unmarshal(b, &databases) if err != nil { - return nil, nil, err + return nil, err } - for _, d := range databases.Results { if d.Object == objectType { resultDatabases = append(resultDatabases, d) @@ -147,7 +144,7 @@ func (ds *DatabaseService) listDatabases(ctx context.Context, apiKey string, pag startCursor += pageSize } - return resultDatabases, nil, nil + return resultDatabases, nil } func (ds *DatabaseService) mapDatabasesToSnaphots(ctx context.Context, mode pb.RpcObjectImportRequestMode, databases []Database, convereterError converter.ConvertError) *converter.Response { @@ -191,6 +188,7 @@ func (ds *DatabaseService) transformDatabase(d Database) *model.SmartBlockSnapsh details[bundle.RelationKeyLastModifiedDate.String()] = pbtypes.String(d.LastEditedTime.String()) details[bundle.RelationKeyLastModifiedBy.String()] = pbtypes.String(d.LastEditedBy.Name) details[bundle.RelationKeyDescription.String()] = pbtypes.String(api.RichTextToDescription(d.Description)) + details[bundle.RelationKeyIsFavorite.String()] = pbtypes.Bool(true) snapshot := &model.SmartBlockSnapshotBase{ Blocks: []*model.Block{}, diff --git a/core/block/import/notion/converter.go b/core/block/import/notion/converter.go index dc717b754..00ea06047 100644 --- a/core/block/import/notion/converter.go +++ b/core/block/import/notion/converter.go @@ -28,7 +28,7 @@ func New(core.Service) converter.Converter { func (n *Notion) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Response { ce := converter.NewError() - apiKey := n.getParams(req.Params) + apiKey := n.getParams(req) if apiKey == "" { ce.Add("apiKey", fmt.Errorf("failed to extract apikey")) return &converter.Response{ @@ -38,9 +38,9 @@ func (n *Notion) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Respons return n.database.GetDatabase(context.TODO(), req.Mode, apiKey) } -func (n *Notion) getParams(param pb.IsRpcObjectImportRequestParams) string { - if p, ok := param.(*pb.RpcObjectImportRequestParamsOfNotionParams); ok { - return p.NotionParams.GetApiKey() +func (n *Notion) getParams(param *pb.RpcObjectImportRequest) string { + if p := param.GetNotionParams(); p != nil { + return p.GetApiKey() } return "" } From d41b5919f9ebddbee9aa7ec63941dc2063c42e59 Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Fri, 4 Nov 2022 10:28:52 +0300 Subject: [PATCH 03/68] GO-470: init Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/notion/api/commonobjects.go | 9 + .../import/notion/api/database/database.go | 117 +--- .../notion/api/database/database_test.go | 50 -- core/block/import/notion/api/page/page.go | 126 ++++ .../notion/api/property/propertyconfig.go | 501 ++++++++++++++++ .../notion/api/property/propertyobject.go | 543 ++++++++++++++++++ core/block/import/notion/api/search/search.go | 106 ++++ .../import/notion/api/search/search_test.go | 62 ++ core/block/import/notion/converter.go | 41 +- core/block/import/objectcreator.go | 1 + 10 files changed, 1396 insertions(+), 160 deletions(-) create mode 100644 core/block/import/notion/api/page/page.go create mode 100644 core/block/import/notion/api/property/propertyconfig.go create mode 100644 core/block/import/notion/api/property/propertyobject.go create mode 100644 core/block/import/notion/api/search/search.go create mode 100644 core/block/import/notion/api/search/search_test.go diff --git a/core/block/import/notion/api/commonobjects.go b/core/block/import/notion/api/commonobjects.go index 885c45d16..612f00916 100644 --- a/core/block/import/notion/api/commonobjects.go +++ b/core/block/import/notion/api/commonobjects.go @@ -96,6 +96,15 @@ type Person struct { Email string `json:"email"` } +type Parent struct { + Type string `json:"type,omitempty"` + PageID string `json:"page_id"` +} + +type Object interface { + GetObjectType() string +} + func RichTextToDescription(rt []RichText) string { var description bytes.Buffer diff --git a/core/block/import/notion/api/database/database.go b/core/block/import/notion/api/database/database.go index 91bd299c6..5d0182797 100644 --- a/core/block/import/notion/api/database/database.go +++ b/core/block/import/notion/api/database/database.go @@ -1,18 +1,12 @@ package database import ( - "bytes" "context" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" "time" "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/block" - "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock" @@ -23,22 +17,12 @@ import ( "github.com/textileio/go-threads/core/thread" ) -type DatabaseID string +const ObjectType = "database" -const ( - endpoint = "/search" - pageSize = 100 - objectType = "database" -) +type Service struct {} -type DatabaseService struct { - client *client.Client -} - -func New() *DatabaseService { - return &DatabaseService{ - client: client.NewClient(), - } +func New() *Service { + return &Service{} } type Database struct { @@ -49,7 +33,7 @@ type Database struct { CreatedBy api.User `json:"created_by,omitempty"` LastEditedBy api.User `json:"last_edited_by,omitempty"` Title []api.RichText `json:"title"` - Parent Parent `json:"parent"` + Parent api.Parent `json:"parent"` URL string `json:"url"` Properties interface{} `json:"properties"` // can't support it for databases yet Description []api.RichText `json:"description"` @@ -59,95 +43,16 @@ type Database struct { Cover *block.Image `json:"cover,omitempty"` } -type Parent struct { - Type string `json:"type,omitempty"` - PageID string `json:"page_id"` +func (p Database) GetObjectType() string { + return ObjectType } -type ListDatabasesResponse struct { - Results []Database `json:"results"` - HasMore bool `json:"has_more"` - NextCursor *string `json:"next_cursor"` -} - -func (ds *DatabaseService) GetDatabase(ctx context.Context, mode pb.RpcObjectImportRequestMode, apiKey string) *converter.Response { - var convereterError = converter.ConvertError{} - databases, err := ds.listDatabases(ctx, apiKey, pageSize) - if err != nil { - convereterError.Add(endpoint, err) - return &converter.Response{Error: convereterError} - } +func (ds *Service) GetDatabase(ctx context.Context, mode pb.RpcObjectImportRequestMode, databases []Database) *converter.Response { + var convereterError converter.ConvertError return ds.mapDatabasesToSnaphots(ctx, mode, databases, convereterError) } -func (ds *DatabaseService) listDatabases(ctx context.Context, apiKey string, pageSize int64) ([]Database, error) { - var ( - hasMore = true - body = &bytes.Buffer{} - resultDatabases = make([]Database, 0) - startCursor int64 - ) - type Option struct { - PageSize int64 `json:"page_size,omitempty"` - StartCursor int64 `json:"start_cursor,omitempty"` - } - err := json.NewEncoder(body).Encode(&Option{PageSize: pageSize, StartCursor: startCursor}) - - if err != nil { - return nil, fmt.Errorf("ListDatabases: %s", err) - } - - req, err := ds.client.PrepareRequest(ctx, apiKey, http.MethodPost, endpoint, body) - - if err != nil { - return nil, fmt.Errorf("ListDatabases: %s", err) - } - - for hasMore { - res, err := ds.client.HttpClient.Do(req) - - if err != nil { - return nil, fmt.Errorf("ListDatabases: %s", err) - } - defer res.Body.Close() - - b, err := ioutil.ReadAll(res.Body) - - if err != nil { - return nil, err - } - var databases ListDatabasesResponse - if res.StatusCode != http.StatusOK { - notionErr := client.TransformHttpCodeToError(b) - if notionErr == nil { - return nil, fmt.Errorf("failed http request, %d code", res.StatusCode) - } - return nil, notionErr - } - - err = json.Unmarshal(b, &databases) - - if err != nil { - return nil, err - } - for _, d := range databases.Results { - if d.Object == objectType { - resultDatabases = append(resultDatabases, d) - } - } - - if !databases.HasMore { - hasMore = false - continue - } - - startCursor += pageSize - - } - return resultDatabases, nil -} - -func (ds *DatabaseService) mapDatabasesToSnaphots(ctx context.Context, mode pb.RpcObjectImportRequestMode, databases []Database, convereterError converter.ConvertError) *converter.Response { +func (ds *Service) mapDatabasesToSnaphots(ctx context.Context, mode pb.RpcObjectImportRequestMode, databases []Database, convereterError converter.ConvertError) *converter.Response { var allSnapshots = make([]*converter.Snapshot, 0) for _, d := range databases { tid, err := threads.ThreadCreateID(thread.AccessControlled, smartblock.SmartBlockTypePage) @@ -173,7 +78,7 @@ func (ds *DatabaseService) mapDatabasesToSnaphots(ctx context.Context, mode pb.R return &converter.Response{Snapshots: allSnapshots, Error: convereterError} } -func (ds *DatabaseService) transformDatabase(d Database) *model.SmartBlockSnapshotBase { +func (ds *Service) transformDatabase(d Database) *model.SmartBlockSnapshotBase { details := make(map[string]*types.Value, 0) details[bundle.RelationKeySource.String()] = pbtypes.String(d.URL) if len(d.Title) > 0{ diff --git a/core/block/import/notion/api/database/database_test.go b/core/block/import/notion/api/database/database_test.go index 0c255e3e6..f0f56b3b9 100644 --- a/core/block/import/notion/api/database/database_test.go +++ b/core/block/import/notion/api/database/database_test.go @@ -1,52 +1,2 @@ package database -import ( - "context" - "net/http" - "net/http/httptest" - "testing" - - "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" - "github.com/anytypeio/go-anytype-middleware/pb" - "github.com/stretchr/testify/assert" -) - - - -func Test_GetDatabaseSuccess(t *testing.T) { - s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(`{"object":"list","results":[{"object":"database","id":"072a11cb-684f-4f2b-9490-79592700c67e","cover":{"type":"external","external":{"url":"https://www.notion.so/images/page-cover/webb1.jpg"}},"icon":{"type":"emoji","emoji":"👜"},"created_time":"2022-10-25T11:44:00.000Z","created_by":{"object":"user","id":"60faafc6-0c5c-4479-a3f7-67d77cd8a56d"},"last_edited_by":{"object":"user","id":"60faafc6-0c5c-4479-a3f7-67d77cd8a56d"},"last_edited_time":"2022-10-31T10:16:00.000Z","title":[{"type":"text","text":{"content":"fsdfsdf","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"fsdfsdf","href":null}],"description":[{"type":"text","text":{"content":"lkjlkjlkjklj","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":true,"code":false,"color":"default"},"plain_text":"lkjlkjlkjklj","href":null},{"type":"text","text":{"content":" lkhlkjl;lk’ ","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":" lkhlkjl;lk’ ","href":null},{"type":"text","text":{"content":"lkjkn ;oj;lj;lk’;l\\\n","link":null},"annotations":{"bold":true,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"lkjkn ;oj;lj;lk’;l\\\n","href":null},{"type":"text","text":{"content":"nb","link":{"url":"/43b4db4f23b846f99909c783b033fb7d"}},"annotations":{"bold":true,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"nb","href":"/43b4db4f23b846f99909c783b033fb7d"},{"type":"text","text":{"content":". \n","link":null},"annotations":{"bold":true,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":". \n","href":null},{"type":"equation","equation":{"expression":"m;lm;’,"},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"m;lm;’,","href":null}],"is_inline":true,"properties":{"Select":{"id":"C%5E%7DO","name":"Select","type":"select","select":{"options":[{"id":"f56c757b-eb58-4a15-b528-055a0e3e85b4","name":"dddd","color":"red"}]}},"Text":{"id":"LwEA","name":"Text","type":"relation","relation":{"database_id":"48f51ca6-f1e3-40ee-97a5-953c2e5d8dda","type":"single_property","single_property":{}}},"ssss":{"id":"MeQJ","name":"ssss","type":"last_edited_time","last_edited_time":{}},"Date":{"id":"VwL%5B","name":"Date","type":"date","date":{}},"Status":{"id":"VwSP","name":"Status","type":"status","status":{"options":[{"id":"d553e1cf-a835-4608-9740-01335bc43a33","name":"Not started","color":"default"},{"id":"e4927bd2-4580-4e37-9095-eb0af45923bc","name":"In progress","color":"blue"},{"id":"631ae48b-ccbd-47fc-83a0-64388237cb90","name":"Done","color":"green"}],"groups":[{"id":"95be5bb3-f557-4e5f-bf80-bc0ba078a5ad","name":"To-do","color":"gray","option_ids":["d553e1cf-a835-4608-9740-01335bc43a33"]},{"id":"c3e8b669-177f-4f6a-a58b-998020b47992","name":"In progress","color":"blue","option_ids":["e4927bd2-4580-4e37-9095-eb0af45923bc"]},{"id":"fdbcab62-2699-49b6-9002-eb10a89806ad","name":"Complete","color":"green","option_ids":["631ae48b-ccbd-47fc-83a0-64388237cb90"]}]}},"Number":{"id":"WxBc","name":"Number","type":"number","number":{"format":"ruble"}},"Last edited time":{"id":"XDl%3D","name":"Last edited time","type":"last_edited_time","last_edited_time":{}},"ww":{"id":"Y%3B%3Bz","name":"ww","type":"rich_text","rich_text":{}},"Multi-select":{"id":"%5D%60%3FX","name":"Multi-select","type":"multi_select","multi_select":{"options":[{"id":"EgfK","name":"ddd","color":"default"},{"id":"QO[c","name":"AAA","color":"purple"},{"id":"UsL>","name":"Option","color":"orange"}]}},"ww (1)":{"id":"%60%3C%3DZ","name":"ww (1)","type":"checkbox","checkbox":{}},"Email":{"id":"bQRa","name":"Email","type":"email","email":{}},"Tags":{"id":"gOGx","name":"Tags","type":"multi_select","multi_select":{"options":[{"id":"21e940af-b7a0-4aae-985b-d3bb38a6ebeb","name":"JJJJ","color":"pink"}]}},"Test test":{"id":"nWZg","name":"Test test","type":"people","people":{}},"Checkbox":{"id":"qVHX","name":"Checkbox","type":"checkbox","checkbox":{}},"Status 1":{"id":"tlUB","name":"Status 1","type":"status","status":{"options":[{"id":"bc2cb10d-92da-40d1-b043-d3c5b52c789e","name":"Not started","color":"default"},{"id":"648b1e10-c0ac-4886-84e0-42d501d36e45","name":"In progress","color":"blue"},{"id":"6f1e3ce8-97db-40b5-8538-13269de69b7f","name":"Done","color":"green"}],"groups":[{"id":"cd0c5f4a-de4d-4662-a2ee-1c78fc0385cd","name":"To-do","color":"gray","option_ids":["bc2cb10d-92da-40d1-b043-d3c5b52c789e"]},{"id":"a341ea69-3102-4d56-b74a-fa3f1c47fa85","name":"In progress","color":"blue","option_ids":["648b1e10-c0ac-4886-84e0-42d501d36e45"]},{"id":"061c2c1f-faa2-49be-996e-f52d74a5b86e","name":"Complete","color":"green","option_ids":["6f1e3ce8-97db-40b5-8538-13269de69b7f"]}]}},"Formula":{"id":"%7Do%40%7B","name":"Formula","type":"formula","formula":{"expression":"log2(prop(\"Number\"))"}},"Name":{"id":"title","name":"Name","type":"title","title":{}}},"parent":{"type":"page_id","page_id":"d6917e78-3212-444d-ae46-97499c021f2d"},"url":"https://www.notion.so/072a11cb684f4f2b949079592700c67e","archived":false}],"next_cursor":null,"has_more":false,"type":"page_or_database","page_or_database":{}}`)) - })) - - defer s.Close() - c := client.NewClient() - c.BasePath = s.URL - ds := New() - ds.client = c - - databases := ds.GetDatabase(context.Background(), pb.RpcObjectImportRequest_ALL_OR_NOTHING, "key") - - assert.NotNil(t, databases) - assert.Len(t, databases.Snapshots, 1) - assert.Nil(t, databases.Error) -} - -func Test_GetDatabaseFailedRequest(t *testing.T) { - s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte(`{"object":"error","status":400,"code":"validation_error","message":"path failed validation: path.database_id should be a valid uuid"}`)) - })) - defer s.Close() - - c := client.NewClient() - c.BasePath = s.URL - ds := New() - ds.client = c - - databases := ds.GetDatabase(context.Background(), pb.RpcObjectImportRequest_ALL_OR_NOTHING, "key") - - assert.NotNil(t, databases) - assert.Nil(t, databases.Snapshots) - assert.NotNil(t, databases.Error) - assert.Contains(t, databases.Error.Error().Error(), "path failed validation: path.database_id should be a valid uuid") -} \ No newline at end of file diff --git a/core/block/import/notion/api/page/page.go b/core/block/import/notion/api/page/page.go new file mode 100644 index 000000000..fc0ce15a2 --- /dev/null +++ b/core/block/import/notion/api/page/page.go @@ -0,0 +1,126 @@ +package page + +import ( + "context" + "time" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/block" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/property" + "github.com/anytypeio/go-anytype-middleware/pb" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/threads" + "github.com/anytypeio/go-anytype-middleware/util/pbtypes" + "github.com/gogo/protobuf/types" + "github.com/textileio/go-threads/core/thread" +) + +const ObjectType = "page" + +type Service struct { + propertyService *property.Service +} + +func New(client *client.Client) *Service { + return &Service{ + propertyService: property.New(client), + } +} + +type Page struct { + Object string `json:"object"` + ID string `json:"id"` + CreatedTime time.Time `json:"created_time"` + LastEditedTime time.Time `json:"last_edited_time"` + CreatedBy api.User `json:"created_by,omitempty"` + LastEditedBy api.User `json:"last_edited_by,omitempty"` + Title []api.RichText `json:"title"` + Parent api.Parent `json:"parent"` + URL string `json:"url"` + Properties property.Properties `json:"properties"` + Archived bool `json:"archived"` + Icon *api.Icon `json:"icon,omitempty"` + Cover *block.Image `json:"cover,omitempty"` +} + +func (p Page) GetObjectType() string { + return ObjectType +} + +func (ds *Service) GetPages(ctx context.Context, apiKey string, mode pb.RpcObjectImportRequestMode, pages []Page) *converter.Response { + var convereterError converter.ConvertError + return ds.mapPagesToSnaphots(ctx, apiKey, mode, pages, convereterError) +} + +func (ds *Service) mapPagesToSnaphots(ctx context.Context, apiKey string, mode pb.RpcObjectImportRequestMode, pages []Page, convereterError converter.ConvertError) *converter.Response { + var allSnapshots = make([]*converter.Snapshot, 0) + for _, p := range pages { + tid, err := threads.ThreadCreateID(thread.AccessControlled, smartblock.SmartBlockTypePage) + if err != nil { + convereterError.Add(p.ID, err) + if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + return &converter.Response{Error: convereterError} + } else { + continue + } + } + snapshot := ds.transformPages(apiKey, &p, mode) + + allSnapshots = append(allSnapshots, &converter.Snapshot{ + Id: tid.String(), + FileName: p.URL, + Snapshot: snapshot, + }) + } + if convereterError.IsEmpty() { + return &converter.Response{Snapshots: allSnapshots, Error: nil} + } + return &converter.Response{Snapshots: allSnapshots, Error: convereterError} +} + +func (ds *Service) transformPages(apiKey string, d *Page, mode pb.RpcObjectImportRequestMode) *model.SmartBlockSnapshotBase { + details := make(map[string]*types.Value, 0) + details[bundle.RelationKeySource.String()] = pbtypes.String(d.URL) + if len(d.Title) > 0 { + details[bundle.RelationKeyName.String()] = pbtypes.String(d.Title[0].PlainText) + } + if d.Icon != nil && d.Icon.Emoji != nil { + details[bundle.RelationKeyIconEmoji.String()] = pbtypes.String(*d.Icon.Emoji) + } + details[bundle.RelationKeyIsArchived.String()] = pbtypes.Bool(d.Archived) + + ds.handlePageProperties(apiKey, d.ID, d.Properties, details, mode) + snapshot := &model.SmartBlockSnapshotBase{ + Blocks: []*model.Block{}, + Details: &types.Struct{Fields: details}, + ObjectTypes: []string{bundle.TypeKeyPage.URL()}, + Collections: nil, + } + + return snapshot +} + +func (ds *Service) handlePageProperties(apiKey, pageID string, p property.Properties, d map[string]*types.Value, mode pb.RpcObjectImportRequestMode) *converter.ConvertError { + var ce converter.ConvertError + for k, v := range p { + object, err := ds.propertyService.GetPropertyObject(context.TODO(), pageID, v.GetID(), apiKey, v.GetPropertyType()) + if err != nil { + ce.Add("property: " + v.GetID(), err) + if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + return &ce + } + } + err = ds.propertyService.SetDetailValue(k, v.GetPropertyType(), object, d) + if err != nil && mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + ce.Add("property: " + v.GetID(), err) + if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + return &ce + } + } + } + return nil +} diff --git a/core/block/import/notion/api/property/propertyconfig.go b/core/block/import/notion/api/property/propertyconfig.go new file mode 100644 index 000000000..908cb6404 --- /dev/null +++ b/core/block/import/notion/api/property/propertyconfig.go @@ -0,0 +1,501 @@ +package property + +import ( + "encoding/json" + "fmt" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" +) + +const ( + PropertyConfigTypeTitle PropertyConfigType = "title" + PropertyConfigTypeRichText PropertyConfigType = "rich_text" + PropertyConfigTypeNumber PropertyConfigType = "number" + PropertyConfigTypeSelect PropertyConfigType = "select" + PropertyConfigTypeMultiSelect PropertyConfigType = "multi_select" + PropertyConfigTypeDate PropertyConfigType = "date" + PropertyConfigTypePeople PropertyConfigType = "people" + PropertyConfigTypeFiles PropertyConfigType = "files" + PropertyConfigTypeCheckbox PropertyConfigType = "checkbox" + PropertyConfigTypeURL PropertyConfigType = "url" + PropertyConfigTypeEmail PropertyConfigType = "email" + PropertyConfigTypePhoneNumber PropertyConfigType = "phone_number" + PropertyConfigTypeFormula PropertyConfigType = "formula" + PropertyConfigTypeRelation PropertyConfigType = "relation" + PropertyConfigTypeRollup PropertyConfigType = "rollup" + PropertyConfigCreatedTime PropertyConfigType = "created_time" + PropertyConfigCreatedBy PropertyConfigType = "created_by" + PropertyConfigLastEditedTime PropertyConfigType = "last_edited_time" + PropertyConfigLastEditedBy PropertyConfigType = "last_edited_by" +) + +type PropertyConfigType string + +type PropertyObject interface { + GetPropertyType() PropertyConfigType + GetID() string +} + +type TitlePropertyConfig struct { + ID string `json:"id,omitempty"` + Type PropertyConfigType `json:"type"` + Title interface{} `json:"title"` +} + +func (t *TitlePropertyConfig) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeTitle +} + +func (t *TitlePropertyConfig) GetID() string { + return t.ID +} + +type RichTextPropertyConfig struct { + ID string `json:"id,omitempty"` + Type PropertyConfigType `json:"type"` + RichText interface{} `json:"rich_text"` +} + +func (rt *RichTextPropertyConfig) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeRichText +} + +func (rt *RichTextPropertyConfig) GetID() string { + return rt.ID +} + +type NumberPropertyConfig struct { + ID string `json:"id,omitempty"` + Type PropertyConfigType `json:"type"` + Number NumberFormatType `json:"format"` +} + +func (n *NumberPropertyConfig) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeNumber +} + +func (n *NumberPropertyConfig) GetID() string { + return n.ID +} + +type NumberFormatType string + +const ( + Number NumberFormatType = "number" + NumberWithCommas NumberFormatType = "number_with_commas" + Percent NumberFormatType = "percent" + Dollar NumberFormatType = "dollar" + CanadianDollar NumberFormatType = "canadian_dollar" + Euro NumberFormatType = "euro" + Pound NumberFormatType = "pound" + Ruble NumberFormatType = "ruble" + Rupee NumberFormatType = "rupee" + Won NumberFormatType = "won" + Yuan NumberFormatType = "yuan" + Real NumberFormatType = "real" + Lira NumberFormatType = "lira" + Rupiah NumberFormatType = "rupiah" + Franc NumberFormatType = "franc" + HongKongDollar NumberFormatType = "hong_kong_dollar" + NewZealandDollar NumberFormatType = "new_zealand_dollar" + Krona NumberFormatType = "krona" + NorwegianKrone NumberFormatType = "norwegian_krone" + MexicanPeso NumberFormatType = "mexican_peso" + Rand NumberFormatType = "rand" + NewTaiwanDollar NumberFormatType = "new_taiwan_dollar" + DanishKrone NumberFormatType = "danish_krone" + Zloty NumberFormatType = "zloty" + Baht NumberFormatType = "baht" + Forint NumberFormatType = "forint" + Koruna NumberFormatType = "koruna" + Shekel NumberFormatType = "shekel" + ChileanPeso NumberFormatType = "chilean_peso" + PhilippinePeso NumberFormatType = "philippine_peso" + Dirham NumberFormatType = "dirham" + ColombianPeso NumberFormatType = "colombian_peso" + Riyal NumberFormatType = "riyal" + Ringgit NumberFormatType = "ringgit" + Leu NumberFormatType = "leu" + ArgentinePeso NumberFormatType = "argentine_peso" + Uruguayan_Pso NumberFormatType = "uruguayan_peso" +) + +type SelectPropertyConfig struct { + ID string `json:"id,omitempty"` + Type PropertyConfigType `json:"type"` + Select Select `json:"select"` +} + +func (s *SelectPropertyConfig) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeSelect +} + +func (s *SelectPropertyConfig) GetID() string { + return s.ID +} + +type Select struct { + Options []SelectOption `json:"options"` +} + +type SelectOption struct { + ID string `json:"id,omitempty"` + Name string `json:"name"` + Color api.Color `json:"color"` +} + +type MultiSelectPropertyConfig struct { + ID string `json:"id,omitempty"` + Type PropertyConfigType `json:"type"` + MultiSelect Select `json:"multi_select"` +} + +func (m *MultiSelectPropertyConfig) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeMultiSelect +} + +func (m *MultiSelectPropertyConfig) GetID() string { + return m.ID +} + +type DatePropertyConfig struct { + ID string `json:"id,omitempty"` + Type PropertyConfigType `json:"type"` + Date interface{} `json:"date"` +} + +func (d *DatePropertyConfig) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeDate +} + +func (d *DatePropertyConfig) GetID() string { + return d.ID +} + +type PeoplePropertyConfig struct { + ID string `json:"id,omitempty"` + Type PropertyConfigType `json:"type"` + People interface{} `json:"people"` +} + +func (p *PeoplePropertyConfig) GetPropertyType() PropertyConfigType { + return PropertyConfigTypePeople +} + +func (p *PeoplePropertyConfig) GetID() string { + return p.ID +} + +type FilesPropertyConfig struct { + ID string `json:"id,omitempty"` + Type PropertyConfigType `json:"type"` + Files interface{} `json:"files"` +} + +func (f *FilesPropertyConfig) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeFiles +} + +func (f *FilesPropertyConfig) GetID() string { + return f.ID +} + +type CheckboxPropertyConfig struct { + ID string `json:"id,omitempty"` + Type PropertyConfigType `json:"type"` + Checkbox interface{} `json:"checkbox"` +} + +func (*CheckboxPropertyConfig) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeCheckbox +} + +func (c *CheckboxPropertyConfig) GetID() string { + return c.ID +} + +type URLPropertyConfig struct { + ID string `json:"id,omitempty"` + Type PropertyConfigType `json:"type"` + URL interface{} `json:"url"` +} + +func (u *URLPropertyConfig) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeURL +} + +func (u *URLPropertyConfig) GetID() string { + return u.ID +} + +type EmailPropertyConfig struct { + ID string `json:"id,omitempty"` + Type PropertyConfigType `json:"type"` + Email interface{} `json:"email"` +} + +func (e *EmailPropertyConfig) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeEmail +} + +func (e *EmailPropertyConfig) GetID() string { + return e.ID +} + +type PhoneNumberPropertyConfig struct { + ID string `json:"id,omitempty"` + Type PropertyConfigType `json:"type"` + PhoneNumber interface{} `json:"phone_number"` +} + +func (p *PhoneNumberPropertyConfig) GetPropertyType() PropertyConfigType { + return PropertyConfigTypePhoneNumber +} + +func (p *PhoneNumberPropertyConfig) GetID() string { + return p.ID +} + +type FormulaPropertyConfig struct { + ID string `json:"id,omitempty"` + Type PropertyConfigType `json:"type"` + Formula FormulaConfig `json:"formula"` +} + +func (f *FormulaPropertyConfig) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeFormula +} + +func (f *FormulaPropertyConfig) GetID() string { + return f.ID +} + +type FormulaConfig struct { + Expression string `json:"expression"` +} + +type RelationPropertyConfig struct { + ID string `json:"id,omitempty"` + Type PropertyConfigType `json:"type"` + Relation RelationConfig `json:"relation"` +} + +func (r *RelationPropertyConfig) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeRelation +} + +func (r *RelationPropertyConfig) GetID() string { + return r.ID +} + +type RelationType string + +const ( + SingleRelation RelationType = "single_property" + DualRelation RelationType = "dual_property" +) + +type RelationConfig struct { + DatabaseID string `json:"database_id"` + Type RelationType `json:"type"` + SingleProperty interface{} `json:"single_property,omitempty"` + DualProperty DualProperty `json:"dual_property,omitempty"` +} + +type DualProperty struct { + SyncedPropertyID string `json:"synced_property_id,omitempty"` + SyncedPropertyName string `json:"synced_property_name,omitempty"` +} + +type RollupPropertyConfig struct { + ID string `json:"id,omitempty"` + Type PropertyConfigType `json:"type"` + Rollup RollupConfig `json:"rollup"` +} + +func (r *RollupPropertyConfig) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeRollup +} + +func (r *RollupPropertyConfig) GetID() string { + return r.ID +} + +type FunctionType string + +const ( + Count FunctionType = "count" + CountValues FunctionType = "count_values" + Empty FunctionType = "empty" + NotEmpty FunctionType = "not_empty" + Unique FunctionType = "unique" + ShowUnique FunctionType = "show_unique" + PercentEmpty FunctionType = "percent_empty" + PercentNotEmpty FunctionType = "percent_not_empty" + Sum FunctionType = "sum" + Average FunctionType = "average" + Median FunctionType = "median" + Min FunctionType = "min" + Max FunctionType = "max" + RangeFunction FunctionType = "rangeFunction" + EarliestDate FunctionType = "earliest_date" + LatestDate FunctionType = "latest_date" + DateRange FunctionType = "date_range" + Checked FunctionType = "checked" + Unchecked FunctionType = "unchecked" + PercentChecked FunctionType = "percent_checked" + PercentUnchecked FunctionType = "percent_unchecked" + CountPerGroup FunctionType = "count_per_group" + PercentPerGroup FunctionType = "percent_per_group" + ShowOriginal FunctionType = "show_original" +) + +type RollupConfig struct { + RelationPropertyName string `json:"relation_property_name"` + RelationPropertyID string `json:"relation_property_id"` + RollupPropertyName string `json:"rollup_property_name"` + RollupPropertyID string `json:"rollup_property_id"` + Function FunctionType `json:"function"` +} + +type CreatedTimePropertyConfig struct { + ID string `json:"id,omitempty"` + Type PropertyConfigType `json:"type"` + CreatedTime interface{} `json:"created_time"` +} + +func (*CreatedTimePropertyConfig) GetPropertyType() PropertyConfigType { + return PropertyConfigCreatedTime +} + +func (c *CreatedTimePropertyConfig) GetID() string { + return c.ID +} + +type CreatedByPropertyConfig struct { + ID string `json:"id"` + Type PropertyConfigType `json:"type"` + CreatedBy interface{} `json:"created_by"` +} + +func (*CreatedByPropertyConfig) GetPropertyType() PropertyConfigType { + return PropertyConfigCreatedBy +} + +func (c *CreatedByPropertyConfig) GetID() string { + return c.ID +} + +type LastEditedTimePropertyConfig struct { + ID string `json:"id"` + Type PropertyConfigType `json:"type"` + LastEditedTime interface{} `json:"last_edited_time"` +} + +func (*LastEditedTimePropertyConfig) GetPropertyType() PropertyConfigType { + return PropertyConfigLastEditedTime +} + +func (l *LastEditedTimePropertyConfig) GetID() string { + return l.ID +} + +type LastEditedByPropertyConfig struct { + ID string `json:"id"` + Type PropertyConfigType `json:"type"` + LastEditedBy interface{} `json:"last_edited_by"` +} + +func (*LastEditedByPropertyConfig) GetPropertyType() PropertyConfigType { + return PropertyConfigLastEditedBy +} + +func (p LastEditedByPropertyConfig) GetType() PropertyConfigType { + return p.Type +} + +func (p *LastEditedByPropertyConfig) GetID() string { + return p.ID +} + +type Properties map[string]PropertyObject + +func (p *Properties) UnmarshalJSON(data []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(data, &raw); err != nil { + return err + } + props, err := parsePropertyConfigs(raw) + if err != nil { + return err + } + + *p = props + return nil +} + +func parsePropertyConfigs(raw map[string]interface{}) (Properties, error) { + result := make(Properties) + for k, v := range raw { + var p PropertyObject + switch rawProperty := v.(type) { + case map[string]interface{}: + switch PropertyConfigType(rawProperty["type"].(string)) { + case PropertyConfigTypeTitle: + p = &TitlePropertyConfig{} + case PropertyConfigTypeRichText: + p = &RichTextPropertyConfig{} + case PropertyConfigTypeNumber: + p = &NumberPropertyConfig{} + case PropertyConfigTypeSelect: + p = &SelectPropertyConfig{} + case PropertyConfigTypeMultiSelect: + p = &MultiSelectPropertyConfig{} + case PropertyConfigTypeDate: + p = &DatePropertyConfig{} + case PropertyConfigTypePeople: + p = &PeoplePropertyConfig{} + case PropertyConfigTypeFiles: + p = &FilesPropertyConfig{} + case PropertyConfigTypeCheckbox: + p = &CheckboxPropertyConfig{} + case PropertyConfigTypeURL: + p = &URLPropertyConfig{} + case PropertyConfigTypeEmail: + p = &EmailPropertyConfig{} + case PropertyConfigTypePhoneNumber: + p = &PhoneNumberPropertyConfig{} + case PropertyConfigTypeFormula: + p = &FormulaPropertyConfig{} + case PropertyConfigTypeRelation: + p = &RelationPropertyConfig{} + case PropertyConfigTypeRollup: + p = &RollupPropertyConfig{} + case PropertyConfigCreatedTime: + p = &CreatedTimePropertyConfig{} + case PropertyConfigCreatedBy: + p = &CreatedByPropertyConfig{} + case PropertyConfigLastEditedTime: + p = &LastEditedTimePropertyConfig{} + case PropertyConfigLastEditedBy: + p = &LastEditedByPropertyConfig{} + default: + return nil, fmt.Errorf("unsupported property type: %s", rawProperty["type"].(string)) + } + b, err := json.Marshal(rawProperty) + if err != nil { + return nil, err + } + + if err = json.Unmarshal(b, &p); err != nil { + return nil, err + } + + result[k] = p + default: + return nil, fmt.Errorf("unsupported property format %T", v) + } + } + + return result, nil +} diff --git a/core/block/import/notion/api/property/propertyobject.go b/core/block/import/notion/api/property/propertyobject.go new file mode 100644 index 000000000..8bff31c42 --- /dev/null +++ b/core/block/import/notion/api/property/propertyobject.go @@ -0,0 +1,543 @@ +package property + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "time" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" + "github.com/anytypeio/go-anytype-middleware/util/pbtypes" + "github.com/gogo/protobuf/types" +) + +type DetailSetter interface { + SetDetail(key string, details map[string]*types.Value) +} + +const endpoint = "/pages/%s/properties/%s" + +type Title struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Title []api.RichText `json:"title"` +} + +func (t Title) SetDetail(key string, details map[string]*types.Value) { + var title string + for i, rt := range t.Title { + title += rt.PlainText + if i != len(t.Title) { + title += "\n" + } + } + details[key] = pbtypes.String(title) +} + +type TitleResponse struct { + Results []Title `json:"results"` + HasMore bool `json:"has_more"` + NextCursor string `json:"next_cursor"` +} + +type RichText struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + RichText []api.RichText `json:"rich_text"` +} + +func (rt RichText) SetDetail(key string, details map[string]*types.Value) { + var richText string + for i, r := range rt.RichText { + richText += r.PlainText + if i != len(rt.RichText) { + richText += "\n" + } + } + details[key] = pbtypes.String(richText) +} + +type RichTextResponse struct { + Results []RichText `json:"results"` + HasMore bool `json:"has_more"` + NextCursor string `json:"next_cursor"` +} + +type NumberProperty struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Number int64 `json:"number"` +} + +func (np NumberProperty) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.Int64(np.Number) +} + +type SelectProperty struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Select SelectOption `json:"select"` +} + +func (sp SelectProperty) SetDetail(key string, details map[string]*types.Value) { + //TODO +} + +type MultiSelect struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + MultiSelect []SelectOption `json:"multi_select"` +} + +func (ms MultiSelect) SetDetail(key string, details map[string]*types.Value) { + //TODO +} + +type DateProperty struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Date Date `json:"date"` +} + +func (dp DateProperty) SetDetail(key string, details map[string]*types.Value) { + return +} + +type Date struct { + Start string `json:"start"` + End string `json:"end"` + TimeZone string `json:"time_zone"` +} + +type Formula struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Formula FormulaType `json:"formula"` +} + +func (f Formula) SetDetail(key string, details map[string]*types.Value) { + switch t := f.Formula.(type) { + case StringFormula: + details[key] = pbtypes.String(t.String) + case NumberFormula: + details[key] = pbtypes.Int64(t.Number) + case BooleanFormula: + details[key] = pbtypes.Bool(t.Boolean) + default: + return + } +} + +type FormulaType interface { + FormulaType() +} + +type StringFormula struct { + Type string `json:"type"` + String string `json:"string"` +} + +func (StringFormula) FormulaType() {} + +type NumberFormula struct { + Type string `json:"type"` + Number int64 `json:"number"` +} + +func (NumberFormula) FormulaType() {} + +type BooleanFormula struct { + Type string `json:"type"` + Boolean bool `json:"boolean"` +} + +func (BooleanFormula) FormulaType() {} + +type DateFormula struct { + Type string `json:"type"` + Date Date `json:"date"` +} + +func (DateFormula) FormulaType() {} + +type RelationProperty struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Relation Relation `json:"relation"` +} + +func (rp RelationProperty) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.String(rp.Relation.ID) +} + +type Relation struct { + ID string `json:"id"` +} + +type RelationResponse struct { + Results []Relation `json:"results"` + HasMore bool `json:"has_more"` + NextCursor string `json:"next_cursor"` +} + +type Rollup struct { + Object string `json:"object"` +} + +func (r Rollup) SetDetail(key string, details map[string]*types.Value) { + return +} + +type People struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + People api.User `json:"type"` +} + +func (p People) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.String(p.People.Name) +} + +type PeopleResponse struct { + Results []People `json:"results"` + HasMore bool `json:"has_more"` + NextCursor string `json:"next_cursor"` +} + +type File struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + File []api.FileObject `json:"files"` +} + +func (f File) SetDetail(key string, details map[string]*types.Value) { + var fileList = make([]string, len(f.File)) + for i, fo := range f.File { + if fo.External != nil { + fileList[i] = fo.External.URL + } else if fo.File != nil { + fileList[i] = fo.File.URL + } + } + details[key] = pbtypes.StringList(fileList) +} + +type Checkbox struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Checkbox bool `json:"checkbox"` +} + +func (c Checkbox) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.Bool(c.Checkbox) +} + +type Url struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + URL string `json:"url"` +} + +func (u Url) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.String(u.URL) +} + +type Email struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Email string `json:"email"` +} + +func (e Email) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.String(e.Email) +} + +type Phone struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Phone string `json:"phone_number"` +} + +func (p Phone) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.String(p.Phone) +} + +type CreatedTime struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + CreatedTime string `json:"created_time"` +} + +func (ct CreatedTime) SetDetail(key string, details map[string]*types.Value) { + t, _ := time.Parse(time.RFC3339, ct.CreatedTime) + details[key] = pbtypes.Int64(t.Unix()) +} + +type CreatedBy struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + CreatedBy api.User `json:"created_by"` +} + +func (cb CreatedBy) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.String(cb.CreatedBy.Name) +} + +type LastEditedTime struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + LastEditedTime string `json:"last_edited_time"` +} + +func (le LastEditedTime) SetDetail(key string, details map[string]*types.Value) { + t, _ := time.Parse(time.RFC3339, le.LastEditedTime) + details[key] = pbtypes.Int64(t.Unix()) +} + +type LastEditedBy struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + LastEditedBy api.User `json:"last_edited_by"` +} + +type Service struct { + client *client.Client +} + +func (lb LastEditedBy) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.String(lb.LastEditedBy.Name) +} + +func New(client *client.Client) *Service { + return &Service{ + client: client, + } +} + +func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, apiKey string, propertyType PropertyConfigType) ([]interface{}, error) { + var ( + hasMore = true + body = &bytes.Buffer{} + startCursor string + response interface{} + paginatedResponse = make([]interface{}, 0) + ) + + type Request struct { + StartCursor string `json:"start_cursor,omitempty"` + } + + for hasMore { + err := json.NewEncoder(body).Encode(&Request{StartCursor: startCursor}) + + if err != nil { + return nil, fmt.Errorf("ListDatabases: %s", err) + } + + request := fmt.Sprintf(endpoint, pageID, propertyID) + req, err := s.client.PrepareRequest(ctx, apiKey, http.MethodGet, request, body) + + if err != nil { + return nil, fmt.Errorf("ListDatabases: %s", err) + } + res, err := s.client.HttpClient.Do(req) + + if err != nil { + return nil, fmt.Errorf("ListDatabases: %s", err) + } + defer res.Body.Close() + + b, err := ioutil.ReadAll(res.Body) + + if err != nil { + return nil, err + } + + if res.StatusCode != http.StatusOK { + notionErr := client.TransformHttpCodeToError(b) + if notionErr == nil { + return nil, fmt.Errorf("failed http request, %d code", res.StatusCode) + } + return nil, notionErr + } + + switch propertyType { + case PropertyConfigTypeTitle: + response = &TitleResponse{} + case PropertyConfigTypeRichText: + response = &RichTextResponse{} + case PropertyConfigTypeNumber: + response = &NumberProperty{} + case PropertyConfigTypeSelect: + response = &SelectProperty{} + case PropertyConfigTypeMultiSelect: + response = &MultiSelect{} + case PropertyConfigTypeDate: + response = &DateProperty{} + case PropertyConfigTypePeople: + response = &PeopleResponse{} + case PropertyConfigTypeFiles: + response = &File{} + case PropertyConfigTypeCheckbox: + response = &Checkbox{} + case PropertyConfigTypeURL: + response = &Url{} + case PropertyConfigTypeEmail: + response = &Email{} + case PropertyConfigTypePhoneNumber: + response = &Phone{} + case PropertyConfigTypeFormula: + response = &Formula{} + case PropertyConfigTypeRelation: + response = &RelationProperty{} + case PropertyConfigTypeRollup: + response = &Rollup{} + case PropertyConfigCreatedTime: + response = &CreatedTime{} + case PropertyConfigCreatedBy: + response = &CreatedBy{} + case PropertyConfigLastEditedTime: + response = &LastEditedTime{} + case PropertyConfigLastEditedBy: + response = &LastEditedBy{} + default: + return nil, fmt.Errorf("unsupported property type: %s", propertyType) + } + + err = json.Unmarshal(b, &response) + + if err != nil { + return nil, err + } + if propertyType == PropertyConfigTypeTitle { + title := response.(TitleResponse) + if title.HasMore { + for _, t := range title.Results { + paginatedResponse = append(paginatedResponse, t) + } + startCursor = title.NextCursor + continue + } + } + if propertyType == PropertyConfigTypeRichText { + richText := response.(RichTextResponse) + if richText.HasMore { + for _, rt := range richText.Results { + paginatedResponse = append(paginatedResponse, rt) + } + startCursor = richText.NextCursor + continue + } + } + if propertyType == PropertyConfigTypePeople { + people := response.(PeopleResponse) + if people.HasMore { + for _, people := range people.Results { + paginatedResponse = append(paginatedResponse, people) + } + startCursor = people.NextCursor + continue + } + } + if propertyType == PropertyConfigTypeRelation { + relations := response.(RelationResponse) + if relations.HasMore { + for _, relations := range relations.Results { + paginatedResponse = append(paginatedResponse, relations) + } + startCursor = relations.NextCursor + continue + } + } + paginatedResponse = append(paginatedResponse, response) + hasMore = false + } + return paginatedResponse, nil +} + +func (s *Service) SetDetailValue(key string, propertyType PropertyConfigType, property []interface{}, details map[string]*types.Value) error { + switch propertyType { + case PropertyConfigTypeTitle: + for _, v := range property { + title := v.(Title) + title.SetDetail(key, details) + } + case PropertyConfigTypeRichText: + for _, v := range property { + rt := v.(RichText) + rt.SetDetail(key, details) + } + case PropertyConfigTypeNumber: + number := property[0].(NumberProperty) + number.SetDetail(key, details) + case PropertyConfigTypeSelect: + selectProperty := property[0].(SelectProperty) + selectProperty.SetDetail(key, details) + case PropertyConfigTypeMultiSelect: + multiSelect := property[0].(MultiSelect) + multiSelect.SetDetail(key, details) + case PropertyConfigTypeDate: + case PropertyConfigTypePeople: + p := property[0].(People) + p.SetDetail(key, details) + case PropertyConfigTypeFiles: + f := property[0].(File) + f.SetDetail(key, details) + case PropertyConfigTypeCheckbox: + c := property[0].(Checkbox) + c.SetDetail(key, details) + case PropertyConfigTypeURL: + url := property[0].(Url) + url.SetDetail(key, details) + case PropertyConfigTypeEmail: + email := property[0].(Email) + email.SetDetail(key, details) + case PropertyConfigTypePhoneNumber: + phone := property[0].(Phone) + phone.SetDetail(key, details) + case PropertyConfigTypeFormula: + formula := property[0].(Formula) + formula.SetDetail(key, details) + case PropertyConfigTypeRelation: + relation := property[0].(RelationProperty) + relation.SetDetail(key, details) + case PropertyConfigTypeRollup: + case PropertyConfigCreatedTime: + ct := property[0].(CreatedTime) + ct.SetDetail(key, details) + case PropertyConfigCreatedBy: + cb := property[0].(CreatedBy) + cb.SetDetail(key, details) + case PropertyConfigLastEditedTime: + lt := property[0].(LastEditedTime) + lt.SetDetail(key, details) + case PropertyConfigLastEditedBy: + lb := property[0].(LastEditedBy) + lb.SetDetail(key, details) + default: + return fmt.Errorf("unsupported property type: %s", propertyType) + } + return nil +} diff --git a/core/block/import/notion/api/search/search.go b/core/block/import/notion/api/search/search.go new file mode 100644 index 000000000..8ce405362 --- /dev/null +++ b/core/block/import/notion/api/search/search.go @@ -0,0 +1,106 @@ +package search + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/database" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/page" +) + +const ( + endpoint = "/search" +) + +type Service struct { + client *client.Client +} + +type SearchResponse struct { + Results []api.Object `json:"results"` + HasMore bool `json:"has_more"` + NextCursor *string `json:"next_cursor"` +} + +func New(client *client.Client) *Service { + return &Service{ + client: client, + } +} + +func (s *Service) Search(ctx context.Context, apiKey string, pageSize int64) ([]database.Database, []page.Page, error) { + var ( + hasMore = true + body = &bytes.Buffer{} + resultDatabases = make([]database.Database, 0) + resultPages = make([]page.Page, 0) + startCursor string + ) + type Option struct { + PageSize int64 `json:"page_size,omitempty"` + StartCursor string `json:"start_cursor,omitempty"` + } + + for hasMore { + err := json.NewEncoder(body).Encode(&Option{PageSize: pageSize, StartCursor: startCursor}) + + if err != nil { + return nil, nil, fmt.Errorf("ListDatabases: %s", err) + } + + req, err := s.client.PrepareRequest(ctx, apiKey, http.MethodPost, endpoint, body) + + if err != nil { + return nil, nil, fmt.Errorf("ListDatabases: %s", err) + } + res, err := s.client.HttpClient.Do(req) + + if err != nil { + return nil, nil, fmt.Errorf("ListDatabases: %s", err) + } + defer res.Body.Close() + + b, err := ioutil.ReadAll(res.Body) + + if err != nil { + return nil, nil, err + } + var objects SearchResponse + if res.StatusCode != http.StatusOK { + notionErr := client.TransformHttpCodeToError(b) + if notionErr == nil { + return nil, nil, fmt.Errorf("failed http request, %d code", res.StatusCode) + } + return nil, nil, notionErr + } + + err = json.Unmarshal(b, &objects) + + if err != nil { + return nil, nil, err + } + for _, o := range objects.Results { + if o.GetObjectType() == database.ObjectType { + resultDatabases = append(resultDatabases, o.(database.Database)) + } + if o.GetObjectType() == page.ObjectType { + resultPages = append(resultPages, o.(page.Page)) + } + } + + if !objects.HasMore { + hasMore = false + continue + } + + startCursor = *objects.NextCursor + + } + return resultDatabases, resultPages, nil +} diff --git a/core/block/import/notion/api/search/search_test.go b/core/block/import/notion/api/search/search_test.go new file mode 100644 index 000000000..f77a47d11 --- /dev/null +++ b/core/block/import/notion/api/search/search_test.go @@ -0,0 +1,62 @@ +package search + +import ( + "context" + "net/http" + "net/http/httptest" + "testing" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/database" + "github.com/anytypeio/go-anytype-middleware/pb" + "github.com/stretchr/testify/assert" +) + +func Test_GetDatabaseSuccess(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"object":"list","results":[{"object":"database","id":"072a11cb-684f-4f2b-9490-79592700c67e","cover":{"type":"external","external":{"url":"https://www.notion.so/images/page-cover/webb1.jpg"}},"icon":{"type":"emoji","emoji":"👜"},"created_time":"2022-10-25T11:44:00.000Z","created_by":{"object":"user","id":"60faafc6-0c5c-4479-a3f7-67d77cd8a56d"},"last_edited_by":{"object":"user","id":"60faafc6-0c5c-4479-a3f7-67d77cd8a56d"},"last_edited_time":"2022-10-31T10:16:00.000Z","title":[{"type":"text","text":{"content":"fsdfsdf","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"fsdfsdf","href":null}],"description":[{"type":"text","text":{"content":"lkjlkjlkjklj","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":true,"code":false,"color":"default"},"plain_text":"lkjlkjlkjklj","href":null},{"type":"text","text":{"content":" lkhlkjl;lk’ ","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":" lkhlkjl;lk’ ","href":null},{"type":"text","text":{"content":"lkjkn ;oj;lj;lk’;l\\\n","link":null},"annotations":{"bold":true,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"lkjkn ;oj;lj;lk’;l\\\n","href":null},{"type":"text","text":{"content":"nb","link":{"url":"/43b4db4f23b846f99909c783b033fb7d"}},"annotations":{"bold":true,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"nb","href":"/43b4db4f23b846f99909c783b033fb7d"},{"type":"text","text":{"content":". \n","link":null},"annotations":{"bold":true,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":". \n","href":null},{"type":"equation","equation":{"expression":"m;lm;’,"},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"m;lm;’,","href":null}],"is_inline":true,"properties":{"Select":{"id":"C%5E%7DO","name":"Select","type":"select","select":{"options":[{"id":"f56c757b-eb58-4a15-b528-055a0e3e85b4","name":"dddd","color":"red"}]}},"Text":{"id":"LwEA","name":"Text","type":"relation","relation":{"database_id":"48f51ca6-f1e3-40ee-97a5-953c2e5d8dda","type":"single_property","single_property":{}}},"ssss":{"id":"MeQJ","name":"ssss","type":"last_edited_time","last_edited_time":{}},"Date":{"id":"VwL%5B","name":"Date","type":"date","date":{}},"Status":{"id":"VwSP","name":"Status","type":"status","status":{"options":[{"id":"d553e1cf-a835-4608-9740-01335bc43a33","name":"Not started","color":"default"},{"id":"e4927bd2-4580-4e37-9095-eb0af45923bc","name":"In progress","color":"blue"},{"id":"631ae48b-ccbd-47fc-83a0-64388237cb90","name":"Done","color":"green"}],"groups":[{"id":"95be5bb3-f557-4e5f-bf80-bc0ba078a5ad","name":"To-do","color":"gray","option_ids":["d553e1cf-a835-4608-9740-01335bc43a33"]},{"id":"c3e8b669-177f-4f6a-a58b-998020b47992","name":"In progress","color":"blue","option_ids":["e4927bd2-4580-4e37-9095-eb0af45923bc"]},{"id":"fdbcab62-2699-49b6-9002-eb10a89806ad","name":"Complete","color":"green","option_ids":["631ae48b-ccbd-47fc-83a0-64388237cb90"]}]}},"Number":{"id":"WxBc","name":"Number","type":"number","number":{"format":"ruble"}},"Last edited time":{"id":"XDl%3D","name":"Last edited time","type":"last_edited_time","last_edited_time":{}},"ww":{"id":"Y%3B%3Bz","name":"ww","type":"rich_text","rich_text":{}},"Multi-select":{"id":"%5D%60%3FX","name":"Multi-select","type":"multi_select","multi_select":{"options":[{"id":"EgfK","name":"ddd","color":"default"},{"id":"QO[c","name":"AAA","color":"purple"},{"id":"UsL>","name":"Option","color":"orange"}]}},"ww (1)":{"id":"%60%3C%3DZ","name":"ww (1)","type":"checkbox","checkbox":{}},"Email":{"id":"bQRa","name":"Email","type":"email","email":{}},"Tags":{"id":"gOGx","name":"Tags","type":"multi_select","multi_select":{"options":[{"id":"21e940af-b7a0-4aae-985b-d3bb38a6ebeb","name":"JJJJ","color":"pink"}]}},"Test test":{"id":"nWZg","name":"Test test","type":"people","people":{}},"Checkbox":{"id":"qVHX","name":"Checkbox","type":"checkbox","checkbox":{}},"Status 1":{"id":"tlUB","name":"Status 1","type":"status","status":{"options":[{"id":"bc2cb10d-92da-40d1-b043-d3c5b52c789e","name":"Not started","color":"default"},{"id":"648b1e10-c0ac-4886-84e0-42d501d36e45","name":"In progress","color":"blue"},{"id":"6f1e3ce8-97db-40b5-8538-13269de69b7f","name":"Done","color":"green"}],"groups":[{"id":"cd0c5f4a-de4d-4662-a2ee-1c78fc0385cd","name":"To-do","color":"gray","option_ids":["bc2cb10d-92da-40d1-b043-d3c5b52c789e"]},{"id":"a341ea69-3102-4d56-b74a-fa3f1c47fa85","name":"In progress","color":"blue","option_ids":["648b1e10-c0ac-4886-84e0-42d501d36e45"]},{"id":"061c2c1f-faa2-49be-996e-f52d74a5b86e","name":"Complete","color":"green","option_ids":["6f1e3ce8-97db-40b5-8538-13269de69b7f"]}]}},"Formula":{"id":"%7Do%40%7B","name":"Formula","type":"formula","formula":{"expression":"log2(prop(\"Number\"))"}},"Name":{"id":"title","name":"Name","type":"title","title":{}}},"parent":{"type":"page_id","page_id":"d6917e78-3212-444d-ae46-97499c021f2d"},"url":"https://www.notion.so/072a11cb684f4f2b949079592700c67e","archived":false}],"next_cursor":null,"has_more":false,"type":"page_or_database","page_or_database":{}}`)) + })) + + defer s.Close() + pageSize := int64(100) + c := client.NewClient() + c.BasePath = s.URL + + searchService := New(c) + db, _, err := searchService.Search(context.TODO(), "key", pageSize) + assert.NotNil(t, db) + assert.Len(t, db, 1) + assert.Nil(t, err) + + ds := database.New() + databases := ds.GetDatabase(context.Background(), pb.RpcObjectImportRequest_ALL_OR_NOTHING, db) + + assert.NotNil(t, databases) + assert.Len(t, databases.Snapshots, 1) + assert.Nil(t, databases.Error) +} + +func Test_GetDatabaseFailedRequest(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(`{"object":"error","status":400,"code":"validation_error","message":"path failed validation: path.database_id should be a valid uuid"}`)) + })) + defer s.Close() + pageSize := int64(100) + c := client.NewClient() + c.BasePath = s.URL + + searchService := New(c) + db, _, err := searchService.Search(context.TODO(), "key", pageSize) + assert.NotNil(t, db) + assert.Len(t, db, 1) + assert.Nil(t, err) + + ds := database.New() + databases := ds.GetDatabase(context.Background(), pb.RpcObjectImportRequest_ALL_OR_NOTHING, db) + + assert.NotNil(t, databases) + assert.Nil(t, databases.Snapshots) + assert.NotNil(t, databases.Error) + assert.Contains(t, databases.Error.Error().Error(), "path failed validation: path.database_id should be a valid uuid") +} \ No newline at end of file diff --git a/core/block/import/notion/converter.go b/core/block/import/notion/converter.go index 00ea06047..46510ab76 100644 --- a/core/block/import/notion/converter.go +++ b/core/block/import/notion/converter.go @@ -5,24 +5,35 @@ import ( "fmt" "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/database" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/page" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/search" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core" ) -const name = "Notion" +const ( + name = "Notion" + pageSize = 100 +) func init() { converter.RegisterFunc(New) } type Notion struct { - database *database.DatabaseService + search *search.Service + databaseService *database.Service + pageService *page.Service } func New(core.Service) converter.Converter { + cl := client.NewClient() return &Notion{ - database: database.New(), + search: search.New(cl), + databaseService: database.New(), + pageService: page.New(cl), } } @@ -35,7 +46,29 @@ func (n *Notion) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Respons Error: ce, } } - return n.database.GetDatabase(context.TODO(), req.Mode, apiKey) + databases, pages, err := n.search.Search(context.TODO(), apiKey, pageSize) + if err != nil { + ce.Add("/search", fmt.Errorf("failed to get pages and databases %s", err)) + return &converter.Response{ + Error: ce, + } + } + databasesSnapshots := n.databaseService.GetDatabase(context.TODO(), req.Mode, databases) + if databasesSnapshots.Error != nil && req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + ce.Merge(databasesSnapshots.Error) + return &converter.Response{ + Error: ce, + } + } + + pagesSnapshots := n.pageService.GetPages(context.TODO(), apiKey, req.Mode, pages) + if pagesSnapshots.Error != nil && req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + ce.Merge(pagesSnapshots.Error) + return &converter.Response{ + Error: ce, + } + } + return nil } func (n *Notion) getParams(param *pb.RpcObjectImportRequest) string { diff --git a/core/block/import/objectcreator.go b/core/block/import/objectcreator.go index ff208d8c4..c69d9a5cb 100644 --- a/core/block/import/objectcreator.go +++ b/core/block/import/objectcreator.go @@ -84,6 +84,7 @@ func (oc *ObjectCreator) Create(ctx *session.Context, snapshot *model.SmartBlock newId, details, err := oc.createSmartBlock(sbType, st) + st.SetDetails(snapshot.Details) if err != nil { return nil, fmt.Errorf("crear object '%s'", st.RootId()) } From 21119db134775a47d6c3f022fa67de82541cc174 Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Mon, 7 Nov 2022 13:40:42 +0300 Subject: [PATCH 04/68] GO-470: add page retrieving Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/converter/error.go | 2 +- core/block/import/notion/api/block/blocks.go | 4 +- core/block/import/notion/api/commonobjects.go | 23 +- .../import/notion/api/database/database.go | 4 +- core/block/import/notion/api/page/page.go | 38 +- .../block/import/notion/api/page/page_test.go | 241 ++++++ .../notion/api/property/detailsetter.go | 88 +++ .../import/notion/api/property/models.go | 501 +++++++++++++ .../notion/api/property/propertyconfig.go | 501 ------------- .../notion/api/property/propertyobject.go | 690 ++++++------------ core/block/import/notion/api/search/search.go | 29 +- .../import/notion/api/search/search_test.go | 101 ++- core/object.go | 3 +- 13 files changed, 1230 insertions(+), 995 deletions(-) create mode 100644 core/block/import/notion/api/page/page_test.go create mode 100644 core/block/import/notion/api/property/detailsetter.go create mode 100644 core/block/import/notion/api/property/models.go delete mode 100644 core/block/import/notion/api/property/propertyconfig.go diff --git a/core/block/import/converter/error.go b/core/block/import/converter/error.go index dd07280d9..230d6ddec 100644 --- a/core/block/import/converter/error.go +++ b/core/block/import/converter/error.go @@ -32,7 +32,7 @@ func (ce ConvertError) Error() error { return nil } for name, err := range ce { - errorString.WriteString(fmt.Sprintf(pattern, name, err)) + errorString.WriteString(fmt.Sprintf(pattern, name, err.Error())) } return fmt.Errorf(errorString.String()) } diff --git a/core/block/import/notion/api/block/blocks.go b/core/block/import/notion/api/block/blocks.go index ace67f4a1..ea60377c0 100644 --- a/core/block/import/notion/api/block/blocks.go +++ b/core/block/import/notion/api/block/blocks.go @@ -5,6 +5,6 @@ import "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" type Image struct { Caption []api.RichText `json:"caption,omitempty"` Type api.FileType `json:"type"` - File *api.FileObject `json:"file,omitempty"` - External *api.FileObject `json:"external,omitempty"` + File api.FileProperty `json:"file,omitempty"` + External api.FileProperty `json:"external,omitempty"` } \ No newline at end of file diff --git a/core/block/import/notion/api/commonobjects.go b/core/block/import/notion/api/commonobjects.go index 612f00916..af2502711 100644 --- a/core/block/import/notion/api/commonobjects.go +++ b/core/block/import/notion/api/commonobjects.go @@ -2,6 +2,7 @@ package api import ( "bytes" + "encoding/json" "time" ) @@ -15,12 +16,11 @@ const ( type RichText struct { Type richTextType `json:"type,omitempty"` - Text *TextObject `json:"text,omitempty"` + Text *TextObject `json:"text,omitempty"` Annotations *Annotations `json:"annotations,omitempty"` PlainText string `json:"plain_text,omitempty"` Href string `json:"href,omitempty"` } - type TextObject struct { Content string `json:"content"` Link *Link `json:"link,omitempty"` @@ -64,8 +64,8 @@ const ( type FileObject struct { Name string `json:"name"` Type FileType `json:"type"` - File *FileProperty `json:"file,omitempty"` - External *FileProperty `json:"external,omitempty"` + File FileProperty `json:"file,omitempty"` + External FileProperty `json:"external,omitempty"` } type FileProperty struct { @@ -73,6 +73,20 @@ type FileProperty struct { ExpiryTime *time.Time `json:"expiry_time,omitempty"` } +func (o *FileProperty) UnmarshalJSON(data []byte) error { + fp := make(map[string]interface{},0) + if err := json.Unmarshal(data, &fp); err != nil { + return err + } + if url, ok := fp["url"].(string); ok { + o.URL = url + } + if t, ok := fp["expiry_time"].(*time.Time); ok { + o.ExpiryTime = t + } + return nil +} + type Icon struct { Type FileType `json:"type"` Emoji *string `json:"emoji,omitempty"` @@ -99,6 +113,7 @@ type Person struct { type Parent struct { Type string `json:"type,omitempty"` PageID string `json:"page_id"` + DatabaseID string `json:"database_id"` } type Object interface { diff --git a/core/block/import/notion/api/database/database.go b/core/block/import/notion/api/database/database.go index 5d0182797..f8668e5f5 100644 --- a/core/block/import/notion/api/database/database.go +++ b/core/block/import/notion/api/database/database.go @@ -43,12 +43,12 @@ type Database struct { Cover *block.Image `json:"cover,omitempty"` } -func (p Database) GetObjectType() string { +func (p *Database) GetObjectType() string { return ObjectType } func (ds *Service) GetDatabase(ctx context.Context, mode pb.RpcObjectImportRequestMode, databases []Database) *converter.Response { - var convereterError converter.ConvertError + convereterError := converter.ConvertError{} return ds.mapDatabasesToSnaphots(ctx, mode, databases, convereterError) } diff --git a/core/block/import/notion/api/page/page.go b/core/block/import/notion/api/page/page.go index fc0ce15a2..798841575 100644 --- a/core/block/import/notion/api/page/page.go +++ b/core/block/import/notion/api/page/page.go @@ -2,7 +2,6 @@ package page import ( "context" - "time" "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" @@ -23,36 +22,38 @@ const ObjectType = "page" type Service struct { propertyService *property.Service + detailSetter *property.DetailSetter } func New(client *client.Client) *Service { return &Service{ propertyService: property.New(client), + detailSetter: property.NewDetailSetter(), } } type Page struct { Object string `json:"object"` ID string `json:"id"` - CreatedTime time.Time `json:"created_time"` - LastEditedTime time.Time `json:"last_edited_time"` + CreatedTime string `json:"created_time"` + LastEditedTime string `json:"last_edited_time"` CreatedBy api.User `json:"created_by,omitempty"` LastEditedBy api.User `json:"last_edited_by,omitempty"` Title []api.RichText `json:"title"` Parent api.Parent `json:"parent"` - URL string `json:"url"` Properties property.Properties `json:"properties"` Archived bool `json:"archived"` Icon *api.Icon `json:"icon,omitempty"` Cover *block.Image `json:"cover,omitempty"` + URL string `json:"url,omitempty"` } -func (p Page) GetObjectType() string { +func (p *Page) GetObjectType() string { return ObjectType } func (ds *Service) GetPages(ctx context.Context, apiKey string, mode pb.RpcObjectImportRequestMode, pages []Page) *converter.Response { - var convereterError converter.ConvertError + convereterError := converter.ConvertError{} return ds.mapPagesToSnaphots(ctx, apiKey, mode, pages, convereterError) } @@ -68,8 +69,16 @@ func (ds *Service) mapPagesToSnaphots(ctx context.Context, apiKey string, mode p continue } } - snapshot := ds.transformPages(apiKey, &p, mode) - + snapshot, ce := ds.transformPages(apiKey, p, mode) + if ce != nil { + convereterError.Merge(*ce) + if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + return &converter.Response{Error: convereterError} + } else { + continue + } + } + allSnapshots = append(allSnapshots, &converter.Snapshot{ Id: tid.String(), FileName: p.URL, @@ -82,7 +91,7 @@ func (ds *Service) mapPagesToSnaphots(ctx context.Context, apiKey string, mode p return &converter.Response{Snapshots: allSnapshots, Error: convereterError} } -func (ds *Service) transformPages(apiKey string, d *Page, mode pb.RpcObjectImportRequestMode) *model.SmartBlockSnapshotBase { +func (ds *Service) transformPages(apiKey string, d Page, mode pb.RpcObjectImportRequestMode) (*model.SmartBlockSnapshotBase, *converter.ConvertError) { details := make(map[string]*types.Value, 0) details[bundle.RelationKeySource.String()] = pbtypes.String(d.URL) if len(d.Title) > 0 { @@ -93,7 +102,10 @@ func (ds *Service) transformPages(apiKey string, d *Page, mode pb.RpcObjectImpor } details[bundle.RelationKeyIsArchived.String()] = pbtypes.Bool(d.Archived) - ds.handlePageProperties(apiKey, d.ID, d.Properties, details, mode) + ce := ds.handlePageProperties(apiKey, d.ID, d.Properties, details, mode) + if ce != nil { + return nil, ce + } snapshot := &model.SmartBlockSnapshotBase{ Blocks: []*model.Block{}, Details: &types.Struct{Fields: details}, @@ -101,11 +113,11 @@ func (ds *Service) transformPages(apiKey string, d *Page, mode pb.RpcObjectImpor Collections: nil, } - return snapshot + return snapshot, nil } func (ds *Service) handlePageProperties(apiKey, pageID string, p property.Properties, d map[string]*types.Value, mode pb.RpcObjectImportRequestMode) *converter.ConvertError { - var ce converter.ConvertError + ce := converter.ConvertError{} for k, v := range p { object, err := ds.propertyService.GetPropertyObject(context.TODO(), pageID, v.GetID(), apiKey, v.GetPropertyType()) if err != nil { @@ -114,7 +126,7 @@ func (ds *Service) handlePageProperties(apiKey, pageID string, p property.Proper return &ce } } - err = ds.propertyService.SetDetailValue(k, v.GetPropertyType(), object, d) + err = ds.detailSetter.SetDetailValue(k, v.GetPropertyType(), object, d) if err != nil && mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { ce.Add("property: " + v.GetID(), err) if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { diff --git a/core/block/import/notion/api/page/page_test.go b/core/block/import/notion/api/page/page_test.go new file mode 100644 index 000000000..e4fff866e --- /dev/null +++ b/core/block/import/notion/api/page/page_test.go @@ -0,0 +1,241 @@ +package page + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/property" + "github.com/anytypeio/go-anytype-middleware/pb" + "github.com/gogo/protobuf/types" + "github.com/stretchr/testify/assert" +) + +func Test_handlePagePropertiesSelect(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"object":"property_item","type":"select","id":"C%5E%7DO","select":{"id":"f56c757b-eb58-4a15-b528-055a0e3e85b4","name":"dddd","color":"red"}}`)) + })) + + c := client.NewClient() + c.BasePath = s.URL + ps := New(c) + + details := make(map[string]*types.Value, 0) + + p := property.SelectProperty{ID:"id", Type: string(property.PropertyConfigTypeSelect)} + pr := property.Properties{"Select": &p} + ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + + assert.Nil(t, ce) + assert.NotEmpty(t, details["Select"]) +} + +func Test_handlePagePropertiesLastEditedTime(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"object":"property_item","type":"last_edited_time","id":"MeQJ","last_edited_time":"2022-11-04T13:02:00.000Z"}`)) + })) + + c := client.NewClient() + c.BasePath = s.URL + ps := New(c) + + details := make(map[string]*types.Value, 0) + + p := property.LastEditedTime{ID: "id", Type: string(property.PropertyConfigLastEditedTime)} + pr := property.Properties{"LastEditedTime": &p} + ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + + assert.Nil(t, ce) + assert.NotEmpty(t, details["LastEditedTime"]) +} + +func Test_handlePagePropertiesRichText(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"object":"list","results":[{"object":"property_item","type":"rich_text","id":"RPBv","rich_text":{"type":"text","text":{"content":"sdfsdfsdfsdfsdfsdf","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"sdfsdfsdfsdfsdfsdf","href":null}}],"next_cursor":null,"has_more":false,"type":"property_item","property_item":{"id":"RPBv","next_url":null,"type":"rich_text","rich_text":{}}}`)) + })) + + c := client.NewClient() + c.BasePath = s.URL + ps := New(c) + + details := make(map[string]*types.Value, 0) + + p := property.RichText{ID: "id", Type: string(property.PropertyConfigLastEditedTime)} + pr := property.Properties{"RichText": &p} + ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + + assert.Nil(t, ce) + assert.NotEmpty(t, details["RichText"]) +} + +func Test_handlePagePropertiesStatus(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"object":"property_item","type":"status","id":"VwSP","status":{"id":"e4927bd2-4580-4e37-9095-eb0af45923bc","name":"In progress","color":"blue"}}`)) + })) + + c := client.NewClient() + c.BasePath = s.URL + ps := New(c) + + details := make(map[string]*types.Value, 0) + + p := property.StatusProperty{ID: "id", Type: property.PropertyConfigStatus} + pr := property.Properties{"Status": &p} + ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + + assert.Nil(t, ce) + assert.NotEmpty(t, details["Status"]) +} + +func Test_handlePagePropertiesNumber(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"object":"property_item","type":"number","id":"WxBc","number":3434}`)) + })) + + c := client.NewClient() + c.BasePath = s.URL + ps := New(c) + + details := make(map[string]*types.Value, 0) + + p := property.NumberProperty{ID: "id", Type: string(property.PropertyConfigTypeNumber)} + pr := property.Properties{"Number": &p} + ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + + assert.Nil(t, ce) + assert.NotEmpty(t, details["Number"]) +} + +func Test_handlePagePropertiesMultiSelect(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"object":"property_item","type":"multi_select","id":"%5D%60%3FX","multi_select":[{"id":"EgfK","name":"ddd","color":"default"},{"id":"QO[c","name":"AAA","color":"purple"},{"id":"UsL>","name":"Option","color":"orange"}]}`)) + })) + + c := client.NewClient() + c.BasePath = s.URL + ps := New(c) + + details := make(map[string]*types.Value, 0) + + p := property.NumberProperty{ID: "id", Type: string(property.PropertyConfigTypeMultiSelect)} + pr := property.Properties{"MultiSelect": &p} + ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + + assert.Nil(t, ce) + assert.NotEmpty(t, details["MultiSelect"]) +} + +func Test_handlePagePropertiesCheckbox(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"object":"property_item","type":"checkbox","id":"%60%3C%3DZ","checkbox":true}`)) + })) + + c := client.NewClient() + c.BasePath = s.URL + ps := New(c) + + details := make(map[string]*types.Value, 0) + + p := property.Checkbox{ID: "id", Type: string(property.PropertyConfigTypeCheckbox)} + pr := property.Properties{"Checkbox": &p} + ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + + assert.Nil(t, ce) + assert.NotEmpty(t, details["Checkbox"]) +} + +func Test_handlePagePropertiesEmail(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"object":"property_item","type":"email","id":"bQRa","email":null}`)) + })) + + c := client.NewClient() + c.BasePath = s.URL + ps := New(c) + + details := make(map[string]*types.Value, 0) + + p := property.Email{ID: "id", Type: string(property.PropertyConfigTypeEmail)} + pr := property.Properties{"Email": &p} + ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + + assert.Nil(t, ce) + assert.NotEmpty(t, details["Email"]) +} + +func Test_handlePagePropertiesRelation(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"object":"list","results":[{"object":"property_item","type":"relation","id":"cm~~","relation":{"id":"18e660df-d7f4-4d4b-b30c-eeb88ffee645"}}],"next_cursor":null,"has_more":false,"type":"property_item","property_item":{"id":"cm~~","next_url":null,"type":"relation","relation":{}}}`)) + })) + + c := client.NewClient() + c.BasePath = s.URL + ps := New(c) + + details := make(map[string]*types.Value, 0) + + p := property.RelationProperty{ID: "id", Type: string(property.PropertyConfigTypeRelation)} + pr := property.Properties{"Relation": &p} + ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + + assert.Nil(t, ce) + assert.NotEmpty(t, details["Relation"]) +} + +func Test_handlePagePropertiesPeople(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"object":"list","results":[{"object":"property_item","type":"people","id":"nWZg","people":{"object":"user","id":"60faafc6-0c5c-4479-a3f7-67d77cd8a56d"}}],"next_cursor":null,"has_more":false,"type":"property_item","property_item":{"id":"nWZg","next_url":null,"type":"people","people":{}}}`)) + })) + + c := client.NewClient() + c.BasePath = s.URL + ps := New(c) + + details := make(map[string]*types.Value, 0) + + p := property.People{ID: "id", Type: string(property.PropertyConfigTypePeople)} + pr := property.Properties{"People": &p} + ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + + assert.Nil(t, ce) + assert.NotEmpty(t, details["People"]) +} + +func Test_handlePagePropertiesFormula(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"object":"property_item","type":"formula","id":"%7Do%40%7B","formula":{"type":"number","number":11.745674324002}}`)) + })) + + c := client.NewClient() + c.BasePath = s.URL + ps := New(c) + + details := make(map[string]*types.Value, 0) + + p := property.Formula{ID: "id", Type: string(property.PropertyConfigTypeFormula)} + pr := property.Properties{"Formula": &p} + ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + + assert.Nil(t, ce) + assert.NotEmpty(t, details["Formula"]) +} + +func Test_handlePagePropertiesTitle(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"object":"list","results":[{"object":"property_item","type":"title","id":"title","title":{"type":"text","text":{"content":"Daily Entry","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"Daily Entry","href":null}}],"next_cursor":null,"has_more":false,"type":"property_item","property_item":{"id":"title","next_url":null,"type":"title","title":{}}}`)) + })) + + c := client.NewClient() + c.BasePath = s.URL + ps := New(c) + + details := make(map[string]*types.Value, 0) + + p := property.Title{ID: "id", Type: string(property.PropertyConfigTypeTitle)} + pr := property.Properties{"Title": &p} + ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + + assert.Nil(t, ce) + assert.NotEmpty(t, details["Title"]) +} \ No newline at end of file diff --git a/core/block/import/notion/api/property/detailsetter.go b/core/block/import/notion/api/property/detailsetter.go new file mode 100644 index 000000000..7daec22f4 --- /dev/null +++ b/core/block/import/notion/api/property/detailsetter.go @@ -0,0 +1,88 @@ +package property + +import ( + "fmt" + + "github.com/gogo/protobuf/types" +) + +type DetailSetter struct{} + +func NewDetailSetter() *DetailSetter { + return &DetailSetter{} +} + +func (*DetailSetter) SetDetailValue(key string, propertyType PropertyConfigType, property []interface{}, details map[string]*types.Value) error { + if len(property) == 0 { + return nil + } + switch propertyType { + case PropertyConfigTypeTitle: + for _, v := range property { + title := v.(Title) + title.SetDetail(key, details) + } + case PropertyConfigTypeRichText: + for _, v := range property { + rt := v.(RichText) + rt.SetDetail(key, details) + } + case PropertyConfigTypePeople: + for _, v := range property { + p := v.(People) + p.SetDetail(key, details) + } + case PropertyConfigTypeRelation: + for _, v := range property { + r := v.(Relation) + r.SetDetail(key, details) + } + case PropertyConfigTypeNumber: + number := property[0].(NumberProperty) + number.SetDetail(key, details) + case PropertyConfigTypeSelect: + selectProperty := property[0].(SelectProperty) + selectProperty.SetDetail(key, details) + case PropertyConfigTypeMultiSelect: + multiSelect := property[0].(MultiSelect) + multiSelect.SetDetail(key, details) + case PropertyConfigTypeDate: + case PropertyConfigTypeFiles: + f := property[0].(File) + f.SetDetail(key, details) + case PropertyConfigTypeCheckbox: + c := property[0].(Checkbox) + c.SetDetail(key, details) + case PropertyConfigTypeURL: + url := property[0].(Url) + url.SetDetail(key, details) + case PropertyConfigTypeEmail: + email := property[0].(Email) + email.SetDetail(key, details) + case PropertyConfigTypePhoneNumber: + phone := property[0].(Phone) + phone.SetDetail(key, details) + case PropertyConfigTypeFormula: + formula := property[0].(Formula) + formula.SetDetail(key, details) + case PropertyConfigTypeRollup: + case PropertyConfigCreatedTime: + ct := property[0].(CreatedTime) + ct.SetDetail(key, details) + case PropertyConfigCreatedBy: + cb := property[0].(CreatedBy) + cb.SetDetail(key, details) + case PropertyConfigLastEditedTime: + lt := property[0].(LastEditedTime) + lt.SetDetail(key, details) + case PropertyConfigLastEditedBy: + lb := property[0].(LastEditedBy) + lb.SetDetail(key, details) + case PropertyConfigStatus: + lb := property[0].(StatusProperty) + lb.SetDetail(key, details) + default: + return fmt.Errorf("unsupported property type: %s", propertyType) + } + return nil +} \ No newline at end of file diff --git a/core/block/import/notion/api/property/models.go b/core/block/import/notion/api/property/models.go new file mode 100644 index 000000000..ebe46e0ce --- /dev/null +++ b/core/block/import/notion/api/property/models.go @@ -0,0 +1,501 @@ +package property + +import ( + "time" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + "github.com/anytypeio/go-anytype-middleware/util/pbtypes" + "github.com/gogo/protobuf/types" +) + +type PropertyConfigType string + +const ( + PropertyConfigTypeTitle PropertyConfigType = "title" + PropertyConfigTypeRichText PropertyConfigType = "rich_text" + PropertyConfigTypeNumber PropertyConfigType = "number" + PropertyConfigTypeSelect PropertyConfigType = "select" + PropertyConfigTypeMultiSelect PropertyConfigType = "multi_select" + PropertyConfigTypeDate PropertyConfigType = "date" + PropertyConfigTypePeople PropertyConfigType = "people" + PropertyConfigTypeFiles PropertyConfigType = "files" + PropertyConfigTypeCheckbox PropertyConfigType = "checkbox" + PropertyConfigTypeURL PropertyConfigType = "url" + PropertyConfigTypeEmail PropertyConfigType = "email" + PropertyConfigTypePhoneNumber PropertyConfigType = "phone_number" + PropertyConfigTypeFormula PropertyConfigType = "formula" + PropertyConfigTypeRelation PropertyConfigType = "relation" + PropertyConfigTypeRollup PropertyConfigType = "rollup" + PropertyConfigCreatedTime PropertyConfigType = "created_time" + PropertyConfigCreatedBy PropertyConfigType = "created_by" + PropertyConfigLastEditedTime PropertyConfigType = "last_edited_time" + PropertyConfigLastEditedBy PropertyConfigType = "last_edited_by" + PropertyConfigStatus PropertyConfigType = "status" +) + +type Setter interface { + SetDetail(key string, details map[string]*types.Value) +} + +type PropertyObject interface { + GetPropertyType() PropertyConfigType + GetID() string +} + +type Title struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Title api.RichText `json:"title"` +} + +func (t *Title) SetDetail(key string, details map[string]*types.Value) { + var title string + if existingTitle, ok := details[key]; ok { + title = existingTitle.GetStringValue() + } + title += t.Title.PlainText + title += "\n" + details[key] = pbtypes.String(title) +} + +func (t *Title) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeTitle +} + +func (t *Title) GetID() string { + return t.ID +} + +type RichText struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + RichText api.RichText `json:"rich_text"` +} + +func (rt *RichText) SetDetail(key string, details map[string]*types.Value) { + var richText string + if existingText, ok := details[key]; ok { + richText = existingText.GetStringValue() + } + richText += rt.RichText.PlainText + richText += "\n" + details[key] = pbtypes.String(richText) +} + +func (rt *RichText) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeRichText +} + +func (rt *RichText) GetID() string { + return rt.ID +} +type NumberProperty struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Number int64 `json:"number"` +} + +func (np *NumberProperty) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.Int64(np.Number) +} + +func (np *NumberProperty) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeNumber +} + +func (np *NumberProperty) GetID() string { + return np.ID +} + +type SelectProperty struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Select SelectOption `json:"select"` +} + +type SelectOption struct { + ID string `json:"id,omitempty"` + Name string `json:"name"` + Color api.Color `json:"color"` +} + +func (sp *SelectProperty) SetDetail(key string, details map[string]*types.Value) { + //TODO +} + +func (sp *SelectProperty) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeSelect +} + +func (sp *SelectProperty) GetID() string { + return sp.ID +} + +type Select struct { + Options []SelectOption `json:"options"` +} + +type MultiSelect struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + MultiSelect []SelectOption `json:"multi_select"` +} + +func (ms *MultiSelect) SetDetail(key string, details map[string]*types.Value) { + //TODO +} + +func (ms *MultiSelect) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeMultiSelect +} + +func (ms *MultiSelect) GetID() string { + return ms.ID +} + +type DateProperty struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Date Date `json:"date"` +} + +func (dp *DateProperty) SetDetail(key string, details map[string]*types.Value) { + return +} + +func (dp *DateProperty) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeDate +} + +func (dp *DateProperty) GetID() string { + return dp.ID +} + +type Date struct { + Start string `json:"start"` + End string `json:"end"` + TimeZone string `json:"time_zone"` +} + +const ( + NumberFormula string = "number" + StringFormula string = "string" + BooleanFormula string = "boolean" + DateFormula string = "date" +) + +type Formula struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Formula map[string]interface{} `json:"formula"` +} + +func (f *Formula) SetDetail(key string, details map[string]*types.Value) { + switch f.Formula["type"].(string) { + case StringFormula: + details[key] = pbtypes.String(f.Formula["string"].(string)) + case NumberFormula: + details[key] = pbtypes.Float64(f.Formula["number"].(float64)) + case BooleanFormula: + details[key] = pbtypes.Bool(f.Formula["boolean"].(bool)) + default: + return + } +} + +func (f *Formula) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeFormula +} + +func (f *Formula) GetID() string { + return f.ID +} + +type RelationProperty struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Relation []Relation `json:"relation"` + HasMore bool `json:"has_more"` +} + +type Relation struct { + ID string `json:"id"` +} + +func (r *Relation) SetDetail(key string, details map[string]*types.Value) { + var ( + relation string + space string + ) + if existingRelation, ok := details[key]; ok { + relation = existingRelation.GetStringValue() + } + if relation != "" { + space = " " + } + details[key] = pbtypes.String(relation + space + r.ID) +} + +func (rp *RelationProperty) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeRelation +} + +func (rp *RelationProperty) GetID() string { + return rp.ID +} + +//can't support it yet +type Rollup struct { + Object string `json:"object"` +} + +func (r *Rollup) SetDetail(key string, details map[string]*types.Value) {} + +func (r *Rollup) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeRollup +} + +func (r *Rollup) GetID() string { + return "" +} + +type People struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + People api.User `json:"people"` +} + +func (p *People) SetDetail(key string, details map[string]*types.Value) { + var peopleList = make([]string, 0) + if existingPeople, ok := details[key]; ok { + list := existingPeople.GetListValue() + for _, v := range list.Values { + peopleList = append(peopleList, v.GetStringValue()) + } + } + peopleList = append(peopleList, p.People.Name) + details[key] = pbtypes.StringList(peopleList) +} + +func (p *People) GetPropertyType() PropertyConfigType { + return PropertyConfigTypePeople +} + +func (p *People) GetID() string { + return p.ID +} + +type File struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + File []api.FileObject `json:"files"` +} + +func (f *File) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeFiles +} + +func (f *File) GetID() string { + return f.ID +} + +func (f *File) SetDetail(key string, details map[string]*types.Value) { + var fileList = make([]string, len(f.File)) + for i, fo := range f.File { + if fo.External.URL != "" { + fileList[i] = fo.External.URL + } else if fo.File.URL != "" { + fileList[i] = fo.File.URL + } + } + details[key] = pbtypes.StringList(fileList) +} + +type Checkbox struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Checkbox bool `json:"checkbox"` +} + +func (c *Checkbox) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.Bool(c.Checkbox) +} + +func (c *Checkbox) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeFiles +} + +func (c *Checkbox) GetID() string { + return c.ID +} + +type Url struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + URL string `json:"url"` +} + +func (u *Url) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.String(u.URL) +} + +func (u *Url) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeURL +} + +func (u *Url) GetID() string { + return u.ID +} + +type Email struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Email string `json:"email"` +} + +func (e *Email) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.String(e.Email) +} + +func (e *Email) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeURL +} + +func (e *Email) GetID() string { + return e.ID +} + +type Phone struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Phone string `json:"phone_number"` +} + +func (p *Phone) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.String(p.Phone) +} + +func (p *Phone) GetPropertyType() PropertyConfigType { + return PropertyConfigTypePhoneNumber +} + +func (p *Phone) GetID() string { + return p.ID +} + +type CreatedTime struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + CreatedTime string `json:"created_time"` +} + +func (ct *CreatedTime) SetDetail(key string, details map[string]*types.Value) { + t, _ := time.Parse(time.RFC3339, ct.CreatedTime) + details[key] = pbtypes.Int64(t.Unix()) +} + +func (ct *CreatedTime) GetPropertyType() PropertyConfigType { + return PropertyConfigCreatedTime +} + +func (ct *CreatedTime) GetID() string { + return ct.ID +} + +type CreatedBy struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + CreatedBy api.User `json:"created_by"` +} + +func (cb *CreatedBy) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.String(cb.CreatedBy.Name) +} + +func (cb *CreatedBy) GetPropertyType() PropertyConfigType { + return PropertyConfigCreatedBy +} + +func (cb *CreatedBy) GetID() string { + return cb.ID +} + +type LastEditedTime struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + LastEditedTime string `json:"last_edited_time"` +} + +func (le *LastEditedTime) SetDetail(key string, details map[string]*types.Value) { + t, _ := time.Parse(time.RFC3339, le.LastEditedTime) + details[key] = pbtypes.Int64(t.Unix()) +} + +func (le *LastEditedTime) GetPropertyType() PropertyConfigType { + return PropertyConfigLastEditedTime +} + +func (le *LastEditedTime) GetID() string { + return le.ID +} + +type LastEditedBy struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + LastEditedBy api.User `json:"last_edited_by"` +} + + +func (lb *LastEditedBy) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.String(lb.LastEditedBy.Name) +} + +func (lb *LastEditedBy) GetPropertyType() PropertyConfigType { + return PropertyConfigLastEditedBy +} + +func (lb *LastEditedBy) GetID() string { + return lb.ID +} + +type StatusProperty struct { + ID string `json:"id"` + Type PropertyConfigType `json:"type"` + Status Status `json:"status"` +} + +type Status struct { + Name string `json:"name,omitempty"` + ID string `json:"id,omitempty"` + Color string `json:"color,omitempty"` +} + +func (sp *StatusProperty) GetPropertyType() PropertyConfigType { + return PropertyConfigStatus +} + +func (sp *StatusProperty) GetID() string { + return sp.ID +} + +func (sp *StatusProperty) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.StringList([]string{sp.Status.Name}) +} \ No newline at end of file diff --git a/core/block/import/notion/api/property/propertyconfig.go b/core/block/import/notion/api/property/propertyconfig.go deleted file mode 100644 index 908cb6404..000000000 --- a/core/block/import/notion/api/property/propertyconfig.go +++ /dev/null @@ -1,501 +0,0 @@ -package property - -import ( - "encoding/json" - "fmt" - - "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" -) - -const ( - PropertyConfigTypeTitle PropertyConfigType = "title" - PropertyConfigTypeRichText PropertyConfigType = "rich_text" - PropertyConfigTypeNumber PropertyConfigType = "number" - PropertyConfigTypeSelect PropertyConfigType = "select" - PropertyConfigTypeMultiSelect PropertyConfigType = "multi_select" - PropertyConfigTypeDate PropertyConfigType = "date" - PropertyConfigTypePeople PropertyConfigType = "people" - PropertyConfigTypeFiles PropertyConfigType = "files" - PropertyConfigTypeCheckbox PropertyConfigType = "checkbox" - PropertyConfigTypeURL PropertyConfigType = "url" - PropertyConfigTypeEmail PropertyConfigType = "email" - PropertyConfigTypePhoneNumber PropertyConfigType = "phone_number" - PropertyConfigTypeFormula PropertyConfigType = "formula" - PropertyConfigTypeRelation PropertyConfigType = "relation" - PropertyConfigTypeRollup PropertyConfigType = "rollup" - PropertyConfigCreatedTime PropertyConfigType = "created_time" - PropertyConfigCreatedBy PropertyConfigType = "created_by" - PropertyConfigLastEditedTime PropertyConfigType = "last_edited_time" - PropertyConfigLastEditedBy PropertyConfigType = "last_edited_by" -) - -type PropertyConfigType string - -type PropertyObject interface { - GetPropertyType() PropertyConfigType - GetID() string -} - -type TitlePropertyConfig struct { - ID string `json:"id,omitempty"` - Type PropertyConfigType `json:"type"` - Title interface{} `json:"title"` -} - -func (t *TitlePropertyConfig) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeTitle -} - -func (t *TitlePropertyConfig) GetID() string { - return t.ID -} - -type RichTextPropertyConfig struct { - ID string `json:"id,omitempty"` - Type PropertyConfigType `json:"type"` - RichText interface{} `json:"rich_text"` -} - -func (rt *RichTextPropertyConfig) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeRichText -} - -func (rt *RichTextPropertyConfig) GetID() string { - return rt.ID -} - -type NumberPropertyConfig struct { - ID string `json:"id,omitempty"` - Type PropertyConfigType `json:"type"` - Number NumberFormatType `json:"format"` -} - -func (n *NumberPropertyConfig) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeNumber -} - -func (n *NumberPropertyConfig) GetID() string { - return n.ID -} - -type NumberFormatType string - -const ( - Number NumberFormatType = "number" - NumberWithCommas NumberFormatType = "number_with_commas" - Percent NumberFormatType = "percent" - Dollar NumberFormatType = "dollar" - CanadianDollar NumberFormatType = "canadian_dollar" - Euro NumberFormatType = "euro" - Pound NumberFormatType = "pound" - Ruble NumberFormatType = "ruble" - Rupee NumberFormatType = "rupee" - Won NumberFormatType = "won" - Yuan NumberFormatType = "yuan" - Real NumberFormatType = "real" - Lira NumberFormatType = "lira" - Rupiah NumberFormatType = "rupiah" - Franc NumberFormatType = "franc" - HongKongDollar NumberFormatType = "hong_kong_dollar" - NewZealandDollar NumberFormatType = "new_zealand_dollar" - Krona NumberFormatType = "krona" - NorwegianKrone NumberFormatType = "norwegian_krone" - MexicanPeso NumberFormatType = "mexican_peso" - Rand NumberFormatType = "rand" - NewTaiwanDollar NumberFormatType = "new_taiwan_dollar" - DanishKrone NumberFormatType = "danish_krone" - Zloty NumberFormatType = "zloty" - Baht NumberFormatType = "baht" - Forint NumberFormatType = "forint" - Koruna NumberFormatType = "koruna" - Shekel NumberFormatType = "shekel" - ChileanPeso NumberFormatType = "chilean_peso" - PhilippinePeso NumberFormatType = "philippine_peso" - Dirham NumberFormatType = "dirham" - ColombianPeso NumberFormatType = "colombian_peso" - Riyal NumberFormatType = "riyal" - Ringgit NumberFormatType = "ringgit" - Leu NumberFormatType = "leu" - ArgentinePeso NumberFormatType = "argentine_peso" - Uruguayan_Pso NumberFormatType = "uruguayan_peso" -) - -type SelectPropertyConfig struct { - ID string `json:"id,omitempty"` - Type PropertyConfigType `json:"type"` - Select Select `json:"select"` -} - -func (s *SelectPropertyConfig) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeSelect -} - -func (s *SelectPropertyConfig) GetID() string { - return s.ID -} - -type Select struct { - Options []SelectOption `json:"options"` -} - -type SelectOption struct { - ID string `json:"id,omitempty"` - Name string `json:"name"` - Color api.Color `json:"color"` -} - -type MultiSelectPropertyConfig struct { - ID string `json:"id,omitempty"` - Type PropertyConfigType `json:"type"` - MultiSelect Select `json:"multi_select"` -} - -func (m *MultiSelectPropertyConfig) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeMultiSelect -} - -func (m *MultiSelectPropertyConfig) GetID() string { - return m.ID -} - -type DatePropertyConfig struct { - ID string `json:"id,omitempty"` - Type PropertyConfigType `json:"type"` - Date interface{} `json:"date"` -} - -func (d *DatePropertyConfig) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeDate -} - -func (d *DatePropertyConfig) GetID() string { - return d.ID -} - -type PeoplePropertyConfig struct { - ID string `json:"id,omitempty"` - Type PropertyConfigType `json:"type"` - People interface{} `json:"people"` -} - -func (p *PeoplePropertyConfig) GetPropertyType() PropertyConfigType { - return PropertyConfigTypePeople -} - -func (p *PeoplePropertyConfig) GetID() string { - return p.ID -} - -type FilesPropertyConfig struct { - ID string `json:"id,omitempty"` - Type PropertyConfigType `json:"type"` - Files interface{} `json:"files"` -} - -func (f *FilesPropertyConfig) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeFiles -} - -func (f *FilesPropertyConfig) GetID() string { - return f.ID -} - -type CheckboxPropertyConfig struct { - ID string `json:"id,omitempty"` - Type PropertyConfigType `json:"type"` - Checkbox interface{} `json:"checkbox"` -} - -func (*CheckboxPropertyConfig) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeCheckbox -} - -func (c *CheckboxPropertyConfig) GetID() string { - return c.ID -} - -type URLPropertyConfig struct { - ID string `json:"id,omitempty"` - Type PropertyConfigType `json:"type"` - URL interface{} `json:"url"` -} - -func (u *URLPropertyConfig) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeURL -} - -func (u *URLPropertyConfig) GetID() string { - return u.ID -} - -type EmailPropertyConfig struct { - ID string `json:"id,omitempty"` - Type PropertyConfigType `json:"type"` - Email interface{} `json:"email"` -} - -func (e *EmailPropertyConfig) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeEmail -} - -func (e *EmailPropertyConfig) GetID() string { - return e.ID -} - -type PhoneNumberPropertyConfig struct { - ID string `json:"id,omitempty"` - Type PropertyConfigType `json:"type"` - PhoneNumber interface{} `json:"phone_number"` -} - -func (p *PhoneNumberPropertyConfig) GetPropertyType() PropertyConfigType { - return PropertyConfigTypePhoneNumber -} - -func (p *PhoneNumberPropertyConfig) GetID() string { - return p.ID -} - -type FormulaPropertyConfig struct { - ID string `json:"id,omitempty"` - Type PropertyConfigType `json:"type"` - Formula FormulaConfig `json:"formula"` -} - -func (f *FormulaPropertyConfig) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeFormula -} - -func (f *FormulaPropertyConfig) GetID() string { - return f.ID -} - -type FormulaConfig struct { - Expression string `json:"expression"` -} - -type RelationPropertyConfig struct { - ID string `json:"id,omitempty"` - Type PropertyConfigType `json:"type"` - Relation RelationConfig `json:"relation"` -} - -func (r *RelationPropertyConfig) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeRelation -} - -func (r *RelationPropertyConfig) GetID() string { - return r.ID -} - -type RelationType string - -const ( - SingleRelation RelationType = "single_property" - DualRelation RelationType = "dual_property" -) - -type RelationConfig struct { - DatabaseID string `json:"database_id"` - Type RelationType `json:"type"` - SingleProperty interface{} `json:"single_property,omitempty"` - DualProperty DualProperty `json:"dual_property,omitempty"` -} - -type DualProperty struct { - SyncedPropertyID string `json:"synced_property_id,omitempty"` - SyncedPropertyName string `json:"synced_property_name,omitempty"` -} - -type RollupPropertyConfig struct { - ID string `json:"id,omitempty"` - Type PropertyConfigType `json:"type"` - Rollup RollupConfig `json:"rollup"` -} - -func (r *RollupPropertyConfig) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeRollup -} - -func (r *RollupPropertyConfig) GetID() string { - return r.ID -} - -type FunctionType string - -const ( - Count FunctionType = "count" - CountValues FunctionType = "count_values" - Empty FunctionType = "empty" - NotEmpty FunctionType = "not_empty" - Unique FunctionType = "unique" - ShowUnique FunctionType = "show_unique" - PercentEmpty FunctionType = "percent_empty" - PercentNotEmpty FunctionType = "percent_not_empty" - Sum FunctionType = "sum" - Average FunctionType = "average" - Median FunctionType = "median" - Min FunctionType = "min" - Max FunctionType = "max" - RangeFunction FunctionType = "rangeFunction" - EarliestDate FunctionType = "earliest_date" - LatestDate FunctionType = "latest_date" - DateRange FunctionType = "date_range" - Checked FunctionType = "checked" - Unchecked FunctionType = "unchecked" - PercentChecked FunctionType = "percent_checked" - PercentUnchecked FunctionType = "percent_unchecked" - CountPerGroup FunctionType = "count_per_group" - PercentPerGroup FunctionType = "percent_per_group" - ShowOriginal FunctionType = "show_original" -) - -type RollupConfig struct { - RelationPropertyName string `json:"relation_property_name"` - RelationPropertyID string `json:"relation_property_id"` - RollupPropertyName string `json:"rollup_property_name"` - RollupPropertyID string `json:"rollup_property_id"` - Function FunctionType `json:"function"` -} - -type CreatedTimePropertyConfig struct { - ID string `json:"id,omitempty"` - Type PropertyConfigType `json:"type"` - CreatedTime interface{} `json:"created_time"` -} - -func (*CreatedTimePropertyConfig) GetPropertyType() PropertyConfigType { - return PropertyConfigCreatedTime -} - -func (c *CreatedTimePropertyConfig) GetID() string { - return c.ID -} - -type CreatedByPropertyConfig struct { - ID string `json:"id"` - Type PropertyConfigType `json:"type"` - CreatedBy interface{} `json:"created_by"` -} - -func (*CreatedByPropertyConfig) GetPropertyType() PropertyConfigType { - return PropertyConfigCreatedBy -} - -func (c *CreatedByPropertyConfig) GetID() string { - return c.ID -} - -type LastEditedTimePropertyConfig struct { - ID string `json:"id"` - Type PropertyConfigType `json:"type"` - LastEditedTime interface{} `json:"last_edited_time"` -} - -func (*LastEditedTimePropertyConfig) GetPropertyType() PropertyConfigType { - return PropertyConfigLastEditedTime -} - -func (l *LastEditedTimePropertyConfig) GetID() string { - return l.ID -} - -type LastEditedByPropertyConfig struct { - ID string `json:"id"` - Type PropertyConfigType `json:"type"` - LastEditedBy interface{} `json:"last_edited_by"` -} - -func (*LastEditedByPropertyConfig) GetPropertyType() PropertyConfigType { - return PropertyConfigLastEditedBy -} - -func (p LastEditedByPropertyConfig) GetType() PropertyConfigType { - return p.Type -} - -func (p *LastEditedByPropertyConfig) GetID() string { - return p.ID -} - -type Properties map[string]PropertyObject - -func (p *Properties) UnmarshalJSON(data []byte) error { - var raw map[string]interface{} - if err := json.Unmarshal(data, &raw); err != nil { - return err - } - props, err := parsePropertyConfigs(raw) - if err != nil { - return err - } - - *p = props - return nil -} - -func parsePropertyConfigs(raw map[string]interface{}) (Properties, error) { - result := make(Properties) - for k, v := range raw { - var p PropertyObject - switch rawProperty := v.(type) { - case map[string]interface{}: - switch PropertyConfigType(rawProperty["type"].(string)) { - case PropertyConfigTypeTitle: - p = &TitlePropertyConfig{} - case PropertyConfigTypeRichText: - p = &RichTextPropertyConfig{} - case PropertyConfigTypeNumber: - p = &NumberPropertyConfig{} - case PropertyConfigTypeSelect: - p = &SelectPropertyConfig{} - case PropertyConfigTypeMultiSelect: - p = &MultiSelectPropertyConfig{} - case PropertyConfigTypeDate: - p = &DatePropertyConfig{} - case PropertyConfigTypePeople: - p = &PeoplePropertyConfig{} - case PropertyConfigTypeFiles: - p = &FilesPropertyConfig{} - case PropertyConfigTypeCheckbox: - p = &CheckboxPropertyConfig{} - case PropertyConfigTypeURL: - p = &URLPropertyConfig{} - case PropertyConfigTypeEmail: - p = &EmailPropertyConfig{} - case PropertyConfigTypePhoneNumber: - p = &PhoneNumberPropertyConfig{} - case PropertyConfigTypeFormula: - p = &FormulaPropertyConfig{} - case PropertyConfigTypeRelation: - p = &RelationPropertyConfig{} - case PropertyConfigTypeRollup: - p = &RollupPropertyConfig{} - case PropertyConfigCreatedTime: - p = &CreatedTimePropertyConfig{} - case PropertyConfigCreatedBy: - p = &CreatedByPropertyConfig{} - case PropertyConfigLastEditedTime: - p = &LastEditedTimePropertyConfig{} - case PropertyConfigLastEditedBy: - p = &LastEditedByPropertyConfig{} - default: - return nil, fmt.Errorf("unsupported property type: %s", rawProperty["type"].(string)) - } - b, err := json.Marshal(rawProperty) - if err != nil { - return nil, err - } - - if err = json.Unmarshal(b, &p); err != nil { - return nil, err - } - - result[k] = p - default: - return nil, fmt.Errorf("unsupported property format %T", v) - } - } - - return result, nil -} diff --git a/core/block/import/notion/api/property/propertyobject.go b/core/block/import/notion/api/property/propertyobject.go index 8bff31c42..d90126db9 100644 --- a/core/block/import/notion/api/property/propertyobject.go +++ b/core/block/import/notion/api/property/propertyobject.go @@ -7,341 +7,121 @@ import ( "fmt" "io/ioutil" "net/http" - "time" - "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" - "github.com/anytypeio/go-anytype-middleware/util/pbtypes" - "github.com/gogo/protobuf/types" ) -type DetailSetter interface { - SetDetail(key string, details map[string]*types.Value) -} - const endpoint = "/pages/%s/properties/%s" - -type Title struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Title []api.RichText `json:"title"` -} - -func (t Title) SetDetail(key string, details map[string]*types.Value) { - var title string - for i, rt := range t.Title { - title += rt.PlainText - if i != len(t.Title) { - title += "\n" - } - } - details[key] = pbtypes.String(title) -} - -type TitleResponse struct { - Results []Title `json:"results"` - HasMore bool `json:"has_more"` - NextCursor string `json:"next_cursor"` -} - -type RichText struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - RichText []api.RichText `json:"rich_text"` -} - -func (rt RichText) SetDetail(key string, details map[string]*types.Value) { - var richText string - for i, r := range rt.RichText { - richText += r.PlainText - if i != len(rt.RichText) { - richText += "\n" - } - } - details[key] = pbtypes.String(richText) -} - -type RichTextResponse struct { - Results []RichText `json:"results"` - HasMore bool `json:"has_more"` - NextCursor string `json:"next_cursor"` -} - -type NumberProperty struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Number int64 `json:"number"` -} - -func (np NumberProperty) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.Int64(np.Number) -} - -type SelectProperty struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Select SelectOption `json:"select"` -} - -func (sp SelectProperty) SetDetail(key string, details map[string]*types.Value) { - //TODO -} - -type MultiSelect struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - MultiSelect []SelectOption `json:"multi_select"` -} - -func (ms MultiSelect) SetDetail(key string, details map[string]*types.Value) { - //TODO -} - -type DateProperty struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Date Date `json:"date"` -} - -func (dp DateProperty) SetDetail(key string, details map[string]*types.Value) { - return -} - -type Date struct { - Start string `json:"start"` - End string `json:"end"` - TimeZone string `json:"time_zone"` -} - -type Formula struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Formula FormulaType `json:"formula"` -} - -func (f Formula) SetDetail(key string, details map[string]*types.Value) { - switch t := f.Formula.(type) { - case StringFormula: - details[key] = pbtypes.String(t.String) - case NumberFormula: - details[key] = pbtypes.Int64(t.Number) - case BooleanFormula: - details[key] = pbtypes.Bool(t.Boolean) - default: - return - } -} - -type FormulaType interface { - FormulaType() -} - -type StringFormula struct { - Type string `json:"type"` - String string `json:"string"` -} - -func (StringFormula) FormulaType() {} - -type NumberFormula struct { - Type string `json:"type"` - Number int64 `json:"number"` -} - -func (NumberFormula) FormulaType() {} - -type BooleanFormula struct { - Type string `json:"type"` - Boolean bool `json:"boolean"` -} - -func (BooleanFormula) FormulaType() {} - -type DateFormula struct { - Type string `json:"type"` - Date Date `json:"date"` -} - -func (DateFormula) FormulaType() {} - -type RelationProperty struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Relation Relation `json:"relation"` -} - -func (rp RelationProperty) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.String(rp.Relation.ID) -} - -type Relation struct { - ID string `json:"id"` -} - -type RelationResponse struct { - Results []Relation `json:"results"` - HasMore bool `json:"has_more"` - NextCursor string `json:"next_cursor"` -} - -type Rollup struct { - Object string `json:"object"` -} - -func (r Rollup) SetDetail(key string, details map[string]*types.Value) { - return -} - -type People struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - People api.User `json:"type"` -} - -func (p People) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.String(p.People.Name) -} - -type PeopleResponse struct { - Results []People `json:"results"` - HasMore bool `json:"has_more"` - NextCursor string `json:"next_cursor"` -} - -type File struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - File []api.FileObject `json:"files"` -} - -func (f File) SetDetail(key string, details map[string]*types.Value) { - var fileList = make([]string, len(f.File)) - for i, fo := range f.File { - if fo.External != nil { - fileList[i] = fo.External.URL - } else if fo.File != nil { - fileList[i] = fo.File.URL - } - } - details[key] = pbtypes.StringList(fileList) -} - -type Checkbox struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Checkbox bool `json:"checkbox"` -} - -func (c Checkbox) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.Bool(c.Checkbox) -} - -type Url struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - URL string `json:"url"` -} - -func (u Url) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.String(u.URL) -} - -type Email struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Email string `json:"email"` -} - -func (e Email) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.String(e.Email) -} - -type Phone struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Phone string `json:"phone_number"` -} - -func (p Phone) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.String(p.Phone) -} - -type CreatedTime struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - CreatedTime string `json:"created_time"` -} - -func (ct CreatedTime) SetDetail(key string, details map[string]*types.Value) { - t, _ := time.Parse(time.RFC3339, ct.CreatedTime) - details[key] = pbtypes.Int64(t.Unix()) -} - -type CreatedBy struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - CreatedBy api.User `json:"created_by"` -} - -func (cb CreatedBy) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.String(cb.CreatedBy.Name) -} - -type LastEditedTime struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - LastEditedTime string `json:"last_edited_time"` -} - -func (le LastEditedTime) SetDetail(key string, details map[string]*types.Value) { - t, _ := time.Parse(time.RFC3339, le.LastEditedTime) - details[key] = pbtypes.Int64(t.Unix()) -} - -type LastEditedBy struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - LastEditedBy api.User `json:"last_edited_by"` -} - type Service struct { client *client.Client } -func (lb LastEditedBy) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.String(lb.LastEditedBy.Name) -} - func New(client *client.Client) *Service { return &Service{ client: client, } } +type Properties map[string]PropertyObject + +func (p *Properties) UnmarshalJSON(data []byte) error { + var raw map[string]interface{} + if err := json.Unmarshal(data, &raw); err != nil { + return err + } + props, err := parsePropertyConfigs(raw) + if err != nil { + return err + } + + *p = props + return nil +} + +func parsePropertyConfigs(raw map[string]interface{}) (Properties, error) { + result := make(Properties) + for k, v := range raw { + var p PropertyObject + switch rawProperty := v.(type) { + case map[string]interface{}: + switch PropertyConfigType(rawProperty["type"].(string)) { + case PropertyConfigTypeTitle: + p = &Title{} + case PropertyConfigTypeRichText: + p = &RichText{} + case PropertyConfigTypeNumber: + p = &NumberProperty{} + case PropertyConfigTypeSelect: + p = &SelectProperty{} + case PropertyConfigTypeMultiSelect: + p = &MultiSelect{} + case PropertyConfigTypeDate: + p = &DateProperty{} + case PropertyConfigTypePeople: + p = &People{} + case PropertyConfigTypeFiles: + p = &File{} + case PropertyConfigTypeCheckbox: + p = &Checkbox{} + case PropertyConfigTypeURL: + p = &Url{} + case PropertyConfigTypeEmail: + p = &Email{} + case PropertyConfigTypePhoneNumber: + p = &Phone{} + case PropertyConfigTypeFormula: + p = &Formula{} + case PropertyConfigTypeRelation: + p = &RelationProperty{} + case PropertyConfigTypeRollup: + p = &Rollup{} + case PropertyConfigCreatedTime: + p = &CreatedTime{} + case PropertyConfigCreatedBy: + p = &CreatedBy{} + case PropertyConfigLastEditedTime: + p = &LastEditedTime{} + case PropertyConfigLastEditedBy: + p = &LastEditedBy{} + case PropertyConfigStatus: + p = &StatusProperty{} + default: + return nil, fmt.Errorf("unsupported property type: %s", rawProperty["type"].(string)) + } + b, err := json.Marshal(rawProperty) + if err != nil { + return nil, err + } + + if err = json.Unmarshal(b, &p); err != nil { + return nil, err + } + + result[k] = p + default: + return nil, fmt.Errorf("unsupported property format %T", v) + } + } + + return result, nil +} + +type PropertyPaginatedRespone struct{ + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Results []interface{} `json:"results"` + Item interface{} `json:"property_item"` + HasMore bool `json:"has_more"` + NextCursor string `json:"next_cursor"` +} + func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, apiKey string, propertyType PropertyConfigType) ([]interface{}, error) { var ( hasMore = true body = &bytes.Buffer{} startCursor string - response interface{} + response PropertyPaginatedRespone paginatedResponse = make([]interface{}, 0) ) @@ -384,160 +164,170 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api } switch propertyType { - case PropertyConfigTypeTitle: - response = &TitleResponse{} - case PropertyConfigTypeRichText: - response = &RichTextResponse{} + case PropertyConfigTypeTitle, PropertyConfigTypeRichText, PropertyConfigTypeRelation, PropertyConfigTypePeople: + err = json.Unmarshal(b, &response) + if err != nil { + continue + } + res := response.Results + for _, v := range res { + buffer, err := json.Marshal(v) + if err != nil { + continue + } + if propertyType == PropertyConfigTypeTitle { + p := Title{} + err = json.Unmarshal(buffer, &p) + if err != nil { + continue + } + paginatedResponse = append(paginatedResponse, p) + } + if propertyType == PropertyConfigTypeRichText { + p := RichText{} + err = json.Unmarshal(buffer, &p) + if err != nil { + continue + } + paginatedResponse = append(paginatedResponse, p) + } + if propertyType == PropertyConfigTypeRelation { + p := Relation{} + err = json.Unmarshal(buffer, &p) + if err != nil { + continue + } + paginatedResponse = append(paginatedResponse, p) + } + if propertyType == PropertyConfigTypePeople { + p := People{} + err = json.Unmarshal(buffer, &p) + if err != nil { + continue + } + paginatedResponse = append(paginatedResponse, p) + } + } + if response.HasMore { + startCursor = response.NextCursor + continue + } case PropertyConfigTypeNumber: - response = &NumberProperty{} + p := NumberProperty{} + err = json.Unmarshal(b, &p) + if err != nil { + continue + } + paginatedResponse = append(paginatedResponse, p) case PropertyConfigTypeSelect: - response = &SelectProperty{} + p := SelectProperty{} + err = json.Unmarshal(b, &p) + if err != nil { + continue + } + paginatedResponse = append(paginatedResponse, p) case PropertyConfigTypeMultiSelect: - response = &MultiSelect{} + p := MultiSelect{} + err = json.Unmarshal(b, &p) + if err != nil { + continue + } + paginatedResponse = append(paginatedResponse, p) case PropertyConfigTypeDate: - response = &DateProperty{} - case PropertyConfigTypePeople: - response = &PeopleResponse{} + date := DateProperty{} + err = json.Unmarshal(b, &date) + if err != nil { + continue + } + paginatedResponse = append(paginatedResponse, date) case PropertyConfigTypeFiles: - response = &File{} + file := File{} + err = json.Unmarshal(b, &file) + if err != nil { + continue + } + paginatedResponse = append(paginatedResponse, file) case PropertyConfigTypeCheckbox: - response = &Checkbox{} + checkbox := Checkbox{} + err = json.Unmarshal(b, &checkbox) + if err != nil { + continue + } + paginatedResponse = append(paginatedResponse, checkbox) case PropertyConfigTypeURL: - response = &Url{} + url := Url{} + err = json.Unmarshal(b, &url) + if err != nil { + continue + } + paginatedResponse = append(paginatedResponse, url) case PropertyConfigTypeEmail: - response = &Email{} + email := Email{} + err = json.Unmarshal(b, &email) + if err != nil { + continue + } + paginatedResponse = append(paginatedResponse, email) case PropertyConfigTypePhoneNumber: - response = &Phone{} + phone := Phone{} + err = json.Unmarshal(b, &phone) + if err != nil { + continue + } + paginatedResponse = append(paginatedResponse, phone) case PropertyConfigTypeFormula: - response = &Formula{} - case PropertyConfigTypeRelation: - response = &RelationProperty{} + formula := Formula{} + err = json.Unmarshal(b, &formula) + if err != nil { + continue + } + paginatedResponse = append(paginatedResponse, formula) case PropertyConfigTypeRollup: - response = &Rollup{} + rollup := Rollup{} + err = json.Unmarshal(b, &rollup) + if err != nil { + continue + } + paginatedResponse = append(paginatedResponse, rollup) case PropertyConfigCreatedTime: - response = &CreatedTime{} + ct := CreatedTime{} + err = json.Unmarshal(b, &ct) + if err != nil { + continue + } + paginatedResponse = append(paginatedResponse, ct) case PropertyConfigCreatedBy: - response = &CreatedBy{} + cb := CreatedBy{} + err = json.Unmarshal(b, &cb) + if err != nil { + continue + } + paginatedResponse = append(paginatedResponse, cb) case PropertyConfigLastEditedTime: - response = &LastEditedTime{} + lt := LastEditedTime{} + err = json.Unmarshal(b, <) + if err != nil { + continue + } + paginatedResponse = append(paginatedResponse, lt) case PropertyConfigLastEditedBy: - response = &LastEditedBy{} + le := LastEditedBy{} + err = json.Unmarshal(b, &le) + if err != nil { + continue + } + paginatedResponse = append(paginatedResponse, le) + case PropertyConfigStatus: + sp := StatusProperty{} + err = json.Unmarshal(b, &sp) + if err != nil { + continue + } + paginatedResponse = append(paginatedResponse, sp) default: return nil, fmt.Errorf("unsupported property type: %s", propertyType) } - - err = json.Unmarshal(b, &response) - - if err != nil { - return nil, err - } - if propertyType == PropertyConfigTypeTitle { - title := response.(TitleResponse) - if title.HasMore { - for _, t := range title.Results { - paginatedResponse = append(paginatedResponse, t) - } - startCursor = title.NextCursor - continue - } - } - if propertyType == PropertyConfigTypeRichText { - richText := response.(RichTextResponse) - if richText.HasMore { - for _, rt := range richText.Results { - paginatedResponse = append(paginatedResponse, rt) - } - startCursor = richText.NextCursor - continue - } - } - if propertyType == PropertyConfigTypePeople { - people := response.(PeopleResponse) - if people.HasMore { - for _, people := range people.Results { - paginatedResponse = append(paginatedResponse, people) - } - startCursor = people.NextCursor - continue - } - } - if propertyType == PropertyConfigTypeRelation { - relations := response.(RelationResponse) - if relations.HasMore { - for _, relations := range relations.Results { - paginatedResponse = append(paginatedResponse, relations) - } - startCursor = relations.NextCursor - continue - } - } - paginatedResponse = append(paginatedResponse, response) hasMore = false } return paginatedResponse, nil } - -func (s *Service) SetDetailValue(key string, propertyType PropertyConfigType, property []interface{}, details map[string]*types.Value) error { - switch propertyType { - case PropertyConfigTypeTitle: - for _, v := range property { - title := v.(Title) - title.SetDetail(key, details) - } - case PropertyConfigTypeRichText: - for _, v := range property { - rt := v.(RichText) - rt.SetDetail(key, details) - } - case PropertyConfigTypeNumber: - number := property[0].(NumberProperty) - number.SetDetail(key, details) - case PropertyConfigTypeSelect: - selectProperty := property[0].(SelectProperty) - selectProperty.SetDetail(key, details) - case PropertyConfigTypeMultiSelect: - multiSelect := property[0].(MultiSelect) - multiSelect.SetDetail(key, details) - case PropertyConfigTypeDate: - case PropertyConfigTypePeople: - p := property[0].(People) - p.SetDetail(key, details) - case PropertyConfigTypeFiles: - f := property[0].(File) - f.SetDetail(key, details) - case PropertyConfigTypeCheckbox: - c := property[0].(Checkbox) - c.SetDetail(key, details) - case PropertyConfigTypeURL: - url := property[0].(Url) - url.SetDetail(key, details) - case PropertyConfigTypeEmail: - email := property[0].(Email) - email.SetDetail(key, details) - case PropertyConfigTypePhoneNumber: - phone := property[0].(Phone) - phone.SetDetail(key, details) - case PropertyConfigTypeFormula: - formula := property[0].(Formula) - formula.SetDetail(key, details) - case PropertyConfigTypeRelation: - relation := property[0].(RelationProperty) - relation.SetDetail(key, details) - case PropertyConfigTypeRollup: - case PropertyConfigCreatedTime: - ct := property[0].(CreatedTime) - ct.SetDetail(key, details) - case PropertyConfigCreatedBy: - cb := property[0].(CreatedBy) - cb.SetDetail(key, details) - case PropertyConfigLastEditedTime: - lt := property[0].(LastEditedTime) - lt.SetDetail(key, details) - case PropertyConfigLastEditedBy: - lb := property[0].(LastEditedBy) - lb.SetDetail(key, details) - default: - return fmt.Errorf("unsupported property type: %s", propertyType) - } - return nil -} diff --git a/core/block/import/notion/api/search/search.go b/core/block/import/notion/api/search/search.go index 8ce405362..f3be68e1d 100644 --- a/core/block/import/notion/api/search/search.go +++ b/core/block/import/notion/api/search/search.go @@ -8,7 +8,6 @@ import ( "io/ioutil" "net/http" - "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/database" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/page" @@ -23,7 +22,7 @@ type Service struct { } type SearchResponse struct { - Results []api.Object `json:"results"` + Results []interface{} `json:"results"` HasMore bool `json:"has_more"` NextCursor *string `json:"next_cursor"` } @@ -86,11 +85,29 @@ func (s *Service) Search(ctx context.Context, apiKey string, pageSize int64) ([] return nil, nil, err } for _, o := range objects.Results { - if o.GetObjectType() == database.ObjectType { - resultDatabases = append(resultDatabases, o.(database.Database)) + if o.(map[string]interface{})["object"] == database.ObjectType { + db, err := json.Marshal(o) + if err != nil { + return nil, nil, fmt.Errorf("ListDatabases: %s", err) + } + d := database.Database{} + err = json.Unmarshal(db, &d) + if err != nil { + return nil, nil, fmt.Errorf("ListDatabases: %s", err) + } + resultDatabases = append(resultDatabases, d) } - if o.GetObjectType() == page.ObjectType { - resultPages = append(resultPages, o.(page.Page)) + if o.(map[string]interface{})["object"] == page.ObjectType{ + pg, err := json.Marshal(o) + if err != nil { + return nil, nil, fmt.Errorf("ListDatabases: %s", err) + } + p := page.Page{} + err = json.Unmarshal(pg, &p) + if err != nil { + return nil, nil, fmt.Errorf("ListDatabases: %s", err) + } + resultPages = append(resultPages, p) } } diff --git a/core/block/import/notion/api/search/search_test.go b/core/block/import/notion/api/search/search_test.go index f77a47d11..002c309b8 100644 --- a/core/block/import/notion/api/search/search_test.go +++ b/core/block/import/notion/api/search/search_test.go @@ -8,6 +8,7 @@ import ( "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/database" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/page" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/stretchr/testify/assert" ) @@ -36,7 +37,86 @@ func Test_GetDatabaseSuccess(t *testing.T) { assert.Nil(t, databases.Error) } -func Test_GetDatabaseFailedRequest(t *testing.T) { +func Test_GetPagesSuccess(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(` + { + "object": "list", + "results": [ + { + "object": "page", + "id": "43b4db4f-23b8-46f9-9909-c783b033fb7d", + "created_time": "2022-10-25T11:44:00.000Z", + "last_edited_time": "2022-11-04T12:00:00.000Z", + "created_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "last_edited_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "cover": { + "type": "external", + "external": { + "url": "https://www.notion.so/images/page-cover/nasa_eagle_in_lunar_orbit.jpg" + } + }, + "icon": { + "type": "emoji", + "emoji": "📣" + }, + "parent": { + "type": "database_id", + "database_id": "072a11cb-684f-4f2b-9490-79592700c67e" + }, + "archived": false, + "properties": { + "✔️ Task List": { + "id": "_OI%5E", + "type": "relation", + "relation": [], + "has_more": true + } + }, + "url": "https://www.notion.so/dd-43b4db4f23b846f99909c783b033fb7d" + } + ], + "next_cursor": null, + "has_more": false, + "type": "page_or_database", + "page_or_database": {} + } + `)) + })) + + defer s.Close() + pageSize := int64(100) + c := client.NewClient() + c.BasePath = s.URL + + searchService := New(c) + _, p, err := searchService.Search(context.TODO(), "key", pageSize) + assert.NotNil(t, p) + assert.Len(t, p, 1) + assert.Nil(t, err) + + s = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"object":"list","results":[{"object":"property_item","type":"relation","id":"cm~~","relation":{"id":"18e660df-d7f4-4d4b-b30c-eeb88ffee645"}}],"next_cursor":null,"has_more":false,"type":"property_item","property_item":{"id":"cm~~","next_url":null,"type":"relation","relation":{}}}`)) + })) + + c = client.NewClient() + c.BasePath = s.URL + ps := page.New(c) + pages := ps.GetPages(context.Background(), "key", pb.RpcObjectImportRequest_ALL_OR_NOTHING, p) + + assert.NotNil(t, pages) + assert.Len(t, pages.Snapshots, 1) + assert.Nil(t, pages.Error) +} + + +func Test_SearcheFailedRequest(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(`{"object":"error","status":400,"code":"validation_error","message":"path failed validation: path.database_id should be a valid uuid"}`)) @@ -47,16 +127,9 @@ func Test_GetDatabaseFailedRequest(t *testing.T) { c.BasePath = s.URL searchService := New(c) - db, _, err := searchService.Search(context.TODO(), "key", pageSize) - assert.NotNil(t, db) - assert.Len(t, db, 1) - assert.Nil(t, err) - - ds := database.New() - databases := ds.GetDatabase(context.Background(), pb.RpcObjectImportRequest_ALL_OR_NOTHING, db) - - assert.NotNil(t, databases) - assert.Nil(t, databases.Snapshots) - assert.NotNil(t, databases.Error) - assert.Contains(t, databases.Error.Error().Error(), "path failed validation: path.database_id should be a valid uuid") -} \ No newline at end of file + db, p, err := searchService.Search(context.TODO(), "key", pageSize) + assert.Nil(t, db) + assert.Nil(t, p) + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "path failed validation: path.database_id should be a valid uuid") +} diff --git a/core/object.go b/core/object.go index e2d495a42..06982ddee 100644 --- a/core/object.go +++ b/core/object.go @@ -776,8 +776,7 @@ func (mw *Middleware) ObjectSetInternalFlags(cctx context.Context, req *pb.RpcOb } func (mw *Middleware) ObjectImport(cctx context.Context, req *pb.RpcObjectImportRequest) *pb.RpcObjectImportResponse { - ctx := mw.newContext(cctx) - + ctx := mw.newContext(cctx) response := func(code pb.RpcObjectImportResponseErrorCode, err error) *pb.RpcObjectImportResponse { m := &pb.RpcObjectImportResponse{Error: &pb.RpcObjectImportResponseError{Code: code}} From 7e70e1befa84e0ea3a99119331304f92fd6e93ae Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Mon, 7 Nov 2022 13:43:08 +0300 Subject: [PATCH 05/68] GO-469: fix conflicts Signed-off-by: AnastasiaShemyakinskaya --- pb/commands.pb.go | 1468 +++++++++++++++++++++++---------------------- 1 file changed, 736 insertions(+), 732 deletions(-) diff --git a/pb/commands.pb.go b/pb/commands.pb.go index ec41504b8..0f1ebef80 100644 --- a/pb/commands.pb.go +++ b/pb/commands.pb.go @@ -43153,738 +43153,742 @@ func init() { func init() { proto.RegisterFile("pb/protos/commands.proto", fileDescriptor_8261c968b2e6f45c) } var fileDescriptor_8261c968b2e6f45c = []byte{ - // 11685 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0xbd, 0x7b, 0x78, 0x2c, 0x47, - 0x79, 0x27, 0x7c, 0x66, 0x7a, 0x2e, 0xd2, 0xab, 0x23, 0x9d, 0x76, 0x73, 0x38, 0x16, 0x65, 0xfb, - 0x60, 0xe4, 0x0b, 0xe6, 0xd8, 0x96, 0xed, 0x63, 0x2e, 0x3e, 0xbe, 0x8f, 0x66, 0x46, 0xd2, 0xd8, - 0xd2, 0x8c, 0xd2, 0x33, 0x3a, 0x27, 0xce, 0xf7, 0x65, 0xb5, 0xad, 0x99, 0x92, 0xd4, 0xd6, 0xa8, - 0x7b, 0xe8, 0xe9, 0xd1, 0x39, 0xe2, 0x79, 0x76, 0x13, 0x27, 0x18, 0x9b, 0xf0, 0x00, 0x81, 0x90, - 0x05, 0x87, 0x05, 0x83, 0xb9, 0x43, 0x08, 0x31, 0xd7, 0x25, 0x0b, 0xce, 0x12, 0x20, 0x0f, 0xe1, - 0x49, 0x30, 0xe1, 0x9e, 0x2c, 0x10, 0x30, 0x59, 0x96, 0xec, 0xc2, 0xf2, 0x90, 0x67, 0x77, 0x59, - 0x96, 0x64, 0xd9, 0xa7, 0xaa, 0xfa, 0x56, 0xa3, 0xe9, 0x9e, 0xee, 0xd1, 0xf4, 0xc8, 0xd9, 0xfc, - 0x35, 0x53, 0xd5, 0x75, 0x79, 0xeb, 0xfd, 0xbd, 0xf5, 0x56, 0xd5, 0x5b, 0x6f, 0x55, 0xc1, 0x74, - 0x6b, 0xfd, 0x86, 0x96, 0xa1, 0x9b, 0x7a, 0xfb, 0x86, 0xba, 0xbe, 0xb3, 0xa3, 0x68, 0x8d, 0xf6, - 0x2c, 0x0d, 0x4b, 0x59, 0x45, 0xdb, 0x33, 0xf7, 0x5a, 0x18, 0x5d, 0xd9, 0xda, 0xde, 0xbc, 0xa1, - 0xa9, 0xae, 0xdf, 0xd0, 0x5a, 0xbf, 0x61, 0x47, 0x6f, 0xe0, 0xa6, 0x9d, 0x81, 0x06, 0xac, 0xe4, - 0xe8, 0x1a, 0xbf, 0x54, 0x4d, 0xbd, 0xae, 0x34, 0xdb, 0xa6, 0x6e, 0x60, 0x2b, 0xe5, 0x09, 0xb7, - 0x4a, 0xbc, 0x8b, 0x35, 0xd3, 0x2e, 0xe1, 0xd2, 0x4d, 0x5d, 0xdf, 0x6c, 0x62, 0xf6, 0x6d, 0xbd, - 0xb3, 0x71, 0x43, 0xdb, 0x34, 0x3a, 0x75, 0xd3, 0xfa, 0x7a, 0x79, 0xf7, 0xd7, 0x06, 0x6e, 0xd7, - 0x0d, 0xb5, 0x65, 0xea, 0x06, 0x4b, 0x31, 0xf3, 0xc1, 0xef, 0xa6, 0x40, 0x90, 0x5b, 0x75, 0xf4, - 0x85, 0x31, 0x10, 0x72, 0xad, 0x16, 0xfa, 0x49, 0x12, 0x60, 0x01, 0x9b, 0x67, 0xb1, 0xd1, 0x56, - 0x75, 0x0d, 0x8d, 0x43, 0x56, 0xc6, 0x2f, 0xee, 0xe0, 0xb6, 0x89, 0xbe, 0x9e, 0x84, 0x31, 0x19, - 0xb7, 0x5b, 0xba, 0xd6, 0xc6, 0xd2, 0xdd, 0x90, 0xc6, 0x86, 0xa1, 0x1b, 0xd3, 0x89, 0xcb, 0x13, - 0xd7, 0x4c, 0x9c, 0x3e, 0x35, 0x6b, 0x35, 0x7c, 0x56, 0x6e, 0xd5, 0x67, 0x73, 0xad, 0xd6, 0xac, - 0x5b, 0xc6, 0xac, 0x9d, 0x69, 0xb6, 0x48, 0x72, 0xc8, 0x2c, 0xa3, 0x34, 0x0d, 0xd9, 0x5d, 0x96, - 0x60, 0x3a, 0x79, 0x79, 0xe2, 0x9a, 0x71, 0xd9, 0x0e, 0x92, 0x2f, 0x0d, 0x6c, 0x2a, 0x6a, 0xb3, - 0x3d, 0x2d, 0xb0, 0x2f, 0x56, 0x10, 0x7d, 0x25, 0x01, 0x69, 0x5a, 0x88, 0x94, 0x87, 0x54, 0x5d, - 0x6f, 0x60, 0x5a, 0xfd, 0xd4, 0xe9, 0x1b, 0xc2, 0x57, 0x3f, 0x9b, 0xd7, 0x1b, 0x58, 0xa6, 0x99, - 0xa5, 0xcb, 0x61, 0xc2, 0x66, 0x88, 0x4b, 0x86, 0x37, 0x6a, 0xa6, 0x01, 0x29, 0x92, 0x5e, 0x1a, - 0x83, 0x54, 0x79, 0x75, 0x69, 0x49, 0x3c, 0x22, 0x5d, 0x04, 0x93, 0xab, 0xe5, 0x7b, 0xcb, 0x95, - 0x73, 0xe5, 0xb5, 0xa2, 0x2c, 0x57, 0x64, 0x31, 0x21, 0x4d, 0xc2, 0xf8, 0x5c, 0xae, 0xb0, 0x56, - 0x2a, 0xaf, 0xac, 0xd6, 0xc4, 0xa4, 0x74, 0x1c, 0xc4, 0xb3, 0x45, 0xb9, 0x5a, 0xaa, 0x94, 0xd7, - 0x4a, 0xd5, 0xb5, 0xe2, 0xf2, 0x4a, 0xed, 0x3e, 0x51, 0x20, 0x89, 0xca, 0x95, 0xda, 0xda, 0x7c, - 0x65, 0xb5, 0x5c, 0x10, 0xb1, 0x34, 0x01, 0xd9, 0x5a, 0x69, 0xb9, 0x58, 0x59, 0xad, 0x89, 0x1b, - 0xe8, 0xc3, 0x02, 0x4c, 0x55, 0xb1, 0x59, 0xc0, 0xbb, 0x6a, 0x1d, 0x57, 0x4d, 0xc5, 0xc4, 0xe8, - 0xd5, 0x09, 0x87, 0xf1, 0xd2, 0x2a, 0x21, 0xd3, 0xf9, 0x64, 0x35, 0xf9, 0xe6, 0x7d, 0x4d, 0xe6, - 0x4b, 0x98, 0xb5, 0x72, 0xcf, 0x7a, 0xe2, 0x64, 0x6f, 0x39, 0x33, 0xd7, 0xc3, 0x84, 0xe7, 0x9b, - 0x34, 0x05, 0x30, 0x97, 0xcb, 0xdf, 0xbb, 0x20, 0x53, 0x0a, 0x8f, 0x90, 0xf0, 0x7c, 0x45, 0x2e, - 0x5a, 0xe1, 0x04, 0x7a, 0xb5, 0x17, 0xfe, 0x02, 0x0f, 0xff, 0x6c, 0x7f, 0x62, 0x7a, 0x88, 0x00, - 0xfa, 0x84, 0x03, 0xe7, 0x02, 0x07, 0xe7, 0xcd, 0xd1, 0x8a, 0x8b, 0x06, 0xe9, 0xe2, 0x60, 0x90, - 0x96, 0x2b, 0x85, 0xe2, 0x1a, 0x41, 0xb0, 0x5a, 0xcb, 0xc9, 0xb5, 0x62, 0x41, 0xc4, 0xe8, 0x8d, - 0x49, 0x18, 0xab, 0x6e, 0x75, 0xcc, 0x86, 0x7e, 0x9e, 0xeb, 0x28, 0xbf, 0xe9, 0xe5, 0xd4, 0x9d, - 0x3c, 0xa7, 0xae, 0xd9, 0xdf, 0x34, 0xab, 0x04, 0x1f, 0x1e, 0x7d, 0xd4, 0xe1, 0x51, 0x8e, 0xe3, - 0xd1, 0xf5, 0x61, 0x0b, 0x3a, 0x2c, 0xee, 0x7c, 0x75, 0x12, 0x32, 0xe7, 0x94, 0x66, 0x13, 0x9b, - 0xe8, 0x6f, 0x93, 0x90, 0xc9, 0x1b, 0x98, 0xc8, 0xf5, 0xb5, 0xae, 0x58, 0x23, 0x18, 0x33, 0x74, - 0xdd, 0x5c, 0x51, 0xcc, 0x2d, 0xda, 0xa6, 0x71, 0xd9, 0x09, 0xdf, 0x9a, 0x7a, 0xf8, 0xfb, 0x42, - 0x02, 0xfd, 0xbe, 0x97, 0x91, 0x77, 0xf1, 0x8c, 0x7c, 0x1e, 0xd7, 0x7e, 0x56, 0xd1, 0x2c, 0xab, - 0xc4, 0x47, 0xe1, 0x20, 0x18, 0xdb, 0xd1, 0xf0, 0x8e, 0xae, 0xa9, 0x75, 0xab, 0xe5, 0x4e, 0x18, - 0xfd, 0x89, 0xc3, 0xe5, 0x39, 0x8e, 0xcb, 0xb3, 0xa1, 0x6b, 0x89, 0xc6, 0xe6, 0xea, 0x00, 0x6c, - 0x7e, 0x36, 0x5c, 0x32, 0x9f, 0x2b, 0x2d, 0x15, 0x0b, 0x6b, 0xb5, 0xca, 0x5a, 0x5e, 0x2e, 0xe6, - 0x6a, 0xc5, 0xb5, 0xa5, 0x4a, 0x3e, 0xb7, 0xb4, 0x26, 0x17, 0x57, 0x2a, 0x22, 0x46, 0xff, 0x39, - 0x49, 0x98, 0x5b, 0xd7, 0x77, 0xb1, 0x81, 0x16, 0x42, 0xf1, 0x39, 0x88, 0x27, 0x16, 0x06, 0xaf, - 0x0d, 0xad, 0xf5, 0x2d, 0xee, 0x58, 0x14, 0xf8, 0x88, 0xf3, 0xa7, 0x43, 0x69, 0xf0, 0xc0, 0xa2, - 0x9e, 0x06, 0x9c, 0xfe, 0xef, 0x49, 0xc8, 0xe6, 0x75, 0x6d, 0x17, 0x1b, 0x26, 0xba, 0x8b, 0xe3, - 0xb4, 0xc3, 0xcd, 0x04, 0xcf, 0x4d, 0x32, 0xa8, 0x61, 0xcd, 0x34, 0xf4, 0xd6, 0x9e, 0x3d, 0xdc, - 0x59, 0x41, 0xf4, 0xae, 0xa8, 0x1c, 0xb6, 0x6a, 0xf6, 0x1f, 0x57, 0x7b, 0x57, 0xc4, 0x91, 0x27, - 0x74, 0x75, 0x80, 0xc7, 0xa2, 0xe0, 0xd2, 0x9b, 0x80, 0x68, 0xb8, 0x9c, 0x8e, 0x8e, 0x0b, 0xfa, - 0x52, 0x12, 0x26, 0x59, 0xe7, 0xab, 0xe2, 0x36, 0x9d, 0x9e, 0x5c, 0x1b, 0x8a, 0xf9, 0x96, 0x28, - 0xff, 0x8e, 0x97, 0xd1, 0xf3, 0x3c, 0xa3, 0x6f, 0xf4, 0xef, 0xe8, 0x56, 0x5d, 0x3e, 0xec, 0x3e, - 0x0e, 0x69, 0x53, 0xdf, 0xc6, 0x76, 0x1b, 0x59, 0x00, 0xbd, 0xdb, 0x61, 0x67, 0x89, 0x63, 0xe7, - 0x0b, 0xa2, 0x56, 0x13, 0x3f, 0x53, 0xdf, 0x9f, 0x84, 0xa3, 0xf9, 0xa6, 0xde, 0x76, 0x78, 0xfa, - 0x6c, 0x97, 0xa7, 0x4e, 0xe3, 0x12, 0xde, 0xc6, 0xfd, 0x3c, 0xe1, 0xe1, 0x63, 0x91, 0xe7, 0x63, - 0x6f, 0x79, 0xf1, 0x14, 0xef, 0xa3, 0x17, 0xde, 0xe5, 0x30, 0x6c, 0x91, 0x63, 0xd8, 0xf3, 0x23, - 0x96, 0x17, 0x3f, 0xbf, 0x3e, 0xfa, 0x1c, 0xc8, 0xe6, 0xea, 0x75, 0xbd, 0xa3, 0x99, 0xe8, 0x6f, - 0x12, 0x90, 0xc9, 0xeb, 0xda, 0x86, 0xba, 0x29, 0x5d, 0x0d, 0x53, 0x58, 0x53, 0xd6, 0x9b, 0xb8, - 0xa0, 0x98, 0xca, 0xae, 0x8a, 0xcf, 0xd3, 0x06, 0x8c, 0xc9, 0x5d, 0xb1, 0x84, 0x28, 0x2b, 0x06, - 0xaf, 0x77, 0x36, 0x29, 0x51, 0x63, 0xb2, 0x37, 0x4a, 0xba, 0x05, 0x2e, 0x66, 0xc1, 0x15, 0x03, - 0x1b, 0xb8, 0x89, 0x95, 0x36, 0xce, 0x6f, 0x29, 0x9a, 0x86, 0x9b, 0xb4, 0xd7, 0x8e, 0xc9, 0x7e, - 0x9f, 0xa5, 0x19, 0x38, 0xca, 0x3e, 0x55, 0x5b, 0x4a, 0x1d, 0xb7, 0xa7, 0x53, 0x34, 0x39, 0x17, - 0x27, 0x5d, 0x0f, 0x69, 0x7c, 0xc1, 0x34, 0x94, 0xe9, 0x06, 0xc5, 0xeb, 0xe2, 0x59, 0xb6, 0x44, - 0x98, 0xb5, 0x97, 0x08, 0xb3, 0x55, 0xba, 0x80, 0x90, 0x59, 0x2a, 0xf4, 0xe9, 0x8c, 0x33, 0x74, - 0xbf, 0xd5, 0x33, 0x25, 0x95, 0x20, 0xa5, 0x29, 0x3b, 0xd8, 0x92, 0x0b, 0xfa, 0x5f, 0x3a, 0x05, - 0xc7, 0x94, 0x5d, 0xc5, 0x54, 0x8c, 0x25, 0xb2, 0x78, 0xa1, 0xc3, 0x0d, 0x65, 0xf9, 0xe2, 0x11, - 0xb9, 0xfb, 0x83, 0x74, 0x29, 0x8c, 0xd3, 0xd5, 0x0d, 0x4d, 0xc5, 0x74, 0x91, 0x1b, 0x21, 0x5d, - 0x03, 0xc7, 0x94, 0x66, 0x6b, 0x4b, 0x29, 0x69, 0xbb, 0xaa, 0x89, 0x09, 0x42, 0xd3, 0xc7, 0x69, - 0x9a, 0xee, 0x68, 0xd6, 0xb1, 0xe7, 0xc6, 0x20, 0xc3, 0x2a, 0x40, 0xaf, 0x4b, 0x87, 0x5e, 0xa3, - 0x30, 0x08, 0x83, 0xa7, 0x0c, 0x37, 0x42, 0x56, 0x61, 0xe9, 0x68, 0x53, 0x26, 0x4e, 0x9f, 0x70, - 0xca, 0xa0, 0xcb, 0x35, 0xbb, 0x14, 0xd9, 0x4e, 0x26, 0xdd, 0x0c, 0x99, 0x3a, 0x15, 0x08, 0xda, - 0xaa, 0x89, 0xd3, 0x97, 0xf4, 0xae, 0x94, 0x26, 0x91, 0xad, 0xa4, 0xe8, 0xdb, 0x42, 0xa8, 0x65, - 0x4d, 0x10, 0xc5, 0xd1, 0xe4, 0xfe, 0x47, 0xc9, 0x01, 0x46, 0xc5, 0xeb, 0xe0, 0x9a, 0x5c, 0x3e, - 0x5f, 0x59, 0x2d, 0xd7, 0xac, 0x31, 0xb1, 0xb0, 0x36, 0xb7, 0x5a, 0x5b, 0x73, 0x47, 0x4a, 0x3a, - 0xf7, 0x5b, 0x23, 0x53, 0x41, 0x91, 0x48, 0xc3, 0xd5, 0x7d, 0x52, 0x17, 0x6b, 0x6b, 0xe5, 0xdc, - 0x72, 0x51, 0xdc, 0x08, 0x51, 0x72, 0xb1, 0xb6, 0x96, 0x3b, 0x9b, 0xab, 0xe5, 0x64, 0x71, 0x93, - 0x1f, 0x9d, 0xab, 0xb5, 0xca, 0xca, 0x9a, 0xbc, 0x5a, 0x2e, 0x97, 0xca, 0x0b, 0xac, 0x6a, 0x32, - 0xa9, 0x39, 0xe1, 0x26, 0x38, 0x27, 0x97, 0x6a, 0xc5, 0xb5, 0x7c, 0xa5, 0x3c, 0x5f, 0x5a, 0x10, - 0xd5, 0x7e, 0x43, 0xfb, 0xfd, 0xd2, 0x71, 0x38, 0xc6, 0x1a, 0x7d, 0x96, 0xe5, 0x2b, 0x14, 0xc5, - 0x97, 0x66, 0xa5, 0x29, 0x18, 0x2f, 0x17, 0x6b, 0x16, 0x67, 0x1e, 0xcc, 0x4a, 0x97, 0xc0, 0x09, - 0x12, 0xce, 0x57, 0xca, 0xe5, 0x62, 0xbe, 0x46, 0x96, 0x7a, 0x72, 0x71, 0x7e, 0xb5, 0x5a, 0x2c, - 0x88, 0x2f, 0xcb, 0x4a, 0x22, 0x4c, 0x90, 0x8f, 0x95, 0xf9, 0xf9, 0xa5, 0x52, 0xb9, 0x28, 0x3e, - 0x94, 0x45, 0xef, 0x48, 0xb9, 0x33, 0x33, 0xcf, 0x42, 0xe1, 0x55, 0x29, 0x8f, 0xb4, 0xe6, 0x78, - 0x69, 0xbd, 0xb6, 0x27, 0xf6, 0xc1, 0x93, 0xab, 0x27, 0x1c, 0x39, 0x2a, 0x70, 0x72, 0x74, 0x63, - 0x84, 0xb2, 0xa2, 0x09, 0xd2, 0x9f, 0x0f, 0x22, 0x48, 0xcf, 0x84, 0x8b, 0xca, 0x95, 0x35, 0x0b, - 0xf1, 0xaa, 0xb3, 0x24, 0xbe, 0x1c, 0x2e, 0x2d, 0x17, 0x19, 0x30, 0x72, 0x31, 0x5f, 0x39, 0x5b, - 0x94, 0xd7, 0xce, 0xe5, 0x96, 0x96, 0x8a, 0xb5, 0xb5, 0xf9, 0x92, 0x5c, 0xad, 0x89, 0x1b, 0xfd, - 0xc0, 0xdb, 0x94, 0xae, 0x80, 0x67, 0xbb, 0xe1, 0xb5, 0xe2, 0x2f, 0x97, 0xaa, 0xb5, 0x2a, 0x15, - 0xa5, 0x7c, 0x45, 0x96, 0x57, 0x57, 0xc8, 0xc2, 0x64, 0x4b, 0x3a, 0x01, 0x92, 0x5b, 0x8a, 0xbc, - 0x5a, 0x66, 0x62, 0xa3, 0x92, 0xfa, 0xad, 0xfa, 0xec, 0xea, 0xc9, 0x82, 0x66, 0xa5, 0x28, 0xcf, - 0x57, 0xe4, 0xe5, 0x62, 0x41, 0xbc, 0xbf, 0x9f, 0xe4, 0x6d, 0x4b, 0x57, 0xc3, 0x4c, 0xae, 0x5c, - 0xa9, 0x2d, 0x16, 0xe5, 0xb5, 0x5c, 0xf9, 0xbe, 0xda, 0x7d, 0x2b, 0xc5, 0xb5, 0x15, 0xb9, 0x92, - 0x2f, 0x56, 0xab, 0x6b, 0xa5, 0xaa, 0x9d, 0x58, 0x6c, 0x12, 0x12, 0x6c, 0x81, 0x2f, 0x55, 0xd7, - 0x0a, 0xc5, 0xa5, 0x22, 0x21, 0x6d, 0x07, 0xbd, 0x52, 0x80, 0x4c, 0x01, 0x37, 0xb1, 0x89, 0xd1, - 0x73, 0x5c, 0x65, 0x7b, 0x02, 0x32, 0x06, 0x26, 0x13, 0x2e, 0x6b, 0x48, 0xb1, 0x42, 0xe8, 0x6f, - 0x92, 0x51, 0x95, 0x1d, 0x2b, 0xdb, 0x47, 0xd9, 0xbd, 0x00, 0x32, 0x6d, 0x53, 0x31, 0x3b, 0x6d, - 0x4b, 0xd7, 0x5d, 0xd6, 0x5b, 0xd7, 0xcd, 0x56, 0x69, 0x22, 0xd9, 0x4a, 0x8c, 0xfe, 0x2a, 0x11, - 0x45, 0x79, 0xf5, 0xa4, 0x20, 0x9a, 0xcc, 0xa9, 0x03, 0x88, 0xdc, 0x49, 0x40, 0x1e, 0x86, 0xe7, - 0x96, 0xe4, 0x62, 0xae, 0x70, 0x9f, 0xc3, 0x78, 0x4c, 0x44, 0xd2, 0xfb, 0x3d, 0x5f, 0x2b, 0x9d, - 0x2d, 0x8a, 0x1b, 0xe8, 0xd3, 0x69, 0xc8, 0x54, 0x71, 0x13, 0xd7, 0x4d, 0x74, 0x9b, 0x8b, 0xc7, - 0x14, 0x24, 0xd5, 0x86, 0x35, 0xf4, 0x25, 0xd5, 0x06, 0xb7, 0xc0, 0x4a, 0xf6, 0x5c, 0xc8, 0xfe, - 0x3c, 0x15, 0x15, 0x29, 0x56, 0xeb, 0xe1, 0x0e, 0x4b, 0x9f, 0x8d, 0x34, 0x2c, 0xf5, 0xa4, 0x38, - 0x1a, 0xb2, 0x5f, 0x49, 0xc6, 0xb0, 0x58, 0x0b, 0xa3, 0x14, 0x36, 0x7c, 0x94, 0x42, 0xd7, 0x60, - 0x33, 0x5f, 0x2a, 0x17, 0xd6, 0x1c, 0x39, 0x29, 0xcf, 0x57, 0xc4, 0x2d, 0x69, 0x16, 0x4e, 0x79, - 0x4a, 0x27, 0x1a, 0xc3, 0xaa, 0x21, 0x57, 0x2e, 0xac, 0x2d, 0x97, 0x8b, 0xcb, 0x95, 0x72, 0x29, - 0xcf, 0x4c, 0x23, 0xc5, 0x1a, 0xd3, 0x32, 0x5d, 0x3a, 0xa4, 0x5a, 0xcc, 0xc9, 0xf9, 0x45, 0xaa, - 0x6e, 0x0a, 0x45, 0xf1, 0x7e, 0xe9, 0xb9, 0x70, 0x85, 0x87, 0x14, 0x4b, 0x15, 0xad, 0xc8, 0xc5, - 0x42, 0x71, 0xbe, 0x54, 0x26, 0x43, 0xe3, 0x52, 0x25, 0x7f, 0x6f, 0x35, 0xbc, 0xb6, 0x41, 0xff, - 0x3b, 0x09, 0xa9, 0xaa, 0xa9, 0xb7, 0xd0, 0xf3, 0x5c, 0x19, 0x3e, 0x09, 0x60, 0xe0, 0x1d, 0x7d, - 0x97, 0x4e, 0x4c, 0x2d, 0xbd, 0xe2, 0x89, 0x41, 0x7f, 0x1a, 0xde, 0x86, 0xe5, 0xa8, 0x05, 0xbd, - 0xe5, 0x33, 0x2e, 0xfd, 0x2c, 0x9c, 0x0d, 0xcb, 0xbf, 0xa0, 0x68, 0x62, 0xf4, 0x5b, 0x89, 0x01, - 0xc4, 0x08, 0xc1, 0x09, 0x8f, 0x06, 0x20, 0x78, 0xd9, 0x0c, 0xc4, 0xd2, 0xc5, 0xf0, 0x8c, 0x2e, - 0xcc, 0x28, 0x54, 0x1b, 0xd2, 0x73, 0xe0, 0x32, 0x2f, 0x54, 0xcb, 0x95, 0xb3, 0x45, 0x47, 0x3e, - 0x0a, 0xb9, 0x5a, 0x4e, 0xdc, 0x44, 0x5f, 0x16, 0x20, 0xb5, 0xac, 0xef, 0x62, 0x74, 0x85, 0xcb, - 0xfc, 0x69, 0xc8, 0x6a, 0xf8, 0xbc, 0xc7, 0x20, 0x63, 0x07, 0xd1, 0x3b, 0x84, 0xa8, 0x6c, 0x27, - 0x65, 0xfb, 0xb0, 0xfd, 0x1b, 0xc9, 0x28, 0x6c, 0xef, 0x51, 0x50, 0x34, 0xb6, 0xff, 0xdd, 0x20, - 0x6c, 0xf7, 0x61, 0x2d, 0x96, 0x66, 0xe0, 0xa4, 0xfb, 0xa1, 0x54, 0x28, 0x96, 0x6b, 0xa5, 0xf9, - 0xfb, 0x5c, 0xe6, 0x96, 0xe4, 0x50, 0xec, 0xef, 0xa7, 0x1d, 0x82, 0x27, 0x8b, 0xd3, 0x70, 0xdc, - 0xfd, 0xb6, 0xc0, 0xe6, 0x7b, 0xe4, 0xcb, 0xfd, 0xe8, 0xb5, 0x69, 0x38, 0xca, 0xb4, 0xe5, 0x6a, - 0xab, 0x41, 0x16, 0x47, 0x57, 0x71, 0x86, 0x08, 0x53, 0xdd, 0xc1, 0xbf, 0xa2, 0x6b, 0xf6, 0xfa, - 0xc8, 0x09, 0xa3, 0x2f, 0x86, 0x36, 0x41, 0xf0, 0x3a, 0x99, 0xd5, 0xe2, 0x83, 0xf3, 0xcf, 0x43, - 0x19, 0x1b, 0x42, 0x14, 0x18, 0x0d, 0xef, 0x97, 0x0e, 0xbb, 0x9b, 0xf9, 0x43, 0xb1, 0xe1, 0x0b, - 0xc5, 0xe6, 0xcc, 0x43, 0x49, 0x18, 0xaf, 0xa9, 0x3b, 0xf8, 0x25, 0xba, 0x86, 0xdb, 0x52, 0x16, - 0x84, 0x85, 0xe5, 0x9a, 0x78, 0x84, 0xfc, 0x29, 0xe6, 0x6b, 0x62, 0x82, 0xfe, 0x29, 0x92, 0xaa, - 0xc9, 0x9f, 0x5c, 0x4d, 0x14, 0xc8, 0x9f, 0xe5, 0x62, 0x4d, 0x4c, 0x91, 0x3f, 0xe5, 0x62, 0x4d, - 0x4c, 0x93, 0x3f, 0x2b, 0x4b, 0x35, 0x31, 0x43, 0xfe, 0x94, 0xaa, 0x35, 0x31, 0x4b, 0xfe, 0xcc, - 0x55, 0x6b, 0xe2, 0x18, 0xf9, 0x73, 0xb6, 0x5a, 0x13, 0xc7, 0xc9, 0x9f, 0x7c, 0xad, 0x26, 0x02, - 0xf9, 0x73, 0x4f, 0xb5, 0x26, 0x4e, 0x90, 0x3f, 0xb9, 0x7c, 0x4d, 0x3c, 0x4a, 0xff, 0x14, 0x6b, - 0xe2, 0x24, 0xf9, 0x53, 0xad, 0xd6, 0xc4, 0x29, 0x5a, 0x72, 0xb5, 0x26, 0x1e, 0xa3, 0x75, 0x95, - 0x6a, 0xa2, 0x48, 0xfe, 0x2c, 0x56, 0x6b, 0xe2, 0x45, 0x34, 0x71, 0xb5, 0x26, 0x4a, 0xb4, 0xd2, - 0x6a, 0x4d, 0x7c, 0x06, 0x4d, 0x53, 0xad, 0x89, 0xc7, 0x69, 0x15, 0xd5, 0x9a, 0xf8, 0x4c, 0x4a, - 0x46, 0xb1, 0x26, 0x9e, 0xa0, 0x69, 0xe4, 0x9a, 0x78, 0x31, 0xfd, 0x54, 0xae, 0x89, 0xd3, 0x94, - 0xb0, 0x62, 0x4d, 0x7c, 0x16, 0xfd, 0x23, 0xd7, 0x44, 0x44, 0x3f, 0xe5, 0x6a, 0xe2, 0x25, 0xe8, - 0x32, 0x18, 0x5f, 0xc0, 0x26, 0xc3, 0x17, 0x89, 0x20, 0x2c, 0x60, 0xd3, 0xbb, 0xda, 0xf8, 0xee, - 0x31, 0x18, 0x3f, 0xa7, 0x1b, 0xdb, 0xed, 0x96, 0x52, 0xc7, 0xe8, 0xe3, 0x6c, 0x9f, 0x2f, 0xdf, - 0x31, 0x0c, 0xac, 0x71, 0xe9, 0x1e, 0x0d, 0x6f, 0x26, 0xb3, 0x4b, 0x9b, 0x75, 0x4b, 0xf2, 0x99, - 0xb2, 0x5c, 0x0e, 0x13, 0xe7, 0xed, 0xd4, 0xa5, 0x86, 0x2d, 0x4e, 0x9e, 0xa8, 0xb0, 0x26, 0xb3, - 0xfe, 0x55, 0xc6, 0x6f, 0x02, 0xfa, 0x40, 0x12, 0x32, 0x0b, 0xd8, 0xcc, 0x35, 0x9b, 0x5e, 0xbe, - 0x3d, 0xe2, 0xe5, 0xdb, 0x1c, 0xcf, 0xb7, 0xeb, 0xfc, 0x1b, 0x91, 0x6b, 0x36, 0x7d, 0x78, 0x36, - 0x03, 0x47, 0x3d, 0x0c, 0x22, 0xd3, 0x72, 0xe1, 0x9a, 0x71, 0x99, 0x8b, 0x43, 0x6f, 0x77, 0xb8, - 0x56, 0xe4, 0xb8, 0x76, 0x53, 0x94, 0x0a, 0xe3, 0xe7, 0xd8, 0xa7, 0xdc, 0x1d, 0xa0, 0xcb, 0x02, - 0xad, 0x48, 0xe8, 0xf5, 0x03, 0x70, 0x31, 0xd0, 0x86, 0xd3, 0x5f, 0xf2, 0xa2, 0xf2, 0x70, 0x08, - 0x06, 0x98, 0x41, 0x78, 0xf8, 0x5f, 0x93, 0x20, 0x56, 0xb1, 0x59, 0x6a, 0x2f, 0xaa, 0x9b, 0x5b, - 0x4d, 0x75, 0x73, 0xcb, 0xc4, 0x0d, 0x74, 0x2f, 0x37, 0xee, 0xe8, 0xeb, 0xf7, 0xe3, 0xba, 0x59, - 0xb2, 0x17, 0x27, 0x4e, 0x58, 0xba, 0x12, 0x26, 0x55, 0x6f, 0x3e, 0xcb, 0xee, 0xc8, 0x47, 0xa2, - 0x97, 0x7b, 0x79, 0xbf, 0xc4, 0xf3, 0xfe, 0x85, 0x3e, 0xcc, 0xe8, 0xa6, 0xc8, 0x67, 0x8c, 0xfa, - 0x03, 0x87, 0xc7, 0x15, 0x8e, 0xc7, 0xb7, 0x0d, 0x56, 0xec, 0x48, 0xcc, 0xe2, 0xf6, 0xd2, 0xcf, - 0xb3, 0xc9, 0xd0, 0x25, 0x4c, 0x89, 0xfd, 0xc2, 0xf4, 0x3f, 0x12, 0xd1, 0xe5, 0x37, 0x68, 0xb1, - 0x17, 0x59, 0x3a, 0x87, 0xb0, 0x0e, 0x1b, 0x84, 0x5f, 0xbf, 0x29, 0x40, 0xa6, 0x78, 0xa1, 0xa5, - 0xf3, 0x3b, 0x62, 0x12, 0xa4, 0x5a, 0xee, 0x34, 0x97, 0xfe, 0x0f, 0xd1, 0x21, 0x3f, 0x36, 0x80, - 0x0e, 0x60, 0x75, 0xfb, 0xe8, 0x00, 0x9b, 0x8c, 0xa4, 0x87, 0x8c, 0xeb, 0x20, 0x4d, 0x3d, 0x69, - 0xac, 0x15, 0xb1, 0xbb, 0x84, 0xb6, 0x8b, 0x28, 0x92, 0xaf, 0x32, 0x4b, 0x14, 0x19, 0x85, 0x9e, - 0xe4, 0xc4, 0x8f, 0xc2, 0x9b, 0x5f, 0x93, 0x80, 0x4c, 0x85, 0xf6, 0x7a, 0xf4, 0xf2, 0x14, 0xa4, - 0x2a, 0x2d, 0xac, 0xa1, 0xf7, 0x7b, 0x0c, 0xf7, 0x97, 0xc2, 0x78, 0x5d, 0xd7, 0x4c, 0x7c, 0xc1, - 0xd5, 0x12, 0x6e, 0x04, 0xa7, 0x42, 0x92, 0x5d, 0x2a, 0x64, 0x1a, 0xb2, 0xa6, 0xc1, 0x20, 0xb3, - 0xbc, 0x72, 0xac, 0xa0, 0x54, 0x86, 0x19, 0x55, 0xab, 0x37, 0x3b, 0x0d, 0x2c, 0xe3, 0xa6, 0x42, - 0x68, 0x6f, 0xe7, 0xda, 0x05, 0xdc, 0xc2, 0x5a, 0x03, 0x6b, 0x26, 0xa3, 0xc6, 0xde, 0x8c, 0x08, - 0x91, 0x92, 0x9f, 0x24, 0xdf, 0xc1, 0xc3, 0xff, 0x5c, 0x8e, 0xdf, 0x2c, 0xc7, 0x2c, 0x69, 0xa5, - 0x0f, 0xf2, 0x67, 0x00, 0x58, 0x0b, 0xce, 0xaa, 0xf8, 0xbc, 0x65, 0x2d, 0x79, 0x56, 0x97, 0xb5, - 0xa4, 0xe2, 0x24, 0x90, 0x3d, 0x89, 0xd1, 0x9f, 0x39, 0x90, 0xdf, 0xcd, 0x41, 0x7e, 0x5d, 0x48, - 0x12, 0xa2, 0xa1, 0xfd, 0xff, 0x0f, 0x30, 0x99, 0xe6, 0x7c, 0x8a, 0x04, 0xe9, 0x59, 0xf0, 0x4c, - 0xdb, 0x0e, 0x50, 0x2e, 0x16, 0x0b, 0xd5, 0xb5, 0xd5, 0x95, 0x05, 0x39, 0x57, 0x28, 0x8a, 0x80, - 0x3e, 0x91, 0x84, 0x34, 0xdd, 0x35, 0x43, 0xf9, 0x21, 0xc8, 0x02, 0xfa, 0x51, 0x22, 0xec, 0x32, - 0xd5, 0x62, 0x0f, 0xad, 0xdb, 0x47, 0xc1, 0xbd, 0x25, 0x94, 0x75, 0x20, 0xa0, 0xa0, 0xf8, 0xbb, - 0x15, 0xe9, 0x4a, 0xd5, 0x2d, 0xfd, 0xfc, 0xff, 0xfb, 0x5d, 0x89, 0xb4, 0xf2, 0x90, 0xbb, 0x52, - 0x0f, 0x12, 0x9e, 0x4e, 0x5d, 0xe9, 0x91, 0x94, 0x33, 0x95, 0x7d, 0xd4, 0x23, 0x0d, 0x37, 0xb9, - 0x4e, 0x8b, 0x89, 0xe0, 0x9d, 0x55, 0x3b, 0x9d, 0x94, 0x83, 0x49, 0x55, 0x33, 0xb1, 0xa1, 0x29, - 0xcd, 0xf9, 0xa6, 0xb2, 0xc9, 0x26, 0xf8, 0x5e, 0xdb, 0x2c, 0xe3, 0x69, 0xc9, 0x93, 0x46, 0xe6, - 0x73, 0x48, 0x27, 0x01, 0x4c, 0xbc, 0xd3, 0x6a, 0x2a, 0xa6, 0x2b, 0x4c, 0x9e, 0x18, 0xf4, 0xc3, - 0xd0, 0x1e, 0x54, 0x76, 0xff, 0xea, 0xe3, 0x41, 0xe5, 0xc8, 0xb4, 0xd0, 0x25, 0xd3, 0xce, 0x70, - 0x9a, 0x0a, 0x31, 0x9c, 0x7a, 0xb9, 0x95, 0x0e, 0xc7, 0x2d, 0xf4, 0xd6, 0x50, 0x2e, 0x5a, 0x41, - 0xcd, 0x88, 0x5f, 0x4f, 0x3c, 0x2a, 0xc0, 0x14, 0xab, 0x7a, 0x4e, 0xd7, 0xb7, 0x77, 0x14, 0x63, - 0x1b, 0xdd, 0x7e, 0x10, 0x11, 0x41, 0x5f, 0xf0, 0xe2, 0xb7, 0xc0, 0xe3, 0x77, 0x93, 0x7f, 0xc3, - 0xed, 0xda, 0x43, 0xe0, 0xd8, 0xad, 0x9b, 0x6e, 0xe2, 0x9d, 0x6f, 0xc3, 0x10, 0xf9, 0x1e, 0x07, - 0x99, 0x7b, 0x38, 0x64, 0x5e, 0x18, 0x99, 0xc0, 0xf8, 0x11, 0x7a, 0xdc, 0x41, 0xc8, 0x56, 0x9b, - 0x07, 0x44, 0xe8, 0x3b, 0x83, 0x21, 0x64, 0xd7, 0x3e, 0x00, 0x42, 0x22, 0x08, 0xdb, 0x78, 0xcf, - 0xea, 0x80, 0xe4, 0xaf, 0x97, 0xec, 0x54, 0x7c, 0x98, 0xf9, 0x90, 0x3c, 0x12, 0xcc, 0x8e, 0xf3, - 0x24, 0x54, 0x5a, 0x43, 0x40, 0xee, 0xaf, 0xbd, 0xc8, 0x2d, 0xf3, 0xc8, 0xbd, 0xa8, 0x3f, 0x1b, - 0x18, 0x0d, 0xa3, 0xe9, 0x61, 0x1f, 0x70, 0xd0, 0x5a, 0xe1, 0xd0, 0xba, 0x7d, 0x40, 0x32, 0xe3, - 0xc7, 0xec, 0xeb, 0x29, 0x18, 0xb7, 0xfd, 0xda, 0x4c, 0xf4, 0xb1, 0x04, 0xb7, 0x9b, 0xdd, 0xd6, - 0x3b, 0x46, 0x9d, 0xb4, 0x41, 0xb8, 0x66, 0x5c, 0xb6, 0x42, 0x5e, 0xb6, 0x24, 0x43, 0x0e, 0xa0, - 0x7d, 0x46, 0xbf, 0xfd, 0x03, 0x6c, 0x2a, 0xea, 0x00, 0x8b, 0x5e, 0x2d, 0x84, 0x5d, 0x8a, 0x72, - 0xdc, 0xaf, 0x62, 0xf3, 0xe9, 0x38, 0x86, 0x7e, 0x2a, 0xd4, 0x2a, 0xb6, 0x4f, 0x4b, 0xa2, 0x09, - 0x4f, 0x65, 0x80, 0xc9, 0xd8, 0x25, 0x70, 0xb1, 0x9d, 0xa2, 0x32, 0x77, 0x4f, 0x31, 0x5f, 0x5b, - 0xa3, 0x33, 0xb1, 0x55, 0x79, 0x49, 0x14, 0xd0, 0x83, 0x29, 0x10, 0x19, 0x69, 0x8c, 0xce, 0xda, - 0x5e, 0x0b, 0xa3, 0x5f, 0x3b, 0xe4, 0x89, 0x18, 0xfa, 0xb1, 0x57, 0x99, 0x94, 0x78, 0x39, 0xb9, - 0xd9, 0x9f, 0xbb, 0x6e, 0x13, 0x7c, 0xc4, 0x65, 0x80, 0x5e, 0x11, 0x20, 0x61, 0xe8, 0x73, 0x8e, - 0x00, 0x2c, 0x71, 0x02, 0x70, 0xcb, 0x00, 0x24, 0x1e, 0xb2, 0x1c, 0x7c, 0x3e, 0x09, 0x93, 0xf6, - 0x34, 0x62, 0x1e, 0x9b, 0xf5, 0x2d, 0x74, 0x26, 0xec, 0xda, 0x4c, 0x04, 0xa1, 0x63, 0x34, 0x2d, - 0x2a, 0xc9, 0x5f, 0xf4, 0x8f, 0x89, 0xb0, 0x7b, 0x1e, 0x16, 0x6f, 0xb8, 0x9a, 0x7d, 0x16, 0xb6, - 0xe1, 0x76, 0x34, 0x42, 0x14, 0x18, 0xbf, 0xba, 0xfe, 0x56, 0x12, 0xa0, 0xa6, 0x3b, 0x93, 0xd6, - 0x03, 0x70, 0x92, 0x73, 0xb2, 0xce, 0xf3, 0x9c, 0xec, 0xb9, 0xa2, 0x77, 0xab, 0x8d, 0x3e, 0x96, - 0xa2, 0x77, 0x38, 0x2c, 0x9e, 0xe7, 0x58, 0x7c, 0x3a, 0x52, 0x4d, 0xf1, 0xf3, 0xf7, 0x13, 0x49, - 0x18, 0x2f, 0x74, 0x5a, 0x4d, 0xb5, 0x4e, 0xd6, 0x8d, 0xcf, 0x0d, 0xc9, 0x5e, 0xf4, 0x60, 0x32, - 0xe2, 0xe8, 0xe3, 0xd4, 0xe1, 0xc3, 0x4b, 0xe6, 0xba, 0x94, 0xb4, 0x5d, 0x97, 0x42, 0x9a, 0x35, - 0xfb, 0x14, 0x3e, 0x02, 0xf1, 0x14, 0xe0, 0x58, 0xa5, 0x85, 0xb5, 0x39, 0x03, 0x2b, 0x8d, 0xba, - 0xd1, 0xd9, 0x59, 0x6f, 0xa3, 0x5c, 0x58, 0x19, 0xf5, 0x58, 0x5b, 0x92, 0x9c, 0xb5, 0x05, 0xbd, - 0xcc, 0x3b, 0xb8, 0x2f, 0xf2, 0xec, 0x3d, 0xed, 0x67, 0xe5, 0xf3, 0xd0, 0x30, 0xc0, 0xe4, 0x2f, - 0x92, 0xd5, 0xb9, 0xcb, 0xe4, 0x92, 0x8a, 0x62, 0x72, 0x79, 0xaf, 0x83, 0xec, 0xbd, 0x1c, 0xb2, - 0x2f, 0x8a, 0xde, 0xae, 0x91, 0x6c, 0x1e, 0x4c, 0x55, 0xb1, 0xe9, 0x03, 0xef, 0x95, 0x30, 0xb9, - 0xee, 0x7e, 0x71, 0x20, 0xe6, 0x23, 0x89, 0x2a, 0x52, 0x9d, 0x4d, 0x52, 0xf2, 0x17, 0xbd, 0x3f, - 0xea, 0xd2, 0x8c, 0x27, 0xc1, 0x07, 0x5d, 0x07, 0xc1, 0x64, 0x98, 0x7d, 0x83, 0x48, 0xeb, 0xac, - 0xc0, 0xfa, 0xe3, 0x47, 0xe1, 0x7d, 0x02, 0x4c, 0x95, 0x76, 0x5a, 0xba, 0x61, 0x2e, 0x2b, 0xc6, - 0x36, 0x3d, 0xd5, 0xb8, 0x10, 0xb6, 0x93, 0x9d, 0x04, 0x50, 0x69, 0x56, 0x8f, 0x17, 0xa4, 0x27, - 0x06, 0x3d, 0x19, 0x15, 0x0b, 0x9e, 0x10, 0xff, 0xbd, 0x5d, 0x43, 0xd7, 0xcd, 0x25, 0x55, 0xdb, - 0x76, 0x37, 0xc8, 0xbd, 0x51, 0x11, 0x77, 0x79, 0x22, 0xa1, 0x15, 0x48, 0x61, 0xfc, 0x68, 0x7d, - 0x26, 0x09, 0x13, 0xd5, 0x2d, 0xc5, 0xc0, 0x73, 0x7b, 0xa4, 0xb1, 0x5d, 0x1e, 0x48, 0x7e, 0x3b, - 0xc1, 0xe8, 0x95, 0x5e, 0x20, 0x24, 0x48, 0x35, 0x55, 0x6d, 0xdb, 0xde, 0x9e, 0x23, 0xff, 0xdd, - 0xa3, 0xbd, 0xc9, 0x1e, 0x47, 0x7b, 0x1d, 0x13, 0xad, 0x53, 0xaf, 0xcf, 0xdc, 0xe7, 0x9d, 0xa1, - 0x8e, 0xf6, 0xf6, 0x2d, 0x2e, 0x7e, 0x36, 0x7e, 0x2d, 0x09, 0xc7, 0x72, 0x8d, 0xc6, 0x39, 0xd5, - 0xdc, 0xaa, 0xd8, 0x3c, 0xba, 0x2b, 0xdc, 0xa6, 0xfa, 0x34, 0x64, 0x5b, 0xca, 0x5e, 0x53, 0x57, - 0x9c, 0x81, 0xc5, 0x0a, 0xa2, 0x07, 0x92, 0x11, 0x07, 0x96, 0x2e, 0x0a, 0x7c, 0x98, 0x1a, 0x49, - 0xa7, 0x07, 0x17, 0x19, 0x3f, 0x63, 0xff, 0x22, 0x05, 0x99, 0x2a, 0x56, 0x8c, 0xfa, 0x16, 0x7a, - 0x53, 0xd2, 0x65, 0xe8, 0x3c, 0x64, 0x37, 0xd4, 0xa6, 0x89, 0x8d, 0x36, 0x5d, 0xff, 0x7b, 0xe7, - 0x31, 0x6c, 0x3c, 0x9b, 0x6b, 0xea, 0xf5, 0xed, 0xd9, 0x3c, 0xd1, 0x2c, 0x9a, 0x39, 0x6b, 0x9f, - 0x9b, 0x9a, 0x9d, 0xa7, 0x99, 0x64, 0x3b, 0xb3, 0x74, 0x37, 0xa4, 0xdb, 0xba, 0x61, 0xda, 0x6b, - 0xb5, 0x53, 0xe1, 0x4a, 0xa9, 0xea, 0x86, 0x29, 0xb3, 0x8c, 0x04, 0xda, 0x8d, 0x4e, 0xb3, 0x59, - 0xc3, 0x17, 0x4c, 0x7b, 0x9d, 0x64, 0x87, 0xa5, 0x13, 0x90, 0xd1, 0x37, 0x36, 0xda, 0x98, 0x2d, - 0xc5, 0xd3, 0xb2, 0x15, 0x92, 0x8e, 0x43, 0xba, 0xa9, 0xee, 0xa8, 0x26, 0x5d, 0x71, 0xa7, 0x65, - 0x16, 0x90, 0x4e, 0x81, 0xa8, 0x3b, 0xab, 0x24, 0x46, 0xe8, 0x74, 0x86, 0xea, 0xa2, 0x7d, 0xf1, - 0xa4, 0xcb, 0x6d, 0xe3, 0xbd, 0xf6, 0x74, 0x96, 0x7e, 0xa7, 0xff, 0xd1, 0x63, 0x51, 0xad, 0xf4, - 0x8c, 0xaf, 0xfe, 0x4b, 0x46, 0x03, 0xd7, 0x75, 0xa3, 0x61, 0xf3, 0xc6, 0x7f, 0xc9, 0x68, 0xa5, - 0x8b, 0x66, 0x5b, 0xef, 0x59, 0x79, 0xfc, 0xf2, 0xf4, 0x58, 0x06, 0xd2, 0x0b, 0x86, 0xd2, 0xda, - 0x42, 0xef, 0x4a, 0x0c, 0x5f, 0x9c, 0x1c, 0x60, 0x93, 0xfd, 0x80, 0x15, 0xfa, 0x00, 0x9b, 0xf2, - 0x00, 0xfb, 0x48, 0x12, 0x52, 0xc5, 0xc6, 0x26, 0xe6, 0x8c, 0x5e, 0x09, 0x8f, 0xd1, 0xeb, 0x04, - 0x64, 0x4c, 0xc5, 0xd8, 0xc4, 0xa6, 0xc5, 0x25, 0x2b, 0xe4, 0x78, 0x46, 0x09, 0x9e, 0xf3, 0x75, - 0x2f, 0x82, 0x14, 0x69, 0x17, 0x95, 0xc8, 0xa9, 0xd3, 0x57, 0xf4, 0x82, 0x86, 0xf2, 0x67, 0x96, - 0xd4, 0x38, 0x4b, 0x28, 0x93, 0x69, 0x86, 0x6e, 0x3c, 0xd2, 0xfb, 0xf0, 0x20, 0x63, 0xbb, 0x5a, - 0xd7, 0xb5, 0xd2, 0x8e, 0xb2, 0x89, 0xa7, 0x33, 0x6c, 0x6c, 0x77, 0x22, 0xec, 0xaf, 0xc5, 0x1d, - 0xfd, 0x7e, 0x75, 0x3a, 0xeb, 0x7e, 0xa5, 0x11, 0xa4, 0x09, 0x5b, 0x6a, 0xa3, 0x81, 0xb5, 0xe9, - 0x31, 0x76, 0x3a, 0x85, 0x85, 0x66, 0x4e, 0x42, 0x8a, 0xd0, 0x40, 0x30, 0x26, 0x8a, 0x5d, 0x3c, - 0x22, 0x1d, 0x25, 0x52, 0xce, 0xac, 0x92, 0x62, 0x02, 0x7d, 0x29, 0x19, 0x71, 0x0f, 0x99, 0x35, - 0xae, 0xb7, 0xcc, 0x5f, 0x0f, 0x69, 0x4d, 0x6f, 0xe0, 0xbe, 0x12, 0xcf, 0x52, 0x49, 0xcf, 0x87, - 0x34, 0x6e, 0x6c, 0xe2, 0x36, 0x05, 0x73, 0xe2, 0xf4, 0xc9, 0x60, 0x5e, 0xca, 0x2c, 0x71, 0xb4, - 0x8d, 0xea, 0x5e, 0xd4, 0xc6, 0xdf, 0x49, 0xfe, 0x57, 0x06, 0x8e, 0xb1, 0xfe, 0x59, 0xed, 0xac, - 0x93, 0xa2, 0xd6, 0x31, 0x7a, 0x8d, 0xc0, 0x1d, 0xe8, 0x6d, 0x77, 0xd6, 0x9d, 0xb1, 0x8c, 0x05, - 0xbc, 0x9d, 0x28, 0x39, 0x14, 0x9d, 0x2c, 0x0c, 0xaa, 0x93, 0x39, 0xfd, 0x2a, 0xd8, 0xdd, 0xd0, - 0xd5, 0xc6, 0x19, 0x1a, 0x6d, 0x6b, 0xe3, 0x1e, 0xba, 0x94, 0x0c, 0xca, 0xca, 0x86, 0x89, 0x8d, - 0x52, 0x83, 0xca, 0xe3, 0xb8, 0x6c, 0x07, 0x89, 0xbe, 0x5f, 0xc7, 0x1b, 0xba, 0x41, 0x16, 0x82, - 0xe3, 0x4c, 0xdf, 0xdb, 0x61, 0x4f, 0xff, 0x04, 0xce, 0x28, 0x7d, 0x0d, 0x1c, 0x53, 0x37, 0x35, - 0xdd, 0xc0, 0x8e, 0x67, 0xcf, 0xf4, 0x51, 0x76, 0x12, 0xb5, 0x2b, 0x5a, 0xba, 0x0e, 0x2e, 0xd2, - 0xf4, 0x02, 0x6e, 0x59, 0x7c, 0x67, 0xa8, 0x4e, 0xd2, 0x1e, 0xb1, 0xff, 0x03, 0xfa, 0x62, 0xd4, - 0x95, 0x67, 0x17, 0xa8, 0x43, 0x53, 0xfd, 0xd2, 0x6d, 0x70, 0xb4, 0x61, 0x79, 0x0d, 0xd4, 0x55, - 0xa7, 0x47, 0xf8, 0xe6, 0xe3, 0x12, 0xbb, 0xe2, 0x94, 0xf2, 0x8a, 0xd3, 0x02, 0x8c, 0x51, 0x57, - 0x73, 0x22, 0x4f, 0xe9, 0xae, 0xc3, 0x8c, 0x74, 0xba, 0xed, 0x34, 0xca, 0xc3, 0x92, 0xd9, 0xbc, - 0x95, 0x45, 0x76, 0x32, 0x47, 0x9b, 0xef, 0x04, 0x73, 0x28, 0xfe, 0xae, 0xf7, 0xb7, 0x02, 0x9c, - 0xb0, 0xd5, 0x1b, 0xa3, 0xa5, 0xa0, 0xb6, 0x4d, 0x55, 0xab, 0x9b, 0xa8, 0xcd, 0x39, 0x10, 0x1a, - 0x56, 0xa2, 0x7b, 0xf1, 0x9e, 0xed, 0x40, 0xe8, 0x89, 0x1a, 0x56, 0x67, 0x44, 0x5f, 0xf1, 0xea, - 0xd7, 0x0a, 0x2f, 0x62, 0x67, 0x7a, 0x31, 0xb0, 0x37, 0xf1, 0x3e, 0x92, 0x96, 0x87, 0xcc, 0xa6, - 0xa1, 0x77, 0x5a, 0x36, 0x91, 0xd7, 0x86, 0x23, 0x72, 0x81, 0xe4, 0x91, 0xad, 0xac, 0xe8, 0x71, - 0x07, 0x5f, 0x99, 0xc3, 0xf7, 0xce, 0x81, 0xc9, 0x1b, 0x81, 0xa9, 0x22, 0x05, 0x47, 0x1d, 0x21, - 0x2b, 0x35, 0xda, 0x48, 0xef, 0xa7, 0x5d, 0xf7, 0x19, 0x26, 0x1c, 0xbd, 0x25, 0x78, 0xf4, 0x56, - 0x0f, 0x4d, 0x33, 0xd1, 0x53, 0xd3, 0xa0, 0x07, 0x84, 0xb0, 0xd7, 0x2f, 0xf0, 0xdd, 0x8c, 0x92, - 0xfb, 0x74, 0x56, 0x1c, 0x21, 0x2f, 0x81, 0xe8, 0xdf, 0xaa, 0xf8, 0xa5, 0xe0, 0x89, 0x24, 0x5c, - 0xc4, 0x04, 0x71, 0x55, 0x6b, 0x3b, 0x23, 0x2d, 0x7f, 0x66, 0x97, 0xb6, 0xa9, 0xed, 0xec, 0x72, - 0xd2, 0x10, 0x6f, 0xd1, 0xbd, 0x87, 0x07, 0xef, 0xf9, 0xfe, 0x6a, 0xcd, 0x53, 0x8b, 0xcf, 0xda, - 0xf0, 0xf7, 0x1d, 0xde, 0x2d, 0x73, 0xbc, 0x3b, 0x33, 0x48, 0xa1, 0xf1, 0x33, 0xf0, 0x75, 0x02, - 0x8c, 0x57, 0xb1, 0xb9, 0xa4, 0xec, 0xe9, 0x1d, 0x13, 0x29, 0x61, 0xcd, 0x4c, 0xb7, 0x40, 0xa6, - 0x49, 0xb3, 0xd0, 0x99, 0xf1, 0xd4, 0xe9, 0xcb, 0x7b, 0x1a, 0x43, 0xe9, 0x66, 0x15, 0x2b, 0x5a, - 0xb6, 0xd2, 0xa3, 0xb7, 0x45, 0x35, 0xa5, 0x3b, 0xd4, 0x0d, 0xc5, 0x0e, 0x18, 0xc9, 0xd0, 0xee, - 0x57, 0x75, 0xfc, 0xb0, 0xbc, 0x4c, 0x80, 0x49, 0xea, 0x7a, 0x3f, 0xaf, 0xec, 0xea, 0x86, 0x6a, - 0xe2, 0x68, 0x16, 0x40, 0x27, 0x9b, 0x75, 0xbe, 0xc0, 0x13, 0x83, 0xde, 0x97, 0x8c, 0xb8, 0xc5, - 0xc6, 0xd1, 0x31, 0x14, 0x10, 0x22, 0x6d, 0xc8, 0x05, 0x55, 0x3f, 0x42, 0x20, 0x72, 0x46, 0x7d, - 0x4b, 0xdd, 0xc5, 0x8d, 0x88, 0x40, 0xd8, 0xd9, 0x5c, 0x20, 0x9c, 0x82, 0x06, 0x03, 0xc2, 0xce, - 0x7e, 0x48, 0x40, 0xf8, 0x54, 0x1f, 0x3f, 0x10, 0xef, 0x61, 0x40, 0x78, 0x7c, 0x0d, 0x96, 0xc3, - 0x02, 0x71, 0x25, 0x4c, 0xba, 0x56, 0x82, 0x55, 0xa3, 0x69, 0xad, 0xe6, 0xf9, 0x48, 0xf4, 0xb9, - 0x01, 0xe0, 0xe8, 0xeb, 0x36, 0x10, 0x0d, 0x8e, 0xcf, 0x46, 0x84, 0xe3, 0xe9, 0xea, 0x12, 0xf0, - 0xa4, 0xc0, 0x4e, 0x48, 0x71, 0x9e, 0x19, 0xf7, 0x87, 0x85, 0x6b, 0x9f, 0x17, 0x48, 0x36, 0xb2, - 0x17, 0xc8, 0x17, 0xa2, 0x7a, 0x81, 0x74, 0x53, 0x3b, 0x14, 0x38, 0x23, 0x39, 0x79, 0xf4, 0xa1, - 0xe0, 0x90, 0x11, 0xfd, 0x81, 0x00, 0x40, 0xef, 0xfe, 0x64, 0xfe, 0x4b, 0x8b, 0x90, 0x61, 0x7f, - 0x6d, 0x27, 0xc8, 0x84, 0xeb, 0x04, 0x79, 0x1d, 0xa4, 0x77, 0x95, 0x66, 0x07, 0x3b, 0x3c, 0xea, - 0x9e, 0x88, 0x9e, 0x25, 0x5f, 0x65, 0x96, 0x08, 0x6d, 0x85, 0x95, 0x8a, 0xbb, 0xbc, 0x0e, 0x38, - 0x44, 0x1e, 0xae, 0xf2, 0xe1, 0xa2, 0x45, 0xe3, 0x2c, 0xfb, 0x75, 0x7d, 0xae, 0xde, 0x11, 0xd5, - 0x21, 0xc2, 0x53, 0xd6, 0x30, 0xa4, 0x21, 0x92, 0x8b, 0x84, 0x6f, 0xdd, 0xf1, 0x2b, 0xda, 0x2f, - 0x24, 0x21, 0x5d, 0xd3, 0xab, 0x98, 0x3b, 0x3f, 0x16, 0x8c, 0x8d, 0x6b, 0xb5, 0x49, 0x7a, 0xad, - 0x36, 0x11, 0x2e, 0x60, 0x75, 0x3c, 0x43, 0xfc, 0x1d, 0xf6, 0xc8, 0x52, 0x05, 0xbb, 0x5b, 0xf9, - 0x2c, 0x10, 0xcd, 0x16, 0xd8, 0xab, 0xf8, 0xf8, 0x19, 0x7a, 0x06, 0x8e, 0xad, 0x6a, 0x0d, 0x5d, - 0xc6, 0x0d, 0xdd, 0xb2, 0xad, 0x90, 0x85, 0x67, 0x47, 0x6b, 0xe8, 0x94, 0xd6, 0xb4, 0x4c, 0xff, - 0x93, 0x38, 0x03, 0x37, 0x74, 0xcb, 0xf0, 0x4d, 0xff, 0xa3, 0x37, 0x0b, 0x90, 0x22, 0x79, 0xc3, - 0x7b, 0xaa, 0xfc, 0x30, 0xea, 0x41, 0x13, 0x52, 0xfc, 0x30, 0xe4, 0x5b, 0xba, 0xcb, 0x63, 0x6d, - 0x62, 0x9b, 0xbc, 0x57, 0xf8, 0xd5, 0xe7, 0x61, 0x85, 0xc7, 0xca, 0xf4, 0x78, 0x94, 0xc3, 0x29, - 0x3d, 0xc8, 0x8e, 0x86, 0x64, 0x61, 0x00, 0x15, 0x29, 0xc2, 0xd1, 0x7c, 0xae, 0x4c, 0x6f, 0x4b, - 0x58, 0xae, 0x9c, 0x2d, 0x8a, 0x02, 0x05, 0x88, 0xb4, 0x26, 0x46, 0x80, 0x48, 0xf1, 0xff, 0x04, - 0x01, 0xea, 0x41, 0xf6, 0x61, 0x00, 0xf4, 0xf9, 0x24, 0x4c, 0x2e, 0xa9, 0x6d, 0xd3, 0xcf, 0xe9, - 0xcb, 0xde, 0x44, 0xb6, 0xed, 0x03, 0x6e, 0x04, 0x7f, 0xd1, 0x76, 0x98, 0x09, 0x21, 0x57, 0x8f, - 0x0f, 0x64, 0xfb, 0xbd, 0x63, 0x22, 0xcd, 0xc1, 0x83, 0xaa, 0x18, 0x8d, 0x77, 0x22, 0xa5, 0x80, - 0x5d, 0x8d, 0x16, 0x9a, 0x93, 0x91, 0x87, 0x5e, 0xb7, 0x92, 0xd1, 0x0f, 0xbd, 0xbe, 0x75, 0x8f, - 0xc0, 0x74, 0x9d, 0x84, 0x8b, 0x48, 0xf5, 0x41, 0x0b, 0x4e, 0x7f, 0x36, 0xf7, 0x5d, 0x70, 0x46, - 0xb6, 0x79, 0xed, 0xa3, 0x65, 0x18, 0x36, 0xaf, 0x7e, 0x85, 0x8e, 0x98, 0xcd, 0x3e, 0x06, 0x96, - 0x7e, 0x6c, 0x0e, 0x30, 0xb0, 0x0c, 0xce, 0xe6, 0x60, 0x23, 0xcb, 0x80, 0x6c, 0x3e, 0x34, 0xd3, - 0xc9, 0x37, 0x92, 0x30, 0x99, 0x6b, 0xb5, 0x9a, 0x7b, 0x35, 0xeb, 0x24, 0x48, 0x24, 0xd3, 0x89, - 0xe7, 0x40, 0x49, 0x72, 0xdf, 0x71, 0xca, 0xc8, 0x6e, 0xe2, 0x1c, 0x1d, 0xc3, 0x70, 0x13, 0x0f, - 0x2a, 0x30, 0x7e, 0xd6, 0xbe, 0x32, 0xcd, 0x14, 0xb1, 0x75, 0xd1, 0xc3, 0xd7, 0x12, 0xc1, 0x37, - 0x3d, 0x70, 0xf2, 0x9c, 0xec, 0x96, 0xe7, 0x3b, 0x20, 0xb3, 0xa1, 0x1b, 0x3b, 0x8a, 0x6d, 0xcb, - 0xbd, 0xca, 0x4f, 0x9c, 0xac, 0xbb, 0x14, 0xe6, 0x69, 0x62, 0xd9, 0xca, 0x44, 0x46, 0xb4, 0x97, - 0xa8, 0x2d, 0xeb, 0x2c, 0x34, 0xf9, 0x4b, 0x2f, 0x39, 0x61, 0x47, 0xa2, 0xcb, 0xb8, 0x6d, 0xe2, - 0x06, 0xdd, 0x7c, 0x1c, 0x93, 0xf9, 0x48, 0x69, 0x06, 0x8e, 0x5a, 0x11, 0xf3, 0x6a, 0x13, 0xb7, - 0xe9, 0x96, 0xf2, 0x98, 0xcc, 0xc5, 0xa1, 0x2f, 0x0f, 0x32, 0x70, 0x44, 0xbe, 0x81, 0x62, 0x1a, - 0xb2, 0xed, 0x4e, 0xbd, 0x8e, 0x71, 0xc3, 0xf2, 0x32, 0xb2, 0x83, 0x11, 0xbd, 0x16, 0x23, 0x0f, - 0x33, 0x87, 0x73, 0x39, 0xc5, 0xcc, 0x0a, 0x64, 0x18, 0x86, 0xd2, 0x51, 0x18, 0xb3, 0xfd, 0x26, - 0x99, 0x5f, 0xc8, 0x8a, 0xb5, 0x48, 0x17, 0x13, 0xa4, 0xc4, 0x7b, 0xaa, 0x95, 0x32, 0xbb, 0xb0, - 0xab, 0x50, 0xb1, 0x2e, 0xec, 0xaa, 0x9e, 0x5d, 0x10, 0x53, 0xd2, 0x14, 0xc0, 0x82, 0x9c, 0x5b, - 0x59, 0x5c, 0xa3, 0x29, 0xd2, 0xe8, 0xc9, 0x2c, 0x64, 0x98, 0x1b, 0x26, 0x7a, 0x22, 0xed, 0x7d, - 0x30, 0xe5, 0xa8, 0xa6, 0x13, 0x32, 0x57, 0x14, 0x43, 0xd9, 0x69, 0x07, 0xed, 0x8d, 0xb1, 0xdc, - 0xce, 0x63, 0x29, 0x65, 0x4f, 0xb6, 0xc5, 0x23, 0x32, 0x57, 0x8c, 0xf4, 0x2f, 0xe0, 0xd8, 0xba, - 0x75, 0x80, 0xa0, 0x6d, 0x95, 0x9c, 0xf4, 0xdf, 0xb1, 0xef, 0x2a, 0x79, 0x8e, 0xcf, 0xb9, 0x78, - 0x44, 0xee, 0x2e, 0x4c, 0x2a, 0xc1, 0x78, 0x5b, 0x53, 0x5a, 0xed, 0x2d, 0xdd, 0x71, 0xa1, 0xb8, - 0x36, 0x44, 0xc9, 0x55, 0x2b, 0x8f, 0xec, 0xe6, 0x96, 0x9e, 0x0f, 0xcf, 0xec, 0xd0, 0x1b, 0xde, - 0x8a, 0x17, 0xe8, 0x46, 0xe9, 0x26, 0x7f, 0x75, 0x40, 0xef, 0x8f, 0xd2, 0x6d, 0x96, 0x87, 0x51, - 0x9a, 0x8a, 0xcf, 0x73, 0x43, 0xd4, 0xed, 0xf1, 0x32, 0xba, 0x0d, 0x52, 0x3b, 0x44, 0xf6, 0x32, - 0xa1, 0x33, 0x2f, 0x53, 0x81, 0x23, 0x99, 0xd0, 0x0c, 0x1c, 0xf5, 0xb2, 0xbe, 0x97, 0x36, 0x41, - 0x57, 0xc0, 0xb1, 0x2e, 0x26, 0xda, 0xc7, 0x4f, 0x12, 0xee, 0xf1, 0x93, 0x5f, 0x85, 0x31, 0x9b, - 0x1f, 0xfb, 0xee, 0x69, 0xcd, 0xc1, 0x98, 0xcd, 0x21, 0x0b, 0xb8, 0xab, 0xba, 0x6c, 0x7b, 0xd5, - 0x1d, 0xc5, 0x30, 0xe9, 0xd6, 0xb5, 0x5d, 0xc8, 0x9c, 0xd2, 0xc6, 0xb2, 0x93, 0x6d, 0xe6, 0x7a, - 0x48, 0x11, 0xaa, 0x25, 0x09, 0xa6, 0x72, 0x4b, 0x4b, 0x6b, 0x15, 0x7a, 0x47, 0xf0, 0x62, 0xa9, - 0xbc, 0xc0, 0x3a, 0x40, 0x69, 0xa1, 0x5c, 0x91, 0x8b, 0x4c, 0xfe, 0xab, 0x62, 0x62, 0xe6, 0x72, - 0xcb, 0x07, 0x0a, 0x20, 0xc3, 0x9a, 0xc7, 0xa4, 0xbd, 0x78, 0x81, 0x19, 0xdc, 0x44, 0x7a, 0x75, - 0x79, 0x8b, 0xb6, 0x85, 0x37, 0x5a, 0x84, 0x71, 0x02, 0x74, 0xb8, 0xd9, 0x6b, 0x50, 0xf9, 0x48, - 0x14, 0x8f, 0xbe, 0x9e, 0x25, 0x45, 0xd3, 0x07, 0xf3, 0xfb, 0xf4, 0x81, 0x04, 0x53, 0xa5, 0x72, - 0xad, 0x28, 0x97, 0x73, 0x4b, 0x8e, 0x42, 0xd8, 0xa7, 0x23, 0x92, 0xbc, 0x8e, 0x10, 0xd0, 0xb7, - 0x05, 0x00, 0x46, 0x0e, 0x51, 0x54, 0xde, 0xeb, 0xd5, 0xbe, 0x16, 0x55, 0x27, 0xbb, 0xc5, 0xf8, - 0xe8, 0xe4, 0x12, 0x8c, 0x19, 0xd6, 0x07, 0xcb, 0xb6, 0xd7, 0xaf, 0x1c, 0xf6, 0xd7, 0x2e, 0x4d, - 0x76, 0xb2, 0xa3, 0x8f, 0x47, 0x51, 0xc1, 0xbe, 0x84, 0x1d, 0x0e, 0xcb, 0x9b, 0xb6, 0xd7, 0xbf, - 0x67, 0x66, 0xc3, 0xf4, 0x40, 0xb8, 0x36, 0xf0, 0x99, 0x3d, 0x2a, 0x61, 0x46, 0xda, 0x2f, 0xfe, - 0xe8, 0x33, 0xc7, 0x60, 0x8a, 0x95, 0xe1, 0x1c, 0xc0, 0xff, 0x87, 0x24, 0x08, 0xb9, 0x06, 0x77, - 0x97, 0x59, 0xf0, 0x34, 0x6d, 0x06, 0x8e, 0x7a, 0x3c, 0x66, 0x9c, 0x8b, 0xf1, 0xbc, 0x71, 0xfc, - 0xab, 0x2a, 0x81, 0xcf, 0x55, 0xf1, 0xd4, 0xcc, 0xe6, 0x1a, 0xc3, 0xd9, 0xe3, 0x8a, 0xe2, 0x01, - 0x1f, 0x50, 0x79, 0xfc, 0x93, 0xba, 0x07, 0xdd, 0x4b, 0xc7, 0x87, 0x8a, 0x40, 0xd4, 0xe3, 0x37, - 0x0e, 0x13, 0xc2, 0xad, 0xc0, 0x87, 0x7e, 0xa0, 0x23, 0xb8, 0xfe, 0xf8, 0x71, 0xf8, 0x85, 0x65, - 0x32, 0xca, 0xed, 0x2a, 0x6a, 0x53, 0x59, 0x6f, 0x46, 0x38, 0x27, 0xf8, 0x19, 0x2f, 0xab, 0xcb, - 0x3c, 0xab, 0x6f, 0x09, 0x6a, 0x2a, 0x57, 0x9f, 0xef, 0xbd, 0xf0, 0xe3, 0x36, 0xae, 0xae, 0x77, - 0x10, 0x3f, 0x6e, 0xda, 0xe5, 0xc9, 0x6e, 0x4a, 0xf4, 0x87, 0x0e, 0xeb, 0x7f, 0x89, 0x63, 0xfd, - 0x1d, 0x83, 0xd2, 0x13, 0x3f, 0x02, 0xaf, 0x12, 0x60, 0x22, 0xd7, 0x68, 0xcc, 0x63, 0xc5, 0xec, - 0x18, 0xb8, 0x81, 0x8a, 0x61, 0xbb, 0xc3, 0xa5, 0xdd, 0x2c, 0x1a, 0xf7, 0x72, 0xe2, 0x63, 0xa1, - 0xaf, 0x55, 0xdc, 0xaf, 0x0d, 0x6c, 0x5a, 0x86, 0xa2, 0x92, 0xc2, 0x5d, 0xc2, 0x18, 0x9a, 0x88, - 0xf8, 0x01, 0x79, 0xbd, 0x00, 0x53, 0x32, 0xbd, 0x94, 0x7c, 0xd8, 0x98, 0x7c, 0x32, 0xa2, 0x77, - 0xa4, 0xe7, 0xf2, 0x13, 0x2f, 0x39, 0x43, 0x81, 0x25, 0x8a, 0x1b, 0x64, 0x38, 0x3a, 0xe2, 0x47, - 0xe6, 0x47, 0x00, 0xe0, 0xf1, 0x89, 0xf8, 0x36, 0xb8, 0xbe, 0xfd, 0xe8, 0x0b, 0x02, 0x1b, 0xcf, - 0xab, 0xdc, 0x11, 0x4e, 0xde, 0x15, 0x22, 0xd1, 0xc3, 0x15, 0x22, 0xd4, 0xa8, 0xf2, 0x93, 0x88, - 0x5b, 0xec, 0x96, 0x97, 0x42, 0xdf, 0xc1, 0x7d, 0x40, 0x2d, 0xf7, 0x54, 0x84, 0xbd, 0xf6, 0x7e, - 0xa4, 0xc4, 0xff, 0x0c, 0x46, 0xd0, 0x5e, 0xbb, 0x34, 0x0d, 0xc7, 0xe5, 0x62, 0xae, 0x50, 0x29, - 0x2f, 0xdd, 0xe7, 0xfd, 0x2a, 0xa6, 0xd0, 0x5b, 0x04, 0xc8, 0x30, 0x79, 0x8b, 0x07, 0xd3, 0xff, - 0x10, 0x51, 0x41, 0xf2, 0x8c, 0x64, 0x94, 0xf9, 0xac, 0x83, 0xfe, 0x53, 0x04, 0x95, 0x17, 0xa2, - 0xd8, 0xa7, 0x2d, 0x44, 0xdf, 0x12, 0x20, 0x45, 0x57, 0x4c, 0x9d, 0xa8, 0x00, 0x15, 0xe0, 0x32, - 0xa5, 0xd5, 0xc2, 0x5a, 0xc3, 0xb9, 0x47, 0x70, 0xde, 0xd0, 0x77, 0x2a, 0xe6, 0x16, 0x36, 0x48, - 0x92, 0xb6, 0x65, 0x69, 0x0e, 0x4e, 0x84, 0xbe, 0x15, 0xd1, 0xf8, 0xcc, 0xf3, 0x3a, 0x60, 0x91, - 0x76, 0x66, 0x7f, 0xbf, 0xbc, 0xc4, 0xa7, 0x5f, 0x2e, 0xa9, 0xda, 0xb6, 0xb7, 0x6f, 0xfe, 0x59, - 0x04, 0xbb, 0x75, 0x5f, 0x7a, 0x0e, 0xd9, 0x11, 0xe6, 0x81, 0x8c, 0x47, 0xc1, 0xbe, 0x5c, 0x00, - 0x91, 0x90, 0xc8, 0x44, 0xd4, 0xba, 0x0c, 0xab, 0xc2, 0xef, 0x23, 0xd0, 0x48, 0xef, 0x3e, 0x82, - 0x1d, 0x21, 0x5d, 0x0d, 0x53, 0xf5, 0x2d, 0x5c, 0xdf, 0x2e, 0x69, 0xb6, 0x51, 0x88, 0x21, 0xdc, - 0x15, 0xcb, 0x7b, 0xcc, 0xde, 0xcb, 0x43, 0xca, 0xdb, 0xa6, 0x39, 0xbe, 0x79, 0x89, 0xf2, 0xe9, - 0x94, 0x2e, 0x30, 0x65, 0x0e, 0x98, 0x5b, 0x07, 0x2a, 0x35, 0x1a, 0x32, 0xe5, 0xc1, 0x1e, 0x2d, - 0xa8, 0xac, 0xd0, 0x57, 0xbe, 0x56, 0xab, 0xc5, 0xc2, 0xda, 0x9c, 0xdd, 0xf9, 0xaa, 0xa2, 0x80, - 0x7e, 0x90, 0x84, 0x2c, 0x23, 0xab, 0xdd, 0x75, 0x51, 0x74, 0xf0, 0x39, 0x0f, 0xf4, 0x81, 0xd0, - 0x0e, 0xc9, 0x0e, 0x23, 0xac, 0x7a, 0x7c, 0x7a, 0xca, 0x2d, 0x90, 0x65, 0x20, 0xdb, 0x66, 0xc9, - 0x93, 0x3e, 0xfd, 0xc4, 0x2a, 0x46, 0xb6, 0x93, 0x87, 0x74, 0x4e, 0xee, 0x43, 0x46, 0xfc, 0x73, - 0x8e, 0x77, 0x4e, 0x40, 0x76, 0x51, 0x6d, 0x9b, 0xba, 0xb1, 0x87, 0xde, 0x91, 0x80, 0xac, 0xf5, - 0xc0, 0xf7, 0x3e, 0x3b, 0xdf, 0xe5, 0x30, 0xd1, 0x32, 0xf0, 0xae, 0xaa, 0x77, 0xda, 0x9e, 0x5b, - 0x01, 0x3c, 0x51, 0x12, 0x82, 0x31, 0xa5, 0x63, 0x6e, 0xe9, 0x86, 0x7b, 0x45, 0x92, 0x1d, 0x96, - 0x4e, 0x02, 0xb0, 0xff, 0x65, 0x65, 0x07, 0x5b, 0xe7, 0x13, 0x3c, 0x31, 0x92, 0x04, 0x29, 0x53, - 0xdd, 0xc1, 0xd6, 0x09, 0x35, 0xfa, 0x5f, 0x9a, 0x86, 0x2c, 0x3d, 0xd2, 0x52, 0x6a, 0x58, 0x27, - 0xd4, 0xec, 0x20, 0x7a, 0xb7, 0x00, 0x13, 0xee, 0x5b, 0xe4, 0x6d, 0xaf, 0xa7, 0x7b, 0x9f, 0xfb, - 0xda, 0x9b, 0x4a, 0xdb, 0xce, 0xe6, 0xec, 0x45, 0xf1, 0x91, 0xee, 0x69, 0x39, 0xc1, 0x73, 0x68, - 0x15, 0x7d, 0x24, 0x19, 0xf6, 0x7c, 0x88, 0xc5, 0x4c, 0xcf, 0x63, 0xe9, 0xfe, 0xb2, 0x35, 0x66, - 0xbd, 0xce, 0x6e, 0x2b, 0xe1, 0x4b, 0x7b, 0x96, 0x64, 0x15, 0x23, 0x3b, 0xa9, 0x43, 0x9e, 0xe9, - 0xe8, 0x4f, 0x49, 0xfc, 0xe2, 0xf5, 0x53, 0x01, 0x26, 0xaa, 0x5b, 0xfa, 0x79, 0xfb, 0xe9, 0xfb, - 0x5f, 0x0d, 0x07, 0xd5, 0xa5, 0x30, 0xbe, 0xdb, 0x05, 0x93, 0x1b, 0xe1, 0x7f, 0xd5, 0x2f, 0x7a, - 0x58, 0x88, 0x0a, 0x93, 0x87, 0xb8, 0xa1, 0x5f, 0xd1, 0x2b, 0xbd, 0xd0, 0x7d, 0x8e, 0x9f, 0x59, - 0x56, 0x82, 0x01, 0xf6, 0x3e, 0xd6, 0x6f, 0x37, 0x30, 0xc5, 0x37, 0x30, 0x1a, 0xf2, 0xfe, 0x8d, - 0x1b, 0xc1, 0x55, 0x05, 0x49, 0xea, 0x65, 0x6a, 0x03, 0x9f, 0x1f, 0x02, 0xf0, 0xe8, 0x67, 0x89, - 0xb0, 0xf6, 0x47, 0x87, 0x03, 0x0e, 0x05, 0x07, 0xba, 0x53, 0xa3, 0x6f, 0x71, 0xf1, 0xf3, 0xf3, - 0x37, 0x2e, 0x82, 0xd4, 0xbc, 0xda, 0xc4, 0x64, 0xfd, 0x9e, 0xad, 0x6c, 0x6c, 0xd0, 0x3b, 0x31, - 0x8a, 0xfe, 0x0f, 0xe8, 0x9d, 0x02, 0xd1, 0xde, 0xa3, 0xd5, 0xcd, 0x15, 0x55, 0xd3, 0x1c, 0x37, - 0x92, 0x7d, 0xf1, 0xbc, 0xa9, 0x2b, 0xd0, 0xb7, 0x93, 0x50, 0x30, 0x6b, 0xd5, 0xee, 0xd3, 0x5f, - 0xae, 0x86, 0xa9, 0xf5, 0x3d, 0x13, 0xb7, 0xad, 0x54, 0x56, 0xb5, 0x29, 0xb9, 0x2b, 0x16, 0x3d, - 0x19, 0xca, 0xdb, 0x33, 0xa0, 0xc2, 0x68, 0x3c, 0x57, 0x86, 0xf4, 0x08, 0xff, 0x26, 0x7d, 0x5e, - 0xab, 0xb4, 0xc4, 0x62, 0xef, 0x2b, 0xd6, 0xd6, 0x56, 0x4a, 0xe5, 0x72, 0xb1, 0x20, 0x6e, 0xa1, - 0x4f, 0x08, 0x30, 0x41, 0xe6, 0x55, 0x36, 0x3a, 0x15, 0xee, 0x75, 0x32, 0x5d, 0x6b, 0xee, 0xb9, - 0x73, 0x47, 0x3b, 0x18, 0x09, 0xa7, 0xff, 0x18, 0x7a, 0x7a, 0x43, 0xd9, 0xe6, 0xa1, 0xc5, 0x1f, - 0xab, 0x0d, 0xb5, 0xd9, 0x8d, 0x55, 0x5a, 0xee, 0x8a, 0xed, 0x81, 0xa9, 0xd0, 0x13, 0xd3, 0x3f, - 0x0a, 0x35, 0xe9, 0xe9, 0x43, 0x5c, 0x34, 0x5c, 0x17, 0x87, 0x85, 0x2b, 0xfa, 0xb1, 0x00, 0x99, - 0xd5, 0x16, 0x45, 0xee, 0x29, 0x8f, 0x13, 0xc6, 0xbe, 0xfd, 0x50, 0xa2, 0xa4, 0x9a, 0xfc, 0x73, - 0xcc, 0xb2, 0x1b, 0x21, 0xdd, 0x6a, 0x6d, 0xf4, 0x30, 0x07, 0x8c, 0xab, 0x03, 0xcf, 0xf0, 0x52, - 0x4e, 0x78, 0xf6, 0x7b, 0xaf, 0x83, 0x8b, 0x1a, 0x6a, 0x5b, 0x59, 0x6f, 0xe2, 0xa2, 0x56, 0x37, - 0xf6, 0x58, 0xa3, 0xd9, 0xf6, 0xf2, 0xfe, 0x0f, 0xd2, 0x1d, 0x90, 0x6e, 0x9b, 0x7b, 0xcd, 0xfd, - 0x7b, 0xcb, 0xbe, 0x55, 0x55, 0x49, 0x72, 0x99, 0xe5, 0x42, 0xbf, 0x48, 0x84, 0xf5, 0x5e, 0xa5, - 0x79, 0x19, 0x6b, 0xfc, 0x5d, 0x31, 0xb6, 0x94, 0xb6, 0xe3, 0x8a, 0x41, 0xfe, 0xa3, 0x47, 0x43, - 0xb9, 0x98, 0xfa, 0x97, 0x1d, 0xbf, 0x4e, 0xfd, 0x66, 0x12, 0xc6, 0x0a, 0xfa, 0x79, 0x8d, 0x62, - 0x7e, 0x13, 0xe7, 0x77, 0x43, 0x5b, 0x93, 0x70, 0x5b, 0xd3, 0xcb, 0xd9, 0x04, 0xfd, 0xdb, 0xd0, - 0xdb, 0xcb, 0xb4, 0x95, 0x76, 0x55, 0x3e, 0x3c, 0x0c, 0x14, 0x2b, 0x8f, 0xe9, 0x3f, 0x68, 0xf3, - 0x39, 0xa8, 0x9e, 0x68, 0xfc, 0xcc, 0x1d, 0xf8, 0xc2, 0x7f, 0xf4, 0xa4, 0x00, 0xa9, 0x82, 0xa1, - 0xb7, 0xd0, 0x1f, 0x24, 0x22, 0xec, 0x81, 0x35, 0x0c, 0xbd, 0x55, 0xa3, 0x37, 0xb6, 0x38, 0x53, - 0x00, 0x2e, 0x4e, 0x3a, 0x03, 0x63, 0x2d, 0xbd, 0xad, 0x9a, 0xf6, 0xb4, 0x6a, 0x6a, 0xdf, 0xab, - 0xba, 0x4c, 0xf2, 0x57, 0xac, 0x44, 0xb2, 0x93, 0x9c, 0xe8, 0x31, 0xca, 0x51, 0xc2, 0x26, 0xc2, - 0x55, 0xfb, 0x66, 0x99, 0xae, 0x58, 0xf4, 0xbb, 0x5e, 0x60, 0x6f, 0xe3, 0x81, 0xbd, 0xaa, 0x07, - 0xc3, 0x0d, 0xbf, 0x67, 0x3a, 0x23, 0x5a, 0xad, 0xdf, 0xe4, 0x80, 0x7c, 0x27, 0x07, 0xf2, 0xa9, - 0x50, 0x75, 0xc6, 0xdf, 0x61, 0x7e, 0x98, 0x05, 0x28, 0x2b, 0xbb, 0xea, 0x26, 0xb3, 0x99, 0x7c, - 0xdd, 0x1e, 0xf0, 0x2c, 0xeb, 0xc6, 0xab, 0x3c, 0x38, 0x9f, 0x81, 0xac, 0x05, 0xab, 0xd5, 0x86, - 0x67, 0x73, 0x6d, 0x70, 0x4b, 0x61, 0x1a, 0xea, 0x82, 0x29, 0xdb, 0xe9, 0xb9, 0x4b, 0xa4, 0x92, - 0x5d, 0x97, 0x48, 0xf5, 0x5c, 0x9e, 0xf9, 0x5d, 0x2d, 0x85, 0x3e, 0x1a, 0xfa, 0xce, 0x30, 0x0f, - 0x3d, 0x9e, 0x16, 0xf9, 0x80, 0x7a, 0x33, 0x64, 0x75, 0xc7, 0xcc, 0x23, 0xf8, 0xae, 0x07, 0x4a, - 0xda, 0x86, 0x2e, 0xdb, 0x29, 0x43, 0x5e, 0xbc, 0x11, 0x8a, 0x8e, 0xf8, 0x81, 0xfe, 0xa2, 0x00, - 0x27, 0x16, 0xec, 0x43, 0x89, 0xa4, 0x1d, 0xe7, 0x54, 0x73, 0x6b, 0x49, 0xd5, 0xb6, 0xdb, 0xe8, - 0x5f, 0x86, 0x9b, 0xc9, 0x7b, 0xf0, 0x4f, 0x46, 0xc3, 0x9f, 0xf7, 0x14, 0xac, 0xf2, 0xa8, 0xdd, - 0xe1, 0x57, 0x4a, 0x6f, 0x6a, 0x7d, 0x00, 0xbc, 0x15, 0x32, 0x8c, 0x50, 0xab, 0x5b, 0xce, 0xf8, - 0xe2, 0xe7, 0x94, 0x24, 0x5b, 0x39, 0x3c, 0x5e, 0x40, 0x67, 0x39, 0x1c, 0xe7, 0x0e, 0x44, 0x59, - 0xfc, 0x9e, 0x82, 0x37, 0x41, 0xd6, 0xe2, 0xb4, 0x34, 0xe5, 0xed, 0xc5, 0xe2, 0x11, 0x09, 0x20, - 0xb3, 0xac, 0xef, 0xe2, 0x9a, 0x2e, 0x26, 0xc8, 0x7f, 0x42, 0x5f, 0x4d, 0x17, 0x93, 0xe8, 0xbf, - 0x00, 0x8c, 0x39, 0x0e, 0xbf, 0x5f, 0x4d, 0xda, 0x77, 0x84, 0x53, 0x33, 0x35, 0x63, 0x46, 0xe8, - 0xdd, 0xf4, 0xd7, 0x87, 0x36, 0x7c, 0x3a, 0x8e, 0xb8, 0xdd, 0x95, 0x85, 0xbc, 0x7e, 0xf7, 0xfd, - 0xa1, 0x0c, 0xa1, 0x61, 0x6b, 0x89, 0xbf, 0xab, 0x7d, 0x2f, 0x69, 0xbf, 0xc4, 0xe0, 0x12, 0x41, - 0xf7, 0xff, 0xf8, 0x97, 0xa5, 0xdd, 0x0d, 0x06, 0x8b, 0xb9, 0x9e, 0x18, 0xfe, 0x79, 0xd1, 0xc0, - 0x9d, 0x57, 0xdf, 0x76, 0x07, 0x1c, 0x7c, 0xee, 0xe6, 0x70, 0xb8, 0xbd, 0xd5, 0x28, 0x35, 0xc5, - 0xcf, 0xe5, 0x0f, 0xb3, 0xc7, 0xba, 0xb4, 0x08, 0x0e, 0x20, 0xdc, 0x85, 0x93, 0x81, 0x0f, 0xcc, - 0xbb, 0x4d, 0x25, 0x35, 0x84, 0xe4, 0xe2, 0x63, 0xa1, 0xde, 0xf8, 0x0f, 0x2c, 0x3a, 0x7e, 0xb6, - 0xfd, 0x20, 0x09, 0xe3, 0xcc, 0xb3, 0x39, 0xd7, 0x6c, 0x76, 0x3d, 0x33, 0xba, 0xcf, 0x99, 0xf4, - 0xdf, 0x87, 0x76, 0x0f, 0x73, 0x5a, 0xe5, 0x94, 0x1d, 0xdb, 0x23, 0x83, 0xe1, 0x0c, 0x3c, 0x7d, - 0x09, 0x1a, 0xc9, 0xa5, 0xa9, 0x13, 0x44, 0xf3, 0xae, 0x18, 0x78, 0x57, 0xc5, 0xe7, 0xd1, 0x25, - 0x01, 0x4b, 0x50, 0xf4, 0x9e, 0xd0, 0x27, 0x0f, 0x3d, 0x45, 0xfa, 0xf0, 0xf8, 0x76, 0x98, 0x68, - 0xba, 0x89, 0xac, 0x11, 0x11, 0x75, 0x8d, 0x88, 0x9e, 0x62, 0x64, 0x6f, 0xf2, 0x90, 0xab, 0x3c, - 0x7f, 0x2a, 0xe2, 0x67, 0xec, 0xf7, 0x33, 0x30, 0xb6, 0xaa, 0xb5, 0x5b, 0x4d, 0xb2, 0x28, 0xfd, - 0x07, 0xc1, 0xb9, 0x41, 0xf5, 0x05, 0xdc, 0x25, 0x53, 0x2f, 0xee, 0x60, 0xc3, 0xde, 0x53, 0x62, - 0x81, 0xde, 0xf7, 0x57, 0xa2, 0x3f, 0xf2, 0xda, 0x98, 0x73, 0x3c, 0xeb, 0x79, 0xd7, 0x72, 0xbb, - 0xd2, 0xe0, 0xab, 0x45, 0x4b, 0x30, 0xd6, 0x52, 0xeb, 0x66, 0xc7, 0x70, 0x6e, 0x5a, 0xbc, 0x3e, - 0x5c, 0x29, 0x2b, 0x2c, 0x97, 0xec, 0x64, 0x47, 0x0a, 0x64, 0xad, 0xc8, 0x7d, 0xe6, 0xc0, 0x7d, - 0x8f, 0x0a, 0x90, 0x39, 0xb3, 0x62, 0x98, 0x6a, 0xdb, 0xbe, 0xa8, 0xd5, 0x0a, 0x11, 0xa5, 0xc8, - 0xfe, 0xad, 0x1a, 0x4d, 0xcb, 0xfc, 0xec, 0x46, 0xa0, 0x4f, 0x38, 0x70, 0x17, 0x38, 0xb8, 0x6f, - 0x8c, 0xd0, 0xf2, 0x68, 0x90, 0xdf, 0x3b, 0xd8, 0x0b, 0xf8, 0x32, 0x7d, 0x95, 0xbe, 0xb4, 0x5c, - 0xaa, 0xad, 0x15, 0x7f, 0x39, 0x5f, 0x2c, 0x16, 0x8a, 0x05, 0xb1, 0x41, 0xdf, 0x27, 0x72, 0x56, - 0xfc, 0xfc, 0x48, 0x60, 0x71, 0xd1, 0x1d, 0x09, 0x9c, 0x08, 0xf4, 0xf6, 0xd0, 0x6e, 0xd2, 0x4e, - 0xc3, 0xfb, 0xac, 0xf5, 0x7b, 0xd9, 0x4b, 0x9e, 0x08, 0xe5, 0xef, 0xdc, 0xaf, 0x86, 0x43, 0x64, - 0xee, 0x77, 0x57, 0x21, 0x4d, 0x97, 0xde, 0xe8, 0x83, 0xf4, 0x7a, 0xcc, 0x56, 0x53, 0xa9, 0x63, - 0xb4, 0x13, 0xe1, 0x4d, 0x81, 0x75, 0x92, 0xdb, 0x7d, 0x53, 0xc0, 0x0a, 0x4a, 0xa7, 0x20, 0x4d, - 0xff, 0x5a, 0x1a, 0xff, 0x78, 0xaf, 0xe5, 0xbe, 0xcc, 0x92, 0xf0, 0x8e, 0x81, 0x81, 0x36, 0x19, - 0x66, 0x25, 0xb0, 0xc8, 0xf4, 0xc1, 0xc9, 0x9f, 0xa6, 0x68, 0xa3, 0x50, 0xb8, 0xcb, 0x80, 0x83, - 0x28, 0x8a, 0x5f, 0x4f, 0xfe, 0x75, 0x0a, 0xd2, 0xd5, 0x56, 0x53, 0x35, 0xd1, 0xef, 0x25, 0x87, - 0x82, 0x99, 0xa1, 0x68, 0x9b, 0xd8, 0x07, 0x33, 0x99, 0x7c, 0x93, 0x59, 0x12, 0xd7, 0x90, 0x99, - 0x0a, 0x61, 0xc8, 0xac, 0xe1, 0x0b, 0x26, 0x67, 0xc8, 0x94, 0xce, 0x58, 0xa7, 0x64, 0xd2, 0x3d, - 0x8e, 0xbc, 0xb1, 0xbc, 0xb4, 0x59, 0x3d, 0xce, 0xc8, 0xcc, 0xdc, 0x64, 0x9d, 0x3d, 0x01, 0xc8, - 0xcc, 0x55, 0x6a, 0xb5, 0xca, 0xb2, 0x78, 0x44, 0xca, 0x82, 0x50, 0xab, 0xac, 0x88, 0x09, 0x69, - 0x1c, 0xd2, 0xa5, 0x72, 0xb9, 0x28, 0x8b, 0x49, 0xf2, 0xb7, 0x56, 0xaa, 0x2d, 0x15, 0x45, 0x01, - 0x7d, 0x28, 0xf4, 0xd0, 0xcb, 0xd7, 0x1d, 0xa7, 0x78, 0x85, 0x1b, 0x84, 0xfd, 0xe9, 0x89, 0x5f, - 0xb8, 0xfe, 0x8d, 0x00, 0xe9, 0x65, 0x6c, 0x6c, 0x62, 0xf4, 0xe2, 0x08, 0xb6, 0xc0, 0x0d, 0xd5, - 0x68, 0xb3, 0xb3, 0x43, 0xae, 0x2d, 0xd0, 0x1b, 0x27, 0x5d, 0x09, 0x93, 0x6d, 0x5c, 0xd7, 0xb5, - 0x86, 0x9d, 0xc8, 0xba, 0x0e, 0x8a, 0x8b, 0x44, 0x8f, 0x44, 0x84, 0x8c, 0x12, 0x3a, 0x14, 0x83, - 0x5e, 0x14, 0x60, 0x7a, 0xd5, 0x1a, 0x3f, 0x30, 0xff, 0x53, 0x20, 0x99, 0x5a, 0x7b, 0xe8, 0x91, - 0xd0, 0x46, 0xda, 0xeb, 0x20, 0x43, 0xc5, 0xd4, 0x9e, 0xaf, 0xf4, 0xd6, 0xc7, 0x56, 0x1a, 0x69, - 0x0e, 0x2e, 0x6a, 0xd3, 0xe7, 0xd3, 0x71, 0x83, 0x74, 0x5d, 0xb9, 0xaf, 0x52, 0xd8, 0x9f, 0x1c, - 0xfd, 0xa5, 0x17, 0xc0, 0xdb, 0x79, 0x00, 0xaf, 0xee, 0xc1, 0x4a, 0xd2, 0x20, 0xff, 0x87, 0x64, - 0x48, 0x33, 0xaa, 0x4d, 0xdd, 0x31, 0x2e, 0xda, 0x61, 0xf2, 0x6d, 0xcb, 0xdc, 0x69, 0xd2, 0x6f, - 0x96, 0x0b, 0x8b, 0x1d, 0x96, 0x66, 0x21, 0xab, 0x68, 0x7b, 0xf4, 0x53, 0x2a, 0xa0, 0xd5, 0x76, - 0x22, 0xf4, 0x66, 0x07, 0xf9, 0xbb, 0x38, 0xe4, 0xaf, 0x0d, 0x47, 0x6e, 0xfc, 0xc0, 0xff, 0x7d, - 0x06, 0xd2, 0x2b, 0x4a, 0xdb, 0xc4, 0xe8, 0xdb, 0x42, 0x58, 0xe4, 0xaf, 0x86, 0xa9, 0x0d, 0xbd, - 0xde, 0x69, 0xe3, 0x06, 0xdf, 0x29, 0xbb, 0x62, 0x87, 0x81, 0xb9, 0x74, 0x0a, 0x44, 0x3b, 0xd2, - 0x2a, 0xd6, 0xb6, 0xd6, 0xef, 0x8b, 0xa7, 0xa7, 0x94, 0xdb, 0x2b, 0x8a, 0x61, 0x56, 0x36, 0x68, - 0x9c, 0x73, 0x4a, 0xd9, 0x1b, 0xc9, 0x41, 0x9f, 0x09, 0x80, 0x3e, 0xeb, 0x0f, 0xfd, 0x58, 0x08, - 0xe8, 0xa5, 0x1c, 0x8c, 0x6d, 0xa8, 0x4d, 0x4c, 0x33, 0x8c, 0xf7, 0xb8, 0xdf, 0xca, 0xda, 0x9e, - 0x20, 0xbc, 0x77, 0xc6, 0xa4, 0x79, 0xb5, 0x89, 0x65, 0x27, 0x1b, 0x5a, 0x62, 0x9b, 0xfd, 0xce, - 0x9d, 0xf5, 0x09, 0xcf, 0x9d, 0xf5, 0x12, 0xa4, 0x1a, 0x8a, 0xa9, 0x50, 0xd6, 0x1f, 0x95, 0xe9, - 0x7f, 0x7e, 0xef, 0x48, 0xe8, 0xde, 0x3b, 0x7a, 0x48, 0x88, 0xa6, 0xff, 0x6c, 0xd2, 0x7c, 0xfa, - 0xcf, 0xba, 0x0d, 0x07, 0xf3, 0x02, 0x73, 0xc2, 0x04, 0x86, 0xba, 0x62, 0x60, 0x73, 0xc5, 0xbb, - 0x3d, 0x93, 0x96, 0xf9, 0x48, 0xba, 0xe3, 0xdd, 0xae, 0x2a, 0x3b, 0x98, 0x56, 0x96, 0x27, 0xdf, - 0xac, 0x3d, 0xce, 0x7d, 0xf1, 0xae, 0xb6, 0x4d, 0x0f, 0x5b, 0xdb, 0xf6, 0x6a, 0x63, 0xfc, 0x9d, - 0xee, 0xad, 0x29, 0x10, 0xf2, 0x1d, 0xf3, 0x69, 0xad, 0x6c, 0xff, 0x31, 0xf4, 0xe6, 0x97, 0xa5, - 0xbd, 0x3a, 0xe6, 0xe1, 0xea, 0xda, 0x88, 0x52, 0x12, 0x6e, 0x93, 0xcd, 0xaf, 0x6d, 0x23, 0x39, - 0xa0, 0x63, 0xfb, 0x21, 0xe8, 0x07, 0x9f, 0x87, 0x23, 0xa6, 0x8c, 0x3c, 0x8a, 0xc1, 0x09, 0xdb, - 0x46, 0x81, 0x94, 0x6b, 0x57, 0x7a, 0x63, 0x68, 0x4f, 0x20, 0xc6, 0x9f, 0x40, 0xa7, 0x80, 0x68, - 0x53, 0xa5, 0x70, 0xb7, 0xbf, 0x05, 0x54, 0x1b, 0x3f, 0x32, 0x3f, 0xf6, 0x5a, 0x0f, 0x72, 0x07, - 0xc6, 0x86, 0x37, 0xdb, 0x07, 0x5a, 0x98, 0x59, 0xb3, 0xfb, 0x18, 0x15, 0xa2, 0xf1, 0x3b, 0x9c, - 0xfd, 0x39, 0xb0, 0xe2, 0x11, 0x1c, 0x89, 0x12, 0x20, 0xc3, 0xf6, 0x0f, 0xd0, 0x7b, 0x43, 0xab, - 0x4c, 0xa2, 0x76, 0x78, 0x07, 0x02, 0x27, 0x1c, 0xc5, 0x94, 0xc0, 0x39, 0x1a, 0xa4, 0x22, 0x39, - 0x1a, 0xf0, 0xfe, 0xc2, 0x21, 0xfa, 0x51, 0xcf, 0xb7, 0xf5, 0x87, 0xbd, 0x4a, 0x8c, 0xd2, 0xc3, - 0x0e, 0xe9, 0xb1, 0xff, 0x9f, 0xf2, 0xb7, 0x92, 0xe5, 0x23, 0x40, 0xee, 0x37, 0x2b, 0x89, 0x70, - 0x4b, 0x39, 0x6b, 0xfa, 0x90, 0x2f, 0x2c, 0x0b, 0x77, 0x10, 0xa0, 0x4f, 0xd5, 0xf1, 0x73, 0xfe, - 0x6d, 0xec, 0xf2, 0xf8, 0x79, 0x15, 0x37, 0x1b, 0x6d, 0x64, 0x1c, 0x7c, 0xe0, 0xb9, 0x01, 0x32, - 0x1b, 0xb4, 0xb0, 0x7e, 0x2f, 0xb2, 0x5b, 0xc9, 0xd0, 0x5b, 0x93, 0x61, 0x0d, 0xeb, 0x96, 0x21, - 0xc3, 0xa6, 0x76, 0x28, 0x30, 0xbd, 0x2d, 0x94, 0x61, 0x3b, 0xb8, 0xe6, 0xf8, 0x51, 0xfa, 0x80, - 0x00, 0x47, 0xad, 0xdb, 0xc0, 0x72, 0x4d, 0x75, 0x53, 0xf3, 0x1e, 0x4d, 0x1b, 0xb8, 0x87, 0x48, - 0x37, 0x42, 0x5a, 0x21, 0xa5, 0x59, 0xee, 0x54, 0xa8, 0xa7, 0x96, 0xa3, 0xf5, 0xc9, 0x2c, 0x61, - 0x84, 0x9b, 0x20, 0x5c, 0xc1, 0xb6, 0x69, 0x1e, 0xe1, 0x4d, 0x10, 0x7d, 0x2b, 0x8f, 0x1f, 0xb1, - 0xef, 0x08, 0x70, 0xdc, 0x22, 0xe0, 0x2c, 0x36, 0x4c, 0xb5, 0xae, 0x34, 0x19, 0x72, 0xaf, 0x4c, - 0x0c, 0x03, 0xba, 0x45, 0x98, 0xdc, 0xf5, 0x16, 0x6b, 0x41, 0x38, 0xd3, 0x13, 0x42, 0x8e, 0x00, - 0x99, 0xcf, 0x18, 0xe1, 0x44, 0x3d, 0xc7, 0x55, 0xae, 0xcc, 0x11, 0x9e, 0xa8, 0x0f, 0x4d, 0x44, - 0xfc, 0x10, 0xff, 0x6e, 0x8a, 0x5d, 0x32, 0xe1, 0xaa, 0xcf, 0xaf, 0x87, 0xc6, 0x76, 0x15, 0x26, - 0x28, 0x96, 0x2c, 0xa3, 0xb5, 0xc6, 0x0b, 0x10, 0x62, 0x47, 0xef, 0x58, 0x37, 0x60, 0x39, 0x79, - 0x65, 0x6f, 0x39, 0xe8, 0x1c, 0x80, 0xfb, 0xc9, 0xab, 0xa4, 0x13, 0x7e, 0x4a, 0x3a, 0x19, 0x4e, - 0x49, 0xbf, 0x27, 0xf4, 0x41, 0xa8, 0xde, 0x64, 0x1f, 0x5c, 0x3c, 0xc2, 0x1d, 0x81, 0xe9, 0x5f, - 0x7b, 0xfc, 0x72, 0xf1, 0xe6, 0x54, 0xf7, 0x7d, 0xb5, 0x9f, 0x19, 0xca, 0x1c, 0xd6, 0xab, 0x0f, - 0x84, 0x2e, 0x7d, 0x30, 0xf8, 0x9c, 0x55, 0xba, 0x06, 0x8e, 0xb1, 0x2a, 0xf2, 0x0e, 0x59, 0xec, - 0x59, 0xc3, 0xee, 0x68, 0xf4, 0xd9, 0x01, 0x84, 0xa0, 0xdf, 0x65, 0xba, 0x41, 0x4a, 0x2e, 0xda, - 0x34, 0x37, 0xaa, 0x80, 0x1c, 0xde, 0x1d, 0xbc, 0x3f, 0x48, 0xb1, 0xd9, 0xee, 0x2a, 0xbd, 0x39, - 0x0e, 0xfd, 0x55, 0x6a, 0x18, 0x23, 0xc2, 0xdd, 0x90, 0x32, 0xed, 0xe7, 0x57, 0x7b, 0x2f, 0x23, - 0xdd, 0x2a, 0xdd, 0x3b, 0xe7, 0xf0, 0x05, 0x73, 0xf1, 0x88, 0x4c, 0x73, 0x4a, 0xa7, 0xe0, 0xd8, - 0xba, 0x52, 0xdf, 0xde, 0x34, 0xf4, 0x8e, 0xd6, 0xc8, 0xeb, 0x4d, 0xdd, 0x60, 0x26, 0x02, 0x7a, - 0xbf, 0x1e, 0xff, 0x41, 0x3a, 0x6d, 0x4f, 0x1d, 0xd2, 0xfd, 0xa6, 0x0e, 0x8b, 0x47, 0xac, 0xc9, - 0x83, 0x74, 0x93, 0xa3, 0x74, 0x32, 0x81, 0x4a, 0x67, 0xf1, 0x88, 0xad, 0x76, 0xa4, 0x02, 0x8c, - 0x35, 0xd4, 0x5d, 0xba, 0xeb, 0x47, 0xcd, 0xb3, 0xfd, 0x0e, 0x56, 0x14, 0xd4, 0x5d, 0xb6, 0x47, - 0xb8, 0x78, 0x44, 0x76, 0x72, 0x4a, 0x0b, 0x30, 0x4e, 0x2d, 0xac, 0xb4, 0x98, 0xb1, 0x48, 0x87, - 0x26, 0x16, 0x8f, 0xc8, 0x6e, 0x5e, 0x32, 0xfb, 0x48, 0x51, 0x77, 0xe4, 0xbb, 0xec, 0x9d, 0xcb, - 0x44, 0xa4, 0x9d, 0x4b, 0xc2, 0x0b, 0xb6, 0x77, 0x79, 0x02, 0xd2, 0x75, 0xca, 0xe1, 0xa4, 0xc5, - 0x61, 0x16, 0x94, 0x6e, 0x87, 0xd4, 0x8e, 0x62, 0xd8, 0xcb, 0xd4, 0xab, 0xfb, 0x97, 0xbb, 0xac, - 0x18, 0xdb, 0x04, 0x41, 0x92, 0x6b, 0x2e, 0x0b, 0x69, 0xca, 0x38, 0xe7, 0x0f, 0x7a, 0xd2, 0x9a, - 0x86, 0xe4, 0x75, 0x8d, 0x0c, 0xfb, 0x35, 0xdd, 0xf6, 0xd9, 0xae, 0x0f, 0x43, 0xe6, 0x78, 0xff, - 0x44, 0x61, 0x9f, 0x7f, 0xe2, 0x5f, 0x0e, 0x30, 0xb7, 0xe8, 0xa6, 0xd4, 0x7f, 0x71, 0xdc, 0xe4, - 0x9e, 0x2a, 0xb7, 0x83, 0x11, 0xb5, 0x46, 0xd4, 0x59, 0x47, 0x1f, 0xf2, 0x46, 0xf0, 0xb2, 0x7c, - 0x0a, 0xa6, 0x09, 0x21, 0xcc, 0x73, 0x97, 0xbf, 0x76, 0x12, 0xfd, 0xf9, 0x50, 0x26, 0x97, 0x3d, - 0x46, 0x04, 0xa1, 0xe7, 0x88, 0xb0, 0xef, 0xdc, 0x46, 0xaa, 0xcf, 0xb9, 0x8d, 0x74, 0x34, 0x73, - 0xca, 0x1f, 0x7b, 0xe5, 0x67, 0x85, 0x97, 0x9f, 0x5b, 0x7d, 0x00, 0xea, 0xc5, 0x97, 0xa1, 0x4c, - 0x40, 0x3e, 0xe8, 0x48, 0x4a, 0x95, 0x93, 0x94, 0xbb, 0x06, 0x27, 0x24, 0x7e, 0x69, 0xf9, 0x64, - 0x0a, 0x9e, 0xe1, 0x12, 0x53, 0xc6, 0xe7, 0x2d, 0x41, 0xf9, 0xea, 0x50, 0x04, 0xe5, 0x26, 0xf7, - 0x41, 0x97, 0x3e, 0x8b, 0x7d, 0x3b, 0x5d, 0xdc, 0x12, 0xf3, 0x17, 0xa1, 0xfd, 0xcd, 0xbb, 0x81, - 0x72, 0x78, 0xe3, 0x23, 0x2c, 0x27, 0x20, 0xc3, 0x34, 0x8c, 0xfd, 0xbc, 0x34, 0x0b, 0x45, 0x54, - 0x37, 0xe1, 0xbc, 0xd4, 0xc3, 0xd2, 0x36, 0x02, 0xf9, 0xb1, 0x0c, 0x0f, 0xb5, 0x8e, 0xa1, 0x95, - 0x34, 0x53, 0x47, 0xbf, 0x31, 0x14, 0xc1, 0x71, 0x3c, 0x7f, 0x84, 0x41, 0x3c, 0x7f, 0x06, 0x32, - 0x43, 0xd8, 0x2d, 0x38, 0x14, 0x33, 0x84, 0x4f, 0xe5, 0xf1, 0xe3, 0xf7, 0xb8, 0x00, 0x27, 0xac, - 0xd5, 0xd0, 0x1c, 0x3f, 0x85, 0x43, 0xf7, 0x0d, 0x03, 0xc8, 0xe3, 0xf6, 0x3c, 0x86, 0x0d, 0x10, - 0x2c, 0xc0, 0x7b, 0x84, 0x07, 0xde, 0xa1, 0xc8, 0xad, 0xd7, 0xba, 0x28, 0x1c, 0x0a, 0x52, 0xe1, - 0xae, 0x4e, 0x8c, 0x40, 0x46, 0xfc, 0x98, 0xbd, 0x46, 0x80, 0x8c, 0x75, 0x2b, 0xfc, 0x6a, 0x2c, - 0xdb, 0xc5, 0xfc, 0x7d, 0x39, 0x21, 0xb6, 0x29, 0x22, 0x5f, 0xc7, 0x1e, 0xdf, 0x06, 0xc5, 0xe1, - 0xdc, 0xb7, 0x8e, 0x1e, 0x11, 0x2c, 0xcb, 0xca, 0x92, 0x62, 0xe2, 0x0b, 0xe8, 0xb7, 0x04, 0xc8, - 0x56, 0xb1, 0x49, 0x34, 0x53, 0x78, 0x8c, 0xfc, 0x6d, 0xe6, 0x92, 0x67, 0xed, 0x36, 0xce, 0x56, - 0x63, 0x51, 0x75, 0x1c, 0xa5, 0x6b, 0xd6, 0xa2, 0x69, 0xd4, 0x3a, 0x2e, 0xa8, 0xf2, 0x11, 0x9c, - 0x4e, 0xbd, 0x12, 0xc6, 0x29, 0x19, 0x14, 0x8e, 0xcf, 0x79, 0xa0, 0x79, 0x5d, 0x22, 0x16, 0x6c, - 0xc8, 0xf0, 0x45, 0xaf, 0x4e, 0xa7, 0xb3, 0x97, 0x89, 0x30, 0xc3, 0x17, 0x59, 0xa6, 0xb5, 0x65, - 0x96, 0x2b, 0xc2, 0x5b, 0x3a, 0x4e, 0xb3, 0x86, 0x8a, 0x6c, 0xb8, 0x47, 0x0e, 0xfa, 0xd5, 0x3d, - 0x82, 0x27, 0x32, 0x04, 0x18, 0xab, 0x92, 0xe5, 0x06, 0x19, 0x53, 0xce, 0x1d, 0x1c, 0xca, 0xde, - 0x83, 0x55, 0xc4, 0x8e, 0x66, 0x73, 0x64, 0x78, 0x43, 0x54, 0x84, 0x8e, 0x16, 0x54, 0x79, 0xfc, - 0x78, 0x7c, 0x88, 0xe1, 0x41, 0x65, 0x19, 0xbd, 0x53, 0x00, 0x61, 0x01, 0x9b, 0x43, 0xf2, 0xf3, - 0x0f, 0xeb, 0x33, 0xce, 0x0f, 0x5d, 0x81, 0x47, 0xbb, 0x39, 0x86, 0x51, 0x9a, 0x67, 0x17, 0xf0, - 0x70, 0x3a, 0x50, 0xb8, 0x33, 0xdd, 0xa1, 0x08, 0x88, 0x1f, 0xb5, 0x8f, 0x31, 0xd4, 0x98, 0x05, - 0xeb, 0xd7, 0x87, 0xa0, 0x11, 0x47, 0x3b, 0x79, 0xb7, 0x19, 0x48, 0xcb, 0x38, 0xac, 0xfe, 0xd6, - 0xab, 0xf2, 0x91, 0x78, 0x84, 0x01, 0xe9, 0xec, 0x5b, 0xb8, 0xbe, 0x8d, 0x1b, 0xe8, 0xff, 0x3b, - 0x38, 0x74, 0xd3, 0x90, 0xad, 0xb3, 0xd2, 0x28, 0x78, 0x63, 0xb2, 0x1d, 0x8c, 0xf0, 0x92, 0x35, - 0xaf, 0x88, 0x58, 0xf6, 0x11, 0xbe, 0x64, 0x1d, 0xa2, 0xfa, 0xf8, 0x91, 0xf9, 0x43, 0x36, 0xc9, - 0x28, 0xd5, 0x75, 0x0d, 0xfd, 0xab, 0x83, 0xc3, 0x72, 0x29, 0x8c, 0xab, 0x75, 0x5d, 0x2b, 0xed, - 0x28, 0x9b, 0xb6, 0x19, 0xd5, 0x8d, 0xb0, 0xbf, 0x16, 0x77, 0xf4, 0xfb, 0x55, 0x6b, 0x6b, 0xc6, - 0x8d, 0x18, 0x74, 0x32, 0x41, 0x48, 0x3f, 0xac, 0xc9, 0x44, 0x8f, 0xba, 0xe3, 0x87, 0xec, 0xb3, - 0xae, 0x0b, 0x05, 0x53, 0x85, 0x4f, 0x0b, 0x4b, 0xc6, 0x20, 0xc3, 0x99, 0xb7, 0x15, 0x87, 0x32, - 0x9c, 0x05, 0x10, 0x10, 0x3f, 0x8e, 0x6f, 0x74, 0x71, 0x8c, 0xdd, 0x8e, 0x71, 0x00, 0x74, 0x86, - 0x37, 0x3d, 0x1c, 0x10, 0x9d, 0xc3, 0x99, 0x22, 0x3e, 0x61, 0x5d, 0x0d, 0x64, 0xcd, 0x78, 0xd0, - 0xaf, 0x0d, 0x03, 0x9c, 0x5b, 0x07, 0xd9, 0x14, 0x63, 0x5b, 0x62, 0x11, 0x5e, 0x4e, 0xd9, 0xc7, - 0x41, 0x52, 0xca, 0x50, 0x10, 0x0c, 0xf7, 0x72, 0x4a, 0x98, 0xfa, 0xe3, 0x07, 0xf0, 0x15, 0x02, - 0x4c, 0xd1, 0x7d, 0xae, 0x26, 0x56, 0x0c, 0xa6, 0x28, 0x87, 0xe2, 0x8d, 0xf9, 0xa1, 0xd0, 0x97, - 0x9a, 0xf3, 0x7c, 0x70, 0xe9, 0x18, 0x0a, 0x14, 0xe1, 0xde, 0xdf, 0x0c, 0x49, 0xc2, 0x48, 0x4c, - 0x81, 0xa2, 0x43, 0x82, 0x25, 0xe2, 0xc3, 0xc1, 0x23, 0xa2, 0xdb, 0x17, 0xcf, 0x0c, 0xbb, 0xb3, - 0x8d, 0xd8, 0xed, 0x2b, 0x0c, 0x11, 0x23, 0xb8, 0x3a, 0xfb, 0x46, 0xcb, 0x14, 0x58, 0xa3, 0x0f, - 0x0b, 0x3d, 0x9a, 0x72, 0x5c, 0xd5, 0xbf, 0x34, 0x14, 0x37, 0x9f, 0x03, 0xdc, 0x73, 0x27, 0x41, - 0xca, 0xd0, 0xcf, 0x33, 0xb3, 0xd4, 0xa4, 0x4c, 0xff, 0xd3, 0x29, 0xbf, 0xde, 0xec, 0xec, 0x68, - 0x6d, 0x3a, 0x77, 0x9c, 0x94, 0xed, 0xa0, 0x74, 0x25, 0x4c, 0x9e, 0x57, 0xcd, 0xad, 0x45, 0xac, - 0x34, 0xb0, 0x21, 0xeb, 0xe7, 0xad, 0xe7, 0x3b, 0xf9, 0x48, 0x7e, 0x0f, 0x36, 0xc4, 0xfc, 0x92, - 0xbe, 0x36, 0x34, 0x12, 0xbf, 0xf6, 0x28, 0x33, 0x4f, 0x7f, 0xaa, 0xe2, 0x17, 0x98, 0x8f, 0x0b, - 0x30, 0x2e, 0xeb, 0xe7, 0x2d, 0x21, 0xf9, 0xd7, 0x87, 0x2b, 0x23, 0x91, 0x17, 0x7a, 0xec, 0xf5, - 0x28, 0x9b, 0xfc, 0x91, 0x2f, 0xf4, 0x02, 0xab, 0x1f, 0x89, 0x7b, 0xfc, 0x51, 0x59, 0x3f, 0x5f, - 0xc5, 0x26, 0xeb, 0x11, 0x68, 0x6d, 0x48, 0x9e, 0x7c, 0x6a, 0x9b, 0x15, 0x68, 0xad, 0xc3, 0x9d, - 0x30, 0x7a, 0x3c, 0xf4, 0xa3, 0x3c, 0x3c, 0x83, 0x1c, 0x12, 0x87, 0x02, 0xd1, 0xfb, 0x42, 0xbd, - 0xc5, 0x13, 0x8e, 0x82, 0xf8, 0x51, 0x7a, 0xa9, 0x00, 0x13, 0xb2, 0x7e, 0x9e, 0x0c, 0x0d, 0xf3, - 0x6a, 0xb3, 0x39, 0x9c, 0x11, 0x32, 0xea, 0xe4, 0xdf, 0x66, 0x83, 0x4d, 0xc5, 0xc8, 0x27, 0xff, - 0x7d, 0x08, 0x88, 0x1f, 0x86, 0x87, 0x58, 0x67, 0xb1, 0x47, 0x68, 0x6d, 0x38, 0x38, 0x0c, 0xda, - 0x21, 0x1c, 0x32, 0x0e, 0xad, 0x43, 0xf8, 0x51, 0x30, 0x92, 0x9d, 0x93, 0xa9, 0x3c, 0x1d, 0xe6, - 0x87, 0xdb, 0x27, 0x3e, 0x12, 0xcd, 0xbd, 0xc6, 0x1a, 0x76, 0x39, 0x42, 0x86, 0x82, 0x46, 0x04, - 0x37, 0x9a, 0x10, 0x34, 0xc4, 0x8f, 0xc7, 0x9f, 0x08, 0x70, 0x94, 0x91, 0xf0, 0x34, 0x99, 0x05, - 0x0c, 0xd4, 0xa9, 0xbc, 0x2d, 0x38, 0x9c, 0x4e, 0x15, 0x40, 0x41, 0xfc, 0x20, 0xfe, 0x9f, 0x24, - 0x9d, 0xc7, 0x0d, 0x70, 0x46, 0xd1, 0x0f, 0xc1, 0x81, 0x27, 0x63, 0x43, 0x3c, 0xa7, 0x38, 0xc8, - 0x64, 0xec, 0x90, 0xce, 0x2a, 0x3e, 0xe4, 0xf4, 0xa2, 0x61, 0x62, 0x70, 0x80, 0xae, 0x30, 0x44, - 0x18, 0x06, 0xec, 0x0a, 0x87, 0x84, 0xc4, 0x77, 0x05, 0x00, 0x46, 0xc0, 0xb2, 0xbe, 0x8b, 0xd1, - 0x63, 0x43, 0x59, 0xf8, 0x76, 0xbb, 0x86, 0x0a, 0x7d, 0x5c, 0x43, 0x23, 0x9e, 0xcd, 0x8e, 0x6a, - 0x09, 0xf4, 0x70, 0x79, 0xd9, 0xf7, 0x51, 0xc4, 0x18, 0x2d, 0x81, 0xc1, 0xf5, 0xc7, 0x8f, 0xf1, - 0xb7, 0xd8, 0x6c, 0xce, 0x3d, 0xc5, 0xf4, 0x86, 0xa1, 0xa0, 0xec, 0x59, 0xfd, 0x0b, 0xfc, 0xea, - 0xff, 0x00, 0xd8, 0x0e, 0x3a, 0x47, 0xec, 0x77, 0x3a, 0x29, 0xfe, 0x39, 0xe2, 0xe1, 0x9d, 0x42, - 0xfa, 0xf5, 0x14, 0x1c, 0xb3, 0x94, 0xc8, 0x3f, 0x05, 0x88, 0x23, 0x9e, 0x25, 0xe1, 0x94, 0x64, - 0x1f, 0x94, 0x87, 0x65, 0x90, 0x8a, 0x62, 0xca, 0x0c, 0x41, 0xde, 0x48, 0xac, 0x1b, 0x99, 0xe2, - 0x85, 0x96, 0xa2, 0x35, 0xc2, 0x5f, 0xcf, 0xd7, 0x07, 0x78, 0xdb, 0xd6, 0x28, 0xf0, 0xb6, 0xc6, - 0x1e, 0x96, 0xc9, 0xc8, 0x3b, 0xd7, 0x94, 0x65, 0x8c, 0xdc, 0x91, 0xef, 0x5c, 0xfb, 0xd7, 0x1d, - 0x3f, 0x4a, 0x1f, 0x11, 0x20, 0x55, 0xd5, 0x0d, 0x13, 0x3d, 0x1c, 0xa5, 0x77, 0x32, 0xce, 0xbb, - 0x20, 0xd9, 0x61, 0x29, 0xcf, 0x3d, 0x54, 0x74, 0x43, 0xf0, 0x79, 0x3a, 0xc5, 0x54, 0xe8, 0xe5, - 0xcd, 0xa4, 0x7e, 0xcf, 0x8b, 0x45, 0x51, 0x2f, 0x6d, 0x60, 0xfc, 0xab, 0xfa, 0x3b, 0x11, 0xc7, - 0x76, 0x69, 0x83, 0x6f, 0xcd, 0x23, 0xb0, 0xfb, 0x4e, 0x58, 0x7e, 0xa9, 0xf4, 0xfd, 0xb6, 0x87, - 0x99, 0xcb, 0x48, 0x59, 0xd9, 0xc1, 0x43, 0x72, 0x19, 0xa6, 0x37, 0xc4, 0x09, 0xee, 0x0d, 0x71, - 0x51, 0x3b, 0x14, 0x3b, 0xe5, 0xc8, 0x48, 0x1a, 0x75, 0x87, 0x0a, 0xa8, 0x3b, 0x7e, 0x60, 0xbe, - 0x41, 0x46, 0x3e, 0xba, 0x86, 0xcc, 0x69, 0x0d, 0xeb, 0xca, 0xad, 0xbf, 0x3f, 0xec, 0xbd, 0x9b, - 0x7d, 0x97, 0x72, 0xf1, 0x97, 0xfb, 0xa5, 0xbb, 0xdf, 0x1b, 0x9b, 0x63, 0x17, 0x7c, 0xd1, 0x93, - 0x97, 0x99, 0x48, 0x6f, 0x8e, 0x39, 0xf9, 0xd0, 0x93, 0xd1, 0xcc, 0x39, 0xb4, 0x88, 0x2e, 0xc6, - 0xc5, 0x3c, 0xa4, 0x46, 0x30, 0xf4, 0x84, 0xa0, 0xee, 0x9f, 0x87, 0x97, 0xd1, 0xfe, 0x27, 0xdf, - 0x22, 0x9a, 0xb2, 0x9d, 0x87, 0xfa, 0x0e, 0xcb, 0xcb, 0xa8, 0x1f, 0x01, 0xf1, 0xe3, 0xf8, 0x64, - 0xda, 0xda, 0xe4, 0xa5, 0x2e, 0x78, 0xe8, 0x9b, 0xc9, 0xd8, 0x95, 0x77, 0xf8, 0x47, 0x4e, 0x5d, - 0xba, 0x82, 0xb5, 0x77, 0x14, 0x47, 0xd7, 0xa0, 0xe2, 0x46, 0x60, 0x4e, 0x48, 0x52, 0x17, 0xe5, - 0x73, 0x6a, 0xc3, 0xdc, 0x1a, 0x92, 0xa3, 0xff, 0x79, 0x52, 0x96, 0xfd, 0x5a, 0x18, 0x0d, 0xa0, - 0x9f, 0x27, 0x22, 0x5d, 0x5f, 0xe1, 0xb0, 0x84, 0x92, 0xe5, 0xc3, 0xe2, 0x08, 0x97, 0x4e, 0x04, - 0x96, 0x37, 0x42, 0x89, 0x3e, 0xab, 0x36, 0xb0, 0xfe, 0x34, 0x94, 0x68, 0x4a, 0xd7, 0xf0, 0x24, - 0x3a, 0xa8, 0xb8, 0x7f, 0xa6, 0x12, 0xed, 0xb0, 0x64, 0x48, 0x12, 0x1d, 0x58, 0xde, 0x08, 0x6e, - 0xb2, 0x06, 0x6b, 0x7e, 0xbd, 0xa4, 0x6a, 0xdb, 0xe8, 0xf3, 0x69, 0xfb, 0x9d, 0xb2, 0x73, 0xaa, - 0xb9, 0x65, 0x1d, 0x73, 0xff, 0x6c, 0xe8, 0x17, 0x0d, 0x06, 0x38, 0xca, 0x7e, 0x12, 0xc0, 0xb4, - 0xde, 0x0f, 0x72, 0xee, 0xcc, 0xf1, 0xc4, 0x48, 0x39, 0x98, 0x54, 0x35, 0x13, 0x1b, 0x9a, 0xd2, - 0x9c, 0x6f, 0x2a, 0x9b, 0xed, 0xe9, 0x2c, 0x3d, 0x9a, 0x79, 0x49, 0xd7, 0xe0, 0x5d, 0xf2, 0xa4, - 0x91, 0xf9, 0x1c, 0xa1, 0xe7, 0x9a, 0x11, 0xaf, 0xfc, 0xb9, 0x21, 0xe4, 0x4d, 0x2c, 0xce, 0xf5, - 0x4f, 0x3f, 0x8a, 0x66, 0x7c, 0x21, 0x80, 0xcc, 0x76, 0x83, 0x11, 0x79, 0xa6, 0xe8, 0x6d, 0xbc, - 0xd0, 0xd5, 0x78, 0x67, 0xea, 0x91, 0x1a, 0xb2, 0x61, 0x26, 0x0c, 0xe9, 0x23, 0x38, 0xf9, 0x91, - 0x86, 0x8b, 0xec, 0xeb, 0xeb, 0x5a, 0x2d, 0xac, 0x18, 0x8a, 0x56, 0xc7, 0x11, 0xa4, 0x39, 0x68, - 0x2e, 0x39, 0x0f, 0x63, 0x6a, 0x5d, 0xd7, 0xaa, 0xea, 0x4b, 0xec, 0x87, 0x37, 0x4e, 0x05, 0x4e, - 0x27, 0x29, 0x47, 0x4a, 0x56, 0x0e, 0xd9, 0xc9, 0x2b, 0x95, 0x60, 0xbc, 0xae, 0x18, 0x8d, 0xaa, - 0xe7, 0x29, 0xe2, 0x6b, 0xfb, 0x17, 0x94, 0xb7, 0xb3, 0xc8, 0x6e, 0x6e, 0xa9, 0xc2, 0x33, 0x31, - 0xd3, 0x75, 0xfa, 0xd7, 0xb7, 0xb0, 0x82, 0x9b, 0x89, 0xe3, 0x39, 0xe1, 0x8e, 0x81, 0x9b, 0xf4, - 0x9d, 0x43, 0xd6, 0xed, 0xc6, 0x65, 0x37, 0x02, 0x7d, 0xdc, 0x2b, 0xcd, 0xcb, 0xbc, 0x34, 0xbf, - 0xc8, 0x47, 0x24, 0xf6, 0xa1, 0x31, 0x94, 0x39, 0xf1, 0x07, 0x1c, 0xc1, 0x5c, 0xe1, 0x04, 0xf3, - 0xf6, 0x01, 0xa9, 0x88, 0x5f, 0x32, 0x3f, 0x98, 0x81, 0x49, 0x76, 0x98, 0xdc, 0x62, 0x27, 0x7a, - 0x05, 0x7d, 0x5a, 0xcb, 0xbc, 0x17, 0xef, 0xa1, 0xea, 0xc1, 0x07, 0x3a, 0x11, 0x84, 0x6d, 0xbc, - 0x67, 0xf5, 0x77, 0xf2, 0x37, 0xea, 0x1e, 0xa9, 0x4d, 0xd7, 0x2c, 0xa3, 0x69, 0xd4, 0x7b, 0xa4, - 0xc1, 0xd5, 0xc7, 0x8f, 0xcf, 0x6b, 0x05, 0x10, 0x72, 0x8d, 0x46, 0xf8, 0xfb, 0x9d, 0xfc, 0xa1, - 0xb8, 0x1c, 0x26, 0xec, 0x3e, 0x73, 0xaf, 0x03, 0x89, 0x37, 0x2a, 0xaa, 0xc1, 0xc9, 0xe1, 0x4d, - 0xae, 0x31, 0x72, 0x0b, 0x6e, 0x40, 0xdd, 0xf1, 0x83, 0xf2, 0x86, 0xac, 0xd5, 0x69, 0xe6, 0x74, - 0x7d, 0x9b, 0x1e, 0x4b, 0x78, 0x58, 0x80, 0xf4, 0x3c, 0x36, 0xeb, 0x5b, 0x43, 0xea, 0x33, 0x1d, - 0xa3, 0x69, 0xf7, 0x99, 0x7d, 0xef, 0x04, 0xf6, 0x9f, 0x18, 0xda, 0x64, 0xcd, 0x52, 0x92, 0x46, - 0x7d, 0x5d, 0x63, 0x60, 0xed, 0xf1, 0x83, 0xf3, 0x73, 0x01, 0xa6, 0x1c, 0xb3, 0x11, 0xc3, 0xe4, - 0xb7, 0x9f, 0x76, 0xc6, 0x40, 0xf4, 0xd5, 0x68, 0x57, 0xaa, 0x38, 0x3c, 0xe5, 0x5b, 0x16, 0xb3, - 0xb5, 0x2e, 0xc2, 0x65, 0x2b, 0xe1, 0x08, 0x1c, 0xc1, 0xb2, 0x58, 0x80, 0x31, 0x4a, 0x50, 0x41, - 0xdd, 0xa5, 0x6e, 0x5a, 0x9c, 0xf5, 0xee, 0x81, 0xa1, 0x58, 0xef, 0x6e, 0xe7, 0xad, 0x77, 0x21, - 0xaf, 0x30, 0xb4, 0x8d, 0x77, 0x11, 0xfd, 0x16, 0x48, 0xfe, 0xa1, 0xdb, 0xee, 0x22, 0xf8, 0x2d, - 0xf4, 0xa9, 0x7f, 0x04, 0x0f, 0xaa, 0x9e, 0xb2, 0x94, 0xad, 0xbd, 0x79, 0x85, 0x1e, 0x90, 0x20, - 0x75, 0x96, 0xfc, 0xf9, 0xa6, 0xfb, 0xac, 0xc0, 0x03, 0x43, 0x38, 0x08, 0x7f, 0x27, 0xa4, 0xe8, - 0xd3, 0xa9, 0xa9, 0xae, 0x2b, 0x37, 0x03, 0x77, 0xd2, 0x08, 0x21, 0x32, 0xcd, 0x17, 0xf5, 0xb2, - 0x32, 0xae, 0x88, 0xd9, 0xe1, 0xb9, 0xe1, 0x49, 0x27, 0x20, 0x43, 0xca, 0x75, 0x96, 0x59, 0x56, - 0x28, 0x8a, 0xf1, 0x3d, 0x04, 0x6d, 0xf1, 0x23, 0xff, 0x4d, 0xfa, 0x82, 0x0a, 0xbd, 0x53, 0xf5, - 0x91, 0x21, 0xc0, 0xeb, 0xc3, 0x96, 0x03, 0xc3, 0xfe, 0x91, 0x83, 0xc0, 0xee, 0x5c, 0xe0, 0x3a, - 0x52, 0x27, 0xda, 0x10, 0x34, 0x8c, 0xe4, 0xe4, 0x6f, 0xc6, 0x72, 0xfc, 0xbb, 0x6f, 0x98, 0xe8, - 0xa6, 0x38, 0xa1, 0x3f, 0x10, 0x3a, 0x43, 0x74, 0x08, 0x1c, 0x18, 0x9d, 0x43, 0x72, 0x09, 0xfc, - 0x53, 0x01, 0x26, 0xaa, 0xee, 0x73, 0x5f, 0xe1, 0x5f, 0x28, 0x88, 0x0c, 0x11, 0x19, 0x6b, 0xb9, - 0xfb, 0x21, 0x27, 0x07, 0xbf, 0x32, 0x94, 0x67, 0x9d, 0x87, 0xfe, 0x51, 0x5f, 0x19, 0x1a, 0x96, - 0x90, 0xf8, 0x81, 0xfc, 0x32, 0x7b, 0x11, 0x24, 0x57, 0x37, 0xd5, 0x5d, 0x8c, 0x1e, 0x8a, 0x51, - 0x91, 0x9e, 0x80, 0x8c, 0xbe, 0xb1, 0xd1, 0xb6, 0xde, 0x81, 0x9b, 0x94, 0xad, 0x90, 0xfb, 0x00, - 0x37, 0x03, 0xd7, 0x7a, 0x80, 0x3b, 0xe2, 0xa5, 0x82, 0xfb, 0x18, 0xca, 0x1a, 0x34, 0xea, 0x4b, - 0x05, 0xc3, 0x91, 0x31, 0x82, 0x6b, 0x83, 0x81, 0x70, 0xcf, 0x32, 0xd9, 0xbc, 0xd3, 0x32, 0x12, - 0xe0, 0x83, 0x63, 0x3b, 0x03, 0x47, 0x3d, 0x16, 0x01, 0xfb, 0x62, 0x7a, 0x2e, 0x2e, 0xea, 0x59, - 0x63, 0x87, 0x65, 0x43, 0xb7, 0x17, 0x44, 0xb0, 0x03, 0x87, 0x21, 0x62, 0x24, 0xef, 0xbe, 0xd8, - 0x43, 0xde, 0x88, 0xb0, 0xfa, 0xa4, 0x17, 0xab, 0x0a, 0x8f, 0xd5, 0x99, 0x30, 0x6c, 0x0a, 0x37, - 0x04, 0x86, 0x5a, 0x4e, 0x3e, 0xee, 0xc0, 0x25, 0x73, 0x70, 0xdd, 0x39, 0x30, 0x1d, 0xf1, 0x23, - 0xf6, 0x69, 0x81, 0x3d, 0xfe, 0x90, 0xdb, 0x55, 0xd4, 0x26, 0x3d, 0x20, 0x3e, 0x84, 0x07, 0xe3, - 0xfe, 0x9b, 0x17, 0x94, 0xb3, 0x3c, 0x28, 0x77, 0x87, 0x61, 0x06, 0x47, 0x91, 0x0f, 0x36, 0x2f, - 0xf0, 0xda, 0xcc, 0xd9, 0x2d, 0xa2, 0x17, 0x77, 0xdf, 0xc4, 0x66, 0x7d, 0xf7, 0x1a, 0xd3, 0xbf, - 0xe4, 0x80, 0x74, 0x1f, 0x07, 0x52, 0xf1, 0xa0, 0x74, 0x45, 0xc3, 0x6a, 0x69, 0x80, 0x17, 0xed, - 0xa7, 0xe1, 0x78, 0xb9, 0x52, 0x5b, 0xcb, 0xad, 0x15, 0x72, 0xb5, 0xdc, 0xd9, 0x52, 0xf1, 0xdc, - 0xda, 0xdc, 0x52, 0x25, 0x7f, 0xaf, 0x28, 0xa0, 0xdf, 0x63, 0x63, 0x60, 0x55, 0xef, 0x18, 0xf5, - 0x61, 0xcd, 0x36, 0xdb, 0xb4, 0x30, 0xab, 0xd3, 0x59, 0xa1, 0xa8, 0x8e, 0xeb, 0xae, 0x3f, 0xa6, - 0x4d, 0x5c, 0xbf, 0x8e, 0x96, 0x1a, 0xb2, 0xe3, 0x7a, 0x5f, 0x0a, 0xe2, 0xef, 0x62, 0x3f, 0x11, - 0x00, 0x16, 0x0c, 0xbd, 0xd3, 0xaa, 0x18, 0x0d, 0x6c, 0xa0, 0xa7, 0xdc, 0x55, 0xdf, 0xef, 0x0c, - 0x61, 0xb2, 0xb2, 0x02, 0xb0, 0xe9, 0x14, 0x6e, 0xe9, 0xa9, 0x1b, 0xc3, 0xad, 0xf1, 0x5c, 0xa2, - 0x64, 0x4f, 0x19, 0xe8, 0x53, 0x5e, 0x8c, 0x7f, 0x89, 0xc7, 0x38, 0x68, 0xe4, 0x71, 0x8b, 0x1b, - 0xe6, 0xaa, 0xef, 0x43, 0x0e, 0xd6, 0x35, 0x0e, 0xeb, 0xbb, 0x0f, 0x40, 0x49, 0xfc, 0x98, 0xff, - 0x4c, 0x80, 0x09, 0xb6, 0x17, 0xcb, 0x78, 0xfa, 0x77, 0x2e, 0xe8, 0x6f, 0x18, 0x02, 0xe8, 0xab, - 0x70, 0x54, 0x77, 0x4b, 0x67, 0x23, 0xa3, 0xd7, 0xba, 0x16, 0x08, 0xbb, 0x87, 0x2e, 0x99, 0x2b, - 0x06, 0x7d, 0xda, 0x8b, 0xbc, 0xcc, 0x23, 0x7f, 0x7b, 0x00, 0xbf, 0x3d, 0x25, 0x0e, 0x13, 0xfa, - 0x0f, 0x3b, 0xd0, 0xaf, 0x72, 0xd0, 0xe7, 0x0e, 0x42, 0x4a, 0xfc, 0xd8, 0x3f, 0xe8, 0x18, 0xe8, - 0x9d, 0xed, 0x93, 0x58, 0x36, 0x4d, 0xde, 0x34, 0xe0, 0x02, 0x83, 0xa7, 0xcd, 0x07, 0xa9, 0x29, - 0x48, 0xaa, 0x36, 0x0d, 0x49, 0xb5, 0x31, 0xd0, 0x12, 0x22, 0xb0, 0xa2, 0xf8, 0x71, 0x78, 0xfb, - 0xb3, 0x20, 0x5d, 0xc0, 0xeb, 0x9d, 0x4d, 0xf4, 0x1e, 0x01, 0xb2, 0x4d, 0x7d, 0xb3, 0xa4, 0x6d, - 0xe8, 0x56, 0xc3, 0x12, 0x76, 0xc3, 0x24, 0x09, 0x52, 0x5b, 0x58, 0xb1, 0x9b, 0x4a, 0xff, 0x4b, - 0x57, 0xc3, 0x14, 0xf9, 0xb5, 0x9f, 0x93, 0x75, 0x6e, 0x9f, 0xec, 0x8a, 0x25, 0x13, 0x54, 0x53, - 0x37, 0x95, 0xa6, 0x8c, 0xeb, 0xba, 0xd1, 0x60, 0xa7, 0x45, 0xd2, 0x32, 0x17, 0x47, 0xf0, 0xa6, - 0x61, 0xea, 0xbf, 0x90, 0xa6, 0x09, 0xdc, 0x08, 0xe9, 0x4a, 0x98, 0xdc, 0x50, 0x8d, 0xb6, 0xc9, - 0x52, 0xd7, 0x98, 0x83, 0x4b, 0x5a, 0xe6, 0x23, 0xe9, 0x7b, 0xf6, 0x6e, 0xc4, 0x59, 0x6c, 0xd0, - 0xc7, 0x85, 0xd2, 0x72, 0x57, 0x2c, 0xa1, 0xa7, 0xa9, 0x78, 0x0a, 0x1b, 0x63, 0xf4, 0x78, 0xe3, - 0x48, 0x8d, 0x6e, 0x98, 0x14, 0x35, 0xce, 0x6a, 0xe4, 0x22, 0x49, 0x8d, 0x24, 0x62, 0xa5, 0xd3, - 0x6c, 0x56, 0x71, 0x3d, 0xb7, 0xa9, 0x4f, 0x03, 0xab, 0x91, 0x8f, 0x95, 0x10, 0x8c, 0x75, 0x5a, - 0x55, 0x53, 0x31, 0x3b, 0xed, 0xe9, 0x09, 0xb6, 0x9f, 0x64, 0x87, 0xa5, 0x93, 0x00, 0x0d, 0xfd, - 0xbc, 0x66, 0x7d, 0x3d, 0xca, 0xfc, 0x8d, 0xdc, 0x18, 0xb2, 0x6c, 0x66, 0x22, 0x3b, 0xc9, 0xee, - 0xb0, 0x63, 0xfe, 0x5c, 0x5f, 0x11, 0x00, 0xcc, 0x2d, 0x03, 0x2b, 0x8d, 0x9e, 0x70, 0xbd, 0x10, - 0x4e, 0x34, 0xf5, 0xcd, 0xf6, 0x39, 0xd5, 0xdc, 0x72, 0x81, 0x58, 0xb4, 0x01, 0x4c, 0xcb, 0x3e, - 0x5f, 0xa5, 0xbb, 0xe1, 0x12, 0xfb, 0xcb, 0xb9, 0x2d, 0xbd, 0x89, 0x6b, 0x06, 0xc6, 0x5d, 0xf8, - 0xa6, 0xe5, 0xa0, 0x24, 0xd2, 0x2c, 0xa4, 0xc8, 0x67, 0xeb, 0xa9, 0x6f, 0xc4, 0xc9, 0x3d, 0x15, - 0xb3, 0x59, 0x4b, 0xc4, 0x64, 0x9a, 0x4e, 0xba, 0x05, 0x2e, 0xd6, 0xcf, 0x6b, 0x4b, 0xfa, 0xe6, - 0xa2, 0xd2, 0xce, 0x2b, 0x1b, 0x58, 0xc6, 0xec, 0xd8, 0x94, 0x6e, 0x58, 0xcf, 0xfe, 0xfb, 0x7d, - 0x96, 0x66, 0x41, 0xaa, 0x2b, 0x1b, 0x78, 0x89, 0x07, 0x80, 0x49, 0x46, 0x8f, 0x2f, 0x04, 0x76, - 0x12, 0xbb, 0x6a, 0x03, 0x91, 0x65, 0x07, 0x51, 0xbd, 0x71, 0x04, 0x50, 0x12, 0x2e, 0xb8, 0x80, - 0x8c, 0xd1, 0x54, 0x5d, 0xb1, 0xfb, 0x44, 0x7a, 0xbc, 0x9f, 0x48, 0x43, 0xb7, 0x48, 0x3b, 0xb0, - 0x4e, 0x78, 0x61, 0xfd, 0x7a, 0x1a, 0x52, 0xd5, 0x3d, 0xad, 0x8e, 0xde, 0xe6, 0x19, 0xfe, 0x4e, - 0xc3, 0x71, 0x83, 0x95, 0x59, 0x33, 0x94, 0x5d, 0x6c, 0xb4, 0xf1, 0x12, 0xb5, 0xa3, 0x24, 0x68, - 0x99, 0x3d, 0xbf, 0x11, 0xf9, 0x6d, 0x6f, 0xab, 0xad, 0xe2, 0x4e, 0xcb, 0xdc, 0x5b, 0x22, 0x78, - 0x24, 0xd9, 0x2d, 0x50, 0x5c, 0xa4, 0x74, 0x27, 0x20, 0xd3, 0xd8, 0xab, 0xe9, 0x36, 0x7e, 0x32, - 0xde, 0xd1, 0x4d, 0x6c, 0x37, 0x8a, 0xf5, 0xe6, 0x80, 0x14, 0xe8, 0xdd, 0x29, 0x8f, 0x6e, 0xbd, - 0x9d, 0xd7, 0xad, 0x57, 0xf7, 0x80, 0x9e, 0x34, 0xcd, 0x47, 0x93, 0xbe, 0x08, 0xb2, 0x4c, 0x9e, - 0xed, 0x55, 0xca, 0x65, 0x3d, 0xf2, 0xbb, 0x12, 0x2f, 0xdb, 0xa9, 0x49, 0xdf, 0x6a, 0xe0, 0x5d, - 0xb5, 0x8e, 0x5d, 0x7f, 0x32, 0x3b, 0xec, 0xc0, 0x54, 0xb3, 0x4a, 0xf6, 0x6a, 0x1e, 0x2b, 0x8e, - 0xf2, 0x80, 0xfd, 0x25, 0x22, 0xad, 0x77, 0x4c, 0x22, 0x62, 0x25, 0xad, 0x42, 0xa5, 0xce, 0x52, - 0x45, 0x01, 0x29, 0xa4, 0x39, 0xb8, 0x94, 0xff, 0xba, 0xc8, 0xeb, 0x44, 0x26, 0x90, 0x81, 0x69, - 0xf6, 0x89, 0x53, 0xb6, 0x9f, 0x38, 0x8d, 0x75, 0x89, 0x13, 0x7a, 0xb3, 0x33, 0xf0, 0xdc, 0xc5, - 0x0d, 0x3c, 0xd7, 0x86, 0x43, 0x61, 0x24, 0xd7, 0x65, 0x65, 0x18, 0xcb, 0xd1, 0x2b, 0x3c, 0xb2, - 0x8d, 0x60, 0xcc, 0x02, 0xd5, 0x56, 0x5f, 0x4e, 0x78, 0x44, 0x32, 0xfc, 0x96, 0xd0, 0xaf, 0x66, - 0x30, 0xee, 0xb1, 0x46, 0xf8, 0x48, 0xf1, 0x4d, 0x90, 0x52, 0xb5, 0x0d, 0xdd, 0x9a, 0xb8, 0xf5, - 0x11, 0x61, 0x9a, 0x34, 0xe4, 0x33, 0x19, 0x01, 0x75, 0xc7, 0x8f, 0xdd, 0xab, 0x05, 0x48, 0x11, - 0x35, 0xef, 0xbd, 0xf7, 0x13, 0xc1, 0x18, 0x9b, 0x14, 0xbb, 0xc0, 0xd9, 0xe1, 0x9e, 0x6f, 0x87, - 0xcc, 0xc0, 0xd1, 0x8e, 0xa6, 0x68, 0xba, 0xb6, 0xb7, 0xa3, 0xbe, 0xc4, 0x99, 0x2a, 0x70, 0x71, - 0x84, 0xfa, 0x4d, 0xac, 0x61, 0x43, 0x31, 0x71, 0x75, 0x77, 0x93, 0xf6, 0xd6, 0x31, 0xd9, 0x1b, - 0x85, 0x1e, 0x4c, 0x46, 0x53, 0x38, 0x84, 0x6a, 0xff, 0x27, 0x2a, 0x37, 0xd4, 0x26, 0xa6, 0xfe, - 0xed, 0x96, 0x8f, 0x87, 0x1d, 0x8e, 0xd4, 0x9b, 0x7a, 0x54, 0x31, 0x12, 0x44, 0x44, 0xf6, 0x66, - 0xca, 0x92, 0x5e, 0x57, 0x9a, 0x6d, 0x53, 0x37, 0x30, 0x7a, 0x81, 0x8b, 0x8e, 0x8d, 0x40, 0xc2, - 0x83, 0xc0, 0x09, 0xc8, 0x34, 0xf4, 0xba, 0xeb, 0xc9, 0x60, 0x85, 0xf8, 0xe5, 0x4c, 0xe0, 0x31, - 0x22, 0xd6, 0xe0, 0xee, 0x7a, 0x63, 0x7b, 0x40, 0x26, 0xdc, 0xd1, 0xa2, 0x50, 0x44, 0x8d, 0xe0, - 0x5e, 0x85, 0x24, 0xa4, 0x56, 0x54, 0x6d, 0xd3, 0xbb, 0x88, 0x39, 0x0e, 0x69, 0x55, 0x6b, 0xe0, - 0x0b, 0xd6, 0x48, 0xcd, 0x02, 0x64, 0x38, 0xd7, 0x3a, 0x3b, 0xeb, 0xd8, 0xa8, 0x6c, 0xd0, 0xe6, - 0xb6, 0x6b, 0x7a, 0x15, 0x6b, 0xf6, 0xcc, 0xac, 0xe7, 0x37, 0xf4, 0x8b, 0x44, 0x34, 0xb9, 0x27, - 0x94, 0xf8, 0xe0, 0xe2, 0x10, 0x95, 0xf4, 0x10, 0x15, 0x49, 0xe2, 0x7b, 0x14, 0x1e, 0x3f, 0x7f, - 0x3f, 0x9f, 0x84, 0xec, 0x32, 0x36, 0x0d, 0xb5, 0xde, 0x46, 0x4f, 0x24, 0x61, 0xb2, 0x8a, 0xcd, - 0x15, 0xc5, 0x50, 0x76, 0xb0, 0x49, 0x96, 0xe4, 0xd7, 0x72, 0x8a, 0xa9, 0xd5, 0x54, 0xcc, 0x0d, - 0xdd, 0xd8, 0xb1, 0x15, 0x93, 0x1d, 0xbe, 0x35, 0xf5, 0xf0, 0xf7, 0x85, 0x04, 0xcf, 0xcc, 0x40, - 0xd7, 0x1b, 0xab, 0xc2, 0x59, 0xae, 0x32, 0x9f, 0x13, 0x16, 0xe1, 0x9c, 0x69, 0xc2, 0x94, 0x18, - 0x3f, 0x33, 0xff, 0x58, 0x00, 0x61, 0x49, 0xdf, 0x44, 0x1f, 0x13, 0x20, 0x45, 0xe5, 0xeb, 0xbd, - 0x9e, 0x21, 0x79, 0x1a, 0xb2, 0x3b, 0xb8, 0xdd, 0x56, 0x36, 0xb1, 0xfd, 0xbe, 0xb4, 0x15, 0x94, - 0xce, 0x40, 0xba, 0x89, 0x77, 0x71, 0x93, 0x92, 0x31, 0x75, 0xfa, 0x0a, 0xae, 0x65, 0x4b, 0xfa, - 0xe6, 0x2c, 0x29, 0xcb, 0x79, 0x85, 0x76, 0x89, 0x24, 0x95, 0x59, 0x8e, 0x99, 0x7b, 0x20, 0x4d, - 0xc3, 0xd2, 0x38, 0xa4, 0x0b, 0xc5, 0xb9, 0xd5, 0x05, 0xf1, 0x08, 0xf9, 0x6b, 0xd3, 0x37, 0x0e, - 0xe9, 0xf9, 0x5c, 0x2d, 0xb7, 0x24, 0x26, 0x49, 0x3b, 0x4a, 0xe5, 0xf9, 0x8a, 0x28, 0x90, 0xc8, - 0x95, 0x5c, 0xb9, 0x94, 0x17, 0x53, 0xd2, 0x04, 0x64, 0xcf, 0xe5, 0xe4, 0x72, 0xa9, 0xbc, 0x20, - 0xa6, 0xd1, 0x03, 0x5e, 0x85, 0x75, 0x2b, 0x8f, 0xdf, 0x95, 0x7e, 0x34, 0xf5, 0x82, 0xec, 0xdf, - 0x39, 0x90, 0xdd, 0xc1, 0x41, 0xf6, 0xbc, 0x30, 0x85, 0x44, 0x43, 0xa9, 0x3c, 0x80, 0x21, 0x7b, - 0x12, 0xc6, 0xcb, 0x95, 0xda, 0xda, 0x7c, 0x65, 0xb5, 0x5c, 0x10, 0x31, 0xe1, 0x41, 0xad, 0xb4, - 0x5c, 0xac, 0xac, 0xd6, 0xc4, 0x0d, 0xf4, 0xb6, 0x24, 0x64, 0x57, 0x0c, 0xbd, 0x8e, 0xdb, 0x6d, - 0xf4, 0xfa, 0x24, 0x64, 0xf2, 0x8a, 0x56, 0xc7, 0x4d, 0xf4, 0x2c, 0x17, 0xc6, 0xae, 0x25, 0x21, - 0xfa, 0x89, 0x57, 0xea, 0xef, 0xe6, 0xb9, 0xc6, 0xbf, 0x2b, 0x6c, 0x95, 0x3b, 0xcb, 0xca, 0xf4, - 0xe1, 0xdd, 0x63, 0x0e, 0xef, 0xf2, 0x1c, 0xef, 0x6e, 0x08, 0x5f, 0x54, 0xfc, 0x72, 0xfe, 0xd3, - 0x04, 0x1c, 0x5f, 0x20, 0xd3, 0x07, 0xb5, 0xce, 0x88, 0xb7, 0xdb, 0x7f, 0x07, 0xdf, 0xfe, 0xe7, - 0x72, 0x44, 0xf7, 0xca, 0xc1, 0x37, 0xfe, 0x51, 0xa7, 0xf1, 0x77, 0x73, 0x8d, 0xbf, 0x2e, 0x64, - 0x39, 0xb1, 0xb7, 0x7c, 0x26, 0x0b, 0x69, 0x3a, 0x45, 0x9e, 0xb9, 0x0a, 0x26, 0xab, 0xa6, 0x81, - 0x95, 0x1d, 0xcf, 0xa0, 0x64, 0xea, 0xdb, 0x58, 0xb3, 0x44, 0x83, 0x05, 0x6e, 0x3d, 0x03, 0x59, - 0x4d, 0x5f, 0x53, 0x3a, 0xe6, 0x96, 0xf4, 0xec, 0x7d, 0xc7, 0x86, 0x96, 0x59, 0xff, 0xaf, 0xb4, - 0xd8, 0x2e, 0xd2, 0x77, 0x6f, 0xa7, 0x13, 0xb3, 0x8c, 0xa6, 0xe7, 0x3a, 0xe6, 0xd6, 0xdc, 0xa5, - 0x9f, 0x7b, 0xea, 0x64, 0xe2, 0x8b, 0x4f, 0x9d, 0x4c, 0x7c, 0xe7, 0xa9, 0x93, 0x89, 0xdf, 0xfe, - 0xde, 0xc9, 0x23, 0x5f, 0xfc, 0xde, 0xc9, 0x23, 0xdf, 0xf8, 0xde, 0xc9, 0x23, 0xbf, 0x92, 0x6c, - 0xad, 0xaf, 0x67, 0x68, 0x29, 0x37, 0xff, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x27, 0x7f, 0x27, - 0x80, 0x12, 0x32, 0x01, 0x00, + // 11749 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x7d, 0x7b, 0x74, 0x2c, 0x47, + 0x79, 0xe7, 0x9d, 0xe9, 0x79, 0x48, 0x9f, 0xae, 0x74, 0xdb, 0x9d, 0xcb, 0xb5, 0x28, 0xdb, 0x17, + 0x47, 0xb6, 0x2f, 0xce, 0xb5, 0x2d, 0xdb, 0xd7, 0x3c, 0x7c, 0xfd, 0x1e, 0xcd, 0x8c, 0xa4, 0xb1, + 0xa5, 0x19, 0xa5, 0x67, 0x74, 0x6f, 0x9c, 0x6c, 0x56, 0xdb, 0x9a, 0x29, 0x49, 0xed, 0x3b, 0x9a, + 0x9e, 0xf4, 0xb4, 0x74, 0xaf, 0x38, 0x67, 0x37, 0x71, 0x12, 0xc7, 0x4e, 0x72, 0x08, 0x09, 0x49, + 0x16, 0x1c, 0x16, 0x0c, 0xe6, 0x0d, 0x21, 0xc4, 0x3c, 0x97, 0x2c, 0x90, 0x25, 0x40, 0x0e, 0xe1, + 0x24, 0x98, 0xf0, 0x4e, 0x16, 0x08, 0x18, 0x96, 0x25, 0xbb, 0xb0, 0x1c, 0x72, 0x76, 0x37, 0xcb, + 0x92, 0x2c, 0x7b, 0xea, 0xd1, 0x8f, 0x1a, 0x4d, 0xf7, 0x74, 0x8f, 0xa6, 0x47, 0xce, 0xe6, 0xaf, + 0x99, 0xaa, 0xae, 0xc7, 0x57, 0xdf, 0xef, 0xab, 0xaf, 0xaa, 0xbe, 0xfa, 0xaa, 0x0a, 0xa6, 0xdb, + 0xeb, 0x37, 0xb7, 0x4d, 0xc3, 0x32, 0x3a, 0x37, 0xd7, 0x8d, 0xed, 0x6d, 0xad, 0xd5, 0xe8, 0xcc, + 0xd2, 0xb0, 0x92, 0xd5, 0x5a, 0x7b, 0xd6, 0x5e, 0x1b, 0xa3, 0x6b, 0xdb, 0x17, 0x36, 0x6f, 0x6e, + 0xea, 0xeb, 0x37, 0xb7, 0xd7, 0x6f, 0xde, 0x36, 0x1a, 0xb8, 0x69, 0x67, 0xa0, 0x01, 0x9e, 0x1c, + 0x5d, 0xef, 0x97, 0xaa, 0x69, 0xd4, 0xb5, 0x66, 0xc7, 0x32, 0x4c, 0xcc, 0x53, 0x9e, 0x70, 0xab, + 0xc4, 0xbb, 0xb8, 0x65, 0xd9, 0x25, 0x5c, 0xb9, 0x69, 0x18, 0x9b, 0x4d, 0xcc, 0xbe, 0xad, 0xef, + 0x6c, 0xdc, 0xdc, 0xb1, 0xcc, 0x9d, 0xba, 0xc5, 0xbf, 0x5e, 0xdd, 0xfd, 0xb5, 0x81, 0x3b, 0x75, + 0x53, 0x6f, 0x5b, 0x86, 0xc9, 0x52, 0xcc, 0x7c, 0xfe, 0x99, 0x14, 0x48, 0x6a, 0xbb, 0x8e, 0x3e, + 0x35, 0x06, 0x52, 0xae, 0xdd, 0x46, 0xdf, 0x4f, 0x02, 0x2c, 0x60, 0xeb, 0x1c, 0x36, 0x3b, 0xba, + 0xd1, 0x42, 0xe3, 0x90, 0x55, 0xf1, 0xcf, 0xed, 0xe0, 0x8e, 0x85, 0xbe, 0x98, 0x84, 0x31, 0x15, + 0x77, 0xda, 0x46, 0xab, 0x83, 0x95, 0xfb, 0x20, 0x8d, 0x4d, 0xd3, 0x30, 0xa7, 0x13, 0x57, 0x27, + 0xae, 0x9f, 0x38, 0x73, 0x7a, 0x96, 0x37, 0x7c, 0x56, 0x6d, 0xd7, 0x67, 0x73, 0xed, 0xf6, 0xac, + 0x5b, 0xc6, 0xac, 0x9d, 0x69, 0xb6, 0x48, 0x72, 0xa8, 0x2c, 0xa3, 0x32, 0x0d, 0xd9, 0x5d, 0x96, + 0x60, 0x3a, 0x79, 0x75, 0xe2, 0xfa, 0x71, 0xd5, 0x0e, 0x92, 0x2f, 0x0d, 0x6c, 0x69, 0x7a, 0xb3, + 0x33, 0x2d, 0xb1, 0x2f, 0x3c, 0x88, 0x3e, 0x97, 0x80, 0x34, 0x2d, 0x44, 0xc9, 0x43, 0xaa, 0x6e, + 0x34, 0x30, 0xad, 0x7e, 0xea, 0xcc, 0xcd, 0xe1, 0xab, 0x9f, 0xcd, 0x1b, 0x0d, 0xac, 0xd2, 0xcc, + 0xca, 0xd5, 0x30, 0x61, 0x33, 0xc4, 0x25, 0xc3, 0x1b, 0x35, 0xd3, 0x80, 0x14, 0x49, 0xaf, 0x8c, + 0x41, 0xaa, 0xbc, 0xba, 0xb4, 0x24, 0x1f, 0x51, 0x2e, 0x83, 0xc9, 0xd5, 0xf2, 0x03, 0xe5, 0xca, + 0xf9, 0xf2, 0x5a, 0x51, 0x55, 0x2b, 0xaa, 0x9c, 0x50, 0x26, 0x61, 0x7c, 0x2e, 0x57, 0x58, 0x2b, + 0x95, 0x57, 0x56, 0x6b, 0x72, 0x52, 0x39, 0x0e, 0xf2, 0xb9, 0xa2, 0x5a, 0x2d, 0x55, 0xca, 0x6b, + 0xa5, 0xea, 0x5a, 0x71, 0x79, 0xa5, 0xf6, 0xa0, 0x2c, 0x91, 0x44, 0xe5, 0x4a, 0x6d, 0x6d, 0xbe, + 0xb2, 0x5a, 0x2e, 0xc8, 0x58, 0x99, 0x80, 0x6c, 0xad, 0xb4, 0x5c, 0xac, 0xac, 0xd6, 0xe4, 0x0d, + 0xf4, 0x1e, 0x09, 0xa6, 0xaa, 0xd8, 0x2a, 0xe0, 0x5d, 0xbd, 0x8e, 0xab, 0x96, 0x66, 0x61, 0xf4, + 0xb2, 0x84, 0xc3, 0x78, 0x65, 0x95, 0x90, 0xe9, 0x7c, 0xe2, 0x4d, 0xbe, 0x6d, 0x5f, 0x93, 0xc5, + 0x12, 0x66, 0x79, 0xee, 0x59, 0x4f, 0x9c, 0xea, 0x2d, 0x67, 0xe6, 0x26, 0x98, 0xf0, 0x7c, 0x53, + 0xa6, 0x00, 0xe6, 0x72, 0xf9, 0x07, 0x16, 0x54, 0x4a, 0xe1, 0x11, 0x12, 0x9e, 0xaf, 0xa8, 0x45, + 0x1e, 0x4e, 0xa0, 0x97, 0x79, 0xe1, 0x2f, 0x88, 0xf0, 0xcf, 0xf6, 0x27, 0xa6, 0x87, 0x08, 0xa0, + 0x0f, 0x3a, 0x70, 0x2e, 0x08, 0x70, 0xde, 0x16, 0xad, 0xb8, 0x68, 0x90, 0x2e, 0x0e, 0x06, 0x69, + 0xb9, 0x52, 0x28, 0xae, 0x11, 0x04, 0xab, 0xb5, 0x9c, 0x5a, 0x2b, 0x16, 0x64, 0x8c, 0x5e, 0x95, + 0x84, 0xb1, 0xea, 0xd6, 0x8e, 0xd5, 0x30, 0x2e, 0x0a, 0x1d, 0xe5, 0x97, 0xbc, 0x9c, 0xba, 0x47, + 0xe4, 0xd4, 0xf5, 0xfb, 0x9b, 0xc6, 0x4b, 0xf0, 0xe1, 0xd1, 0xfb, 0x1c, 0x1e, 0xe5, 0x04, 0x1e, + 0xdd, 0x14, 0xb6, 0xa0, 0xc3, 0xe2, 0xce, 0xe7, 0x27, 0x21, 0x73, 0x5e, 0x6b, 0x36, 0xb1, 0x85, + 0xbe, 0x99, 0x84, 0x4c, 0xde, 0xc4, 0x44, 0xae, 0x6f, 0x70, 0xc5, 0x1a, 0xc1, 0x98, 0x69, 0x18, + 0xd6, 0x8a, 0x66, 0x6d, 0xd1, 0x36, 0x8d, 0xab, 0x4e, 0xf8, 0x8e, 0xd4, 0x63, 0xdf, 0x92, 0x12, + 0xe8, 0xf7, 0xbd, 0x8c, 0xbc, 0x57, 0x64, 0xe4, 0x4f, 0x08, 0xed, 0x67, 0x15, 0xcd, 0xb2, 0x4a, + 0x7c, 0x14, 0x0e, 0x82, 0xb1, 0xed, 0x16, 0xde, 0x36, 0x5a, 0x7a, 0x9d, 0xb7, 0xdc, 0x09, 0xa3, + 0x3f, 0x71, 0xb8, 0x3c, 0x27, 0x70, 0x79, 0x36, 0x74, 0x2d, 0xd1, 0xd8, 0x5c, 0x1d, 0x80, 0xcd, + 0xcf, 0x83, 0x2b, 0xe6, 0x73, 0xa5, 0xa5, 0x62, 0x61, 0xad, 0x56, 0x59, 0xcb, 0xab, 0xc5, 0x5c, + 0xad, 0xb8, 0xb6, 0x54, 0xc9, 0xe7, 0x96, 0xd6, 0xd4, 0xe2, 0x4a, 0x45, 0xc6, 0xe8, 0xbf, 0x24, + 0x09, 0x73, 0xeb, 0xc6, 0x2e, 0x36, 0xd1, 0x42, 0x28, 0x3e, 0x07, 0xf1, 0x84, 0x63, 0xf0, 0xf2, + 0xd0, 0x5a, 0x9f, 0x73, 0x87, 0x53, 0xe0, 0x23, 0xce, 0x1f, 0x0d, 0xa5, 0xc1, 0x03, 0x8b, 0x7a, + 0x16, 0x70, 0xfa, 0x7f, 0x24, 0x21, 0x9b, 0x37, 0x5a, 0xbb, 0xd8, 0xb4, 0xd0, 0xbd, 0x02, 0xa7, + 0x1d, 0x6e, 0x26, 0x44, 0x6e, 0x92, 0x41, 0x0d, 0xb7, 0x2c, 0xd3, 0x68, 0xef, 0xd9, 0xc3, 0x1d, + 0x0f, 0xa2, 0x37, 0x47, 0xe5, 0x30, 0xaf, 0xd9, 0x7f, 0x5c, 0xed, 0x5d, 0x91, 0x40, 0x9e, 0xd4, + 0xd5, 0x01, 0x9e, 0x8c, 0x82, 0x4b, 0x6f, 0x02, 0xa2, 0xe1, 0x72, 0x26, 0x3a, 0x2e, 0xe8, 0x33, + 0x49, 0x98, 0x64, 0x9d, 0xaf, 0x8a, 0x3b, 0x74, 0x7a, 0x72, 0x43, 0x28, 0xe6, 0x73, 0x51, 0xfe, + 0x6d, 0x2f, 0xa3, 0xe7, 0x45, 0x46, 0xdf, 0xe2, 0xdf, 0xd1, 0x79, 0x5d, 0x3e, 0xec, 0x3e, 0x0e, + 0x69, 0xcb, 0xb8, 0x80, 0xed, 0x36, 0xb2, 0x00, 0x7a, 0x8b, 0xc3, 0xce, 0x92, 0xc0, 0xce, 0x17, + 0x46, 0xad, 0x26, 0x7e, 0xa6, 0xbe, 0x23, 0x09, 0x47, 0xf3, 0x4d, 0xa3, 0xe3, 0xf0, 0xf4, 0x79, + 0x2e, 0x4f, 0x9d, 0xc6, 0x25, 0xbc, 0x8d, 0xfb, 0x61, 0xc2, 0xc3, 0xc7, 0xa2, 0xc8, 0xc7, 0xde, + 0xf2, 0xe2, 0x29, 0xde, 0x47, 0x2f, 0xbc, 0xd9, 0x61, 0xd8, 0xa2, 0xc0, 0xb0, 0x17, 0x44, 0x2c, + 0x2f, 0x7e, 0x7e, 0xbd, 0xef, 0xc7, 0x21, 0x9b, 0xab, 0xd7, 0x8d, 0x9d, 0x96, 0x85, 0xfe, 0x26, + 0x01, 0x99, 0xbc, 0xd1, 0xda, 0xd0, 0x37, 0x95, 0x53, 0x30, 0x85, 0x5b, 0xda, 0x7a, 0x13, 0x17, + 0x34, 0x4b, 0xdb, 0xd5, 0xf1, 0x45, 0xda, 0x80, 0x31, 0xb5, 0x2b, 0x96, 0x10, 0xc5, 0x63, 0xf0, + 0xfa, 0xce, 0x26, 0x25, 0x6a, 0x4c, 0xf5, 0x46, 0x29, 0xb7, 0xc3, 0xe5, 0x2c, 0xb8, 0x62, 0x62, + 0x13, 0x37, 0xb1, 0xd6, 0xc1, 0xf9, 0x2d, 0xad, 0xd5, 0xc2, 0x4d, 0xda, 0x6b, 0xc7, 0x54, 0xbf, + 0xcf, 0xca, 0x0c, 0x1c, 0x65, 0x9f, 0xaa, 0x6d, 0xad, 0x8e, 0x3b, 0xd3, 0x29, 0x9a, 0x5c, 0x88, + 0x53, 0x6e, 0x82, 0x34, 0xbe, 0x64, 0x99, 0xda, 0x74, 0x83, 0xe2, 0x75, 0xf9, 0x2c, 0x5b, 0x22, + 0xcc, 0xda, 0x4b, 0x84, 0xd9, 0x2a, 0x5d, 0x40, 0xa8, 0x2c, 0x15, 0xfa, 0x68, 0xc6, 0x19, 0xba, + 0x5f, 0xe7, 0x99, 0x92, 0x2a, 0x90, 0x6a, 0x69, 0xdb, 0x98, 0xcb, 0x05, 0xfd, 0xaf, 0x9c, 0x86, + 0x63, 0xda, 0xae, 0x66, 0x69, 0xe6, 0x12, 0x59, 0xbc, 0xd0, 0xe1, 0x86, 0xb2, 0x7c, 0xf1, 0x88, + 0xda, 0xfd, 0x41, 0xb9, 0x12, 0xc6, 0xe9, 0xea, 0x86, 0xa6, 0x62, 0xba, 0xc8, 0x8d, 0x50, 0xae, + 0x87, 0x63, 0x5a, 0xb3, 0xbd, 0xa5, 0x95, 0x5a, 0xbb, 0xba, 0x85, 0x09, 0x42, 0xd3, 0xc7, 0x69, + 0x9a, 0xee, 0x68, 0xd6, 0xb1, 0xe7, 0xc6, 0x20, 0xc3, 0x2a, 0x40, 0xbf, 0x93, 0x0e, 0xbd, 0x46, + 0x61, 0x10, 0x06, 0x4f, 0x19, 0x6e, 0x81, 0xac, 0xc6, 0xd2, 0xd1, 0xa6, 0x4c, 0x9c, 0x39, 0xe1, + 0x94, 0x41, 0x97, 0x6b, 0x76, 0x29, 0xaa, 0x9d, 0x4c, 0xb9, 0x0d, 0x32, 0x75, 0x2a, 0x10, 0xb4, + 0x55, 0x13, 0x67, 0xae, 0xe8, 0x5d, 0x29, 0x4d, 0xa2, 0xf2, 0xa4, 0xe8, 0xab, 0x52, 0xa8, 0x65, + 0x4d, 0x10, 0xc5, 0xd1, 0xe4, 0xfe, 0xbb, 0xc9, 0x01, 0x46, 0xc5, 0x1b, 0xe1, 0xfa, 0x5c, 0x3e, + 0x5f, 0x59, 0x2d, 0xd7, 0xf8, 0x98, 0x58, 0x58, 0x9b, 0x5b, 0xad, 0xad, 0xb9, 0x23, 0x25, 0x9d, + 0xfb, 0xad, 0x91, 0xa9, 0xa0, 0x4c, 0xa4, 0xe1, 0x54, 0x9f, 0xd4, 0xc5, 0xda, 0x5a, 0x39, 0xb7, + 0x5c, 0x94, 0x37, 0x42, 0x94, 0x5c, 0xac, 0xad, 0xe5, 0xce, 0xe5, 0x6a, 0x39, 0x55, 0xde, 0x14, + 0x47, 0xe7, 0x6a, 0xad, 0xb2, 0xb2, 0xa6, 0xae, 0x96, 0xcb, 0xa5, 0xf2, 0x02, 0xab, 0x9a, 0x4c, + 0x6a, 0x4e, 0xb8, 0x09, 0xce, 0xab, 0xa5, 0x5a, 0x71, 0x2d, 0x5f, 0x29, 0xcf, 0x97, 0x16, 0x64, + 0xbd, 0xdf, 0xd0, 0xfe, 0x90, 0x72, 0x1c, 0x8e, 0xb1, 0x46, 0x9f, 0x63, 0xf9, 0x0a, 0x45, 0xf9, + 0x97, 0xb3, 0xca, 0x14, 0x8c, 0x97, 0x8b, 0x35, 0xce, 0x99, 0x47, 0xb2, 0xca, 0x15, 0x70, 0x82, + 0x84, 0xf3, 0x95, 0x72, 0xb9, 0x98, 0xaf, 0x91, 0xa5, 0x9e, 0x5a, 0x9c, 0x5f, 0xad, 0x16, 0x0b, + 0xf2, 0xaf, 0x64, 0x15, 0x19, 0x26, 0xc8, 0xc7, 0xca, 0xfc, 0xfc, 0x52, 0xa9, 0x5c, 0x94, 0x1f, + 0xcd, 0xa2, 0x37, 0xa6, 0xdc, 0x99, 0x99, 0x67, 0xa1, 0xf0, 0x1b, 0x29, 0x8f, 0xb4, 0xe6, 0x44, + 0x69, 0xbd, 0xa1, 0x27, 0xf6, 0xc1, 0x93, 0xab, 0x0f, 0x3b, 0x72, 0x54, 0x10, 0xe4, 0xe8, 0x96, + 0x08, 0x65, 0x45, 0x13, 0xa4, 0x3f, 0x1f, 0x44, 0x90, 0x9e, 0x03, 0x97, 0x95, 0x2b, 0x6b, 0x1c, + 0xf1, 0xaa, 0xb3, 0x24, 0xbe, 0x1a, 0xae, 0x2c, 0x17, 0x19, 0x30, 0x6a, 0x31, 0x5f, 0x39, 0x57, + 0x54, 0xd7, 0xce, 0xe7, 0x96, 0x96, 0x8a, 0xb5, 0xb5, 0xf9, 0x92, 0x5a, 0xad, 0xc9, 0x1b, 0xfd, + 0xc0, 0xdb, 0x54, 0xae, 0x81, 0xe7, 0xb9, 0xe1, 0xb5, 0xe2, 0x4f, 0x95, 0xaa, 0xb5, 0x2a, 0x15, + 0xa5, 0x7c, 0x45, 0x55, 0x57, 0x57, 0xc8, 0xc2, 0x64, 0x4b, 0x39, 0x01, 0x8a, 0x5b, 0x8a, 0xba, + 0x5a, 0x66, 0x62, 0xa3, 0x93, 0xfa, 0x79, 0x7d, 0x76, 0xf5, 0x64, 0x41, 0xb3, 0x52, 0x54, 0xe7, + 0x2b, 0xea, 0x72, 0xb1, 0x20, 0x3f, 0xd4, 0x4f, 0xf2, 0x2e, 0x28, 0xa7, 0x60, 0x26, 0x57, 0xae, + 0xd4, 0x16, 0x8b, 0xea, 0x5a, 0xae, 0xfc, 0x60, 0xed, 0xc1, 0x95, 0xe2, 0xda, 0x8a, 0x5a, 0xc9, + 0x17, 0xab, 0xd5, 0xb5, 0x52, 0xd5, 0x4e, 0x2c, 0x37, 0x09, 0x09, 0xb6, 0xc0, 0x97, 0xaa, 0x6b, + 0x85, 0xe2, 0x52, 0x91, 0x90, 0xb6, 0x8d, 0x5e, 0x2a, 0x41, 0xa6, 0x80, 0x9b, 0xd8, 0xc2, 0xe8, + 0xc7, 0x5d, 0x65, 0x7b, 0x02, 0x32, 0x26, 0x26, 0x13, 0x2e, 0x3e, 0xa4, 0xf0, 0x10, 0xfa, 0x9b, + 0x64, 0x54, 0x65, 0xc7, 0xca, 0xf6, 0x51, 0x76, 0x2f, 0x84, 0x4c, 0xc7, 0xd2, 0xac, 0x9d, 0x0e, + 0xd7, 0x75, 0x57, 0xf5, 0xd6, 0x75, 0xb3, 0x55, 0x9a, 0x48, 0xe5, 0x89, 0xd1, 0x5f, 0x25, 0xa2, + 0x28, 0xaf, 0x9e, 0x14, 0x44, 0x93, 0x39, 0x7d, 0x00, 0x91, 0x3b, 0x09, 0xc8, 0xc3, 0xf0, 0xdc, + 0x92, 0x5a, 0xcc, 0x15, 0x1e, 0x74, 0x18, 0x8f, 0x89, 0x48, 0x7a, 0xbf, 0xe7, 0x6b, 0xa5, 0x73, + 0x45, 0x79, 0x03, 0x7d, 0x34, 0x0d, 0x99, 0x2a, 0x6e, 0xe2, 0xba, 0x85, 0xee, 0x74, 0xf1, 0x98, + 0x82, 0xa4, 0xde, 0xe0, 0x43, 0x5f, 0x52, 0x6f, 0x08, 0x0b, 0xac, 0x64, 0xcf, 0x85, 0xec, 0x0f, + 0x53, 0x51, 0x91, 0x62, 0xb5, 0x1e, 0xee, 0xb0, 0xf4, 0xf1, 0x48, 0xc3, 0x52, 0x4f, 0x8a, 0xa3, + 0x21, 0xfb, 0xb9, 0x64, 0x0c, 0x8b, 0xb5, 0x30, 0x4a, 0x61, 0xc3, 0x47, 0x29, 0x74, 0x0d, 0x36, + 0xf3, 0xa5, 0x72, 0x61, 0xcd, 0x91, 0x93, 0xf2, 0x7c, 0x45, 0xde, 0x52, 0x66, 0xe1, 0xb4, 0xa7, + 0x74, 0xa2, 0x31, 0x78, 0x0d, 0xb9, 0x72, 0x61, 0x6d, 0xb9, 0x5c, 0x5c, 0xae, 0x94, 0x4b, 0x79, + 0x66, 0x1a, 0x29, 0xd6, 0x98, 0x96, 0xe9, 0xd2, 0x21, 0xd5, 0x62, 0x4e, 0xcd, 0x2f, 0x52, 0x75, + 0x53, 0x28, 0xca, 0x0f, 0x29, 0xcf, 0x87, 0x6b, 0x3c, 0xa4, 0x70, 0x55, 0xb4, 0xa2, 0x16, 0x0b, + 0xc5, 0xf9, 0x52, 0x99, 0x0c, 0x8d, 0x4b, 0x95, 0xfc, 0x03, 0xd5, 0xf0, 0xda, 0x06, 0xfd, 0x9f, + 0x24, 0xa4, 0xaa, 0x96, 0xd1, 0x46, 0x3f, 0xe1, 0xca, 0xf0, 0x49, 0x00, 0x13, 0x6f, 0x1b, 0xbb, + 0x74, 0x62, 0xca, 0xf5, 0x8a, 0x27, 0x06, 0xfd, 0x69, 0x78, 0x1b, 0x96, 0xa3, 0x16, 0x8c, 0xb6, + 0xcf, 0xb8, 0xf4, 0x83, 0x70, 0x36, 0x2c, 0xff, 0x82, 0xa2, 0x89, 0xd1, 0xaf, 0x25, 0x06, 0x10, + 0x23, 0x04, 0x27, 0x3c, 0x1a, 0x80, 0xe0, 0x65, 0x33, 0x10, 0x2b, 0x97, 0xc3, 0x8f, 0x75, 0x61, + 0x46, 0xa1, 0xda, 0x50, 0x7e, 0x1c, 0xae, 0xf2, 0x42, 0xb5, 0x5c, 0x39, 0x57, 0x74, 0xe4, 0xa3, + 0x90, 0xab, 0xe5, 0xe4, 0x4d, 0xf4, 0x59, 0x09, 0x52, 0xcb, 0xc6, 0x2e, 0x46, 0xd7, 0xb8, 0xcc, + 0x9f, 0x86, 0x6c, 0x0b, 0x5f, 0xf4, 0x18, 0x64, 0xec, 0x20, 0x7a, 0xa3, 0x14, 0x95, 0xed, 0xa4, + 0x6c, 0x1f, 0xb6, 0x7f, 0x29, 0x19, 0x85, 0xed, 0x3d, 0x0a, 0x8a, 0xc6, 0xf6, 0xbf, 0x1d, 0x84, + 0xed, 0x3e, 0xac, 0xc5, 0xca, 0x0c, 0x9c, 0x74, 0x3f, 0x94, 0x0a, 0xc5, 0x72, 0xad, 0x34, 0xff, + 0xa0, 0xcb, 0xdc, 0x92, 0x1a, 0x8a, 0xfd, 0xfd, 0xb4, 0x43, 0xf0, 0x64, 0x71, 0x1a, 0x8e, 0xbb, + 0xdf, 0x16, 0xd8, 0x7c, 0x8f, 0x7c, 0x79, 0x08, 0xbd, 0x3c, 0x0d, 0x47, 0x99, 0xb6, 0x5c, 0x6d, + 0x37, 0xc8, 0xe2, 0xe8, 0x3a, 0xc1, 0x10, 0x61, 0xe9, 0xdb, 0xf8, 0xa7, 0x8d, 0x96, 0xbd, 0x3e, + 0x72, 0xc2, 0xe8, 0xd3, 0xa1, 0x4d, 0x10, 0xa2, 0x4e, 0x66, 0xb5, 0xf8, 0xe0, 0xfc, 0xc3, 0x50, + 0xc6, 0x86, 0x10, 0x05, 0x46, 0xc3, 0xfb, 0x97, 0x87, 0xdd, 0xcd, 0xfc, 0xa1, 0xd8, 0xf0, 0x85, + 0x62, 0x73, 0xe6, 0xd1, 0x24, 0x8c, 0xd7, 0xf4, 0x6d, 0xfc, 0x12, 0xa3, 0x85, 0x3b, 0x4a, 0x16, + 0xa4, 0x85, 0xe5, 0x9a, 0x7c, 0x84, 0xfc, 0x29, 0xe6, 0x6b, 0x72, 0x82, 0xfe, 0x29, 0x92, 0xaa, + 0xc9, 0x9f, 0x5c, 0x4d, 0x96, 0xc8, 0x9f, 0xe5, 0x62, 0x4d, 0x4e, 0x91, 0x3f, 0xe5, 0x62, 0x4d, + 0x4e, 0x93, 0x3f, 0x2b, 0x4b, 0x35, 0x39, 0x43, 0xfe, 0x94, 0xaa, 0x35, 0x39, 0x4b, 0xfe, 0xcc, + 0x55, 0x6b, 0xf2, 0x18, 0xf9, 0x73, 0xae, 0x5a, 0x93, 0xc7, 0xc9, 0x9f, 0x7c, 0xad, 0x26, 0x03, + 0xf9, 0x73, 0x7f, 0xb5, 0x26, 0x4f, 0x90, 0x3f, 0xb9, 0x7c, 0x4d, 0x3e, 0x4a, 0xff, 0x14, 0x6b, + 0xf2, 0x24, 0xf9, 0x53, 0xad, 0xd6, 0xe4, 0x29, 0x5a, 0x72, 0xb5, 0x26, 0x1f, 0xa3, 0x75, 0x95, + 0x6a, 0xb2, 0x4c, 0xfe, 0x2c, 0x56, 0x6b, 0xf2, 0x65, 0x34, 0x71, 0xb5, 0x26, 0x2b, 0xb4, 0xd2, + 0x6a, 0x4d, 0xfe, 0x31, 0x9a, 0xa6, 0x5a, 0x93, 0x8f, 0xd3, 0x2a, 0xaa, 0x35, 0xf9, 0x39, 0x94, + 0x8c, 0x62, 0x4d, 0x3e, 0x41, 0xd3, 0xa8, 0x35, 0xf9, 0x72, 0xfa, 0xa9, 0x5c, 0x93, 0xa7, 0x29, + 0x61, 0xc5, 0x9a, 0xfc, 0x5c, 0xfa, 0x47, 0xad, 0xc9, 0x88, 0x7e, 0xca, 0xd5, 0xe4, 0x2b, 0xd0, + 0x55, 0x30, 0xbe, 0x80, 0x2d, 0x86, 0x2f, 0x92, 0x41, 0x5a, 0xc0, 0x96, 0x77, 0xb5, 0xf1, 0xf5, + 0x63, 0x30, 0x7e, 0xde, 0x30, 0x2f, 0x74, 0xda, 0x5a, 0x1d, 0xa3, 0x0f, 0xb0, 0x7d, 0xbe, 0xfc, + 0x8e, 0x69, 0xe2, 0x96, 0x90, 0xee, 0x89, 0xf0, 0x66, 0x32, 0xbb, 0xb4, 0x59, 0xb7, 0x24, 0x9f, + 0x29, 0xcb, 0xd5, 0x30, 0x71, 0xd1, 0x4e, 0x5d, 0x6a, 0xd8, 0xe2, 0xe4, 0x89, 0x0a, 0x6b, 0x32, + 0xeb, 0x5f, 0x65, 0xfc, 0x26, 0xa0, 0x77, 0x26, 0x21, 0xb3, 0x80, 0xad, 0x5c, 0xb3, 0xe9, 0xe5, + 0xdb, 0xe3, 0x5e, 0xbe, 0xcd, 0x89, 0x7c, 0xbb, 0xd1, 0xbf, 0x11, 0xb9, 0x66, 0xd3, 0x87, 0x67, + 0x33, 0x70, 0xd4, 0xc3, 0x20, 0x32, 0x2d, 0x97, 0xae, 0x1f, 0x57, 0x85, 0x38, 0xf4, 0x06, 0x87, + 0x6b, 0x45, 0x81, 0x6b, 0xb7, 0x46, 0xa9, 0x30, 0x7e, 0x8e, 0x7d, 0xc4, 0xdd, 0x01, 0xba, 0x2a, + 0xd0, 0x8a, 0x84, 0x5e, 0x31, 0x00, 0x17, 0x03, 0x6d, 0x38, 0xfd, 0x25, 0x2f, 0x2a, 0x0f, 0x87, + 0x60, 0x80, 0x19, 0x84, 0x87, 0xff, 0x2d, 0x09, 0x72, 0x15, 0x5b, 0xa5, 0xce, 0xa2, 0xbe, 0xb9, + 0xd5, 0xd4, 0x37, 0xb7, 0x2c, 0xdc, 0x40, 0x0f, 0x08, 0xe3, 0x8e, 0xb1, 0xfe, 0x10, 0xae, 0x5b, + 0x25, 0x7b, 0x71, 0xe2, 0x84, 0x95, 0x6b, 0x61, 0x52, 0xf7, 0xe6, 0xe3, 0x76, 0x47, 0x31, 0x12, + 0xfd, 0xaa, 0x97, 0xf7, 0x4b, 0x22, 0xef, 0x5f, 0xe4, 0xc3, 0x8c, 0x6e, 0x8a, 0x7c, 0xc6, 0xa8, + 0x3f, 0x70, 0x78, 0x5c, 0x11, 0x78, 0x7c, 0xe7, 0x60, 0xc5, 0x8e, 0xc4, 0x2c, 0x6e, 0x2f, 0xfd, + 0x3c, 0x9b, 0x0c, 0x5d, 0xc2, 0x94, 0xd8, 0x2f, 0x4c, 0xff, 0x33, 0x11, 0x5d, 0x7e, 0x83, 0x16, + 0x7b, 0x91, 0xa5, 0x73, 0x08, 0xeb, 0xb0, 0x41, 0xf8, 0xf5, 0x4b, 0x12, 0x64, 0x8a, 0x97, 0xda, + 0x86, 0xb8, 0x23, 0xa6, 0x40, 0xaa, 0xed, 0x4e, 0x73, 0xe9, 0xff, 0x10, 0x1d, 0xf2, 0xfd, 0x03, + 0xe8, 0x00, 0x56, 0xb7, 0x8f, 0x0e, 0xb0, 0xc9, 0x48, 0x7a, 0xc8, 0xb8, 0x11, 0xd2, 0xd4, 0x93, + 0x86, 0xaf, 0x88, 0xdd, 0x25, 0xb4, 0x5d, 0x44, 0x91, 0x7c, 0x55, 0x59, 0xa2, 0xc8, 0x28, 0xf4, + 0x24, 0x67, 0x04, 0x7a, 0xf6, 0xe5, 0x09, 0xc8, 0x54, 0x68, 0xaf, 0x47, 0xbf, 0x9a, 0x82, 0x54, + 0xa5, 0x8d, 0x5b, 0xe8, 0x1d, 0x1e, 0xc3, 0xfd, 0x95, 0x30, 0x5e, 0x37, 0x5a, 0x16, 0xbe, 0xe4, + 0x6a, 0x09, 0x37, 0x42, 0x50, 0x21, 0xc9, 0x2e, 0x15, 0x32, 0x0d, 0x59, 0xcb, 0x64, 0x90, 0x71, + 0xaf, 0x1c, 0x1e, 0x54, 0xca, 0x30, 0xa3, 0xb7, 0xea, 0xcd, 0x9d, 0x06, 0x56, 0x71, 0x53, 0x23, + 0xb4, 0x77, 0x72, 0x9d, 0x02, 0x6e, 0xe3, 0x56, 0x03, 0xb7, 0x2c, 0x46, 0x8d, 0xbd, 0x19, 0x11, + 0x22, 0xa5, 0x38, 0x49, 0xbe, 0x5b, 0x84, 0xff, 0xf9, 0x02, 0xbf, 0x59, 0x8e, 0x59, 0xd2, 0x4a, + 0x1f, 0xe4, 0xcf, 0x02, 0xb0, 0x16, 0x9c, 0xd3, 0xf1, 0x45, 0x6e, 0x2d, 0x79, 0x6e, 0x97, 0xb5, + 0xa4, 0xe2, 0x24, 0x50, 0x3d, 0x89, 0xd1, 0x9f, 0x39, 0x90, 0xdf, 0x27, 0x40, 0x7e, 0x63, 0x48, + 0x12, 0xa2, 0xa1, 0xfd, 0x2f, 0x06, 0x98, 0x4c, 0x0b, 0x3e, 0x45, 0x92, 0xf2, 0x5c, 0x78, 0x8e, + 0x6d, 0x07, 0x28, 0x17, 0x8b, 0x85, 0xea, 0xda, 0xea, 0xca, 0x82, 0x9a, 0x2b, 0x14, 0x65, 0x40, + 0x1f, 0x4c, 0x42, 0x9a, 0xee, 0x9a, 0xa1, 0xfc, 0x10, 0x64, 0x01, 0x7d, 0x37, 0x11, 0x76, 0x99, + 0xca, 0xd9, 0x43, 0xeb, 0xf6, 0x51, 0x70, 0xaf, 0x0d, 0x65, 0x1d, 0x08, 0x28, 0x28, 0xfe, 0x6e, + 0x45, 0xba, 0x52, 0x75, 0xcb, 0xb8, 0xf8, 0xff, 0x7f, 0x57, 0x22, 0xad, 0x3c, 0xe4, 0xae, 0xd4, + 0x83, 0x84, 0x67, 0x53, 0x57, 0x7a, 0x3c, 0xe5, 0x4c, 0x65, 0x9f, 0xf0, 0x48, 0xc3, 0xad, 0xae, + 0xd3, 0x62, 0x22, 0x78, 0x67, 0xd5, 0x4e, 0xa7, 0xe4, 0x60, 0x52, 0x6f, 0x59, 0xd8, 0x6c, 0x69, + 0xcd, 0xf9, 0xa6, 0xb6, 0xc9, 0x26, 0xf8, 0x5e, 0xdb, 0x2c, 0xe3, 0x69, 0xc9, 0x93, 0x46, 0x15, + 0x73, 0x28, 0x27, 0x01, 0x2c, 0xbc, 0xdd, 0x6e, 0x6a, 0x96, 0x2b, 0x4c, 0x9e, 0x18, 0xf4, 0x9d, + 0xd0, 0x1e, 0x54, 0x76, 0xff, 0xea, 0xe3, 0x41, 0xe5, 0xc8, 0xb4, 0xd4, 0x25, 0xd3, 0xce, 0x70, + 0x9a, 0x0a, 0x31, 0x9c, 0x7a, 0xb9, 0x95, 0x0e, 0xc7, 0x2d, 0xf4, 0xba, 0x50, 0x2e, 0x5a, 0x41, + 0xcd, 0x88, 0x5f, 0x4f, 0x3c, 0x21, 0xc1, 0x14, 0xab, 0x7a, 0xce, 0x30, 0x2e, 0x6c, 0x6b, 0xe6, + 0x05, 0x74, 0xd7, 0x41, 0x44, 0x04, 0x7d, 0xca, 0x8b, 0xdf, 0x82, 0x88, 0xdf, 0xad, 0xfe, 0x0d, + 0xb7, 0x6b, 0x0f, 0x81, 0x63, 0xb7, 0x6e, 0xba, 0x55, 0x74, 0xbe, 0x0d, 0x43, 0xe4, 0x5b, 0x1d, + 0x64, 0xee, 0x17, 0x90, 0x79, 0x51, 0x64, 0x02, 0xe3, 0x47, 0xe8, 0x29, 0x07, 0x21, 0x5b, 0x6d, + 0x1e, 0x10, 0xa1, 0xaf, 0x0d, 0x86, 0x90, 0x5d, 0xfb, 0x00, 0x08, 0xc9, 0x20, 0x5d, 0xc0, 0x7b, + 0xbc, 0x03, 0x92, 0xbf, 0x5e, 0xb2, 0x53, 0xf1, 0x61, 0xe6, 0x43, 0xf2, 0x48, 0x30, 0x3b, 0x2e, + 0x92, 0x50, 0x69, 0x0f, 0x01, 0xb9, 0xbf, 0xf6, 0x22, 0xb7, 0x2c, 0x22, 0xf7, 0xe2, 0xfe, 0x6c, + 0x60, 0x34, 0x8c, 0xa6, 0x87, 0xbd, 0xd3, 0x41, 0x6b, 0x45, 0x40, 0xeb, 0xae, 0x01, 0xc9, 0x8c, + 0x1f, 0xb3, 0x2f, 0xa6, 0x60, 0xdc, 0xf6, 0x6b, 0xb3, 0xd0, 0xfb, 0x13, 0xc2, 0x6e, 0x76, 0xc7, + 0xd8, 0x31, 0xeb, 0xa4, 0x0d, 0xd2, 0xf5, 0xe3, 0x2a, 0x0f, 0x79, 0xd9, 0x92, 0x0c, 0x39, 0x80, + 0xf6, 0x19, 0xfd, 0xf6, 0x0f, 0xb0, 0xa9, 0xa8, 0x03, 0x2c, 0x7a, 0x99, 0x14, 0x76, 0x29, 0x2a, + 0x70, 0xbf, 0x8a, 0xad, 0x67, 0xe3, 0x18, 0xfa, 0x91, 0x50, 0xab, 0xd8, 0x3e, 0x2d, 0x89, 0x26, + 0x3c, 0x95, 0x01, 0x26, 0x63, 0x57, 0xc0, 0xe5, 0x76, 0x8a, 0xca, 0xdc, 0xfd, 0xc5, 0x7c, 0x6d, + 0x8d, 0xce, 0xc4, 0x56, 0xd5, 0x25, 0x59, 0x42, 0x8f, 0xa4, 0x40, 0x66, 0xa4, 0x31, 0x3a, 0x6b, + 0x7b, 0x6d, 0x8c, 0x7e, 0xfe, 0x90, 0x27, 0x62, 0xe8, 0x7b, 0x5e, 0x65, 0x52, 0x12, 0xe5, 0xe4, + 0x36, 0x7f, 0xee, 0xba, 0x4d, 0xf0, 0x11, 0x97, 0x01, 0x7a, 0x45, 0x80, 0x84, 0xa1, 0x4f, 0x38, + 0x02, 0xb0, 0x24, 0x08, 0xc0, 0xed, 0x03, 0x90, 0x78, 0xc8, 0x72, 0xf0, 0xc9, 0x24, 0x4c, 0xda, + 0xd3, 0x88, 0x79, 0x6c, 0xd5, 0xb7, 0xd0, 0xd9, 0xb0, 0x6b, 0x33, 0x19, 0xa4, 0x1d, 0xb3, 0xc9, + 0xa9, 0x24, 0x7f, 0xd1, 0x3f, 0x26, 0xc2, 0xee, 0x79, 0x70, 0xde, 0x08, 0x35, 0xfb, 0x2c, 0x6c, + 0xc3, 0xed, 0x68, 0x84, 0x28, 0x30, 0x7e, 0x75, 0xfd, 0x95, 0x24, 0x40, 0xcd, 0x70, 0x26, 0xad, + 0x07, 0xe0, 0xa4, 0xe0, 0x64, 0x9d, 0x17, 0x39, 0xd9, 0x73, 0x45, 0xef, 0x56, 0x1b, 0x7d, 0x2c, + 0x45, 0x6f, 0x74, 0x58, 0x3c, 0x2f, 0xb0, 0xf8, 0x4c, 0xa4, 0x9a, 0xe2, 0xe7, 0xef, 0x07, 0x93, + 0x30, 0x5e, 0xd8, 0x69, 0x37, 0xf5, 0x3a, 0x59, 0x37, 0x3e, 0x3f, 0x24, 0x7b, 0xd1, 0x23, 0xc9, + 0x88, 0xa3, 0x8f, 0x53, 0x87, 0x0f, 0x2f, 0x99, 0xeb, 0x52, 0xd2, 0x76, 0x5d, 0x0a, 0x69, 0xd6, + 0xec, 0x53, 0xf8, 0x08, 0xc4, 0x53, 0x82, 0x63, 0x95, 0x36, 0x6e, 0xcd, 0x99, 0x58, 0x6b, 0xd4, + 0xcd, 0x9d, 0xed, 0xf5, 0x0e, 0xca, 0x85, 0x95, 0x51, 0x8f, 0xb5, 0x25, 0x29, 0x58, 0x5b, 0xd0, + 0xaf, 0x78, 0x07, 0xf7, 0x45, 0x91, 0xbd, 0x67, 0xfc, 0xac, 0x7c, 0x1e, 0x1a, 0x06, 0x98, 0xfc, + 0x45, 0xb2, 0x3a, 0x77, 0x99, 0x5c, 0x52, 0x51, 0x4c, 0x2e, 0x6f, 0x73, 0x90, 0x7d, 0x40, 0x40, + 0xf6, 0xc5, 0xd1, 0xdb, 0x35, 0x92, 0xcd, 0x83, 0xa9, 0x2a, 0xb6, 0x7c, 0xe0, 0xbd, 0x16, 0x26, + 0xd7, 0xdd, 0x2f, 0x0e, 0xc4, 0x62, 0x24, 0x51, 0x45, 0xba, 0xb3, 0x49, 0x4a, 0xfe, 0xa2, 0x77, + 0x44, 0x5d, 0x9a, 0x89, 0x24, 0xf8, 0xa0, 0xeb, 0x20, 0x98, 0x0c, 0xb3, 0x6f, 0x10, 0x69, 0x9d, + 0x15, 0x58, 0x7f, 0xfc, 0x28, 0xbc, 0x5d, 0x82, 0xa9, 0xd2, 0x76, 0xdb, 0x30, 0xad, 0x65, 0xcd, + 0xbc, 0x40, 0x4f, 0x35, 0x2e, 0x84, 0xed, 0x64, 0x27, 0x01, 0x74, 0x9a, 0xd5, 0xe3, 0x05, 0xe9, + 0x89, 0x41, 0x4f, 0x47, 0xc5, 0x42, 0x24, 0xc4, 0x7f, 0x6f, 0xd7, 0x34, 0x0c, 0x6b, 0x49, 0x6f, + 0x5d, 0x70, 0x37, 0xc8, 0xbd, 0x51, 0x11, 0x77, 0x79, 0x22, 0xa1, 0x15, 0x48, 0x61, 0xfc, 0x68, + 0x7d, 0x2c, 0x09, 0x13, 0xd5, 0x2d, 0xcd, 0xc4, 0x73, 0x7b, 0xa4, 0xb1, 0x5d, 0x1e, 0x48, 0x7e, + 0x3b, 0xc1, 0xe8, 0xa5, 0x5e, 0x20, 0x14, 0x48, 0x35, 0xf5, 0xd6, 0x05, 0x7b, 0x7b, 0x8e, 0xfc, + 0x77, 0x8f, 0xf6, 0x26, 0x7b, 0x1c, 0xed, 0x75, 0x4c, 0xb4, 0x4e, 0xbd, 0x3e, 0x73, 0x9f, 0x37, + 0x85, 0x3a, 0xda, 0xdb, 0xb7, 0xb8, 0xf8, 0xd9, 0xf8, 0x85, 0x24, 0x1c, 0xcb, 0x35, 0x1a, 0xe7, + 0x75, 0x6b, 0xab, 0x62, 0xf3, 0xe8, 0xde, 0x70, 0x9b, 0xea, 0xd3, 0x90, 0x6d, 0x6b, 0x7b, 0x4d, + 0x43, 0x73, 0x06, 0x16, 0x1e, 0x44, 0x0f, 0x27, 0x23, 0x0e, 0x2c, 0x5d, 0x14, 0xf8, 0x30, 0x35, + 0x92, 0x4e, 0x0f, 0x2e, 0x32, 0x7e, 0xc6, 0xfe, 0x45, 0x0a, 0x32, 0x55, 0xac, 0x99, 0xf5, 0x2d, + 0xf4, 0xea, 0xa4, 0xcb, 0xd0, 0x79, 0xc8, 0x6e, 0xe8, 0x4d, 0x0b, 0x9b, 0x1d, 0xba, 0xfe, 0xf7, + 0xce, 0x63, 0xd8, 0x78, 0x36, 0xd7, 0x34, 0xea, 0x17, 0x66, 0xf3, 0x44, 0xb3, 0xb4, 0xac, 0x59, + 0xfb, 0xdc, 0xd4, 0xec, 0x3c, 0xcd, 0xa4, 0xda, 0x99, 0x95, 0xfb, 0x20, 0xdd, 0x31, 0x4c, 0xcb, + 0x5e, 0xab, 0x9d, 0x0e, 0x57, 0x4a, 0xd5, 0x30, 0x2d, 0x95, 0x65, 0x24, 0xd0, 0x6e, 0xec, 0x34, + 0x9b, 0x35, 0x7c, 0xc9, 0xb2, 0xd7, 0x49, 0x76, 0x58, 0x39, 0x01, 0x19, 0x63, 0x63, 0xa3, 0x83, + 0xd9, 0x52, 0x3c, 0xad, 0xf2, 0x90, 0x72, 0x1c, 0xd2, 0x4d, 0x7d, 0x5b, 0xb7, 0xe8, 0x8a, 0x3b, + 0xad, 0xb2, 0x80, 0x72, 0x1a, 0x64, 0xc3, 0x59, 0x25, 0x31, 0x42, 0xa7, 0x33, 0x54, 0x17, 0xed, + 0x8b, 0x27, 0x5d, 0xee, 0x02, 0xde, 0xeb, 0x4c, 0x67, 0xe9, 0x77, 0xfa, 0x1f, 0x3d, 0x19, 0xd5, + 0x4a, 0xcf, 0xf8, 0xea, 0xbf, 0x64, 0x34, 0x71, 0xdd, 0x30, 0x1b, 0x36, 0x6f, 0xfc, 0x97, 0x8c, + 0x3c, 0x5d, 0x34, 0xdb, 0x7a, 0xcf, 0xca, 0xe3, 0x97, 0xa7, 0x27, 0x33, 0x90, 0x5e, 0x30, 0xb5, + 0xf6, 0x16, 0x7a, 0x73, 0x62, 0xf8, 0xe2, 0xe4, 0x00, 0x9b, 0xec, 0x07, 0xac, 0xd4, 0x07, 0xd8, + 0x94, 0x07, 0xd8, 0xc7, 0x93, 0x90, 0x2a, 0x36, 0x36, 0xb1, 0x60, 0xf4, 0x4a, 0x78, 0x8c, 0x5e, + 0x27, 0x20, 0x63, 0x69, 0xe6, 0x26, 0xb6, 0x38, 0x97, 0x78, 0xc8, 0xf1, 0x8c, 0x92, 0x3c, 0xe7, + 0xeb, 0x5e, 0x0c, 0x29, 0xd2, 0x2e, 0x2a, 0x91, 0x53, 0x67, 0xae, 0xe9, 0x05, 0x0d, 0xe5, 0xcf, + 0x2c, 0xa9, 0x71, 0x96, 0x50, 0xa6, 0xd2, 0x0c, 0xdd, 0x78, 0xa4, 0xf7, 0xe1, 0x41, 0xc6, 0x76, + 0xbd, 0x6e, 0xb4, 0x4a, 0xdb, 0xda, 0x26, 0x9e, 0xce, 0xb0, 0xb1, 0xdd, 0x89, 0xb0, 0xbf, 0x16, + 0xb7, 0x8d, 0x87, 0xf4, 0xe9, 0xac, 0xfb, 0x95, 0x46, 0x90, 0x26, 0x6c, 0xe9, 0x8d, 0x06, 0x6e, + 0x4d, 0x8f, 0xb1, 0xd3, 0x29, 0x2c, 0x34, 0x73, 0x12, 0x52, 0x84, 0x06, 0x82, 0x31, 0x51, 0xec, + 0xf2, 0x11, 0xe5, 0x28, 0x91, 0x72, 0x66, 0x95, 0x94, 0x13, 0xe8, 0x33, 0xc9, 0x88, 0x7b, 0xc8, + 0xac, 0x71, 0xbd, 0x65, 0xfe, 0x26, 0x48, 0xb7, 0x8c, 0x06, 0xee, 0x2b, 0xf1, 0x2c, 0x95, 0xf2, + 0x02, 0x48, 0xe3, 0xc6, 0x26, 0xee, 0x50, 0x30, 0x27, 0xce, 0x9c, 0x0c, 0xe6, 0xa5, 0xca, 0x12, + 0x47, 0xdb, 0xa8, 0xee, 0x45, 0x6d, 0xfc, 0x9d, 0xe4, 0x7f, 0x67, 0xe0, 0x18, 0xeb, 0x9f, 0xd5, + 0x9d, 0x75, 0x52, 0xd4, 0x3a, 0x46, 0xbf, 0x25, 0x09, 0x07, 0x7a, 0x3b, 0x3b, 0xeb, 0xce, 0x58, + 0xc6, 0x02, 0xde, 0x4e, 0x94, 0x1c, 0x8a, 0x4e, 0x96, 0x06, 0xd5, 0xc9, 0x82, 0x7e, 0x95, 0xec, + 0x6e, 0xe8, 0x6a, 0xe3, 0x0c, 0x8d, 0xb6, 0xb5, 0x71, 0x0f, 0x5d, 0x4a, 0x06, 0x65, 0x6d, 0xc3, + 0xc2, 0x66, 0xa9, 0x41, 0xe5, 0x71, 0x5c, 0xb5, 0x83, 0x44, 0xdf, 0xaf, 0xe3, 0x0d, 0xc3, 0x24, + 0x0b, 0xc1, 0x71, 0xa6, 0xef, 0xed, 0xb0, 0xa7, 0x7f, 0x82, 0x60, 0x94, 0xbe, 0x1e, 0x8e, 0xe9, + 0x9b, 0x2d, 0xc3, 0xc4, 0x8e, 0x67, 0xcf, 0xf4, 0x51, 0x76, 0x12, 0xb5, 0x2b, 0x5a, 0xb9, 0x11, + 0x2e, 0x6b, 0x19, 0x05, 0xdc, 0xe6, 0x7c, 0x67, 0xa8, 0x4e, 0xd2, 0x1e, 0xb1, 0xff, 0x03, 0xfa, + 0x74, 0xd4, 0x95, 0x67, 0x17, 0xa8, 0x43, 0x53, 0xfd, 0xca, 0x9d, 0x70, 0xb4, 0xc1, 0xbd, 0x06, + 0xea, 0xba, 0xd3, 0x23, 0x7c, 0xf3, 0x09, 0x89, 0x5d, 0x71, 0x4a, 0x79, 0xc5, 0x69, 0x01, 0xc6, + 0xa8, 0xab, 0x39, 0x91, 0xa7, 0x74, 0xd7, 0x61, 0x46, 0x3a, 0xdd, 0x76, 0x1a, 0xe5, 0x61, 0xc9, + 0x6c, 0x9e, 0x67, 0x51, 0x9d, 0xcc, 0xd1, 0xe6, 0x3b, 0xc1, 0x1c, 0x8a, 0xbf, 0xeb, 0x7d, 0x53, + 0x82, 0x13, 0xb6, 0x7a, 0x63, 0xb4, 0x14, 0xf4, 0x8e, 0xa5, 0xb7, 0xea, 0x16, 0xea, 0x08, 0x0e, + 0x84, 0x26, 0x4f, 0xf4, 0x00, 0xde, 0xb3, 0x1d, 0x08, 0x3d, 0x51, 0xc3, 0xea, 0x8c, 0xe8, 0x73, + 0x5e, 0xfd, 0x5a, 0x11, 0x45, 0xec, 0x6c, 0x2f, 0x06, 0xf6, 0x26, 0xde, 0x47, 0xd2, 0xf2, 0x90, + 0xd9, 0x34, 0x8d, 0x9d, 0xb6, 0x4d, 0xe4, 0x0d, 0xe1, 0x88, 0x5c, 0x20, 0x79, 0x54, 0x9e, 0x15, + 0x3d, 0xe5, 0xe0, 0xab, 0x0a, 0xf8, 0xde, 0x33, 0x30, 0x79, 0x23, 0x30, 0x55, 0xa4, 0xe0, 0xa8, + 0x23, 0x64, 0xa5, 0x46, 0x07, 0x19, 0xfd, 0xb4, 0xeb, 0x3e, 0xc3, 0x84, 0xa3, 0xb7, 0x24, 0x8f, + 0xde, 0xea, 0xa1, 0x69, 0x26, 0x7a, 0x6a, 0x1a, 0xf4, 0xb0, 0x14, 0xf6, 0xfa, 0x05, 0xb1, 0x9b, + 0x51, 0x72, 0x9f, 0xcd, 0x8a, 0x23, 0xe4, 0x25, 0x10, 0xfd, 0x5b, 0x15, 0xbf, 0x14, 0x7c, 0x38, + 0x09, 0x97, 0x31, 0x41, 0x5c, 0x6d, 0x75, 0x9c, 0x91, 0x56, 0x3c, 0xb3, 0x4b, 0xdb, 0xd4, 0x71, + 0x76, 0x39, 0x69, 0x48, 0xb4, 0xe8, 0xde, 0x2f, 0x82, 0xf7, 0x02, 0x7f, 0xb5, 0xe6, 0xa9, 0xc5, + 0x67, 0x6d, 0xf8, 0xfb, 0x0e, 0xef, 0x96, 0x05, 0xde, 0x9d, 0x1d, 0xa4, 0xd0, 0xf8, 0x19, 0xf8, + 0x3b, 0x12, 0x8c, 0x57, 0xb1, 0xb5, 0xa4, 0xed, 0x19, 0x3b, 0x16, 0xd2, 0xc2, 0x9a, 0x99, 0x6e, + 0x87, 0x4c, 0x93, 0x66, 0xa1, 0x33, 0xe3, 0xa9, 0x33, 0x57, 0xf7, 0x34, 0x86, 0xd2, 0xcd, 0x2a, + 0x56, 0xb4, 0xca, 0xd3, 0xa3, 0xd7, 0x47, 0x35, 0xa5, 0x3b, 0xd4, 0x0d, 0xc5, 0x0e, 0x18, 0xc9, + 0xd0, 0xee, 0x57, 0x75, 0xfc, 0xb0, 0xfc, 0x8a, 0x04, 0x93, 0xd4, 0xf5, 0x7e, 0x5e, 0xdb, 0x35, + 0x4c, 0xdd, 0xc2, 0xd1, 0x2c, 0x80, 0x4e, 0x36, 0x7e, 0xbe, 0xc0, 0x13, 0x83, 0xde, 0x9e, 0x8c, + 0xb8, 0xc5, 0x26, 0xd0, 0x31, 0x14, 0x10, 0x22, 0x6d, 0xc8, 0x05, 0x55, 0x3f, 0x42, 0x20, 0x72, + 0x66, 0x7d, 0x4b, 0xdf, 0xc5, 0x8d, 0x88, 0x40, 0xd8, 0xd9, 0x5c, 0x20, 0x9c, 0x82, 0x06, 0x03, + 0xc2, 0xce, 0x7e, 0x48, 0x40, 0xf8, 0x54, 0x1f, 0x3f, 0x10, 0x6f, 0x65, 0x40, 0x78, 0x7c, 0x0d, + 0x96, 0xc3, 0x02, 0x71, 0x2d, 0x4c, 0xba, 0x56, 0x82, 0x55, 0xb3, 0xc9, 0x57, 0xf3, 0x62, 0x24, + 0xfa, 0xc4, 0x00, 0x70, 0xf4, 0x75, 0x1b, 0x88, 0x06, 0xc7, 0xc7, 0x23, 0xc2, 0xf1, 0x6c, 0x75, + 0x09, 0x78, 0x5a, 0x62, 0x27, 0xa4, 0x04, 0xcf, 0x8c, 0x87, 0xc2, 0xc2, 0xb5, 0xcf, 0x0b, 0x24, + 0x1b, 0xd9, 0x0b, 0xe4, 0x53, 0x51, 0xbd, 0x40, 0xba, 0xa9, 0x1d, 0x0a, 0x9c, 0x91, 0x9c, 0x3c, + 0xfa, 0x50, 0x70, 0xc8, 0x88, 0x7e, 0x5b, 0x02, 0xa0, 0x77, 0x7f, 0x32, 0xff, 0xa5, 0x45, 0xc8, + 0xb0, 0xbf, 0xb6, 0x13, 0x64, 0xc2, 0x75, 0x82, 0xbc, 0x11, 0xd2, 0xbb, 0x5a, 0x73, 0x07, 0x3b, + 0x3c, 0xea, 0x9e, 0x88, 0x9e, 0x23, 0x5f, 0x55, 0x96, 0x08, 0x6d, 0x85, 0x95, 0x8a, 0x7b, 0xbd, + 0x0e, 0x38, 0x44, 0x1e, 0xae, 0xf3, 0xe1, 0x22, 0xa7, 0x71, 0x96, 0xfd, 0xba, 0x3e, 0x57, 0x6f, + 0x8c, 0xea, 0x10, 0xe1, 0x29, 0x6b, 0x18, 0xd2, 0x10, 0xc9, 0x45, 0xc2, 0xb7, 0xee, 0xf8, 0x15, + 0xed, 0xa7, 0x92, 0x90, 0xae, 0x19, 0x55, 0x2c, 0x9c, 0x1f, 0x0b, 0xc6, 0xc6, 0xb5, 0xda, 0x24, + 0xbd, 0x56, 0x9b, 0x08, 0x17, 0xb0, 0x3a, 0x9e, 0x21, 0xfe, 0x0e, 0x7b, 0x64, 0xa9, 0x82, 0xdd, + 0xad, 0x7c, 0x16, 0x88, 0x66, 0x0b, 0xec, 0x55, 0x7c, 0xfc, 0x0c, 0x3d, 0x0b, 0xc7, 0x56, 0x5b, + 0x0d, 0x43, 0xc5, 0x0d, 0x83, 0xdb, 0x56, 0xc8, 0xc2, 0x73, 0xa7, 0xd5, 0x30, 0x28, 0xad, 0x69, + 0x95, 0xfe, 0x27, 0x71, 0x26, 0x6e, 0x18, 0xdc, 0xf0, 0x4d, 0xff, 0xa3, 0xd7, 0x48, 0x90, 0x22, + 0x79, 0xc3, 0x7b, 0xaa, 0x7c, 0x27, 0xea, 0x41, 0x13, 0x52, 0xfc, 0x30, 0xe4, 0x5b, 0xb9, 0xd7, + 0x63, 0x6d, 0x62, 0x9b, 0xbc, 0xd7, 0xf8, 0xd5, 0xe7, 0x61, 0x85, 0xc7, 0xca, 0xf4, 0x54, 0x94, + 0xc3, 0x29, 0x3d, 0xc8, 0x8e, 0x86, 0x64, 0x61, 0x00, 0x15, 0x29, 0xc3, 0xd1, 0x7c, 0xae, 0x4c, + 0x6f, 0x4b, 0x58, 0xae, 0x9c, 0x2b, 0xca, 0x12, 0x05, 0x88, 0xb4, 0x26, 0x46, 0x80, 0x48, 0xf1, + 0xff, 0x04, 0x01, 0xea, 0x41, 0xf6, 0x61, 0x00, 0xf4, 0xc9, 0x24, 0x4c, 0x2e, 0xe9, 0x1d, 0xcb, + 0xcf, 0xe9, 0xcb, 0xde, 0x44, 0xb6, 0xed, 0x03, 0x6e, 0x84, 0x78, 0xd1, 0x76, 0x98, 0x09, 0xa1, + 0x50, 0x8f, 0x0f, 0x64, 0xfb, 0xbd, 0x63, 0x22, 0xcd, 0xc1, 0x83, 0xaa, 0x18, 0x8d, 0x77, 0x22, + 0xa5, 0x80, 0x5d, 0x8d, 0x16, 0x9a, 0x93, 0x91, 0x87, 0x5e, 0xb7, 0x92, 0xd1, 0x0f, 0xbd, 0xbe, + 0x75, 0x8f, 0xc0, 0x74, 0x9d, 0x84, 0xcb, 0x48, 0xf5, 0x41, 0x0b, 0x4e, 0x7f, 0x36, 0xf7, 0x5d, + 0x70, 0x46, 0xb6, 0x79, 0xed, 0xa3, 0x65, 0x18, 0x36, 0xaf, 0x7e, 0x85, 0x8e, 0x98, 0xcd, 0x3e, + 0x06, 0x96, 0x7e, 0x6c, 0x0e, 0x30, 0xb0, 0x0c, 0xce, 0xe6, 0x60, 0x23, 0xcb, 0x80, 0x6c, 0x3e, + 0x34, 0xd3, 0xc9, 0x97, 0x92, 0x30, 0x99, 0x6b, 0xb7, 0x9b, 0x7b, 0x35, 0x7e, 0x12, 0x24, 0x92, + 0xe9, 0xc4, 0x73, 0xa0, 0x24, 0xb9, 0xef, 0x38, 0x65, 0x64, 0x37, 0x71, 0x81, 0x8e, 0x61, 0xb8, + 0x89, 0x07, 0x15, 0x18, 0x3f, 0x6b, 0x5f, 0x9a, 0x66, 0x8a, 0x98, 0x5f, 0xf4, 0xf0, 0x85, 0x44, + 0xf0, 0x4d, 0x0f, 0x82, 0x3c, 0x27, 0xbb, 0xe5, 0xf9, 0x6e, 0xc8, 0x6c, 0x18, 0xe6, 0xb6, 0x66, + 0xdb, 0x72, 0xaf, 0xf3, 0x13, 0x27, 0x7e, 0x97, 0xc2, 0x3c, 0x4d, 0xac, 0xf2, 0x4c, 0x64, 0x44, + 0x7b, 0x89, 0xde, 0xe6, 0x67, 0xa1, 0xc9, 0x5f, 0x7a, 0xc9, 0x09, 0x3b, 0x12, 0x5d, 0xc6, 0x1d, + 0x0b, 0x37, 0xe8, 0xe6, 0xe3, 0x98, 0x2a, 0x46, 0x2a, 0x33, 0x70, 0x94, 0x47, 0xcc, 0xeb, 0x4d, + 0xdc, 0xa1, 0x5b, 0xca, 0x63, 0xaa, 0x10, 0x87, 0x3e, 0x3b, 0xc8, 0xc0, 0x11, 0xf9, 0x06, 0x8a, + 0x69, 0xc8, 0x76, 0x76, 0xea, 0x75, 0x8c, 0x1b, 0xdc, 0xcb, 0xc8, 0x0e, 0x46, 0xf4, 0x5a, 0x8c, + 0x3c, 0xcc, 0x1c, 0xce, 0xe5, 0x14, 0x33, 0x2b, 0x90, 0x61, 0x18, 0x2a, 0x47, 0x61, 0xcc, 0xf6, + 0x9b, 0x64, 0x7e, 0x21, 0x2b, 0x7c, 0x91, 0x2e, 0x27, 0x48, 0x89, 0xf7, 0x57, 0x2b, 0x65, 0x76, + 0x61, 0x57, 0xa1, 0xc2, 0x2f, 0xec, 0xaa, 0x9e, 0x5b, 0x90, 0x53, 0xca, 0x14, 0xc0, 0x82, 0x9a, + 0x5b, 0x59, 0x5c, 0xa3, 0x29, 0xd2, 0xe8, 0x9b, 0x63, 0x90, 0x61, 0x6e, 0x98, 0xe8, 0xb3, 0x19, + 0xef, 0x83, 0x29, 0x47, 0x5b, 0x06, 0x21, 0x73, 0x45, 0x33, 0xb5, 0xed, 0x4e, 0xd0, 0xde, 0x18, + 0xcb, 0xed, 0x3c, 0x96, 0x52, 0xf6, 0x64, 0x5b, 0x3c, 0xa2, 0x0a, 0xc5, 0x28, 0xff, 0x12, 0x8e, + 0xad, 0xf3, 0x03, 0x04, 0x1d, 0x5e, 0x72, 0xd2, 0x7f, 0xc7, 0xbe, 0xab, 0xe4, 0x39, 0x31, 0xe7, + 0xe2, 0x11, 0xb5, 0xbb, 0x30, 0xe5, 0x67, 0x60, 0x6a, 0x9b, 0x73, 0x85, 0x17, 0x2f, 0xf5, 0xf3, + 0x8f, 0x75, 0x8a, 0x5f, 0x16, 0x32, 0x2e, 0x1e, 0x51, 0xbb, 0x8a, 0x52, 0x4a, 0x30, 0xde, 0x69, + 0x69, 0xed, 0xce, 0x96, 0x61, 0xd9, 0xe7, 0xe0, 0x6e, 0x08, 0x51, 0x6e, 0x95, 0xe7, 0x51, 0xdd, + 0xdc, 0xca, 0x0b, 0xe0, 0x39, 0x3b, 0xf4, 0xfa, 0xb8, 0xe2, 0x25, 0xba, 0x0b, 0xbb, 0x69, 0xdf, + 0x4b, 0xc0, 0xfa, 0x5b, 0xef, 0x8f, 0xca, 0x9d, 0xdc, 0x7d, 0x29, 0x43, 0x65, 0xf3, 0xf9, 0x21, + 0xea, 0xf6, 0xb8, 0x30, 0xdd, 0x09, 0xa9, 0x6d, 0x22, 0xd8, 0xd9, 0xd0, 0x99, 0x97, 0xa9, 0x34, + 0x93, 0x4c, 0xe8, 0x14, 0x1c, 0xf5, 0xe2, 0xaa, 0x9c, 0x80, 0x8c, 0xd6, 0xd6, 0xdd, 0xed, 0x77, + 0x1e, 0x42, 0xd7, 0xc2, 0x94, 0xc8, 0xc6, 0x5e, 0x4a, 0x0d, 0x5d, 0x03, 0xc7, 0xba, 0xb0, 0xb4, + 0x4f, 0xc1, 0x24, 0xdc, 0x53, 0x30, 0x3f, 0x0b, 0x63, 0x36, 0xe7, 0xf6, 0x5d, 0x17, 0x9b, 0x83, + 0x31, 0x9b, 0x97, 0x5c, 0x7e, 0xae, 0xeb, 0x32, 0x31, 0x56, 0xb7, 0x35, 0xd3, 0xa2, 0x3b, 0xe8, + 0x76, 0x21, 0x73, 0x5a, 0x07, 0xab, 0x4e, 0xb6, 0x99, 0x9b, 0x20, 0x45, 0xda, 0xa7, 0x28, 0x30, + 0x95, 0x5b, 0x5a, 0x5a, 0xab, 0xd0, 0xab, 0x8a, 0x17, 0x4b, 0xe5, 0x05, 0xd6, 0x0f, 0x4b, 0x0b, + 0xe5, 0x8a, 0x5a, 0x64, 0xdd, 0xb0, 0x2a, 0x27, 0x66, 0x66, 0xb9, 0x2b, 0x16, 0x40, 0x86, 0x31, + 0x82, 0x75, 0x3a, 0xa7, 0x0b, 0x26, 0x48, 0xa8, 0x78, 0x89, 0x59, 0x01, 0xe5, 0xe4, 0xdc, 0x18, + 0x64, 0xda, 0xb4, 0x65, 0xa2, 0x25, 0x25, 0x8c, 0x67, 0xa2, 0x83, 0x42, 0xaf, 0x91, 0xee, 0xbd, + 0x51, 0xdc, 0x0c, 0x7b, 0x96, 0x14, 0x4d, 0x49, 0xcd, 0xef, 0x53, 0x52, 0x0a, 0x4c, 0x95, 0xca, + 0xb5, 0xa2, 0x5a, 0xce, 0x2d, 0x39, 0x5a, 0x6a, 0x9f, 0xe2, 0x4a, 0x8a, 0x8a, 0x4b, 0x42, 0xdf, + 0x91, 0x00, 0x18, 0x39, 0x44, 0x7b, 0x7a, 0xef, 0x7c, 0xfb, 0x42, 0xd4, 0x81, 0xc2, 0x2d, 0xc6, + 0x67, 0xa0, 0x28, 0xc1, 0x98, 0xc9, 0x3f, 0x70, 0x83, 0x63, 0xbf, 0x72, 0xd8, 0x5f, 0xbb, 0x34, + 0xd5, 0xc9, 0x8e, 0x3e, 0x10, 0x65, 0x5c, 0xf0, 0x25, 0xec, 0x70, 0x58, 0xfe, 0x12, 0xfb, 0x28, + 0x82, 0x67, 0xba, 0xc5, 0xf4, 0x47, 0xb8, 0x36, 0x88, 0x99, 0x3d, 0xaa, 0x64, 0xe6, 0xea, 0x7e, + 0x9d, 0x01, 0x7d, 0xec, 0x18, 0x4c, 0xb1, 0x12, 0x9d, 0x3b, 0x02, 0xfe, 0x21, 0x09, 0x52, 0xae, + 0x21, 0x5c, 0xb7, 0x16, 0x3c, 0x93, 0x9c, 0x81, 0xa3, 0x1e, 0xa7, 0x1e, 0xe7, 0xee, 0x3e, 0x6f, + 0x9c, 0xf8, 0xf0, 0x4b, 0xe0, 0x8b, 0x5a, 0x22, 0x35, 0xb3, 0xb9, 0xc6, 0x70, 0xb6, 0xe1, 0xa2, + 0x38, 0xe9, 0x07, 0x54, 0x1e, 0xff, 0xbc, 0xf3, 0x11, 0xf7, 0x5e, 0xf4, 0xa1, 0x22, 0x10, 0xf5, + 0x84, 0x90, 0xc3, 0x84, 0x70, 0x46, 0x82, 0xa1, 0x9f, 0x39, 0x09, 0xae, 0x3f, 0x7e, 0x1c, 0x7e, + 0xc4, 0xad, 0x5a, 0xb9, 0x5d, 0x4d, 0x6f, 0x6a, 0xeb, 0xcd, 0x08, 0x47, 0x19, 0x3f, 0xe6, 0x65, + 0x75, 0x59, 0x64, 0xf5, 0xed, 0x41, 0x4d, 0x15, 0xea, 0xf3, 0xbd, 0xba, 0x7e, 0xdc, 0xc6, 0xd5, + 0x75, 0x60, 0x12, 0xc7, 0x54, 0xbb, 0x3c, 0xd5, 0x4d, 0x89, 0xfe, 0xd0, 0x61, 0xfd, 0x4f, 0x0a, + 0xac, 0xbf, 0x7b, 0x50, 0x7a, 0xe2, 0x47, 0xe0, 0x37, 0x24, 0x98, 0xc8, 0x35, 0x1a, 0xf3, 0x58, + 0xb3, 0x76, 0x4c, 0xdc, 0x40, 0xc5, 0xb0, 0xdd, 0xe1, 0xca, 0x6e, 0x16, 0x8d, 0x7b, 0x39, 0xf1, + 0xfe, 0xd0, 0x37, 0x3f, 0xee, 0xd7, 0x06, 0x36, 0x2d, 0x43, 0x51, 0x49, 0xe1, 0xee, 0x89, 0x0c, + 0x4d, 0x44, 0xfc, 0x80, 0xbc, 0x42, 0x82, 0x29, 0x95, 0xde, 0x9b, 0x3e, 0x6c, 0x4c, 0x3e, 0x14, + 0xd1, 0x81, 0xd3, 0x73, 0x3f, 0x8b, 0x97, 0x9c, 0xa1, 0xc0, 0x12, 0xc5, 0x53, 0x33, 0x1c, 0x1d, + 0xf1, 0x23, 0xf3, 0x5d, 0x00, 0xf0, 0xb8, 0x6d, 0x7c, 0x15, 0xdc, 0xe3, 0x07, 0xe8, 0x53, 0x12, + 0x1b, 0xcf, 0xab, 0xc2, 0x29, 0x53, 0xd1, 0x5b, 0x23, 0xd1, 0xc3, 0x5b, 0x23, 0xd4, 0xa8, 0xf2, + 0xfd, 0x88, 0x5e, 0x00, 0xdc, 0x91, 0xa2, 0xef, 0xe0, 0x3e, 0xa0, 0x96, 0x7b, 0x26, 0x82, 0x3b, + 0x40, 0x3f, 0x52, 0xe2, 0x7f, 0xa9, 0x23, 0xc8, 0x1d, 0x40, 0x99, 0x86, 0xe3, 0x6a, 0x31, 0x57, + 0xa8, 0x94, 0x97, 0x1e, 0xf4, 0x7e, 0x95, 0x53, 0xe8, 0xb5, 0x12, 0x64, 0x98, 0xbc, 0xc5, 0x83, + 0xe9, 0x7f, 0x8c, 0xa8, 0x20, 0x45, 0x46, 0x32, 0xca, 0x7c, 0x56, 0x45, 0xff, 0x39, 0x82, 0xca, + 0x0b, 0x51, 0xec, 0xb3, 0x16, 0xa2, 0xaf, 0x48, 0x90, 0xa2, 0xeb, 0xa7, 0x9d, 0xa8, 0x00, 0x15, + 0xe0, 0x2a, 0xad, 0xdd, 0xc6, 0xad, 0x86, 0x73, 0xd5, 0xe1, 0xbc, 0x69, 0x6c, 0x57, 0xac, 0x2d, + 0x6c, 0x92, 0x24, 0x1d, 0x6e, 0x0c, 0x0f, 0x4e, 0x84, 0xbe, 0x12, 0xd1, 0x3e, 0x2e, 0xf2, 0x3a, + 0x60, 0xc9, 0x76, 0x76, 0x7f, 0xbf, 0xbc, 0xc2, 0xa7, 0x5f, 0x2e, 0xe9, 0xad, 0x0b, 0xde, 0xbe, + 0xf9, 0x67, 0x11, 0x4c, 0xeb, 0x7d, 0xe9, 0x39, 0x64, 0x5f, 0x9d, 0x87, 0x33, 0x1e, 0x05, 0xfb, + 0xab, 0x12, 0xc8, 0x84, 0x44, 0x26, 0xa2, 0xfc, 0xbe, 0xae, 0x8a, 0xb8, 0xd5, 0x41, 0x23, 0xbd, + 0x5b, 0x1d, 0x76, 0x84, 0x72, 0x0a, 0xa6, 0xea, 0x5b, 0xb8, 0x7e, 0xa1, 0xd4, 0xb2, 0x4d, 0x4b, + 0x0c, 0xe1, 0xae, 0x58, 0xd1, 0xa9, 0xf7, 0x01, 0x11, 0x52, 0xd1, 0x7c, 0x2e, 0xf0, 0xcd, 0x4b, + 0x94, 0x4f, 0xa7, 0x74, 0x81, 0x29, 0x0b, 0xc0, 0xdc, 0x31, 0x50, 0xa9, 0xd1, 0x90, 0x29, 0x0f, + 0xf6, 0xae, 0x42, 0x65, 0x85, 0x3e, 0x44, 0xb6, 0x5a, 0x2d, 0x16, 0xd6, 0xe6, 0xec, 0xce, 0x57, + 0x95, 0x25, 0xf4, 0xed, 0x24, 0x64, 0x19, 0x59, 0x9d, 0xae, 0xbb, 0xac, 0x83, 0x8f, 0xa2, 0xa0, + 0x77, 0x86, 0xf6, 0x99, 0x76, 0x18, 0xc1, 0xeb, 0xf1, 0xe9, 0x29, 0xb7, 0x43, 0x96, 0x81, 0x6c, + 0x5b, 0x4e, 0x4f, 0xfa, 0xf4, 0x13, 0x5e, 0x8c, 0x6a, 0x27, 0x0f, 0xe9, 0x3f, 0xdd, 0x87, 0x8c, + 0xf8, 0xe7, 0x1c, 0x6f, 0x9a, 0x80, 0xec, 0xa2, 0xde, 0xb1, 0x0c, 0x73, 0x0f, 0xbd, 0x31, 0x01, + 0x59, 0xfe, 0x06, 0xf9, 0x3e, 0x1b, 0xe0, 0xd5, 0x30, 0xd1, 0x36, 0xf1, 0xae, 0x6e, 0xec, 0x74, + 0x3c, 0x17, 0x17, 0x78, 0xa2, 0x14, 0x04, 0x63, 0xda, 0x8e, 0xb5, 0x65, 0x98, 0xee, 0x2d, 0x4e, + 0x76, 0x58, 0x39, 0x09, 0xc0, 0xfe, 0x97, 0xb5, 0x6d, 0xcc, 0x8f, 0x50, 0x78, 0x62, 0x14, 0x05, + 0x52, 0x96, 0xbe, 0x8d, 0xf9, 0x21, 0x3a, 0xfa, 0x5f, 0x99, 0x86, 0x2c, 0x3d, 0x75, 0x53, 0x6a, + 0xf0, 0x43, 0x74, 0x76, 0x10, 0xbd, 0x45, 0x82, 0x09, 0xf7, 0xb9, 0xf4, 0x8e, 0xd7, 0x19, 0xbf, + 0xcf, 0x95, 0xf2, 0x4d, 0xad, 0x63, 0x67, 0x73, 0xb6, 0xcb, 0xc4, 0x48, 0xf7, 0x40, 0x9f, 0xe4, + 0x39, 0x57, 0x8b, 0xde, 0x9b, 0x0c, 0x7b, 0x84, 0x85, 0x33, 0xd3, 0xf3, 0x9e, 0xbb, 0xbf, 0x6c, + 0x8d, 0xf1, 0x07, 0xe4, 0x6d, 0x25, 0x7c, 0x65, 0xcf, 0x92, 0x78, 0x31, 0xaa, 0x93, 0x3a, 0xe4, + 0xb1, 0x93, 0xfe, 0x94, 0xc4, 0x2f, 0x5e, 0x7f, 0x2f, 0xc1, 0x44, 0x75, 0xcb, 0xb8, 0x68, 0xbf, + 0xce, 0xff, 0xb3, 0xe1, 0xa0, 0xba, 0x12, 0xc6, 0x77, 0xbb, 0x60, 0x72, 0x23, 0xfc, 0x6f, 0x23, + 0x46, 0x8f, 0x49, 0x51, 0x61, 0xf2, 0x10, 0x37, 0xf4, 0x5b, 0x84, 0x95, 0x17, 0x41, 0x96, 0x53, + 0xcd, 0x2d, 0x2b, 0xc1, 0x00, 0xdb, 0x89, 0xbd, 0x0d, 0x4c, 0x89, 0x0d, 0x8c, 0x86, 0xbc, 0x7f, + 0xe3, 0x46, 0x70, 0x9b, 0x42, 0x92, 0x3a, 0xc2, 0xda, 0xc0, 0xe7, 0x87, 0x00, 0x3c, 0xfa, 0x41, + 0x22, 0xac, 0xfd, 0xd1, 0xe1, 0x80, 0x43, 0xc1, 0x81, 0xae, 0xfd, 0xe8, 0x5b, 0x5c, 0xfc, 0xfc, + 0xfc, 0xc5, 0xcb, 0x20, 0x35, 0xaf, 0x37, 0x31, 0x59, 0xbf, 0x67, 0x2b, 0x1b, 0x1b, 0xf4, 0xda, + 0x8e, 0xa2, 0xff, 0x1b, 0x7f, 0xa7, 0x41, 0xb6, 0xb7, 0x91, 0x0d, 0x6b, 0x45, 0x6f, 0xb5, 0x1c, + 0x4f, 0x97, 0x7d, 0xf1, 0xa2, 0xa9, 0x2b, 0xd0, 0xfd, 0x94, 0x50, 0x30, 0xcb, 0x6b, 0xf7, 0xe9, + 0x2f, 0xa7, 0x60, 0x6a, 0x7d, 0xcf, 0xc2, 0x1d, 0x9e, 0x8a, 0x57, 0x9b, 0x52, 0xbb, 0x62, 0xd1, + 0xd3, 0xa1, 0x1c, 0x52, 0x03, 0x2a, 0x8c, 0xc6, 0x73, 0x6d, 0x80, 0x39, 0xca, 0x71, 0x90, 0xcb, + 0x95, 0x42, 0x91, 0x3d, 0x86, 0x57, 0xcb, 0xa9, 0xb5, 0x62, 0x41, 0xde, 0xa4, 0x2f, 0x80, 0x95, + 0x96, 0x58, 0xec, 0x83, 0xc5, 0xda, 0xda, 0x4a, 0xa9, 0x5c, 0x2e, 0x16, 0xe4, 0x2d, 0xf4, 0x41, + 0x09, 0x26, 0xc8, 0xbc, 0xca, 0x46, 0xa7, 0x22, 0x3c, 0xa0, 0x66, 0xb4, 0x9a, 0x7b, 0xee, 0xdc, + 0xd1, 0x0e, 0x46, 0xc2, 0xe9, 0x3f, 0x85, 0x9e, 0xde, 0x50, 0xb6, 0x79, 0x68, 0xf1, 0xc7, 0x6a, + 0x43, 0x6f, 0x76, 0x63, 0x95, 0x56, 0xbb, 0x62, 0x7b, 0x60, 0x2a, 0xf5, 0xc4, 0xf4, 0x8f, 0x42, + 0x4d, 0x7a, 0xfa, 0x10, 0x17, 0x0d, 0xd7, 0xc5, 0x61, 0xe1, 0x8a, 0xbe, 0x27, 0x41, 0x66, 0xb5, + 0x4d, 0x91, 0x7b, 0xc6, 0xe3, 0x27, 0xb2, 0x6f, 0xaf, 0x94, 0x28, 0xa9, 0xa6, 0xf8, 0x62, 0xb4, + 0xea, 0x46, 0x28, 0x77, 0xf0, 0x6d, 0x1f, 0xe6, 0x23, 0x72, 0x2a, 0xf0, 0x98, 0x31, 0xe5, 0x84, + 0x67, 0xd7, 0xf8, 0x46, 0xb8, 0xac, 0xa1, 0x77, 0xb4, 0xf5, 0x26, 0x2e, 0xb6, 0xea, 0xe6, 0x1e, + 0x6b, 0x34, 0x73, 0x18, 0xd9, 0xff, 0x41, 0xb9, 0x1b, 0xd2, 0x1d, 0x6b, 0xaf, 0xc9, 0xa6, 0x4d, + 0xde, 0x4d, 0x66, 0xdf, 0xaa, 0xaa, 0x24, 0xb9, 0xca, 0x72, 0xa1, 0x1f, 0x25, 0xc2, 0x3a, 0xd8, + 0xd2, 0xbc, 0x8c, 0x35, 0xfe, 0xde, 0x22, 0x5b, 0x5a, 0xc7, 0xf1, 0x16, 0x21, 0xff, 0xd1, 0x13, + 0xa1, 0xbc, 0x60, 0xfd, 0xcb, 0x8e, 0x5f, 0xa7, 0x7e, 0x39, 0x09, 0x63, 0x05, 0xe3, 0x62, 0x8b, + 0x62, 0x7e, 0xab, 0xe0, 0x1a, 0x44, 0x5b, 0x93, 0x70, 0x5b, 0xd3, 0xcb, 0x1f, 0x06, 0xfd, 0xbb, + 0xd0, 0x9b, 0xcd, 0xb4, 0x95, 0x76, 0x55, 0x3e, 0x3c, 0x0c, 0x14, 0x2b, 0x8f, 0xe9, 0x3f, 0x68, + 0x2b, 0x3a, 0xa8, 0x9e, 0x68, 0xfc, 0xcc, 0x1d, 0xf8, 0x4d, 0x02, 0xf4, 0xb4, 0x04, 0xa9, 0x82, + 0x69, 0xb4, 0xd1, 0x1f, 0x24, 0x22, 0xec, 0x81, 0x35, 0x4c, 0xa3, 0x5d, 0xa3, 0x97, 0xca, 0x38, + 0x53, 0x00, 0x21, 0x4e, 0x39, 0x0b, 0x63, 0x6d, 0xa3, 0xa3, 0x5b, 0xf6, 0xb4, 0x6a, 0x6a, 0xdf, + 0xc3, 0xbf, 0x4c, 0xf2, 0x57, 0x78, 0x22, 0xd5, 0x49, 0x4e, 0xf4, 0x18, 0xe5, 0x28, 0x61, 0x13, + 0xe1, 0xaa, 0x7d, 0xf9, 0x4d, 0x57, 0x2c, 0xfa, 0x5d, 0x2f, 0xb0, 0x77, 0x8a, 0xc0, 0x5e, 0xd7, + 0x83, 0xe1, 0xa6, 0xdf, 0x4b, 0xa2, 0x11, 0xad, 0xd6, 0xaf, 0x76, 0x40, 0xbe, 0x47, 0x00, 0xf9, + 0x74, 0xa8, 0x3a, 0xe3, 0xef, 0x30, 0xdf, 0xc9, 0x02, 0x94, 0xb5, 0x5d, 0x7d, 0x93, 0xd9, 0x4c, + 0xbe, 0x68, 0x0f, 0x78, 0xdc, 0xba, 0xf1, 0x1b, 0x1e, 0x9c, 0xcf, 0x42, 0x96, 0xc3, 0xca, 0xdb, + 0xf0, 0x3c, 0xa1, 0x0d, 0x6e, 0x29, 0x4c, 0x43, 0x5d, 0xb2, 0x54, 0x3b, 0xbd, 0x70, 0xcf, 0x55, + 0xb2, 0xeb, 0x9e, 0xab, 0x9e, 0xcb, 0x33, 0xbf, 0xdb, 0xaf, 0xd0, 0xfb, 0x42, 0x5f, 0x6b, 0xe6, + 0xa1, 0xc7, 0xd3, 0x22, 0x1f, 0x50, 0x6f, 0x83, 0xac, 0xe1, 0x98, 0x79, 0x24, 0xdf, 0xf5, 0x40, + 0xa9, 0xb5, 0x61, 0xa8, 0x76, 0xca, 0x90, 0x77, 0x83, 0x84, 0xa2, 0x23, 0x7e, 0xa0, 0x3f, 0x2d, + 0xc1, 0x89, 0x05, 0xfb, 0xdc, 0x24, 0x69, 0xc7, 0x79, 0xdd, 0xda, 0x5a, 0xd2, 0x5b, 0x17, 0x3a, + 0xe8, 0x5f, 0x85, 0x9b, 0xc9, 0x7b, 0xf0, 0x4f, 0x46, 0xc3, 0x5f, 0x74, 0x66, 0xac, 0x8a, 0xa8, + 0xdd, 0xed, 0x57, 0x4a, 0x6f, 0x6a, 0x7d, 0x00, 0xbc, 0x03, 0x32, 0x8c, 0x50, 0xde, 0x2d, 0x67, + 0x7c, 0xf1, 0x73, 0x4a, 0x52, 0x79, 0x0e, 0x8f, 0x4f, 0xd0, 0x39, 0x01, 0xc7, 0xb9, 0x03, 0x51, + 0x16, 0xbf, 0x33, 0xe3, 0xad, 0x90, 0xe5, 0x9c, 0x56, 0xa6, 0xbc, 0xbd, 0x58, 0x3e, 0xa2, 0x00, + 0x64, 0x96, 0x8d, 0x5d, 0x5c, 0x33, 0xe4, 0x04, 0xf9, 0x4f, 0xe8, 0xab, 0x19, 0x72, 0x12, 0xfd, + 0x57, 0x80, 0x31, 0xc7, 0x27, 0xf9, 0xf3, 0x49, 0xfb, 0x1a, 0x73, 0x6a, 0xa6, 0x66, 0xcc, 0x08, + 0xbd, 0x9b, 0xfe, 0x8a, 0xd0, 0x86, 0x4f, 0xc7, 0x57, 0xb8, 0xbb, 0xb2, 0x90, 0x37, 0x04, 0xbf, + 0x23, 0x94, 0x21, 0x34, 0x6c, 0x2d, 0xf1, 0x77, 0xb5, 0x6f, 0x24, 0xed, 0xc7, 0x22, 0x5c, 0x22, + 0xe8, 0xfe, 0x9f, 0xf8, 0xf8, 0xb5, 0xbb, 0xc1, 0xc0, 0x99, 0xeb, 0x89, 0x11, 0x5f, 0x40, 0x0d, + 0xdc, 0x79, 0xf5, 0x6d, 0x77, 0xc0, 0xd9, 0xec, 0x6e, 0x0e, 0x87, 0xdb, 0x5b, 0x8d, 0x52, 0x53, + 0xfc, 0x5c, 0x7e, 0x0f, 0x7b, 0x4f, 0xac, 0x15, 0xc1, 0x01, 0x44, 0xb8, 0x13, 0x33, 0xf0, 0x0d, + 0x7c, 0xb7, 0xa9, 0xa4, 0x86, 0x90, 0x5c, 0x7c, 0x32, 0x11, 0xe6, 0xb1, 0xfa, 0xc0, 0xa2, 0xe3, + 0x67, 0xdb, 0xb7, 0x93, 0x30, 0xce, 0x9c, 0xaf, 0x73, 0xcd, 0x66, 0xd7, 0x4b, 0xa8, 0xfb, 0x1c, + 0x4d, 0xff, 0x43, 0x68, 0xf7, 0x30, 0xa7, 0x55, 0x4e, 0xd9, 0xb1, 0xbd, 0x83, 0x18, 0xce, 0xc0, + 0xd3, 0x97, 0xa0, 0x91, 0xdc, 0xeb, 0x3a, 0x41, 0x34, 0xef, 0x8a, 0x89, 0x77, 0x75, 0x7c, 0x11, + 0x5d, 0x11, 0xb0, 0x04, 0x45, 0x6f, 0x0d, 0x7d, 0x38, 0xd2, 0x53, 0xa4, 0x0f, 0x8f, 0xef, 0x82, + 0x89, 0xa6, 0x9b, 0x88, 0x8f, 0x88, 0xa8, 0x6b, 0x44, 0xf4, 0x14, 0xa3, 0x7a, 0x93, 0x87, 0x5c, + 0xe5, 0xf9, 0x53, 0x11, 0x3f, 0x63, 0xbf, 0x95, 0x81, 0xb1, 0xd5, 0x56, 0xa7, 0xdd, 0x24, 0x8b, + 0xd2, 0x7f, 0x90, 0x9c, 0x4b, 0x5e, 0x5f, 0x28, 0xdc, 0x83, 0xf5, 0x73, 0x3b, 0xd8, 0xb4, 0xf7, + 0x94, 0x58, 0xa0, 0xf7, 0x15, 0x9b, 0xe8, 0x8f, 0xbc, 0x36, 0xe6, 0x9c, 0xc8, 0x7a, 0xd1, 0x41, + 0xdd, 0xae, 0x34, 0xf8, 0xf6, 0xd3, 0x12, 0x8c, 0xb5, 0xf5, 0xba, 0xb5, 0x63, 0x3a, 0x97, 0x41, + 0xde, 0x14, 0xae, 0x94, 0x15, 0x96, 0x4b, 0x75, 0xb2, 0x23, 0x0d, 0xb2, 0x3c, 0x72, 0x9f, 0x39, + 0x70, 0xdf, 0xbb, 0x07, 0xd4, 0xa9, 0xdc, 0xb4, 0xf4, 0x8e, 0x7d, 0x97, 0x2c, 0x0f, 0x11, 0xa5, + 0xc8, 0xfe, 0xad, 0x9a, 0x4d, 0x6e, 0x7e, 0x76, 0x23, 0xd0, 0x07, 0x1d, 0xb8, 0x0b, 0x02, 0xdc, + 0xb7, 0x44, 0x68, 0x79, 0x34, 0xc8, 0x1f, 0x18, 0xec, 0x91, 0x7e, 0x95, 0x3e, 0x9c, 0x5f, 0x5a, + 0x2e, 0xd5, 0xd6, 0x8a, 0x3f, 0x95, 0x2f, 0x16, 0x0b, 0xc5, 0x82, 0xdc, 0xa0, 0x4f, 0x28, 0x39, + 0x2b, 0x7e, 0x71, 0x24, 0xe0, 0x5c, 0x74, 0x47, 0x02, 0x27, 0x02, 0xbd, 0x21, 0xb4, 0xd3, 0xb4, + 0xd3, 0xf0, 0x3e, 0x6b, 0xfd, 0x5e, 0xf6, 0x92, 0x0f, 0x87, 0xf2, 0x7e, 0xee, 0x57, 0xc3, 0x21, + 0x32, 0xf7, 0xeb, 0xab, 0x90, 0xa6, 0x4b, 0x6f, 0xf4, 0x2e, 0x7a, 0x83, 0x67, 0xbb, 0xa9, 0xd5, + 0x31, 0xda, 0x8e, 0xf0, 0xec, 0xc1, 0x3a, 0xc9, 0xed, 0x3e, 0x7b, 0xc0, 0x83, 0xca, 0x69, 0x48, + 0xd3, 0xbf, 0x5c, 0xe3, 0x1f, 0xef, 0xb5, 0xdc, 0x57, 0x59, 0x12, 0xd1, 0x31, 0x30, 0xd0, 0x26, + 0xc3, 0xac, 0x04, 0x9c, 0x4c, 0x1f, 0x9c, 0xfc, 0x69, 0x8a, 0x36, 0x0a, 0x85, 0xbb, 0xaf, 0x38, + 0x88, 0xa2, 0xf8, 0xf5, 0xe4, 0x5f, 0xa7, 0x20, 0x5d, 0x6d, 0x37, 0x75, 0x0b, 0xfd, 0x5e, 0x72, + 0x28, 0x98, 0x99, 0x5a, 0x6b, 0x13, 0xfb, 0x60, 0xa6, 0x92, 0x6f, 0x2a, 0x4b, 0xe2, 0x1a, 0x32, + 0x53, 0x21, 0x0c, 0x99, 0x35, 0x7c, 0xc9, 0x12, 0x0c, 0x99, 0xca, 0x59, 0x7e, 0xd6, 0x26, 0xdd, + 0xe3, 0x54, 0x1e, 0xcb, 0x4b, 0x9b, 0xd5, 0xe3, 0xa4, 0xcd, 0xcc, 0xad, 0xfc, 0x5c, 0x0a, 0x40, + 0x66, 0xae, 0x52, 0xab, 0x55, 0x96, 0xe5, 0x23, 0x4a, 0x16, 0xa4, 0x5a, 0x65, 0x45, 0x4e, 0x28, + 0xe3, 0x90, 0x2e, 0x95, 0xcb, 0x45, 0x55, 0x4e, 0x92, 0xbf, 0xb5, 0x52, 0x6d, 0xa9, 0x28, 0x4b, + 0xe8, 0xdd, 0xa1, 0x87, 0x5e, 0xb1, 0xee, 0x38, 0xc5, 0x2b, 0xdc, 0x20, 0xec, 0x4f, 0x4f, 0xfc, + 0xc2, 0xf5, 0x6f, 0x25, 0x48, 0x2f, 0x63, 0x73, 0x13, 0xa3, 0x9f, 0x8b, 0x60, 0x0b, 0xdc, 0xd0, + 0xcd, 0x0e, 0x3b, 0x57, 0xe4, 0xda, 0x02, 0xbd, 0x71, 0xca, 0xb5, 0x30, 0xd9, 0xc1, 0x75, 0xa3, + 0xd5, 0xb0, 0x13, 0xf1, 0x1b, 0xab, 0x84, 0x48, 0xf4, 0x78, 0x44, 0xc8, 0x28, 0xa1, 0x43, 0x31, + 0xe8, 0x45, 0x01, 0xa6, 0x57, 0xad, 0xf1, 0x03, 0xf3, 0xbf, 0x24, 0x92, 0xa9, 0xbd, 0x87, 0x1e, + 0x0f, 0x6d, 0xa4, 0xbd, 0x11, 0x32, 0x54, 0x4c, 0xed, 0xf9, 0x4a, 0x6f, 0x7d, 0xcc, 0xd3, 0x28, + 0x73, 0x70, 0x59, 0x87, 0xbe, 0xf0, 0x8e, 0x1b, 0xa4, 0xeb, 0xaa, 0x7d, 0x95, 0xc2, 0xfe, 0xe4, + 0xe8, 0x2f, 0xbd, 0x00, 0xde, 0x25, 0x02, 0x78, 0xaa, 0x07, 0x2b, 0x49, 0x83, 0xfc, 0xdf, 0xba, + 0x21, 0xcd, 0xa8, 0x36, 0x0d, 0xc7, 0xb8, 0x68, 0x87, 0xc9, 0xb7, 0x2d, 0x6b, 0xbb, 0x49, 0xbf, + 0x71, 0x17, 0x16, 0x3b, 0xac, 0xcc, 0x42, 0x56, 0x6b, 0xed, 0xd1, 0x4f, 0xa9, 0x80, 0x56, 0xdb, + 0x89, 0xd0, 0x6b, 0x1c, 0xe4, 0xef, 0x15, 0x90, 0xbf, 0x21, 0x1c, 0xb9, 0xf1, 0x03, 0xff, 0x77, + 0x19, 0x48, 0xaf, 0x68, 0x1d, 0x0b, 0xa3, 0xaf, 0x4a, 0x61, 0x91, 0x3f, 0x05, 0x53, 0x1b, 0x46, + 0x7d, 0xa7, 0x83, 0x1b, 0x62, 0xa7, 0xec, 0x8a, 0x1d, 0x06, 0xe6, 0xca, 0x69, 0x90, 0xed, 0x48, + 0x5e, 0xac, 0x6d, 0xad, 0xdf, 0x17, 0x4f, 0x0f, 0x52, 0x77, 0x56, 0x34, 0xd3, 0xaa, 0x6c, 0xd0, + 0x38, 0xe7, 0x20, 0xb5, 0x37, 0x52, 0x80, 0x3e, 0x13, 0x00, 0x7d, 0xd6, 0x1f, 0xfa, 0xb1, 0x10, + 0xd0, 0x2b, 0x39, 0x18, 0xdb, 0xd0, 0x9b, 0x98, 0x66, 0x18, 0xef, 0x71, 0x05, 0x17, 0xdf, 0x9e, + 0x20, 0xbc, 0x77, 0xc6, 0xa4, 0x79, 0xbd, 0x89, 0x55, 0x27, 0x1b, 0x5a, 0x62, 0x9b, 0xfd, 0xce, + 0xb5, 0xfa, 0x09, 0xcf, 0xb5, 0xfa, 0x0a, 0xa4, 0x1a, 0x9a, 0xa5, 0x51, 0xd6, 0x1f, 0x55, 0xe9, + 0x7f, 0x71, 0xef, 0x48, 0xea, 0xde, 0x3b, 0x7a, 0x54, 0x8a, 0xa6, 0xff, 0x6c, 0xd2, 0x7c, 0xfa, + 0xcf, 0xba, 0x0d, 0x07, 0xf3, 0x02, 0x73, 0xc2, 0x04, 0x86, 0xba, 0x66, 0x62, 0x6b, 0xc5, 0xbb, + 0x3d, 0x93, 0x56, 0xc5, 0x48, 0xba, 0xe3, 0xdd, 0xa9, 0x6a, 0xdb, 0x98, 0x56, 0x96, 0x27, 0xdf, + 0xf8, 0x1e, 0xe7, 0xbe, 0x78, 0x57, 0xdb, 0xa6, 0x87, 0xad, 0x6d, 0x7b, 0xb5, 0x31, 0xfe, 0x4e, + 0xf7, 0xba, 0x14, 0x48, 0xf9, 0x1d, 0xeb, 0x59, 0xad, 0x6c, 0xff, 0x31, 0xf4, 0xe6, 0x17, 0xd7, + 0x5e, 0x3b, 0xd6, 0xe1, 0xea, 0xda, 0x88, 0x52, 0x12, 0x6e, 0x93, 0xcd, 0xaf, 0x6d, 0x23, 0x39, + 0xa0, 0x63, 0xfb, 0x21, 0x18, 0x07, 0x9f, 0x87, 0x23, 0xa6, 0x8c, 0x3c, 0x8a, 0xc1, 0x09, 0xdb, + 0x46, 0x81, 0x94, 0x6b, 0x57, 0x7a, 0x55, 0x68, 0x4f, 0x20, 0xc6, 0x9f, 0x40, 0xa7, 0x80, 0x68, + 0x53, 0xa5, 0x70, 0x17, 0xd4, 0x05, 0x54, 0x1b, 0x3f, 0x32, 0xdf, 0xf3, 0x5a, 0x0f, 0x72, 0x07, + 0xc6, 0x46, 0x34, 0xdb, 0x07, 0x5a, 0x98, 0x59, 0xb3, 0xfb, 0x18, 0x15, 0xa2, 0xf1, 0x3b, 0x9c, + 0xfd, 0x39, 0xb0, 0xe2, 0x11, 0x1c, 0x89, 0x92, 0x20, 0xc3, 0xf6, 0x0f, 0xd0, 0xdb, 0x42, 0xab, + 0x4c, 0xa2, 0x76, 0x44, 0x07, 0x02, 0x27, 0x1c, 0xc5, 0x94, 0x20, 0x38, 0x1a, 0xa4, 0x22, 0x39, + 0x1a, 0x88, 0xfe, 0xc2, 0x21, 0xfa, 0x51, 0xcf, 0xe7, 0xff, 0x87, 0xbd, 0x4a, 0x8c, 0xd2, 0xc3, + 0x7a, 0x12, 0x34, 0x02, 0x7f, 0x61, 0xf1, 0xe2, 0xb4, 0x7c, 0x04, 0xc8, 0xfd, 0x66, 0x25, 0x11, + 0x2e, 0x52, 0x67, 0x4d, 0x1f, 0xf2, 0x9d, 0x6a, 0xe1, 0x0e, 0x02, 0xf4, 0xa9, 0x3a, 0x7e, 0xce, + 0xbf, 0x9e, 0xdd, 0x6f, 0x3f, 0xaf, 0xe3, 0x66, 0xa3, 0x83, 0xcc, 0x83, 0x0f, 0x3c, 0x37, 0x43, + 0x66, 0x83, 0x16, 0xd6, 0xef, 0xd1, 0x78, 0x9e, 0x0c, 0xbd, 0x2e, 0x19, 0xd6, 0xb0, 0xce, 0x0d, + 0x19, 0x36, 0xb5, 0x43, 0x81, 0xe9, 0xf5, 0xa1, 0x0c, 0xdb, 0xc1, 0x35, 0xc7, 0x8f, 0xd2, 0x3b, + 0x25, 0x38, 0xca, 0x2f, 0x2c, 0xcb, 0x35, 0xf5, 0xcd, 0x96, 0xf7, 0x68, 0xda, 0xc0, 0x3d, 0x44, + 0xb9, 0x05, 0xd2, 0x1a, 0x29, 0x8d, 0xbb, 0x53, 0xa1, 0x9e, 0x5a, 0x8e, 0xd6, 0xa7, 0xb2, 0x84, + 0x11, 0x6e, 0x82, 0x70, 0x05, 0xdb, 0xa6, 0x79, 0x84, 0x37, 0x41, 0xf4, 0xad, 0x3c, 0x7e, 0xc4, + 0xbe, 0x26, 0xc1, 0x71, 0x4e, 0xc0, 0x39, 0x6c, 0x5a, 0x7a, 0x5d, 0x6b, 0x32, 0xe4, 0x5e, 0x9a, + 0x18, 0x06, 0x74, 0x8b, 0x30, 0xb9, 0xeb, 0x2d, 0x96, 0x43, 0x38, 0xd3, 0x13, 0x42, 0x81, 0x00, + 0x55, 0xcc, 0x18, 0xe1, 0x44, 0xbd, 0xc0, 0x55, 0xa1, 0xcc, 0x11, 0x9e, 0xa8, 0x0f, 0x4d, 0x44, + 0xfc, 0x10, 0xff, 0x6e, 0x8a, 0x5d, 0x32, 0xe1, 0xaa, 0xcf, 0x2f, 0x86, 0xc6, 0x76, 0x15, 0x26, + 0x28, 0x96, 0x2c, 0x23, 0x5f, 0xe3, 0x05, 0x08, 0xb1, 0xa3, 0x77, 0xf8, 0x25, 0x5d, 0x4e, 0x5e, + 0xd5, 0x5b, 0x0e, 0x3a, 0x0f, 0xe0, 0x7e, 0xf2, 0x2a, 0xe9, 0x84, 0x9f, 0x92, 0x4e, 0x86, 0x53, + 0xd2, 0x6f, 0x0d, 0x7d, 0x10, 0xaa, 0x37, 0xd9, 0x07, 0x17, 0x8f, 0x70, 0x47, 0x60, 0xfa, 0xd7, + 0x1e, 0xbf, 0x5c, 0xbc, 0x26, 0xd5, 0x7d, 0xa5, 0xee, 0xc7, 0x86, 0x32, 0x87, 0xf5, 0xea, 0x03, + 0xa9, 0x4b, 0x1f, 0x0c, 0x3e, 0x67, 0x55, 0xae, 0x87, 0x63, 0xac, 0x8a, 0xbc, 0x43, 0x16, 0x7b, + 0x79, 0xb1, 0x3b, 0x1a, 0x7d, 0x7c, 0x00, 0x21, 0xe8, 0x77, 0xdf, 0x6f, 0x90, 0x92, 0x8b, 0x36, + 0xcd, 0x8d, 0x2a, 0x20, 0x87, 0x77, 0x4d, 0xf0, 0xb7, 0x53, 0x6c, 0xb6, 0xbb, 0x4a, 0xef, 0x9f, + 0x43, 0x7f, 0x95, 0x1a, 0xc6, 0x88, 0x70, 0x1f, 0xa4, 0x2c, 0xfb, 0x85, 0xd8, 0xde, 0xcb, 0x48, + 0xb7, 0x4a, 0xf7, 0xe6, 0x3a, 0x7c, 0xc9, 0x5a, 0x3c, 0xa2, 0xd2, 0x9c, 0xca, 0x69, 0x38, 0xb6, + 0xae, 0xd5, 0x2f, 0x6c, 0x9a, 0xc6, 0x4e, 0xab, 0x91, 0x37, 0x9a, 0x86, 0xc9, 0x4c, 0x04, 0xf4, + 0x0a, 0x40, 0xf1, 0x83, 0x72, 0xc6, 0x9e, 0x3a, 0xa4, 0xfb, 0x4d, 0x1d, 0x16, 0x8f, 0xf0, 0xc9, + 0x83, 0x72, 0xab, 0xa3, 0x74, 0x32, 0x81, 0x4a, 0x67, 0xf1, 0x88, 0xad, 0x76, 0x94, 0x02, 0x8c, + 0x35, 0xf4, 0x5d, 0xba, 0xeb, 0xc7, 0xaf, 0xd4, 0x0b, 0x3e, 0x58, 0x51, 0xd0, 0x77, 0xd9, 0x1e, + 0xe1, 0xe2, 0x11, 0xd5, 0xc9, 0xa9, 0x2c, 0xc0, 0x38, 0xb5, 0xb0, 0xd2, 0x62, 0xc6, 0x22, 0x1d, + 0x9a, 0x58, 0x3c, 0xa2, 0xba, 0x79, 0xc9, 0xec, 0x23, 0x45, 0xdd, 0x91, 0xef, 0xb5, 0x77, 0x2e, + 0x13, 0x91, 0x76, 0x2e, 0x09, 0x2f, 0xd8, 0xde, 0xe5, 0x09, 0x48, 0xd7, 0x29, 0x87, 0x93, 0x9c, + 0xc3, 0x2c, 0xa8, 0xdc, 0x05, 0xa9, 0x6d, 0xcd, 0xb4, 0x97, 0xa9, 0xa7, 0xfa, 0x97, 0xbb, 0xac, + 0x99, 0x17, 0x08, 0x82, 0x24, 0xd7, 0x5c, 0x16, 0xd2, 0x94, 0x71, 0xce, 0x1f, 0xf4, 0x34, 0x9f, + 0x86, 0xe4, 0x8d, 0x16, 0x19, 0xf6, 0x6b, 0x86, 0xed, 0xb3, 0x5d, 0x1f, 0x86, 0xcc, 0x89, 0xfe, + 0x89, 0xd2, 0x3e, 0xff, 0xc4, 0xbf, 0x1c, 0x60, 0x6e, 0xd1, 0x4d, 0xa9, 0xff, 0xe2, 0xb8, 0x29, + 0xbc, 0xa6, 0x6e, 0x07, 0x23, 0x6a, 0x8d, 0xa8, 0xb3, 0x8e, 0x3e, 0xe4, 0x8d, 0xe0, 0xf1, 0xfb, + 0x14, 0x4c, 0x13, 0x42, 0x98, 0xe7, 0xae, 0x78, 0x79, 0x25, 0xfa, 0xf3, 0xa1, 0x4c, 0x2e, 0x7b, + 0x8c, 0x08, 0x52, 0xcf, 0x11, 0x61, 0xdf, 0xb9, 0x8d, 0x54, 0x9f, 0x73, 0x1b, 0xe9, 0x68, 0xe6, + 0x94, 0x3f, 0xf6, 0xca, 0xcf, 0x8a, 0x28, 0x3f, 0x77, 0xf8, 0x00, 0xd4, 0x8b, 0x2f, 0x43, 0x99, + 0x80, 0xbc, 0xcb, 0x91, 0x94, 0xaa, 0x20, 0x29, 0xf7, 0x0e, 0x4e, 0x48, 0xfc, 0xd2, 0xf2, 0xa1, + 0x14, 0xfc, 0x98, 0x4b, 0x4c, 0x19, 0x5f, 0xe4, 0x82, 0xf2, 0xf9, 0xa1, 0x08, 0xca, 0xad, 0xee, + 0x9b, 0x33, 0x7d, 0x16, 0xfb, 0x76, 0xba, 0xb8, 0x25, 0xe6, 0x2f, 0x42, 0xfb, 0x9b, 0x77, 0x03, + 0xe5, 0xf0, 0xc6, 0x47, 0x58, 0x4e, 0x40, 0x86, 0x69, 0x18, 0xfb, 0x05, 0x6c, 0x16, 0x8a, 0xa8, + 0x6e, 0xc2, 0x79, 0xa9, 0x87, 0xa5, 0x6d, 0x04, 0xf2, 0xc3, 0x0d, 0x0f, 0xb5, 0x1d, 0xb3, 0x55, + 0x6a, 0x59, 0x06, 0xfa, 0xc5, 0xa1, 0x08, 0x8e, 0xe3, 0xf9, 0x23, 0x0d, 0xe2, 0xf9, 0x33, 0x90, + 0x19, 0xc2, 0x6e, 0xc1, 0xa1, 0x98, 0x21, 0x7c, 0x2a, 0x8f, 0x1f, 0xbf, 0xa7, 0x24, 0x38, 0xc1, + 0x57, 0x43, 0x73, 0xe2, 0x14, 0x0e, 0x3d, 0x38, 0x0c, 0x20, 0x8f, 0xdb, 0xf3, 0x18, 0x36, 0x40, + 0xb0, 0x80, 0xe8, 0x11, 0x1e, 0x78, 0x87, 0xa2, 0xb0, 0x5e, 0xeb, 0xa2, 0x70, 0x28, 0x48, 0x85, + 0xbb, 0x3a, 0x31, 0x02, 0x19, 0xf1, 0x63, 0xf6, 0x5b, 0x12, 0x64, 0xf8, 0xc5, 0xf5, 0xab, 0xb1, + 0x6c, 0x17, 0x8b, 0xf7, 0xe5, 0x84, 0xd8, 0xa6, 0x88, 0x7c, 0x63, 0x7c, 0x7c, 0x1b, 0x14, 0x87, + 0x73, 0x25, 0x3c, 0x7a, 0x5c, 0xe2, 0x96, 0x95, 0x25, 0xcd, 0xc2, 0x97, 0xd0, 0xaf, 0x49, 0x90, + 0xad, 0x62, 0x8b, 0x68, 0xa6, 0xf0, 0x18, 0xf9, 0xdb, 0xcc, 0x15, 0xcf, 0xda, 0x6d, 0x9c, 0xad, + 0xc6, 0xa2, 0xea, 0x38, 0x4a, 0xd7, 0x2c, 0xa7, 0x69, 0xd4, 0x3a, 0x2e, 0xa8, 0xf2, 0x11, 0x9c, + 0x4e, 0xbd, 0x16, 0xc6, 0x29, 0x19, 0x14, 0x8e, 0x4f, 0x78, 0xa0, 0xf9, 0x9d, 0x44, 0x2c, 0xd8, + 0x90, 0xe1, 0x8b, 0x5e, 0xab, 0x4e, 0x67, 0x2f, 0x13, 0x61, 0x86, 0x2f, 0xb2, 0x4c, 0xeb, 0xa8, + 0x2c, 0x57, 0x84, 0xe7, 0x7e, 0x9c, 0x66, 0x0d, 0x15, 0xd9, 0x70, 0xef, 0x30, 0xf4, 0xab, 0x7b, + 0x04, 0xaf, 0x78, 0x48, 0x30, 0x56, 0x25, 0xcb, 0x0d, 0x32, 0xa6, 0x9c, 0x3f, 0x38, 0x94, 0xbd, + 0x07, 0xab, 0x88, 0x1d, 0xcd, 0xe6, 0xc8, 0xf0, 0x86, 0xa8, 0x08, 0x1d, 0x2d, 0xa8, 0xf2, 0xf8, + 0xf1, 0x78, 0x37, 0xc3, 0x83, 0xca, 0x32, 0x7a, 0x93, 0x04, 0xd2, 0x02, 0xb6, 0x86, 0xe4, 0xe7, + 0x1f, 0xd6, 0x67, 0x5c, 0x1c, 0xba, 0x02, 0x8f, 0x76, 0x0b, 0x0c, 0xa3, 0x34, 0xcf, 0x2e, 0xe0, + 0xe1, 0x74, 0xa0, 0x70, 0x67, 0xba, 0x43, 0x11, 0x10, 0x3f, 0x6a, 0xef, 0x67, 0xa8, 0x31, 0x0b, + 0xd6, 0x2f, 0x0c, 0x41, 0x23, 0x8e, 0x76, 0xf2, 0x6e, 0x33, 0x90, 0x96, 0x71, 0x58, 0xfd, 0xad, + 0x57, 0xe5, 0x23, 0xf1, 0x08, 0x03, 0xd2, 0xd9, 0xb7, 0x70, 0xfd, 0x02, 0x6e, 0xa0, 0x9f, 0x39, + 0x38, 0x74, 0xd3, 0x90, 0xad, 0xb3, 0xd2, 0x28, 0x78, 0x63, 0xaa, 0x1d, 0x8c, 0xf0, 0xd8, 0xb6, + 0xa8, 0x88, 0x58, 0xf6, 0x11, 0x3e, 0xb6, 0x1d, 0xa2, 0xfa, 0xf8, 0x91, 0xf9, 0x43, 0x36, 0xc9, + 0x28, 0xd5, 0x8d, 0x16, 0xfa, 0xd7, 0x07, 0x87, 0xe5, 0x4a, 0x18, 0xd7, 0xeb, 0x46, 0xab, 0xb4, + 0xad, 0x6d, 0xda, 0x66, 0x54, 0x37, 0xc2, 0xfe, 0x5a, 0xdc, 0x36, 0x1e, 0xd2, 0xf9, 0xd6, 0x8c, + 0x1b, 0x31, 0xe8, 0x64, 0x82, 0x90, 0x7e, 0x58, 0x93, 0x89, 0x1e, 0x75, 0xc7, 0x0f, 0xd9, 0xc7, + 0x5d, 0x17, 0x0a, 0xa6, 0x0a, 0x9f, 0x15, 0x96, 0x8c, 0x41, 0x86, 0x33, 0x6f, 0x2b, 0x0e, 0x65, + 0x38, 0x0b, 0x20, 0x20, 0x7e, 0x1c, 0x5f, 0xe5, 0xe2, 0x18, 0xbb, 0x1d, 0xe3, 0x00, 0xe8, 0x0c, + 0x6f, 0x7a, 0x38, 0x20, 0x3a, 0x87, 0x33, 0x45, 0xfc, 0x30, 0xbf, 0x1a, 0x88, 0xcf, 0x78, 0xd0, + 0xcf, 0x0f, 0x03, 0x9c, 0x3b, 0x06, 0xd9, 0x14, 0x63, 0x5b, 0x62, 0x11, 0x5e, 0x4e, 0xd9, 0xc7, + 0x41, 0x52, 0xca, 0x50, 0x10, 0x0c, 0xf7, 0x72, 0x4a, 0x98, 0xfa, 0xe3, 0x07, 0xf0, 0xd7, 0x25, + 0x98, 0xa2, 0xfb, 0x5c, 0x4d, 0xac, 0x99, 0x4c, 0x51, 0x0e, 0xc5, 0x1b, 0xf3, 0xdd, 0xa1, 0x2f, + 0x35, 0x17, 0xf9, 0xe0, 0xd2, 0x31, 0x14, 0x28, 0xc2, 0x3d, 0x11, 0x1a, 0x92, 0x84, 0x91, 0x98, + 0x02, 0x65, 0x87, 0x04, 0x2e, 0xe2, 0xc3, 0xc1, 0x23, 0xa2, 0xdb, 0x97, 0xc8, 0x0c, 0xbb, 0xb3, + 0x8d, 0xd8, 0xed, 0x2b, 0x0c, 0x11, 0x23, 0xb8, 0x3a, 0xfb, 0x16, 0x6e, 0x0a, 0xac, 0xd1, 0x87, + 0x85, 0x9e, 0x48, 0x39, 0xae, 0xea, 0x9f, 0x19, 0x8a, 0x9b, 0xcf, 0x01, 0xee, 0xb9, 0x53, 0x20, + 0x65, 0x1a, 0x17, 0x99, 0x59, 0x6a, 0x52, 0xa5, 0xff, 0xe9, 0x94, 0xdf, 0x68, 0xee, 0x6c, 0xb7, + 0xd8, 0xb3, 0x87, 0x93, 0xaa, 0x1d, 0x54, 0xae, 0x85, 0xc9, 0x8b, 0xba, 0xb5, 0xb5, 0x88, 0xb5, + 0x06, 0x36, 0x55, 0xe3, 0x22, 0x7f, 0x61, 0x54, 0x8c, 0x14, 0xf7, 0x60, 0x43, 0xcc, 0x2f, 0xe9, + 0x6b, 0x43, 0x23, 0xf1, 0x6b, 0x8f, 0x32, 0xf3, 0xf4, 0xa7, 0x2a, 0x7e, 0x81, 0xf9, 0x80, 0x04, + 0xe3, 0xaa, 0x71, 0x91, 0x0b, 0xc9, 0xbf, 0x39, 0x5c, 0x19, 0x89, 0xbc, 0xd0, 0x63, 0xaf, 0x47, + 0xd9, 0xe4, 0x8f, 0x7c, 0xa1, 0x17, 0x58, 0xfd, 0x48, 0xdc, 0xe3, 0x8f, 0xaa, 0xc6, 0xc5, 0x2a, + 0xb6, 0x58, 0x8f, 0x40, 0x6b, 0x43, 0xf2, 0xe4, 0xd3, 0x3b, 0xac, 0x40, 0xbe, 0x0e, 0x77, 0xc2, + 0xe8, 0xa9, 0xd0, 0x8f, 0xf2, 0x88, 0x0c, 0x72, 0x48, 0x1c, 0x0a, 0x44, 0x6f, 0x0f, 0xf5, 0x16, + 0x4f, 0x38, 0x0a, 0xe2, 0x47, 0xe9, 0x97, 0x25, 0x98, 0x50, 0x8d, 0x8b, 0x64, 0x68, 0x98, 0xd7, + 0x9b, 0xcd, 0xe1, 0x8c, 0x90, 0x51, 0x27, 0xff, 0x36, 0x1b, 0x6c, 0x2a, 0x46, 0x3e, 0xf9, 0xef, + 0x43, 0x40, 0xfc, 0x30, 0x3c, 0xca, 0x3a, 0x8b, 0x3d, 0x42, 0xb7, 0x86, 0x83, 0xc3, 0xa0, 0x1d, + 0xc2, 0x21, 0xe3, 0xd0, 0x3a, 0x84, 0x1f, 0x05, 0x23, 0xd9, 0x39, 0x99, 0xca, 0xd3, 0x61, 0x7e, + 0xb8, 0x7d, 0xe2, 0xbd, 0xd1, 0xdc, 0x6b, 0xf8, 0xb0, 0x2b, 0x10, 0x32, 0x14, 0x34, 0x22, 0xb8, + 0xd1, 0x84, 0xa0, 0x21, 0x7e, 0x3c, 0xfe, 0x44, 0x82, 0xa3, 0x8c, 0x84, 0x67, 0xc9, 0x2c, 0x60, + 0xa0, 0x4e, 0xe5, 0x6d, 0xc1, 0xe1, 0x74, 0xaa, 0x00, 0x0a, 0xe2, 0x07, 0xf1, 0xff, 0x26, 0xe9, + 0x3c, 0x6e, 0x80, 0x33, 0x8a, 0x7e, 0x08, 0x0e, 0x3c, 0x19, 0x1b, 0xe2, 0x39, 0xc5, 0x41, 0x26, + 0x63, 0x87, 0x74, 0x56, 0xf1, 0x51, 0xa7, 0x17, 0x0d, 0x13, 0x83, 0x03, 0x74, 0x85, 0x21, 0xc2, + 0x30, 0x60, 0x57, 0x38, 0x24, 0x24, 0xbe, 0x2e, 0x01, 0x30, 0x02, 0x96, 0x8d, 0x5d, 0x8c, 0x9e, + 0x1c, 0xca, 0xc2, 0xb7, 0xdb, 0x35, 0x54, 0xea, 0xe3, 0x1a, 0x1a, 0xf1, 0x6c, 0x76, 0x54, 0x4b, + 0xa0, 0x87, 0xcb, 0xcb, 0xbe, 0x8f, 0x22, 0xc6, 0x68, 0x09, 0x0c, 0xae, 0x3f, 0x7e, 0x8c, 0xbf, + 0xc2, 0x66, 0x73, 0xee, 0x29, 0xa6, 0x57, 0x0e, 0x05, 0x65, 0xcf, 0xea, 0x5f, 0x12, 0x57, 0xff, + 0x07, 0xc0, 0x76, 0xd0, 0x39, 0x62, 0xbf, 0xd3, 0x49, 0xf1, 0xcf, 0x11, 0x0f, 0xef, 0x14, 0xd2, + 0x2f, 0xa4, 0xe0, 0x18, 0x57, 0x22, 0xff, 0x14, 0x20, 0x8e, 0x78, 0x96, 0x44, 0x50, 0x92, 0x7d, + 0x50, 0x1e, 0x96, 0x41, 0x2a, 0x8a, 0x29, 0x33, 0x04, 0x79, 0x23, 0xb1, 0x6e, 0x64, 0x8a, 0x97, + 0xda, 0x5a, 0xab, 0x11, 0xfe, 0x7a, 0xbe, 0x3e, 0xc0, 0xdb, 0xb6, 0x46, 0x49, 0xb4, 0x35, 0xf6, + 0xb0, 0x4c, 0x46, 0xde, 0xb9, 0xa6, 0x2c, 0x63, 0xe4, 0x8e, 0x7c, 0xe7, 0xda, 0xbf, 0xee, 0xf8, + 0x51, 0x7a, 0xaf, 0x04, 0xa9, 0xaa, 0x61, 0x5a, 0xe8, 0xb1, 0x28, 0xbd, 0x93, 0x71, 0xde, 0x05, + 0xc9, 0x0e, 0x2b, 0x79, 0xe1, 0xa1, 0xa2, 0x9b, 0x83, 0xcf, 0xd3, 0x69, 0x96, 0x46, 0x2f, 0x6f, + 0x26, 0xf5, 0x7b, 0x5e, 0x2c, 0x8a, 0x7a, 0x69, 0x03, 0xe3, 0x5f, 0xd5, 0xdf, 0x89, 0x38, 0xb6, + 0x4b, 0x1b, 0x7c, 0x6b, 0x1e, 0x81, 0xdd, 0x77, 0x82, 0xfb, 0xa5, 0xd2, 0xf7, 0xdb, 0x1e, 0x63, + 0x2e, 0x23, 0x65, 0x6d, 0x1b, 0x0f, 0xc9, 0x65, 0x98, 0xde, 0x10, 0x27, 0xb9, 0x37, 0xc4, 0x45, + 0xed, 0x50, 0xec, 0x94, 0x23, 0x23, 0x69, 0xd4, 0x1d, 0x2a, 0xa0, 0xee, 0xf8, 0x81, 0xf9, 0x12, + 0x19, 0xf9, 0xe8, 0x1a, 0x32, 0xd7, 0x6a, 0xf0, 0x2b, 0xb7, 0xfe, 0xee, 0xb0, 0xf7, 0x6e, 0xf6, + 0x5d, 0xca, 0x25, 0x5e, 0xee, 0x97, 0xee, 0x7e, 0x6f, 0x6c, 0x8e, 0x5d, 0xf0, 0x45, 0x4f, 0x5e, + 0x66, 0x22, 0xbd, 0x39, 0xe6, 0xe4, 0x43, 0x4f, 0x47, 0x33, 0xe7, 0xd0, 0x22, 0xba, 0x18, 0x17, + 0xf3, 0x90, 0x1a, 0xc1, 0xd0, 0x13, 0x82, 0xba, 0x7f, 0x1e, 0x5e, 0x46, 0xfb, 0x9f, 0x7c, 0x8b, + 0x68, 0xca, 0x76, 0x1e, 0xea, 0x3b, 0x2c, 0x2f, 0xa3, 0x7e, 0x04, 0xc4, 0x8f, 0xe3, 0xd3, 0x69, + 0xbe, 0xc9, 0x4b, 0x5d, 0xf0, 0xd0, 0x97, 0x93, 0xb1, 0x2b, 0xef, 0xf0, 0x8f, 0x9c, 0xba, 0x74, + 0x05, 0x6b, 0xef, 0x28, 0x8e, 0xae, 0x41, 0xc5, 0x8d, 0xc0, 0x9c, 0x90, 0xa4, 0x2e, 0xca, 0xe7, + 0xf5, 0x86, 0xb5, 0x35, 0x24, 0x47, 0xff, 0x8b, 0xa4, 0x2c, 0xfb, 0xb5, 0x30, 0x1a, 0x40, 0x3f, + 0x4c, 0x44, 0xba, 0xbe, 0xc2, 0x61, 0x09, 0x25, 0xcb, 0x87, 0xc5, 0x11, 0x2e, 0x9d, 0x08, 0x2c, + 0x6f, 0x84, 0x12, 0x7d, 0x4e, 0x6f, 0x60, 0xe3, 0x59, 0x28, 0xd1, 0x94, 0xae, 0xe1, 0x49, 0x74, + 0x50, 0x71, 0xff, 0x4c, 0x25, 0xda, 0x61, 0xc9, 0x90, 0x24, 0x3a, 0xb0, 0xbc, 0x11, 0xdc, 0x64, + 0x0d, 0x7c, 0x7e, 0xbd, 0xa4, 0xb7, 0x2e, 0xa0, 0x4f, 0xa6, 0xed, 0x77, 0xca, 0xce, 0xeb, 0xd6, + 0x16, 0x3f, 0xe6, 0xfe, 0xf1, 0xd0, 0x2f, 0x1a, 0x0c, 0x70, 0x94, 0xfd, 0x24, 0x80, 0xc5, 0xdf, + 0x0f, 0x72, 0xee, 0xcc, 0xf1, 0xc4, 0x28, 0x39, 0x98, 0xd4, 0x5b, 0x16, 0x36, 0x5b, 0x5a, 0x73, + 0xbe, 0xa9, 0x6d, 0x76, 0xa6, 0xb3, 0xf4, 0x68, 0xe6, 0x15, 0x5d, 0x83, 0x77, 0xc9, 0x93, 0x46, + 0x15, 0x73, 0x84, 0x9e, 0x6b, 0x46, 0xbc, 0xf2, 0xe7, 0xe6, 0x90, 0x37, 0xb1, 0x38, 0xd7, 0x3f, + 0x7d, 0x37, 0x9a, 0xf1, 0x85, 0x00, 0x32, 0xdb, 0x0d, 0x46, 0xe4, 0x99, 0xa2, 0xb7, 0xf1, 0x52, + 0x57, 0xe3, 0x9d, 0xa9, 0x47, 0x6a, 0xc8, 0x86, 0x99, 0x30, 0xa4, 0x8f, 0xe0, 0xe4, 0x47, 0x1a, + 0x2e, 0xb3, 0xaf, 0xaf, 0x6b, 0xb7, 0xb1, 0x66, 0x6a, 0xad, 0x3a, 0x8e, 0x20, 0xcd, 0x41, 0x73, + 0xc9, 0x79, 0x18, 0xd3, 0xeb, 0x46, 0xab, 0xaa, 0xbf, 0xc4, 0x7e, 0x78, 0xe3, 0x74, 0xe0, 0x74, + 0x92, 0x72, 0xa4, 0xc4, 0x73, 0xa8, 0x4e, 0x5e, 0xa5, 0x04, 0xe3, 0x75, 0xcd, 0x6c, 0x54, 0x3d, + 0x4f, 0x11, 0xdf, 0xd0, 0xbf, 0xa0, 0xbc, 0x9d, 0x45, 0x75, 0x73, 0x2b, 0x15, 0x91, 0x89, 0x99, + 0xae, 0xd3, 0xbf, 0xbe, 0x85, 0x15, 0xdc, 0x4c, 0x02, 0xcf, 0x09, 0x77, 0x4c, 0xdc, 0xa4, 0xef, + 0x1c, 0xb2, 0x6e, 0x37, 0xae, 0xba, 0x11, 0xe8, 0x03, 0x5e, 0x69, 0x5e, 0x16, 0xa5, 0xf9, 0xc5, + 0x3e, 0x22, 0xb1, 0x0f, 0x8d, 0xa1, 0xcc, 0x89, 0xdf, 0xe9, 0x08, 0xe6, 0x8a, 0x20, 0x98, 0x77, + 0x0d, 0x48, 0x45, 0xfc, 0x92, 0xf9, 0xae, 0x0c, 0x4c, 0xb2, 0xc3, 0xe4, 0x9c, 0x9d, 0xe8, 0xd7, + 0xe9, 0xd3, 0x5a, 0xd6, 0x03, 0x78, 0x0f, 0x55, 0x0f, 0x3e, 0xd0, 0xc9, 0x20, 0x5d, 0xc0, 0x7b, + 0xbc, 0xbf, 0x93, 0xbf, 0x51, 0xf7, 0x48, 0x6d, 0xba, 0x66, 0x19, 0x4d, 0xa3, 0xde, 0x23, 0x0d, + 0xae, 0x3e, 0x7e, 0x7c, 0x5e, 0x2e, 0x81, 0x94, 0x6b, 0x34, 0xc2, 0xdf, 0xef, 0xe4, 0x0f, 0xc5, + 0xd5, 0x30, 0x61, 0xf7, 0x99, 0x07, 0x1c, 0x48, 0xbc, 0x51, 0x51, 0x0d, 0x4e, 0x0e, 0x6f, 0x72, + 0x8d, 0x91, 0x5b, 0x70, 0x03, 0xea, 0x8e, 0x1f, 0x94, 0x57, 0x66, 0x79, 0xa7, 0x99, 0x33, 0x8c, + 0x0b, 0xf4, 0x58, 0xc2, 0x63, 0x12, 0xa4, 0xe7, 0xb1, 0x55, 0xdf, 0x1a, 0x52, 0x9f, 0xd9, 0x31, + 0x9b, 0x76, 0x9f, 0xd9, 0xf7, 0x4e, 0x60, 0xff, 0x89, 0xa1, 0x4d, 0xd6, 0x2c, 0x25, 0x69, 0xd4, + 0xd7, 0x35, 0x06, 0xd6, 0x1e, 0x3f, 0x38, 0x3f, 0x94, 0x60, 0xca, 0x31, 0x1b, 0x31, 0x4c, 0x7e, + 0xf3, 0x59, 0x67, 0x0c, 0x44, 0x9f, 0x8f, 0x76, 0xa5, 0x8a, 0xc3, 0x53, 0xb1, 0x65, 0x31, 0x5b, + 0xeb, 0x22, 0x5c, 0xb6, 0x12, 0x8e, 0xc0, 0x11, 0x2c, 0x8b, 0x25, 0x18, 0xa3, 0x04, 0x15, 0xf4, + 0x5d, 0xea, 0xa6, 0x25, 0x58, 0xef, 0x1e, 0x1e, 0x8a, 0xf5, 0xee, 0x2e, 0xd1, 0x7a, 0x17, 0xf2, + 0x0a, 0x43, 0xdb, 0x78, 0x17, 0xd1, 0x6f, 0x81, 0xe4, 0x1f, 0xba, 0xed, 0x2e, 0x82, 0xdf, 0x42, + 0x9f, 0xfa, 0x47, 0xf0, 0xa0, 0xea, 0x69, 0xae, 0x6c, 0xed, 0xcd, 0x2b, 0xf4, 0xb0, 0x02, 0xa9, + 0x73, 0xe4, 0xcf, 0x97, 0xdd, 0x67, 0x05, 0x1e, 0x1e, 0xc2, 0x41, 0xf8, 0x7b, 0x20, 0x45, 0x9f, + 0x4e, 0x4d, 0x75, 0x5d, 0xb9, 0x19, 0xb8, 0x93, 0x46, 0x08, 0x51, 0x69, 0xbe, 0xa8, 0x97, 0x95, + 0x09, 0x45, 0xcc, 0x0e, 0xcf, 0x0d, 0x4f, 0x39, 0x01, 0x19, 0x52, 0xae, 0xb3, 0xcc, 0xe2, 0xa1, + 0x28, 0xc6, 0xf7, 0x10, 0xb4, 0xc5, 0x8f, 0xfc, 0x97, 0xe9, 0x0b, 0x2a, 0xf4, 0x4e, 0xd5, 0xc7, + 0x87, 0x00, 0xaf, 0x0f, 0x5b, 0x0e, 0x0c, 0xfb, 0x7b, 0x0f, 0x02, 0xbb, 0x73, 0x81, 0xeb, 0x48, + 0x9d, 0x68, 0x43, 0xd0, 0x30, 0x92, 0x93, 0xbf, 0x19, 0xee, 0xf8, 0xf7, 0xe0, 0x30, 0xd1, 0x4d, + 0x09, 0x42, 0x7f, 0x20, 0x74, 0x86, 0xe8, 0x10, 0x38, 0x30, 0x3a, 0x87, 0xe4, 0x12, 0xf8, 0xa7, + 0x12, 0x4c, 0x54, 0xdd, 0xe7, 0xbe, 0xc2, 0xbf, 0x50, 0x10, 0x19, 0x22, 0x32, 0xd6, 0x0a, 0xf7, + 0x43, 0x4e, 0x0e, 0x7e, 0x65, 0xa8, 0xc8, 0x3a, 0x0f, 0xfd, 0xa3, 0xbe, 0x32, 0x34, 0x2c, 0x21, + 0xf1, 0x03, 0xf9, 0x59, 0xf6, 0x22, 0x48, 0xae, 0x6e, 0xe9, 0xbb, 0x18, 0x3d, 0x1a, 0xa3, 0x22, + 0x3d, 0x01, 0x19, 0x63, 0x63, 0xa3, 0xc3, 0xdf, 0x81, 0x9b, 0x54, 0x79, 0xc8, 0x7d, 0x80, 0x9b, + 0x81, 0xcb, 0x1f, 0xe0, 0x8e, 0x78, 0xa9, 0xe0, 0x3e, 0x86, 0xb2, 0x06, 0x8d, 0xfa, 0x52, 0xc1, + 0x70, 0x64, 0x8c, 0xe0, 0xda, 0x60, 0x20, 0xdc, 0xe3, 0x26, 0x9b, 0x37, 0x71, 0x23, 0x01, 0x3e, + 0x38, 0xb6, 0x33, 0x70, 0xd4, 0x63, 0x11, 0xb0, 0x2f, 0xa6, 0x17, 0xe2, 0xa2, 0x9e, 0x35, 0x76, + 0x58, 0x36, 0x74, 0x7b, 0x41, 0x04, 0x3b, 0x70, 0x18, 0x22, 0x46, 0xf2, 0xee, 0x8b, 0x3d, 0xe4, + 0x8d, 0x08, 0xab, 0x0f, 0x79, 0xb1, 0xaa, 0x88, 0x58, 0x9d, 0x0d, 0xc3, 0xa6, 0x70, 0x43, 0x60, + 0xa8, 0xe5, 0xe4, 0x53, 0x0e, 0x5c, 0xaa, 0x00, 0xd7, 0x3d, 0x03, 0xd3, 0x11, 0x3f, 0x62, 0x1f, + 0x95, 0xd8, 0xe3, 0x0f, 0xb9, 0x5d, 0x4d, 0x6f, 0xd2, 0x03, 0xe2, 0x43, 0x78, 0x30, 0xee, 0xbf, + 0x7b, 0x41, 0x39, 0x27, 0x82, 0x72, 0x5f, 0x18, 0x66, 0x08, 0x14, 0xf9, 0x60, 0xf3, 0x42, 0xaf, + 0xcd, 0x9c, 0xdd, 0x22, 0x7a, 0x79, 0xf7, 0x4d, 0x6c, 0xfc, 0xbb, 0xd7, 0x98, 0xfe, 0x19, 0x07, + 0xa4, 0x07, 0x05, 0x90, 0x8a, 0x07, 0xa5, 0x2b, 0x1a, 0x56, 0x4b, 0x03, 0xbc, 0x68, 0x3f, 0x0d, + 0xc7, 0xcb, 0x95, 0xda, 0x5a, 0x6e, 0xad, 0x90, 0xab, 0xe5, 0xce, 0x95, 0x8a, 0xe7, 0xd7, 0xe6, + 0x96, 0x2a, 0xf9, 0x07, 0x64, 0x09, 0xfd, 0x1e, 0x1b, 0x03, 0xab, 0xc6, 0x8e, 0x59, 0x1f, 0xd6, + 0x6c, 0xb3, 0x43, 0x0b, 0xe3, 0x9d, 0x8e, 0x87, 0xa2, 0x3a, 0xae, 0xbb, 0xfe, 0x98, 0x36, 0x71, + 0xfd, 0x3a, 0x5a, 0x6a, 0xc8, 0x8e, 0xeb, 0x7d, 0x29, 0x88, 0xbf, 0x8b, 0x7d, 0x5f, 0x02, 0x58, + 0x30, 0x8d, 0x9d, 0x76, 0xc5, 0x6c, 0x60, 0x13, 0x3d, 0xe3, 0xae, 0xfa, 0x7e, 0x7b, 0x08, 0x93, + 0x95, 0x15, 0x80, 0x4d, 0xa7, 0x70, 0xae, 0xa7, 0x6e, 0x09, 0xb7, 0xc6, 0x73, 0x89, 0x52, 0x3d, + 0x65, 0xa0, 0x8f, 0x78, 0x31, 0xfe, 0x49, 0x11, 0xe3, 0xa0, 0x91, 0xc7, 0x2d, 0x6e, 0x98, 0xab, + 0xbe, 0x77, 0x3b, 0x58, 0xd7, 0x04, 0xac, 0xef, 0x3b, 0x00, 0x25, 0xf1, 0x63, 0xfe, 0x03, 0x09, + 0x26, 0xd8, 0x5e, 0x2c, 0xe3, 0xe9, 0xdf, 0xba, 0xa0, 0xbf, 0x72, 0x08, 0xa0, 0xaf, 0xc2, 0x51, + 0xc3, 0x2d, 0x9d, 0x8d, 0x8c, 0x5e, 0xeb, 0x5a, 0x20, 0xec, 0x1e, 0xba, 0x54, 0xa1, 0x18, 0xf4, + 0x51, 0x2f, 0xf2, 0xaa, 0x88, 0xfc, 0x5d, 0x01, 0xfc, 0xf6, 0x94, 0x38, 0x4c, 0xe8, 0xdf, 0xe3, + 0x40, 0xbf, 0x2a, 0x40, 0x9f, 0x3b, 0x08, 0x29, 0xf1, 0x63, 0xff, 0x88, 0x63, 0xa0, 0x77, 0xb6, + 0x4f, 0x62, 0xd9, 0x34, 0x79, 0xf5, 0x80, 0x0b, 0x0c, 0x91, 0x36, 0x1f, 0xa4, 0xa6, 0x20, 0xa9, + 0xdb, 0x34, 0x24, 0xf5, 0xc6, 0x40, 0x4b, 0x88, 0xc0, 0x8a, 0xe2, 0xc7, 0xe1, 0x0d, 0xcf, 0x85, + 0x74, 0x01, 0xaf, 0xef, 0x6c, 0xa2, 0xb7, 0x4a, 0x90, 0x6d, 0x1a, 0x9b, 0xa5, 0xd6, 0x86, 0xc1, + 0x1b, 0x96, 0xb0, 0x1b, 0xa6, 0x28, 0x90, 0xda, 0xc2, 0x9a, 0xdd, 0x54, 0xfa, 0x5f, 0x39, 0x05, + 0x53, 0xe4, 0xd7, 0x7e, 0x4e, 0xd6, 0xb9, 0x7d, 0xb2, 0x2b, 0x96, 0x4c, 0x50, 0x2d, 0xc3, 0xd2, + 0x9a, 0x2a, 0xae, 0x1b, 0x66, 0x83, 0x9d, 0x16, 0x49, 0xab, 0x42, 0x1c, 0xc1, 0x9b, 0x86, 0xa9, + 0xff, 0x42, 0x9a, 0x26, 0x70, 0x23, 0x94, 0x6b, 0x61, 0x72, 0x43, 0x37, 0x3b, 0x16, 0x4b, 0x5d, + 0x63, 0x0e, 0x2e, 0x69, 0x55, 0x8c, 0xa4, 0xef, 0xd9, 0xbb, 0x11, 0xe7, 0xb0, 0x49, 0x1f, 0x17, + 0x4a, 0xab, 0x5d, 0xb1, 0x84, 0x9e, 0xa6, 0xe6, 0x29, 0x6c, 0x8c, 0xd1, 0xe3, 0x8d, 0x23, 0x35, + 0xba, 0x61, 0x52, 0xd4, 0x38, 0xab, 0x51, 0x88, 0x24, 0x35, 0x92, 0x88, 0x95, 0x9d, 0x66, 0xb3, + 0x8a, 0xeb, 0xb9, 0x4d, 0x63, 0x1a, 0x58, 0x8d, 0x62, 0xac, 0x82, 0x60, 0x6c, 0xa7, 0x5d, 0xb5, + 0x34, 0x6b, 0xa7, 0x33, 0x3d, 0xc1, 0xf6, 0x93, 0xec, 0xb0, 0x72, 0x12, 0xa0, 0x61, 0x5c, 0x6c, + 0xf1, 0xaf, 0x47, 0x99, 0xbf, 0x91, 0x1b, 0x43, 0x96, 0xcd, 0x4c, 0x64, 0x27, 0xd9, 0x1d, 0x76, + 0xcc, 0x9f, 0xeb, 0x73, 0x12, 0x80, 0xb5, 0x65, 0x62, 0xad, 0xd1, 0x13, 0xae, 0x17, 0xc1, 0x89, + 0xa6, 0xb1, 0xd9, 0x39, 0xaf, 0x5b, 0x5b, 0x2e, 0x10, 0x8b, 0x36, 0x80, 0x69, 0xd5, 0xe7, 0xab, + 0x72, 0x1f, 0x5c, 0x61, 0x7f, 0x39, 0xbf, 0x65, 0x34, 0x71, 0xcd, 0xc4, 0xb8, 0x0b, 0xdf, 0xb4, + 0x1a, 0x94, 0x44, 0x99, 0x85, 0x14, 0xf9, 0xcc, 0x9f, 0xfa, 0x46, 0x82, 0xdc, 0x53, 0x31, 0x9b, + 0xe5, 0x22, 0xa6, 0xd2, 0x74, 0xca, 0xed, 0x70, 0xb9, 0x71, 0xb1, 0xb5, 0x64, 0x6c, 0x2e, 0x6a, + 0x9d, 0xbc, 0xb6, 0x81, 0x55, 0xcc, 0x8e, 0x4d, 0x19, 0x26, 0x7f, 0xf6, 0xdf, 0xef, 0xb3, 0x32, + 0x0b, 0x4a, 0x5d, 0xdb, 0xc0, 0x4b, 0x22, 0x00, 0x4c, 0x32, 0x7a, 0x7c, 0x21, 0xb0, 0x93, 0xd8, + 0x55, 0x1b, 0x88, 0x2c, 0x3b, 0x88, 0xea, 0x8d, 0x23, 0x80, 0x92, 0x70, 0xc1, 0x05, 0x64, 0x8c, + 0xa6, 0xea, 0x8a, 0xdd, 0x27, 0xd2, 0xe3, 0xfd, 0x44, 0x1a, 0xba, 0x45, 0xda, 0x81, 0x75, 0xc2, + 0x0b, 0xeb, 0x17, 0xd3, 0x90, 0xaa, 0xee, 0xb5, 0xea, 0xe8, 0xf5, 0x9e, 0xe1, 0xef, 0x0c, 0x1c, + 0x37, 0x59, 0x99, 0x35, 0x53, 0xdb, 0xc5, 0x66, 0x07, 0x2f, 0x51, 0x3b, 0x4a, 0x82, 0x96, 0xd9, + 0xf3, 0x1b, 0x91, 0xdf, 0xce, 0x05, 0xbd, 0x5d, 0xdc, 0x6e, 0x5b, 0x7b, 0x4b, 0x04, 0x8f, 0x24, + 0xbb, 0x05, 0x4a, 0x88, 0x54, 0xee, 0x01, 0x64, 0x99, 0x7b, 0x35, 0xc3, 0xc6, 0x4f, 0xc5, 0xdb, + 0x86, 0x85, 0xed, 0x46, 0xb1, 0xde, 0x1c, 0x90, 0x02, 0xbd, 0x25, 0xe5, 0xd1, 0xad, 0x77, 0x89, + 0xba, 0xf5, 0x54, 0x0f, 0xe8, 0x49, 0xd3, 0x7c, 0x34, 0xe9, 0x8b, 0x21, 0xcb, 0xe4, 0xd9, 0x5e, + 0xa5, 0x5c, 0xd5, 0x23, 0xbf, 0x2b, 0xf1, 0xaa, 0x9d, 0x9a, 0xf4, 0xad, 0x06, 0xde, 0xd5, 0xeb, + 0xd8, 0xf5, 0x27, 0xb3, 0xc3, 0x0e, 0x4c, 0x35, 0x5e, 0xb2, 0x57, 0xf3, 0xf0, 0x38, 0xca, 0x03, + 0xf6, 0x97, 0x88, 0xb4, 0xb1, 0x63, 0x11, 0x11, 0x2b, 0xb5, 0x2a, 0x54, 0xea, 0xb8, 0x2a, 0x0a, + 0x48, 0xa1, 0xcc, 0xc1, 0x95, 0xe2, 0xd7, 0x45, 0x51, 0x27, 0x32, 0x81, 0x0c, 0x4c, 0xb3, 0x4f, + 0x9c, 0xb2, 0xfd, 0xc4, 0x69, 0xac, 0x4b, 0x9c, 0xd0, 0x6b, 0x9c, 0x81, 0xe7, 0x5e, 0x61, 0xe0, + 0xb9, 0x21, 0x1c, 0x0a, 0x23, 0xb9, 0x2e, 0x2b, 0xc3, 0x58, 0x8e, 0x7e, 0xdd, 0x23, 0xdb, 0x08, + 0xc6, 0x38, 0xa8, 0xb6, 0xfa, 0x72, 0xc2, 0x23, 0x92, 0xe1, 0xd7, 0x86, 0x7e, 0x35, 0x83, 0x71, + 0x8f, 0x35, 0xc2, 0x47, 0x8a, 0x6f, 0x85, 0x94, 0xde, 0xda, 0x30, 0xf8, 0xc4, 0xad, 0x8f, 0x08, + 0xd3, 0xa4, 0x21, 0x9f, 0xc9, 0x08, 0xa8, 0x3b, 0x7e, 0xec, 0x5e, 0x26, 0x41, 0x8a, 0xa8, 0x79, + 0xef, 0xbd, 0x9f, 0x08, 0xc6, 0xd8, 0xa4, 0xd8, 0x05, 0xce, 0x0e, 0xf7, 0x7c, 0x3b, 0x64, 0x06, + 0x8e, 0xee, 0xb4, 0xb4, 0x96, 0xd1, 0xda, 0xdb, 0xd6, 0x5f, 0xe2, 0x4c, 0x15, 0x84, 0x38, 0x42, + 0xfd, 0x26, 0x6e, 0x61, 0x53, 0xb3, 0x70, 0x75, 0x77, 0x93, 0xf6, 0xd6, 0x31, 0xd5, 0x1b, 0x85, + 0x1e, 0x49, 0x46, 0x53, 0x38, 0x84, 0x6a, 0xff, 0x27, 0x2a, 0x37, 0xf4, 0x26, 0xa6, 0xfe, 0xed, + 0xdc, 0xc7, 0xc3, 0x0e, 0x47, 0xea, 0x4d, 0x3d, 0xaa, 0x18, 0x09, 0x22, 0x32, 0x7b, 0x33, 0x65, + 0xc9, 0xa8, 0x6b, 0xcd, 0x8e, 0x65, 0x98, 0x18, 0xbd, 0xd0, 0x45, 0xc7, 0x46, 0x20, 0xe1, 0x41, + 0xe0, 0x04, 0x64, 0x1a, 0x46, 0xdd, 0xf5, 0x64, 0xe0, 0x21, 0x71, 0x39, 0x13, 0x78, 0x8c, 0x88, + 0x35, 0xb8, 0xbb, 0xde, 0xd8, 0x1e, 0x90, 0x09, 0x77, 0xb4, 0x28, 0x14, 0x51, 0x23, 0xb8, 0x57, + 0x21, 0x09, 0xa9, 0x15, 0xbd, 0xb5, 0xe9, 0x5d, 0xc4, 0x1c, 0x87, 0xb4, 0xde, 0x6a, 0xe0, 0x4b, + 0x7c, 0xa4, 0x66, 0x01, 0x32, 0x9c, 0xb7, 0x76, 0xb6, 0xd7, 0xb1, 0x59, 0xd9, 0xa0, 0xcd, 0xed, + 0xd4, 0x8c, 0x2a, 0x6e, 0xd9, 0x33, 0xb3, 0x9e, 0xdf, 0xd0, 0x8f, 0x12, 0xd1, 0xe4, 0x9e, 0x50, + 0xe2, 0x83, 0x8b, 0x43, 0x54, 0xd2, 0x43, 0x54, 0x24, 0x89, 0xef, 0x51, 0x78, 0xfc, 0xfc, 0xfd, + 0x64, 0x12, 0xb2, 0xcb, 0xd8, 0x32, 0xf5, 0x7a, 0x07, 0x7d, 0x38, 0x09, 0x93, 0x55, 0x6c, 0xad, + 0x68, 0xa6, 0xb6, 0x8d, 0x2d, 0xb2, 0x24, 0xbf, 0x41, 0x50, 0x4c, 0xed, 0xa6, 0x66, 0x6d, 0x18, + 0xe6, 0xb6, 0xad, 0x98, 0xec, 0xf0, 0x1d, 0xa9, 0xc7, 0xbe, 0x25, 0x25, 0x44, 0x66, 0x06, 0xba, + 0xde, 0xf0, 0x0a, 0x67, 0x85, 0xca, 0x7c, 0x4e, 0x58, 0x84, 0x73, 0xa6, 0x09, 0x53, 0x62, 0xfc, + 0xcc, 0xfc, 0x63, 0x09, 0xa4, 0x25, 0x63, 0x13, 0xbd, 0x5f, 0x82, 0x14, 0x95, 0xaf, 0xb7, 0x79, + 0x86, 0xe4, 0x69, 0xc8, 0x6e, 0xe3, 0x4e, 0x47, 0xdb, 0xc4, 0xf6, 0xfb, 0xd2, 0x3c, 0xa8, 0x9c, + 0x85, 0x74, 0x13, 0xef, 0xe2, 0x26, 0x25, 0x63, 0xea, 0xcc, 0x35, 0x42, 0xcb, 0x96, 0x8c, 0xcd, + 0x59, 0x52, 0x96, 0xf3, 0x0a, 0xed, 0x12, 0x49, 0xaa, 0xb2, 0x1c, 0x33, 0xf7, 0x43, 0x9a, 0x86, + 0x95, 0x71, 0x48, 0x17, 0x8a, 0x73, 0xab, 0x0b, 0xf2, 0x11, 0xf2, 0xd7, 0xa6, 0x6f, 0x1c, 0xd2, + 0xf3, 0xb9, 0x5a, 0x6e, 0x49, 0x4e, 0x92, 0x76, 0x94, 0xca, 0xf3, 0x15, 0x59, 0x22, 0x91, 0x2b, + 0xb9, 0x72, 0x29, 0x2f, 0xa7, 0x94, 0x09, 0xc8, 0x9e, 0xcf, 0xa9, 0xe5, 0x52, 0x79, 0x41, 0x4e, + 0xa3, 0x87, 0xbd, 0x0a, 0xeb, 0x0e, 0x11, 0xbf, 0x6b, 0xfd, 0x68, 0xea, 0x05, 0xd9, 0xbf, 0x77, + 0x20, 0xbb, 0x5b, 0x80, 0xec, 0x27, 0xc2, 0x14, 0x12, 0x0d, 0xa5, 0xf2, 0x00, 0x86, 0xec, 0x49, + 0x18, 0x2f, 0x57, 0x6a, 0x6b, 0xf3, 0x95, 0xd5, 0x72, 0x41, 0xc6, 0x84, 0x07, 0xb5, 0xd2, 0x72, + 0xb1, 0xb2, 0x5a, 0x93, 0x37, 0xd0, 0xeb, 0x93, 0x90, 0x5d, 0x31, 0x8d, 0x3a, 0xee, 0x74, 0xd0, + 0x2b, 0x92, 0x90, 0xc9, 0x6b, 0xad, 0x3a, 0x6e, 0xa2, 0xe7, 0xba, 0x30, 0x76, 0x2d, 0x09, 0xd1, + 0xf7, 0xbd, 0x52, 0x7f, 0x9f, 0xc8, 0x35, 0xf1, 0x5d, 0x61, 0x5e, 0xee, 0x2c, 0x2b, 0xd3, 0x87, + 0x77, 0x4f, 0x3a, 0xbc, 0xcb, 0x0b, 0xbc, 0xbb, 0x39, 0x7c, 0x51, 0xf1, 0xcb, 0xf9, 0xdf, 0x27, + 0xe0, 0xf8, 0x02, 0x99, 0x3e, 0xe8, 0x75, 0x46, 0xbc, 0xdd, 0xfe, 0xbb, 0xc5, 0xf6, 0x3f, 0x5f, + 0x20, 0xba, 0x57, 0x0e, 0xb1, 0xf1, 0x4f, 0x38, 0x8d, 0xbf, 0x4f, 0x68, 0xfc, 0x8d, 0x21, 0xcb, + 0x89, 0xbd, 0xe5, 0x33, 0x59, 0x48, 0xd3, 0x29, 0xf2, 0xcc, 0x75, 0x30, 0x59, 0xb5, 0x4c, 0xac, + 0x6d, 0x7b, 0x06, 0x25, 0xcb, 0xb8, 0x80, 0x5b, 0x5c, 0x34, 0x58, 0xe0, 0x8e, 0xb3, 0x90, 0x6d, + 0x19, 0x6b, 0xda, 0x8e, 0xb5, 0xa5, 0x3c, 0x6f, 0xdf, 0xb1, 0xa1, 0x65, 0xd6, 0xff, 0x2b, 0x6d, + 0xb6, 0x8b, 0xf4, 0xf5, 0xbb, 0xe8, 0xc4, 0x2c, 0xd3, 0x32, 0x72, 0x3b, 0xd6, 0xd6, 0xdc, 0x95, + 0x9f, 0x78, 0xe6, 0x64, 0xe2, 0xd3, 0xcf, 0x9c, 0x4c, 0x7c, 0xed, 0x99, 0x93, 0x89, 0xdf, 0xfc, + 0xc6, 0xc9, 0x23, 0x9f, 0xfe, 0xc6, 0xc9, 0x23, 0x5f, 0xfa, 0xc6, 0xc9, 0x23, 0x3f, 0x9d, 0x6c, + 0xaf, 0xaf, 0x67, 0x68, 0x29, 0xb7, 0xfd, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x2a, 0xd4, 0x23, + 0xda, 0xb5, 0x32, 0x01, 0x00, } func (m *Rpc) Marshal() (dAtA []byte, err error) { From c96d82babb866db8293f6e2991a9153c45a8b7e7 Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Wed, 9 Nov 2022 07:44:02 +0300 Subject: [PATCH 06/68] GO-470: add relation creation Signed-off-by: AnastasiaShemyakinskaya --- core/block/editor.go | 7 +- core/block/import/importer.go | 3 +- core/block/import/notion/api/page/page.go | 26 +- .../block/import/notion/api/page/page_test.go | 26 +- .../notion/api/property/detailsetter.go | 36 +- .../import/notion/api/property/models.go | 501 ------------------ .../notion/api/property/propertyitem.go | 315 +++++++++++ .../notion/api/property/propertyobject.go | 72 ++- .../notion/api/property/propertyvalue.go | 414 +++++++++++++++ core/block/import/notion/converter.go | 21 +- core/block/import/objectcreator.go | 42 +- core/block/import/relationcreator.go | 131 +++++ core/block/import/types.go | 4 + 13 files changed, 1011 insertions(+), 587 deletions(-) delete mode 100644 core/block/import/notion/api/property/models.go create mode 100644 core/block/import/notion/api/property/propertyitem.go create mode 100644 core/block/import/notion/api/property/propertyvalue.go create mode 100644 core/block/import/relationcreator.go diff --git a/core/block/editor.go b/core/block/editor.go index 59a7d7755..f675cf9dd 100644 --- a/core/block/editor.go +++ b/core/block/editor.go @@ -524,7 +524,12 @@ func (s *service) UploadFile(req pb.RpcFileUploadRequest) (hash string, err erro } else { upl.AutoType(true) } - res := upl.SetFile(req.LocalPath).Upload(context.TODO()) + if req.LocalPath != "" { + upl.SetFile(req.LocalPath) + } else if req.Url != "" { + upl.SetUrl(req.Url) + } + res := upl.Upload(context.TODO()) if res.Err != nil { return "", res.Err } diff --git a/core/block/import/importer.go b/core/block/import/importer.go index ee52cba8d..323b0a2e4 100644 --- a/core/block/import/importer.go +++ b/core/block/import/importer.go @@ -45,7 +45,8 @@ func (i *Import) Init(a *app.App) (err error) { } factory := syncer.New(syncer.NewFileSyncer(i.s), syncer.NewBookmarkSyncer(i.s)) ou := NewObjectUpdater(i.s, core, factory) - i.oc = NewCreator(i.s, core, ou, factory) + relationCreator := NewRelationCreator(i.s) + i.oc = NewCreator(i.s, core, ou, factory, relationCreator) return nil } diff --git a/core/block/import/notion/api/page/page.go b/core/block/import/notion/api/page/page.go index 798841575..5f9354a0a 100644 --- a/core/block/import/notion/api/page/page.go +++ b/core/block/import/notion/api/page/page.go @@ -39,7 +39,6 @@ type Page struct { LastEditedTime string `json:"last_edited_time"` CreatedBy api.User `json:"created_by,omitempty"` LastEditedBy api.User `json:"last_edited_by,omitempty"` - Title []api.RichText `json:"title"` Parent api.Parent `json:"parent"` Properties property.Properties `json:"properties"` Archived bool `json:"archived"` @@ -86,7 +85,7 @@ func (ds *Service) mapPagesToSnaphots(ctx context.Context, apiKey string, mode p }) } if convereterError.IsEmpty() { - return &converter.Response{Snapshots: allSnapshots, Error: nil} + return &converter.Response{Snapshots: allSnapshots, Error: nil} } return &converter.Response{Snapshots: allSnapshots, Error: convereterError} } @@ -94,45 +93,50 @@ func (ds *Service) mapPagesToSnaphots(ctx context.Context, apiKey string, mode p func (ds *Service) transformPages(apiKey string, d Page, mode pb.RpcObjectImportRequestMode) (*model.SmartBlockSnapshotBase, *converter.ConvertError) { details := make(map[string]*types.Value, 0) details[bundle.RelationKeySource.String()] = pbtypes.String(d.URL) - if len(d.Title) > 0 { - details[bundle.RelationKeyName.String()] = pbtypes.String(d.Title[0].PlainText) - } if d.Icon != nil && d.Icon.Emoji != nil { details[bundle.RelationKeyIconEmoji.String()] = pbtypes.String(*d.Icon.Emoji) } details[bundle.RelationKeyIsArchived.String()] = pbtypes.Bool(d.Archived) - ce := ds.handlePageProperties(apiKey, d.ID, d.Properties, details, mode) + relations, ce := ds.handlePageProperties(apiKey, d.ID, d.Properties, details, mode) if ce != nil { - return nil, ce + if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + return nil, ce + } } snapshot := &model.SmartBlockSnapshotBase{ Blocks: []*model.Block{}, Details: &types.Struct{Fields: details}, ObjectTypes: []string{bundle.TypeKeyPage.URL()}, Collections: nil, + RelationLinks: relations, } return snapshot, nil } -func (ds *Service) handlePageProperties(apiKey, pageID string, p property.Properties, d map[string]*types.Value, mode pb.RpcObjectImportRequestMode) *converter.ConvertError { +func (ds *Service) handlePageProperties(apiKey, pageID string, p property.Properties, d map[string]*types.Value, mode pb.RpcObjectImportRequestMode) ([]*model.RelationLink, *converter.ConvertError) { ce := converter.ConvertError{} + relations := make([]*model.RelationLink, 0) for k, v := range p { object, err := ds.propertyService.GetPropertyObject(context.TODO(), pageID, v.GetID(), apiKey, v.GetPropertyType()) if err != nil { ce.Add("property: " + v.GetID(), err) if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return &ce + return relations, &ce } } err = ds.detailSetter.SetDetailValue(k, v.GetPropertyType(), object, d) if err != nil && mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { ce.Add("property: " + v.GetID(), err) if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return &ce + return relations, &ce } } + relations = append(relations, &model.RelationLink{ + Key: k, + Format: v.GetFormat(), + }) } - return nil + return relations, nil } diff --git a/core/block/import/notion/api/page/page_test.go b/core/block/import/notion/api/page/page_test.go index e4fff866e..58f455dff 100644 --- a/core/block/import/notion/api/page/page_test.go +++ b/core/block/import/notion/api/page/page_test.go @@ -25,7 +25,7 @@ func Test_handlePagePropertiesSelect(t *testing.T) { p := property.SelectProperty{ID:"id", Type: string(property.PropertyConfigTypeSelect)} pr := property.Properties{"Select": &p} - ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["Select"]) @@ -44,7 +44,7 @@ func Test_handlePagePropertiesLastEditedTime(t *testing.T) { p := property.LastEditedTime{ID: "id", Type: string(property.PropertyConfigLastEditedTime)} pr := property.Properties{"LastEditedTime": &p} - ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["LastEditedTime"]) @@ -63,7 +63,7 @@ func Test_handlePagePropertiesRichText(t *testing.T) { p := property.RichText{ID: "id", Type: string(property.PropertyConfigLastEditedTime)} pr := property.Properties{"RichText": &p} - ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["RichText"]) @@ -82,7 +82,7 @@ func Test_handlePagePropertiesStatus(t *testing.T) { p := property.StatusProperty{ID: "id", Type: property.PropertyConfigStatus} pr := property.Properties{"Status": &p} - ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["Status"]) @@ -101,7 +101,7 @@ func Test_handlePagePropertiesNumber(t *testing.T) { p := property.NumberProperty{ID: "id", Type: string(property.PropertyConfigTypeNumber)} pr := property.Properties{"Number": &p} - ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["Number"]) @@ -120,7 +120,7 @@ func Test_handlePagePropertiesMultiSelect(t *testing.T) { p := property.NumberProperty{ID: "id", Type: string(property.PropertyConfigTypeMultiSelect)} pr := property.Properties{"MultiSelect": &p} - ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["MultiSelect"]) @@ -139,7 +139,7 @@ func Test_handlePagePropertiesCheckbox(t *testing.T) { p := property.Checkbox{ID: "id", Type: string(property.PropertyConfigTypeCheckbox)} pr := property.Properties{"Checkbox": &p} - ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["Checkbox"]) @@ -158,7 +158,7 @@ func Test_handlePagePropertiesEmail(t *testing.T) { p := property.Email{ID: "id", Type: string(property.PropertyConfigTypeEmail)} pr := property.Properties{"Email": &p} - ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["Email"]) @@ -177,7 +177,7 @@ func Test_handlePagePropertiesRelation(t *testing.T) { p := property.RelationProperty{ID: "id", Type: string(property.PropertyConfigTypeRelation)} pr := property.Properties{"Relation": &p} - ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["Relation"]) @@ -196,7 +196,7 @@ func Test_handlePagePropertiesPeople(t *testing.T) { p := property.People{ID: "id", Type: string(property.PropertyConfigTypePeople)} pr := property.Properties{"People": &p} - ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["People"]) @@ -215,7 +215,7 @@ func Test_handlePagePropertiesFormula(t *testing.T) { p := property.Formula{ID: "id", Type: string(property.PropertyConfigTypeFormula)} pr := property.Properties{"Formula": &p} - ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["Formula"]) @@ -234,8 +234,8 @@ func Test_handlePagePropertiesTitle(t *testing.T) { p := property.Title{ID: "id", Type: string(property.PropertyConfigTypeTitle)} pr := property.Properties{"Title": &p} - ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) - assert.NotEmpty(t, details["Title"]) + assert.NotEmpty(t, details["name"]) } \ No newline at end of file diff --git a/core/block/import/notion/api/property/detailsetter.go b/core/block/import/notion/api/property/detailsetter.go index 7daec22f4..34c3a198b 100644 --- a/core/block/import/notion/api/property/detailsetter.go +++ b/core/block/import/notion/api/property/detailsetter.go @@ -19,67 +19,67 @@ func (*DetailSetter) SetDetailValue(key string, propertyType PropertyConfigType, switch propertyType { case PropertyConfigTypeTitle: for _, v := range property { - title := v.(Title) + title := v.(TitleItem) title.SetDetail(key, details) } case PropertyConfigTypeRichText: for _, v := range property { - rt := v.(RichText) + rt := v.(RichTextItem) rt.SetDetail(key, details) } case PropertyConfigTypePeople: for _, v := range property { - p := v.(People) + p := v.(PeopleItem) p.SetDetail(key, details) } case PropertyConfigTypeRelation: for _, v := range property { - r := v.(Relation) + r := v.(RelationItem) r.SetDetail(key, details) } case PropertyConfigTypeNumber: - number := property[0].(NumberProperty) + number := property[0].(NumberItem) number.SetDetail(key, details) case PropertyConfigTypeSelect: - selectProperty := property[0].(SelectProperty) + selectProperty := property[0].(SelectItem) selectProperty.SetDetail(key, details) case PropertyConfigTypeMultiSelect: - multiSelect := property[0].(MultiSelect) + multiSelect := property[0].(MultiSelectItem) multiSelect.SetDetail(key, details) case PropertyConfigTypeDate: case PropertyConfigTypeFiles: - f := property[0].(File) + f := property[0].(FileItem) f.SetDetail(key, details) case PropertyConfigTypeCheckbox: - c := property[0].(Checkbox) + c := property[0].(CheckboxItem) c.SetDetail(key, details) case PropertyConfigTypeURL: - url := property[0].(Url) + url := property[0].(UrlItem) url.SetDetail(key, details) case PropertyConfigTypeEmail: - email := property[0].(Email) + email := property[0].(EmailItem) email.SetDetail(key, details) case PropertyConfigTypePhoneNumber: - phone := property[0].(Phone) + phone := property[0].(PhoneItem) phone.SetDetail(key, details) case PropertyConfigTypeFormula: - formula := property[0].(Formula) + formula := property[0].(FormulaItem) formula.SetDetail(key, details) case PropertyConfigTypeRollup: case PropertyConfigCreatedTime: - ct := property[0].(CreatedTime) + ct := property[0].(CreatedTimeItem) ct.SetDetail(key, details) case PropertyConfigCreatedBy: - cb := property[0].(CreatedBy) + cb := property[0].(CreatedByItem) cb.SetDetail(key, details) case PropertyConfigLastEditedTime: - lt := property[0].(LastEditedTime) + lt := property[0].(LastEditedTimeItem) lt.SetDetail(key, details) case PropertyConfigLastEditedBy: - lb := property[0].(LastEditedBy) + lb := property[0].(LastEditedByItem) lb.SetDetail(key, details) case PropertyConfigStatus: - lb := property[0].(StatusProperty) + lb := property[0].(StatusItem) lb.SetDetail(key, details) default: return fmt.Errorf("unsupported property type: %s", propertyType) diff --git a/core/block/import/notion/api/property/models.go b/core/block/import/notion/api/property/models.go deleted file mode 100644 index ebe46e0ce..000000000 --- a/core/block/import/notion/api/property/models.go +++ /dev/null @@ -1,501 +0,0 @@ -package property - -import ( - "time" - - "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" - "github.com/anytypeio/go-anytype-middleware/util/pbtypes" - "github.com/gogo/protobuf/types" -) - -type PropertyConfigType string - -const ( - PropertyConfigTypeTitle PropertyConfigType = "title" - PropertyConfigTypeRichText PropertyConfigType = "rich_text" - PropertyConfigTypeNumber PropertyConfigType = "number" - PropertyConfigTypeSelect PropertyConfigType = "select" - PropertyConfigTypeMultiSelect PropertyConfigType = "multi_select" - PropertyConfigTypeDate PropertyConfigType = "date" - PropertyConfigTypePeople PropertyConfigType = "people" - PropertyConfigTypeFiles PropertyConfigType = "files" - PropertyConfigTypeCheckbox PropertyConfigType = "checkbox" - PropertyConfigTypeURL PropertyConfigType = "url" - PropertyConfigTypeEmail PropertyConfigType = "email" - PropertyConfigTypePhoneNumber PropertyConfigType = "phone_number" - PropertyConfigTypeFormula PropertyConfigType = "formula" - PropertyConfigTypeRelation PropertyConfigType = "relation" - PropertyConfigTypeRollup PropertyConfigType = "rollup" - PropertyConfigCreatedTime PropertyConfigType = "created_time" - PropertyConfigCreatedBy PropertyConfigType = "created_by" - PropertyConfigLastEditedTime PropertyConfigType = "last_edited_time" - PropertyConfigLastEditedBy PropertyConfigType = "last_edited_by" - PropertyConfigStatus PropertyConfigType = "status" -) - -type Setter interface { - SetDetail(key string, details map[string]*types.Value) -} - -type PropertyObject interface { - GetPropertyType() PropertyConfigType - GetID() string -} - -type Title struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Title api.RichText `json:"title"` -} - -func (t *Title) SetDetail(key string, details map[string]*types.Value) { - var title string - if existingTitle, ok := details[key]; ok { - title = existingTitle.GetStringValue() - } - title += t.Title.PlainText - title += "\n" - details[key] = pbtypes.String(title) -} - -func (t *Title) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeTitle -} - -func (t *Title) GetID() string { - return t.ID -} - -type RichText struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - RichText api.RichText `json:"rich_text"` -} - -func (rt *RichText) SetDetail(key string, details map[string]*types.Value) { - var richText string - if existingText, ok := details[key]; ok { - richText = existingText.GetStringValue() - } - richText += rt.RichText.PlainText - richText += "\n" - details[key] = pbtypes.String(richText) -} - -func (rt *RichText) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeRichText -} - -func (rt *RichText) GetID() string { - return rt.ID -} -type NumberProperty struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Number int64 `json:"number"` -} - -func (np *NumberProperty) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.Int64(np.Number) -} - -func (np *NumberProperty) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeNumber -} - -func (np *NumberProperty) GetID() string { - return np.ID -} - -type SelectProperty struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Select SelectOption `json:"select"` -} - -type SelectOption struct { - ID string `json:"id,omitempty"` - Name string `json:"name"` - Color api.Color `json:"color"` -} - -func (sp *SelectProperty) SetDetail(key string, details map[string]*types.Value) { - //TODO -} - -func (sp *SelectProperty) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeSelect -} - -func (sp *SelectProperty) GetID() string { - return sp.ID -} - -type Select struct { - Options []SelectOption `json:"options"` -} - -type MultiSelect struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - MultiSelect []SelectOption `json:"multi_select"` -} - -func (ms *MultiSelect) SetDetail(key string, details map[string]*types.Value) { - //TODO -} - -func (ms *MultiSelect) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeMultiSelect -} - -func (ms *MultiSelect) GetID() string { - return ms.ID -} - -type DateProperty struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Date Date `json:"date"` -} - -func (dp *DateProperty) SetDetail(key string, details map[string]*types.Value) { - return -} - -func (dp *DateProperty) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeDate -} - -func (dp *DateProperty) GetID() string { - return dp.ID -} - -type Date struct { - Start string `json:"start"` - End string `json:"end"` - TimeZone string `json:"time_zone"` -} - -const ( - NumberFormula string = "number" - StringFormula string = "string" - BooleanFormula string = "boolean" - DateFormula string = "date" -) - -type Formula struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Formula map[string]interface{} `json:"formula"` -} - -func (f *Formula) SetDetail(key string, details map[string]*types.Value) { - switch f.Formula["type"].(string) { - case StringFormula: - details[key] = pbtypes.String(f.Formula["string"].(string)) - case NumberFormula: - details[key] = pbtypes.Float64(f.Formula["number"].(float64)) - case BooleanFormula: - details[key] = pbtypes.Bool(f.Formula["boolean"].(bool)) - default: - return - } -} - -func (f *Formula) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeFormula -} - -func (f *Formula) GetID() string { - return f.ID -} - -type RelationProperty struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Relation []Relation `json:"relation"` - HasMore bool `json:"has_more"` -} - -type Relation struct { - ID string `json:"id"` -} - -func (r *Relation) SetDetail(key string, details map[string]*types.Value) { - var ( - relation string - space string - ) - if existingRelation, ok := details[key]; ok { - relation = existingRelation.GetStringValue() - } - if relation != "" { - space = " " - } - details[key] = pbtypes.String(relation + space + r.ID) -} - -func (rp *RelationProperty) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeRelation -} - -func (rp *RelationProperty) GetID() string { - return rp.ID -} - -//can't support it yet -type Rollup struct { - Object string `json:"object"` -} - -func (r *Rollup) SetDetail(key string, details map[string]*types.Value) {} - -func (r *Rollup) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeRollup -} - -func (r *Rollup) GetID() string { - return "" -} - -type People struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - People api.User `json:"people"` -} - -func (p *People) SetDetail(key string, details map[string]*types.Value) { - var peopleList = make([]string, 0) - if existingPeople, ok := details[key]; ok { - list := existingPeople.GetListValue() - for _, v := range list.Values { - peopleList = append(peopleList, v.GetStringValue()) - } - } - peopleList = append(peopleList, p.People.Name) - details[key] = pbtypes.StringList(peopleList) -} - -func (p *People) GetPropertyType() PropertyConfigType { - return PropertyConfigTypePeople -} - -func (p *People) GetID() string { - return p.ID -} - -type File struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - File []api.FileObject `json:"files"` -} - -func (f *File) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeFiles -} - -func (f *File) GetID() string { - return f.ID -} - -func (f *File) SetDetail(key string, details map[string]*types.Value) { - var fileList = make([]string, len(f.File)) - for i, fo := range f.File { - if fo.External.URL != "" { - fileList[i] = fo.External.URL - } else if fo.File.URL != "" { - fileList[i] = fo.File.URL - } - } - details[key] = pbtypes.StringList(fileList) -} - -type Checkbox struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Checkbox bool `json:"checkbox"` -} - -func (c *Checkbox) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.Bool(c.Checkbox) -} - -func (c *Checkbox) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeFiles -} - -func (c *Checkbox) GetID() string { - return c.ID -} - -type Url struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - URL string `json:"url"` -} - -func (u *Url) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.String(u.URL) -} - -func (u *Url) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeURL -} - -func (u *Url) GetID() string { - return u.ID -} - -type Email struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Email string `json:"email"` -} - -func (e *Email) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.String(e.Email) -} - -func (e *Email) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeURL -} - -func (e *Email) GetID() string { - return e.ID -} - -type Phone struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Phone string `json:"phone_number"` -} - -func (p *Phone) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.String(p.Phone) -} - -func (p *Phone) GetPropertyType() PropertyConfigType { - return PropertyConfigTypePhoneNumber -} - -func (p *Phone) GetID() string { - return p.ID -} - -type CreatedTime struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - CreatedTime string `json:"created_time"` -} - -func (ct *CreatedTime) SetDetail(key string, details map[string]*types.Value) { - t, _ := time.Parse(time.RFC3339, ct.CreatedTime) - details[key] = pbtypes.Int64(t.Unix()) -} - -func (ct *CreatedTime) GetPropertyType() PropertyConfigType { - return PropertyConfigCreatedTime -} - -func (ct *CreatedTime) GetID() string { - return ct.ID -} - -type CreatedBy struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - CreatedBy api.User `json:"created_by"` -} - -func (cb *CreatedBy) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.String(cb.CreatedBy.Name) -} - -func (cb *CreatedBy) GetPropertyType() PropertyConfigType { - return PropertyConfigCreatedBy -} - -func (cb *CreatedBy) GetID() string { - return cb.ID -} - -type LastEditedTime struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - LastEditedTime string `json:"last_edited_time"` -} - -func (le *LastEditedTime) SetDetail(key string, details map[string]*types.Value) { - t, _ := time.Parse(time.RFC3339, le.LastEditedTime) - details[key] = pbtypes.Int64(t.Unix()) -} - -func (le *LastEditedTime) GetPropertyType() PropertyConfigType { - return PropertyConfigLastEditedTime -} - -func (le *LastEditedTime) GetID() string { - return le.ID -} - -type LastEditedBy struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - LastEditedBy api.User `json:"last_edited_by"` -} - - -func (lb *LastEditedBy) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.String(lb.LastEditedBy.Name) -} - -func (lb *LastEditedBy) GetPropertyType() PropertyConfigType { - return PropertyConfigLastEditedBy -} - -func (lb *LastEditedBy) GetID() string { - return lb.ID -} - -type StatusProperty struct { - ID string `json:"id"` - Type PropertyConfigType `json:"type"` - Status Status `json:"status"` -} - -type Status struct { - Name string `json:"name,omitempty"` - ID string `json:"id,omitempty"` - Color string `json:"color,omitempty"` -} - -func (sp *StatusProperty) GetPropertyType() PropertyConfigType { - return PropertyConfigStatus -} - -func (sp *StatusProperty) GetID() string { - return sp.ID -} - -func (sp *StatusProperty) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.StringList([]string{sp.Status.Name}) -} \ No newline at end of file diff --git a/core/block/import/notion/api/property/propertyitem.go b/core/block/import/notion/api/property/propertyitem.go new file mode 100644 index 000000000..0093e01ce --- /dev/null +++ b/core/block/import/notion/api/property/propertyitem.go @@ -0,0 +1,315 @@ +package property + +import ( + "strconv" + "time" + + "github.com/gogo/protobuf/types" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" + "github.com/anytypeio/go-anytype-middleware/util/pbtypes" +) + +type TitleItem struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Title api.RichText `json:"title"` +} + +func (t *TitleItem) SetDetail(key string, details map[string]*types.Value) { + var title string + if existingTitle, ok := details[bundle.RelationKeyName.String()]; ok { + title = existingTitle.GetStringValue() + } + title += t.Title.PlainText + title += "\n" + details[bundle.RelationKeyName.String()] = pbtypes.String(title) +} + +type RichTextItem struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + RichText api.RichText `json:"rich_text"` +} + +func (rt *RichTextItem) SetDetail(key string, details map[string]*types.Value) { + var richText string + if existingText, ok := details[key]; ok { + richText = existingText.GetStringValue() + } + richText += rt.RichText.PlainText + richText += "\n" + details[key] = pbtypes.String(richText) +} + +type NumberItem struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Number int64 `json:"number"` +} + +func (np *NumberItem) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.Int64(np.Number) +} + +type SelectItem struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Select SelectOption `json:"select"` +} + +type SelectOption struct { + ID string `json:"id,omitempty"` + Name string `json:"name"` + Color api.Color `json:"color"` +} + +func (sp *SelectItem) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.StringList([]string{sp.Select.Name}) +} + +type MultiSelectItem struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + MultiSelect []SelectOption `json:"multi_select"` +} + +func (ms *MultiSelectItem) SetDetail(key string, details map[string]*types.Value) { + msList := make([]string, 0) + for _, so := range ms.MultiSelect { + msList = append(msList, so.Name) + } + details[key] = pbtypes.StringList(msList) +} + +//can't support it yet +type DateItem struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Date Date `json:"date"` +} + +func (dp *DateItem) SetDetail(key string, details map[string]*types.Value) {} + +type Date struct { + Start string `json:"start"` + End string `json:"end"` + TimeZone string `json:"time_zone"` +} + +const ( + NumberFormula string = "number" + StringFormula string = "string" + BooleanFormula string = "boolean" + DateFormula string = "date" +) + +type FormulaItem struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Formula map[string]interface{} `json:"formula"` +} + +func (f *FormulaItem) SetDetail(key string, details map[string]*types.Value) { + switch f.Formula["type"].(string) { + case StringFormula: + if f.Formula["string"] != nil { + details[key] = pbtypes.String(f.Formula["string"].(string)) + } + case NumberFormula: + if f.Formula["number"] != nil { + stringNumber := strconv.FormatFloat(f.Formula["number"].(float64),'f', 6, 64) + details[key] = pbtypes.String(stringNumber) + } + case BooleanFormula: + if f.Formula["boolean"] != nil { + stringBool := strconv.FormatBool(f.Formula["boolean"].(bool)) + details[key] = pbtypes.String(stringBool) + } + default: + return + } +} + +type RelationItem struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Relation Relation `json:"relation"` + HasMore bool `json:"has_more"` +} + +type Relation struct { + ID string `json:"id"` +} + +func (r *RelationItem) SetDetail(key string, details map[string]*types.Value) { + var ( + relation = make([]string, 0) + ) + if rel, ok := details[key]; ok { + existingRelation := rel.GetListValue() + for _, v := range existingRelation.Values { + relation = append(relation, v.GetStringValue()) + } + } + relation = append(relation, r.Relation.ID) + details[key] = pbtypes.StringList(relation) +} + +type PeopleItem struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + People api.User `json:"people"` +} + +func (p *PeopleItem) SetDetail(key string, details map[string]*types.Value) { + var peopleList = make([]string, 0) + if existingPeople, ok := details[key]; ok { + list := existingPeople.GetListValue() + for _, v := range list.Values { + peopleList = append(peopleList, v.GetStringValue()) + } + } + peopleList = append(peopleList, p.People.Name) + details[key] = pbtypes.StringList(peopleList) +} + +type FileItem struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + File []api.FileObject `json:"files"` +} + +func (f *FileItem) SetDetail(key string, details map[string]*types.Value) { + var fileList = make([]string, len(f.File)) + for i, fo := range f.File { + if fo.External.URL != "" { + fileList[i] = fo.External.URL + } else if fo.File.URL != "" { + fileList[i] = fo.File.URL + } + } + details[key] = pbtypes.StringList(fileList) +} + +func (f *FileItem) GetFormat() model.RelationFormat { + return model.RelationFormat_file +} + +type CheckboxItem struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Checkbox bool `json:"checkbox"` +} + +func (c *CheckboxItem) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.Bool(c.Checkbox) +} + +type UrlItem struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + URL string `json:"url"` +} + +func (u *UrlItem) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.String(u.URL) +} + +type EmailItem struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Email string `json:"email"` +} + +func (e *EmailItem) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.String(e.Email) +} + +type PhoneItem struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Phone string `json:"phone_number"` +} + +func (p *PhoneItem) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.String(p.Phone) +} + +type CreatedTimeItem struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + CreatedTime string `json:"created_time"` +} + +func (ct *CreatedTimeItem) SetDetail(key string, details map[string]*types.Value) { + t, _ := time.Parse(time.RFC3339, ct.CreatedTime) + details[key] = pbtypes.Int64(t.Unix()) +} + +type CreatedByItem struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + CreatedBy api.User `json:"created_by"` +} + +func (cb *CreatedByItem) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.String(cb.CreatedBy.Name) +} + +type LastEditedTimeItem struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + LastEditedTime string `json:"last_edited_time"` +} + +func (le *LastEditedTimeItem) SetDetail(key string, details map[string]*types.Value) { + t, _ := time.Parse(time.RFC3339, le.LastEditedTime) + details[key] = pbtypes.Int64(t.Unix()) +} + +type LastEditedByItem struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + LastEditedBy api.User `json:"last_edited_by"` +} + +func (lb *LastEditedByItem) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.String(lb.LastEditedBy.Name) +} + +type StatusItem struct { + ID string `json:"id"` + Type PropertyConfigType `json:"type"` + Status Status `json:"status"` +} + +type Status struct { + Name string `json:"name,omitempty"` + ID string `json:"id,omitempty"` + Color string `json:"color,omitempty"` +} + +func (sp *StatusItem) SetDetail(key string, details map[string]*types.Value) { + details[key] = pbtypes.StringList([]string{sp.Status.Name}) +} diff --git a/core/block/import/notion/api/property/propertyobject.go b/core/block/import/notion/api/property/propertyobject.go index d90126db9..ff2e80537 100644 --- a/core/block/import/notion/api/property/propertyobject.go +++ b/core/block/import/notion/api/property/propertyobject.go @@ -9,8 +9,11 @@ import ( "net/http" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/logging" ) +var logger = logging.Logger("notion-property-retriever") + const endpoint = "/pages/%s/properties/%s" type Service struct { client *client.Client @@ -133,19 +136,19 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api err := json.NewEncoder(body).Encode(&Request{StartCursor: startCursor}) if err != nil { - return nil, fmt.Errorf("ListDatabases: %s", err) + return nil, fmt.Errorf("GetPropertyObject: %s", err) } request := fmt.Sprintf(endpoint, pageID, propertyID) req, err := s.client.PrepareRequest(ctx, apiKey, http.MethodGet, request, body) if err != nil { - return nil, fmt.Errorf("ListDatabases: %s", err) + return nil, fmt.Errorf("GetPropertyObject: %s", err) } res, err := s.client.HttpClient.Do(req) if err != nil { - return nil, fmt.Errorf("ListDatabases: %s", err) + return nil, fmt.Errorf("GetPropertyObject: %s", err) } defer res.Body.Close() @@ -158,7 +161,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api if res.StatusCode != http.StatusOK { notionErr := client.TransformHttpCodeToError(b) if notionErr == nil { - return nil, fmt.Errorf("failed http request, %d code", res.StatusCode) + return nil, fmt.Errorf("GetPropertyObject: failed http request, %d code", res.StatusCode) } return nil, notionErr } @@ -173,36 +176,41 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api for _, v := range res { buffer, err := json.Marshal(v) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal: %s", err) continue } if propertyType == PropertyConfigTypeTitle { - p := Title{} + p := TitleItem{} err = json.Unmarshal(buffer, &p) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal TitleItem: %s", err) continue } paginatedResponse = append(paginatedResponse, p) } if propertyType == PropertyConfigTypeRichText { - p := RichText{} + p := RichTextItem{} err = json.Unmarshal(buffer, &p) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal RichTextItem: %s", err) continue } paginatedResponse = append(paginatedResponse, p) } if propertyType == PropertyConfigTypeRelation { - p := Relation{} + p := RelationItem{} err = json.Unmarshal(buffer, &p) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal RelationItem: %s", err) continue } paginatedResponse = append(paginatedResponse, p) } if propertyType == PropertyConfigTypePeople { - p := People{} + p := PeopleItem{} err = json.Unmarshal(buffer, &p) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal PeopleItem: %s", err) continue } paginatedResponse = append(paginatedResponse, p) @@ -213,72 +221,82 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api continue } case PropertyConfigTypeNumber: - p := NumberProperty{} + p := NumberItem{} err = json.Unmarshal(b, &p) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal NumberItem: %s", err) continue } paginatedResponse = append(paginatedResponse, p) case PropertyConfigTypeSelect: - p := SelectProperty{} + p := SelectItem{} err = json.Unmarshal(b, &p) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal SelectItem: %s", err) continue } paginatedResponse = append(paginatedResponse, p) case PropertyConfigTypeMultiSelect: - p := MultiSelect{} + p := MultiSelectItem{} err = json.Unmarshal(b, &p) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal MultiSelectItem: %s", err) continue } paginatedResponse = append(paginatedResponse, p) case PropertyConfigTypeDate: - date := DateProperty{} + date := DateItem{} err = json.Unmarshal(b, &date) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal DateItem: %s", err) continue } paginatedResponse = append(paginatedResponse, date) case PropertyConfigTypeFiles: - file := File{} + file := FileItem{} err = json.Unmarshal(b, &file) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal FileItem: %s", err) continue } paginatedResponse = append(paginatedResponse, file) case PropertyConfigTypeCheckbox: - checkbox := Checkbox{} + checkbox := CheckboxItem{} err = json.Unmarshal(b, &checkbox) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal CheckboxItem: %s", err) continue } paginatedResponse = append(paginatedResponse, checkbox) case PropertyConfigTypeURL: - url := Url{} + url := UrlItem{} err = json.Unmarshal(b, &url) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal UrlItem: %s", err) continue } paginatedResponse = append(paginatedResponse, url) case PropertyConfigTypeEmail: - email := Email{} + email := EmailItem{} err = json.Unmarshal(b, &email) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal EmailItem: %s", err) continue } paginatedResponse = append(paginatedResponse, email) case PropertyConfigTypePhoneNumber: - phone := Phone{} + phone := PhoneItem{} err = json.Unmarshal(b, &phone) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal PhoneItem: %s", err) continue } paginatedResponse = append(paginatedResponse, phone) case PropertyConfigTypeFormula: - formula := Formula{} + formula := FormulaItem{} err = json.Unmarshal(b, &formula) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal FormulaItem: %s", err) continue } paginatedResponse = append(paginatedResponse, formula) @@ -286,46 +304,52 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api rollup := Rollup{} err = json.Unmarshal(b, &rollup) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal Rollup: %s", err) continue } paginatedResponse = append(paginatedResponse, rollup) case PropertyConfigCreatedTime: - ct := CreatedTime{} + ct := CreatedTimeItem{} err = json.Unmarshal(b, &ct) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal CreatedTimeItem: %s", err) continue } paginatedResponse = append(paginatedResponse, ct) case PropertyConfigCreatedBy: - cb := CreatedBy{} + cb := CreatedByItem{} err = json.Unmarshal(b, &cb) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal CreatedByItem: %s", err) continue } paginatedResponse = append(paginatedResponse, cb) case PropertyConfigLastEditedTime: - lt := LastEditedTime{} + lt := LastEditedTimeItem{} err = json.Unmarshal(b, <) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal LastEditedTimeItem: %s", err) continue } paginatedResponse = append(paginatedResponse, lt) case PropertyConfigLastEditedBy: - le := LastEditedBy{} + le := LastEditedByItem{} err = json.Unmarshal(b, &le) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal LastEditedByItem: %s", err) continue } paginatedResponse = append(paginatedResponse, le) case PropertyConfigStatus: - sp := StatusProperty{} + sp := StatusItem{} err = json.Unmarshal(b, &sp) if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal StatusItem: %s", err) continue } paginatedResponse = append(paginatedResponse, sp) default: - return nil, fmt.Errorf("unsupported property type: %s", propertyType) + return nil, fmt.Errorf("GetPropertyObject: unsupported property type: %s", propertyType) } hasMore = false } diff --git a/core/block/import/notion/api/property/propertyvalue.go b/core/block/import/notion/api/property/propertyvalue.go new file mode 100644 index 000000000..634031c37 --- /dev/null +++ b/core/block/import/notion/api/property/propertyvalue.go @@ -0,0 +1,414 @@ +package property + +import ( + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" +) + +type PropertyConfigType string + +const ( + PropertyConfigTypeTitle PropertyConfigType = "title" + PropertyConfigTypeRichText PropertyConfigType = "rich_text" + PropertyConfigTypeNumber PropertyConfigType = "number" + PropertyConfigTypeSelect PropertyConfigType = "select" + PropertyConfigTypeMultiSelect PropertyConfigType = "multi_select" + PropertyConfigTypeDate PropertyConfigType = "date" + PropertyConfigTypePeople PropertyConfigType = "people" + PropertyConfigTypeFiles PropertyConfigType = "files" + PropertyConfigTypeCheckbox PropertyConfigType = "checkbox" + PropertyConfigTypeURL PropertyConfigType = "url" + PropertyConfigTypeEmail PropertyConfigType = "email" + PropertyConfigTypePhoneNumber PropertyConfigType = "phone_number" + PropertyConfigTypeFormula PropertyConfigType = "formula" + PropertyConfigTypeRelation PropertyConfigType = "relation" + PropertyConfigTypeRollup PropertyConfigType = "rollup" + PropertyConfigCreatedTime PropertyConfigType = "created_time" + PropertyConfigCreatedBy PropertyConfigType = "created_by" + PropertyConfigLastEditedTime PropertyConfigType = "last_edited_time" + PropertyConfigLastEditedBy PropertyConfigType = "last_edited_by" + PropertyConfigStatus PropertyConfigType = "status" +) + +type PropertyObject interface { + GetPropertyType() PropertyConfigType + GetID() string + GetFormat() model.RelationFormat +} + +type Title struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Title interface{} `json:"title"` +} + +func (t *Title) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeTitle +} + +func (t *Title) GetID() string { + return t.ID +} + +func (t *Title) GetFormat() model.RelationFormat { + return model.RelationFormat_shorttext +} + +type RichText struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + RichText interface{} `json:"rich_text"` +} + +func (rt *RichText) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeRichText +} + +func (rt *RichText) GetID() string { + return rt.ID +} + +func (rt *RichText) GetFormat() model.RelationFormat { + return model.RelationFormat_longtext +} + +type NumberProperty struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Number interface{} `json:"number"` +} + +func (np *NumberProperty) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeNumber +} + +func (np *NumberProperty) GetID() string { + return np.ID +} + +func (np *NumberProperty) GetFormat() model.RelationFormat { + return model.RelationFormat_number +} + +type SelectProperty struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Select interface{} `json:"select"` +} + +func (sp *SelectProperty) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeSelect +} + +func (sp *SelectProperty) GetID() string { + return sp.ID +} + +func (sp *SelectProperty) GetFormat() model.RelationFormat { + return model.RelationFormat_tag +} + +type MultiSelect struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + MultiSelect interface{} `json:"multi_select"` +} + +func (ms *MultiSelect) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeMultiSelect +} + +func (ms *MultiSelect) GetID() string { + return ms.ID +} + +func (ms *MultiSelect) GetFormat() model.RelationFormat { + return model.RelationFormat_tag +} + +type DateProperty struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Date interface{} `json:"date"` +} + +func (dp *DateProperty) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeDate +} + +func (dp *DateProperty) GetID() string { + return dp.ID +} + +func (dp *DateProperty) GetFormat() model.RelationFormat { + return model.RelationFormat_date +} + +type Formula struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Formula interface{} `json:"formula"` +} + +func (f *Formula) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeFormula +} + +func (f *Formula) GetID() string { + return f.ID +} + +func (f *Formula) GetFormat() model.RelationFormat { + return model.RelationFormat_shorttext +} + +type RelationProperty struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Relation interface{} `json:"relation"` +} + +func (rp *RelationProperty) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeRelation +} + +func (rp *RelationProperty) GetID() string { + return rp.ID +} + +func (r *RelationProperty) GetFormat() model.RelationFormat { + return model.RelationFormat_object +} + +//can't support it yet +type Rollup struct { + Object string `json:"object"` + ID string `json:"id"` +} + +func (r *Rollup) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeRollup +} + +func (p *Rollup) GetFormat() model.RelationFormat { + return model.RelationFormat_longtext +} + +func (r *Rollup) GetID() string { + return r.ID +} + +type People struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + People interface{} `json:"people"` +} + +func (p *People) GetPropertyType() PropertyConfigType { + return PropertyConfigTypePeople +} + +func (p *People) GetID() string { + return p.ID +} + +func (p *People) GetFormat() model.RelationFormat { + return model.RelationFormat_tag +} + +type File struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + File interface{} `json:"files"` +} + +func (f *File) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeFiles +} + +func (f *File) GetID() string { + return f.ID +} + +func (f *File) GetFormat() model.RelationFormat { + return model.RelationFormat_file +} + +type Checkbox struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Checkbox interface{} `json:"checkbox"` +} + +func (c *Checkbox) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeCheckbox +} + +func (c *Checkbox) GetID() string { + return c.ID +} + +func (c *Checkbox) GetFormat() model.RelationFormat { + return model.RelationFormat_checkbox +} + +type Url struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + URL interface{} `json:"url"` +} + +func (u *Url) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeURL +} + +func (u *Url) GetID() string { + return u.ID +} + +func (u *Url) GetFormat() model.RelationFormat { + return model.RelationFormat_url +} + +type Email struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Email interface{} `json:"email"` +} + +func (e *Email) GetPropertyType() PropertyConfigType { + return PropertyConfigTypeURL +} + +func (e *Email) GetID() string { + return e.ID +} + +func (e *Email) GetFormat() model.RelationFormat { + return model.RelationFormat_email +} + +type Phone struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Phone interface{} `json:"phone_number"` +} + +func (p *Phone) GetPropertyType() PropertyConfigType { + return PropertyConfigTypePhoneNumber +} + +func (p *Phone) GetID() string { + return p.ID +} + +func (p *Phone) GetFormat() model.RelationFormat { + return model.RelationFormat_phone +} + +type CreatedTime struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + CreatedTime interface{} `json:"created_time"` +} + +func (ct *CreatedTime) GetPropertyType() PropertyConfigType { + return PropertyConfigCreatedTime +} + +func (ct *CreatedTime) GetID() string { + return ct.ID +} + +func (ct *CreatedTime) GetFormat() model.RelationFormat { + return model.RelationFormat_date +} + +type CreatedBy struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + CreatedBy interface{} `json:"created_by"` +} + +func (cb *CreatedBy) GetPropertyType() PropertyConfigType { + return PropertyConfigCreatedBy +} + +func (cb *CreatedBy) GetID() string { + return cb.ID +} + +func (cb *CreatedBy) GetFormat() model.RelationFormat { + return model.RelationFormat_shorttext +} + +type LastEditedTime struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + LastEditedTime interface{} `json:"last_edited_time"` +} + +func (le *LastEditedTime) GetPropertyType() PropertyConfigType { + return PropertyConfigLastEditedTime +} + +func (le *LastEditedTime) GetID() string { + return le.ID +} + +func (le *LastEditedTime) GetFormat() model.RelationFormat { + return model.RelationFormat_date +} + +type LastEditedBy struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + LastEditedBy interface{} `json:"last_edited_by"` +} + +func (lb *LastEditedBy) GetPropertyType() PropertyConfigType { + return PropertyConfigLastEditedBy +} + +func (lb *LastEditedBy) GetID() string { + return lb.ID +} + +func (lb *LastEditedBy) GetFormat() model.RelationFormat { + return model.RelationFormat_shorttext +} + +type StatusProperty struct { + ID string `json:"id"` + Type PropertyConfigType `json:"type"` + Status interface{} `json:"status"` +} + +func (sp *StatusProperty) GetPropertyType() PropertyConfigType { + return PropertyConfigStatus +} + +func (sp *StatusProperty) GetID() string { + return sp.ID +} + +func (sp *StatusProperty) GetFormat() model.RelationFormat { + return model.RelationFormat_status +} diff --git a/core/block/import/notion/converter.go b/core/block/import/notion/converter.go index 46510ab76..16391dac4 100644 --- a/core/block/import/notion/converter.go +++ b/core/block/import/notion/converter.go @@ -68,7 +68,26 @@ func (n *Notion) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Respons Error: ce, } } - return nil + + allSnaphots := make([]*converter.Snapshot, 0, len(pagesSnapshots.Snapshots) + len(databasesSnapshots.Snapshots)) + allSnaphots = append(allSnaphots, pagesSnapshots.Snapshots...) + allSnaphots = append(allSnaphots, databasesSnapshots.Snapshots...) + if pagesSnapshots.Error != nil { + ce.Merge(pagesSnapshots.Error) + } + if databasesSnapshots.Error != nil { + ce.Merge(databasesSnapshots.Error) + } + if !ce.IsEmpty() { + return &converter.Response{ + Snapshots: allSnaphots, + Error: ce, + } + } + return &converter.Response{ + Snapshots: allSnaphots, + Error: nil, + } } func (n *Notion) getParams(param *pb.RpcObjectImportRequest) string { diff --git a/core/block/import/objectcreator.go b/core/block/import/objectcreator.go index c69d9a5cb..8c4fa32a9 100644 --- a/core/block/import/objectcreator.go +++ b/core/block/import/objectcreator.go @@ -27,11 +27,12 @@ type ObjectCreator struct { service block.Service core core.Service updater Updater + relationCreator RelationCreator syncFactory *syncer.Factory } -func NewCreator(service block.Service, core core.Service, updater Updater, syncFactory *syncer.Factory) Creator { - return &ObjectCreator{service: service, core: core, updater: updater, syncFactory: syncFactory} +func NewCreator(service block.Service, core core.Service, updater Updater, syncFactory *syncer.Factory, relationCreator RelationCreator) Creator { + return &ObjectCreator{service: service, core: core, updater: updater, syncFactory: syncFactory, relationCreator: relationCreator} } // Create creates smart blocks from given snapshots @@ -71,22 +72,29 @@ func (oc *ObjectCreator) Create(ctx *session.Context, snapshot *model.SmartBlock return nil, fmt.Errorf("new id not found for '%s'", st.RootId()) } + var filesToDelete []string defer func() { // delete file in ipfs if there is error after creation if err != nil { for _, bl := range st.Blocks() { if f := bl.GetFile(); f != nil { - oc.deleteFile(f) + oc.deleteFile(f.Hash) + } + for _, hash := range filesToDelete { + oc.deleteFile(hash) } } } }() newId, details, err := oc.createSmartBlock(sbType, st) - - st.SetDetails(snapshot.Details) if err != nil { - return nil, fmt.Errorf("crear object '%s'", st.RootId()) + return nil, fmt.Errorf("create object '%s'", st.RootId()) + } + + filesToDelete, err = oc.relationCreator.Create(ctx, snapshot, newId) + if err != nil { + return nil, fmt.Errorf("relation create '%s'", err) } if isFavorite { @@ -165,24 +173,24 @@ func (oc *ObjectCreator) addRootBlock(snapshot *model.SmartBlockSnapshotBase, pa } } -func (oc *ObjectCreator) deleteFile(f *model.BlockContentFile) { - inboundLinks, err := oc.core.ObjectStore().GetOutboundLinksById(f.Hash) +func (oc *ObjectCreator) deleteFile(hash string) { + inboundLinks, err := oc.core.ObjectStore().GetOutboundLinksById(hash) if err != nil { - log.With("file", f.Hash).Errorf("failed to get inbound links for file: %s", err.Error()) + log.With("file", hash).Errorf("failed to get inbound links for file: %s", err.Error()) return } if len(inboundLinks) == 0 { - if err = oc.core.ObjectStore().DeleteObject(f.Hash); err != nil { - log.With("file", f.Hash).Errorf("failed to delete file from objectstore: %s", err.Error()) + if err = oc.core.ObjectStore().DeleteObject(hash); err != nil { + log.With("file", hash).Errorf("failed to delete file from objectstore: %s", err.Error()) } - if err = oc.core.FileStore().DeleteByHash(f.Hash); err != nil { - log.With("file", f.Hash).Errorf("failed to delete file from filestore: %s", err.Error()) + if err = oc.core.FileStore().DeleteByHash(hash); err != nil { + log.With("file", hash).Errorf("failed to delete file from filestore: %s", err.Error()) } - if _, err = oc.core.FileOffload(f.Hash); err != nil { - log.With("file", f.Hash).Errorf("failed to offload file: %s", err.Error()) + if _, err = oc.core.FileOffload(hash); err != nil { + log.With("file", hash).Errorf("failed to offload file: %s", err.Error()) } - if err = oc.core.FileStore().DeleteFileKeys(f.Hash); err != nil { - log.With("file", f.Hash).Errorf("failed to delete file keys: %s", err.Error()) + if err = oc.core.FileStore().DeleteFileKeys(hash); err != nil { + log.With("file", hash).Errorf("failed to delete file keys: %s", err.Error()) } } } \ No newline at end of file diff --git a/core/block/import/relationcreator.go b/core/block/import/relationcreator.go new file mode 100644 index 000000000..f743d59f3 --- /dev/null +++ b/core/block/import/relationcreator.go @@ -0,0 +1,131 @@ +package importer + +import ( + "fmt" + "strings" + + "github.com/anytypeio/go-anytype-middleware/core/block" + "github.com/anytypeio/go-anytype-middleware/core/block/editor" + "github.com/anytypeio/go-anytype-middleware/core/session" + "github.com/anytypeio/go-anytype-middleware/pb" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" + "github.com/anytypeio/go-anytype-middleware/util/pbtypes" + "github.com/gogo/protobuf/types" +) + +type RelationService struct { + service block.Service +} + +func NewRelationCreator(service block.Service) RelationCreator { + return &RelationService{ + service: service, + } +} + +func (rc *RelationService) Create(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, pageID string) ([]string, error) { + var ( + object *types.Struct + relationID string + err error + filesToDelete = make([]string, 0) + ) + for _, r := range snapshot.RelationLinks { + detail := &types.Struct{ + Fields: map[string]*types.Value{ + bundle.RelationKeyName.String(): pbtypes.String(r.Key), + bundle.RelationKeyRelationFormat.String(): pbtypes.Int64(int64(r.Format)), + }, + } + if _, object, err = rc.service.CreateRelation(detail); err != nil && err != editor.ErrSubObjectAlreadyExists { + log.Errorf("create relation %s", err) + continue + } + + if object != nil && object.Fields != nil &&object.Fields[bundle.RelationKeyRelationKey.String()] != nil { + relationID = object.Fields[bundle.RelationKeyRelationKey.String()].GetStringValue() + } else { + continue + } + + if err := rc.service.AddExtraRelations(ctx, pageID, []string{relationID}); err != nil { + log.Errorf("add extra relation %s", err) + continue + } + + if snapshot.Details != nil && snapshot.Details.Fields != nil && object != nil { + if snapshot.Details.Fields[r.Key].GetListValue() != nil { + rc.handleListValue(ctx, snapshot, r, relationID) + } + + if r.Format == model.RelationFormat_file { + rc.handleFileRelation(ctx, snapshot, r, filesToDelete) + } + details := make([]*pb.RpcObjectSetDetailsDetail, 0) + details = append(details, &pb.RpcObjectSetDetailsDetail{ + Key: relationID, + Value: snapshot.Details.Fields[r.Key], + }) + err = rc.service.SetDetails(ctx, pb.RpcObjectSetDetailsRequest{ + ContextId: pageID, + Details: details, + }) + if err != nil { + return filesToDelete, fmt.Errorf("set details '%s'", err.Error()) + } + } + } + return filesToDelete, nil +} + +func (rc *RelationService) handleListValue(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, r *model.RelationLink, relationID string) { + var( + optionsIds = make([]string, 0) + id string + err error + ) + for _, v := range snapshot.Details.Fields[r.Key].GetListValue().Values { + if r.Format == model.RelationFormat_tag || r.Format == model.RelationFormat_status { + if id, _, err = rc.service.CreateRelationOption(&types.Struct{ + Fields: map[string]*types.Value{ + bundle.RelationKeyName.String(): pbtypes.String(v.GetStringValue()), + bundle.RelationKeyRelationKey.String(): pbtypes.String(relationID), + bundle.RelationKeyType.String(): pbtypes.String(bundle.TypeKeyRelationOption.URL()), + bundle.RelationKeyLayout.String(): pbtypes.Float64(float64(model.ObjectType_relationOption)), + }, + }); err != nil { + log.Errorf("add extra relation %s", err) + } + } else { + id = v.GetStringValue() + } + optionsIds = append(optionsIds, id) + } + snapshot.Details.Fields[r.Key] = pbtypes.StringList(optionsIds) +} + +func (rc *RelationService) handleFileRelation(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, r *model.RelationLink, filesToDelete []string) { + if files := snapshot.Details.Fields[r.Key].GetListValue(); files != nil { + allFilesHashes := make([]string, 0) + for _, f := range files.Values { + file := f.GetStringValue() + if file != "" { + req := pb.RpcFileUploadRequest{LocalPath: file} + if strings.HasPrefix(file, "http://") || strings.HasPrefix(file, "https://") { + req.Url = file + req.LocalPath = "" + } + hash, err := rc.service.UploadFile(req) + if err != nil { + log.Errorf("file uploading %s", err) + } else { + file = hash + } + filesToDelete = append(filesToDelete, file) + allFilesHashes = append(allFilesHashes, file) + } + } + snapshot.Details.Fields[r.Key] = pbtypes.StringList(allFilesHashes) + } +} \ No newline at end of file diff --git a/core/block/import/types.go b/core/block/import/types.go index 7ddf6d799..c6d3e630c 100644 --- a/core/block/import/types.go +++ b/core/block/import/types.go @@ -29,3 +29,7 @@ type Creator interface { type Updater interface { Update(ctx *session.Context, cs *model.SmartBlockSnapshotBase, pageID string) (*types.Struct, error) } + +type RelationCreator interface { + Create(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, pageID string) ([]string, error) +} From 58fb40b93b0a810ecd1ad6ba8dcaeef0f49b054c Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Wed, 9 Nov 2022 09:56:52 +0300 Subject: [PATCH 07/68] GO-470: add comments Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/notion/api/client/client.go | 2 ++ core/block/import/notion/api/client/error.go | 1 + core/block/import/notion/api/commonobjects.go | 7 +++---- core/block/import/notion/api/database/database.go | 4 +++- core/block/import/notion/api/page/page.go | 5 ++++- core/block/import/notion/api/property/detailsetter.go | 2 ++ core/block/import/notion/api/property/propertyitem.go | 2 ++ core/block/import/notion/api/property/propertyobject.go | 1 + core/block/import/notion/api/property/propertyvalue.go | 2 +- core/block/import/notion/api/search/search.go | 2 ++ core/block/import/relationcreator.go | 3 +++ core/block/import/types.go | 1 + 12 files changed, 25 insertions(+), 7 deletions(-) diff --git a/core/block/import/notion/api/client/client.go b/core/block/import/notion/api/client/client.go index d0665161b..5f7727770 100644 --- a/core/block/import/notion/api/client/client.go +++ b/core/block/import/notion/api/client/client.go @@ -18,6 +18,7 @@ type Client struct { BasePath string } +// NewClient is a constructor for Client func NewClient() *Client { c := &Client{ HttpClient:&http.Client{Timeout: time.Minute}, @@ -26,6 +27,7 @@ func NewClient() *Client { return c } +// PrepareRequest create http.Request based on given method, url and body func (c *Client) PrepareRequest(ctx context.Context, apiKey, method, url string, body *bytes.Buffer) (*http.Request, error) { resultUrl := c.BasePath + url req, err := http.NewRequestWithContext(ctx, method, resultUrl, body) diff --git a/core/block/import/notion/api/client/error.go b/core/block/import/notion/api/client/error.go index 8ce2c49c1..97ae5f0eb 100644 --- a/core/block/import/notion/api/client/error.go +++ b/core/block/import/notion/api/client/error.go @@ -13,6 +13,7 @@ type NotionErrorResponse struct { Message string `json:"message,omitempty"` } +//TransformHttpCodeToError reads error response and transofrm it to NotionErrorResponse and creates error based on NotionErrorResponse func TransformHttpCodeToError(response []byte) error { var notionErr NotionErrorResponse if err := json.Unmarshal(response, ¬ionErr); err != nil { diff --git a/core/block/import/notion/api/commonobjects.go b/core/block/import/notion/api/commonobjects.go index af2502711..069990cb9 100644 --- a/core/block/import/notion/api/commonobjects.go +++ b/core/block/import/notion/api/commonobjects.go @@ -14,6 +14,7 @@ const ( Equation richTextType = "equation" ) +// RichText represent RichText object from Notion https://developers.notion.com/reference/rich-text type RichText struct { Type richTextType `json:"type,omitempty"` Text *TextObject `json:"text,omitempty"` @@ -61,6 +62,7 @@ const ( File FileType = "file" ) +// FileObject represent File Object object from Notion https://developers.notion.com/reference/file-object type FileObject struct { Name string `json:"name"` Type FileType `json:"type"` @@ -96,6 +98,7 @@ type Icon struct { type userType string +// User represent User Object object from Notion https://developers.notion.com/reference/user type User struct { Object string `json:"object,omitempty"` ID string `json:"id"` @@ -116,10 +119,6 @@ type Parent struct { DatabaseID string `json:"database_id"` } -type Object interface { - GetObjectType() string -} - func RichTextToDescription(rt []RichText) string { var description bytes.Buffer diff --git a/core/block/import/notion/api/database/database.go b/core/block/import/notion/api/database/database.go index f8668e5f5..d5951d3e2 100644 --- a/core/block/import/notion/api/database/database.go +++ b/core/block/import/notion/api/database/database.go @@ -21,10 +21,11 @@ const ObjectType = "database" type Service struct {} +// New is a constructor for Service func New() *Service { return &Service{} } - +// Database represent Database object from Notion https://developers.notion.com/reference/database type Database struct { Object string `json:"object"` ID string `json:"id"` @@ -47,6 +48,7 @@ func (p *Database) GetObjectType() string { return ObjectType } +// GetDatabase makes snaphots from notion Database objects func (ds *Service) GetDatabase(ctx context.Context, mode pb.RpcObjectImportRequestMode, databases []Database) *converter.Response { convereterError := converter.ConvertError{} return ds.mapDatabasesToSnaphots(ctx, mode, databases, convereterError) diff --git a/core/block/import/notion/api/page/page.go b/core/block/import/notion/api/page/page.go index 5f9354a0a..27fc4761a 100644 --- a/core/block/import/notion/api/page/page.go +++ b/core/block/import/notion/api/page/page.go @@ -25,13 +25,14 @@ type Service struct { detailSetter *property.DetailSetter } +// New is a constructor for Service func New(client *client.Client) *Service { return &Service{ propertyService: property.New(client), detailSetter: property.NewDetailSetter(), } } - +// Page represents Page object from notion https://developers.notion.com/reference/page type Page struct { Object string `json:"object"` ID string `json:"id"` @@ -51,6 +52,7 @@ func (p *Page) GetObjectType() string { return ObjectType } +// GetPages transform Page objects from Notion to snaphots func (ds *Service) GetPages(ctx context.Context, apiKey string, mode pb.RpcObjectImportRequestMode, pages []Page) *converter.Response { convereterError := converter.ConvertError{} return ds.mapPagesToSnaphots(ctx, apiKey, mode, pages, convereterError) @@ -115,6 +117,7 @@ func (ds *Service) transformPages(apiKey string, d Page, mode pb.RpcObjectImport return snapshot, nil } +// handlePageProperties gets properties values by their ids from notion api and transforms them to Details and RelationLinks func (ds *Service) handlePageProperties(apiKey, pageID string, p property.Properties, d map[string]*types.Value, mode pb.RpcObjectImportRequestMode) ([]*model.RelationLink, *converter.ConvertError) { ce := converter.ConvertError{} relations := make([]*model.RelationLink, 0) diff --git a/core/block/import/notion/api/property/detailsetter.go b/core/block/import/notion/api/property/detailsetter.go index 34c3a198b..bf0eff43d 100644 --- a/core/block/import/notion/api/property/detailsetter.go +++ b/core/block/import/notion/api/property/detailsetter.go @@ -8,10 +8,12 @@ import ( type DetailSetter struct{} +// New is a constructor for DetailSetter func NewDetailSetter() *DetailSetter { return &DetailSetter{} } +// SetDetailValue creates Detail based on property type and value func (*DetailSetter) SetDetailValue(key string, propertyType PropertyConfigType, property []interface{}, details map[string]*types.Value) error { if len(property) == 0 { return nil diff --git a/core/block/import/notion/api/property/propertyitem.go b/core/block/import/notion/api/property/propertyitem.go index 0093e01ce..4e3fce9aa 100644 --- a/core/block/import/notion/api/property/propertyitem.go +++ b/core/block/import/notion/api/property/propertyitem.go @@ -1,5 +1,7 @@ package property +// This file represent property item from Notion https://developers.notion.com/reference/property-item-object + import ( "strconv" "time" diff --git a/core/block/import/notion/api/property/propertyobject.go b/core/block/import/notion/api/property/propertyobject.go index ff2e80537..312112ec8 100644 --- a/core/block/import/notion/api/property/propertyobject.go +++ b/core/block/import/notion/api/property/propertyobject.go @@ -119,6 +119,7 @@ type PropertyPaginatedRespone struct{ NextCursor string `json:"next_cursor"` } +// GetPropertyObject get from Notion properties values based on type and id and marshal it to according structure from propertyitem.go func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, apiKey string, propertyType PropertyConfigType) ([]interface{}, error) { var ( hasMore = true diff --git a/core/block/import/notion/api/property/propertyvalue.go b/core/block/import/notion/api/property/propertyvalue.go index 634031c37..844cf4cfc 100644 --- a/core/block/import/notion/api/property/propertyvalue.go +++ b/core/block/import/notion/api/property/propertyvalue.go @@ -1,5 +1,6 @@ package property +// This file represent property configuration from Notion https://developers.notion.com/reference/property-object import ( "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" ) @@ -28,7 +29,6 @@ const ( PropertyConfigLastEditedBy PropertyConfigType = "last_edited_by" PropertyConfigStatus PropertyConfigType = "status" ) - type PropertyObject interface { GetPropertyType() PropertyConfigType GetID() string diff --git a/core/block/import/notion/api/search/search.go b/core/block/import/notion/api/search/search.go index f3be68e1d..80a2314de 100644 --- a/core/block/import/notion/api/search/search.go +++ b/core/block/import/notion/api/search/search.go @@ -27,12 +27,14 @@ type SearchResponse struct { NextCursor *string `json:"next_cursor"` } +// New is a constructor for Service func New(client *client.Client) *Service { return &Service{ client: client, } } +// Search calls /search endoint from Notion, which return all databases and pages from user integration func (s *Service) Search(ctx context.Context, apiKey string, pageSize int64) ([]database.Database, []page.Page, error) { var ( hasMore = true diff --git a/core/block/import/relationcreator.go b/core/block/import/relationcreator.go index f743d59f3..065bae65d 100644 --- a/core/block/import/relationcreator.go +++ b/core/block/import/relationcreator.go @@ -18,12 +18,15 @@ type RelationService struct { service block.Service } +// NewRelationCreator constructor for RelationService func NewRelationCreator(service block.Service) RelationCreator { return &RelationService{ service: service, } } +// Create read relations link from snaphot and create according relations in anytype, also set details for according relation in object +// for files it loads them in ipfs func (rc *RelationService) Create(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, pageID string) ([]string, error) { var ( object *types.Struct diff --git a/core/block/import/types.go b/core/block/import/types.go index c6d3e630c..782456867 100644 --- a/core/block/import/types.go +++ b/core/block/import/types.go @@ -30,6 +30,7 @@ type Updater interface { Update(ctx *session.Context, cs *model.SmartBlockSnapshotBase, pageID string) (*types.Struct, error) } +// RelationCreator incapsulates logic for creation of relations type RelationCreator interface { Create(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, pageID string) ([]string, error) } From 362a96143da363a2af1dd375c6137d21a0418768 Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Wed, 9 Nov 2022 11:52:56 +0300 Subject: [PATCH 08/68] GO-470: add retry mechanism Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/notion/api/search/search.go | 42 +++++++++++++++---- core/block/import/notion/converter.go | 25 ++++++----- 2 files changed, 48 insertions(+), 19 deletions(-) diff --git a/core/block/import/notion/api/search/search.go b/core/block/import/notion/api/search/search.go index 80a2314de..9b74f02d3 100644 --- a/core/block/import/notion/api/search/search.go +++ b/core/block/import/notion/api/search/search.go @@ -7,12 +7,16 @@ import ( "fmt" "io/ioutil" "net/http" + "time" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/database" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/page" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/logging" ) +var logger = logging.Logger("notion-search") + const ( endpoint = "/search" ) @@ -23,8 +27,8 @@ type Service struct { type SearchResponse struct { Results []interface{} `json:"results"` - HasMore bool `json:"has_more"` - NextCursor *string `json:"next_cursor"` + HasMore bool `json:"has_more"` + NextCursor *string `json:"next_cursor"` } // New is a constructor for Service @@ -34,6 +38,28 @@ func New(client *client.Client) *Service { } } +type Effector func(ctx context.Context, apiKey string, pageSize int64) ([]database.Database, []page.Page, error) + +// Retry is an implementation for retry pattern +func Retry(effector Effector, retries int, delay time.Duration) Effector { + return func(ctx context.Context, apiKey string, pageSize int64) ([]database.Database, []page.Page, error) { + for r := 0; ; r++ { + database, pages, err := effector(ctx, apiKey, pageSize) + if err == nil || r >= retries { + return database, pages, err + } + + logger.Infof("Attempt %d failed; retrying in %v", r+1, delay) + + select { + case <-time.After(delay): + case <-ctx.Done(): + return nil, nil, ctx.Err() + } + } + } +} + // Search calls /search endoint from Notion, which return all databases and pages from user integration func (s *Service) Search(ctx context.Context, apiKey string, pageSize int64) ([]database.Database, []page.Page, error) { var ( @@ -44,19 +70,19 @@ func (s *Service) Search(ctx context.Context, apiKey string, pageSize int64) ([] startCursor string ) type Option struct { - PageSize int64 `json:"page_size,omitempty"` + PageSize int64 `json:"page_size,omitempty"` StartCursor string `json:"start_cursor,omitempty"` } - + for hasMore { err := json.NewEncoder(body).Encode(&Option{PageSize: pageSize, StartCursor: startCursor}) - + if err != nil { return nil, nil, fmt.Errorf("ListDatabases: %s", err) } - + req, err := s.client.PrepareRequest(ctx, apiKey, http.MethodPost, endpoint, body) - + if err != nil { return nil, nil, fmt.Errorf("ListDatabases: %s", err) } @@ -99,7 +125,7 @@ func (s *Service) Search(ctx context.Context, apiKey string, pageSize int64) ([] } resultDatabases = append(resultDatabases, d) } - if o.(map[string]interface{})["object"] == page.ObjectType{ + if o.(map[string]interface{})["object"] == page.ObjectType { pg, err := json.Marshal(o) if err != nil { return nil, nil, fmt.Errorf("ListDatabases: %s", err) diff --git a/core/block/import/notion/converter.go b/core/block/import/notion/converter.go index 16391dac4..8aa824f12 100644 --- a/core/block/import/notion/converter.go +++ b/core/block/import/notion/converter.go @@ -3,6 +3,7 @@ package notion import ( "context" "fmt" + "time" "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" @@ -14,8 +15,10 @@ import ( ) const ( - name = "Notion" - pageSize = 100 + name = "Notion" + pageSize = 100 + retryDelay = time.Second + retryAmount = 5 ) func init() { @@ -23,17 +26,17 @@ func init() { } type Notion struct { - search *search.Service + search *search.Service databaseService *database.Service - pageService *page.Service + pageService *page.Service } func New(core.Service) converter.Converter { cl := client.NewClient() return &Notion{ - search: search.New(cl), + search: search.New(cl), databaseService: database.New(), - pageService: page.New(cl), + pageService: page.New(cl), } } @@ -46,7 +49,8 @@ func (n *Notion) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Respons Error: ce, } } - databases, pages, err := n.search.Search(context.TODO(), apiKey, pageSize) + databases, pages, err := search.Retry(n.search.Search, retryAmount, retryDelay)(context.TODO(), apiKey, pageSize) + if err != nil { ce.Add("/search", fmt.Errorf("failed to get pages and databases %s", err)) return &converter.Response{ @@ -69,7 +73,7 @@ func (n *Notion) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Respons } } - allSnaphots := make([]*converter.Snapshot, 0, len(pagesSnapshots.Snapshots) + len(databasesSnapshots.Snapshots)) + allSnaphots := make([]*converter.Snapshot, 0, len(pagesSnapshots.Snapshots)+len(databasesSnapshots.Snapshots)) allSnaphots = append(allSnaphots, pagesSnapshots.Snapshots...) allSnaphots = append(allSnaphots, databasesSnapshots.Snapshots...) if pagesSnapshots.Error != nil { @@ -81,12 +85,12 @@ func (n *Notion) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Respons if !ce.IsEmpty() { return &converter.Response{ Snapshots: allSnaphots, - Error: ce, + Error: ce, } } return &converter.Response{ Snapshots: allSnaphots, - Error: nil, + Error: nil, } } @@ -100,4 +104,3 @@ func (n *Notion) getParams(param *pb.RpcObjectImportRequest) string { func (n *Notion) Name() string { return name } - From 30c4c84a363570cffc58660afedd0b33d1063d2b Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Thu, 17 Nov 2022 17:43:14 +0300 Subject: [PATCH 09/68] GO-470: fix comments Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/notion/api/page/page.go | 2 +- .../notion/api/property/detailsetter.go | 83 +++---------------- .../notion/api/property/propertyitem.go | 8 ++ .../notion/api/property/propertyobject.go | 46 +++++----- .../notion/api/property/propertyvalue.go | 4 + 5 files changed, 46 insertions(+), 97 deletions(-) diff --git a/core/block/import/notion/api/page/page.go b/core/block/import/notion/api/page/page.go index 27fc4761a..59780ac77 100644 --- a/core/block/import/notion/api/page/page.go +++ b/core/block/import/notion/api/page/page.go @@ -22,7 +22,7 @@ const ObjectType = "page" type Service struct { propertyService *property.Service - detailSetter *property.DetailSetter + detailSetter *property.DetailValueSetter } // New is a constructor for Service diff --git a/core/block/import/notion/api/property/detailsetter.go b/core/block/import/notion/api/property/detailsetter.go index bf0eff43d..71af30933 100644 --- a/core/block/import/notion/api/property/detailsetter.go +++ b/core/block/import/notion/api/property/detailsetter.go @@ -1,90 +1,27 @@ package property import ( - "fmt" - "github.com/gogo/protobuf/types" ) -type DetailSetter struct{} +type DetailValueSetter struct{} -// New is a constructor for DetailSetter -func NewDetailSetter() *DetailSetter { - return &DetailSetter{} +// New is a constructor for DetailValueSetter +func NewDetailSetter() *DetailValueSetter { + return &DetailValueSetter{} } // SetDetailValue creates Detail based on property type and value -func (*DetailSetter) SetDetailValue(key string, propertyType PropertyConfigType, property []interface{}, details map[string]*types.Value) error { +func (*DetailValueSetter) SetDetailValue(key string, propertyType PropertyConfigType, property []DetailSetter, details map[string]*types.Value) error { if len(property) == 0 { return nil } - switch propertyType { - case PropertyConfigTypeTitle: - for _, v := range property { - title := v.(TitleItem) - title.SetDetail(key, details) + if IsVector(propertyType) { + for _, pr := range property { + pr.SetDetail(key, details) } - case PropertyConfigTypeRichText: - for _, v := range property { - rt := v.(RichTextItem) - rt.SetDetail(key, details) - } - case PropertyConfigTypePeople: - for _, v := range property { - p := v.(PeopleItem) - p.SetDetail(key, details) - } - case PropertyConfigTypeRelation: - for _, v := range property { - r := v.(RelationItem) - r.SetDetail(key, details) - } - case PropertyConfigTypeNumber: - number := property[0].(NumberItem) - number.SetDetail(key, details) - case PropertyConfigTypeSelect: - selectProperty := property[0].(SelectItem) - selectProperty.SetDetail(key, details) - case PropertyConfigTypeMultiSelect: - multiSelect := property[0].(MultiSelectItem) - multiSelect.SetDetail(key, details) - case PropertyConfigTypeDate: - case PropertyConfigTypeFiles: - f := property[0].(FileItem) - f.SetDetail(key, details) - case PropertyConfigTypeCheckbox: - c := property[0].(CheckboxItem) - c.SetDetail(key, details) - case PropertyConfigTypeURL: - url := property[0].(UrlItem) - url.SetDetail(key, details) - case PropertyConfigTypeEmail: - email := property[0].(EmailItem) - email.SetDetail(key, details) - case PropertyConfigTypePhoneNumber: - phone := property[0].(PhoneItem) - phone.SetDetail(key, details) - case PropertyConfigTypeFormula: - formula := property[0].(FormulaItem) - formula.SetDetail(key, details) - case PropertyConfigTypeRollup: - case PropertyConfigCreatedTime: - ct := property[0].(CreatedTimeItem) - ct.SetDetail(key, details) - case PropertyConfigCreatedBy: - cb := property[0].(CreatedByItem) - cb.SetDetail(key, details) - case PropertyConfigLastEditedTime: - lt := property[0].(LastEditedTimeItem) - lt.SetDetail(key, details) - case PropertyConfigLastEditedBy: - lb := property[0].(LastEditedByItem) - lb.SetDetail(key, details) - case PropertyConfigStatus: - lb := property[0].(StatusItem) - lb.SetDetail(key, details) - default: - return fmt.Errorf("unsupported property type: %s", propertyType) + } else { + property[0].SetDetail(key, details) } return nil } \ No newline at end of file diff --git a/core/block/import/notion/api/property/propertyitem.go b/core/block/import/notion/api/property/propertyitem.go index 4e3fce9aa..c5a911420 100644 --- a/core/block/import/notion/api/property/propertyitem.go +++ b/core/block/import/notion/api/property/propertyitem.go @@ -14,6 +14,10 @@ import ( "github.com/anytypeio/go-anytype-middleware/util/pbtypes" ) +type DetailSetter interface { + SetDetail(key string, details map[string]*types.Value) +} + type TitleItem struct { Object string `json:"object"` ID string `json:"id"` @@ -315,3 +319,7 @@ type Status struct { func (sp *StatusItem) SetDetail(key string, details map[string]*types.Value) { details[key] = pbtypes.StringList([]string{sp.Status.Name}) } + +type RollupItem struct {} + +func (sp *RollupItem) SetDetail(key string, details map[string]*types.Value) {} \ No newline at end of file diff --git a/core/block/import/notion/api/property/propertyobject.go b/core/block/import/notion/api/property/propertyobject.go index 312112ec8..7a411291f 100644 --- a/core/block/import/notion/api/property/propertyobject.go +++ b/core/block/import/notion/api/property/propertyobject.go @@ -120,13 +120,13 @@ type PropertyPaginatedRespone struct{ } // GetPropertyObject get from Notion properties values based on type and id and marshal it to according structure from propertyitem.go -func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, apiKey string, propertyType PropertyConfigType) ([]interface{}, error) { +func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, apiKey string, propertyType PropertyConfigType) ([]DetailSetter, error) { var ( hasMore = true body = &bytes.Buffer{} startCursor string response PropertyPaginatedRespone - paginatedResponse = make([]interface{}, 0) + paginatedResponse = make([]DetailSetter, 0) ) type Request struct { @@ -187,7 +187,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api logger.Errorf("GetPropertyObject: failed to marshal TitleItem: %s", err) continue } - paginatedResponse = append(paginatedResponse, p) + paginatedResponse = append(paginatedResponse, &p) } if propertyType == PropertyConfigTypeRichText { p := RichTextItem{} @@ -196,7 +196,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api logger.Errorf("GetPropertyObject: failed to marshal RichTextItem: %s", err) continue } - paginatedResponse = append(paginatedResponse, p) + paginatedResponse = append(paginatedResponse, &p) } if propertyType == PropertyConfigTypeRelation { p := RelationItem{} @@ -205,7 +205,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api logger.Errorf("GetPropertyObject: failed to marshal RelationItem: %s", err) continue } - paginatedResponse = append(paginatedResponse, p) + paginatedResponse = append(paginatedResponse, &p) } if propertyType == PropertyConfigTypePeople { p := PeopleItem{} @@ -214,7 +214,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api logger.Errorf("GetPropertyObject: failed to marshal PeopleItem: %s", err) continue } - paginatedResponse = append(paginatedResponse, p) + paginatedResponse = append(paginatedResponse, &p) } } if response.HasMore { @@ -228,7 +228,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api logger.Errorf("GetPropertyObject: failed to marshal NumberItem: %s", err) continue } - paginatedResponse = append(paginatedResponse, p) + paginatedResponse = append(paginatedResponse, &p) case PropertyConfigTypeSelect: p := SelectItem{} err = json.Unmarshal(b, &p) @@ -236,7 +236,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api logger.Errorf("GetPropertyObject: failed to marshal SelectItem: %s", err) continue } - paginatedResponse = append(paginatedResponse, p) + paginatedResponse = append(paginatedResponse, &p) case PropertyConfigTypeMultiSelect: p := MultiSelectItem{} err = json.Unmarshal(b, &p) @@ -244,7 +244,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api logger.Errorf("GetPropertyObject: failed to marshal MultiSelectItem: %s", err) continue } - paginatedResponse = append(paginatedResponse, p) + paginatedResponse = append(paginatedResponse, &p) case PropertyConfigTypeDate: date := DateItem{} err = json.Unmarshal(b, &date) @@ -252,7 +252,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api logger.Errorf("GetPropertyObject: failed to marshal DateItem: %s", err) continue } - paginatedResponse = append(paginatedResponse, date) + paginatedResponse = append(paginatedResponse, &date) case PropertyConfigTypeFiles: file := FileItem{} err = json.Unmarshal(b, &file) @@ -260,7 +260,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api logger.Errorf("GetPropertyObject: failed to marshal FileItem: %s", err) continue } - paginatedResponse = append(paginatedResponse, file) + paginatedResponse = append(paginatedResponse, &file) case PropertyConfigTypeCheckbox: checkbox := CheckboxItem{} err = json.Unmarshal(b, &checkbox) @@ -268,7 +268,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api logger.Errorf("GetPropertyObject: failed to marshal CheckboxItem: %s", err) continue } - paginatedResponse = append(paginatedResponse, checkbox) + paginatedResponse = append(paginatedResponse, &checkbox) case PropertyConfigTypeURL: url := UrlItem{} err = json.Unmarshal(b, &url) @@ -276,7 +276,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api logger.Errorf("GetPropertyObject: failed to marshal UrlItem: %s", err) continue } - paginatedResponse = append(paginatedResponse, url) + paginatedResponse = append(paginatedResponse, &url) case PropertyConfigTypeEmail: email := EmailItem{} err = json.Unmarshal(b, &email) @@ -284,7 +284,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api logger.Errorf("GetPropertyObject: failed to marshal EmailItem: %s", err) continue } - paginatedResponse = append(paginatedResponse, email) + paginatedResponse = append(paginatedResponse, &email) case PropertyConfigTypePhoneNumber: phone := PhoneItem{} err = json.Unmarshal(b, &phone) @@ -292,7 +292,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api logger.Errorf("GetPropertyObject: failed to marshal PhoneItem: %s", err) continue } - paginatedResponse = append(paginatedResponse, phone) + paginatedResponse = append(paginatedResponse, &phone) case PropertyConfigTypeFormula: formula := FormulaItem{} err = json.Unmarshal(b, &formula) @@ -300,15 +300,15 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api logger.Errorf("GetPropertyObject: failed to marshal FormulaItem: %s", err) continue } - paginatedResponse = append(paginatedResponse, formula) + paginatedResponse = append(paginatedResponse, &formula) case PropertyConfigTypeRollup: - rollup := Rollup{} + rollup := RollupItem{} err = json.Unmarshal(b, &rollup) if err != nil { logger.Errorf("GetPropertyObject: failed to marshal Rollup: %s", err) continue } - paginatedResponse = append(paginatedResponse, rollup) + paginatedResponse = append(paginatedResponse, &rollup) case PropertyConfigCreatedTime: ct := CreatedTimeItem{} err = json.Unmarshal(b, &ct) @@ -316,7 +316,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api logger.Errorf("GetPropertyObject: failed to marshal CreatedTimeItem: %s", err) continue } - paginatedResponse = append(paginatedResponse, ct) + paginatedResponse = append(paginatedResponse, &ct) case PropertyConfigCreatedBy: cb := CreatedByItem{} err = json.Unmarshal(b, &cb) @@ -324,7 +324,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api logger.Errorf("GetPropertyObject: failed to marshal CreatedByItem: %s", err) continue } - paginatedResponse = append(paginatedResponse, cb) + paginatedResponse = append(paginatedResponse, &cb) case PropertyConfigLastEditedTime: lt := LastEditedTimeItem{} err = json.Unmarshal(b, <) @@ -332,7 +332,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api logger.Errorf("GetPropertyObject: failed to marshal LastEditedTimeItem: %s", err) continue } - paginatedResponse = append(paginatedResponse, lt) + paginatedResponse = append(paginatedResponse, <) case PropertyConfigLastEditedBy: le := LastEditedByItem{} err = json.Unmarshal(b, &le) @@ -340,7 +340,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api logger.Errorf("GetPropertyObject: failed to marshal LastEditedByItem: %s", err) continue } - paginatedResponse = append(paginatedResponse, le) + paginatedResponse = append(paginatedResponse, &le) case PropertyConfigStatus: sp := StatusItem{} err = json.Unmarshal(b, &sp) @@ -348,7 +348,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, api logger.Errorf("GetPropertyObject: failed to marshal StatusItem: %s", err) continue } - paginatedResponse = append(paginatedResponse, sp) + paginatedResponse = append(paginatedResponse, &sp) default: return nil, fmt.Errorf("GetPropertyObject: unsupported property type: %s", propertyType) } diff --git a/core/block/import/notion/api/property/propertyvalue.go b/core/block/import/notion/api/property/propertyvalue.go index 844cf4cfc..cb9e0080e 100644 --- a/core/block/import/notion/api/property/propertyvalue.go +++ b/core/block/import/notion/api/property/propertyvalue.go @@ -7,6 +7,10 @@ import ( type PropertyConfigType string +func IsVector (p PropertyConfigType) bool { + return p == PropertyConfigTypeTitle || p == PropertyConfigTypeRichText || p == PropertyConfigTypePeople || p == PropertyConfigTypeRelation +} + const ( PropertyConfigTypeTitle PropertyConfigType = "title" PropertyConfigTypeRichText PropertyConfigType = "rich_text" From 9b288bf4d332f0f29e77a2cd6cd3b15fb2f21aed Mon Sep 17 00:00:00 2001 From: Anastasia Shemyakinskaya <36507473+AnastasiaShemyakinskaya@users.noreply.github.com> Date: Mon, 21 Nov 2022 13:08:37 +0300 Subject: [PATCH 10/68] GO-471: retrieve text blocks from notion (#1617) Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/importer.go | 2 +- core/block/import/notion/api/block/block.go | 61 ++ core/block/import/notion/api/block/blocks.go | 10 - core/block/import/notion/api/block/mapper.go | 107 +++ .../block/import/notion/api/block/retrieve.go | 313 +++++++ .../import/notion/api/block/retrieve_test.go | 786 ++++++++++++++++++ core/block/import/notion/api/block/text.go | 325 ++++++++ .../import/notion/api/block/text_test.go | 182 ++++ core/block/import/notion/api/commonobjects.go | 244 +++++- .../import/notion/api/commonobjects_test.go | 105 +++ .../import/notion/api/database/database.go | 20 +- core/block/import/notion/api/page/page.go | 81 +- .../block/import/notion/api/page/page_test.go | 24 +- .../notion/api/property/propertyitem.go | 26 +- .../import/notion/api/search/search_test.go | 4 +- core/block/import/notion/converter.go | 4 +- core/block/import/objectcreator.go | 11 +- core/block/import/pb/converter.go | 2 +- core/block/import/relationcreator.go | 4 +- core/block/import/syncer/icon.go | 51 ++ core/block/import/syncer/syncer.go | 8 +- 21 files changed, 2251 insertions(+), 119 deletions(-) create mode 100644 core/block/import/notion/api/block/block.go delete mode 100644 core/block/import/notion/api/block/blocks.go create mode 100644 core/block/import/notion/api/block/mapper.go create mode 100644 core/block/import/notion/api/block/retrieve.go create mode 100644 core/block/import/notion/api/block/retrieve_test.go create mode 100644 core/block/import/notion/api/block/text.go create mode 100644 core/block/import/notion/api/block/text_test.go create mode 100644 core/block/import/notion/api/commonobjects_test.go create mode 100644 core/block/import/syncer/icon.go diff --git a/core/block/import/importer.go b/core/block/import/importer.go index f5b2be69a..199a66cd8 100644 --- a/core/block/import/importer.go +++ b/core/block/import/importer.go @@ -43,7 +43,7 @@ func (i *Import) Init(a *app.App) (err error) { converter := f(core) i.converters[converter.Name()] = converter } - factory := syncer.New(syncer.NewFileSyncer(i.s), syncer.NewBookmarkSyncer(i.s)) + factory := syncer.New(syncer.NewFileSyncer(i.s), syncer.NewBookmarkSyncer(i.s), syncer.NewIconSyncer(i.s)) ou := NewObjectUpdater(i.s, core, factory) relationCreator := NewRelationCreator(i.s) i.oc = NewCreator(i.s, core, ou, factory, relationCreator) diff --git a/core/block/import/notion/api/block/block.go b/core/block/import/notion/api/block/block.go new file mode 100644 index 000000000..8b1d4a72a --- /dev/null +++ b/core/block/import/notion/api/block/block.go @@ -0,0 +1,61 @@ +package block + +import ( + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" +) + +type BlockType string + +const ( + Paragraph BlockType = "paragraph" + BulletList BlockType = "bulleted_list_item" + NumberList BlockType = "numbered_list_item" + Toggle BlockType = "toggle" + SyncedBlock BlockType = "synced_block" + Template BlockType = "template" + Column BlockType = "column" + ChildPage BlockType = "child_page" + ChildDatabase BlockType = "child_database" + Table BlockType = "table" + Heading1 BlockType = "heading_1" + Heading2 BlockType = "heading_2" + Heading3 BlockType = "heading_3" + ToDo BlockType = "to_do" + Embed BlockType = "embed" + Image BlockType = "image" + Video BlockType = "video" + File BlockType = "file" + Pdf BlockType = "pdf" + Bookmark BlockType = "bookmark" + Callout BlockType = "callout" + Quote BlockType = "quote" + Equation BlockType = "equation" + Divider BlockType = "divider" + TableOfContents BlockType = "table_of_contents" + ColumnList BlockType = "column_list" + LinkPreview BlockType = "link_preview" + LinkToPage BlockType = "link_to_page" + TableRow BlockType = "table_row" + Code BlockType = "code" + Unsupported BlockType = "unsupported" +) + +type Block struct { + Object string `json:"object"` + ID string `json:"id"` + CreatedTime string `json:"created_time"` + LastEditedTime string `json:"last_edited_time"` + CreatedBy api.User `json:"created_by,omitempty"` + LastEditedBy api.User `json:"last_edited_by,omitempty"` + Parent api.Parent `json:"parent"` + Archived bool `json:"archived"` + HasChildren bool `json:"has_children"` + Type BlockType `json:"type"` +} + +type ImageBlock struct { + Caption []api.RichText `json:"caption,omitempty"` + Type api.FileType `json:"type"` + File api.FileProperty `json:"file,omitempty"` + External api.FileProperty `json:"external,omitempty"` +} diff --git a/core/block/import/notion/api/block/blocks.go b/core/block/import/notion/api/block/blocks.go deleted file mode 100644 index ea60377c0..000000000 --- a/core/block/import/notion/api/block/blocks.go +++ /dev/null @@ -1,10 +0,0 @@ -package block - -import "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" - -type Image struct { - Caption []api.RichText `json:"caption,omitempty"` - Type api.FileType `json:"type"` - File api.FileProperty `json:"file,omitempty"` - External api.FileProperty `json:"external,omitempty"` -} \ No newline at end of file diff --git a/core/block/import/notion/api/block/mapper.go b/core/block/import/notion/api/block/mapper.go new file mode 100644 index 000000000..7739ce3aa --- /dev/null +++ b/core/block/import/notion/api/block/mapper.go @@ -0,0 +1,107 @@ +package block + +import ( + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" +) + +type Mapper struct{} + +func (m *Mapper) MapBlocks(blocks []interface{}, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID map[string]string) ([]*model.Block, []string) { + var ( + anytypeBlocks = make([]*model.Block, 0) + ids = make([]string, 0) + ) + for _, bl := range blocks { + switch block := bl.(type) { + case *ParagraphBlock: + childIds := make([]string, 0) + var childBlocks []*model.Block + if block.HasChildren { + childBlocks, childIds = m.MapBlocks(block.Paragraph.Children, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) + } + allBlocks, blockIDs := block.Paragraph.GetTextBlocks(model.BlockContentText_Paragraph, childIds, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) + anytypeBlocks = append(anytypeBlocks, allBlocks...) + anytypeBlocks = append(anytypeBlocks, childBlocks...) + ids = append(ids, blockIDs...) + case *Heading1Block: + allBlocks, blockIDs := block.Heading1.GetTextBlocks(model.BlockContentText_Header1, []string{}, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) + anytypeBlocks = append(anytypeBlocks, allBlocks...) + ids = append(ids, blockIDs...) + case *Heading2Block: + allBlocks, blockIDs := block.Heading2.GetTextBlocks(model.BlockContentText_Header2, []string{}, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) + anytypeBlocks = append(anytypeBlocks, allBlocks...) + ids = append(ids, blockIDs...) + case *Heading3Block: + allBlocks, blockIDs := block.Heading3.GetTextBlocks(model.BlockContentText_Header3, []string{}, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) + anytypeBlocks = append(anytypeBlocks, allBlocks...) + ids = append(ids, blockIDs...) + case *CalloutBlock: + childIds := make([]string, 0) + var childBlocks []*model.Block + if block.HasChildren { + childBlocks, childIds = m.MapBlocks(block.Callout.Children, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) + } + calloutBlocks, blockIDs := block.Callout.GetCalloutBlocks(childIds) + anytypeBlocks = append(anytypeBlocks, calloutBlocks...) + anytypeBlocks = append(anytypeBlocks, childBlocks...) + ids = append(ids, blockIDs...) + case *QuoteBlock: + childIds := make([]string, 0) + var childBlocks []*model.Block + if block.HasChildren { + childBlocks, childIds = m.MapBlocks(block.Quote.Children, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) + } + allBlocks, blockIDs := block.Quote.GetTextBlocks(model.BlockContentText_Quote, childIds, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) + anytypeBlocks = append(anytypeBlocks, allBlocks...) + anytypeBlocks = append(anytypeBlocks, childBlocks...) + ids = append(ids, blockIDs...) + case *BulletedListBlock: + childIds := make([]string, 0) + var childBlocks []*model.Block + if block.HasChildren { + childBlocks, childIds = m.MapBlocks(block.BulletedList.Children, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) + } + allBlocks, blockIDs := block.BulletedList.GetTextBlocks(model.BlockContentText_Marked, childIds, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) + anytypeBlocks = append(anytypeBlocks, allBlocks...) + anytypeBlocks = append(anytypeBlocks, childBlocks...) + ids = append(ids, blockIDs...) + case *NumberedListBlock: + childIds := make([]string, 0) + var childBlocks []*model.Block + if block.HasChildren { + childBlocks, childIds = m.MapBlocks(block.NumberedList.Children, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) + } + allBlocks, blockIDs := block.NumberedList.GetTextBlocks(model.BlockContentText_Numbered, childIds, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) + anytypeBlocks = append(anytypeBlocks, allBlocks...) + anytypeBlocks = append(anytypeBlocks, childBlocks...) + ids = append(ids, blockIDs...) + case *ToggleBlock: + childIds := make([]string, 0) + var childBlocks []*model.Block + if block.HasChildren { + childBlocks, childIds = m.MapBlocks(block.Toggle.Children, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) + } + allBlocks, blockIDs := block.Toggle.GetTextBlocks(model.BlockContentText_Toggle, childIds, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) + anytypeBlocks = append(anytypeBlocks, allBlocks...) + anytypeBlocks = append(anytypeBlocks, childBlocks...) + ids = append(ids, blockIDs...) + case *CodeBlock: + c := bl.(*CodeBlock) + anytypeBlocks = append(anytypeBlocks, c.Code.GetCodeBlock()) + case *EquationBlock: + e := bl.(*EquationBlock) + anytypeBlocks = append(anytypeBlocks, e.Equation.HandleEquation()) + case *ToDoBlock: + childIds := make([]string, 0) + var childBlocks []*model.Block + if block.HasChildren { + childBlocks, childIds = m.MapBlocks(block.ToDo.Children, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) + } + allBlocks, blockIDs := block.ToDo.GetTextBlocks(model.BlockContentText_Checkbox, childIds, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) + anytypeBlocks = append(anytypeBlocks, allBlocks...) + anytypeBlocks = append(anytypeBlocks, childBlocks...) + ids = append(ids, blockIDs...) + } + } + return anytypeBlocks, ids +} diff --git a/core/block/import/notion/api/block/retrieve.go b/core/block/import/notion/api/block/retrieve.go new file mode 100644 index 000000000..693c09410 --- /dev/null +++ b/core/block/import/notion/api/block/retrieve.go @@ -0,0 +1,313 @@ +package block + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "strconv" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" + "github.com/anytypeio/go-anytype-middleware/pb" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/logging" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" +) + +var logger = logging.Logger("notion-get-blocks") + +const ( + // Page is also a block, so we use endpoint to retrieve its children + endpoint = "/blocks/%s/children" + startCursor = "start_cursor" + pageSize = "page_size" +) + +type Service struct { + client *client.Client + mapper *Mapper +} + +func New(client *client.Client) *Service { + return &Service{ + client: client, + mapper: &Mapper{}, + } +} + +type Response struct { + Results []interface{} `json:"results"` + HasMore bool `json:"has_more"` + NextCursor *string `json:"next_cursor"` + Block Block `json:"block"` +} + +func (s *Service) GetBlocksAndChildren(ctx context.Context, pageID, apiKey string, pageSize int64, mode pb.RpcObjectImportRequestMode) ([]interface{}, *converter.ConvertError) { + ce := &converter.ConvertError{} + allBlocks := make([]interface{}, 0) + blocks, err := s.getBlocks(ctx, pageID, apiKey, pageSize) + if err != nil { + ce.Add(endpoint, err) + if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + return nil, ce + } + } + + for _, b := range blocks { + switch bl := b.(type) { + case *Heading1Block, *Heading2Block, *Heading3Block, *CodeBlock, *EquationBlock: + allBlocks = append(allBlocks, bl) + case *ParagraphBlock: + if bl.HasChildren { + children, err := s.GetBlocksAndChildren(ctx, bl.ID, apiKey, pageSize, mode) + if err != nil { + ce.Merge(*err) + if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + return nil, ce + } + } + bl.Paragraph.Children = children + } + allBlocks = append(allBlocks, bl) + case *CalloutBlock: + if bl.HasChildren { + children, err := s.GetBlocksAndChildren(ctx, bl.ID, apiKey, pageSize, mode) + if err != nil { + ce.Merge(*err) + if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + return nil, ce + } + } + bl.Callout.Children = children + } + allBlocks = append(allBlocks, bl) + case *QuoteBlock: + if bl.HasChildren { + children, err := s.GetBlocksAndChildren(ctx, bl.ID, apiKey, pageSize, mode) + if err != nil { + ce.Merge(*err) + if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + return nil, ce + } + } + bl.Quote.Children = children + } + allBlocks = append(allBlocks, bl) + case *BulletedListBlock: + if bl.HasChildren { + children, err := s.GetBlocksAndChildren(ctx, bl.ID, apiKey, pageSize, mode) + if err != nil { + ce.Merge(*err) + if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + return nil, ce + } + } + bl.BulletedList.Children = children + } + allBlocks = append(allBlocks, bl) + case *NumberedListBlock: + if bl.HasChildren { + children, err := s.GetBlocksAndChildren(ctx, bl.ID, apiKey, pageSize, mode) + if err != nil { + ce.Merge(*err) + if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + return nil, ce + } + } + bl.NumberedList.Children = children + } + allBlocks = append(allBlocks, bl) + case *ToggleBlock: + if bl.HasChildren { + children, err := s.GetBlocksAndChildren(ctx, bl.ID, apiKey, pageSize, mode) + if err != nil { + ce.Merge(*err) + if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + return nil, ce + } + } + bl.Toggle.Children = children + } + allBlocks = append(allBlocks, bl) + case *ToDoBlock: + if bl.HasChildren { + children, err := s.GetBlocksAndChildren(ctx, bl.ID, apiKey, pageSize, mode) + if err != nil { + ce.Merge(*err) + if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + return nil, ce + } + } + bl.ToDo.Children = children + } + allBlocks = append(allBlocks, bl) + } + } + return allBlocks, nil +} + +func (s *Service) MapNotionBlocksToAnytype(blocks []interface{}, notionPagesIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID map[string]string) []*model.Block { + allBlocks, _ := s.mapper.MapBlocks(blocks, notionPagesIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) + return allBlocks +} + +func (s *Service) getBlocks(ctx context.Context, pageID, apiKey string, pagination int64) ([]interface{}, error) { + var ( + hasMore = true + body = &bytes.Buffer{} + blocks = make([]interface{}, 0) + cursor string + ) + + for hasMore { + url := fmt.Sprintf(endpoint, pageID) + + req, err := s.client.PrepareRequest(ctx, apiKey, http.MethodGet, url, body) + + if err != nil { + return nil, fmt.Errorf("GetBlocks: %s", err) + } + query := req.URL.Query() + + if cursor != "" { + query.Add(startCursor, cursor) + } + + query.Add(pageSize, strconv.FormatInt(pagination, 10)) + + req.URL.RawQuery = query.Encode() + + res, err := s.client.HttpClient.Do(req) + + if err != nil { + return nil, fmt.Errorf("GetBlocks: %s", err) + } + defer res.Body.Close() + + b, err := ioutil.ReadAll(res.Body) + + if err != nil { + return nil, err + } + var objects Response + if res.StatusCode != http.StatusOK { + notionErr := client.TransformHttpCodeToError(b) + if notionErr == nil { + return nil, fmt.Errorf("GetBlocks: failed http request, %d code", res.StatusCode) + } + return nil, notionErr + } + + err = json.Unmarshal(b, &objects) + + if err != nil { + return nil, err + } + + for _, b := range objects.Results { + buffer, err := json.Marshal(b) + if err != nil { + logger.Errorf("GetBlocks: failed to marshal: %s", err) + continue + } + blockMap := b.(map[string]interface{}) + switch BlockType(blockMap["type"].(string)) { + case Paragraph: + p := ParagraphBlock{} + err = json.Unmarshal(buffer, &p) + if err != nil { + continue + } + blocks = append(blocks, &p) + case Heading1: + h := Heading1Block{} + err = json.Unmarshal(buffer, &h) + if err != nil { + continue + } + blocks = append(blocks, &h) + case Heading2: + h := Heading2Block{} + err = json.Unmarshal(buffer, &h) + if err != nil { + continue + } + blocks = append(blocks, &h) + case Heading3: + h := Heading3Block{} + err = json.Unmarshal(buffer, &h) + if err != nil { + continue + } + blocks = append(blocks, &h) + case Callout: + c := CalloutBlock{} + err = json.Unmarshal(buffer, &c) + if err != nil { + continue + } + blocks = append(blocks, &c) + case Quote: + q := QuoteBlock{} + err = json.Unmarshal(buffer, &q) + if err != nil { + continue + } + blocks = append(blocks, &q) + case BulletList: + list := BulletedListBlock{} + err = json.Unmarshal(buffer, &list) + if err != nil { + continue + } + blocks = append(blocks, &list) + case NumberList: + nl := NumberedListBlock{} + err = json.Unmarshal(buffer, &nl) + if err != nil { + continue + } + blocks = append(blocks, &nl) + case Toggle: + t := ToggleBlock{} + err = json.Unmarshal(buffer, &t) + if err != nil { + continue + } + blocks = append(blocks, &t) + case Code: + c := CodeBlock{} + err = json.Unmarshal(buffer, &c) + if err != nil { + continue + } + blocks = append(blocks, &c) + case Equation: + e := EquationBlock{} + err = json.Unmarshal(buffer, &e) + if err != nil { + continue + } + blocks = append(blocks, &e) + case ToDo: + t := ToDoBlock{} + err = json.Unmarshal(buffer, &t) + if err != nil { + continue + } + blocks = append(blocks, &t) + } + } + + if !objects.HasMore { + hasMore = false + continue + } + + cursor = *objects.NextCursor + + } + return blocks, nil +} diff --git a/core/block/import/notion/api/block/retrieve_test.go b/core/block/import/notion/api/block/retrieve_test.go new file mode 100644 index 000000000..a2c346632 --- /dev/null +++ b/core/block/import/notion/api/block/retrieve_test.go @@ -0,0 +1,786 @@ +package block + +import ( + "context" + "net/http" + "net/http/httptest" + "testing" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" + "github.com/anytypeio/go-anytype-middleware/pb" + "github.com/stretchr/testify/assert" +) + +func Test_GetBlocksAndChildrenSuccessParagraph(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(` + { + "object": "list", + "results": [ + { + "object": "block", + "id": "a80ae792-b87e-48d2-b24c-c32c1e14d509", + "parent": { + "type": "page_id", + "page_id": "088b08d5-b692-4805-8338-1b147a3bff4a" + }, + "created_time": "2022-11-14T11:52:00.000Z", + "last_edited_time": "2022-11-14T12:18:00.000Z", + "created_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "last_edited_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "has_children": false, + "archived": false, + "type": "paragraph", + "paragraph": { + "rich_text": [ + { + "type": "text", + "text": { + "content": "dsadasd sdasd\n", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "dsadasd sdasd\n", + "href": null + }, + { + "type": "text", + "text": { + "content": "asd ", + "link": null + }, + "annotations": { + "bold": true, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "asd ", + "href": null + }, + { + "type": "text", + "text": { + "content": "asdasd. \n", + "link": null + }, + "annotations": { + "bold": true, + "italic": true, + "strikethrough": false, + "underline": true, + "code": false, + "color": "default" + }, + "plain_text": "asdasd. \n", + "href": null + }, + { + "type": "text", + "text": { + "content": "asdasd", + "link": null + }, + "annotations": { + "bold": true, + "italic": true, + "strikethrough": false, + "underline": true, + "code": false, + "color": "orange_background" + }, + "plain_text": "asdasd", + "href": null + } + ], + "color": "green_background" + } + } + + ], + "next_cursor": null, + "has_more": false, + "type": "block", + "block": {} + } + `)) + })) + + defer s.Close() + pageSize := int64(100) + c := client.NewClient() + c.BasePath = s.URL + + blockService := New(c) + bl, err := blockService.GetBlocksAndChildren(context.TODO(), "id", "key", pageSize, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + assert.Nil(t, err) + assert.Len(t, bl, 1) + _, ok := bl[0].(*ParagraphBlock) + assert.True(t, ok) +} + +func Test_GetBlocksAndChildrenSuccessHeading3(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(` + { + "object": "list", + "results": [ + { + "object": "block", + "id": "968c10fd-39f5-4a31-8a47-719778d9cb22", + "parent": { + "type": "page_id", + "page_id": "088b08d5-b692-4805-8338-1b147a3bff4a" + }, + "created_time": "2022-11-14T11:54:00.000Z", + "last_edited_time": "2022-11-14T11:54:00.000Z", + "created_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "last_edited_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "has_children": false, + "archived": false, + "type": "heading_3", + "heading_3": { + "rich_text": [ + { + "type": "text", + "text": { + "content": "Heading 3", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": true, + "underline": true, + "code": false, + "color": "blue_background" + }, + "plain_text": "Heading 3", + "href": null + } + ], + "is_toggleable": false, + "color": "default" + } + } + ], + "next_cursor": null, + "has_more": false, + "type": "block", + "block": {} + } + `)) + })) + + defer s.Close() + pageSize := int64(100) + c := client.NewClient() + c.BasePath = s.URL + + blockService := New(c) + bl, err := blockService.GetBlocksAndChildren(context.TODO(), "id", "key", pageSize, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + assert.Nil(t, err) + assert.Len(t, bl, 1) + _, ok := bl[0].(*Heading3Block) + assert.True(t, ok) +} + +func Test_GetBlocksAndChildrenSuccessTodo(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(` + { + "object": "list", + "results": [ + { + "object": "block", + "id": "c0c29ebb-3064-466c-b058-54f07128a1e9", + "parent": { + "type": "page_id", + "page_id": "088b08d5-b692-4805-8338-1b147a3bff4a" + }, + "created_time": "2022-11-14T11:53:00.000Z", + "last_edited_time": "2022-11-14T11:54:00.000Z", + "created_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "last_edited_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "has_children": false, + "archived": false, + "type": "to_do", + "to_do": { + "rich_text": [], + "checked": false, + "color": "default" + } + } + ], + "next_cursor": null, + "has_more": false, + "type": "block", + "block": {} + } + `)) + })) + + defer s.Close() + pageSize := int64(100) + c := client.NewClient() + c.BasePath = s.URL + + blockService := New(c) + bl, err := blockService.GetBlocksAndChildren(context.TODO(), "id", "key", pageSize, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + assert.Nil(t, err) + assert.Len(t, bl, 1) + _, ok := bl[0].(*ToDoBlock) + assert.True(t, ok) +} + +func Test_GetBlocksAndChildrenSuccessHeading2(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(` + { + "object": "list", + "results": [ + { + "object": "block", + "id": "1d5f7d59-32aa-46dc-aec7-e275fdd56752", + "parent": { + "type": "page_id", + "page_id": "088b08d5-b692-4805-8338-1b147a3bff4a" + }, + "created_time": "2022-11-14T11:54:00.000Z", + "last_edited_time": "2022-11-14T11:54:00.000Z", + "created_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "last_edited_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "has_children": false, + "archived": false, + "type": "heading_2", + "heading_2": { + "rich_text": [ + { + "type": "text", + "text": { + "content": "Heading 2", + "link": null + }, + "annotations": { + "bold": true, + "italic": true, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "Heading 2", + "href": null + } + ], + "is_toggleable": false, + "color": "default" + } + } + ], + "next_cursor": null, + "has_more": false, + "type": "block", + "block": {} + } + `)) + })) + + defer s.Close() + pageSize := int64(100) + c := client.NewClient() + c.BasePath = s.URL + + blockService := New(c) + bl, err := blockService.GetBlocksAndChildren(context.TODO(), "id", "key", pageSize, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + assert.Nil(t, err) + assert.Len(t, bl, 1) + _, ok := bl[0].(*Heading2Block) + assert.True(t, ok) +} + +func Test_GetBlocksAndChildrenSuccessBulletList(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(` + { + "object": "list", + "results": [ + { + "object": "block", + "id": "152b978d-ee32-498c-a9db-985677a6dce6", + "parent": { + "type": "page_id", + "page_id": "088b08d5-b692-4805-8338-1b147a3bff4a" + }, + "created_time": "2022-11-14T11:55:00.000Z", + "last_edited_time": "2022-11-14T11:55:00.000Z", + "created_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "last_edited_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "has_children": false, + "archived": false, + "type": "bulleted_list_item", + "bulleted_list_item": { + "rich_text": [ + { + "type": "text", + "text": { + "content": "buller", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "buller", + "href": null + } + ], + "color": "default" + } + } + ], + "next_cursor": null, + "has_more": false, + "type": "block", + "block": {} + } + `)) + })) + + defer s.Close() + pageSize := int64(100) + c := client.NewClient() + c.BasePath = s.URL + + blockService := New(c) + bl, err := blockService.GetBlocksAndChildren(context.TODO(), "id", "key", pageSize, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + assert.Nil(t, err) + assert.Len(t, bl, 1) + _, ok := bl[0].(*BulletedListBlock) + assert.True(t, ok) +} + +func Test_GetBlocksAndChildrenSuccessNumberedList(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(` + { + "object": "list", + "results": [ + { + "object": "block", + "id": "38fc4773-8b28-445c-83bf-cb8c06badf10", + "parent": { + "type": "page_id", + "page_id": "088b08d5-b692-4805-8338-1b147a3bff4a" + }, + "created_time": "2022-11-14T11:55:00.000Z", + "last_edited_time": "2022-11-14T12:17:00.000Z", + "created_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "last_edited_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "has_children": false, + "archived": false, + "type": "numbered_list_item", + "numbered_list_item": { + "rich_text": [ + { + "type": "text", + "text": { + "content": "Number", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "Number", + "href": null + } + ], + "color": "default" + } + } + ], + "next_cursor": null, + "has_more": false, + "type": "block", + "block": {} + } + `)) + })) + + defer s.Close() + pageSize := int64(100) + c := client.NewClient() + c.BasePath = s.URL + + blockService := New(c) + bl, err := blockService.GetBlocksAndChildren(context.TODO(), "id", "key", pageSize, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + assert.Nil(t, err) + assert.Len(t, bl, 1) + _, ok := bl[0].(*NumberedListBlock) + assert.True(t, ok) +} + +func Test_GetBlocksAndChildrenSuccessToggle(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(` + { + "object": "list", + "results": [ + { + "object": "block", + "id": "ac80ca02-f09c-49f9-bc6f-2079058f1923", + "parent": { + "type": "page_id", + "page_id": "088b08d5-b692-4805-8338-1b147a3bff4a" + }, + "created_time": "2022-11-14T11:55:00.000Z", + "last_edited_time": "2022-11-14T11:55:00.000Z", + "created_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "last_edited_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "has_children": false, + "archived": false, + "type": "toggle", + "toggle": { + "rich_text": [ + { + "type": "text", + "text": { + "content": "Toggle", + "link": null + }, + "annotations": { + "bold": true, + "italic": false, + "strikethrough": false, + "underline": false, + "code": true, + "color": "default" + }, + "plain_text": "Toggle", + "href": null + } + ], + "color": "default" + } + } + ], + "next_cursor": null, + "has_more": false, + "type": "block", + "block": {} + } + `)) + })) + + defer s.Close() + pageSize := int64(100) + c := client.NewClient() + c.BasePath = s.URL + + blockService := New(c) + bl, err := blockService.GetBlocksAndChildren(context.TODO(), "id", "key", pageSize, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + assert.Nil(t, err) + assert.Len(t, bl, 1) + _, ok := bl[0].(*ToggleBlock) + assert.True(t, ok) +} + +func Test_GetBlocksAndChildrenSuccessQuote(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(` + { + "object": "list", + "results": [ + { + "object": "block", + "id": "659d5d72-2a8d-4df2-9475-9bd2ac816ddd", + "parent": { + "type": "page_id", + "page_id": "088b08d5-b692-4805-8338-1b147a3bff4a" + }, + "created_time": "2022-11-14T11:55:00.000Z", + "last_edited_time": "2022-11-14T11:56:00.000Z", + "created_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "last_edited_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "has_children": false, + "archived": false, + "type": "quote", + "quote": { + "rich_text": [ + { + "type": "text", + "text": { + "content": "Quote", + "link": { + "url": "ref" + } + }, + "annotations": { + "bold": true, + "italic": false, + "strikethrough": true, + "underline": false, + "code": false, + "color": "yellow_background" + }, + "plain_text": "Quote", + "href": "ref" + } + ], + "color": "default" + } + } + ], + "next_cursor": null, + "has_more": false, + "type": "block", + "block": {} + } + `)) + })) + + defer s.Close() + pageSize := int64(100) + c := client.NewClient() + c.BasePath = s.URL + + blockService := New(c) + bl, err := blockService.GetBlocksAndChildren(context.TODO(), "id", "key", pageSize, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + assert.Nil(t, err) + assert.Len(t, bl, 1) + _, ok := bl[0].(*QuoteBlock) + assert.True(t, ok) +} + +func Test_GetBlocksAndChildrenSuccessCallout(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(` + { + "object": "list", + "results": [ + { + "object": "block", + "id": "b17fb388-715c-4f3d-841c-7492d4c29e39", + "parent": { + "type": "page_id", + "page_id": "088b08d5-b692-4805-8338-1b147a3bff4a" + }, + "created_time": "2022-11-14T11:56:00.000Z", + "last_edited_time": "2022-11-14T12:17:00.000Z", + "created_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "last_edited_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "has_children": false, + "archived": false, + "type": "callout", + "callout": { + "rich_text": [ + { + "type": "text", + "text": { + "content": "BBBBBBB", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "BBBBBBB", + "href": null + } + ], + "icon": { + "type": "file", + "file": { + "url": "url", + "expiry_time": "2022-11-14T14:38:56.733Z" + } + }, + "color": "gray_background" + } + } + ], + "next_cursor": null, + "has_more": false, + "type": "block", + "block": {} + } + `)) + })) + + defer s.Close() + pageSize := int64(100) + c := client.NewClient() + c.BasePath = s.URL + + blockService := New(c) + bl, err := blockService.GetBlocksAndChildren(context.TODO(), "id", "key", pageSize, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + assert.Nil(t, err) + assert.Len(t, bl, 1) + _, ok := bl[0].(*CalloutBlock) + assert.True(t, ok) +} + +func Test_GetBlocksAndChildrenSuccessCode(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(` + { + "object": "list", + "results": [ + { + "object": "block", + "id": "b4b694d7-aed7-4ceb-aa22-f48026b07f5d", + "parent": { + "type": "page_id", + "page_id": "088b08d5-b692-4805-8338-1b147a3bff4a" + }, + "created_time": "2022-11-14T12:22:00.000Z", + "last_edited_time": "2022-11-14T12:22:00.000Z", + "created_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "last_edited_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "has_children": false, + "archived": false, + "type": "code", + "code": { + "caption": [], + "rich_text": [ + { + "type": "text", + "text": { + "content": "Code", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "Code", + "href": null + } + ], + "language": "html" + } + } + ], + "next_cursor": null, + "has_more": false, + "type": "block", + "block": {} + } + `)) + })) + + defer s.Close() + pageSize := int64(100) + c := client.NewClient() + c.BasePath = s.URL + + blockService := New(c) + bl, err := blockService.GetBlocksAndChildren(context.TODO(), "id", "key", pageSize, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + assert.Nil(t, err) + assert.Len(t, bl, 1) + _, ok := bl[0].(*CodeBlock) + assert.True(t, ok) +} + +func Test_GetBlocksAndChildrenSuccessError(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(`{"object":"error","status":404,"code":"object_not_found","message":"Could not find block with ID: d6917e78-3212-444d-ae46-97499c021f2d. Make sure the relevant pages and databases are shared with your integration."}`)) + })) + + defer s.Close() + pageSize := int64(100) + c := client.NewClient() + c.BasePath = s.URL + + blockService := New(c) + bl, err := blockService.GetBlocksAndChildren(context.TODO(), "id", "key", pageSize, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + assert.NotNil(t, err) + assert.Empty(t, bl) +} diff --git a/core/block/import/notion/api/block/text.go b/core/block/import/notion/api/block/text.go new file mode 100644 index 000000000..6bd7f17c1 --- /dev/null +++ b/core/block/import/notion/api/block/text.go @@ -0,0 +1,325 @@ +package block + +import ( + "strings" + + "github.com/globalsign/mgo/bson" + "github.com/gogo/protobuf/types" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" + "github.com/anytypeio/go-anytype-middleware/util/pbtypes" + textUtil "github.com/anytypeio/go-anytype-middleware/util/text" +) + +type ParagraphBlock struct { + Block + Paragraph TextObjectWithChildren `json:"paragraph"` +} + +type Heading1Block struct { + Block + Heading1 HeadingObject `json:"heading_1"` +} + +type Heading2Block struct { + Block + Heading2 HeadingObject `json:"heading_2"` +} + +type Heading3Block struct { + Block + Heading3 HeadingObject `json:"heading_3"` +} + +type HeadingObject struct { + TextObject + IsToggleable bool `json:"is_toggleable"` +} + +type CalloutBlock struct { + Block + Callout CalloutObject `json:"callout"` +} + +type CalloutObject struct { + TextObjectWithChildren + Icon *api.Icon `json:"icon"` +} + +type QuoteBlock struct { + Block + Quote TextObjectWithChildren `json:"quote"` +} + +type NumberedListBlock struct { + Block + NumberedList TextObjectWithChildren `json:"bulleted_list_item"` +} + +type ToDoBlock struct { + Block + ToDo ToDoObject `json:"to_do"` +} + +type ToDoObject struct { + TextObjectWithChildren + Checked bool `json:"checked"` +} + +type BulletedListBlock struct { + Block + BulletedList TextObjectWithChildren `json:"bulleted_list_item"` +} + +type ToggleBlock struct { + Block + Toggle TextObjectWithChildren `json:"toggle"` +} + +type TextObjectWithChildren struct { + TextObject + Children []interface{} `json:"children"` +} + +type TextObject struct { + RichText []api.RichText `json:"rich_text"` + Color string `json:"color"` +} + +func (c *CalloutObject) GetCalloutBlocks(childIds []string) ([]*model.Block, []string) { + calloutBlocks, blockIDs := c.GetTextBlocks(model.BlockContentText_Callout, childIds, nil, nil, nil, nil) + for _, cb := range calloutBlocks { + text, ok := cb.Content.(*model.BlockContentOfText) + if ok { + if c.Icon != nil { + if c.Icon.Emoji != nil { + text.Text.IconEmoji = *c.Icon.Emoji + } + if c.Icon.Type == api.External && c.Icon.External != nil { + text.Text.IconImage = c.Icon.External.URL + } + if c.Icon.Type == api.File && c.Icon.File != nil { + text.Text.IconImage = c.Icon.File.URL + } + } + cb.Content = text + } + } + return calloutBlocks, blockIDs +} + +func (t *TextObject) GetTextBlocks(style model.BlockContentTextStyle, childIds []string, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID map[string]string) ([]*model.Block, []string) { + marks := []*model.BlockContentTextMark{} + id := bson.NewObjectId().Hex() + allBlocks := make([]*model.Block, 0) + allIds := make([]string, 0) + var text strings.Builder + for _, rt := range t.RichText { + if rt.Type == api.Text { + marks = append(marks, t.handleTextType(rt, &text, notionPageIdsToAnytype, notionDatabaseIdsToAnytype)...) + } + if rt.Type == api.Mention { + marks = append(marks, t.handleMentionType(rt, &text, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID)...) + } + if rt.Type == api.Equation { + eqBlock := rt.Equation.HandleEquation() + allBlocks = append(allBlocks, eqBlock) + allIds = append(allIds, eqBlock.Id) + } + } + var backgroundColor string + if strings.Contains(t.Color, api.NotionBackgroundColorPrefix) { + backgroundColor = api.NotionColorToAnytype[t.Color] + } + + if len(t.RichText) == 1 && t.RichText[0].Type == api.Equation { + return allBlocks, allIds + } + allBlocks = append(allBlocks, &model.Block{ + Id: id, + ChildrenIds: childIds, + BackgroundColor: backgroundColor, + Content: &model.BlockContentOfText{ + Text: &model.BlockContentText{ + Text: text.String(), + Style: style, + Marks: &model.BlockContentTextMarks{Marks: marks}, + Checked: false, + Color: api.NotionColorToAnytype[t.Color], + }, + }, + }) + for _, b := range allBlocks { + allIds = append(allIds, b.Id) + } + return allBlocks, allIds +} + +func (t *TextObject) handleTextType(rt api.RichText, text *strings.Builder, notionPageIdsToAnytype, notionDatabaseIdsToAnytype map[string]string) []*model.BlockContentTextMark { + marks := []*model.BlockContentTextMark{} + from := textUtil.UTF16RuneCountString(text.String()) + if rt.Text != nil && rt.Text.Link != nil && rt.Text.Link.Url != "" { + text.WriteString(rt.Text.Content) + } else { + text.WriteString(rt.PlainText) + } + to := textUtil.UTF16RuneCountString(text.String()) + if rt.Text != nil && rt.Text.Link != nil && rt.Text.Link.Url != "" { + url := strings.Trim(rt.Text.Link.Url, "/") + if databaseID, ok := notionDatabaseIdsToAnytype[url]; ok { + url = databaseID + } + if pageID, ok := notionPageIdsToAnytype[url]; ok { + url = pageID + } + marks = append(marks, &model.BlockContentTextMark{ + Range: &model.Range{ + From: int32(from), + To: int32(to), + }, + Type: model.BlockContentTextMark_Link, + Param: url, + }) + } + marks = append(marks, rt.BuildMarkdownFromAnnotations(int32(from), int32(to))...) + return marks +} + +func (t *TextObject) handleMentionType(rt api.RichText, text *strings.Builder, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID map[string]string) []*model.BlockContentTextMark { + if rt.Mention.Type == api.UserMention { + return t.handleUserMention(rt, text) + } + if rt.Mention.Type == api.Database { + return t.handleDatabaseMention(rt, text, notionDatabaseIdsToAnytype, databaseNameToID) + } + if rt.Mention.Type == api.Page { + return t.handlePageMention(rt, text, notionPageIdsToAnytype, pageNameToID) + } + if rt.Mention.Type == api.Date { + return t.handleDateMention(rt, text) + } + if rt.Mention.Type == api.LinkPreview { + return t.handleLinkPreviewMention(rt, text) + } + return nil +} + +func (t *TextObject) handleUserMention(rt api.RichText, text *strings.Builder) []*model.BlockContentTextMark { + from := textUtil.UTF16RuneCountString(text.String()) + text.WriteString(rt.Mention.User.Name) + to := textUtil.UTF16RuneCountString(text.String()) + return rt.BuildMarkdownFromAnnotations(int32(from), int32(to)) +} + +func (t *TextObject) handleDatabaseMention(rt api.RichText, text *strings.Builder, notionDatabaseIdsToAnytype, databaseNameToID map[string]string) []*model.BlockContentTextMark { + if notionDatabaseIdsToAnytype == nil { + return nil + } + from := textUtil.UTF16RuneCountString(text.String()) + text.WriteString(databaseNameToID[rt.Mention.Database.ID]) + to := textUtil.UTF16RuneCountString(text.String()) + marks := rt.BuildMarkdownFromAnnotations(int32(from), int32(to)) + marks = append(marks, &model.BlockContentTextMark{ + Range: &model.Range{ + From: int32(from), + To: int32(to), + }, + Type: model.BlockContentTextMark_Mention, + Param: notionDatabaseIdsToAnytype[rt.Mention.Database.ID], + }) + return marks +} + +func (t *TextObject) handlePageMention(rt api.RichText, text *strings.Builder, notionPageIdsToAnytype, pageNameToID map[string]string) []*model.BlockContentTextMark { + if notionPageIdsToAnytype == nil { + return nil + } + from := textUtil.UTF16RuneCountString(text.String()) + text.WriteString(pageNameToID[rt.Mention.Page.ID]) + to := textUtil.UTF16RuneCountString(text.String()) + marks := rt.BuildMarkdownFromAnnotations(int32(from), int32(to)) + marks = append(marks, &model.BlockContentTextMark{ + Range: &model.Range{ + From: int32(from), + To: int32(to), + }, + Type: model.BlockContentTextMark_Mention, + Param: notionPageIdsToAnytype[rt.Mention.Page.ID], + }) + return marks +} + +func (t *TextObject) handleDateMention(rt api.RichText, text *strings.Builder) []*model.BlockContentTextMark { + var textDate string + if rt.Mention.Date.Start != "" { + textDate = rt.Mention.Date.Start + } + if rt.Mention.Date.End != "" { + textDate += " " + rt.Mention.Date.End + } + from := textUtil.UTF16RuneCountString(text.String()) + text.WriteString(textDate) + to := textUtil.UTF16RuneCountString(text.String()) + marks := rt.BuildMarkdownFromAnnotations(int32(from), int32(to)) + return marks +} + +func (t *TextObject) handleLinkPreviewMention(rt api.RichText, text *strings.Builder) []*model.BlockContentTextMark { + from := textUtil.UTF16RuneCountString(text.String()) + text.WriteString(rt.Mention.LinkPreview.Url) + to := textUtil.UTF16RuneCountString(text.String()) + marks := rt.BuildMarkdownFromAnnotations(int32(from), int32(to)) + marks = append(marks, &model.BlockContentTextMark{ + Range: &model.Range{ + From: int32(from), + To: int32(to), + }, + Type: model.BlockContentTextMark_Link, + }) + return marks +} + +type CodeBlock struct { + Block + Code CodeObject `json:"code"` +} + +type CodeObject struct { + RichText []api.RichText `json:"rich_text"` + Caption []api.RichText `json:"caption"` + Language string `json:"language"` +} + +func (c *CodeObject) GetCodeBlock() *model.Block { + id := bson.NewObjectId().Hex() + bl := &model.Block{ + Id: id, + Fields: &types.Struct{ + Fields: map[string]*types.Value{"lang": pbtypes.String(c.Language)}, + }, + } + marks := []*model.BlockContentTextMark{} + var code string + for _, rt := range c.RichText { + from := textUtil.UTF16RuneCountString(code) + code += rt.PlainText + to := textUtil.UTF16RuneCountString(code) + marks = append(marks, rt.BuildMarkdownFromAnnotations(int32(from), int32(to))...) + } + bl.Content = &model.BlockContentOfText{ + Text: &model.BlockContentText{ + Text: code, + Style: model.BlockContentText_Code, + Marks: &model.BlockContentTextMarks{ + Marks: marks, + }, + }, + } + return bl +} + +type EquationBlock struct { + Block + Equation api.EquationObject `json:"equation"` +} diff --git a/core/block/import/notion/api/block/text_test.go b/core/block/import/notion/api/block/text_test.go new file mode 100644 index 000000000..eaa3f285b --- /dev/null +++ b/core/block/import/notion/api/block/text_test.go @@ -0,0 +1,182 @@ +package block + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" +) + +func Test_GetTextBlocksTextSuccess(t *testing.T) { + to := &TextObject{ + RichText: []api.RichText{ + { + Type: api.Text, + PlainText: "test", + }, + { + Type: api.Text, + PlainText: "test2", + }, + }, + Color: api.RedBackGround, + } + + bl, _ := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, nil, nil, nil, nil) + assert.Len(t, bl, 1) + assert.Equal(t, bl[0].GetText().Style, model.BlockContentText_Paragraph) + assert.Equal(t, bl[0].BackgroundColor, api.AnytypeRed) + assert.Equal(t, bl[0].GetText().Text, "testtest2") +} + +func Test_GetTextBlocksTextUserMention(t *testing.T) { + to := &TextObject{ + RichText: []api.RichText{ + { + Type: api.Mention, + Mention: &api.MentionObject{ + Type: api.UserMention, + User: &api.User{ + ID: "id", + Name: "Nastya", + }, + }, + }, + }, + } + + bl, _ := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, nil, nil, nil, nil) + assert.Len(t, bl, 1) + assert.Equal(t, bl[0].GetText().Style, model.BlockContentText_Paragraph) + assert.Len(t, bl[0].GetText().Marks.Marks, 0) + assert.Equal(t, bl[0].GetText().Text, "Nastya") +} + +func Test_GetTextBlocksTextPageMention(t *testing.T) { + to := &TextObject{ + RichText: []api.RichText{ + { + Type: api.Mention, + Mention: &api.MentionObject{ + Type: api.Page, + Page: &api.PageMention{ + ID: "notionID", + }, + }, + }, + }, + } + + bl, _ := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, map[string]string{"notionID": "anytypeID"}, nil, map[string]string{"notionID": "Page"}, nil) + assert.Len(t, bl, 1) + assert.Equal(t, bl[0].GetText().Style, model.BlockContentText_Paragraph) + assert.Len(t, bl[0].GetText().Marks.Marks, 1) + assert.Equal(t, bl[0].GetText().Marks.Marks[0].Type, model.BlockContentTextMark_Mention) + assert.Equal(t, bl[0].GetText().Text, "Page") +} + +func Test_GetTextBlocksDatabaseMention(t *testing.T) { + to := &TextObject{ + RichText: []api.RichText{ + { + Type: api.Mention, + Mention: &api.MentionObject{ + Type: api.Database, + Database: &api.DatabaseMention{ + ID: "notionID", + }, + }, + }, + }, + } + + bl, _ := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, nil, map[string]string{"notionID": "anytypeID"}, nil, map[string]string{"notionID": "Database"}) + assert.Len(t, bl, 1) + assert.Equal(t, bl[0].GetText().Style, model.BlockContentText_Paragraph) + assert.Len(t, bl[0].GetText().Marks.Marks, 1) + assert.Equal(t, bl[0].GetText().Marks.Marks[0].Type, model.BlockContentTextMark_Mention) + assert.Equal(t, bl[0].GetText().Text, "Database") +} + +func Test_GetTextBlocksDateMention(t *testing.T) { + to := &TextObject{ + RichText: []api.RichText{ + { + Type: api.Mention, + Mention: &api.MentionObject{ + Type: api.Date, + Date: &api.DateObject{ + Start: "2022-11-14", + }, + }, + }, + }, + } + + bl, _ := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, nil, nil, nil, nil) + assert.Len(t, bl, 1) + assert.Equal(t, bl[0].GetText().Style, model.BlockContentText_Paragraph) + assert.Len(t, bl[0].GetText().Marks.Marks, 0) + assert.Equal(t, bl[0].GetText().Text, "2022-11-14") +} + +func Test_GetTextBlocksLinkPreview(t *testing.T) { + to := &TextObject{ + RichText: []api.RichText{ + { + Type: api.Mention, + Mention: &api.MentionObject{ + Type: api.LinkPreview, + LinkPreview: &api.Link{ + Url: "ref", + }, + }, + }, + }, + } + + bl, _ := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, nil, nil, nil, nil) + assert.Len(t, bl, 1) + assert.Equal(t, bl[0].GetText().Style, model.BlockContentText_Paragraph) + assert.NotNil(t, bl[0].GetText().Marks) + assert.Len(t, bl[0].GetText().Marks.Marks, 1) + assert.Equal(t, bl[0].GetText().Marks.Marks[0].Type, model.BlockContentTextMark_Link) + assert.Equal(t, bl[0].GetText().Text, "ref") +} + +func Test_GetTextBlocksEquation(t *testing.T) { + to := &TextObject{ + RichText: []api.RichText{ + { + Type: api.Equation, + Equation: &api.EquationObject{ + Expression: "Equation", + }, + }, + }, + } + + bl, _ := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, nil, nil, nil, nil) + assert.Len(t, bl, 1) + assert.NotNil(t, bl[0].GetLatex()) + assert.Equal(t, bl[0].GetLatex().Text, "Equation") +} + +func Test_GetCodeBlocksSuccess(t *testing.T) { + co := &CodeBlock{ + Code: CodeObject{ + RichText: []api.RichText{ + { + Type: api.Text, + PlainText: "Code", + }, + }, + Language: "Go", + }, + } + bl := co.Code.GetCodeBlock() + assert.NotNil(t, bl) + assert.Equal(t, bl.GetText().Text, "Code") +} \ No newline at end of file diff --git a/core/block/import/notion/api/commonobjects.go b/core/block/import/notion/api/commonobjects.go index 069990cb9..02151e0cd 100644 --- a/core/block/import/notion/api/commonobjects.go +++ b/core/block/import/notion/api/commonobjects.go @@ -3,49 +3,215 @@ package api import ( "bytes" "encoding/json" + "strings" "time" + + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" + "github.com/globalsign/mgo/bson" ) type richTextType string const ( - Text richTextType = "text" - Mention richTextType = "mention" - Equation richTextType = "equation" + Text richTextType = "text" + Mention richTextType = "mention" + Equation richTextType = "equation" + NotionBackgroundColorPrefix = "background" ) // RichText represent RichText object from Notion https://developers.notion.com/reference/rich-text type RichText struct { - Type richTextType `json:"type,omitempty"` - Text *TextObject `json:"text,omitempty"` - Annotations *Annotations `json:"annotations,omitempty"` - PlainText string `json:"plain_text,omitempty"` - Href string `json:"href,omitempty"` + Type richTextType `json:"type,omitempty"` + Text *TextObject `json:"text,omitempty"` + Mention *MentionObject `json:"mention,omitempty"` + Equation *EquationObject `json:"equation,omitempty"` + Annotations *Annotations `json:"annotations,omitempty"` + PlainText string `json:"plain_text,omitempty"` + Href string `json:"href,omitempty"` } type TextObject struct { Content string `json:"content"` Link *Link `json:"link,omitempty"` } +type EquationObject struct { + Expression string `json:"expression"` +} + +func (e *EquationObject) HandleEquation() *model.Block { + id := bson.NewObjectId().Hex() + return &model.Block{ + Id: id, + ChildrenIds: []string{}, + Content: &model.BlockContentOfLatex{ + Latex: &model.BlockContentLatex{ + Text: e.Expression, + }, + }, + } +} type Link struct { Url string `json:"url,omitempty"` } -type Color string +func (rt *RichText) BuildMarkdownFromAnnotations(from, to int32) []*model.BlockContentTextMark { + marks := []*model.BlockContentTextMark{} + if rt.Annotations == nil { + return marks + } + if rt.Annotations.Bold { + marks = append(marks, &model.BlockContentTextMark{ + Range: &model.Range{ + From: from, + To: to, + }, + Type: model.BlockContentTextMark_Bold, + }) + } + if rt.Annotations.Italic { + marks = append(marks, &model.BlockContentTextMark{ + Range: &model.Range{ + From: from, + To: to, + }, + Type: model.BlockContentTextMark_Italic, + }) + } + if rt.Annotations.Strikethrough { + marks = append(marks, &model.BlockContentTextMark{ + Range: &model.Range{ + From: from, + To: to, + }, + Type: model.BlockContentTextMark_Strikethrough, + }) + } + if rt.Annotations.Underline { + marks = append(marks, &model.BlockContentTextMark{ + Range: &model.Range{ + From: from, + To: to, + }, + Type: model.BlockContentTextMark_Underscored, + }) + } + if rt.Annotations.Color != "" { + markType := model.BlockContentTextMark_TextColor + if strings.Contains(rt.Annotations.Color, NotionBackgroundColorPrefix) { + markType = model.BlockContentTextMark_BackgroundColor + } + marks = append(marks, &model.BlockContentTextMark{ + Range: &model.Range{ + From: from, + To: to, + }, + Type: markType, + Param: NotionColorToAnytype[rt.Annotations.Color], + }) + } + + if rt.Annotations.Code { + marks = append(marks, &model.BlockContentTextMark{ + Range: &model.Range{ + From: from, + To: to, + }, + Type: model.BlockContentTextMark_Keyboard, + }) + } + + return marks +} + +type mentionType string const ( - DefaultColor Color = "default" - Gray Color = "gray" - Brown Color = "brown" - Orange Color = "orange" - Yellow Color = "yellow" - Green Color = "green" - Blue Color = "blue" - Purple Color = "purple" - Pink Color = "pink" - Red Color = "red" + UserMention mentionType = "user" + Page mentionType = "page" + Database mentionType = "database" + Date mentionType = "date" + LinkPreview mentionType = "link_preview" ) +type MentionObject struct { + Type mentionType `json:"type,omitempty"` + User *User `json:"user,omitempty"` + Page *PageMention `json:"page,omitempty"` + Database *DatabaseMention `json:"database,omitempty"` + Date *DateObject `json:"date,omitempty"` + LinkPreview *Link `json:"link_preview,omitempty"` +} + +type PageMention struct { + ID string `json:"id"` +} + +type DatabaseMention struct { + ID string `json:"id"` +} + +type DateObject struct { + Start string `json:"start"` + End string `json:"end"` + TimeZone string `json:"time_zone"` +} + +const ( + DefaultColor string = "default" + Gray string = "gray" + Brown string = "brown" + Orange string = "orange" + Yellow string = "yellow" + Green string = "green" + Blue string = "blue" + Purple string = "purple" + Pink string = "pink" + Red string = "red" + + GrayBackGround string = "gray_background" + BrownBackGround string = "brown_background" + OrangeBackGround string = "orange_background" + YellowBackGround string = "yellow_background" + GreenBackGround string = "green_background" + BlueBackGround string = "blue_background" + PurpleBackGround string = "purple_background" + PinkBackGround string = "pink_background" + RedBackGround string = "red_background" + + AnytypeGray string = "gray" + AnytypeOrange string = "orange" + AnytypeYellow string = "yellow" + AnytypeGreen string = "lime" + AnytypeBlue string = "blue" + AnytypePurple string = "purple" + AnytypePink string = "pink" + AnytypeRed string = "red" + AnytypeDefault string = "default" +) + +var NotionColorToAnytype = map[string]string{ + DefaultColor: AnytypeDefault, + Gray: AnytypeGray, + Brown: "", + Orange: AnytypeOrange, + Yellow: AnytypeYellow, + Green: AnytypeGreen, + Blue: AnytypeBlue, + Purple: AnytypePurple, + Pink: AnytypePink, + Red: AnytypeRed, + + GrayBackGround: AnytypeGray, + BrownBackGround: "", + OrangeBackGround: AnytypeOrange, + YellowBackGround: AnytypeYellow, + GreenBackGround: AnytypeGreen, + BlueBackGround: AnytypeBlue, + PurpleBackGround: AnytypePurple, + PinkBackGround: AnytypePink, + RedBackGround: AnytypeRed, +} + type Annotations struct { Bold bool `json:"bold"` Italic bool `json:"italic"` @@ -64,8 +230,8 @@ const ( // FileObject represent File Object object from Notion https://developers.notion.com/reference/file-object type FileObject struct { - Name string `json:"name"` - Type FileType `json:"type"` + Name string `json:"name"` + Type FileType `json:"type"` File FileProperty `json:"file,omitempty"` External FileProperty `json:"external,omitempty"` } @@ -76,37 +242,37 @@ type FileProperty struct { } func (o *FileProperty) UnmarshalJSON(data []byte) error { - fp := make(map[string]interface{},0) - if err := json.Unmarshal(data, &fp); err != nil { - return err - } + fp := make(map[string]interface{}, 0) + if err := json.Unmarshal(data, &fp); err != nil { + return err + } if url, ok := fp["url"].(string); ok { o.URL = url } if t, ok := fp["expiry_time"].(*time.Time); ok { o.ExpiryTime = t } - return nil + return nil } type Icon struct { - Type FileType `json:"type"` - Emoji *string `json:"emoji,omitempty"` - File *FileObject `json:"file,omitempty"` - External *FileObject `json:"external,omitempty"` + Type FileType `json:"type"` + Emoji *string `json:"emoji,omitempty"` + File *FileProperty `json:"file,omitempty"` + External *FileProperty `json:"external,omitempty"` } type userType string // User represent User Object object from Notion https://developers.notion.com/reference/user type User struct { - Object string `json:"object,omitempty"` - ID string `json:"id"` - Type userType `json:"type,omitempty"` - Name string `json:"name,omitempty"` - AvatarURL string `json:"avatar_url,omitempty"` - Person *Person `json:"person,omitempty"` - Bot *struct{} `json:"bot,omitempty"` + Object string `json:"object,omitempty"` + ID string `json:"id"` + Type userType `json:"type,omitempty"` + Name string `json:"name,omitempty"` + AvatarURL string `json:"avatar_url,omitempty"` + Person *Person `json:"person,omitempty"` + Bot *struct{} `json:"bot,omitempty"` } type Person struct { @@ -114,8 +280,8 @@ type Person struct { } type Parent struct { - Type string `json:"type,omitempty"` - PageID string `json:"page_id"` + Type string `json:"type,omitempty"` + PageID string `json:"page_id"` DatabaseID string `json:"database_id"` } diff --git a/core/block/import/notion/api/commonobjects_test.go b/core/block/import/notion/api/commonobjects_test.go new file mode 100644 index 000000000..b560733ee --- /dev/null +++ b/core/block/import/notion/api/commonobjects_test.go @@ -0,0 +1,105 @@ +package api + +import ( + "testing" + + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" + "github.com/stretchr/testify/assert" +) + +func Test_BuildMarkdownFromAnnotationsBold(t *testing.T) { + rt := &RichText{ + Annotations: &Annotations{ + Bold: true, + Italic: false, + Strikethrough: false, + Underline: false, + Code: false, + Color: "", + }, + } + marks := rt.BuildMarkdownFromAnnotations(0, 5) + assert.Len(t, marks, 1) + assert.Equal(t, marks[0].Type, model.BlockContentTextMark_Bold) +} + +func Test_BuildMarkdownFromAnnotationsItalic(t *testing.T) { + rt := &RichText{ + Annotations: &Annotations{ + Bold: false, + Italic: true, + Strikethrough: false, + Underline: false, + Code: false, + Color: "", + }, + } + marks := rt.BuildMarkdownFromAnnotations(0, 5) + assert.Len(t, marks, 1) + assert.Equal(t, marks[0].Type, model.BlockContentTextMark_Italic) +} + +func Test_BuildMarkdownFromAnnotationsStrikethrough(t *testing.T) { + rt := &RichText{ + Annotations: &Annotations{ + Bold: false, + Italic: false, + Strikethrough: true, + Underline: false, + Code: false, + Color: "", + }, + } + marks := rt.BuildMarkdownFromAnnotations(0, 5) + assert.Len(t, marks, 1) + assert.Equal(t, marks[0].Type, model.BlockContentTextMark_Strikethrough) +} + +func Test_BuildMarkdownFromAnnotationsUnderline(t *testing.T) { + rt := &RichText{ + Annotations: &Annotations{ + Bold: false, + Italic: false, + Strikethrough: false, + Underline: true, + Code: false, + Color: "", + }, + } + marks := rt.BuildMarkdownFromAnnotations(0, 5) + assert.Len(t, marks, 1) + assert.Equal(t, marks[0].Type, model.BlockContentTextMark_Underscored) +} + +func Test_BuildMarkdownFromAnnotationsTwoMarks(t *testing.T) { + rt := &RichText{ + Annotations: &Annotations{ + Bold: true, + Italic: true, + Strikethrough: false, + Underline: false, + Code: false, + Color: "", + }, + } + marks := rt.BuildMarkdownFromAnnotations(0, 5) + assert.Len(t, marks, 2) + assert.Equal(t, marks[0].Type, model.BlockContentTextMark_Bold) + assert.Equal(t, marks[1].Type, model.BlockContentTextMark_Italic) +} + +func Test_BuildMarkdownFromAnnotationsColor(t *testing.T) { + rt := &RichText{ + Annotations: &Annotations{ + Bold: false, + Italic: false, + Strikethrough: false, + Underline: false, + Code: false, + Color: "red", + }, + } + marks := rt.BuildMarkdownFromAnnotations(0, 5) + assert.Len(t, marks, 1) + assert.Equal(t, marks[0].Param, "red") +} \ No newline at end of file diff --git a/core/block/import/notion/api/database/database.go b/core/block/import/notion/api/database/database.go index d5951d3e2..c29e14a5b 100644 --- a/core/block/import/notion/api/database/database.go +++ b/core/block/import/notion/api/database/database.go @@ -41,7 +41,7 @@ type Database struct { IsInline bool `json:"is_inline"` Archived bool `json:"archived"` Icon *api.Icon `json:"icon,omitempty"` - Cover *block.Image `json:"cover,omitempty"` + Cover *block.ImageBlock `json:"cover,omitempty"` } func (p *Database) GetObjectType() string { @@ -49,19 +49,23 @@ func (p *Database) GetObjectType() string { } // GetDatabase makes snaphots from notion Database objects -func (ds *Service) GetDatabase(ctx context.Context, mode pb.RpcObjectImportRequestMode, databases []Database) *converter.Response { +func (ds *Service) GetDatabase(ctx context.Context, mode pb.RpcObjectImportRequestMode, databases []Database) (*converter.Response, map[string]string, map[string]string) { convereterError := converter.ConvertError{} return ds.mapDatabasesToSnaphots(ctx, mode, databases, convereterError) } -func (ds *Service) mapDatabasesToSnaphots(ctx context.Context, mode pb.RpcObjectImportRequestMode, databases []Database, convereterError converter.ConvertError) *converter.Response { - var allSnapshots = make([]*converter.Snapshot, 0) +func (ds *Service) mapDatabasesToSnaphots(ctx context.Context, mode pb.RpcObjectImportRequestMode, databases []Database, convereterError converter.ConvertError) (*converter.Response, map[string]string, map[string]string) { + var ( + allSnapshots = make([]*converter.Snapshot, 0) + notionIdsToAnytype = make(map[string]string, 0) + databaseNameToID = make(map[string]string, 0) + ) for _, d := range databases { tid, err := threads.ThreadCreateID(thread.AccessControlled, smartblock.SmartBlockTypePage) if err != nil { convereterError.Add(d.ID, err) if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return &converter.Response{Error: convereterError} + return &converter.Response{Error: convereterError}, nil, nil } else { continue } @@ -73,11 +77,13 @@ func (ds *Service) mapDatabasesToSnaphots(ctx context.Context, mode pb.RpcObject FileName: d.URL, Snapshot: snapshot, }) + notionIdsToAnytype[d.ID] = tid.String() + databaseNameToID[d.ID] = pbtypes.GetString(snapshot.Details, bundle.RelationKeyName.String()) } if convereterError.IsEmpty() { - return &converter.Response{Snapshots: allSnapshots, Error: nil} + return &converter.Response{Snapshots: allSnapshots, Error: nil}, notionIdsToAnytype, databaseNameToID } - return &converter.Response{Snapshots: allSnapshots, Error: convereterError} + return &converter.Response{Snapshots: allSnapshots, Error: convereterError}, notionIdsToAnytype, databaseNameToID } func (ds *Service) transformDatabase(d Database) *model.SmartBlockSnapshotBase { diff --git a/core/block/import/notion/api/page/page.go b/core/block/import/notion/api/page/page.go index 59780ac77..6d34a5022 100644 --- a/core/block/import/notion/api/page/page.go +++ b/core/block/import/notion/api/page/page.go @@ -3,6 +3,9 @@ package page import ( "context" + "github.com/gogo/protobuf/types" + "github.com/textileio/go-threads/core/thread" + "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/block" @@ -14,24 +17,30 @@ import ( "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" "github.com/anytypeio/go-anytype-middleware/pkg/lib/threads" "github.com/anytypeio/go-anytype-middleware/util/pbtypes" - "github.com/gogo/protobuf/types" - "github.com/textileio/go-threads/core/thread" ) -const ObjectType = "page" +const ( + ObjectType = "page" + pageSize = 100 +) type Service struct { propertyService *property.Service - detailSetter *property.DetailValueSetter + detailSetter *property.DetailValueSetter + blockService *block.Service + client *client.Client } // New is a constructor for Service func New(client *client.Client) *Service { return &Service{ propertyService: property.New(client), - detailSetter: property.NewDetailSetter(), + detailSetter: property.NewDetailSetter(), + blockService: block.New(client), + client: client, } } + // Page represents Page object from notion https://developers.notion.com/reference/page type Page struct { Object string `json:"object"` @@ -44,7 +53,7 @@ type Page struct { Properties property.Properties `json:"properties"` Archived bool `json:"archived"` Icon *api.Icon `json:"icon,omitempty"` - Cover *block.Image `json:"cover,omitempty"` + Cover *block.ImageBlock `json:"cover,omitempty"` URL string `json:"url,omitempty"` } @@ -53,13 +62,14 @@ func (p *Page) GetObjectType() string { } // GetPages transform Page objects from Notion to snaphots -func (ds *Service) GetPages(ctx context.Context, apiKey string, mode pb.RpcObjectImportRequestMode, pages []Page) *converter.Response { +func (ds *Service) GetPages(ctx context.Context, apiKey string, mode pb.RpcObjectImportRequestMode, pages []Page, notionDatabaseIdsToAnytype, databaseNameToID map[string]string) *converter.Response { convereterError := converter.ConvertError{} - return ds.mapPagesToSnaphots(ctx, apiKey, mode, pages, convereterError) + return ds.mapPagesToSnaphots(ctx, apiKey, mode, pages, convereterError, notionDatabaseIdsToAnytype, databaseNameToID) } -func (ds *Service) mapPagesToSnaphots(ctx context.Context, apiKey string, mode pb.RpcObjectImportRequestMode, pages []Page, convereterError converter.ConvertError) *converter.Response { +func (ds *Service) mapPagesToSnaphots(ctx context.Context, apiKey string, mode pb.RpcObjectImportRequestMode, pages []Page, convereterError converter.ConvertError, notionDatabaseIdsToAnytype, databaseNameToID map[string]string) *converter.Response { var allSnapshots = make([]*converter.Snapshot, 0) + var notionPagesIdsToAnytype = make(map[string]string, 0) for _, p := range pages { tid, err := threads.ThreadCreateID(thread.AccessControlled, smartblock.SmartBlockTypePage) if err != nil { @@ -70,7 +80,10 @@ func (ds *Service) mapPagesToSnaphots(ctx context.Context, apiKey string, mode p continue } } - snapshot, ce := ds.transformPages(apiKey, p, mode) + notionPagesIdsToAnytype[p.ID] = tid.String() + } + for _, p := range pages { + snapshot, ce := ds.transformPages(ctx, apiKey, p, mode, notionPagesIdsToAnytype, notionDatabaseIdsToAnytype, databaseNameToID) if ce != nil { convereterError.Merge(*ce) if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { @@ -79,20 +92,20 @@ func (ds *Service) mapPagesToSnaphots(ctx context.Context, apiKey string, mode p continue } } - + allSnapshots = append(allSnapshots, &converter.Snapshot{ - Id: tid.String(), + Id: notionPagesIdsToAnytype[p.ID], FileName: p.URL, Snapshot: snapshot, }) } if convereterError.IsEmpty() { - return &converter.Response{Snapshots: allSnapshots, Error: nil} + return &converter.Response{Snapshots: allSnapshots, Error: nil} } return &converter.Response{Snapshots: allSnapshots, Error: convereterError} } -func (ds *Service) transformPages(apiKey string, d Page, mode pb.RpcObjectImportRequestMode) (*model.SmartBlockSnapshotBase, *converter.ConvertError) { +func (ds *Service) transformPages(ctx context.Context, apiKey string, d Page, mode pb.RpcObjectImportRequestMode, notionPagesIdsToAnytype, notionDatabaseIdsToAnytype, databaseNameToID map[string]string) (*model.SmartBlockSnapshotBase, *converter.ConvertError) { details := make(map[string]*types.Value, 0) details[bundle.RelationKeySource.String()] = pbtypes.String(d.URL) if d.Icon != nil && d.Icon.Emoji != nil { @@ -100,17 +113,31 @@ func (ds *Service) transformPages(apiKey string, d Page, mode pb.RpcObjectImport } details[bundle.RelationKeyIsArchived.String()] = pbtypes.Bool(d.Archived) - relations, ce := ds.handlePageProperties(apiKey, d.ID, d.Properties, details, mode) + var ( + allErrors = &converter.ConvertError{} + relations []*model.RelationLink + ) + relations, pageNameToID, ce := ds.handlePageProperties(apiKey, d.ID, d.Properties, details, mode) if ce != nil { + allErrors.Merge(*ce) if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return nil, ce + return nil, allErrors } } + + notionBlocks, blocksAndChildrenErr := ds.blockService.GetBlocksAndChildren(ctx, d.ID, apiKey, pageSize, mode) + if blocksAndChildrenErr != nil { + allErrors.Merge(*blocksAndChildrenErr) + if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + return nil, allErrors + } + } + + anytypeBlocks := ds.blockService.MapNotionBlocksToAnytype(notionBlocks, notionPagesIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) snapshot := &model.SmartBlockSnapshotBase{ - Blocks: []*model.Block{}, - Details: &types.Struct{Fields: details}, - ObjectTypes: []string{bundle.TypeKeyPage.URL()}, - Collections: nil, + Blocks: anytypeBlocks, + Details: &types.Struct{Fields: details}, + ObjectTypes: []string{bundle.TypeKeyPage.URL()}, RelationLinks: relations, } @@ -118,28 +145,34 @@ func (ds *Service) transformPages(apiKey string, d Page, mode pb.RpcObjectImport } // handlePageProperties gets properties values by their ids from notion api and transforms them to Details and RelationLinks -func (ds *Service) handlePageProperties(apiKey, pageID string, p property.Properties, d map[string]*types.Value, mode pb.RpcObjectImportRequestMode) ([]*model.RelationLink, *converter.ConvertError) { +func (ds *Service) handlePageProperties(apiKey, pageID string, p property.Properties, d map[string]*types.Value, mode pb.RpcObjectImportRequestMode) ([]*model.RelationLink, map[string]string, *converter.ConvertError) { ce := converter.ConvertError{} relations := make([]*model.RelationLink, 0) + pageNameToID := make(map[string]string, 0) for k, v := range p { object, err := ds.propertyService.GetPropertyObject(context.TODO(), pageID, v.GetID(), apiKey, v.GetPropertyType()) if err != nil { ce.Add("property: " + v.GetID(), err) if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return relations, &ce + return relations, pageNameToID, &ce } } err = ds.detailSetter.SetDetailValue(k, v.GetPropertyType(), object, d) if err != nil && mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { ce.Add("property: " + v.GetID(), err) if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return relations, &ce + return relations, pageNameToID, &ce } } relations = append(relations, &model.RelationLink{ Key: k, Format: v.GetFormat(), }) + if v.GetPropertyType() == property.PropertyConfigTypeTitle { + if name, ok := d[bundle.RelationKeyName.String()]; ok { + pageNameToID[pageID] = name.GetStringValue() + } + } } - return relations, nil + return relations, pageNameToID, nil } diff --git a/core/block/import/notion/api/page/page_test.go b/core/block/import/notion/api/page/page_test.go index 58f455dff..f144b4246 100644 --- a/core/block/import/notion/api/page/page_test.go +++ b/core/block/import/notion/api/page/page_test.go @@ -25,7 +25,7 @@ func Test_handlePagePropertiesSelect(t *testing.T) { p := property.SelectProperty{ID:"id", Type: string(property.PropertyConfigTypeSelect)} pr := property.Properties{"Select": &p} - _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["Select"]) @@ -44,7 +44,7 @@ func Test_handlePagePropertiesLastEditedTime(t *testing.T) { p := property.LastEditedTime{ID: "id", Type: string(property.PropertyConfigLastEditedTime)} pr := property.Properties{"LastEditedTime": &p} - _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["LastEditedTime"]) @@ -63,7 +63,7 @@ func Test_handlePagePropertiesRichText(t *testing.T) { p := property.RichText{ID: "id", Type: string(property.PropertyConfigLastEditedTime)} pr := property.Properties{"RichText": &p} - _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["RichText"]) @@ -82,7 +82,7 @@ func Test_handlePagePropertiesStatus(t *testing.T) { p := property.StatusProperty{ID: "id", Type: property.PropertyConfigStatus} pr := property.Properties{"Status": &p} - _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["Status"]) @@ -101,7 +101,7 @@ func Test_handlePagePropertiesNumber(t *testing.T) { p := property.NumberProperty{ID: "id", Type: string(property.PropertyConfigTypeNumber)} pr := property.Properties{"Number": &p} - _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["Number"]) @@ -120,7 +120,7 @@ func Test_handlePagePropertiesMultiSelect(t *testing.T) { p := property.NumberProperty{ID: "id", Type: string(property.PropertyConfigTypeMultiSelect)} pr := property.Properties{"MultiSelect": &p} - _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["MultiSelect"]) @@ -139,7 +139,7 @@ func Test_handlePagePropertiesCheckbox(t *testing.T) { p := property.Checkbox{ID: "id", Type: string(property.PropertyConfigTypeCheckbox)} pr := property.Properties{"Checkbox": &p} - _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["Checkbox"]) @@ -158,7 +158,7 @@ func Test_handlePagePropertiesEmail(t *testing.T) { p := property.Email{ID: "id", Type: string(property.PropertyConfigTypeEmail)} pr := property.Properties{"Email": &p} - _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["Email"]) @@ -177,7 +177,7 @@ func Test_handlePagePropertiesRelation(t *testing.T) { p := property.RelationProperty{ID: "id", Type: string(property.PropertyConfigTypeRelation)} pr := property.Properties{"Relation": &p} - _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["Relation"]) @@ -196,7 +196,7 @@ func Test_handlePagePropertiesPeople(t *testing.T) { p := property.People{ID: "id", Type: string(property.PropertyConfigTypePeople)} pr := property.Properties{"People": &p} - _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["People"]) @@ -215,7 +215,7 @@ func Test_handlePagePropertiesFormula(t *testing.T) { p := property.Formula{ID: "id", Type: string(property.PropertyConfigTypeFormula)} pr := property.Properties{"Formula": &p} - _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["Formula"]) @@ -234,7 +234,7 @@ func Test_handlePagePropertiesTitle(t *testing.T) { p := property.Title{ID: "id", Type: string(property.PropertyConfigTypeTitle)} pr := property.Properties{"Title": &p} - _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) assert.Nil(t, ce) assert.NotEmpty(t, details["name"]) diff --git a/core/block/import/notion/api/property/propertyitem.go b/core/block/import/notion/api/property/propertyitem.go index c5a911420..ccf35e2de 100644 --- a/core/block/import/notion/api/property/propertyitem.go +++ b/core/block/import/notion/api/property/propertyitem.go @@ -73,7 +73,7 @@ type SelectItem struct { type SelectOption struct { ID string `json:"id,omitempty"` Name string `json:"name"` - Color api.Color `json:"color"` + Color string `json:"color"` } func (sp *SelectItem) SetDetail(key string, details map[string]*types.Value) { @@ -97,20 +97,14 @@ func (ms *MultiSelectItem) SetDetail(key string, details map[string]*types.Value //can't support it yet type DateItem struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Date Date `json:"date"` + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Date api.DateObject `json:"date"` } func (dp *DateItem) SetDetail(key string, details map[string]*types.Value) {} -type Date struct { - Start string `json:"start"` - End string `json:"end"` - TimeZone string `json:"time_zone"` -} - const ( NumberFormula string = "number" StringFormula string = "string" @@ -133,7 +127,7 @@ func (f *FormulaItem) SetDetail(key string, details map[string]*types.Value) { } case NumberFormula: if f.Formula["number"] != nil { - stringNumber := strconv.FormatFloat(f.Formula["number"].(float64),'f', 6, 64) + stringNumber := strconv.FormatFloat(f.Formula["number"].(float64), 'f', 6, 64) details[key] = pbtypes.String(stringNumber) } case BooleanFormula: @@ -147,11 +141,11 @@ func (f *FormulaItem) SetDetail(key string, details map[string]*types.Value) { } type RelationItem struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` Relation Relation `json:"relation"` - HasMore bool `json:"has_more"` + HasMore bool `json:"has_more"` } type Relation struct { diff --git a/core/block/import/notion/api/search/search_test.go b/core/block/import/notion/api/search/search_test.go index 002c309b8..0fed43b33 100644 --- a/core/block/import/notion/api/search/search_test.go +++ b/core/block/import/notion/api/search/search_test.go @@ -30,7 +30,7 @@ func Test_GetDatabaseSuccess(t *testing.T) { assert.Nil(t, err) ds := database.New() - databases := ds.GetDatabase(context.Background(), pb.RpcObjectImportRequest_ALL_OR_NOTHING, db) + databases, _, _ := ds.GetDatabase(context.Background(), pb.RpcObjectImportRequest_ALL_OR_NOTHING, db) assert.NotNil(t, databases) assert.Len(t, databases.Snapshots, 1) @@ -108,7 +108,7 @@ func Test_GetPagesSuccess(t *testing.T) { c = client.NewClient() c.BasePath = s.URL ps := page.New(c) - pages := ps.GetPages(context.Background(), "key", pb.RpcObjectImportRequest_ALL_OR_NOTHING, p) + pages := ps.GetPages(context.Background(), "key", pb.RpcObjectImportRequest_ALL_OR_NOTHING, p, map[string]string{}, map[string]string{}) assert.NotNil(t, pages) assert.Len(t, pages.Snapshots, 1) diff --git a/core/block/import/notion/converter.go b/core/block/import/notion/converter.go index 8aa824f12..05e53e519 100644 --- a/core/block/import/notion/converter.go +++ b/core/block/import/notion/converter.go @@ -57,7 +57,7 @@ func (n *Notion) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Respons Error: ce, } } - databasesSnapshots := n.databaseService.GetDatabase(context.TODO(), req.Mode, databases) + databasesSnapshots, notionIdsToAnytype, databaseNameToID := n.databaseService.GetDatabase(context.TODO(), req.Mode, databases) if databasesSnapshots.Error != nil && req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { ce.Merge(databasesSnapshots.Error) return &converter.Response{ @@ -65,7 +65,7 @@ func (n *Notion) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Respons } } - pagesSnapshots := n.pageService.GetPages(context.TODO(), apiKey, req.Mode, pages) + pagesSnapshots := n.pageService.GetPages(context.TODO(), apiKey, req.Mode, pages, notionIdsToAnytype, databaseNameToID) if pagesSnapshots.Error != nil && req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { ce.Merge(pagesSnapshots.Error) return &converter.Response{ diff --git a/core/block/import/objectcreator.go b/core/block/import/objectcreator.go index 8c4fa32a9..66684f618 100644 --- a/core/block/import/objectcreator.go +++ b/core/block/import/objectcreator.go @@ -112,6 +112,7 @@ func (oc *ObjectCreator) Create(ctx *session.Context, snapshot *model.SmartBlock } return true }) + return details, nil } @@ -162,8 +163,16 @@ func (oc *ObjectCreator) addRootBlock(snapshot *model.SmartBlockSnapshotBase, pa } } if err != nil { + notRootBlockChild := make(map[string]bool, 0) for _, b := range snapshot.Blocks { - childrenIds = append(childrenIds, b.Id) + if len(b.ChildrenIds) != 0 { + for _, id := range b.ChildrenIds { + notRootBlockChild[id] = true + } + } + if _, ok := notRootBlockChild[b.Id]; !ok { + childrenIds = append(childrenIds, b.Id) + } } snapshot.Blocks = append(snapshot.Blocks, &model.Block{ Id: pageID, diff --git a/core/block/import/pb/converter.go b/core/block/import/pb/converter.go index d37b5bd54..fb3bfb2b5 100644 --- a/core/block/import/pb/converter.go +++ b/core/block/import/pb/converter.go @@ -44,9 +44,9 @@ func (p *Pb) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Response { if err != nil && req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { return &converter.Response{Error: err} } + allErrors.Merge(err) allSnapshots := make([]*converter.Snapshot, 0) - allErrors.Merge(err) for name, file := range pbFiles { id := strings.TrimSuffix(file.Name, filepath.Ext(file.Name)) var ( diff --git a/core/block/import/relationcreator.go b/core/block/import/relationcreator.go index 065bae65d..0bac505d2 100644 --- a/core/block/import/relationcreator.go +++ b/core/block/import/relationcreator.go @@ -1,7 +1,6 @@ package importer import ( - "fmt" "strings" "github.com/anytypeio/go-anytype-middleware/core/block" @@ -75,7 +74,8 @@ func (rc *RelationService) Create(ctx *session.Context, snapshot *model.SmartBlo Details: details, }) if err != nil { - return filesToDelete, fmt.Errorf("set details '%s'", err.Error()) + log.Errorf("set details %s", err) + continue } } } diff --git a/core/block/import/syncer/icon.go b/core/block/import/syncer/icon.go new file mode 100644 index 000000000..315066246 --- /dev/null +++ b/core/block/import/syncer/icon.go @@ -0,0 +1,51 @@ +package syncer + +import ( + "fmt" + "os" + "strings" + + "github.com/anytypeio/go-anytype-middleware/core/block" + "github.com/anytypeio/go-anytype-middleware/core/block/editor/basic" + "github.com/anytypeio/go-anytype-middleware/core/block/editor/smartblock" + "github.com/anytypeio/go-anytype-middleware/core/block/simple" + "github.com/anytypeio/go-anytype-middleware/core/session" + "github.com/anytypeio/go-anytype-middleware/pb" +) + +type IconSyncer struct { + service block.Service +} + +func NewIconSyncer(service block.Service) *IconSyncer { + return &IconSyncer{service: service} +} + +func (is *IconSyncer) Sync(ctx *session.Context, id string, b simple.Block) error { + fileName := b.Model().GetText().GetIconImage() + req := pb.RpcFileUploadRequest{LocalPath: fileName} + if strings.HasPrefix(fileName, "http://") || strings.HasPrefix(fileName, "https://") { + req = pb.RpcFileUploadRequest{Url: fileName} + } + hash, err := is.service.UploadFile(req) + if err != nil { + return fmt.Errorf("failed uploading icon image file: %s", err) + } + + err = is.service.Do(id, func(sb smartblock.SmartBlock) error { + bs := basic.NewBasic(sb) + err := bs.Update(ctx, func(simpleBlock simple.Block) error { + simpleBlock.Model().GetText().IconImage = hash + return nil + }, b.Model().Id) + if err != nil { + return fmt.Errorf("failed to update block: %s", err) + } + return nil + }) + if err != nil { + return fmt.Errorf("failed to update block: %s", err) + } + os.Remove(fileName) + return nil +} diff --git a/core/block/import/syncer/syncer.go b/core/block/import/syncer/syncer.go index 11a5d8574..a800b6b59 100644 --- a/core/block/import/syncer/syncer.go +++ b/core/block/import/syncer/syncer.go @@ -5,10 +5,11 @@ import "github.com/anytypeio/go-anytype-middleware/core/block/simple" type Factory struct { fs Syncer bs Syncer + is Syncer } -func New(fs *FileSyncer, bs *BookmarkSyncer) *Factory { - return &Factory{fs:fs, bs: bs} +func New(fs *FileSyncer, bs *BookmarkSyncer, is *IconSyncer) *Factory { + return &Factory{fs:fs, bs: bs, is: is} } func (f *Factory) GetSyncer(b simple.Block) Syncer { @@ -18,5 +19,8 @@ func (f *Factory) GetSyncer(b simple.Block) Syncer { if file := b.Model().GetFile(); file != nil { return f.fs } + if b.Model().GetText() != nil && b.Model().GetText().GetIconImage() != "" { + return f.is + } return nil } From ce2e2adffa61cdd3648596ff9b262fbf9081f69f Mon Sep 17 00:00:00 2001 From: Anastasia Shemyakinskaya <36507473+AnastasiaShemyakinskaya@users.noreply.github.com> Date: Tue, 22 Nov 2022 11:10:40 +0300 Subject: [PATCH 11/68] GO-472: retrieve file blocks from notion api (#1618) Signed-off-by: AnastasiaShemyakinskaya --- core/block/editor.go | 2 +- core/block/import/notion/api/block/block.go | 7 - core/block/import/notion/api/block/file.go | 24 +++ core/block/import/notion/api/block/mapper.go | 16 ++ .../block/import/notion/api/block/retrieve.go | 30 +++- core/block/import/notion/api/commonobjects.go | 18 +++ .../import/notion/api/commonobjects_test.go | 151 +++++++++++++++++- .../import/notion/api/database/database.go | 55 +++---- core/block/import/notion/api/page/page.go | 8 +- core/block/import/objectcreator.go | 34 ++-- core/block/import/syncer/file.go | 2 +- 11 files changed, 282 insertions(+), 65 deletions(-) create mode 100644 core/block/import/notion/api/block/file.go diff --git a/core/block/editor.go b/core/block/editor.go index f675cf9dd..92b5efdae 100644 --- a/core/block/editor.go +++ b/core/block/editor.go @@ -561,7 +561,7 @@ func (s *service) UploadFileBlockWithHash(ctx *session.Context, contextId string hash = res.Hash return nil }) - + return hash, err } diff --git a/core/block/import/notion/api/block/block.go b/core/block/import/notion/api/block/block.go index 8b1d4a72a..e9867d1ac 100644 --- a/core/block/import/notion/api/block/block.go +++ b/core/block/import/notion/api/block/block.go @@ -52,10 +52,3 @@ type Block struct { HasChildren bool `json:"has_children"` Type BlockType `json:"type"` } - -type ImageBlock struct { - Caption []api.RichText `json:"caption,omitempty"` - Type api.FileType `json:"type"` - File api.FileProperty `json:"file,omitempty"` - External api.FileProperty `json:"external,omitempty"` -} diff --git a/core/block/import/notion/api/block/file.go b/core/block/import/notion/api/block/file.go new file mode 100644 index 000000000..20056c56c --- /dev/null +++ b/core/block/import/notion/api/block/file.go @@ -0,0 +1,24 @@ +package block + +import "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + +type FileBlock struct { + Block + File api.FileObject `json:"file"` + Caption []api.RichText `json:"caption"` +} + +type ImageBlock struct { + Block + File api.FileObject `json:"image"` +} + +type PdfBlock struct { + Block + File api.FileObject `json:"pdf"` +} + +type VideoBlock struct { + Block + File api.FileObject `json:"video"` +} diff --git a/core/block/import/notion/api/block/mapper.go b/core/block/import/notion/api/block/mapper.go index 7739ce3aa..e9d9a5887 100644 --- a/core/block/import/notion/api/block/mapper.go +++ b/core/block/import/notion/api/block/mapper.go @@ -101,6 +101,22 @@ func (m *Mapper) MapBlocks(blocks []interface{}, notionPageIdsToAnytype, notionD anytypeBlocks = append(anytypeBlocks, allBlocks...) anytypeBlocks = append(anytypeBlocks, childBlocks...) ids = append(ids, blockIDs...) + case *FileBlock: + fileBlock, id := block.File.GetFileBlock(model.BlockContentFile_File) + anytypeBlocks = append(anytypeBlocks, fileBlock) + ids = append(ids, id) + case *ImageBlock: + fileBlock, id := block.File.GetFileBlock(model.BlockContentFile_Image) + anytypeBlocks = append(anytypeBlocks, fileBlock) + ids = append(ids, id) + case *VideoBlock: + fileBlock, id := block.File.GetFileBlock(model.BlockContentFile_Video) + anytypeBlocks = append(anytypeBlocks, fileBlock) + ids = append(ids, id) + case *PdfBlock: + fileBlock, id := block.File.GetFileBlock(model.BlockContentFile_PDF) + anytypeBlocks = append(anytypeBlocks, fileBlock) + ids = append(ids, id) } } return anytypeBlocks, ids diff --git a/core/block/import/notion/api/block/retrieve.go b/core/block/import/notion/api/block/retrieve.go index 693c09410..51dedcc30 100644 --- a/core/block/import/notion/api/block/retrieve.go +++ b/core/block/import/notion/api/block/retrieve.go @@ -57,7 +57,7 @@ func (s *Service) GetBlocksAndChildren(ctx context.Context, pageID, apiKey strin for _, b := range blocks { switch bl := b.(type) { - case *Heading1Block, *Heading2Block, *Heading3Block, *CodeBlock, *EquationBlock: + case *Heading1Block, *Heading2Block, *Heading3Block, *CodeBlock, *EquationBlock, *FileBlock, *ImageBlock, *VideoBlock, *PdfBlock: allBlocks = append(allBlocks, bl) case *ParagraphBlock: if bl.HasChildren { @@ -298,6 +298,34 @@ func (s *Service) getBlocks(ctx context.Context, pageID, apiKey string, paginati continue } blocks = append(blocks, &t) + case File: + f := FileBlock{} + err = json.Unmarshal(buffer, &f) + if err != nil { + continue + } + blocks = append(blocks, &f) + case Image: + i := ImageBlock{} + err = json.Unmarshal(buffer, &i) + if err != nil { + continue + } + blocks = append(blocks, &i) + case Video: + v := VideoBlock{} + err = json.Unmarshal(buffer, &v) + if err != nil { + continue + } + blocks = append(blocks, &v) + case Pdf: + p := PdfBlock{} + err = json.Unmarshal(buffer, &p) + if err != nil { + continue + } + blocks = append(blocks, &p) } } diff --git a/core/block/import/notion/api/commonobjects.go b/core/block/import/notion/api/commonobjects.go index 02151e0cd..e559a6c7e 100644 --- a/core/block/import/notion/api/commonobjects.go +++ b/core/block/import/notion/api/commonobjects.go @@ -236,6 +236,24 @@ type FileObject struct { External FileProperty `json:"external,omitempty"` } +func (f *FileObject) GetFileBlock(fileType model.BlockContentFileType) (*model.Block, string) { + id := bson.NewObjectId().Hex() + name := f.External.URL + if name == "" { + name = f.File.URL + } + return &model.Block{ + Id: id, + Content: &model.BlockContentOfFile{ + File: &model.BlockContentFile{ + Name: name, + AddedAt: time.Now().Unix(), + Type: fileType, + }, + }, + }, id +} + type FileProperty struct { URL string `json:"url,omitempty"` ExpiryTime *time.Time `json:"expiry_time,omitempty"` diff --git a/core/block/import/notion/api/commonobjects_test.go b/core/block/import/notion/api/commonobjects_test.go index b560733ee..37c106933 100644 --- a/core/block/import/notion/api/commonobjects_test.go +++ b/core/block/import/notion/api/commonobjects_test.go @@ -2,6 +2,7 @@ package api import ( "testing" + "time" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" "github.com/stretchr/testify/assert" @@ -18,7 +19,7 @@ func Test_BuildMarkdownFromAnnotationsBold(t *testing.T) { Color: "", }, } - marks := rt.BuildMarkdownFromAnnotations(0, 5) + marks := rt.BuildMarkdownFromAnnotations(0, 5) assert.Len(t, marks, 1) assert.Equal(t, marks[0].Type, model.BlockContentTextMark_Bold) } @@ -34,7 +35,7 @@ func Test_BuildMarkdownFromAnnotationsItalic(t *testing.T) { Color: "", }, } - marks := rt.BuildMarkdownFromAnnotations(0, 5) + marks := rt.BuildMarkdownFromAnnotations(0, 5) assert.Len(t, marks, 1) assert.Equal(t, marks[0].Type, model.BlockContentTextMark_Italic) } @@ -50,7 +51,7 @@ func Test_BuildMarkdownFromAnnotationsStrikethrough(t *testing.T) { Color: "", }, } - marks := rt.BuildMarkdownFromAnnotations(0, 5) + marks := rt.BuildMarkdownFromAnnotations(0, 5) assert.Len(t, marks, 1) assert.Equal(t, marks[0].Type, model.BlockContentTextMark_Strikethrough) } @@ -66,7 +67,7 @@ func Test_BuildMarkdownFromAnnotationsUnderline(t *testing.T) { Color: "", }, } - marks := rt.BuildMarkdownFromAnnotations(0, 5) + marks := rt.BuildMarkdownFromAnnotations(0, 5) assert.Len(t, marks, 1) assert.Equal(t, marks[0].Type, model.BlockContentTextMark_Underscored) } @@ -82,7 +83,7 @@ func Test_BuildMarkdownFromAnnotationsTwoMarks(t *testing.T) { Color: "", }, } - marks := rt.BuildMarkdownFromAnnotations(0, 5) + marks := rt.BuildMarkdownFromAnnotations(0, 5) assert.Len(t, marks, 2) assert.Equal(t, marks[0].Type, model.BlockContentTextMark_Bold) assert.Equal(t, marks[1].Type, model.BlockContentTextMark_Italic) @@ -99,7 +100,143 @@ func Test_BuildMarkdownFromAnnotationsColor(t *testing.T) { Color: "red", }, } - marks := rt.BuildMarkdownFromAnnotations(0, 5) + marks := rt.BuildMarkdownFromAnnotations(0, 5) assert.Len(t, marks, 1) assert.Equal(t, marks[0].Param, "red") -} \ No newline at end of file +} + +func Test_GetFileBlockImage(t *testing.T) { + f := &FileObject{ + Name: "file", + File: FileProperty{ + URL: "", + ExpiryTime: &time.Time{}, + }, + External: FileProperty{ + URL: "https:/example.ru/", + ExpiryTime: &time.Time{}, + }, + } + imageBlock, _ := f.GetFileBlock(model.BlockContentFile_Image) + assert.NotNil(t, imageBlock.GetFile()) + assert.Equal(t, imageBlock.GetFile().Name, "https:/example.ru/") + assert.Equal(t, imageBlock.GetFile().Type, model.BlockContentFile_Image) + + f = &FileObject{ + Name: "file", + File: FileProperty{ + URL: "https:/example.ru/", + ExpiryTime: &time.Time{}, + }, + External: FileProperty{ + URL: "", + ExpiryTime: &time.Time{}, + }, + } + imageBlock, _ = f.GetFileBlock(model.BlockContentFile_Image) + assert.NotNil(t, imageBlock.GetFile()) + assert.Equal(t, imageBlock.GetFile().Name, "https:/example.ru/") + assert.Equal(t, imageBlock.GetFile().Type, model.BlockContentFile_Image) +} + +func Test_GetFileBlockPdf(t *testing.T) { + f := &FileObject{ + Name: "file", + File: FileProperty{ + URL: "", + ExpiryTime: &time.Time{}, + }, + External: FileProperty{ + URL: "https:/example.ru/", + ExpiryTime: &time.Time{}, + }, + } + imageBlock, _ := f.GetFileBlock(model.BlockContentFile_PDF) + assert.NotNil(t, imageBlock.GetFile()) + assert.Equal(t, imageBlock.GetFile().Name, "https:/example.ru/") + assert.Equal(t, imageBlock.GetFile().Type, model.BlockContentFile_PDF) + + f = &FileObject{ + Name: "file", + File: FileProperty{ + URL: "https:/example.ru/", + ExpiryTime: &time.Time{}, + }, + External: FileProperty{ + URL: "", + ExpiryTime: &time.Time{}, + }, + } + imageBlock, _ = f.GetFileBlock(model.BlockContentFile_PDF) + assert.NotNil(t, imageBlock.GetFile()) + assert.Equal(t, imageBlock.GetFile().Name, "https:/example.ru/") + assert.Equal(t, imageBlock.GetFile().Type, model.BlockContentFile_PDF) +} + +func Test_GetFileBlockFile(t *testing.T) { + f := &FileObject{ + Name: "file", + File: FileProperty{ + URL: "", + ExpiryTime: &time.Time{}, + }, + External: FileProperty{ + URL: "https:/example.ru/", + ExpiryTime: &time.Time{}, + }, + } + imageBlock, _ := f.GetFileBlock(model.BlockContentFile_File) + assert.NotNil(t, imageBlock.GetFile()) + assert.Equal(t, imageBlock.GetFile().Name, "https:/example.ru/") + assert.Equal(t, imageBlock.GetFile().Type, model.BlockContentFile_File) + + f = &FileObject{ + Name: "file", + File: FileProperty{ + URL: "https:/example.ru/", + ExpiryTime: &time.Time{}, + }, + External: FileProperty{ + URL: "", + ExpiryTime: &time.Time{}, + }, + } + imageBlock, _ = f.GetFileBlock(model.BlockContentFile_File) + assert.NotNil(t, imageBlock.GetFile()) + assert.Equal(t, imageBlock.GetFile().Name, "https:/example.ru/") + assert.Equal(t, imageBlock.GetFile().Type, model.BlockContentFile_File) +} + +func Test_GetFileBlockVideo(t *testing.T) { + f := &FileObject{ + Name: "file", + File: FileProperty{ + URL: "", + ExpiryTime: &time.Time{}, + }, + External: FileProperty{ + URL: "https:/example.ru/", + ExpiryTime: &time.Time{}, + }, + } + imageBlock, _ := f.GetFileBlock(model.BlockContentFile_Video) + assert.NotNil(t, imageBlock.GetFile()) + assert.Equal(t, imageBlock.GetFile().Name, "https:/example.ru/") + assert.Equal(t, imageBlock.GetFile().Type, model.BlockContentFile_Video) + + f = &FileObject{ + Name: "file", + File: FileProperty{ + URL: "https:/example.ru/", + ExpiryTime: &time.Time{}, + }, + External: FileProperty{ + URL: "", + ExpiryTime: &time.Time{}, + }, + } + imageBlock, _ = f.GetFileBlock(model.BlockContentFile_Video) + assert.NotNil(t, imageBlock.GetFile()) + assert.Equal(t, imageBlock.GetFile().Name, "https:/example.ru/") + assert.Equal(t, imageBlock.GetFile().Type, model.BlockContentFile_Video) +} diff --git a/core/block/import/notion/api/database/database.go b/core/block/import/notion/api/database/database.go index c29e14a5b..36b994d07 100644 --- a/core/block/import/notion/api/database/database.go +++ b/core/block/import/notion/api/database/database.go @@ -4,44 +4,45 @@ import ( "context" "time" + "github.com/gogo/protobuf/types" + "github.com/textileio/go-threads/core/thread" + "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" - "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/block" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" "github.com/anytypeio/go-anytype-middleware/pkg/lib/threads" "github.com/anytypeio/go-anytype-middleware/util/pbtypes" - "github.com/gogo/protobuf/types" - "github.com/textileio/go-threads/core/thread" ) const ObjectType = "database" -type Service struct {} +type Service struct{} // New is a constructor for Service func New() *Service { return &Service{} } + // Database represent Database object from Notion https://developers.notion.com/reference/database type Database struct { - Object string `json:"object"` - ID string `json:"id"` - CreatedTime time.Time `json:"created_time"` - LastEditedTime time.Time `json:"last_edited_time"` - CreatedBy api.User `json:"created_by,omitempty"` - LastEditedBy api.User `json:"last_edited_by,omitempty"` - Title []api.RichText `json:"title"` - Parent api.Parent `json:"parent"` - URL string `json:"url"` - Properties interface{} `json:"properties"` // can't support it for databases yet - Description []api.RichText `json:"description"` - IsInline bool `json:"is_inline"` - Archived bool `json:"archived"` - Icon *api.Icon `json:"icon,omitempty"` - Cover *block.ImageBlock `json:"cover,omitempty"` + Object string `json:"object"` + ID string `json:"id"` + CreatedTime time.Time `json:"created_time"` + LastEditedTime time.Time `json:"last_edited_time"` + CreatedBy api.User `json:"created_by,omitempty"` + LastEditedBy api.User `json:"last_edited_by,omitempty"` + Title []api.RichText `json:"title"` + Parent api.Parent `json:"parent"` + URL string `json:"url"` + Properties interface{} `json:"properties"` // can't support it for databases yet + Description []api.RichText `json:"description"` + IsInline bool `json:"is_inline"` + Archived bool `json:"archived"` + Icon *api.Icon `json:"icon,omitempty"` + Cover *api.FileObject `json:"cover,omitempty"` } func (p *Database) GetObjectType() string { @@ -49,16 +50,16 @@ func (p *Database) GetObjectType() string { } // GetDatabase makes snaphots from notion Database objects -func (ds *Service) GetDatabase(ctx context.Context, mode pb.RpcObjectImportRequestMode, databases []Database) (*converter.Response, map[string]string, map[string]string) { +func (ds *Service) GetDatabase(ctx context.Context, mode pb.RpcObjectImportRequestMode, databases []Database) (*converter.Response, map[string]string, map[string]string) { convereterError := converter.ConvertError{} return ds.mapDatabasesToSnaphots(ctx, mode, databases, convereterError) } func (ds *Service) mapDatabasesToSnaphots(ctx context.Context, mode pb.RpcObjectImportRequestMode, databases []Database, convereterError converter.ConvertError) (*converter.Response, map[string]string, map[string]string) { var ( - allSnapshots = make([]*converter.Snapshot, 0) + allSnapshots = make([]*converter.Snapshot, 0) notionIdsToAnytype = make(map[string]string, 0) - databaseNameToID = make(map[string]string, 0) + databaseNameToID = make(map[string]string, 0) ) for _, d := range databases { tid, err := threads.ThreadCreateID(thread.AccessControlled, smartblock.SmartBlockTypePage) @@ -71,7 +72,7 @@ func (ds *Service) mapDatabasesToSnaphots(ctx context.Context, mode pb.RpcObject } } snapshot := ds.transformDatabase(d) - + allSnapshots = append(allSnapshots, &converter.Snapshot{ Id: tid.String(), FileName: d.URL, @@ -89,7 +90,7 @@ func (ds *Service) mapDatabasesToSnaphots(ctx context.Context, mode pb.RpcObject func (ds *Service) transformDatabase(d Database) *model.SmartBlockSnapshotBase { details := make(map[string]*types.Value, 0) details[bundle.RelationKeySource.String()] = pbtypes.String(d.URL) - if len(d.Title) > 0{ + if len(d.Title) > 0 { details[bundle.RelationKeyName.String()] = pbtypes.String(d.Title[0].PlainText) } if d.Icon != nil && d.Icon.Emoji != nil { @@ -101,11 +102,11 @@ func (ds *Service) transformDatabase(d Database) *model.SmartBlockSnapshotBase { details[bundle.RelationKeyLastModifiedDate.String()] = pbtypes.String(d.LastEditedTime.String()) details[bundle.RelationKeyLastModifiedBy.String()] = pbtypes.String(d.LastEditedBy.Name) details[bundle.RelationKeyDescription.String()] = pbtypes.String(api.RichTextToDescription(d.Description)) - details[bundle.RelationKeyIsFavorite.String()] = pbtypes.Bool(true) + details[bundle.RelationKeyIsFavorite.String()] = pbtypes.Bool(true) snapshot := &model.SmartBlockSnapshotBase{ - Blocks: []*model.Block{}, - Details: &types.Struct{Fields: details}, + Blocks: []*model.Block{}, + Details: &types.Struct{Fields: details}, ObjectTypes: []string{bundle.TypeKeyPage.URL()}, Collections: nil, } diff --git a/core/block/import/notion/api/page/page.go b/core/block/import/notion/api/page/page.go index 6d34a5022..07c0573d5 100644 --- a/core/block/import/notion/api/page/page.go +++ b/core/block/import/notion/api/page/page.go @@ -53,7 +53,7 @@ type Page struct { Properties property.Properties `json:"properties"` Archived bool `json:"archived"` Icon *api.Icon `json:"icon,omitempty"` - Cover *block.ImageBlock `json:"cover,omitempty"` + Cover *api.FileObject `json:"cover,omitempty"` URL string `json:"url,omitempty"` } @@ -92,7 +92,7 @@ func (ds *Service) mapPagesToSnaphots(ctx context.Context, apiKey string, mode p continue } } - + allSnapshots = append(allSnapshots, &converter.Snapshot{ Id: notionPagesIdsToAnytype[p.ID], FileName: p.URL, @@ -152,14 +152,14 @@ func (ds *Service) handlePageProperties(apiKey, pageID string, p property.Proper for k, v := range p { object, err := ds.propertyService.GetPropertyObject(context.TODO(), pageID, v.GetID(), apiKey, v.GetPropertyType()) if err != nil { - ce.Add("property: " + v.GetID(), err) + ce.Add("property: "+v.GetID(), err) if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { return relations, pageNameToID, &ce } } err = ds.detailSetter.SetDetailValue(k, v.GetPropertyType(), object, d) if err != nil && mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - ce.Add("property: " + v.GetID(), err) + ce.Add("property: "+v.GetID(), err) if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { return relations, pageNameToID, &ce } diff --git a/core/block/import/objectcreator.go b/core/block/import/objectcreator.go index 66684f618..4ac8c92a8 100644 --- a/core/block/import/objectcreator.go +++ b/core/block/import/objectcreator.go @@ -24,11 +24,11 @@ import ( ) type ObjectCreator struct { - service block.Service - core core.Service - updater Updater + service block.Service + core core.Service + updater Updater relationCreator RelationCreator - syncFactory *syncer.Factory + syncFactory *syncer.Factory } func NewCreator(service block.Service, core core.Service, updater Updater, syncFactory *syncer.Factory, relationCreator RelationCreator) Creator { @@ -38,7 +38,7 @@ func NewCreator(service block.Service, core core.Service, updater Updater, syncF // Create creates smart blocks from given snapshots func (oc *ObjectCreator) Create(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, pageID string, sbType smartblock.SmartBlockType, updateExisting bool) (*types.Struct, error) { isFavorite := pbtypes.GetBool(snapshot.Details, bundle.RelationKeyIsFavorite.String()) - + var err error if updateExisting { @@ -56,21 +56,21 @@ func (oc *ObjectCreator) Create(ctx *session.Context, snapshot *model.SmartBlock } } if !found { - oc.addRootBlock(snapshot, pageID) + oc.addRootBlock(snapshot, pageID) } st := state.NewDocFromSnapshot(pageID, &pb.ChangeSnapshot{Data: snapshot}).(*state.State) st.SetRootId(pageID) - + st.RemoveDetail(bundle.RelationKeyCreator.String(), bundle.RelationKeyLastModifiedBy.String()) st.SetLocalDetail(bundle.RelationKeyCreator.String(), pbtypes.String(addr.AnytypeProfileId)) st.SetLocalDetail(bundle.RelationKeyLastModifiedBy.String(), pbtypes.String(addr.AnytypeProfileId)) st.InjectDerivedDetails() - + if err = oc.validate(st); err != nil { return nil, fmt.Errorf("new id not found for '%s'", st.RootId()) - } + } var filesToDelete []string defer func() { @@ -112,7 +112,7 @@ func (oc *ObjectCreator) Create(ctx *session.Context, snapshot *model.SmartBlock } return true }) - + return details, nil } @@ -148,13 +148,13 @@ func (oc *ObjectCreator) createSmartBlock(sbType smartblock.SmartBlockType, st * func (oc *ObjectCreator) addRootBlock(snapshot *model.SmartBlockSnapshotBase, pageID string) { var ( childrenIds = make([]string, 0, len(snapshot.Blocks)) - err error + err error ) for i, b := range snapshot.Blocks { - _, err = thread.Decode(b.Id) + _, err = thread.Decode(b.Id) if err == nil { childrenIds = append(childrenIds, b.ChildrenIds...) - snapshot.Blocks[i] = &model.Block{ + snapshot.Blocks[i] = &model.Block{ Id: pageID, Content: &model.BlockContentOfSmartblock{}, ChildrenIds: childrenIds, @@ -173,13 +173,13 @@ func (oc *ObjectCreator) addRootBlock(snapshot *model.SmartBlockSnapshotBase, pa if _, ok := notRootBlockChild[b.Id]; !ok { childrenIds = append(childrenIds, b.Id) } - } - snapshot.Blocks = append(snapshot.Blocks, &model.Block{ + } + snapshot.Blocks = append(snapshot.Blocks, &model.Block{ Id: pageID, Content: &model.BlockContentOfSmartblock{}, ChildrenIds: childrenIds, }) - } + } } func (oc *ObjectCreator) deleteFile(hash string) { @@ -202,4 +202,4 @@ func (oc *ObjectCreator) deleteFile(hash string) { log.With("file", hash).Errorf("failed to delete file keys: %s", err.Error()) } } -} \ No newline at end of file +} diff --git a/core/block/import/syncer/file.go b/core/block/import/syncer/file.go index 99a9ddfab..64be1194d 100644 --- a/core/block/import/syncer/file.go +++ b/core/block/import/syncer/file.go @@ -27,7 +27,7 @@ func (fs *FileSyncer) Sync(ctx *session.Context, id string, b simple.Block) erro if strings.HasPrefix(b.Model().GetFile().Name, "http://") || strings.HasPrefix(b.Model().GetFile().Name, "https://") { params = pb.RpcBlockUploadRequest{ Url: b.Model().GetFile().Name, - BlockId: b.Model().Id, + BlockId: b.Model().Id, } } hash, err := fs.service.UploadFileBlockWithHash(ctx, id, params) From 453bb0a0d5c4b613faa375936bb2f123ad96080a Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Wed, 30 Nov 2022 12:03:30 +0300 Subject: [PATCH 12/68] GO-474: get div block Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/notion/api/block/div.go | 23 +++++++++++++++++++ core/block/import/notion/api/block/mapper.go | 4 ++++ .../block/import/notion/api/block/retrieve.go | 9 +++++++- 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 core/block/import/notion/api/block/div.go diff --git a/core/block/import/notion/api/block/div.go b/core/block/import/notion/api/block/div.go new file mode 100644 index 000000000..263aa3d18 --- /dev/null +++ b/core/block/import/notion/api/block/div.go @@ -0,0 +1,23 @@ +package block + +import ( + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" + "github.com/globalsign/mgo/bson" +) + +type DividerBlock struct { + Block + Divider struct{} `json:"divider"` +} + +func (*DividerBlock) GetDivBlock() (*model.Block, string) { + id := bson.NewObjectId().Hex() + return &model.Block{ + Id: id, + Content: &model.BlockContentOfDiv{ + Div: &model.BlockContentDiv{ + Style: 0, + }, + }, + }, id +} diff --git a/core/block/import/notion/api/block/mapper.go b/core/block/import/notion/api/block/mapper.go index e9d9a5887..5dc4f83bc 100644 --- a/core/block/import/notion/api/block/mapper.go +++ b/core/block/import/notion/api/block/mapper.go @@ -117,6 +117,10 @@ func (m *Mapper) MapBlocks(blocks []interface{}, notionPageIdsToAnytype, notionD fileBlock, id := block.File.GetFileBlock(model.BlockContentFile_PDF) anytypeBlocks = append(anytypeBlocks, fileBlock) ids = append(ids, id) + case *DividerBlock: + db, id := block.GetDivBlock() + anytypeBlocks = append(anytypeBlocks, db) + ids = append(ids, id) } } return anytypeBlocks, ids diff --git a/core/block/import/notion/api/block/retrieve.go b/core/block/import/notion/api/block/retrieve.go index 51dedcc30..f3599fb67 100644 --- a/core/block/import/notion/api/block/retrieve.go +++ b/core/block/import/notion/api/block/retrieve.go @@ -57,7 +57,7 @@ func (s *Service) GetBlocksAndChildren(ctx context.Context, pageID, apiKey strin for _, b := range blocks { switch bl := b.(type) { - case *Heading1Block, *Heading2Block, *Heading3Block, *CodeBlock, *EquationBlock, *FileBlock, *ImageBlock, *VideoBlock, *PdfBlock: + case *Heading1Block, *Heading2Block, *Heading3Block, *CodeBlock, *EquationBlock, *FileBlock, *ImageBlock, *VideoBlock, *PdfBlock, *DividerBlock: allBlocks = append(allBlocks, bl) case *ParagraphBlock: if bl.HasChildren { @@ -326,6 +326,13 @@ func (s *Service) getBlocks(ctx context.Context, pageID, apiKey string, paginati continue } blocks = append(blocks, &p) + case Divider: + d := DividerBlock{} + err = json.Unmarshal(buffer, &d) + if err != nil { + continue + } + blocks = append(blocks, &d) } } From 4bbcd0849e21f90474a0650f506e5337ff0e88b2 Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Fri, 2 Dec 2022 00:01:11 +0300 Subject: [PATCH 13/68] GO-475: get table of content Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/notion/api/block/mapper.go | 4 +++ .../block/import/notion/api/block/retrieve.go | 9 ++++- .../import/notion/api/block/tableofcontent.go | 35 +++++++++++++++++++ core/block/import/notion/api/block/text.go | 2 +- core/block/import/notion/api/commonobjects.go | 4 +-- 5 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 core/block/import/notion/api/block/tableofcontent.go diff --git a/core/block/import/notion/api/block/mapper.go b/core/block/import/notion/api/block/mapper.go index 5dc4f83bc..775d04b39 100644 --- a/core/block/import/notion/api/block/mapper.go +++ b/core/block/import/notion/api/block/mapper.go @@ -121,6 +121,10 @@ func (m *Mapper) MapBlocks(blocks []interface{}, notionPageIdsToAnytype, notionD db, id := block.GetDivBlock() anytypeBlocks = append(anytypeBlocks, db) ids = append(ids, id) + case *TableOfContentsBlock: + db, id := block.GetTableOfContentsBlock() + anytypeBlocks = append(anytypeBlocks, db) + ids = append(ids, id) } } return anytypeBlocks, ids diff --git a/core/block/import/notion/api/block/retrieve.go b/core/block/import/notion/api/block/retrieve.go index f3599fb67..9662d5dee 100644 --- a/core/block/import/notion/api/block/retrieve.go +++ b/core/block/import/notion/api/block/retrieve.go @@ -57,7 +57,7 @@ func (s *Service) GetBlocksAndChildren(ctx context.Context, pageID, apiKey strin for _, b := range blocks { switch bl := b.(type) { - case *Heading1Block, *Heading2Block, *Heading3Block, *CodeBlock, *EquationBlock, *FileBlock, *ImageBlock, *VideoBlock, *PdfBlock, *DividerBlock: + case *Heading1Block, *Heading2Block, *Heading3Block, *CodeBlock, *EquationBlock, *FileBlock, *ImageBlock, *VideoBlock, *PdfBlock, *DividerBlock, *TableOfContentsBlock: allBlocks = append(allBlocks, bl) case *ParagraphBlock: if bl.HasChildren { @@ -333,6 +333,13 @@ func (s *Service) getBlocks(ctx context.Context, pageID, apiKey string, paginati continue } blocks = append(blocks, &d) + case TableOfContents: + t := TableOfContentsBlock{} + err = json.Unmarshal(buffer, &t) + if err != nil { + continue + } + blocks = append(blocks, &t) } } diff --git a/core/block/import/notion/api/block/tableofcontent.go b/core/block/import/notion/api/block/tableofcontent.go new file mode 100644 index 000000000..3b175f9b0 --- /dev/null +++ b/core/block/import/notion/api/block/tableofcontent.go @@ -0,0 +1,35 @@ +package block + +import ( + "strings" + + "github.com/globalsign/mgo/bson" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" +) + +type TableOfContentsBlock struct { + Block + TableOfContent TableOfContentsObject `json:"table_of_contents"` +} + +type TableOfContentsObject struct { + Color string `json:"color"` +} + +func (t *TableOfContentsBlock) GetTableOfContentsBlock() (*model.Block, string) { + id := bson.NewObjectId().Hex() + var color string + // Anytype Table Of Content doesn't support different colors of text, only background + if strings.HasSuffix(t.TableOfContent.Color, api.NotionBackgroundColorSuffix) { + color = api.NotionColorToAnytype[t.TableOfContent.Color] + } + return &model.Block{ + Id: id, + BackgroundColor: color, + Content: &model.BlockContentOfTableOfContents{ + TableOfContents: &model.BlockContentTableOfContents{}, + }, + }, id +} diff --git a/core/block/import/notion/api/block/text.go b/core/block/import/notion/api/block/text.go index 6bd7f17c1..ecc32c621 100644 --- a/core/block/import/notion/api/block/text.go +++ b/core/block/import/notion/api/block/text.go @@ -129,7 +129,7 @@ func (t *TextObject) GetTextBlocks(style model.BlockContentTextStyle, childIds [ } } var backgroundColor string - if strings.Contains(t.Color, api.NotionBackgroundColorPrefix) { + if strings.Contains(t.Color, api.NotionBackgroundColorSuffix) { backgroundColor = api.NotionColorToAnytype[t.Color] } diff --git a/core/block/import/notion/api/commonobjects.go b/core/block/import/notion/api/commonobjects.go index e559a6c7e..e3b19a540 100644 --- a/core/block/import/notion/api/commonobjects.go +++ b/core/block/import/notion/api/commonobjects.go @@ -16,7 +16,7 @@ const ( Text richTextType = "text" Mention richTextType = "mention" Equation richTextType = "equation" - NotionBackgroundColorPrefix = "background" + NotionBackgroundColorSuffix = "background" ) // RichText represent RichText object from Notion https://developers.notion.com/reference/rich-text @@ -97,7 +97,7 @@ func (rt *RichText) BuildMarkdownFromAnnotations(from, to int32) []*model.BlockC } if rt.Annotations.Color != "" { markType := model.BlockContentTextMark_TextColor - if strings.Contains(rt.Annotations.Color, NotionBackgroundColorPrefix) { + if strings.Contains(rt.Annotations.Color, NotionBackgroundColorSuffix) { markType = model.BlockContentTextMark_BackgroundColor } marks = append(marks, &model.BlockContentTextMark{ From 0afd6006f19b34bed783ff281fbb9a56618ea554 Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Fri, 2 Dec 2022 18:39:01 +0300 Subject: [PATCH 14/68] GO-475: fix comments Signed-off-by: AnastasiaShemyakinskaya --- .../block/import/notion/api/block/retrieve.go | 56 +++++++++++++------ core/block/import/notion/api/block/text.go | 2 +- core/block/import/notion/api/commonobjects.go | 11 ++-- 3 files changed, 45 insertions(+), 24 deletions(-) diff --git a/core/block/import/notion/api/block/retrieve.go b/core/block/import/notion/api/block/retrieve.go index 9662d5dee..82842ef56 100644 --- a/core/block/import/notion/api/block/retrieve.go +++ b/core/block/import/notion/api/block/retrieve.go @@ -9,6 +9,8 @@ import ( "net/http" "strconv" + "go.uber.org/zap" + "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" "github.com/anytypeio/go-anytype-middleware/pb" @@ -215,128 +217,146 @@ func (s *Service) getBlocks(ctx context.Context, pageID, apiKey string, paginati blockMap := b.(map[string]interface{}) switch BlockType(blockMap["type"].(string)) { case Paragraph: - p := ParagraphBlock{} + var p ParagraphBlock err = json.Unmarshal(buffer, &p) if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) continue } blocks = append(blocks, &p) case Heading1: - h := Heading1Block{} + var h Heading1Block err = json.Unmarshal(buffer, &h) if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) continue } blocks = append(blocks, &h) case Heading2: - h := Heading2Block{} + var h Heading2Block err = json.Unmarshal(buffer, &h) if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) continue } blocks = append(blocks, &h) case Heading3: - h := Heading3Block{} + var h Heading3Block err = json.Unmarshal(buffer, &h) if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) continue } blocks = append(blocks, &h) case Callout: - c := CalloutBlock{} + var c CalloutBlock err = json.Unmarshal(buffer, &c) if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) continue } blocks = append(blocks, &c) case Quote: - q := QuoteBlock{} + var q QuoteBlock err = json.Unmarshal(buffer, &q) if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) continue } blocks = append(blocks, &q) case BulletList: - list := BulletedListBlock{} + var list BulletedListBlock err = json.Unmarshal(buffer, &list) if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) continue } blocks = append(blocks, &list) case NumberList: - nl := NumberedListBlock{} + var nl NumberedListBlock err = json.Unmarshal(buffer, &nl) if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) continue } blocks = append(blocks, &nl) case Toggle: - t := ToggleBlock{} + var t ToggleBlock err = json.Unmarshal(buffer, &t) if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) continue } blocks = append(blocks, &t) case Code: - c := CodeBlock{} + var c CodeBlock err = json.Unmarshal(buffer, &c) if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) continue } blocks = append(blocks, &c) case Equation: - e := EquationBlock{} + var e EquationBlock err = json.Unmarshal(buffer, &e) if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) continue } blocks = append(blocks, &e) case ToDo: - t := ToDoBlock{} + var t ToDoBlock err = json.Unmarshal(buffer, &t) if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) continue } blocks = append(blocks, &t) case File: - f := FileBlock{} + var f FileBlock err = json.Unmarshal(buffer, &f) if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) continue } blocks = append(blocks, &f) case Image: - i := ImageBlock{} + var i ImageBlock err = json.Unmarshal(buffer, &i) if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) continue } blocks = append(blocks, &i) case Video: - v := VideoBlock{} + var v VideoBlock err = json.Unmarshal(buffer, &v) if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) continue } blocks = append(blocks, &v) case Pdf: - p := PdfBlock{} + var p PdfBlock err = json.Unmarshal(buffer, &p) if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) continue } blocks = append(blocks, &p) case Divider: - d := DividerBlock{} + var d DividerBlock err = json.Unmarshal(buffer, &d) if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) continue } blocks = append(blocks, &d) case TableOfContents: - t := TableOfContentsBlock{} + var t TableOfContentsBlock err = json.Unmarshal(buffer, &t) if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) continue } blocks = append(blocks, &t) diff --git a/core/block/import/notion/api/block/text.go b/core/block/import/notion/api/block/text.go index ecc32c621..a47404b5f 100644 --- a/core/block/import/notion/api/block/text.go +++ b/core/block/import/notion/api/block/text.go @@ -129,7 +129,7 @@ func (t *TextObject) GetTextBlocks(style model.BlockContentTextStyle, childIds [ } } var backgroundColor string - if strings.Contains(t.Color, api.NotionBackgroundColorSuffix) { + if strings.HasSuffix(t.Color, api.NotionBackgroundColorSuffix) { backgroundColor = api.NotionColorToAnytype[t.Color] } diff --git a/core/block/import/notion/api/commonobjects.go b/core/block/import/notion/api/commonobjects.go index e3b19a540..6fb1fc2ea 100644 --- a/core/block/import/notion/api/commonobjects.go +++ b/core/block/import/notion/api/commonobjects.go @@ -13,12 +13,13 @@ import ( type richTextType string const ( - Text richTextType = "text" - Mention richTextType = "mention" - Equation richTextType = "equation" - NotionBackgroundColorSuffix = "background" + Text richTextType = "text" + Mention richTextType = "mention" + Equation richTextType = "equation" ) +const NotionBackgroundColorSuffix = "background" + // RichText represent RichText object from Notion https://developers.notion.com/reference/rich-text type RichText struct { Type richTextType `json:"type,omitempty"` @@ -97,7 +98,7 @@ func (rt *RichText) BuildMarkdownFromAnnotations(from, to int32) []*model.BlockC } if rt.Annotations.Color != "" { markType := model.BlockContentTextMark_TextColor - if strings.Contains(rt.Annotations.Color, NotionBackgroundColorSuffix) { + if strings.HasSuffix(rt.Annotations.Color, NotionBackgroundColorSuffix) { markType = model.BlockContentTextMark_BackgroundColor } marks = append(marks, &model.BlockContentTextMark{ From 1510ae7d101acd3608d3dd3169a025c5910cad09 Mon Sep 17 00:00:00 2001 From: Anastasia Shemyakinskaya <36507473+AnastasiaShemyakinskaya@users.noreply.github.com> Date: Mon, 12 Dec 2022 20:28:06 +0300 Subject: [PATCH 15/68] GO-476: retrieve link object from notion api (#1636) Signed-off-by: AnastasiaShemyakinskaya --- .github/workflows/golangci-lint.yml | 2 +- .golangci.yml | 7 +- Makefile | 8 +- core/block/import/converter/types.go | 9 + core/block/import/importer.go | 8 +- core/block/import/importer_test.go | 14 +- core/block/import/mock.go | 4 +- core/block/import/notion/api/block/block.go | 37 ++ core/block/import/notion/api/block/div.go | 13 +- core/block/import/notion/api/block/file.go | 37 +- core/block/import/notion/api/block/link.go | 157 ++++++ .../import/notion/api/block/link_test.go | 36 ++ core/block/import/notion/api/block/mapper.go | 167 ++----- .../block/import/notion/api/block/retrieve.go | 159 +++--- .../import/notion/api/block/tableofcontent.go | 11 +- core/block/import/notion/api/block/text.go | 389 +++++++-------- .../import/notion/api/block/text_test.go | 86 ++-- .../import/notion/api/block/textobject.go | 259 ++++++++++ core/block/import/notion/api/commonobjects.go | 16 +- .../import/notion/api/database/database.go | 2 +- core/block/import/notion/api/page/page.go | 156 +++--- .../block/import/notion/api/page/page_test.go | 171 ++++--- .../block/import/notion/api/page/pageslink.go | 53 ++ .../notion/api/property/detailsetter.go | 27 -- .../notion/api/property/propertyitem.go | 458 ++++++++++++++---- .../notion/api/property/propertyobject.go | 314 +----------- .../notion/api/property/propertyvalue.go | 418 ---------------- .../import/notion/api/search/search_test.go | 331 ++++++++++--- core/block/import/notion/converter.go | 26 +- core/block/import/objectcreator.go | 78 +-- core/block/import/relationcreator.go | 131 +++-- core/block/import/types.go | 7 +- 32 files changed, 1995 insertions(+), 1596 deletions(-) create mode 100644 core/block/import/notion/api/block/link.go create mode 100644 core/block/import/notion/api/block/link_test.go create mode 100644 core/block/import/notion/api/block/textobject.go create mode 100644 core/block/import/notion/api/page/pageslink.go delete mode 100644 core/block/import/notion/api/property/detailsetter.go delete mode 100644 core/block/import/notion/api/property/propertyvalue.go diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 4932557bd..e8911178b 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -19,4 +19,4 @@ jobs: with: version: latest only-new-issues: true - args: --timeout 15m \ No newline at end of file + args: --timeout 15m --skip-files ".*_test.go" \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml index a6fc1f043..e8085aaac 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -10,6 +10,11 @@ un: go: '1.18' linters-settings: + lll: + line-length: 150 + funlen: + lines: 100 + statements: 50 errcheck: check-blank: true errchkjson: @@ -44,14 +49,12 @@ linters: - nestif - prealloc - revive - - wsl - unused - errcheck - funlen - gosimple - govet - typecheck - - stylecheck - unconvert max-issues-per-linter: 0 diff --git a/Makefile b/Makefile index 8e7f88ebb..790686e90 100644 --- a/Makefile +++ b/Makefile @@ -248,14 +248,14 @@ install-linter: run-linter: ifdef GOLANGCI_LINT_BRANCH - @golangci-lint run -v ./... --new-from-rev=$(GOLANGCI_LINT_BRANCH) --timeout 15m + @golangci-lint run -v ./... --new-from-rev=$(GOLANGCI_LINT_BRANCH) --timeout 15m --skip-files ".*_test.go" else - @golangci-lint run -v ./... --new-from-rev=master --timeout 15m + @golangci-lint run -v ./... --new-from-rev=master --timeout 15m --skip-files ".*_test.go" endif run-linter-fix: ifdef GOLANGCI_LINT_BRANCH - @golangci-lint run -v ./... --new-from-rev=$(GOLANGCI_LINT_BRANCH) --timeout 15m --fix + @golangci-lint run -v ./... --new-from-rev=$(GOLANGCI_LINT_BRANCH) --timeout 15m --skip-files ".*_test.go" --fix else - @golangci-lint run -v ./... --new-from-rev=master --timeout 15m --fix + @golangci-lint run -v ./... --new-from-rev=master --timeout 15m --skip-files ".*_test.go" --fix endif \ No newline at end of file diff --git a/core/block/import/converter/types.go b/core/block/import/converter/types.go index 2e3986fb5..076774c49 100644 --- a/core/block/import/converter/types.go +++ b/core/block/import/converter/types.go @@ -41,9 +41,18 @@ type Snapshot struct { Snapshot *model.SmartBlockSnapshotBase } +// Relation incapsulate name and relations format. We need this structure, so we don't create relations in Anytype +// during GetSnapshots step in converter and create them in RelationCreator +type Relation struct { + BlockID string // if relations is used as a block + Name string + Format model.RelationFormat +} + // Response expected response of each converter, incapsulate blocks snapshots and converting errors type Response struct { Snapshots []*Snapshot + Relations map[string][]*Relation // object id to its relations Error ConvertError } diff --git a/core/block/import/importer.go b/core/block/import/importer.go index 199a66cd8..9c0190687 100644 --- a/core/block/import/importer.go +++ b/core/block/import/importer.go @@ -177,7 +177,11 @@ func (i *Import) createObjects(ctx *session.Context, res *converter.Response, pr default: } progress.AddDone(1) - detail, err := i.oc.Create(ctx, snapshot.Snapshot, snapshot.Id, sbType, req.UpdateExistingObjects) + var relations []*converter.Relation + if res.Relations != nil { + relations = res.Relations[snapshot.Id] + } + detail, err := i.oc.Create(ctx, snapshot.Snapshot, relations, snapshot.Id, sbType, req.UpdateExistingObjects) if err != nil { allErrors[getFileName(snapshot)] = err if req.Mode != pb.RpcObjectImportRequest_IGNORE_ERRORS { @@ -192,4 +196,4 @@ func (i *Import) createObjects(ctx *session.Context, res *converter.Response, pr func convertType(cType string) pb.RpcObjectImportListImportResponseType { return pb.RpcObjectImportListImportResponseType(pb.RpcObjectImportListImportResponseType_value[cType]) -} \ No newline at end of file +} diff --git a/core/block/import/importer_test.go b/core/block/import/importer_test.go index fd395eddd..2e5825450 100644 --- a/core/block/import/importer_test.go +++ b/core/block/import/importer_test.go @@ -38,7 +38,7 @@ func Test_ImportSuccess(t *testing.T) { i.converters = make(map[string]cv.Converter, 0) i.converters["Notion"] = converter creator := NewMockCreator(ctrl) - creator.EXPECT().Create(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + creator.EXPECT().Create(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) i.oc = creator err := i.Import(session.NewContext(), &pb.RpcObjectImportRequest{ @@ -99,7 +99,7 @@ func Test_ImportErrorFromObjectCreator(t *testing.T) { i.converters = make(map[string]cv.Converter, 0) i.converters["Notion"] = converter creator := NewMockCreator(ctrl) - creator.EXPECT().Create(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("creator error")).Times(1) + creator.EXPECT().Create(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("creator error")).Times(1) i.oc = creator res := i.Import(session.NewContext(), &pb.RpcObjectImportRequest{ @@ -137,7 +137,7 @@ func Test_ImportIgnoreErrorMode(t *testing.T) { i.converters = make(map[string]cv.Converter, 0) i.converters["Notion"] = converter creator := NewMockCreator(ctrl) - creator.EXPECT().Create(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + creator.EXPECT().Create(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) i.oc = creator res := i.Import(session.NewContext(), &pb.RpcObjectImportRequest{ @@ -175,7 +175,7 @@ func Test_ImportIgnoreErrorModeWithTwoErrorsPerFile(t *testing.T) { i.converters = make(map[string]cv.Converter, 0) i.converters["Notion"] = converter creator := NewMockCreator(ctrl) - creator.EXPECT().Create(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("creator error")).Times(1) + creator.EXPECT().Create(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("creator error")).Times(1) i.oc = creator res := i.Import(session.NewContext(), &pb.RpcObjectImportRequest{ @@ -198,7 +198,7 @@ func Test_ImportExternalPlugin(t *testing.T) { i.converters = make(map[string]cv.Converter, 0) creator := NewMockCreator(ctrl) - creator.EXPECT().Create(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + creator.EXPECT().Create(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) i.oc = creator snapshots := make([]*pb.RpcObjectImportRequestSnapshot, 0) @@ -327,7 +327,7 @@ func Test_ImportWebSuccess(t *testing.T) { i.converters = make(map[string]cv.Converter, 0) creator := NewMockCreator(ctrl) - creator.EXPECT().Create(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + creator.EXPECT().Create(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) i.oc = creator parser := parsers.NewMockParser(ctrl) @@ -365,7 +365,7 @@ func Test_ImportWebFailedToCreateObject(t *testing.T) { i.converters = make(map[string]cv.Converter, 0) creator := NewMockCreator(ctrl) - creator.EXPECT().Create(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")).Times(1) + creator.EXPECT().Create(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("error")).Times(1) i.oc = creator parser := parsers.NewMockParser(ctrl) diff --git a/core/block/import/mock.go b/core/block/import/mock.go index 07403e2ce..42e49c7f8 100644 --- a/core/block/import/mock.go +++ b/core/block/import/mock.go @@ -188,7 +188,7 @@ func (m *MockCreator) EXPECT() *MockCreatorMockRecorder { } // Create mocks base method. -func (m *MockCreator) Create(ctx *session.Context, cs *model.SmartBlockSnapshotBase, pageID string, sbType smartblock.SmartBlockType, updateExisting bool) (*types.Struct, error) { +func (m *MockCreator) Create(ctx *session.Context, cs *model.SmartBlockSnapshotBase, relations []*converter.Relation, pageID string, sbType smartblock.SmartBlockType, updateExisting bool) (*types.Struct, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Create", ctx, cs, pageID, sbType, updateExisting) ret0, _ := ret[0].(*types.Struct) @@ -197,7 +197,7 @@ func (m *MockCreator) Create(ctx *session.Context, cs *model.SmartBlockSnapshotB } // Create indicates an expected call of Create. -func (mr *MockCreatorMockRecorder) Create(ctx, cs, pageID, sbType, updateExisting interface{}) *gomock.Call { +func (mr *MockCreatorMockRecorder) Create(ctx, cs, relations, pageID, sbType, updateExisting interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockCreator)(nil).Create), ctx, cs, pageID, sbType, updateExisting) } diff --git a/core/block/import/notion/api/block/block.go b/core/block/import/notion/api/block/block.go index e9867d1ac..ed18547d4 100644 --- a/core/block/import/notion/api/block/block.go +++ b/core/block/import/notion/api/block/block.go @@ -1,7 +1,10 @@ package block import ( + "github.com/globalsign/mgo/bson" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" ) type BlockType string @@ -52,3 +55,37 @@ type Block struct { HasChildren bool `json:"has_children"` Type BlockType `json:"type"` } + +type Identifiable interface { + GetID() string +} + +type ChildSetter interface { + Identifiable + HasChild() bool + SetChildren(children []interface{}) +} + +type Getter interface { + GetBlocks(req *MapRequest) *MapResponse +} + +const unsupportedBlockMessage = "Unsupported block" + +type UnsupportedBlock struct{} + +func (*UnsupportedBlock) GetBlocks(req *MapRequest) *MapResponse { + id := bson.NewObjectId().Hex() + bl := &model.Block{ + Id: id, + Content: &model.BlockContentOfText{ + Text: &model.BlockContentText{ + Text: unsupportedBlockMessage, + }, + }, + } + return &MapResponse{ + Blocks: []*model.Block{bl}, + BlockIDs: []string{id}, + } +} diff --git a/core/block/import/notion/api/block/div.go b/core/block/import/notion/api/block/div.go index 263aa3d18..bfd7e4aa4 100644 --- a/core/block/import/notion/api/block/div.go +++ b/core/block/import/notion/api/block/div.go @@ -1,8 +1,9 @@ package block import ( - "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" "github.com/globalsign/mgo/bson" + + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" ) type DividerBlock struct { @@ -10,14 +11,18 @@ type DividerBlock struct { Divider struct{} `json:"divider"` } -func (*DividerBlock) GetDivBlock() (*model.Block, string) { +func (*DividerBlock) GetBlocks(*MapRequest) *MapResponse { id := bson.NewObjectId().Hex() - return &model.Block{ + block := &model.Block{ Id: id, Content: &model.BlockContentOfDiv{ Div: &model.BlockContentDiv{ Style: 0, }, }, - }, id + } + return &MapResponse{ + Blocks: []*model.Block{block}, + BlockIDs: []string{id}, + } } diff --git a/core/block/import/notion/api/block/file.go b/core/block/import/notion/api/block/file.go index 20056c56c..b3ffb486c 100644 --- a/core/block/import/notion/api/block/file.go +++ b/core/block/import/notion/api/block/file.go @@ -1,6 +1,9 @@ package block -import "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" +import ( + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" +) type FileBlock struct { Block @@ -8,17 +11,49 @@ type FileBlock struct { Caption []api.RichText `json:"caption"` } +func (f *FileBlock) GetBlocks(*MapRequest) *MapResponse { + block, id := f.File.GetFileBlock(model.BlockContentFile_File) + return &MapResponse{ + Blocks: []*model.Block{block}, + BlockIDs: []string{id}, + } +} + type ImageBlock struct { Block File api.FileObject `json:"image"` } +func (i *ImageBlock) GetBlocks(*MapRequest) *MapResponse { + block, id := i.File.GetFileBlock(model.BlockContentFile_Image) + return &MapResponse{ + Blocks: []*model.Block{block}, + BlockIDs: []string{id}, + } +} + type PdfBlock struct { Block File api.FileObject `json:"pdf"` } +func (p *PdfBlock) GetBlocks(*MapRequest) *MapResponse { + block, id := p.File.GetFileBlock(model.BlockContentFile_PDF) + return &MapResponse{ + Blocks: []*model.Block{block}, + BlockIDs: []string{id}, + } +} + type VideoBlock struct { Block File api.FileObject `json:"video"` } + +func (p *VideoBlock) GetBlocks(*MapRequest) *MapResponse { + block, id := p.File.GetFileBlock(model.BlockContentFile_Video) + return &MapResponse{ + Blocks: []*model.Block{block}, + BlockIDs: []string{id}, + } +} diff --git a/core/block/import/notion/api/block/link.go b/core/block/import/notion/api/block/link.go new file mode 100644 index 000000000..21b9e1569 --- /dev/null +++ b/core/block/import/notion/api/block/link.go @@ -0,0 +1,157 @@ +package block + +import ( + "strings" + + "github.com/globalsign/mgo/bson" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" + textUtil "github.com/anytypeio/go-anytype-middleware/util/text" +) + +const notFoundPageMessage = "Can't access object in Notion, please provide access in API" + +type EmbedBlock struct { + Block + Embed LinkToWeb `json:"embed"` +} + +type LinkToWeb struct { + URL string `json:"url"` +} + +type LinkPreviewBlock struct { + Block + LinkPreview LinkToWeb `json:"link_preview"` +} + +func (b *LinkToWeb) GetBlocks(*MapRequest) *MapResponse { + id := bson.NewObjectId().Hex() + + to := textUtil.UTF16RuneCountString(b.URL) + + bl := &model.Block{ + Id: id, + ChildrenIds: nil, + Content: &model.BlockContentOfText{ + Text: &model.BlockContentText{ + Text: b.URL, + Marks: &model.BlockContentTextMarks{ + Marks: []*model.BlockContentTextMark{ + { + Range: &model.Range{ + From: int32(0), + To: int32(to), + }, + Type: model.BlockContentTextMark_Link, + Param: b.URL, + }, + }, + }, + }, + }, + } + return &MapResponse{ + Blocks: []*model.Block{bl}, + BlockIDs: []string{id}, + } +} + +type ChildPageBlock struct { + Block + ChildPage Child `json:"child_page"` +} + +func (b *ChildPageBlock) GetBlocks(req *MapRequest) *MapResponse { + bl, id := b.ChildPage.GetLinkToObjectBlock(req.NotionPageIdsToAnytype, req.PageNameToID) + return &MapResponse{ + Blocks: []*model.Block{bl}, + BlockIDs: []string{id}, + } +} + +type ChildDatabaseBlock struct { + Block + ChildDatabase Child `json:"child_database"` +} + +func (b *ChildDatabaseBlock) GetBlocks(req *MapRequest) *MapResponse { + bl, id := b.ChildDatabase.GetLinkToObjectBlock(req.NotionDatabaseIdsToAnytype, req.DatabaseNameToID) + return &MapResponse{ + Blocks: []*model.Block{bl}, + BlockIDs: []string{id}, + } +} + +type Child struct { + Title string `json:"title"` +} + +func (c *Child) GetLinkToObjectBlock(notionIdsToAnytype, idToName map[string]string) (*model.Block, string) { + var ( + targetBlockID string + ok bool + ) + for id, name := range idToName { + if strings.EqualFold(name, c.Title) { + if len(notionIdsToAnytype) > 0 { + targetBlockID, ok = notionIdsToAnytype[id] + } + break + } + } + + id := bson.NewObjectId().Hex() + if !ok { + return &model.Block{ + Id: id, + ChildrenIds: nil, + Content: &model.BlockContentOfText{ + Text: &model.BlockContentText{ + Text: notFoundPageMessage, + Marks: &model.BlockContentTextMarks{ + Marks: []*model.BlockContentTextMark{}, + }, + }, + }, + }, id + } + + return &model.Block{ + Id: id, + ChildrenIds: nil, + Content: &model.BlockContentOfLink{ + Link: &model.BlockContentLink{ + TargetBlockId: targetBlockID, + }, + }}, id +} + +type LinkToPageBlock struct { + Block + LinkToPage api.Parent `json:"link_to_page"` +} + +func (l *LinkToPageBlock) GetBlocks(req *MapRequest) *MapResponse { + var anytypeID string + if l.LinkToPage.PageID != "" { + anytypeID = req.NotionPageIdsToAnytype[l.LinkToPage.PageID] + } + if l.LinkToPage.DatabaseID != "" { + anytypeID = req.NotionDatabaseIdsToAnytype[l.LinkToPage.DatabaseID] + } + id := bson.NewObjectId().Hex() + bl := &model.Block{ + Id: id, + ChildrenIds: nil, + Content: &model.BlockContentOfLink{ + Link: &model.BlockContentLink{ + TargetBlockId: anytypeID, + }, + }} + return &MapResponse{ + Blocks: []*model.Block{bl}, + BlockIDs: []string{id}, + } +} diff --git a/core/block/import/notion/api/block/link_test.go b/core/block/import/notion/api/block/link_test.go new file mode 100644 index 000000000..ff12cca77 --- /dev/null +++ b/core/block/import/notion/api/block/link_test.go @@ -0,0 +1,36 @@ +package block + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" +) + +func Test_GetLinkToObjectBlockSuccess(t *testing.T) { + c := &Child{Title: "title"} + nameToID := map[string]string{"id": "title"} + notionIdsToAnytype := map[string]string{"id": "anytypeId"} + bl, _ := c.GetLinkToObjectBlock(notionIdsToAnytype, nameToID) + assert.NotNil(t, bl) + content, ok := bl.Content.(*model.BlockContentOfLink) + assert.True(t, ok) + assert.Equal(t, content.Link.TargetBlockId, "anytypeId") +} + +func Test_GetLinkToObjectBlockFail(t *testing.T) { + c := &Child{Title: "title"} + bl, _ := c.GetLinkToObjectBlock(nil, nil) + assert.NotNil(t, bl) + content, ok := bl.Content.(*model.BlockContentOfText) + assert.True(t, ok) + assert.Equal(t, content.Text.Text, notFoundPageMessage) + + nameToID := map[string]string{"id": "title"} + bl, _ = c.GetLinkToObjectBlock(nameToID, nil) + assert.NotNil(t, bl) + content, ok = bl.Content.(*model.BlockContentOfText) + assert.True(t, ok) + assert.Equal(t, content.Text.Text, notFoundPageMessage) +} diff --git a/core/block/import/notion/api/block/mapper.go b/core/block/import/notion/api/block/mapper.go index 775d04b39..9430639cb 100644 --- a/core/block/import/notion/api/block/mapper.go +++ b/core/block/import/notion/api/block/mapper.go @@ -1,131 +1,56 @@ package block import ( + "github.com/gogo/protobuf/types" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" ) -type Mapper struct{} +// MapRequest is a data object with all necessary structures for blocks +type MapRequest struct { + Blocks []interface{} + // Need all these maps for correct mapping of pages and databases from notion to anytype + // for such blocks as mentions or links to objects + NotionPageIdsToAnytype map[string]string + NotionDatabaseIdsToAnytype map[string]string + PageNameToID map[string]string + DatabaseNameToID map[string]string +} -func (m *Mapper) MapBlocks(blocks []interface{}, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID map[string]string) ([]*model.Block, []string) { - var ( - anytypeBlocks = make([]*model.Block, 0) - ids = make([]string, 0) - ) - for _, bl := range blocks { - switch block := bl.(type) { - case *ParagraphBlock: - childIds := make([]string, 0) - var childBlocks []*model.Block - if block.HasChildren { - childBlocks, childIds = m.MapBlocks(block.Paragraph.Children, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) - } - allBlocks, blockIDs := block.Paragraph.GetTextBlocks(model.BlockContentText_Paragraph, childIds, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) - anytypeBlocks = append(anytypeBlocks, allBlocks...) - anytypeBlocks = append(anytypeBlocks, childBlocks...) - ids = append(ids, blockIDs...) - case *Heading1Block: - allBlocks, blockIDs := block.Heading1.GetTextBlocks(model.BlockContentText_Header1, []string{}, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) - anytypeBlocks = append(anytypeBlocks, allBlocks...) - ids = append(ids, blockIDs...) - case *Heading2Block: - allBlocks, blockIDs := block.Heading2.GetTextBlocks(model.BlockContentText_Header2, []string{}, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) - anytypeBlocks = append(anytypeBlocks, allBlocks...) - ids = append(ids, blockIDs...) - case *Heading3Block: - allBlocks, blockIDs := block.Heading3.GetTextBlocks(model.BlockContentText_Header3, []string{}, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) - anytypeBlocks = append(anytypeBlocks, allBlocks...) - ids = append(ids, blockIDs...) - case *CalloutBlock: - childIds := make([]string, 0) - var childBlocks []*model.Block - if block.HasChildren { - childBlocks, childIds = m.MapBlocks(block.Callout.Children, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) - } - calloutBlocks, blockIDs := block.Callout.GetCalloutBlocks(childIds) - anytypeBlocks = append(anytypeBlocks, calloutBlocks...) - anytypeBlocks = append(anytypeBlocks, childBlocks...) - ids = append(ids, blockIDs...) - case *QuoteBlock: - childIds := make([]string, 0) - var childBlocks []*model.Block - if block.HasChildren { - childBlocks, childIds = m.MapBlocks(block.Quote.Children, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) - } - allBlocks, blockIDs := block.Quote.GetTextBlocks(model.BlockContentText_Quote, childIds, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) - anytypeBlocks = append(anytypeBlocks, allBlocks...) - anytypeBlocks = append(anytypeBlocks, childBlocks...) - ids = append(ids, blockIDs...) - case *BulletedListBlock: - childIds := make([]string, 0) - var childBlocks []*model.Block - if block.HasChildren { - childBlocks, childIds = m.MapBlocks(block.BulletedList.Children, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) - } - allBlocks, blockIDs := block.BulletedList.GetTextBlocks(model.BlockContentText_Marked, childIds, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) - anytypeBlocks = append(anytypeBlocks, allBlocks...) - anytypeBlocks = append(anytypeBlocks, childBlocks...) - ids = append(ids, blockIDs...) - case *NumberedListBlock: - childIds := make([]string, 0) - var childBlocks []*model.Block - if block.HasChildren { - childBlocks, childIds = m.MapBlocks(block.NumberedList.Children, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) - } - allBlocks, blockIDs := block.NumberedList.GetTextBlocks(model.BlockContentText_Numbered, childIds, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) - anytypeBlocks = append(anytypeBlocks, allBlocks...) - anytypeBlocks = append(anytypeBlocks, childBlocks...) - ids = append(ids, blockIDs...) - case *ToggleBlock: - childIds := make([]string, 0) - var childBlocks []*model.Block - if block.HasChildren { - childBlocks, childIds = m.MapBlocks(block.Toggle.Children, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) - } - allBlocks, blockIDs := block.Toggle.GetTextBlocks(model.BlockContentText_Toggle, childIds, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) - anytypeBlocks = append(anytypeBlocks, allBlocks...) - anytypeBlocks = append(anytypeBlocks, childBlocks...) - ids = append(ids, blockIDs...) - case *CodeBlock: - c := bl.(*CodeBlock) - anytypeBlocks = append(anytypeBlocks, c.Code.GetCodeBlock()) - case *EquationBlock: - e := bl.(*EquationBlock) - anytypeBlocks = append(anytypeBlocks, e.Equation.HandleEquation()) - case *ToDoBlock: - childIds := make([]string, 0) - var childBlocks []*model.Block - if block.HasChildren { - childBlocks, childIds = m.MapBlocks(block.ToDo.Children, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) - } - allBlocks, blockIDs := block.ToDo.GetTextBlocks(model.BlockContentText_Checkbox, childIds, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) - anytypeBlocks = append(anytypeBlocks, allBlocks...) - anytypeBlocks = append(anytypeBlocks, childBlocks...) - ids = append(ids, blockIDs...) - case *FileBlock: - fileBlock, id := block.File.GetFileBlock(model.BlockContentFile_File) - anytypeBlocks = append(anytypeBlocks, fileBlock) - ids = append(ids, id) - case *ImageBlock: - fileBlock, id := block.File.GetFileBlock(model.BlockContentFile_Image) - anytypeBlocks = append(anytypeBlocks, fileBlock) - ids = append(ids, id) - case *VideoBlock: - fileBlock, id := block.File.GetFileBlock(model.BlockContentFile_Video) - anytypeBlocks = append(anytypeBlocks, fileBlock) - ids = append(ids, id) - case *PdfBlock: - fileBlock, id := block.File.GetFileBlock(model.BlockContentFile_PDF) - anytypeBlocks = append(anytypeBlocks, fileBlock) - ids = append(ids, id) - case *DividerBlock: - db, id := block.GetDivBlock() - anytypeBlocks = append(anytypeBlocks, db) - ids = append(ids, id) - case *TableOfContentsBlock: - db, id := block.GetTableOfContentsBlock() - anytypeBlocks = append(anytypeBlocks, db) - ids = append(ids, id) +type MapResponse struct { + Blocks []*model.Block + Relations []*converter.Relation + Details map[string]*types.Value + BlockIDs []string +} + +func (m *MapResponse) Merge(mergedResp *MapResponse) { + if mergedResp != nil { + m.BlockIDs = append(m.BlockIDs, mergedResp.BlockIDs...) + m.Relations = append(m.Relations, mergedResp.Relations...) + m.Blocks = append(m.Blocks, mergedResp.Blocks...) + m.MergeDetails(mergedResp.Details) + } +} + +func (m *MapResponse) MergeDetails(mergeDetails map[string]*types.Value) { + if m.Details == nil { + m.Details = make(map[string]*types.Value, 0) + } + for k, v := range mergeDetails { + m.Details[k] = v + } +} + +func MapBlocks(req *MapRequest) *MapResponse { + resp := &MapResponse{} + for _, bl := range req.Blocks { + if ba, ok := bl.(Getter); ok { + textResp := ba.GetBlocks(req) + resp.Merge(textResp) + continue } } - return anytypeBlocks, ids + return resp } diff --git a/core/block/import/notion/api/block/retrieve.go b/core/block/import/notion/api/block/retrieve.go index 82842ef56..dde37c05b 100644 --- a/core/block/import/notion/api/block/retrieve.go +++ b/core/block/import/notion/api/block/retrieve.go @@ -15,7 +15,6 @@ import ( "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/logging" - "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" ) var logger = logging.Logger("notion-get-blocks") @@ -29,13 +28,11 @@ const ( type Service struct { client *client.Client - mapper *Mapper } func New(client *client.Client) *Service { return &Service{ client: client, - mapper: &Mapper{}, } } @@ -56,103 +53,29 @@ func (s *Service) GetBlocksAndChildren(ctx context.Context, pageID, apiKey strin return nil, ce } } - for _, b := range blocks { - switch bl := b.(type) { - case *Heading1Block, *Heading2Block, *Heading3Block, *CodeBlock, *EquationBlock, *FileBlock, *ImageBlock, *VideoBlock, *PdfBlock, *DividerBlock, *TableOfContentsBlock: - allBlocks = append(allBlocks, bl) - case *ParagraphBlock: - if bl.HasChildren { - children, err := s.GetBlocksAndChildren(ctx, bl.ID, apiKey, pageSize, mode) - if err != nil { - ce.Merge(*err) - if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return nil, ce - } - } - bl.Paragraph.Children = children - } - allBlocks = append(allBlocks, bl) - case *CalloutBlock: - if bl.HasChildren { - children, err := s.GetBlocksAndChildren(ctx, bl.ID, apiKey, pageSize, mode) - if err != nil { - ce.Merge(*err) - if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return nil, ce - } - } - bl.Callout.Children = children - } - allBlocks = append(allBlocks, bl) - case *QuoteBlock: - if bl.HasChildren { - children, err := s.GetBlocksAndChildren(ctx, bl.ID, apiKey, pageSize, mode) - if err != nil { - ce.Merge(*err) - if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return nil, ce - } - } - bl.Quote.Children = children - } - allBlocks = append(allBlocks, bl) - case *BulletedListBlock: - if bl.HasChildren { - children, err := s.GetBlocksAndChildren(ctx, bl.ID, apiKey, pageSize, mode) - if err != nil { - ce.Merge(*err) - if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return nil, ce - } - } - bl.BulletedList.Children = children - } - allBlocks = append(allBlocks, bl) - case *NumberedListBlock: - if bl.HasChildren { - children, err := s.GetBlocksAndChildren(ctx, bl.ID, apiKey, pageSize, mode) - if err != nil { - ce.Merge(*err) - if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return nil, ce - } - } - bl.NumberedList.Children = children - } - allBlocks = append(allBlocks, bl) - case *ToggleBlock: - if bl.HasChildren { - children, err := s.GetBlocksAndChildren(ctx, bl.ID, apiKey, pageSize, mode) - if err != nil { - ce.Merge(*err) - if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return nil, ce - } - } - bl.Toggle.Children = children - } - allBlocks = append(allBlocks, bl) - case *ToDoBlock: - if bl.HasChildren { - children, err := s.GetBlocksAndChildren(ctx, bl.ID, apiKey, pageSize, mode) - if err != nil { - ce.Merge(*err) - if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return nil, ce - } - } - bl.ToDo.Children = children - } - allBlocks = append(allBlocks, bl) + cs, ok := b.(ChildSetter) + if !ok { + allBlocks = append(allBlocks, b) + continue } + if cs.HasChild() { + children, err := s.GetBlocksAndChildren(ctx, cs.GetID(), apiKey, pageSize, mode) + if err != nil { + ce.Merge(*err) + } + if err != nil && mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + return nil, ce + } + cs.SetChildren(children) + } + allBlocks = append(allBlocks, b) } return allBlocks, nil } -func (s *Service) MapNotionBlocksToAnytype(blocks []interface{}, notionPagesIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID map[string]string) []*model.Block { - allBlocks, _ := s.mapper.MapBlocks(blocks, notionPagesIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) - return allBlocks +func (s *Service) MapNotionBlocksToAnytype(req *MapRequest) *MapResponse { + return MapBlocks(req) } func (s *Service) getBlocks(ctx context.Context, pageID, apiKey string, pagination int64) ([]interface{}, error) { @@ -360,6 +283,54 @@ func (s *Service) getBlocks(ctx context.Context, pageID, apiKey string, paginati continue } blocks = append(blocks, &t) + case Embed: + var e EmbedBlock + err = json.Unmarshal(buffer, &e) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + continue + } + blocks = append(blocks, &e) + case LinkPreview: + var lp LinkPreviewBlock + err = json.Unmarshal(buffer, &lp) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + continue + } + blocks = append(blocks, &lp) + case ChildDatabase: + var c ChildDatabaseBlock + err = json.Unmarshal(buffer, &c) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + continue + } + blocks = append(blocks, &c) + case ChildPage: + var c ChildPageBlock + err = json.Unmarshal(buffer, &c) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + continue + } + blocks = append(blocks, &c) + case LinkToPage: + var l LinkToPageBlock + err = json.Unmarshal(buffer, &l) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + continue + } + blocks = append(blocks, &l) + case Unsupported: + var u UnsupportedBlock + err = json.Unmarshal(buffer, &u) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + continue + } + blocks = append(blocks, &u) } } diff --git a/core/block/import/notion/api/block/tableofcontent.go b/core/block/import/notion/api/block/tableofcontent.go index 3b175f9b0..84c39f893 100644 --- a/core/block/import/notion/api/block/tableofcontent.go +++ b/core/block/import/notion/api/block/tableofcontent.go @@ -18,18 +18,23 @@ type TableOfContentsObject struct { Color string `json:"color"` } -func (t *TableOfContentsBlock) GetTableOfContentsBlock() (*model.Block, string) { +func (t *TableOfContentsBlock) GetBlocks(req *MapRequest) *MapResponse { id := bson.NewObjectId().Hex() var color string // Anytype Table Of Content doesn't support different colors of text, only background if strings.HasSuffix(t.TableOfContent.Color, api.NotionBackgroundColorSuffix) { color = api.NotionColorToAnytype[t.TableOfContent.Color] } - return &model.Block{ + + block := &model.Block{ Id: id, BackgroundColor: color, Content: &model.BlockContentOfTableOfContents{ TableOfContents: &model.BlockContentTableOfContents{}, }, - }, id + } + return &MapResponse{ + Blocks: []*model.Block{block}, + BlockIDs: []string{id}, + } } diff --git a/core/block/import/notion/api/block/text.go b/core/block/import/notion/api/block/text.go index a47404b5f..07c697672 100644 --- a/core/block/import/notion/api/block/text.go +++ b/core/block/import/notion/api/block/text.go @@ -1,8 +1,6 @@ package block import ( - "strings" - "github.com/globalsign/mgo/bson" "github.com/gogo/protobuf/types" @@ -17,21 +15,56 @@ type ParagraphBlock struct { Paragraph TextObjectWithChildren `json:"paragraph"` } +func (p *ParagraphBlock) GetBlocks(req *MapRequest) *MapResponse { + childResp := &MapResponse{} + if p.HasChildren { + mapper := ChildrenMapper(&p.Paragraph) + childResp = mapper.MapChildren(req) + } + resp := p.Paragraph.GetTextBlocks(model.BlockContentText_Paragraph, childResp.BlockIDs, req) + resp.Merge(childResp) + return resp +} + +func (p *ParagraphBlock) HasChild() bool { + return p.HasChildren +} + +func (p *ParagraphBlock) SetChildren(children []interface{}) { + p.Paragraph.Children = children +} + +func (p *ParagraphBlock) GetID() string { + return p.ID +} + type Heading1Block struct { Block Heading1 HeadingObject `json:"heading_1"` } +func (h *Heading1Block) GetBlocks(req *MapRequest) *MapResponse { + return h.Heading1.GetTextBlocks(model.BlockContentText_Header1, nil, req) +} + type Heading2Block struct { Block Heading2 HeadingObject `json:"heading_2"` } +func (h *Heading2Block) GetBlocks(req *MapRequest) *MapResponse { + return h.Heading2.GetTextBlocks(model.BlockContentText_Header2, nil, req) +} + type Heading3Block struct { Block Heading3 HeadingObject `json:"heading_3"` } +func (p *Heading3Block) GetBlocks(req *MapRequest) *MapResponse { + return p.Heading3.GetTextBlocks(model.BlockContentText_Header3, nil, req) +} + type HeadingObject struct { TextObject IsToggleable bool `json:"is_toggleable"` @@ -47,21 +80,129 @@ type CalloutObject struct { Icon *api.Icon `json:"icon"` } +func (c *CalloutBlock) GetBlocks(req *MapRequest) *MapResponse { + calloutResp := c.Callout.GetTextBlocks(model.BlockContentText_Callout, nil, req) + extendedBlocks := make([]*model.Block, 0, len(calloutResp.Blocks)) + for _, cb := range calloutResp.Blocks { + text, ok := cb.Content.(*model.BlockContentOfText) + if !ok { + extendedBlocks = append(extendedBlocks, cb) + continue + } + if c.Callout.Icon != nil { + if c.Callout.Icon.Emoji != nil { + text.Text.IconEmoji = *c.Callout.Icon.Emoji + } + if c.Callout.Icon.Type == api.External && c.Callout.Icon.External != nil { + text.Text.IconImage = c.Callout.Icon.External.URL + } + if c.Callout.Icon.Type == api.File && c.Callout.Icon.File != nil { + text.Text.IconImage = c.Callout.Icon.File.URL + } + } + cb.Content = text + extendedBlocks = append(extendedBlocks, cb) + } + calloutResp.Blocks = extendedBlocks + return calloutResp +} + +func (c *CalloutBlock) HasChild() bool { + return c.HasChildren +} + +func (c *CalloutBlock) SetChildren(children []interface{}) { + c.Callout.Children = children +} + +func (c *CalloutBlock) GetID() string { + return c.ID +} + type QuoteBlock struct { Block Quote TextObjectWithChildren `json:"quote"` } +func (q *QuoteBlock) GetBlocks(req *MapRequest) *MapResponse { + childResp := &MapResponse{} + if q.HasChildren { + mapper := ChildrenMapper(&q.Quote) + childResp = mapper.MapChildren(req) + } + resp := q.Quote.GetTextBlocks(model.BlockContentText_Quote, childResp.BlockIDs, req) + resp.Merge(childResp) + return resp +} + +func (q *QuoteBlock) HasChild() bool { + return q.HasChildren +} + +func (q *QuoteBlock) SetChildren(children []interface{}) { + q.Quote.Children = children +} + +func (q *QuoteBlock) GetID() string { + return q.ID +} + type NumberedListBlock struct { Block NumberedList TextObjectWithChildren `json:"bulleted_list_item"` } +func (n *NumberedListBlock) GetBlocks(req *MapRequest) *MapResponse { + childResp := &MapResponse{} + if n.HasChildren { + mapper := ChildrenMapper(&n.NumberedList) + childResp = mapper.MapChildren(req) + } + resp := n.NumberedList.GetTextBlocks(model.BlockContentText_Numbered, childResp.BlockIDs, req) + resp.Merge(childResp) + return resp +} + +func (n *NumberedListBlock) HasChild() bool { + return n.HasChildren +} + +func (n *NumberedListBlock) SetChildren(children []interface{}) { + n.NumberedList.Children = children +} + +func (n *NumberedListBlock) GetID() string { + return n.ID +} + type ToDoBlock struct { Block ToDo ToDoObject `json:"to_do"` } +func (t *ToDoBlock) GetBlocks(req *MapRequest) *MapResponse { + childResp := &MapResponse{} + if t.HasChildren { + mapper := ChildrenMapper(&t.ToDo) + childResp = mapper.MapChildren(req) + } + resp := t.ToDo.GetTextBlocks(model.BlockContentText_Checkbox, childResp.BlockIDs, req) + resp.Merge(childResp) + return resp +} + +func (t *ToDoBlock) HasChild() bool { + return t.HasChildren +} + +func (t *ToDoBlock) SetChildren(children []interface{}) { + t.ToDo.Children = children +} + +func (t *ToDoBlock) GetID() string { + return t.ID +} + type ToDoObject struct { TextObjectWithChildren Checked bool `json:"checked"` @@ -72,212 +213,55 @@ type BulletedListBlock struct { BulletedList TextObjectWithChildren `json:"bulleted_list_item"` } +func (b *BulletedListBlock) GetBlocks(req *MapRequest) *MapResponse { + childResp := &MapResponse{} + if b.HasChildren { + mapper := ChildrenMapper(&b.BulletedList) + childResp = mapper.MapChildren(req) + } + resp := b.BulletedList.GetTextBlocks(model.BlockContentText_Marked, childResp.BlockIDs, req) + resp.Merge(childResp) + return resp +} + +func (b *BulletedListBlock) HasChild() bool { + return b.HasChildren +} + +func (b *BulletedListBlock) SetChildren(children []interface{}) { + b.BulletedList.Children = children +} + +func (b *BulletedListBlock) GetID() string { + return b.ID +} + type ToggleBlock struct { Block Toggle TextObjectWithChildren `json:"toggle"` } -type TextObjectWithChildren struct { - TextObject - Children []interface{} `json:"children"` +func (t *ToggleBlock) GetBlocks(req *MapRequest) *MapResponse { + childResp := &MapResponse{} + if t.HasChildren { + mapper := ChildrenMapper(&t.Toggle) + childResp = mapper.MapChildren(req) + } + resp := t.Toggle.GetTextBlocks(model.BlockContentText_Toggle, childResp.BlockIDs, req) + resp.Merge(childResp) + return resp } -type TextObject struct { - RichText []api.RichText `json:"rich_text"` - Color string `json:"color"` +func (t *ToggleBlock) HasChild() bool { + return t.HasChildren } -func (c *CalloutObject) GetCalloutBlocks(childIds []string) ([]*model.Block, []string) { - calloutBlocks, blockIDs := c.GetTextBlocks(model.BlockContentText_Callout, childIds, nil, nil, nil, nil) - for _, cb := range calloutBlocks { - text, ok := cb.Content.(*model.BlockContentOfText) - if ok { - if c.Icon != nil { - if c.Icon.Emoji != nil { - text.Text.IconEmoji = *c.Icon.Emoji - } - if c.Icon.Type == api.External && c.Icon.External != nil { - text.Text.IconImage = c.Icon.External.URL - } - if c.Icon.Type == api.File && c.Icon.File != nil { - text.Text.IconImage = c.Icon.File.URL - } - } - cb.Content = text - } - } - return calloutBlocks, blockIDs +func (t *ToggleBlock) SetChildren(children []interface{}) { + t.Toggle.Children = children } -func (t *TextObject) GetTextBlocks(style model.BlockContentTextStyle, childIds []string, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID map[string]string) ([]*model.Block, []string) { - marks := []*model.BlockContentTextMark{} - id := bson.NewObjectId().Hex() - allBlocks := make([]*model.Block, 0) - allIds := make([]string, 0) - var text strings.Builder - for _, rt := range t.RichText { - if rt.Type == api.Text { - marks = append(marks, t.handleTextType(rt, &text, notionPageIdsToAnytype, notionDatabaseIdsToAnytype)...) - } - if rt.Type == api.Mention { - marks = append(marks, t.handleMentionType(rt, &text, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID)...) - } - if rt.Type == api.Equation { - eqBlock := rt.Equation.HandleEquation() - allBlocks = append(allBlocks, eqBlock) - allIds = append(allIds, eqBlock.Id) - } - } - var backgroundColor string - if strings.HasSuffix(t.Color, api.NotionBackgroundColorSuffix) { - backgroundColor = api.NotionColorToAnytype[t.Color] - } - - if len(t.RichText) == 1 && t.RichText[0].Type == api.Equation { - return allBlocks, allIds - } - allBlocks = append(allBlocks, &model.Block{ - Id: id, - ChildrenIds: childIds, - BackgroundColor: backgroundColor, - Content: &model.BlockContentOfText{ - Text: &model.BlockContentText{ - Text: text.String(), - Style: style, - Marks: &model.BlockContentTextMarks{Marks: marks}, - Checked: false, - Color: api.NotionColorToAnytype[t.Color], - }, - }, - }) - for _, b := range allBlocks { - allIds = append(allIds, b.Id) - } - return allBlocks, allIds -} - -func (t *TextObject) handleTextType(rt api.RichText, text *strings.Builder, notionPageIdsToAnytype, notionDatabaseIdsToAnytype map[string]string) []*model.BlockContentTextMark { - marks := []*model.BlockContentTextMark{} - from := textUtil.UTF16RuneCountString(text.String()) - if rt.Text != nil && rt.Text.Link != nil && rt.Text.Link.Url != "" { - text.WriteString(rt.Text.Content) - } else { - text.WriteString(rt.PlainText) - } - to := textUtil.UTF16RuneCountString(text.String()) - if rt.Text != nil && rt.Text.Link != nil && rt.Text.Link.Url != "" { - url := strings.Trim(rt.Text.Link.Url, "/") - if databaseID, ok := notionDatabaseIdsToAnytype[url]; ok { - url = databaseID - } - if pageID, ok := notionPageIdsToAnytype[url]; ok { - url = pageID - } - marks = append(marks, &model.BlockContentTextMark{ - Range: &model.Range{ - From: int32(from), - To: int32(to), - }, - Type: model.BlockContentTextMark_Link, - Param: url, - }) - } - marks = append(marks, rt.BuildMarkdownFromAnnotations(int32(from), int32(to))...) - return marks -} - -func (t *TextObject) handleMentionType(rt api.RichText, text *strings.Builder, notionPageIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID map[string]string) []*model.BlockContentTextMark { - if rt.Mention.Type == api.UserMention { - return t.handleUserMention(rt, text) - } - if rt.Mention.Type == api.Database { - return t.handleDatabaseMention(rt, text, notionDatabaseIdsToAnytype, databaseNameToID) - } - if rt.Mention.Type == api.Page { - return t.handlePageMention(rt, text, notionPageIdsToAnytype, pageNameToID) - } - if rt.Mention.Type == api.Date { - return t.handleDateMention(rt, text) - } - if rt.Mention.Type == api.LinkPreview { - return t.handleLinkPreviewMention(rt, text) - } - return nil -} - -func (t *TextObject) handleUserMention(rt api.RichText, text *strings.Builder) []*model.BlockContentTextMark { - from := textUtil.UTF16RuneCountString(text.String()) - text.WriteString(rt.Mention.User.Name) - to := textUtil.UTF16RuneCountString(text.String()) - return rt.BuildMarkdownFromAnnotations(int32(from), int32(to)) -} - -func (t *TextObject) handleDatabaseMention(rt api.RichText, text *strings.Builder, notionDatabaseIdsToAnytype, databaseNameToID map[string]string) []*model.BlockContentTextMark { - if notionDatabaseIdsToAnytype == nil { - return nil - } - from := textUtil.UTF16RuneCountString(text.String()) - text.WriteString(databaseNameToID[rt.Mention.Database.ID]) - to := textUtil.UTF16RuneCountString(text.String()) - marks := rt.BuildMarkdownFromAnnotations(int32(from), int32(to)) - marks = append(marks, &model.BlockContentTextMark{ - Range: &model.Range{ - From: int32(from), - To: int32(to), - }, - Type: model.BlockContentTextMark_Mention, - Param: notionDatabaseIdsToAnytype[rt.Mention.Database.ID], - }) - return marks -} - -func (t *TextObject) handlePageMention(rt api.RichText, text *strings.Builder, notionPageIdsToAnytype, pageNameToID map[string]string) []*model.BlockContentTextMark { - if notionPageIdsToAnytype == nil { - return nil - } - from := textUtil.UTF16RuneCountString(text.String()) - text.WriteString(pageNameToID[rt.Mention.Page.ID]) - to := textUtil.UTF16RuneCountString(text.String()) - marks := rt.BuildMarkdownFromAnnotations(int32(from), int32(to)) - marks = append(marks, &model.BlockContentTextMark{ - Range: &model.Range{ - From: int32(from), - To: int32(to), - }, - Type: model.BlockContentTextMark_Mention, - Param: notionPageIdsToAnytype[rt.Mention.Page.ID], - }) - return marks -} - -func (t *TextObject) handleDateMention(rt api.RichText, text *strings.Builder) []*model.BlockContentTextMark { - var textDate string - if rt.Mention.Date.Start != "" { - textDate = rt.Mention.Date.Start - } - if rt.Mention.Date.End != "" { - textDate += " " + rt.Mention.Date.End - } - from := textUtil.UTF16RuneCountString(text.String()) - text.WriteString(textDate) - to := textUtil.UTF16RuneCountString(text.String()) - marks := rt.BuildMarkdownFromAnnotations(int32(from), int32(to)) - return marks -} - -func (t *TextObject) handleLinkPreviewMention(rt api.RichText, text *strings.Builder) []*model.BlockContentTextMark { - from := textUtil.UTF16RuneCountString(text.String()) - text.WriteString(rt.Mention.LinkPreview.Url) - to := textUtil.UTF16RuneCountString(text.String()) - marks := rt.BuildMarkdownFromAnnotations(int32(from), int32(to)) - marks = append(marks, &model.BlockContentTextMark{ - Range: &model.Range{ - From: int32(from), - To: int32(to), - }, - Type: model.BlockContentTextMark_Link, - }) - return marks +func (t *ToggleBlock) GetID() string { + return t.ID } type CodeBlock struct { @@ -291,17 +275,17 @@ type CodeObject struct { Language string `json:"language"` } -func (c *CodeObject) GetCodeBlock() *model.Block { +func (c *CodeBlock) GetBlocks(req *MapRequest) *MapResponse { id := bson.NewObjectId().Hex() bl := &model.Block{ Id: id, Fields: &types.Struct{ - Fields: map[string]*types.Value{"lang": pbtypes.String(c.Language)}, + Fields: map[string]*types.Value{"lang": pbtypes.String(c.Code.Language)}, }, } marks := []*model.BlockContentTextMark{} var code string - for _, rt := range c.RichText { + for _, rt := range c.Code.RichText { from := textUtil.UTF16RuneCountString(code) code += rt.PlainText to := textUtil.UTF16RuneCountString(code) @@ -316,7 +300,10 @@ func (c *CodeObject) GetCodeBlock() *model.Block { }, }, } - return bl + return &MapResponse{ + Blocks: []*model.Block{bl}, + BlockIDs: []string{id}, + } } type EquationBlock struct { diff --git a/core/block/import/notion/api/block/text_test.go b/core/block/import/notion/api/block/text_test.go index eaa3f285b..43d5fba60 100644 --- a/core/block/import/notion/api/block/text_test.go +++ b/core/block/import/notion/api/block/text_test.go @@ -24,11 +24,11 @@ func Test_GetTextBlocksTextSuccess(t *testing.T) { Color: api.RedBackGround, } - bl, _ := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, nil, nil, nil, nil) - assert.Len(t, bl, 1) - assert.Equal(t, bl[0].GetText().Style, model.BlockContentText_Paragraph) - assert.Equal(t, bl[0].BackgroundColor, api.AnytypeRed) - assert.Equal(t, bl[0].GetText().Text, "testtest2") + bl := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, &MapRequest{}) + assert.Len(t, bl.Blocks, 1) + assert.Equal(t, bl.Blocks[0].GetText().Style, model.BlockContentText_Paragraph) + assert.Equal(t, bl.Blocks[0].BackgroundColor, api.AnytypeRed) + assert.Equal(t, bl.Blocks[0].GetText().Text, "testtest2") } func Test_GetTextBlocksTextUserMention(t *testing.T) { @@ -47,11 +47,11 @@ func Test_GetTextBlocksTextUserMention(t *testing.T) { }, } - bl, _ := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, nil, nil, nil, nil) - assert.Len(t, bl, 1) - assert.Equal(t, bl[0].GetText().Style, model.BlockContentText_Paragraph) - assert.Len(t, bl[0].GetText().Marks.Marks, 0) - assert.Equal(t, bl[0].GetText().Text, "Nastya") + bl := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, &MapRequest{}) + assert.Len(t, bl.Blocks, 1) + assert.Equal(t, bl.Blocks[0].GetText().Style, model.BlockContentText_Paragraph) + assert.Len(t, bl.Blocks[0].GetText().Marks.Marks, 0) + assert.Equal(t, bl.Blocks[0].GetText().Text, "Nastya") } func Test_GetTextBlocksTextPageMention(t *testing.T) { @@ -69,12 +69,15 @@ func Test_GetTextBlocksTextPageMention(t *testing.T) { }, } - bl, _ := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, map[string]string{"notionID": "anytypeID"}, nil, map[string]string{"notionID": "Page"}, nil) - assert.Len(t, bl, 1) - assert.Equal(t, bl[0].GetText().Style, model.BlockContentText_Paragraph) - assert.Len(t, bl[0].GetText().Marks.Marks, 1) - assert.Equal(t, bl[0].GetText().Marks.Marks[0].Type, model.BlockContentTextMark_Mention) - assert.Equal(t, bl[0].GetText().Text, "Page") + bl := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, &MapRequest{ + NotionPageIdsToAnytype: map[string]string{"notionID": "anytypeID"}, + PageNameToID: map[string]string{"notionID": "Page"}, + }) + assert.Len(t, bl.Blocks, 1) + assert.Equal(t, bl.Blocks[0].GetText().Style, model.BlockContentText_Paragraph) + assert.Len(t, bl.Blocks[0].GetText().Marks.Marks, 1) + assert.Equal(t, bl.Blocks[0].GetText().Marks.Marks[0].Type, model.BlockContentTextMark_Mention) + assert.Equal(t, bl.Blocks[0].GetText().Text, "Page") } func Test_GetTextBlocksDatabaseMention(t *testing.T) { @@ -92,12 +95,15 @@ func Test_GetTextBlocksDatabaseMention(t *testing.T) { }, } - bl, _ := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, nil, map[string]string{"notionID": "anytypeID"}, nil, map[string]string{"notionID": "Database"}) - assert.Len(t, bl, 1) - assert.Equal(t, bl[0].GetText().Style, model.BlockContentText_Paragraph) - assert.Len(t, bl[0].GetText().Marks.Marks, 1) - assert.Equal(t, bl[0].GetText().Marks.Marks[0].Type, model.BlockContentTextMark_Mention) - assert.Equal(t, bl[0].GetText().Text, "Database") + bl := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, &MapRequest{ + NotionDatabaseIdsToAnytype: map[string]string{"notionID": "anytypeID"}, + DatabaseNameToID: map[string]string{"notionID": "Database"}, + }) + assert.Len(t, bl.Blocks, 1) + assert.Equal(t, bl.Blocks[0].GetText().Style, model.BlockContentText_Paragraph) + assert.Len(t, bl.Blocks[0].GetText().Marks.Marks, 1) + assert.Equal(t, bl.Blocks[0].GetText().Marks.Marks[0].Type, model.BlockContentTextMark_Mention) + assert.Equal(t, bl.Blocks[0].GetText().Text, "Database") } func Test_GetTextBlocksDateMention(t *testing.T) { @@ -115,11 +121,10 @@ func Test_GetTextBlocksDateMention(t *testing.T) { }, } - bl, _ := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, nil, nil, nil, nil) - assert.Len(t, bl, 1) - assert.Equal(t, bl[0].GetText().Style, model.BlockContentText_Paragraph) - assert.Len(t, bl[0].GetText().Marks.Marks, 0) - assert.Equal(t, bl[0].GetText().Text, "2022-11-14") + bl := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, &MapRequest{}) + assert.Len(t, bl.Blocks, 1) + assert.NotNil(t, bl.Blocks[0].GetRelation()) + assert.Len(t, bl.Relations, 1) } func Test_GetTextBlocksLinkPreview(t *testing.T) { @@ -137,13 +142,13 @@ func Test_GetTextBlocksLinkPreview(t *testing.T) { }, } - bl, _ := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, nil, nil, nil, nil) - assert.Len(t, bl, 1) - assert.Equal(t, bl[0].GetText().Style, model.BlockContentText_Paragraph) - assert.NotNil(t, bl[0].GetText().Marks) - assert.Len(t, bl[0].GetText().Marks.Marks, 1) - assert.Equal(t, bl[0].GetText().Marks.Marks[0].Type, model.BlockContentTextMark_Link) - assert.Equal(t, bl[0].GetText().Text, "ref") + bl := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, &MapRequest{}) + assert.Len(t, bl.Blocks, 1) + assert.Equal(t, bl.Blocks[0].GetText().Style, model.BlockContentText_Paragraph) + assert.NotNil(t, bl.Blocks[0].GetText().Marks) + assert.Len(t, bl.Blocks[0].GetText().Marks.Marks, 1) + assert.Equal(t, bl.Blocks[0].GetText().Marks.Marks[0].Type, model.BlockContentTextMark_Link) + assert.Equal(t, bl.Blocks[0].GetText().Text, "ref") } func Test_GetTextBlocksEquation(t *testing.T) { @@ -158,10 +163,10 @@ func Test_GetTextBlocksEquation(t *testing.T) { }, } - bl, _ := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, nil, nil, nil, nil) - assert.Len(t, bl, 1) - assert.NotNil(t, bl[0].GetLatex()) - assert.Equal(t, bl[0].GetLatex().Text, "Equation") + bl := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, &MapRequest{}) + assert.Len(t, bl.Blocks, 1) + assert.NotNil(t, bl.Blocks[0].GetLatex()) + assert.Equal(t, bl.Blocks[0].GetLatex().Text, "Equation") } func Test_GetCodeBlocksSuccess(t *testing.T) { @@ -176,7 +181,8 @@ func Test_GetCodeBlocksSuccess(t *testing.T) { Language: "Go", }, } - bl := co.Code.GetCodeBlock() + bl := co.GetBlocks(&MapRequest{}) assert.NotNil(t, bl) - assert.Equal(t, bl.GetText().Text, "Code") + assert.Len(t, bl.Blocks, 1) + assert.Equal(t, bl.Blocks[0].GetText().Text, "Code") } \ No newline at end of file diff --git a/core/block/import/notion/api/block/textobject.go b/core/block/import/notion/api/block/textobject.go new file mode 100644 index 000000000..8c9f1f9e2 --- /dev/null +++ b/core/block/import/notion/api/block/textobject.go @@ -0,0 +1,259 @@ +package block + +import ( + "strings" + "time" + + "github.com/globalsign/mgo/bson" + "github.com/gogo/protobuf/types" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" + "github.com/anytypeio/go-anytype-middleware/util/pbtypes" + textUtil "github.com/anytypeio/go-anytype-middleware/util/text" +) + +const DateMentionTimeFormat = "2006-01-02" + +type ChildrenMapper interface { + MapChildren(req *MapRequest) *MapResponse +} + +type TextObject struct { + RichText []api.RichText `json:"rich_text"` + Color string `json:"color"` +} + +func (t *TextObject) GetTextBlocks(style model.BlockContentTextStyle, childIds []string, req *MapRequest) *MapResponse { + marks := []*model.BlockContentTextMark{} + id := bson.NewObjectId().Hex() + allBlocks := make([]*model.Block, 0) + allIds := make([]string, 0) + var ( + text strings.Builder + relations []*converter.Relation + details map[string]*types.Value + ) + for _, rt := range t.RichText { + if rt.Type == api.Text { + marks = append(marks, t.handleTextType(rt, &text, req.NotionPageIdsToAnytype, req.NotionDatabaseIdsToAnytype)...) + } + if rt.Type == api.Mention { + // Return Relation block for Date mention + if rt.Mention.Type == api.Date { + var ( + relationBlock *model.Block + relationBlockID string + relation *converter.Relation + ) + relationBlock, relation, details, relationBlockID = t.handleDateMention(rt, &text) + allBlocks = append(allBlocks, relationBlock) + allIds = append(allIds, relationBlockID) + relations = append(relations, relation) + continue + } + marks = append(marks, t.handleMentionType(rt, &text, req)...) + } + if rt.Type == api.Equation { + eqBlock := rt.Equation.HandleEquation() + allBlocks = append(allBlocks, eqBlock) + allIds = append(allIds, eqBlock.Id) + } + } + var backgroundColor string + if strings.Contains(t.Color, api.NotionBackgroundColorSuffix) { + backgroundColor = api.NotionColorToAnytype[t.Color] + } + + if t.isNotTextBlocks() { + return &MapResponse{ + Blocks: allBlocks, + Relations: relations, + Details: details, + BlockIDs: allIds, + } + } + allBlocks = append(allBlocks, &model.Block{ + Id: id, + ChildrenIds: childIds, + BackgroundColor: backgroundColor, + Content: &model.BlockContentOfText{ + Text: &model.BlockContentText{ + Text: text.String(), + Style: style, + Marks: &model.BlockContentTextMarks{Marks: marks}, + Checked: false, + Color: api.NotionColorToAnytype[t.Color], + }, + }, + }) + for _, b := range allBlocks { + allIds = append(allIds, b.Id) + } + return &MapResponse{ + Blocks: allBlocks, + Relations: relations, + Details: details, + BlockIDs: allIds, + } +} + +func (t *TextObject) handleTextType(rt api.RichText, + text *strings.Builder, + notionPageIdsToAnytype, + notionDatabaseIdsToAnytype map[string]string) []*model.BlockContentTextMark { + marks := []*model.BlockContentTextMark{} + from := textUtil.UTF16RuneCountString(text.String()) + if rt.Text != nil && rt.Text.Link != nil && rt.Text.Link.Url != "" { + text.WriteString(rt.Text.Content) + } else { + text.WriteString(rt.PlainText) + } + to := textUtil.UTF16RuneCountString(text.String()) + if rt.Text != nil && rt.Text.Link != nil && rt.Text.Link.Url != "" { + url := strings.Trim(rt.Text.Link.Url, "/") + if databaseID, ok := notionDatabaseIdsToAnytype[url]; ok { + url = databaseID + } + if pageID, ok := notionPageIdsToAnytype[url]; ok { + url = pageID + } + marks = append(marks, &model.BlockContentTextMark{ + Range: &model.Range{ + From: int32(from), + To: int32(to), + }, + Type: model.BlockContentTextMark_Link, + Param: url, + }) + } + marks = append(marks, rt.BuildMarkdownFromAnnotations(int32(from), int32(to))...) + return marks +} + +func (t *TextObject) handleMentionType(rt api.RichText, text *strings.Builder, req *MapRequest) []*model.BlockContentTextMark { + if rt.Mention.Type == api.UserMention { + return t.handleUserMention(rt, text) + } + if rt.Mention.Type == api.Database { + return t.handleDatabaseMention(rt, text, req.NotionDatabaseIdsToAnytype, req.DatabaseNameToID) + } + if rt.Mention.Type == api.Page { + return t.handlePageMention(rt, text, req.NotionPageIdsToAnytype, req.PageNameToID) + } + if rt.Mention.Type == api.LinkPreview { + return t.handleLinkPreviewMention(rt, text) + } + return nil +} + +func (t *TextObject) handleUserMention(rt api.RichText, text *strings.Builder) []*model.BlockContentTextMark { + from := textUtil.UTF16RuneCountString(text.String()) + text.WriteString(rt.Mention.User.Name) + to := textUtil.UTF16RuneCountString(text.String()) + return rt.BuildMarkdownFromAnnotations(int32(from), int32(to)) +} + +func (t *TextObject) handleDatabaseMention(rt api.RichText, + text *strings.Builder, + notionDatabaseIdsToAnytype, databaseNameToID map[string]string) []*model.BlockContentTextMark { + if notionDatabaseIdsToAnytype == nil { + return nil + } + from := textUtil.UTF16RuneCountString(text.String()) + text.WriteString(databaseNameToID[rt.Mention.Database.ID]) + to := textUtil.UTF16RuneCountString(text.String()) + marks := rt.BuildMarkdownFromAnnotations(int32(from), int32(to)) + marks = append(marks, &model.BlockContentTextMark{ + Range: &model.Range{ + From: int32(from), + To: int32(to), + }, + Type: model.BlockContentTextMark_Mention, + Param: notionDatabaseIdsToAnytype[rt.Mention.Database.ID], + }) + return marks +} + +func (t *TextObject) handlePageMention(rt api.RichText, + text *strings.Builder, + notionPageIdsToAnytype, pageNameToID map[string]string) []*model.BlockContentTextMark { + if notionPageIdsToAnytype == nil { + return nil + } + from := textUtil.UTF16RuneCountString(text.String()) + text.WriteString(pageNameToID[rt.Mention.Page.ID]) + to := textUtil.UTF16RuneCountString(text.String()) + marks := rt.BuildMarkdownFromAnnotations(int32(from), int32(to)) + marks = append(marks, &model.BlockContentTextMark{ + Range: &model.Range{ + From: int32(from), + To: int32(to), + }, + Type: model.BlockContentTextMark_Mention, + Param: notionPageIdsToAnytype[rt.Mention.Page.ID], + }) + return marks +} + +func (t *TextObject) handleDateMention(rt api.RichText, text *strings.Builder) (*model.Block, *converter.Relation, map[string]*types.Value, string) { + var textDate string + if rt.Mention.Date.Start != "" { + textDate = rt.Mention.Date.Start + } + if rt.Mention.Date.End != "" { + textDate += " " + rt.Mention.Date.End + } + date, err := time.Parse(DateMentionTimeFormat, textDate) + if err != nil { + return nil, nil, nil, "" + } + rel := converter.Relation{ + BlockID: bson.NewObjectId().Hex(), + Name: "Date", + Format: model.RelationFormat_date, + } + id := bson.NewObjectId().Hex() + details := map[string]*types.Value{rel.Name: pbtypes.Int64(date.Unix())} + return &model.Block{ + Id: id, + Content: &model.BlockContentOfRelation{ + Relation: &model.BlockContentRelation{ + Key: rel.BlockID, + }, + }, + }, &rel, details, id +} + +func (t *TextObject) handleLinkPreviewMention(rt api.RichText, text *strings.Builder) []*model.BlockContentTextMark { + from := textUtil.UTF16RuneCountString(text.String()) + text.WriteString(rt.Mention.LinkPreview.Url) + to := textUtil.UTF16RuneCountString(text.String()) + marks := rt.BuildMarkdownFromAnnotations(int32(from), int32(to)) + marks = append(marks, &model.BlockContentTextMark{ + Range: &model.Range{ + From: int32(from), + To: int32(to), + }, + Type: model.BlockContentTextMark_Link, + }) + return marks +} + +func (t *TextObject) isNotTextBlocks() bool { + return (len(t.RichText) == 1 && t.RichText[0].Type == api.Mention && t.RichText[0].Mention.Type == api.Date) || + len(t.RichText) == 1 && t.RichText[0].Type == api.Equation +} + +type TextObjectWithChildren struct { + TextObject + Children []interface{} `json:"children"` +} + +func (t *TextObjectWithChildren) MapChildren(req *MapRequest) *MapResponse { + childReq := *req + childReq.Blocks = t.Children + resp := MapBlocks(&childReq) + return resp +} diff --git a/core/block/import/notion/api/commonobjects.go b/core/block/import/notion/api/commonobjects.go index 6fb1fc2ea..8607fe788 100644 --- a/core/block/import/notion/api/commonobjects.go +++ b/core/block/import/notion/api/commonobjects.go @@ -1,7 +1,6 @@ package api import ( - "bytes" "encoding/json" "strings" "time" @@ -304,12 +303,13 @@ type Parent struct { DatabaseID string `json:"database_id"` } -func RichTextToDescription(rt []RichText) string { - var description bytes.Buffer - - for _, text := range rt { - description.WriteString(text.PlainText) - description.WriteRune('\n') +func RichTextToDescription(rt []*RichText) string { + var richText strings.Builder + for i, title := range rt { + richText.WriteString(title.PlainText) + if i != len(rt)-1 { + richText.WriteString("\n") + } } - return description.String() + return richText.String() } diff --git a/core/block/import/notion/api/database/database.go b/core/block/import/notion/api/database/database.go index 36b994d07..f8e6d5393 100644 --- a/core/block/import/notion/api/database/database.go +++ b/core/block/import/notion/api/database/database.go @@ -38,7 +38,7 @@ type Database struct { Parent api.Parent `json:"parent"` URL string `json:"url"` Properties interface{} `json:"properties"` // can't support it for databases yet - Description []api.RichText `json:"description"` + Description []*api.RichText `json:"description"` IsInline bool `json:"is_inline"` Archived bool `json:"archived"` Icon *api.Icon `json:"icon,omitempty"` diff --git a/core/block/import/notion/api/page/page.go b/core/block/import/notion/api/page/page.go index 07c0573d5..7010836dd 100644 --- a/core/block/import/notion/api/page/page.go +++ b/core/block/import/notion/api/page/page.go @@ -14,30 +14,29 @@ import ( "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/logging" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" "github.com/anytypeio/go-anytype-middleware/pkg/lib/threads" "github.com/anytypeio/go-anytype-middleware/util/pbtypes" ) +var logger = logging.Logger("notion-page") + const ( ObjectType = "page" pageSize = 100 ) type Service struct { - propertyService *property.Service - detailSetter *property.DetailValueSetter - blockService *block.Service - client *client.Client + blockService *block.Service + client *client.Client } // New is a constructor for Service func New(client *client.Client) *Service { return &Service{ - propertyService: property.New(client), - detailSetter: property.NewDetailSetter(), - blockService: block.New(client), - client: client, + blockService: block.New(client), + client: client, } } @@ -62,12 +61,21 @@ func (p *Page) GetObjectType() string { } // GetPages transform Page objects from Notion to snaphots -func (ds *Service) GetPages(ctx context.Context, apiKey string, mode pb.RpcObjectImportRequestMode, pages []Page, notionDatabaseIdsToAnytype, databaseNameToID map[string]string) *converter.Response { +func (ds *Service) GetPages(ctx context.Context, + apiKey string, + mode pb.RpcObjectImportRequestMode, + pages []Page, + request *block.MapRequest) (*converter.Response, map[string]string) { convereterError := converter.ConvertError{} - return ds.mapPagesToSnaphots(ctx, apiKey, mode, pages, convereterError, notionDatabaseIdsToAnytype, databaseNameToID) + return ds.mapPagesToSnaphots(ctx, apiKey, mode, pages, convereterError, request) } -func (ds *Service) mapPagesToSnaphots(ctx context.Context, apiKey string, mode pb.RpcObjectImportRequestMode, pages []Page, convereterError converter.ConvertError, notionDatabaseIdsToAnytype, databaseNameToID map[string]string) *converter.Response { +func (ds *Service) mapPagesToSnaphots(ctx context.Context, + apiKey string, + mode pb.RpcObjectImportRequestMode, + pages []Page, + convereterError converter.ConvertError, + request *block.MapRequest) (*converter.Response, map[string]string) { var allSnapshots = make([]*converter.Snapshot, 0) var notionPagesIdsToAnytype = make(map[string]string, 0) for _, p := range pages { @@ -75,104 +83,128 @@ func (ds *Service) mapPagesToSnaphots(ctx context.Context, apiKey string, mode p if err != nil { convereterError.Add(p.ID, err) if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return &converter.Response{Error: convereterError} + return &converter.Response{Error: convereterError}, nil } else { continue } } notionPagesIdsToAnytype[p.ID] = tid.String() } + relationsToPageID := make(map[string][]*converter.Relation) + // Need to collect pages title and notion ids mapping for such blocks as ChildPage and ChildDatabase, + // because we only get title in those blocks from API + pageNameToID := make(map[string]string, 0) for _, p := range pages { - snapshot, ce := ds.transformPages(ctx, apiKey, p, mode, notionPagesIdsToAnytype, notionDatabaseIdsToAnytype, databaseNameToID) + for _, v := range p.Properties { + if t, ok := v.(*property.TitleItem); ok { + title := api.RichTextToDescription(t.Title) + pageNameToID[p.ID] = title + break + } + } + } + request.NotionPageIdsToAnytype = notionPagesIdsToAnytype + request.PageNameToID = pageNameToID + for _, p := range pages { + snapshot, relations, ce := ds.transformPages(ctx, apiKey, p, mode, request) if ce != nil { convereterError.Merge(*ce) if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return &converter.Response{Error: convereterError} + return &converter.Response{Error: convereterError}, nil } else { continue } } - + pageID := notionPagesIdsToAnytype[p.ID] allSnapshots = append(allSnapshots, &converter.Snapshot{ - Id: notionPagesIdsToAnytype[p.ID], + Id: pageID, FileName: p.URL, Snapshot: snapshot, }) + relationsToPageID[pageID] = relations } if convereterError.IsEmpty() { - return &converter.Response{Snapshots: allSnapshots, Error: nil} + return &converter.Response{Snapshots: allSnapshots, Relations: relationsToPageID, Error: nil}, notionPagesIdsToAnytype } - return &converter.Response{Snapshots: allSnapshots, Error: convereterError} + return &converter.Response{Snapshots: allSnapshots, Relations: relationsToPageID, Error: convereterError}, notionPagesIdsToAnytype } -func (ds *Service) transformPages(ctx context.Context, apiKey string, d Page, mode pb.RpcObjectImportRequestMode, notionPagesIdsToAnytype, notionDatabaseIdsToAnytype, databaseNameToID map[string]string) (*model.SmartBlockSnapshotBase, *converter.ConvertError) { +func (ds *Service) transformPages(ctx context.Context, + apiKey string, + p Page, + mode pb.RpcObjectImportRequestMode, + request *block.MapRequest) (*model.SmartBlockSnapshotBase, []*converter.Relation, *converter.ConvertError) { details := make(map[string]*types.Value, 0) - details[bundle.RelationKeySource.String()] = pbtypes.String(d.URL) - if d.Icon != nil && d.Icon.Emoji != nil { - details[bundle.RelationKeyIconEmoji.String()] = pbtypes.String(*d.Icon.Emoji) + details[bundle.RelationKeySource.String()] = pbtypes.String(p.URL) + if p.Icon != nil && p.Icon.Emoji != nil { + details[bundle.RelationKeyIconEmoji.String()] = pbtypes.String(*p.Icon.Emoji) } - details[bundle.RelationKeyIsArchived.String()] = pbtypes.Bool(d.Archived) + details[bundle.RelationKeyIsArchived.String()] = pbtypes.Bool(p.Archived) + details[bundle.RelationKeyIsFavorite.String()] = pbtypes.Bool(true) var ( allErrors = &converter.ConvertError{} - relations []*model.RelationLink + relations []*converter.Relation ) - relations, pageNameToID, ce := ds.handlePageProperties(apiKey, d.ID, d.Properties, details, mode) - if ce != nil { - allErrors.Merge(*ce) - if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return nil, allErrors - } - } + relations = ds.handlePageProperties(apiKey, p.ID, p.Properties, details, request.NotionPageIdsToAnytype, request.NotionDatabaseIdsToAnytype) - notionBlocks, blocksAndChildrenErr := ds.blockService.GetBlocksAndChildren(ctx, d.ID, apiKey, pageSize, mode) + notionBlocks, blocksAndChildrenErr := ds.blockService.GetBlocksAndChildren(ctx, p.ID, apiKey, pageSize, mode) if blocksAndChildrenErr != nil { allErrors.Merge(*blocksAndChildrenErr) if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return nil, allErrors + return nil, nil, allErrors } } - anytypeBlocks := ds.blockService.MapNotionBlocksToAnytype(notionBlocks, notionPagesIdsToAnytype, notionDatabaseIdsToAnytype, pageNameToID, databaseNameToID) + request.Blocks = notionBlocks + resp := ds.blockService.MapNotionBlocksToAnytype(request) + resp.MergeDetails(details) + relations = append(relations, resp.Relations...) snapshot := &model.SmartBlockSnapshotBase{ - Blocks: anytypeBlocks, - Details: &types.Struct{Fields: details}, - ObjectTypes: []string{bundle.TypeKeyPage.URL()}, - RelationLinks: relations, + Blocks: resp.Blocks, + Details: &types.Struct{Fields: resp.Details}, + ObjectTypes: []string{bundle.TypeKeyPage.URL()}, } - return snapshot, nil + return snapshot, relations, nil } // handlePageProperties gets properties values by their ids from notion api and transforms them to Details and RelationLinks -func (ds *Service) handlePageProperties(apiKey, pageID string, p property.Properties, d map[string]*types.Value, mode pb.RpcObjectImportRequestMode) ([]*model.RelationLink, map[string]string, *converter.ConvertError) { - ce := converter.ConvertError{} - relations := make([]*model.RelationLink, 0) - pageNameToID := make(map[string]string, 0) +func (ds *Service) handlePageProperties(apiKey, pageID string, + p property.Properties, + d map[string]*types.Value, + notionPagesIdsToAnytype, notionDatabaseIdsToAnytype map[string]string) []*converter.Relation { + relations := make([]*converter.Relation, 0) for k, v := range p { - object, err := ds.propertyService.GetPropertyObject(context.TODO(), pageID, v.GetID(), apiKey, v.GetPropertyType()) - if err != nil { - ce.Add("property: "+v.GetID(), err) - if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return relations, pageNameToID, &ce - } + if rel, ok := v.(*property.RelationItem); ok { + linkRelationsIDWithAnytypeID(rel, notionPagesIdsToAnytype, notionDatabaseIdsToAnytype) } - err = ds.detailSetter.SetDetailValue(k, v.GetPropertyType(), object, d) - if err != nil && mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - ce.Add("property: "+v.GetID(), err) - if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return relations, pageNameToID, &ce - } + var ( + ds property.DetailSetter + ok bool + ) + if ds, ok = v.(property.DetailSetter); !ok { + logger.With("method", "handlePageProperties").Errorf("failed to convert to interface DetailSetter, %s", v.GetPropertyType()) + continue } - relations = append(relations, &model.RelationLink{ - Key: k, + ds.SetDetail(k, d) + relations = append(relations, &converter.Relation{ + Name: k, Format: v.GetFormat(), }) - if v.GetPropertyType() == property.PropertyConfigTypeTitle { - if name, ok := d[bundle.RelationKeyName.String()]; ok { - pageNameToID[pageID] = name.GetStringValue() - } + } + return relations +} + +// linkRelationsIDWithAnytypeID take anytype ID based on page/database ID from Notin. In property we get id from Notion, so we somehow need to +// map this ID with anytype for correct Relation. We use two maps notionPagesIdsToAnytype, notionDatabaseIdsToAnytype for this +func linkRelationsIDWithAnytypeID(rel *property.RelationItem, notionPagesIdsToAnytype, notionDatabaseIdsToAnytype map[string]string) { + for _, r := range rel.Relation { + if anytypeID, ok := notionPagesIdsToAnytype[r.ID]; ok { + r.ID = anytypeID + } + if anytypeID, ok := notionDatabaseIdsToAnytype[r.ID]; ok { + r.ID = anytypeID } } - return relations, pageNameToID, nil } diff --git a/core/block/import/notion/api/page/page_test.go b/core/block/import/notion/api/page/page_test.go index f144b4246..826858b2c 100644 --- a/core/block/import/notion/api/page/page_test.go +++ b/core/block/import/notion/api/page/page_test.go @@ -5,48 +5,50 @@ import ( "net/http/httptest" "testing" - "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" - "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/property" - "github.com/anytypeio/go-anytype-middleware/pb" "github.com/gogo/protobuf/types" "github.com/stretchr/testify/assert" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/property" + "github.com/anytypeio/go-anytype-middleware/util/pbtypes" ) func Test_handlePagePropertiesSelect(t *testing.T) { - s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(`{"object":"property_item","type":"select","id":"C%5E%7DO","select":{"id":"f56c757b-eb58-4a15-b528-055a0e3e85b4","name":"dddd","color":"red"}}`)) - })) - + details := make(map[string]*types.Value, 0) c := client.NewClient() - c.BasePath = s.URL ps := New(c) - details := make(map[string]*types.Value, 0) - - p := property.SelectProperty{ID:"id", Type: string(property.PropertyConfigTypeSelect)} + p := property.SelectItem{ + Object: "", + ID: "id", + Type: string(property.PropertyConfigTypeSelect), + Select: property.SelectOption{ + ID: "id", + Name: "Name", + Color: api.Blue, + }, + } pr := property.Properties{"Select": &p} - _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) - assert.Nil(t, ce) assert.NotEmpty(t, details["Select"]) } func Test_handlePagePropertiesLastEditedTime(t *testing.T) { - s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(`{"object":"property_item","type":"last_edited_time","id":"MeQJ","last_edited_time":"2022-11-04T13:02:00.000Z"}`)) - })) - c := client.NewClient() - c.BasePath = s.URL ps := New(c) details := make(map[string]*types.Value, 0) - p := property.LastEditedTime{ID: "id", Type: string(property.PropertyConfigLastEditedTime)} + p := property.LastEditedTimeItem{ + ID: "id", + Type: string(property.PropertyConfigLastEditedTime), + LastEditedTime: "2022-12-07", + } pr := property.Properties{"LastEditedTime": &p} - _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) - assert.Nil(t, ce) assert.NotEmpty(t, details["LastEditedTime"]) } @@ -61,30 +63,31 @@ func Test_handlePagePropertiesRichText(t *testing.T) { details := make(map[string]*types.Value, 0) - p := property.RichText{ID: "id", Type: string(property.PropertyConfigLastEditedTime)} + p := property.RichTextItem{ID: "id", Type: string(property.PropertyConfigLastEditedTime)} pr := property.Properties{"RichText": &p} - _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) - assert.Nil(t, ce) assert.NotEmpty(t, details["RichText"]) } func Test_handlePagePropertiesStatus(t *testing.T) { - s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(`{"object":"property_item","type":"status","id":"VwSP","status":{"id":"e4927bd2-4580-4e37-9095-eb0af45923bc","name":"In progress","color":"blue"}}`)) - })) - c := client.NewClient() - c.BasePath = s.URL ps := New(c) details := make(map[string]*types.Value, 0) - p := property.StatusProperty{ID: "id", Type: property.PropertyConfigStatus} + p := property.StatusItem{ + ID: "id", + Type: property.PropertyConfigStatus, + Status: &property.Status{ + Name: "Done", + ID: "id", + Color: api.Pink, + }, + } pr := property.Properties{"Status": &p} - _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) - assert.Nil(t, ce) assert.NotEmpty(t, details["Status"]) } @@ -99,11 +102,15 @@ func Test_handlePagePropertiesNumber(t *testing.T) { details := make(map[string]*types.Value, 0) - p := property.NumberProperty{ID: "id", Type: string(property.PropertyConfigTypeNumber)} + num := int64(12) + p := property.NumberItem{ + ID: "id", + Type: string(property.PropertyConfigTypeNumber), + Number: &num, + } pr := property.Properties{"Number": &p} - _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) - assert.Nil(t, ce) assert.NotEmpty(t, details["Number"]) } @@ -118,11 +125,20 @@ func Test_handlePagePropertiesMultiSelect(t *testing.T) { details := make(map[string]*types.Value, 0) - p := property.NumberProperty{ID: "id", Type: string(property.PropertyConfigTypeMultiSelect)} + p := property.MultiSelectItem{ + ID: "id", + Type: string(property.PropertyConfigTypeMultiSelect), + MultiSelect: []*property.SelectOption{ + { + ID: "id", + Name: "Name", + Color: api.Blue, + }, + }, + } pr := property.Properties{"MultiSelect": &p} - _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) - assert.Nil(t, ce) assert.NotEmpty(t, details["MultiSelect"]) } @@ -137,36 +153,38 @@ func Test_handlePagePropertiesCheckbox(t *testing.T) { details := make(map[string]*types.Value, 0) - p := property.Checkbox{ID: "id", Type: string(property.PropertyConfigTypeCheckbox)} + p := property.CheckboxItem{ + ID: "id", + Type: string(property.PropertyConfigTypeCheckbox), + Checkbox: true, + } pr := property.Properties{"Checkbox": &p} - _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) - assert.Nil(t, ce) assert.NotEmpty(t, details["Checkbox"]) } func Test_handlePagePropertiesEmail(t *testing.T) { - s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(`{"object":"property_item","type":"email","id":"bQRa","email":null}`)) - })) - c := client.NewClient() - c.BasePath = s.URL ps := New(c) details := make(map[string]*types.Value, 0) - p := property.Email{ID: "id", Type: string(property.PropertyConfigTypeEmail)} + email := "a@mail.com" + p := property.EmailItem{ + ID: "id", + Type: string(property.PropertyConfigTypeEmail), + Email: &email, + } pr := property.Properties{"Email": &p} - _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) - assert.Nil(t, ce) assert.NotEmpty(t, details["Email"]) } func Test_handlePagePropertiesRelation(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(`{"object":"list","results":[{"object":"property_item","type":"relation","id":"cm~~","relation":{"id":"18e660df-d7f4-4d4b-b30c-eeb88ffee645"}}],"next_cursor":null,"has_more":false,"type":"property_item","property_item":{"id":"cm~~","next_url":null,"type":"relation","relation":{}}}`)) + w.Write([]byte(`{"object":"list","results":[{"object":"property_item","type":"relation","id":"cm~~","relation":{"id":"id"}}],"next_cursor":null,"has_more":false,"type":"property_item","property_item":{"id":"cm~~","next_url":null,"type":"relation","relation":{}}}`)) })) c := client.NewClient() @@ -175,67 +193,64 @@ func Test_handlePagePropertiesRelation(t *testing.T) { details := make(map[string]*types.Value, 0) - p := property.RelationProperty{ID: "id", Type: string(property.PropertyConfigTypeRelation)} + p := property.RelationItem{ID: "id", Type: string(property.PropertyConfigTypeRelation), Relation: []*property.Relation{{ID: "id"}}} pr := property.Properties{"Relation": &p} - _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + notionPageIdsToAnytype := map[string]string{"id": "anytypeID"} + notionDatabaseIdsToAnytype := map[string]string{"id": "anytypeID"} + _ = ps.handlePageProperties("key", "id", pr, details, notionPageIdsToAnytype, notionDatabaseIdsToAnytype) - assert.Nil(t, ce) - assert.NotEmpty(t, details["Relation"]) + assert.NotNil(t, details["Relation"].GetListValue()) + assert.Len(t, details["Relation"].GetListValue().Values, 1) + assert.Equal(t, pbtypes.GetStringListValue(details["Relation"])[0], "anytypeID") } func Test_handlePagePropertiesPeople(t *testing.T) { - s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(`{"object":"list","results":[{"object":"property_item","type":"people","id":"nWZg","people":{"object":"user","id":"60faafc6-0c5c-4479-a3f7-67d77cd8a56d"}}],"next_cursor":null,"has_more":false,"type":"property_item","property_item":{"id":"nWZg","next_url":null,"type":"people","people":{}}}`)) - })) - c := client.NewClient() - c.BasePath = s.URL ps := New(c) details := make(map[string]*types.Value, 0) - p := property.People{ID: "id", Type: string(property.PropertyConfigTypePeople)} + p := property.PeopleItem{ + Object: "", + ID: "id", + Type: string(property.PropertyConfigTypePeople), + } pr := property.Properties{"People": &p} - _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) - assert.Nil(t, ce) assert.NotEmpty(t, details["People"]) } func Test_handlePagePropertiesFormula(t *testing.T) { - s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(`{"object":"property_item","type":"formula","id":"%7Do%40%7B","formula":{"type":"number","number":11.745674324002}}`)) - })) - c := client.NewClient() - c.BasePath = s.URL ps := New(c) details := make(map[string]*types.Value, 0) - p := property.Formula{ID: "id", Type: string(property.PropertyConfigTypeFormula)} + p := property.FormulaItem{ + ID: "id", + Type: string(property.PropertyConfigTypeFormula), + Formula: map[string]interface{}{"type": property.NumberFormula, "number": float64(1)}, + } pr := property.Properties{"Formula": &p} - _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) - assert.Nil(t, ce) assert.NotEmpty(t, details["Formula"]) } func Test_handlePagePropertiesTitle(t *testing.T) { - s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(`{"object":"list","results":[{"object":"property_item","type":"title","id":"title","title":{"type":"text","text":{"content":"Daily Entry","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"Daily Entry","href":null}}],"next_cursor":null,"has_more":false,"type":"property_item","property_item":{"id":"title","next_url":null,"type":"title","title":{}}}`)) - })) - c := client.NewClient() - c.BasePath = s.URL ps := New(c) details := make(map[string]*types.Value, 0) - p := property.Title{ID: "id", Type: string(property.PropertyConfigTypeTitle)} + p := property.TitleItem{ + ID: "id", + Type: string(property.PropertyConfigTypeTitle), + Title: []*api.RichText{{PlainText: "Title"}}, + } pr := property.Properties{"Title": &p} - _, _, ce := ps.handlePageProperties("key", "id", pr, details, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) - assert.Nil(t, ce) assert.NotEmpty(t, details["name"]) } \ No newline at end of file diff --git a/core/block/import/notion/api/page/pageslink.go b/core/block/import/notion/api/page/pageslink.go new file mode 100644 index 000000000..6e4bbbac7 --- /dev/null +++ b/core/block/import/notion/api/page/pageslink.go @@ -0,0 +1,53 @@ +package page + +import ( + "github.com/globalsign/mgo/bson" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/database" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" +) + +// TODO tests +func SetPageLinksInDatabase(databaseSnaphots *converter.Response, + pages []Page, + databases []database.Database, + notionPageIdsToAnytype, notionDatabaseIdsToAnytype map[string]string) { + snapshots := makeSnapshotMapFromArray(databaseSnaphots.Snapshots) + + for _, p := range pages { + if p.Parent.DatabaseID != "" { + if parentID, ok := notionDatabaseIdsToAnytype[p.Parent.DatabaseID]; ok { + addLinkBlockToDatabase(snapshots[parentID], notionPageIdsToAnytype[p.ID]) + } + } + } + for _, d := range databases { + if d.Parent.DatabaseID != "" { + if parentID, ok := notionDatabaseIdsToAnytype[d.Parent.DatabaseID]; ok { + addLinkBlockToDatabase(snapshots[parentID], notionDatabaseIdsToAnytype[d.ID]) + } + } + } +} + +func addLinkBlockToDatabase(snapshots *converter.Snapshot, targetID string) { + id := bson.NewObjectId().Hex() + link := &model.Block{ + Id: id, + ChildrenIds: []string{}, + Content: &model.BlockContentOfLink{ + Link: &model.BlockContentLink{ + TargetBlockId: targetID, + }, + }} + snapshots.Snapshot.Blocks = append(snapshots.Snapshot.Blocks, link) +} + +func makeSnapshotMapFromArray(snapshots []*converter.Snapshot) map[string]*converter.Snapshot { + snapshotsMap := make(map[string]*converter.Snapshot, len(snapshots)) + for _, s := range snapshots { + snapshotsMap[s.Id] = s + } + return snapshotsMap +} diff --git a/core/block/import/notion/api/property/detailsetter.go b/core/block/import/notion/api/property/detailsetter.go deleted file mode 100644 index 71af30933..000000000 --- a/core/block/import/notion/api/property/detailsetter.go +++ /dev/null @@ -1,27 +0,0 @@ -package property - -import ( - "github.com/gogo/protobuf/types" -) - -type DetailValueSetter struct{} - -// New is a constructor for DetailValueSetter -func NewDetailSetter() *DetailValueSetter { - return &DetailValueSetter{} -} - -// SetDetailValue creates Detail based on property type and value -func (*DetailValueSetter) SetDetailValue(key string, propertyType PropertyConfigType, property []DetailSetter, details map[string]*types.Value) error { - if len(property) == 0 { - return nil - } - if IsVector(propertyType) { - for _, pr := range property { - pr.SetDetail(key, details) - } - } else { - property[0].SetDetail(key, details) - } - return nil -} \ No newline at end of file diff --git a/core/block/import/notion/api/property/propertyitem.go b/core/block/import/notion/api/property/propertyitem.go index ccf35e2de..52c93eac8 100644 --- a/core/block/import/notion/api/property/propertyitem.go +++ b/core/block/import/notion/api/property/propertyitem.go @@ -4,6 +4,7 @@ package property import ( "strconv" + "strings" "time" "github.com/gogo/protobuf/types" @@ -14,53 +15,124 @@ import ( "github.com/anytypeio/go-anytype-middleware/util/pbtypes" ) +type ConfigType string + +type Object interface { + GetPropertyType() ConfigType + GetID() string + GetFormat() model.RelationFormat +} + +const ( + PropertyConfigTypeTitle ConfigType = "title" + PropertyConfigTypeRichText ConfigType = "rich_text" + PropertyConfigTypeNumber ConfigType = "number" + PropertyConfigTypeSelect ConfigType = "select" + PropertyConfigTypeMultiSelect ConfigType = "multi_select" + PropertyConfigTypeDate ConfigType = "date" + PropertyConfigTypePeople ConfigType = "people" + PropertyConfigTypeFiles ConfigType = "files" + PropertyConfigTypeCheckbox ConfigType = "checkbox" + PropertyConfigTypeURL ConfigType = "url" + PropertyConfigTypeEmail ConfigType = "email" + PropertyConfigTypePhoneNumber ConfigType = "phone_number" + PropertyConfigTypeFormula ConfigType = "formula" + PropertyConfigTypeRelation ConfigType = "relation" + PropertyConfigTypeRollup ConfigType = "rollup" + PropertyConfigCreatedTime ConfigType = "created_time" + PropertyConfigCreatedBy ConfigType = "created_by" + PropertyConfigLastEditedTime ConfigType = "last_edited_time" + PropertyConfigLastEditedBy ConfigType = "last_edited_by" + PropertyConfigStatus ConfigType = "status" +) + type DetailSetter interface { - SetDetail(key string, details map[string]*types.Value) + SetDetail(key string, details map[string]*types.Value) } type TitleItem struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Title api.RichText `json:"title"` + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Title []*api.RichText `json:"title"` } func (t *TitleItem) SetDetail(key string, details map[string]*types.Value) { - var title string - if existingTitle, ok := details[bundle.RelationKeyName.String()]; ok { - title = existingTitle.GetStringValue() + var richText strings.Builder + for i, title := range t.Title { + richText.WriteString(title.PlainText) + if i != len(title.PlainText)-1 { + richText.WriteString("\n") + } } - title += t.Title.PlainText - title += "\n" - details[bundle.RelationKeyName.String()] = pbtypes.String(title) + details[bundle.RelationKeyName.String()] = pbtypes.String(richText.String()) +} + +func (t *TitleItem) GetPropertyType() ConfigType { + return PropertyConfigTypeTitle +} + +func (t *TitleItem) GetID() string { + return t.ID +} + +func (t *TitleItem) GetFormat() model.RelationFormat { + return model.RelationFormat_shorttext } type RichTextItem struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - RichText api.RichText `json:"rich_text"` + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + RichText []*api.RichText `json:"rich_text"` } func (rt *RichTextItem) SetDetail(key string, details map[string]*types.Value) { - var richText string - if existingText, ok := details[key]; ok { - richText = existingText.GetStringValue() + var richText strings.Builder + for i, r := range rt.RichText { + richText.WriteString(r.PlainText) + if i != len(rt.RichText)-1 { + richText.WriteString("\n") + } } - richText += rt.RichText.PlainText - richText += "\n" - details[key] = pbtypes.String(richText) + details[key] = pbtypes.String(richText.String()) +} + +func (rt *RichTextItem) GetPropertyType() ConfigType { + return PropertyConfigTypeRichText +} + +func (rt *RichTextItem) GetID() string { + return rt.ID +} + +func (rt *RichTextItem) GetFormat() model.RelationFormat { + return model.RelationFormat_longtext } type NumberItem struct { Object string `json:"object"` ID string `json:"id"` Type string `json:"type"` - Number int64 `json:"number"` + Number *int64 `json:"number"` } func (np *NumberItem) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.Int64(np.Number) + if np.Number != nil { + details[key] = pbtypes.Int64(*np.Number) + } +} + +func (np *NumberItem) GetPropertyType() ConfigType { + return PropertyConfigTypeNumber +} + +func (np *NumberItem) GetID() string { + return np.ID +} + +func (np *NumberItem) GetFormat() model.RelationFormat { + return model.RelationFormat_number } type SelectItem struct { @@ -71,8 +143,8 @@ type SelectItem struct { } type SelectOption struct { - ID string `json:"id,omitempty"` - Name string `json:"name"` + ID string `json:"id,omitempty"` + Name string `json:"name"` Color string `json:"color"` } @@ -80,11 +152,23 @@ func (sp *SelectItem) SetDetail(key string, details map[string]*types.Value) { details[key] = pbtypes.StringList([]string{sp.Select.Name}) } +func (sp *SelectItem) GetPropertyType() ConfigType { + return PropertyConfigTypeSelect +} + +func (sp *SelectItem) GetID() string { + return sp.ID +} + +func (sp *SelectItem) GetFormat() model.RelationFormat { + return model.RelationFormat_tag +} + type MultiSelectItem struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - MultiSelect []SelectOption `json:"multi_select"` + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + MultiSelect []*SelectOption `json:"multi_select"` } func (ms *MultiSelectItem) SetDetail(key string, details map[string]*types.Value) { @@ -95,15 +179,52 @@ func (ms *MultiSelectItem) SetDetail(key string, details map[string]*types.Value details[key] = pbtypes.StringList(msList) } -//can't support it yet -type DateItem struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Date api.DateObject `json:"date"` +func (ms *MultiSelectItem) GetPropertyType() ConfigType { + return PropertyConfigTypeMultiSelect } -func (dp *DateItem) SetDetail(key string, details map[string]*types.Value) {} +func (ms *MultiSelectItem) GetID() string { + return ms.ID +} + +func (ms *MultiSelectItem) GetFormat() model.RelationFormat { + return model.RelationFormat_tag +} + +//can't support it yet +type DateItem struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Date *api.DateObject `json:"date"` +} + +func (dp *DateItem) SetDetail(key string, details map[string]*types.Value) { + if dp.Date != nil { + var date strings.Builder + if dp.Date.Start != "" { + date.WriteString(dp.Date.Start) + } + if dp.Date.End != "" { + if dp.Date.Start != "" { + date.WriteString(" ") + } + date.WriteString(dp.Date.End) + } + } +} + +func (dp *DateItem) GetPropertyType() ConfigType { + return PropertyConfigTypeDate +} + +func (dp *DateItem) GetID() string { + return dp.ID +} + +func (dp *DateItem) GetFormat() model.RelationFormat { + return model.RelationFormat_date +} const ( NumberFormula string = "number" @@ -120,6 +241,9 @@ type FormulaItem struct { } func (f *FormulaItem) SetDetail(key string, details map[string]*types.Value) { + if f.Formula == nil { + return + } switch f.Formula["type"].(string) { case StringFormula: if f.Formula["string"] != nil { @@ -140,51 +264,77 @@ func (f *FormulaItem) SetDetail(key string, details map[string]*types.Value) { } } +func (f *FormulaItem) GetPropertyType() ConfigType { + return PropertyConfigTypeFormula +} + +func (f *FormulaItem) GetID() string { + return f.ID +} + +func (f *FormulaItem) GetFormat() model.RelationFormat { + return model.RelationFormat_shorttext +} + type RelationItem struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Relation Relation `json:"relation"` - HasMore bool `json:"has_more"` + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Relation []*Relation `json:"relation"` + HasMore bool `json:"has_more"` } type Relation struct { ID string `json:"id"` } -func (r *RelationItem) SetDetail(key string, details map[string]*types.Value) { - var ( - relation = make([]string, 0) - ) - if rel, ok := details[key]; ok { - existingRelation := rel.GetListValue() - for _, v := range existingRelation.Values { - relation = append(relation, v.GetStringValue()) - } +func (rp *RelationItem) SetDetail(key string, details map[string]*types.Value) { + relation := make([]string, 0, len(rp.Relation)) + for _, rel := range rp.Relation { + relation = append(relation, rel.ID) } - relation = append(relation, r.Relation.ID) details[key] = pbtypes.StringList(relation) } +func (rp *RelationItem) GetPropertyType() ConfigType { + return PropertyConfigTypeRelation +} + +func (rp *RelationItem) GetID() string { + return rp.ID +} + +func (rp *RelationItem) GetFormat() model.RelationFormat { + return model.RelationFormat_object +} + type PeopleItem struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - People api.User `json:"people"` + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + People []*api.User `json:"people"` } func (p *PeopleItem) SetDetail(key string, details map[string]*types.Value) { - var peopleList = make([]string, 0) - if existingPeople, ok := details[key]; ok { - list := existingPeople.GetListValue() - for _, v := range list.Values { - peopleList = append(peopleList, v.GetStringValue()) - } + peopleList := make([]string, 0, len(p.People)) + for _, people := range p.People { + peopleList = append(peopleList, people.Name) } - peopleList = append(peopleList, p.People.Name) details[key] = pbtypes.StringList(peopleList) } +func (p *PeopleItem) GetPropertyType() ConfigType { + return PropertyConfigTypePeople +} + +func (p *PeopleItem) GetID() string { + return p.ID +} + +func (p *PeopleItem) GetFormat() model.RelationFormat { + return model.RelationFormat_tag +} + type FileItem struct { Object string `json:"object"` ID string `json:"id"` @@ -192,8 +342,20 @@ type FileItem struct { File []api.FileObject `json:"files"` } +func (f *FileItem) GetPropertyType() ConfigType { + return PropertyConfigTypeFiles +} + +func (f *FileItem) GetID() string { + return f.ID +} + +func (f *FileItem) GetFormat() model.RelationFormat { + return model.RelationFormat_file +} + func (f *FileItem) SetDetail(key string, details map[string]*types.Value) { - var fileList = make([]string, len(f.File)) + fileList := make([]string, len(f.File)) for i, fo := range f.File { if fo.External.URL != "" { fileList[i] = fo.External.URL @@ -204,10 +366,6 @@ func (f *FileItem) SetDetail(key string, details map[string]*types.Value) { details[key] = pbtypes.StringList(fileList) } -func (f *FileItem) GetFormat() model.RelationFormat { - return model.RelationFormat_file -} - type CheckboxItem struct { Object string `json:"object"` ID string `json:"id"` @@ -219,37 +377,91 @@ func (c *CheckboxItem) SetDetail(key string, details map[string]*types.Value) { details[key] = pbtypes.Bool(c.Checkbox) } +func (c *CheckboxItem) GetPropertyType() ConfigType { + return PropertyConfigTypeCheckbox +} + +func (c *CheckboxItem) GetID() string { + return c.ID +} + +func (c *CheckboxItem) GetFormat() model.RelationFormat { + return model.RelationFormat_checkbox +} + type UrlItem struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - URL string `json:"url"` + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + URL *string `json:"url"` } func (u *UrlItem) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.String(u.URL) + if u.URL != nil { + details[key] = pbtypes.String(*u.URL) + } +} + +func (u *UrlItem) GetPropertyType() ConfigType { + return PropertyConfigTypeURL +} + +func (u *UrlItem) GetID() string { + return u.ID +} + +func (u *UrlItem) GetFormat() model.RelationFormat { + return model.RelationFormat_url } type EmailItem struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Email string `json:"email"` + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Email *string `json:"email"` } func (e *EmailItem) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.String(e.Email) + if e.Email != nil { + details[key] = pbtypes.String(*e.Email) + } +} + +func (e *EmailItem) GetPropertyType() ConfigType { + return PropertyConfigTypeURL +} + +func (e *EmailItem) GetID() string { + return e.ID +} + +func (e *EmailItem) GetFormat() model.RelationFormat { + return model.RelationFormat_email } type PhoneItem struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Phone string `json:"phone_number"` + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Phone *string `json:"phone_number"` } func (p *PhoneItem) SetDetail(key string, details map[string]*types.Value) { - details[key] = pbtypes.String(p.Phone) + if p.Phone != nil { + details[key] = pbtypes.String(*p.Phone) + } +} + +func (p *PhoneItem) GetPropertyType() ConfigType { + return PropertyConfigTypePhoneNumber +} + +func (p *PhoneItem) GetID() string { + return p.ID +} + +func (p *PhoneItem) GetFormat() model.RelationFormat { + return model.RelationFormat_phone } type CreatedTimeItem struct { @@ -264,6 +476,18 @@ func (ct *CreatedTimeItem) SetDetail(key string, details map[string]*types.Value details[key] = pbtypes.Int64(t.Unix()) } +func (ct *CreatedTimeItem) GetPropertyType() ConfigType { + return PropertyConfigCreatedTime +} + +func (ct *CreatedTimeItem) GetID() string { + return ct.ID +} + +func (ct *CreatedTimeItem) GetFormat() model.RelationFormat { + return model.RelationFormat_date +} + type CreatedByItem struct { Object string `json:"object"` ID string `json:"id"` @@ -275,6 +499,18 @@ func (cb *CreatedByItem) SetDetail(key string, details map[string]*types.Value) details[key] = pbtypes.String(cb.CreatedBy.Name) } +func (cb *CreatedByItem) GetPropertyType() ConfigType { + return PropertyConfigCreatedBy +} + +func (cb *CreatedByItem) GetID() string { + return cb.ID +} + +func (cb *CreatedByItem) GetFormat() model.RelationFormat { + return model.RelationFormat_shorttext +} + type LastEditedTimeItem struct { Object string `json:"object"` ID string `json:"id"` @@ -287,6 +523,18 @@ func (le *LastEditedTimeItem) SetDetail(key string, details map[string]*types.Va details[key] = pbtypes.Int64(t.Unix()) } +func (le *LastEditedTimeItem) GetPropertyType() ConfigType { + return PropertyConfigLastEditedTime +} + +func (le *LastEditedTimeItem) GetID() string { + return le.ID +} + +func (le *LastEditedTimeItem) GetFormat() model.RelationFormat { + return model.RelationFormat_date +} + type LastEditedByItem struct { Object string `json:"object"` ID string `json:"id"` @@ -298,10 +546,22 @@ func (lb *LastEditedByItem) SetDetail(key string, details map[string]*types.Valu details[key] = pbtypes.String(lb.LastEditedBy.Name) } +func (lb *LastEditedByItem) GetPropertyType() ConfigType { + return PropertyConfigLastEditedBy +} + +func (lb *LastEditedByItem) GetID() string { + return lb.ID +} + +func (lb *LastEditedByItem) GetFormat() model.RelationFormat { + return model.RelationFormat_shorttext +} + type StatusItem struct { - ID string `json:"id"` - Type PropertyConfigType `json:"type"` - Status Status `json:"status"` + ID string `json:"id"` + Type ConfigType `json:"type"` + Status *Status `json:"status"` } type Status struct { @@ -314,6 +574,30 @@ func (sp *StatusItem) SetDetail(key string, details map[string]*types.Value) { details[key] = pbtypes.StringList([]string{sp.Status.Name}) } -type RollupItem struct {} +func (sp *StatusItem) GetPropertyType() ConfigType { + return PropertyConfigStatus +} -func (sp *RollupItem) SetDetail(key string, details map[string]*types.Value) {} \ No newline at end of file +func (sp *StatusItem) GetID() string { + return sp.ID +} + +func (sp *StatusItem) GetFormat() model.RelationFormat { + return model.RelationFormat_status +} + +type RollupItem struct{} + +func (r *RollupItem) SetDetail(key string, details map[string]*types.Value) {} + +func (r *RollupItem) GetPropertyType() ConfigType { + return PropertyConfigTypeRollup +} + +func (r *RollupItem) GetFormat() model.RelationFormat { + return model.RelationFormat_longtext +} + +func (r *RollupItem) GetID() string { + return "" +} diff --git a/core/block/import/notion/api/property/propertyobject.go b/core/block/import/notion/api/property/propertyobject.go index 7a411291f..f6e0fada8 100644 --- a/core/block/import/notion/api/property/propertyobject.go +++ b/core/block/import/notion/api/property/propertyobject.go @@ -1,31 +1,11 @@ package property import ( - "bytes" - "context" "encoding/json" "fmt" - "io/ioutil" - "net/http" - - "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" - "github.com/anytypeio/go-anytype-middleware/pkg/lib/logging" ) -var logger = logging.Logger("notion-property-retriever") - -const endpoint = "/pages/%s/properties/%s" -type Service struct { - client *client.Client -} - -func New(client *client.Client) *Service { - return &Service{ - client: client, - } -} - -type Properties map[string]PropertyObject +type Properties map[string]Object func (p *Properties) UnmarshalJSON(data []byte) error { var raw map[string]interface{} @@ -44,50 +24,50 @@ func (p *Properties) UnmarshalJSON(data []byte) error { func parsePropertyConfigs(raw map[string]interface{}) (Properties, error) { result := make(Properties) for k, v := range raw { - var p PropertyObject + var p Object switch rawProperty := v.(type) { case map[string]interface{}: - switch PropertyConfigType(rawProperty["type"].(string)) { + switch ConfigType(rawProperty["type"].(string)) { case PropertyConfigTypeTitle: - p = &Title{} + p = &TitleItem{} case PropertyConfigTypeRichText: - p = &RichText{} + p = &RichTextItem{} case PropertyConfigTypeNumber: - p = &NumberProperty{} + p = &NumberItem{} case PropertyConfigTypeSelect: - p = &SelectProperty{} + p = &SelectItem{} case PropertyConfigTypeMultiSelect: - p = &MultiSelect{} + p = &MultiSelectItem{} case PropertyConfigTypeDate: - p = &DateProperty{} + p = &DateItem{} case PropertyConfigTypePeople: - p = &People{} + p = &PeopleItem{} case PropertyConfigTypeFiles: - p = &File{} + p = &FileItem{} case PropertyConfigTypeCheckbox: - p = &Checkbox{} + p = &CheckboxItem{} case PropertyConfigTypeURL: - p = &Url{} + p = &UrlItem{} case PropertyConfigTypeEmail: - p = &Email{} + p = &EmailItem{} case PropertyConfigTypePhoneNumber: - p = &Phone{} + p = &PhoneItem{} case PropertyConfigTypeFormula: - p = &Formula{} + p = &FormulaItem{} case PropertyConfigTypeRelation: - p = &RelationProperty{} + p = &RelationItem{} case PropertyConfigTypeRollup: - p = &Rollup{} + p = &RollupItem{} case PropertyConfigCreatedTime: - p = &CreatedTime{} + p = &CreatedTimeItem{} case PropertyConfigCreatedBy: - p = &CreatedBy{} + p = &CreatedByItem{} case PropertyConfigLastEditedTime: - p = &LastEditedTime{} + p = &LastEditedTimeItem{} case PropertyConfigLastEditedBy: - p = &LastEditedBy{} + p = &LastEditedByItem{} case PropertyConfigStatus: - p = &StatusProperty{} + p = &StatusItem{} default: return nil, fmt.Errorf("unsupported property type: %s", rawProperty["type"].(string)) } @@ -108,251 +88,3 @@ func parsePropertyConfigs(raw map[string]interface{}) (Properties, error) { return result, nil } - -type PropertyPaginatedRespone struct{ - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Results []interface{} `json:"results"` - Item interface{} `json:"property_item"` - HasMore bool `json:"has_more"` - NextCursor string `json:"next_cursor"` -} - -// GetPropertyObject get from Notion properties values based on type and id and marshal it to according structure from propertyitem.go -func (s *Service) GetPropertyObject(ctx context.Context, pageID, propertyID, apiKey string, propertyType PropertyConfigType) ([]DetailSetter, error) { - var ( - hasMore = true - body = &bytes.Buffer{} - startCursor string - response PropertyPaginatedRespone - paginatedResponse = make([]DetailSetter, 0) - ) - - type Request struct { - StartCursor string `json:"start_cursor,omitempty"` - } - - for hasMore { - err := json.NewEncoder(body).Encode(&Request{StartCursor: startCursor}) - - if err != nil { - return nil, fmt.Errorf("GetPropertyObject: %s", err) - } - - request := fmt.Sprintf(endpoint, pageID, propertyID) - req, err := s.client.PrepareRequest(ctx, apiKey, http.MethodGet, request, body) - - if err != nil { - return nil, fmt.Errorf("GetPropertyObject: %s", err) - } - res, err := s.client.HttpClient.Do(req) - - if err != nil { - return nil, fmt.Errorf("GetPropertyObject: %s", err) - } - defer res.Body.Close() - - b, err := ioutil.ReadAll(res.Body) - - if err != nil { - return nil, err - } - - if res.StatusCode != http.StatusOK { - notionErr := client.TransformHttpCodeToError(b) - if notionErr == nil { - return nil, fmt.Errorf("GetPropertyObject: failed http request, %d code", res.StatusCode) - } - return nil, notionErr - } - - switch propertyType { - case PropertyConfigTypeTitle, PropertyConfigTypeRichText, PropertyConfigTypeRelation, PropertyConfigTypePeople: - err = json.Unmarshal(b, &response) - if err != nil { - continue - } - res := response.Results - for _, v := range res { - buffer, err := json.Marshal(v) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal: %s", err) - continue - } - if propertyType == PropertyConfigTypeTitle { - p := TitleItem{} - err = json.Unmarshal(buffer, &p) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal TitleItem: %s", err) - continue - } - paginatedResponse = append(paginatedResponse, &p) - } - if propertyType == PropertyConfigTypeRichText { - p := RichTextItem{} - err = json.Unmarshal(buffer, &p) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal RichTextItem: %s", err) - continue - } - paginatedResponse = append(paginatedResponse, &p) - } - if propertyType == PropertyConfigTypeRelation { - p := RelationItem{} - err = json.Unmarshal(buffer, &p) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal RelationItem: %s", err) - continue - } - paginatedResponse = append(paginatedResponse, &p) - } - if propertyType == PropertyConfigTypePeople { - p := PeopleItem{} - err = json.Unmarshal(buffer, &p) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal PeopleItem: %s", err) - continue - } - paginatedResponse = append(paginatedResponse, &p) - } - } - if response.HasMore { - startCursor = response.NextCursor - continue - } - case PropertyConfigTypeNumber: - p := NumberItem{} - err = json.Unmarshal(b, &p) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal NumberItem: %s", err) - continue - } - paginatedResponse = append(paginatedResponse, &p) - case PropertyConfigTypeSelect: - p := SelectItem{} - err = json.Unmarshal(b, &p) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal SelectItem: %s", err) - continue - } - paginatedResponse = append(paginatedResponse, &p) - case PropertyConfigTypeMultiSelect: - p := MultiSelectItem{} - err = json.Unmarshal(b, &p) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal MultiSelectItem: %s", err) - continue - } - paginatedResponse = append(paginatedResponse, &p) - case PropertyConfigTypeDate: - date := DateItem{} - err = json.Unmarshal(b, &date) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal DateItem: %s", err) - continue - } - paginatedResponse = append(paginatedResponse, &date) - case PropertyConfigTypeFiles: - file := FileItem{} - err = json.Unmarshal(b, &file) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal FileItem: %s", err) - continue - } - paginatedResponse = append(paginatedResponse, &file) - case PropertyConfigTypeCheckbox: - checkbox := CheckboxItem{} - err = json.Unmarshal(b, &checkbox) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal CheckboxItem: %s", err) - continue - } - paginatedResponse = append(paginatedResponse, &checkbox) - case PropertyConfigTypeURL: - url := UrlItem{} - err = json.Unmarshal(b, &url) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal UrlItem: %s", err) - continue - } - paginatedResponse = append(paginatedResponse, &url) - case PropertyConfigTypeEmail: - email := EmailItem{} - err = json.Unmarshal(b, &email) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal EmailItem: %s", err) - continue - } - paginatedResponse = append(paginatedResponse, &email) - case PropertyConfigTypePhoneNumber: - phone := PhoneItem{} - err = json.Unmarshal(b, &phone) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal PhoneItem: %s", err) - continue - } - paginatedResponse = append(paginatedResponse, &phone) - case PropertyConfigTypeFormula: - formula := FormulaItem{} - err = json.Unmarshal(b, &formula) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal FormulaItem: %s", err) - continue - } - paginatedResponse = append(paginatedResponse, &formula) - case PropertyConfigTypeRollup: - rollup := RollupItem{} - err = json.Unmarshal(b, &rollup) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal Rollup: %s", err) - continue - } - paginatedResponse = append(paginatedResponse, &rollup) - case PropertyConfigCreatedTime: - ct := CreatedTimeItem{} - err = json.Unmarshal(b, &ct) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal CreatedTimeItem: %s", err) - continue - } - paginatedResponse = append(paginatedResponse, &ct) - case PropertyConfigCreatedBy: - cb := CreatedByItem{} - err = json.Unmarshal(b, &cb) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal CreatedByItem: %s", err) - continue - } - paginatedResponse = append(paginatedResponse, &cb) - case PropertyConfigLastEditedTime: - lt := LastEditedTimeItem{} - err = json.Unmarshal(b, <) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal LastEditedTimeItem: %s", err) - continue - } - paginatedResponse = append(paginatedResponse, <) - case PropertyConfigLastEditedBy: - le := LastEditedByItem{} - err = json.Unmarshal(b, &le) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal LastEditedByItem: %s", err) - continue - } - paginatedResponse = append(paginatedResponse, &le) - case PropertyConfigStatus: - sp := StatusItem{} - err = json.Unmarshal(b, &sp) - if err != nil { - logger.Errorf("GetPropertyObject: failed to marshal StatusItem: %s", err) - continue - } - paginatedResponse = append(paginatedResponse, &sp) - default: - return nil, fmt.Errorf("GetPropertyObject: unsupported property type: %s", propertyType) - } - hasMore = false - } - return paginatedResponse, nil -} diff --git a/core/block/import/notion/api/property/propertyvalue.go b/core/block/import/notion/api/property/propertyvalue.go deleted file mode 100644 index cb9e0080e..000000000 --- a/core/block/import/notion/api/property/propertyvalue.go +++ /dev/null @@ -1,418 +0,0 @@ -package property - -// This file represent property configuration from Notion https://developers.notion.com/reference/property-object -import ( - "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" -) - -type PropertyConfigType string - -func IsVector (p PropertyConfigType) bool { - return p == PropertyConfigTypeTitle || p == PropertyConfigTypeRichText || p == PropertyConfigTypePeople || p == PropertyConfigTypeRelation -} - -const ( - PropertyConfigTypeTitle PropertyConfigType = "title" - PropertyConfigTypeRichText PropertyConfigType = "rich_text" - PropertyConfigTypeNumber PropertyConfigType = "number" - PropertyConfigTypeSelect PropertyConfigType = "select" - PropertyConfigTypeMultiSelect PropertyConfigType = "multi_select" - PropertyConfigTypeDate PropertyConfigType = "date" - PropertyConfigTypePeople PropertyConfigType = "people" - PropertyConfigTypeFiles PropertyConfigType = "files" - PropertyConfigTypeCheckbox PropertyConfigType = "checkbox" - PropertyConfigTypeURL PropertyConfigType = "url" - PropertyConfigTypeEmail PropertyConfigType = "email" - PropertyConfigTypePhoneNumber PropertyConfigType = "phone_number" - PropertyConfigTypeFormula PropertyConfigType = "formula" - PropertyConfigTypeRelation PropertyConfigType = "relation" - PropertyConfigTypeRollup PropertyConfigType = "rollup" - PropertyConfigCreatedTime PropertyConfigType = "created_time" - PropertyConfigCreatedBy PropertyConfigType = "created_by" - PropertyConfigLastEditedTime PropertyConfigType = "last_edited_time" - PropertyConfigLastEditedBy PropertyConfigType = "last_edited_by" - PropertyConfigStatus PropertyConfigType = "status" -) -type PropertyObject interface { - GetPropertyType() PropertyConfigType - GetID() string - GetFormat() model.RelationFormat -} - -type Title struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Title interface{} `json:"title"` -} - -func (t *Title) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeTitle -} - -func (t *Title) GetID() string { - return t.ID -} - -func (t *Title) GetFormat() model.RelationFormat { - return model.RelationFormat_shorttext -} - -type RichText struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - RichText interface{} `json:"rich_text"` -} - -func (rt *RichText) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeRichText -} - -func (rt *RichText) GetID() string { - return rt.ID -} - -func (rt *RichText) GetFormat() model.RelationFormat { - return model.RelationFormat_longtext -} - -type NumberProperty struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Number interface{} `json:"number"` -} - -func (np *NumberProperty) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeNumber -} - -func (np *NumberProperty) GetID() string { - return np.ID -} - -func (np *NumberProperty) GetFormat() model.RelationFormat { - return model.RelationFormat_number -} - -type SelectProperty struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Select interface{} `json:"select"` -} - -func (sp *SelectProperty) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeSelect -} - -func (sp *SelectProperty) GetID() string { - return sp.ID -} - -func (sp *SelectProperty) GetFormat() model.RelationFormat { - return model.RelationFormat_tag -} - -type MultiSelect struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - MultiSelect interface{} `json:"multi_select"` -} - -func (ms *MultiSelect) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeMultiSelect -} - -func (ms *MultiSelect) GetID() string { - return ms.ID -} - -func (ms *MultiSelect) GetFormat() model.RelationFormat { - return model.RelationFormat_tag -} - -type DateProperty struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Date interface{} `json:"date"` -} - -func (dp *DateProperty) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeDate -} - -func (dp *DateProperty) GetID() string { - return dp.ID -} - -func (dp *DateProperty) GetFormat() model.RelationFormat { - return model.RelationFormat_date -} - -type Formula struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Formula interface{} `json:"formula"` -} - -func (f *Formula) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeFormula -} - -func (f *Formula) GetID() string { - return f.ID -} - -func (f *Formula) GetFormat() model.RelationFormat { - return model.RelationFormat_shorttext -} - -type RelationProperty struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Relation interface{} `json:"relation"` -} - -func (rp *RelationProperty) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeRelation -} - -func (rp *RelationProperty) GetID() string { - return rp.ID -} - -func (r *RelationProperty) GetFormat() model.RelationFormat { - return model.RelationFormat_object -} - -//can't support it yet -type Rollup struct { - Object string `json:"object"` - ID string `json:"id"` -} - -func (r *Rollup) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeRollup -} - -func (p *Rollup) GetFormat() model.RelationFormat { - return model.RelationFormat_longtext -} - -func (r *Rollup) GetID() string { - return r.ID -} - -type People struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - People interface{} `json:"people"` -} - -func (p *People) GetPropertyType() PropertyConfigType { - return PropertyConfigTypePeople -} - -func (p *People) GetID() string { - return p.ID -} - -func (p *People) GetFormat() model.RelationFormat { - return model.RelationFormat_tag -} - -type File struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - File interface{} `json:"files"` -} - -func (f *File) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeFiles -} - -func (f *File) GetID() string { - return f.ID -} - -func (f *File) GetFormat() model.RelationFormat { - return model.RelationFormat_file -} - -type Checkbox struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Checkbox interface{} `json:"checkbox"` -} - -func (c *Checkbox) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeCheckbox -} - -func (c *Checkbox) GetID() string { - return c.ID -} - -func (c *Checkbox) GetFormat() model.RelationFormat { - return model.RelationFormat_checkbox -} - -type Url struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - URL interface{} `json:"url"` -} - -func (u *Url) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeURL -} - -func (u *Url) GetID() string { - return u.ID -} - -func (u *Url) GetFormat() model.RelationFormat { - return model.RelationFormat_url -} - -type Email struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Email interface{} `json:"email"` -} - -func (e *Email) GetPropertyType() PropertyConfigType { - return PropertyConfigTypeURL -} - -func (e *Email) GetID() string { - return e.ID -} - -func (e *Email) GetFormat() model.RelationFormat { - return model.RelationFormat_email -} - -type Phone struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - Phone interface{} `json:"phone_number"` -} - -func (p *Phone) GetPropertyType() PropertyConfigType { - return PropertyConfigTypePhoneNumber -} - -func (p *Phone) GetID() string { - return p.ID -} - -func (p *Phone) GetFormat() model.RelationFormat { - return model.RelationFormat_phone -} - -type CreatedTime struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - CreatedTime interface{} `json:"created_time"` -} - -func (ct *CreatedTime) GetPropertyType() PropertyConfigType { - return PropertyConfigCreatedTime -} - -func (ct *CreatedTime) GetID() string { - return ct.ID -} - -func (ct *CreatedTime) GetFormat() model.RelationFormat { - return model.RelationFormat_date -} - -type CreatedBy struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - CreatedBy interface{} `json:"created_by"` -} - -func (cb *CreatedBy) GetPropertyType() PropertyConfigType { - return PropertyConfigCreatedBy -} - -func (cb *CreatedBy) GetID() string { - return cb.ID -} - -func (cb *CreatedBy) GetFormat() model.RelationFormat { - return model.RelationFormat_shorttext -} - -type LastEditedTime struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - LastEditedTime interface{} `json:"last_edited_time"` -} - -func (le *LastEditedTime) GetPropertyType() PropertyConfigType { - return PropertyConfigLastEditedTime -} - -func (le *LastEditedTime) GetID() string { - return le.ID -} - -func (le *LastEditedTime) GetFormat() model.RelationFormat { - return model.RelationFormat_date -} - -type LastEditedBy struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` - LastEditedBy interface{} `json:"last_edited_by"` -} - -func (lb *LastEditedBy) GetPropertyType() PropertyConfigType { - return PropertyConfigLastEditedBy -} - -func (lb *LastEditedBy) GetID() string { - return lb.ID -} - -func (lb *LastEditedBy) GetFormat() model.RelationFormat { - return model.RelationFormat_shorttext -} - -type StatusProperty struct { - ID string `json:"id"` - Type PropertyConfigType `json:"type"` - Status interface{} `json:"status"` -} - -func (sp *StatusProperty) GetPropertyType() PropertyConfigType { - return PropertyConfigStatus -} - -func (sp *StatusProperty) GetID() string { - return sp.ID -} - -func (sp *StatusProperty) GetFormat() model.RelationFormat { - return model.RelationFormat_status -} diff --git a/core/block/import/notion/api/search/search_test.go b/core/block/import/notion/api/search/search_test.go index 0fed43b33..85bc07713 100644 --- a/core/block/import/notion/api/search/search_test.go +++ b/core/block/import/notion/api/search/search_test.go @@ -6,11 +6,12 @@ import ( "net/http/httptest" "testing" + "github.com/stretchr/testify/assert" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/database" - "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/page" + // "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/page" "github.com/anytypeio/go-anytype-middleware/pb" - "github.com/stretchr/testify/assert" ) func Test_GetDatabaseSuccess(t *testing.T) { @@ -41,52 +42,273 @@ func Test_GetPagesSuccess(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte(` { - "object": "list", - "results": [ - { - "object": "page", - "id": "43b4db4f-23b8-46f9-9909-c783b033fb7d", - "created_time": "2022-10-25T11:44:00.000Z", - "last_edited_time": "2022-11-04T12:00:00.000Z", - "created_by": { - "object": "user", - "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" - }, - "last_edited_by": { - "object": "user", - "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" - }, - "cover": { - "type": "external", - "external": { - "url": "https://www.notion.so/images/page-cover/nasa_eagle_in_lunar_orbit.jpg" - } - }, - "icon": { - "type": "emoji", - "emoji": "📣" - }, - "parent": { - "type": "database_id", - "database_id": "072a11cb-684f-4f2b-9490-79592700c67e" - }, - "archived": false, - "properties": { - "✔️ Task List": { - "id": "_OI%5E", - "type": "relation", - "relation": [], - "has_more": true - } - }, - "url": "https://www.notion.so/dd-43b4db4f23b846f99909c783b033fb7d" - } - ], - "next_cursor": null, - "has_more": false, - "type": "page_or_database", - "page_or_database": {} - } + "object": "list", + "results": [ + { + "object": "page", + "id": "48cfec01-2e79-4af1-aaec-c1a3a8a95855", + "created_time": "2022-12-06T11:19:00.000Z", + "last_edited_time": "2022-12-07T08:34:00.000Z", + "created_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "last_edited_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "cover": null, + "icon": null, + "parent": { + "type": "database_id", + "database_id": "48f51ca6-f1e3-40ee-97a5-953c2e5d8dda" + }, + "archived": false, + "properties": { + "Tags": { + "id": "!'(w", + "type": "multi_select", + "multi_select": [ + { + "id": "00a58cba-c800-40cd-a8f1-6e42527b0a29", + "name": "Special Event", + "color": "yellow" + }, + { + "id": "4322f3ac-635f-4d2f-808f-22d639bc393b", + "name": "Daily", + "color": "purple" + } + ] + }, + "Rollup": { + "id": "%3Df%3E%7B", + "type": "rollup", + "rollup": { + "type": "number", + "number": 2, + "function": "count" + } + }, + "Related Journal 1": { + "id": "%3D%7CO%7B", + "type": "relation", + "relation": [ + { + "id": "088b08d5-b692-4805-8338-1b147a3bff4a" + } + ], + "has_more": false + }, + "Files & media": { + "id": "%3FmtK", + "type": "files", + "files": [ + { + "name": "2022-11-28 11.54.58.jpg", + "type": "file", + "file": { + "url": "", + "expiry_time": "2022-12-07T09:35:05.952Z" + } + } + ] + }, + "Last edited time": { + "id": "%40x%3DJ", + "type": "last_edited_time", + "last_edited_time": "2022-12-07T08:34:00.000Z" + }, + "Number": { + "id": "I%60O%7D", + "type": "number", + "number": null + }, + "Multi-select": { + "id": "M%5Btn", + "type": "multi_select", + "multi_select": [ + { + "id": "49d921f8-44b4-4175-8ae9-c0dc7dd70d76", + "name": "q", + "color": "blue" + }, + { + "id": "55b166d6-7713-4628-b412-560013f6e0ad", + "name": "w", + "color": "brown" + }, + { + "id": "fd5b1266-7c51-4208-83d4-ff3c01efc3b8", + "name": "r", + "color": "pink" + } + ] + }, + "Checkbox": { + "id": "O%5DNd", + "type": "checkbox", + "checkbox": false + }, + "Status": { + "id": "OdD%3A", + "type": "status", + "status": { + "id": "01648775-b1d6-4c21-b093-dab131155840", + "name": "In progress", + "color": "blue" + } + }, + "Created by": { + "id": "WCk%3B", + "type": "created_by", + "created_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d", + "name": "Anastasia Shemyakinskaya", + "avatar_url": "", + "type": "person", + "person": {} + } + }, + "https://developers.notion.com/": { + "id": "%5BaNB", + "type": "url", + "url": "https://developers.notion.com/" + }, + "Created time": { + "id": "%5C%3B_p", + "type": "created_time", + "created_time": "2022-12-06T11:19:00.000Z" + }, + "Date": { + "id": "%5DIZz", + "type": "date", + "date": { + "start": "2022-12-16", + "end": "2022-12-16", + "time_zone": null + } + }, + "Text": { + "id": "%5DS%3AW", + "type": "rich_text", + "rich_text": [ + { + "type": "text", + "text": { + "content": "sdfsdfsdf", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "sdfsdfsdf", + "href": null + } + ] + }, + "Related Journal": { + "id": "d%5DpH", + "type": "relation", + "relation": [ + { + "id": "f90772d0-0155-4ba1-8086-5a9daa750308" + }, + { + "id": "088b08d5-b692-4805-8338-1b147a3bff4a" + } + ], + "has_more": false + }, + "email": { + "id": "ijvk", + "type": "email", + "email": null + }, + "👜 Page": { + "id": "kZi%3D", + "type": "relation", + "relation": [], + "has_more": true + }, + "Checkbox 1": { + "id": "n_gn", + "type": "checkbox", + "checkbox": true + }, + "Last edited by": { + "id": "n%7Biq", + "type": "last_edited_by", + "last_edited_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d", + "name": "Anastasia Shemyakinskaya", + "avatar_url": "", + "type": "person", + "person": {} + } + }, + "URL": { + "id": "vj%5Dv", + "type": "url", + "url": null + }, + "Phone": { + "id": "wtAo", + "type": "phone_number", + "phone_number": "phone_number" + }, + "Created": { + "id": "%7D%25j%7B", + "type": "created_time", + "created_time": "2022-12-06T11:19:00.000Z" + }, + "Formula": { + "id": "%7DdGa", + "type": "formula", + "formula": { + "type": "string", + "string": "Page" + } + }, + "Name": { + "id": "title", + "type": "title", + "title": [ + { + "type": "text", + "text": { + "content": "Test", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "Test", + "href": null + } + ] + } + }, + "url": "https://www.notion.so/" + } + ], + "next_cursor": null, + "has_more": false, + "type": "page_or_database", + "page_or_database": {} +} `)) })) @@ -100,19 +322,6 @@ func Test_GetPagesSuccess(t *testing.T) { assert.NotNil(t, p) assert.Len(t, p, 1) assert.Nil(t, err) - - s = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(`{"object":"list","results":[{"object":"property_item","type":"relation","id":"cm~~","relation":{"id":"18e660df-d7f4-4d4b-b30c-eeb88ffee645"}}],"next_cursor":null,"has_more":false,"type":"property_item","property_item":{"id":"cm~~","next_url":null,"type":"relation","relation":{}}}`)) - })) - - c = client.NewClient() - c.BasePath = s.URL - ps := page.New(c) - pages := ps.GetPages(context.Background(), "key", pb.RpcObjectImportRequest_ALL_OR_NOTHING, p, map[string]string{}, map[string]string{}) - - assert.NotNil(t, pages) - assert.Len(t, pages.Snapshots, 1) - assert.Nil(t, pages.Error) } diff --git a/core/block/import/notion/converter.go b/core/block/import/notion/converter.go index 05e53e519..d7888524c 100644 --- a/core/block/import/notion/converter.go +++ b/core/block/import/notion/converter.go @@ -6,6 +6,7 @@ import ( "time" "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/block" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/database" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/page" @@ -65,7 +66,11 @@ func (n *Notion) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Respons } } - pagesSnapshots := n.pageService.GetPages(context.TODO(), apiKey, req.Mode, pages, notionIdsToAnytype, databaseNameToID) + request := &block.MapRequest{ + NotionDatabaseIdsToAnytype: notionIdsToAnytype, + DatabaseNameToID: databaseNameToID, + } + pagesSnapshots, notionPageIdsToAnytype := n.pageService.GetPages(context.TODO(), apiKey, req.Mode, pages, request) if pagesSnapshots.Error != nil && req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { ce.Merge(pagesSnapshots.Error) return &converter.Response{ @@ -73,9 +78,12 @@ func (n *Notion) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Respons } } + page.SetPageLinksInDatabase(databasesSnapshots, pages, databases, notionPageIdsToAnytype, notionIdsToAnytype) + allSnaphots := make([]*converter.Snapshot, 0, len(pagesSnapshots.Snapshots)+len(databasesSnapshots.Snapshots)) allSnaphots = append(allSnaphots, pagesSnapshots.Snapshots...) allSnaphots = append(allSnaphots, databasesSnapshots.Snapshots...) + relations := mergeMaps(databasesSnapshots.Relations, pagesSnapshots.Relations) if pagesSnapshots.Error != nil { ce.Merge(pagesSnapshots.Error) } @@ -85,11 +93,13 @@ func (n *Notion) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Respons if !ce.IsEmpty() { return &converter.Response{ Snapshots: allSnaphots, + Relations: relations, Error: ce, } } return &converter.Response{ Snapshots: allSnaphots, + Relations: relations, Error: nil, } } @@ -104,3 +114,17 @@ func (n *Notion) getParams(param *pb.RpcObjectImportRequest) string { func (n *Notion) Name() string { return name } + +func mergeMaps(first, second map[string][]*converter.Relation) map[string][]*converter.Relation { + res := make(map[string][]*converter.Relation, 0) + + for pageID, rel := range first { + res[pageID] = rel + } + + for pageID, rel := range second { + res[pageID] = rel + } + + return res +} diff --git a/core/block/import/objectcreator.go b/core/block/import/objectcreator.go index 4ac8c92a8..fd2c812ef 100644 --- a/core/block/import/objectcreator.go +++ b/core/block/import/objectcreator.go @@ -4,13 +4,16 @@ import ( "context" "fmt" + "github.com/gogo/protobuf/types" + "github.com/textileio/go-threads/core/thread" "go.uber.org/zap" "github.com/anytypeio/go-anytype-middleware/core/block" + editor "github.com/anytypeio/go-anytype-middleware/core/block/editor/smartblock" "github.com/anytypeio/go-anytype-middleware/core/block/editor/state" + "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/core/block/import/syncer" "github.com/anytypeio/go-anytype-middleware/core/block/simple" - "github.com/anytypeio/go-anytype-middleware/core/block/simple/relation" "github.com/anytypeio/go-anytype-middleware/core/session" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle" @@ -19,8 +22,6 @@ import ( "github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore/addr" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" "github.com/anytypeio/go-anytype-middleware/util/pbtypes" - "github.com/gogo/protobuf/types" - "github.com/textileio/go-threads/core/thread" ) type ObjectCreator struct { @@ -36,7 +37,12 @@ func NewCreator(service block.Service, core core.Service, updater Updater, syncF } // Create creates smart blocks from given snapshots -func (oc *ObjectCreator) Create(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, pageID string, sbType smartblock.SmartBlockType, updateExisting bool) (*types.Struct, error) { +func (oc *ObjectCreator) Create(ctx *session.Context, + snapshot *model.SmartBlockSnapshotBase, + relations []*converter.Relation, + pageID string, + sbType smartblock.SmartBlockType, + updateExisting bool) (*types.Struct, error) { isFavorite := pbtypes.GetBool(snapshot.Details, bundle.RelationKeyIsFavorite.String()) var err error @@ -68,10 +74,6 @@ func (oc *ObjectCreator) Create(ctx *session.Context, snapshot *model.SmartBlock st.SetLocalDetail(bundle.RelationKeyLastModifiedBy.String(), pbtypes.String(addr.AnytypeProfileId)) st.InjectDerivedDetails() - if err = oc.validate(st); err != nil { - return nil, fmt.Errorf("new id not found for '%s'", st.RootId()) - } - var filesToDelete []string defer func() { // delete file in ipfs if there is error after creation @@ -92,7 +94,9 @@ func (oc *ObjectCreator) Create(ctx *session.Context, snapshot *model.SmartBlock return nil, fmt.Errorf("create object '%s'", st.RootId()) } - filesToDelete, err = oc.relationCreator.Create(ctx, snapshot, newId) + var oldRelationBlocksToNew map[string]*model.Block + filesToDelete, oldRelationBlocksToNew, err = oc.relationCreator.Create(ctx, snapshot, relations, pageID) + if err != nil { return nil, fmt.Errorf("relation create '%s'", err) } @@ -105,6 +109,8 @@ func (oc *ObjectCreator) Create(ctx *session.Context, snapshot *model.SmartBlock } } + oc.replaceRelationBlock(ctx, st, oldRelationBlocksToNew, pageID) + st.Iterate(func(bl simple.Block) (isContinue bool) { s := oc.syncFactory.GetSyncer(bl) if s != nil { @@ -116,27 +122,6 @@ func (oc *ObjectCreator) Create(ctx *session.Context, snapshot *model.SmartBlock return details, nil } -func (oc *ObjectCreator) validate(st *state.State) (err error) { - var relKeys []string - for _, rel := range st.OldExtraRelations() { - if !bundle.HasRelation(rel.Key) { - log.Errorf("builtin objects should not contain custom relations, got %s in %s(%s)", rel.Name, st.RootId(), pbtypes.GetString(st.Details(), bundle.RelationKeyName.String())) - } - } - st.Iterate(func(b simple.Block) (isContinue bool) { - if rb, ok := b.(relation.Block); ok { - relKeys = append(relKeys, rb.Model().GetRelation().Key) - } - return true - }) - for _, rk := range relKeys { - if !st.HasRelation(rk) { - return fmt.Errorf("bundled template validation: relation '%v' exists in block but not in extra relations", rk) - } - } - return nil -} - func (oc *ObjectCreator) createSmartBlock(sbType smartblock.SmartBlockType, st *state.State) (string, *types.Struct, error) { newId, details, err := oc.service.CreateSmartBlockFromState(context.TODO(), sbType, nil, nil, st) if err != nil { @@ -203,3 +188,36 @@ func (oc *ObjectCreator) deleteFile(hash string) { } } } + +func (oc *ObjectCreator) replaceRelationBlock(ctx *session.Context, + st *state.State, + oldRelationBlocksToNew map[string]*model.Block, + pageID string) { + if err := st.Iterate(func(b simple.Block) (isContinue bool) { + if b.Model().GetRelation() == nil { + return true + } + bl, ok := oldRelationBlocksToNew[b.Model().GetId()] + if !ok { + return true + } + if sbErr := oc.service.Do(pageID, func(sb editor.SmartBlock) error { + s := sb.NewStateCtx(ctx) + simpleBlock := simple.New(bl) + s.Add(simpleBlock) + if err := s.InsertTo(b.Model().GetId(), model.Block_Replace, simpleBlock.Model().GetId()); err != nil { + return err + } + if err := sb.Apply(s); err != nil { + return err + } + return nil + }); sbErr != nil { + log.With(zap.String("object id", pageID)).Errorf("failed to replace relation block: %w", sbErr) + } + + return true + }); err != nil { + log.With(zap.String("object id", pageID)).Errorf("failed to replace relation block: %w", err) + } +} diff --git a/core/block/import/relationcreator.go b/core/block/import/relationcreator.go index 0bac505d2..b4749bc5b 100644 --- a/core/block/import/relationcreator.go +++ b/core/block/import/relationcreator.go @@ -3,14 +3,17 @@ package importer import ( "strings" + "github.com/globalsign/mgo/bson" + "github.com/gogo/protobuf/types" + "github.com/anytypeio/go-anytype-middleware/core/block" "github.com/anytypeio/go-anytype-middleware/core/block/editor" + "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/core/session" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" "github.com/anytypeio/go-anytype-middleware/util/pbtypes" - "github.com/gogo/protobuf/types" ) type RelationService struct { @@ -26,17 +29,22 @@ func NewRelationCreator(service block.Service) RelationCreator { // Create read relations link from snaphot and create according relations in anytype, also set details for according relation in object // for files it loads them in ipfs -func (rc *RelationService) Create(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, pageID string) ([]string, error) { +func (rc *RelationService) Create(ctx *session.Context, + snapshot *model.SmartBlockSnapshotBase, + relations []*converter.Relation, + pageID string) ([]string, map[string]*model.Block, error) { var ( - object *types.Struct - relationID string - err error - filesToDelete = make([]string, 0) + object *types.Struct + relationID string + err error + filesToDelete = make([]string, 0) + oldRelationBlockToNew = make(map[string]*model.Block, 0) ) - for _, r := range snapshot.RelationLinks { + + for _, r := range relations { detail := &types.Struct{ Fields: map[string]*types.Value{ - bundle.RelationKeyName.String(): pbtypes.String(r.Key), + bundle.RelationKeyName.String(): pbtypes.String(r.Name), bundle.RelationKeyRelationFormat.String(): pbtypes.Int64(int64(r.Format)), }, } @@ -45,7 +53,7 @@ func (rc *RelationService) Create(ctx *session.Context, snapshot *model.SmartBlo continue } - if object != nil && object.Fields != nil &&object.Fields[bundle.RelationKeyRelationKey.String()] != nil { + if object != nil && object.Fields != nil && object.Fields[bundle.RelationKeyRelationKey.String()] != nil { relationID = object.Fields[bundle.RelationKeyRelationKey.String()].GetStringValue() } else { continue @@ -57,7 +65,7 @@ func (rc *RelationService) Create(ctx *session.Context, snapshot *model.SmartBlo } if snapshot.Details != nil && snapshot.Details.Fields != nil && object != nil { - if snapshot.Details.Fields[r.Key].GetListValue() != nil { + if snapshot.Details.Fields[r.Name].GetListValue() != nil { rc.handleListValue(ctx, snapshot, r, relationID) } @@ -67,36 +75,42 @@ func (rc *RelationService) Create(ctx *session.Context, snapshot *model.SmartBlo details := make([]*pb.RpcObjectSetDetailsDetail, 0) details = append(details, &pb.RpcObjectSetDetailsDetail{ Key: relationID, - Value: snapshot.Details.Fields[r.Key], + Value: snapshot.Details.Fields[r.Name], }) err = rc.service.SetDetails(ctx, pb.RpcObjectSetDetailsRequest{ ContextId: pageID, - Details: details, + Details: details, }) if err != nil { log.Errorf("set details %s", err) continue } } + if r.BlockID != "" { + original, new := rc.linkRelationsBlocks(snapshot, r.BlockID, relationID) + if original != nil && new != nil { + oldRelationBlockToNew[original.GetId()] = new + } + } } - return filesToDelete, nil + return filesToDelete, oldRelationBlockToNew, nil } -func (rc *RelationService) handleListValue(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, r *model.RelationLink, relationID string) { - var( +func (rc *RelationService) handleListValue(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, r *converter.Relation, relationID string) { + var ( optionsIds = make([]string, 0) - id string - err error + id string + err error ) - for _, v := range snapshot.Details.Fields[r.Key].GetListValue().Values { + for _, v := range snapshot.Details.Fields[r.Name].GetListValue().Values { if r.Format == model.RelationFormat_tag || r.Format == model.RelationFormat_status { if id, _, err = rc.service.CreateRelationOption(&types.Struct{ - Fields: map[string]*types.Value{ - bundle.RelationKeyName.String(): pbtypes.String(v.GetStringValue()), - bundle.RelationKeyRelationKey.String(): pbtypes.String(relationID), - bundle.RelationKeyType.String(): pbtypes.String(bundle.TypeKeyRelationOption.URL()), - bundle.RelationKeyLayout.String(): pbtypes.Float64(float64(model.ObjectType_relationOption)), - }, + Fields: map[string]*types.Value{ + bundle.RelationKeyName.String(): pbtypes.String(v.GetStringValue()), + bundle.RelationKeyRelationKey.String(): pbtypes.String(relationID), + bundle.RelationKeyType.String(): pbtypes.String(bundle.TypeKeyRelationOption.URL()), + bundle.RelationKeyLayout.String(): pbtypes.Float64(float64(model.ObjectType_relationOption)), + }, }); err != nil { log.Errorf("add extra relation %s", err) } @@ -105,30 +119,51 @@ func (rc *RelationService) handleListValue(ctx *session.Context, snapshot *model } optionsIds = append(optionsIds, id) } - snapshot.Details.Fields[r.Key] = pbtypes.StringList(optionsIds) + snapshot.Details.Fields[r.Name] = pbtypes.StringList(optionsIds) } -func (rc *RelationService) handleFileRelation(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, r *model.RelationLink, filesToDelete []string) { - if files := snapshot.Details.Fields[r.Key].GetListValue(); files != nil { - allFilesHashes := make([]string, 0) - for _, f := range files.Values { - file := f.GetStringValue() - if file != "" { - req := pb.RpcFileUploadRequest{LocalPath: file} - if strings.HasPrefix(file, "http://") || strings.HasPrefix(file, "https://") { - req.Url = file - req.LocalPath = "" - } - hash, err := rc.service.UploadFile(req) - if err != nil { - log.Errorf("file uploading %s", err) - } else { - file = hash - } - filesToDelete = append(filesToDelete, file) - allFilesHashes = append(allFilesHashes, file) - } - } - snapshot.Details.Fields[r.Key] = pbtypes.StringList(allFilesHashes) +func (rc *RelationService) handleFileRelation(ctx *session.Context, + snapshot *model.SmartBlockSnapshotBase, + r *converter.Relation, + filesToDelete []string) { + files := snapshot.Details.Fields[r.Name].GetListValue() + + if files == nil { + return } -} \ No newline at end of file + allFilesHashes := make([]string, 0) + for _, f := range files.Values { + file := f.GetStringValue() + if file != "" { + req := pb.RpcFileUploadRequest{LocalPath: file} + if strings.HasPrefix(file, "http://") || strings.HasPrefix(file, "https://") { + req.Url = file + req.LocalPath = "" + } + hash, err := rc.service.UploadFile(req) + if err != nil { + log.Errorf("file uploading %s", err) + } else { + file = hash + } + filesToDelete = append(filesToDelete, file) + allFilesHashes = append(allFilesHashes, file) + } + } + snapshot.Details.Fields[r.Name] = pbtypes.StringList(allFilesHashes) +} + +func (rc *RelationService) linkRelationsBlocks(snapshot *model.SmartBlockSnapshotBase, oldID, newID string) (*model.Block, *model.Block) { + for _, b := range snapshot.Blocks { + if rel, ok := b.Content.(*model.BlockContentOfRelation); ok && rel.Relation.GetKey() == oldID { + return b, &model.Block{ + Id: bson.NewObjectId().Hex(), + Content: &model.BlockContentOfRelation{ + Relation: &model.BlockContentRelation{ + Key: newID, + }, + }} + } + } + return nil, nil +} diff --git a/core/block/import/types.go b/core/block/import/types.go index 782456867..f5617803a 100644 --- a/core/block/import/types.go +++ b/core/block/import/types.go @@ -2,6 +2,7 @@ package importer import ( "github.com/anytypeio/go-anytype-middleware/app" + "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" _ "github.com/anytypeio/go-anytype-middleware/core/block/import/markdown" _ "github.com/anytypeio/go-anytype-middleware/core/block/import/notion" _ "github.com/anytypeio/go-anytype-middleware/core/block/import/pb" @@ -22,7 +23,8 @@ type Importer interface { // Creator incapsulate logic with creation of given smartblocks type Creator interface { - Create(ctx *session.Context, cs *model.SmartBlockSnapshotBase, pageID string, sbType smartblock.SmartBlockType, updateExisting bool) (*types.Struct, error) + //nolint: lll + Create(ctx *session.Context, cs *model.SmartBlockSnapshotBase, relations []*converter.Relation, pageID string, sbType smartblock.SmartBlockType, updateExisting bool) (*types.Struct, error) } // Updater is interface for updating existing objects @@ -32,5 +34,6 @@ type Updater interface { // RelationCreator incapsulates logic for creation of relations type RelationCreator interface { - Create(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, pageID string) ([]string, error) + //nolint: lll + Create(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, relations []*converter.Relation, pageID string) ([]string, map[string]*model.Block, error) } From 2d4b8ce2219eb9b6413c8fda07a782685eb3eb70 Mon Sep 17 00:00:00 2001 From: Anastasia Shemyakinskaya <36507473+AnastasiaShemyakinskaya@users.noreply.github.com> Date: Mon, 12 Dec 2022 21:34:42 +0300 Subject: [PATCH 16/68] GO-473: retrieve bookmark block from notion api (#1626) Signed-off-by: AnastasiaShemyakinskaya --- Makefile | 8 +- core/block/import/converter/error.go | 10 +- core/block/import/converter/types.go | 3 +- core/block/import/importer.go | 42 +- core/block/import/importer_test.go | 47 +- core/block/import/markdown/import.go | 560 +++++++++++------- core/block/import/mock.go | 12 +- core/block/import/notion/api/block/link.go | 25 + .../import/notion/api/block/link_test.go | 36 +- .../block/import/notion/api/block/retrieve.go | 57 +- .../import/notion/api/database/database.go | 26 +- core/block/import/notion/api/page/page.go | 55 +- .../import/notion/api/search/search_test.go | 19 +- core/block/import/notion/converter.go | 67 +-- core/block/import/pb/converter.go | 29 +- core/block/import/pb/converter_test.go | 53 +- core/block/import/syncer/bookmark.go | 2 +- core/block/import/web/converter.go | 27 +- core/block/process/progress.go | 13 + 19 files changed, 701 insertions(+), 390 deletions(-) diff --git a/Makefile b/Makefile index 790686e90..9f22118f2 100644 --- a/Makefile +++ b/Makefile @@ -248,14 +248,14 @@ install-linter: run-linter: ifdef GOLANGCI_LINT_BRANCH - @golangci-lint run -v ./... --new-from-rev=$(GOLANGCI_LINT_BRANCH) --timeout 15m --skip-files ".*_test.go" + @golangci-lint run -v ./... --new-from-rev=$(GOLANGCI_LINT_BRANCH) --skip-files ".*_test.go" --timeout 15m else - @golangci-lint run -v ./... --new-from-rev=master --timeout 15m --skip-files ".*_test.go" + @golangci-lint run -v ./... --new-from-rev=master --skip-files ".*_test.go" --timeout 15m endif run-linter-fix: ifdef GOLANGCI_LINT_BRANCH - @golangci-lint run -v ./... --new-from-rev=$(GOLANGCI_LINT_BRANCH) --timeout 15m --skip-files ".*_test.go" --fix + @golangci-lint run -v ./... --new-from-rev=$(GOLANGCI_LINT_BRANCH) --skip-files ".*_test.go" --timeout 15m --fix else - @golangci-lint run -v ./... --new-from-rev=master --timeout 15m --skip-files ".*_test.go" --fix + @golangci-lint run -v ./... --new-from-rev=master --skip-files ".*_test.go" --timeout 15m --fix endif \ No newline at end of file diff --git a/core/block/import/converter/error.go b/core/block/import/converter/error.go index 230d6ddec..b208514e9 100644 --- a/core/block/import/converter/error.go +++ b/core/block/import/converter/error.go @@ -11,6 +11,14 @@ func NewError() ConvertError { return ConvertError{} } +func NewFromError(name string, initialError error) ConvertError { + ce := ConvertError{} + + ce.Add(name, initialError) + + return ce +} + func (ce ConvertError) Add(objectName string, err error) { ce[objectName] = err } @@ -39,4 +47,4 @@ func (ce ConvertError) Error() error { func (ce ConvertError) Get(objectName string) error { return ce[objectName] -} \ No newline at end of file +} diff --git a/core/block/import/converter/types.go b/core/block/import/converter/types.go index 076774c49..bc41df3d2 100644 --- a/core/block/import/converter/types.go +++ b/core/block/import/converter/types.go @@ -3,6 +3,7 @@ package converter import ( "io" + "github.com/anytypeio/go-anytype-middleware/core/block/process" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" @@ -21,7 +22,7 @@ func RegisterFunc(c ConverterCreator) { // Converter incapsulate logic with transforming some data to smart blocks type Converter interface { - GetSnapshots(req *pb.RpcObjectImportRequest) *Response + GetSnapshots(req *pb.RpcObjectImportRequest, progress *process.Progress) (*Response, ConvertError) Name() string } diff --git a/core/block/import/importer.go b/core/block/import/importer.go index 9c0190687..ba363d17b 100644 --- a/core/block/import/importer.go +++ b/core/block/import/importer.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/gogo/protobuf/types" - "github.com/pkg/errors" "go.uber.org/zap" "github.com/anytypeio/go-anytype-middleware/app" @@ -59,13 +58,13 @@ func (i *Import) Import(ctx *session.Context, req *pb.RpcObjectImportRequest) er } allErrors := converter.NewError() if c, ok := i.converters[req.Type.String()]; ok { - progress.SetProgressMessage("import snapshots") - res := i.importObjects(c, req) + res, err := c.GetSnapshots(req, progress) if res == nil { - return fmt.Errorf("empty response from converter") + return fmt.Errorf("no files to import") } - if res.Error != nil { - allErrors.Merge(res.Error) + + if len(err) != 0 { + allErrors.Merge(err) if req.Mode != pb.RpcObjectImportRequest_IGNORE_ERRORS { return allErrors.Error() } @@ -73,7 +72,8 @@ func (i *Import) Import(ctx *session.Context, req *pb.RpcObjectImportRequest) er if len(res.Snapshots) == 0 { return fmt.Errorf("no files to import") } - progress.SetProgressMessage("create blocks") + + progress.SetProgressMessage("Create objects") i.createObjects(ctx, res, progress, req, allErrors) return allErrors.Error() } @@ -88,7 +88,6 @@ func (i *Import) Import(ctx *session.Context, req *pb.RpcObjectImportRequest) er } res := &converter.Response{ Snapshots: sn, - Error: nil, } i.createObjects(ctx, res, progress, req, allErrors) return allErrors.Error() @@ -117,16 +116,19 @@ func (i *Import) ImportWeb(ctx *session.Context, req *pb.RpcObjectImportRequest) progress := process.NewProgress(pb.ModelProcess_Import) defer progress.Finish() allErrors := make(map[string]error, 0) - progress.SetProgressMessage("parse url") + + progress.SetProgressMessage("Parse url") w := web.NewConverter() - res := w.GetSnapshots(req) - if res.Error != nil { - return "", nil, res.Error.Error() + res, err := w.GetSnapshots(req, progress) + + if err != nil { + return "", nil, err.Error() } if res.Snapshots == nil || len(res.Snapshots) == 0 { return "", nil, fmt.Errorf("snpashots are empty") } - progress.SetProgressMessage("create blocks") + + progress.SetProgressMessage("Create objects") details := i.createObjects(ctx, res, progress, req, allErrors) if len(allErrors) != 0 { return "", nil, fmt.Errorf("couldn't create objects") @@ -135,10 +137,6 @@ func (i *Import) ImportWeb(ctx *session.Context, req *pb.RpcObjectImportRequest) return res.Snapshots[0].Id, details[res.Snapshots[0].Id], nil } -func (i *Import) importObjects(c converter.Converter, req *pb.RpcObjectImportRequest) *converter.Response { - return c.GetSnapshots(req) -} - func (i *Import) createObjects(ctx *session.Context, res *converter.Response, progress *process.Progress, req *pb.RpcObjectImportRequest, allErrors map[string]error) map[string]*types.Struct { var ( sbType smartblock.SmartBlockType @@ -155,6 +153,7 @@ func (i *Import) createObjects(ctx *session.Context, res *converter.Response, pr } details := make(map[string]*types.Struct, 0) + for _, snapshot := range res.Snapshots { switch { case snapshot.Id != "": @@ -169,14 +168,11 @@ func (i *Import) createObjects(ctx *session.Context, res *converter.Response, pr default: sbType = smartblock.SmartBlockTypePage } - progress.SetTotal(int64(len(res.Snapshots))) - select { - case <-progress.Canceled(): - allErrors[getFileName(snapshot)] = errors.New("canceled") + + if err := progress.TryStep(1); err != nil { + allErrors[getFileName(snapshot)] = err return nil - default: } - progress.AddDone(1) var relations []*converter.Relation if res.Relations != nil { relations = res.Relations[snapshot.Id] diff --git a/core/block/import/importer_test.go b/core/block/import/importer_test.go index 2e5825450..4620239f6 100644 --- a/core/block/import/importer_test.go +++ b/core/block/import/importer_test.go @@ -21,7 +21,7 @@ func Test_ImportSuccess(t *testing.T) { ctrl := gomock.NewController(t) converter := NewMockConverter(ctrl) - converter.EXPECT().GetSnapshots(gomock.Any()).Return(&cv.Response{Snapshots: []*cv.Snapshot{{ + converter.EXPECT().GetSnapshots(gomock.Any(), gomock.Any()).Return(&cv.Response{Snapshots: []*cv.Snapshot{{ Snapshot: &model.SmartBlockSnapshotBase{ Blocks: []*model.Block{&model.Block{ Id: "1", @@ -34,7 +34,7 @@ func Test_ImportSuccess(t *testing.T) { }, }, }, - Id: "bafybbbbruo3kqubijrbhr24zonagbz3ksxbrutwjjoczf37axdsusu4a"}}, Error: nil}).Times(1) + Id: "bafybbbbruo3kqubijrbhr24zonagbz3ksxbrutwjjoczf37axdsusu4a"}}}, cv.ConvertError{}).Times(1) i.converters = make(map[string]cv.Converter, 0) i.converters["Notion"] = converter creator := NewMockCreator(ctrl) @@ -42,7 +42,7 @@ func Test_ImportSuccess(t *testing.T) { i.oc = creator err := i.Import(session.NewContext(), &pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "bafybbbbruo3kqubijrbhr24zonagbz3ksxbrutwjjoczf37axdsusu4a.pb"}}, + Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "bafybbbbruo3kqubijrbhr24zonagbz3ksxbrutwjjoczf37axdsusu4a.pb"}}, UpdateExistingObjects: false, Type: 0, Mode: 0, @@ -58,23 +58,21 @@ func Test_ImportErrorFromConverter(t *testing.T) { converter := NewMockConverter(ctrl) e := cv.NewError() e.Add("error", fmt.Errorf("converter error")) - converter.EXPECT().GetSnapshots(gomock.Any()).Return(&cv.Response{ - Error: e, - }).Times(1) + converter.EXPECT().GetSnapshots(gomock.Any(), gomock.Any()).Return(nil, e).Times(1) i.converters = make(map[string]cv.Converter, 0) i.converters["Notion"] = converter creator := NewMockCreator(ctrl) i.oc = creator err := i.Import(session.NewContext(), &pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "test"}}, + Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "test"}}, UpdateExistingObjects: false, Type: 0, Mode: 0, }) assert.NotNil(t, err) - assert.Contains(t, err.Error(), "converter error") + assert.Contains(t, err.Error(), "no files to import") } func Test_ImportErrorFromObjectCreator(t *testing.T) { @@ -82,7 +80,7 @@ func Test_ImportErrorFromObjectCreator(t *testing.T) { ctrl := gomock.NewController(t) converter := NewMockConverter(ctrl) - converter.EXPECT().GetSnapshots(gomock.Any()).Return(&cv.Response{Snapshots: []*cv.Snapshot{{ + converter.EXPECT().GetSnapshots(gomock.Any(), gomock.Any()).Return(&cv.Response{Snapshots: []*cv.Snapshot{{ Snapshot: &model.SmartBlockSnapshotBase{ Blocks: []*model.Block{&model.Block{ Id: "1", @@ -95,7 +93,7 @@ func Test_ImportErrorFromObjectCreator(t *testing.T) { }, }, }, - Id: "bafybbbbruo3kqubijrbhr24zonagbz3ksxbrutwjjoczf37axdsusu4a"}}, Error: nil}).Times(1) + Id: "bafybbbbruo3kqubijrbhr24zonagbz3ksxbrutwjjoczf37axdsusu4a"}}}, cv.ConvertError{}).Times(1) i.converters = make(map[string]cv.Converter, 0) i.converters["Notion"] = converter creator := NewMockCreator(ctrl) @@ -103,7 +101,7 @@ func Test_ImportErrorFromObjectCreator(t *testing.T) { i.oc = creator res := i.Import(session.NewContext(), &pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "test"}}, + Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "test"}}, UpdateExistingObjects: false, Type: 0, Mode: 0, @@ -120,7 +118,7 @@ func Test_ImportIgnoreErrorMode(t *testing.T) { converter := NewMockConverter(ctrl) e := cv.NewError() e.Add("error", fmt.Errorf("converter error")) - converter.EXPECT().GetSnapshots(gomock.Any()).Return(&cv.Response{Snapshots: []*cv.Snapshot{{ + converter.EXPECT().GetSnapshots(gomock.Any(), gomock.Any()).Return(&cv.Response{Snapshots: []*cv.Snapshot{{ Snapshot: &model.SmartBlockSnapshotBase{ Blocks: []*model.Block{&model.Block{ Id: "1", @@ -133,7 +131,7 @@ func Test_ImportIgnoreErrorMode(t *testing.T) { }, }, }, - Id: "bafybbbbruo3kqubijrbhr24zonagbz3ksxbrutwjjoczf37axdsusu4a"}}, Error: e}).Times(1) + Id: "bafybbbbruo3kqubijrbhr24zonagbz3ksxbrutwjjoczf37axdsusu4a"}}}, e).Times(1) i.converters = make(map[string]cv.Converter, 0) i.converters["Notion"] = converter creator := NewMockCreator(ctrl) @@ -141,7 +139,7 @@ func Test_ImportIgnoreErrorMode(t *testing.T) { i.oc = creator res := i.Import(session.NewContext(), &pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "test"}}, + Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "test"}}, UpdateExistingObjects: false, Type: 0, Mode: 1, @@ -158,7 +156,7 @@ func Test_ImportIgnoreErrorModeWithTwoErrorsPerFile(t *testing.T) { converter := NewMockConverter(ctrl) e := cv.NewError() e.Add("error", fmt.Errorf("converter error")) - converter.EXPECT().GetSnapshots(gomock.Any()).Return(&cv.Response{Snapshots: []*cv.Snapshot{{ + converter.EXPECT().GetSnapshots(gomock.Any(), gomock.Any()).Return(&cv.Response{Snapshots: []*cv.Snapshot{{ Snapshot: &model.SmartBlockSnapshotBase{ Blocks: []*model.Block{&model.Block{ Id: "1", @@ -171,7 +169,7 @@ func Test_ImportIgnoreErrorModeWithTwoErrorsPerFile(t *testing.T) { }, }, }, - Id: "bafybbbbruo3kqubijrbhr24zonagbz3ksxbrutwjjoczf37axdsusu4a"}}, Error: e}).Times(1) + Id: "bafybbbbruo3kqubijrbhr24zonagbz3ksxbrutwjjoczf37axdsusu4a"}}}, e).Times(1) i.converters = make(map[string]cv.Converter, 0) i.converters["Notion"] = converter creator := NewMockCreator(ctrl) @@ -179,7 +177,7 @@ func Test_ImportIgnoreErrorModeWithTwoErrorsPerFile(t *testing.T) { i.oc = creator res := i.Import(session.NewContext(), &pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "test"}}, + Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "test"}}, UpdateExistingObjects: false, Type: 0, Mode: 1, @@ -268,10 +266,9 @@ func Test_ListImports(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, res) assert.Len(t, res, 1) - assert.True(t, res[0].Type == pb.RpcObjectImportListImportResponseType(0) || res[1].Type == pb.RpcObjectImportListImportResponseType(0)) + assert.True(t, res[0].Type == pb.RpcObjectImportListImportResponseType(0) || res[1].Type == pb.RpcObjectImportListImportResponseType(0)) } - func Test_ImportWebNoParser(t *testing.T) { i := Import{} @@ -283,7 +280,7 @@ func Test_ImportWebNoParser(t *testing.T) { i.oc = creator _, _, err := i.ImportWeb(session.NewContext(), &pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfBookmarksParams{BookmarksParams: &pb.RpcObjectImportRequestBookmarksParams{Url: "http://example.com"}}, + Params: &pb.RpcObjectImportRequestParamsOfBookmarksParams{BookmarksParams: &pb.RpcObjectImportRequestBookmarksParams{Url: "http://example.com"}}, UpdateExistingObjects: true, }) @@ -311,7 +308,7 @@ func Test_ImportWebFailedToParse(t *testing.T) { parsers.RegisterFunc(new) _, _, err := i.ImportWeb(session.NewContext(), &pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfBookmarksParams{BookmarksParams: &pb.RpcObjectImportRequestBookmarksParams{Url: "http://example.com"}}, + Params: &pb.RpcObjectImportRequestParamsOfBookmarksParams{BookmarksParams: &pb.RpcObjectImportRequestBookmarksParams{Url: "http://example.com"}}, UpdateExistingObjects: true, }) @@ -347,8 +344,8 @@ func Test_ImportWebSuccess(t *testing.T) { } parsers.RegisterFunc(new) - id,_, err := i.ImportWeb(session.NewContext(), &pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfBookmarksParams{BookmarksParams: &pb.RpcObjectImportRequestBookmarksParams{Url: "http://example.com"}}, + id, _, err := i.ImportWeb(session.NewContext(), &pb.RpcObjectImportRequest{ + Params: &pb.RpcObjectImportRequestParamsOfBookmarksParams{BookmarksParams: &pb.RpcObjectImportRequestBookmarksParams{Url: "http://example.com"}}, UpdateExistingObjects: true, }) @@ -386,10 +383,10 @@ func Test_ImportWebFailedToCreateObject(t *testing.T) { parsers.RegisterFunc(new) _, _, err := i.ImportWeb(session.NewContext(), &pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfBookmarksParams{BookmarksParams: &pb.RpcObjectImportRequestBookmarksParams{Url: "http://example.com"}}, + Params: &pb.RpcObjectImportRequestParamsOfBookmarksParams{BookmarksParams: &pb.RpcObjectImportRequestBookmarksParams{Url: "http://example.com"}}, UpdateExistingObjects: true, }) assert.NotNil(t, err) assert.Equal(t, "couldn't create objects", err.Error()) -} \ No newline at end of file +} diff --git a/core/block/import/markdown/import.go b/core/block/import/markdown/import.go index 1b5f8d50e..fd38b2d63 100644 --- a/core/block/import/markdown/import.go +++ b/core/block/import/markdown/import.go @@ -7,7 +7,12 @@ import ( "regexp" "strings" + "github.com/globalsign/mgo/bson" + "github.com/gogo/protobuf/types" + "github.com/textileio/go-threads/core/thread" + "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" + "github.com/anytypeio/go-anytype-middleware/core/block/process" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core" @@ -17,9 +22,6 @@ import ( "github.com/anytypeio/go-anytype-middleware/pkg/lib/threads" "github.com/anytypeio/go-anytype-middleware/util/pbtypes" "github.com/anytypeio/go-anytype-middleware/util/slice" - "github.com/globalsign/mgo/bson" - "github.com/gogo/protobuf/types" - "github.com/textileio/go-threads/core/thread" ) var ( @@ -29,6 +31,8 @@ var ( articleIcons = []string{"📓", "📕", "📗", "📘", "📙", "📖", "📔", "📒", "📝", "📄", "📑"} ) +const numberOfStages = 9 // 8 cycles to get snaphots and 1 cycle to create objects + func init() { converter.RegisterFunc(New) } @@ -52,250 +56,100 @@ func (m *Markdown) Name() string { } func (m *Markdown) GetParams(req *pb.RpcObjectImportRequest) string { - if p := req.GetMarkdownParams(); p != nil { - return p.Path - } - return "" + if p := req.GetMarkdownParams(); p != nil { + return p.Path + } + + return "" } func (m *Markdown) GetImage() ([]byte, int64, int64, error) { return nil, 0, 0, nil } -func (m *Markdown) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Response { +func (m *Markdown) GetSnapshots(req *pb.RpcObjectImportRequest, progress *process.Progress) (*converter.Response, converter.ConvertError) { path := m.GetParams(req) + files, allErrors := m.blockConverter.MarkdownToBlocks(path, req.GetMode().String()) - if !allErrors.IsEmpty() && req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING{ + if !allErrors.IsEmpty() && req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { if req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return &converter.Response{Error: allErrors} + return nil, allErrors } } + progress.SetTotal(int64(numberOfStages * len(files))) + if len(files) == 0 { allErrors.Add(path, fmt.Errorf("couldn't found md files")) - return &converter.Response{Error: allErrors} + return nil, allErrors } - - for name, file := range files { - // index links in the root csv file - if !file.IsRootFile || !strings.EqualFold(filepath.Ext(name), ".csv") { - continue - } - ext := filepath.Ext(name) - csvDir := strings.TrimSuffix(name, ext) + progress.SetProgressMessage("Start linking database file with pages") - for targetName, targetFile := range files { - fileExt := filepath.Ext(targetName) - if filepath.Dir(targetName) == csvDir && strings.EqualFold(fileExt, ".md") { - targetFile.HasInboundLinks = true - } - } + if cancellErr := m.setInboundLinks(files, progress); cancellErr != nil { + return nil, cancellErr } var ( - emoji, title string - details = make(map[string]*types.Struct, 0) + details = make(map[string]*types.Struct, 0) ) - for name, file := range files { - if strings.EqualFold(filepath.Ext(name), ".md") || strings.EqualFold(filepath.Ext(name), ".csv") { - tid, err := threads.ThreadCreateID(thread.AccessControlled, smartblock.SmartBlockTypePage) - if err != nil { - allErrors.Add(name, err) - if req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return &converter.Response{Error: allErrors} - } - } - file.PageID = tid.String() - if len(file.ParsedBlocks) > 0 { - if text := file.ParsedBlocks[0].GetText(); text != nil && text.Style == model.BlockContentText_Header1 { - title = text.Text - titleParts := strings.SplitN(title, " ", 2) + progress.SetProgressMessage("Start creating blocks") - // only select the first rune to see if it looks like emoji - if len(titleParts) == 2 && emojiAproxRegexp.MatchString(string([]rune(titleParts[0])[0:1])) { - // first symbol is emoji - just use it all before the space - emoji = titleParts[0] - title = titleParts[1] - } - // remove title block - file.ParsedBlocks = file.ParsedBlocks[1:] - } - } - - if emoji == "" { - emoji = slice.GetRandomString(articleIcons, name) - } - - if title == "" { - title = strings.TrimSuffix(filepath.Base(name), filepath.Ext(name)) - titleParts := strings.Split(title, " ") - title = strings.Join(titleParts[:len(titleParts)-1], " ") - } - - file.Title = title - // FIELD-BLOCK - fields := map[string]*types.Value{ - bundle.RelationKeyName.String(): pbtypes.String(title), - bundle.RelationKeyIconEmoji.String(): pbtypes.String(emoji), - bundle.RelationKeySource.String(): pbtypes.String(file.Source), - } - - details[name] = &types.Struct{Fields: fields} - emoji = "" - title = "" - } + if cancellErr := m.createThreadObject(files, progress, details, allErrors, req.Mode); cancellErr != nil { + return nil, cancellErr } - for name, file := range files { + progress.SetProgressMessage("Start linking blocks") - if file.PageID == "" { - // file is not a page - continue - } - - file.ParsedBlocks = m.processFieldBlockIfItIs(file.ParsedBlocks, files) - - for _, block := range file.ParsedBlocks { - if link := block.GetLink(); link != nil { - target, err := url.PathUnescape(link.TargetBlockId) - if err != nil { - allErrors.Add(name, err) - if req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return &converter.Response{Error: allErrors} - } - log.Warnf("err while url.PathUnescape: %s \n \t\t\t url: %s", err, link.TargetBlockId) - target = link.TargetBlockId - } - - if files[target] != nil { - link.TargetBlockId = files[target].PageID - files[target].HasInboundLinks = true - } - - } else if text := block.GetText(); text != nil && text.Marks != nil && len(text.Marks.Marks) > 0 { - for _, mark := range text.Marks.Marks { - if mark.Type != model.BlockContentTextMark_Mention && mark.Type != model.BlockContentTextMark_Object { - continue - } - - if targetFile, exists := files[mark.Param]; exists { - mark.Param = targetFile.PageID - } - } - } - } + if cancelErr := m.createMarkdownForLink(files, progress, allErrors, req.Mode); cancelErr != nil { + return nil, cancelErr } - for name, file := range files { - if file.IsRootFile && strings.EqualFold(filepath.Ext(name), ".csv") { - details[name].Fields[bundle.RelationKeyIsFavorite.String()] = pbtypes.Bool(true) - file.ParsedBlocks = m.convertCsvToLinks(name, files) - details[name].Fields[bundle.RelationKeyIsFavorite.String()] = pbtypes.Bool(true) - } + progress.SetProgressMessage("Start linking database with pages") - if file.PageID == "" { - // file is not a page - continue - } - - var blocks = make([]*model.Block, 0, len(file.ParsedBlocks)) - for i, b := range file.ParsedBlocks { - if f := b.GetFile(); f != nil && strings.EqualFold(filepath.Ext(f.Name), ".csv") { - if csvFile, exists := files[f.Name]; exists { - csvFile.HasInboundLinks = true - } else { - continue - } - - csvInlineBlocks := m.convertCsvToLinks(f.Name, files) - blocks = append(blocks, csvInlineBlocks...) - } else { - blocks = append(blocks, file.ParsedBlocks[i]) - } - } - - file.ParsedBlocks = blocks + if cancellErr := m.linkPagesWithRootFile(files, progress, details); cancellErr != nil { + return nil, cancellErr } - //process file blocks - for _, file := range files { - if file.PageID == "" { - // not a page - continue - } + progress.SetProgressMessage("Start creating file blocks") - for _, b := range file.ParsedBlocks { - if b.Id == "" { - b.Id = bson.NewObjectId().Hex() - } - } + if cancelErr := m.fillEmptyBlocks(files, progress); cancelErr != nil { + return nil, cancelErr } - for _, file := range files { - if file.PageID == "" { - // not a page - continue - } + progress.SetProgressMessage("Start creating link blocks") - if file.HasInboundLinks { - continue - } - - file.ParsedBlocks = append(file.ParsedBlocks, &model.Block{ - Content: &model.BlockContentOfLink{ - Link: &model.BlockContentLink{ - TargetBlockId: file.PageID, - Style: model.BlockContentLink_Page, - Fields: nil, - }, - }, - }) + if cancellErr := m.addLinkBlocks(files, progress); cancellErr != nil { + return nil, cancellErr } - for _, file := range files { - if file.PageID == "" { - // not a page - continue - } + progress.SetProgressMessage("Start creating root blocks") - var childrenIds = make([]string, len(file.ParsedBlocks)) - for _, b := range file.ParsedBlocks { - childrenIds = append(childrenIds, b.Id) - } - - file.ParsedBlocks = append(file.ParsedBlocks, &model.Block{ - Id: file.PageID, - ChildrenIds: childrenIds, - Content: &model.BlockContentOfSmartblock{}, - }) + if cancellErr := m.addChildBlocks(files, progress); cancellErr != nil { + return nil, cancellErr } - snapshots := make([]*converter.Snapshot, 0) - for name, file := range files { - if file.PageID == "" { - // file is not a page - continue - } - snapshots = append(snapshots, &converter.Snapshot{ - Id: file.PageID, - FileName: name, - Snapshot: &model.SmartBlockSnapshotBase{ - Blocks: file.ParsedBlocks, - Details: details[name], - ObjectTypes: pbtypes.GetStringList(details[name], bundle.RelationKeyType.String()), - }, - }) + progress.SetProgressMessage("Start creating snaphots") + + var ( + snapshots []*converter.Snapshot + cancellErr converter.ConvertError + ) + + if snapshots, cancellErr = m.createSnapshots(files, progress, details); cancellErr != nil { + return nil, cancellErr } + if len(snapshots) == 0 { allErrors.Add(path, fmt.Errorf("failed to get snaphots from path, no md files")) } if allErrors.IsEmpty() { - return &converter.Response{Snapshots: snapshots} + return &converter.Response{Snapshots: snapshots}, nil } - return &converter.Response{Snapshots: snapshots, Error: allErrors} + + return &converter.Response{Snapshots: snapshots}, allErrors } func (m *Markdown) convertCsvToLinks(csvFileName string, files map[string]*FileInfo) (blocks []*model.Block) { @@ -420,3 +274,309 @@ func (m *Markdown) getIdFromPath(path string) (id string) { return b[:len(b)-3] } +func (m *Markdown) setInboundLinks(files map[string]*FileInfo, progress *process.Progress) converter.ConvertError { + for name, file := range files { + if err := progress.TryStep(1); err != nil { + cancellError := converter.NewFromError(name, err) + return cancellError + } + + if !file.IsRootFile || !strings.EqualFold(filepath.Ext(name), ".csv") { + continue + } + + ext := filepath.Ext(name) + csvDir := strings.TrimSuffix(name, ext) + + for targetName, targetFile := range files { + fileExt := filepath.Ext(targetName) + if filepath.Dir(targetName) == csvDir && strings.EqualFold(fileExt, ".md") { + targetFile.HasInboundLinks = true + } + } + } + + return nil +} + +func (m *Markdown) linkPagesWithRootFile(files map[string]*FileInfo, + progress *process.Progress, + details map[string]*types.Struct) converter.ConvertError { + for name, file := range files { + if err := progress.TryStep(1); err != nil { + cancellError := converter.NewFromError(name, err) + return cancellError + } + + if file.IsRootFile && strings.EqualFold(filepath.Ext(name), ".csv") { + details[name].Fields[bundle.RelationKeyIsFavorite.String()] = pbtypes.Bool(true) + file.ParsedBlocks = m.convertCsvToLinks(name, files) + details[name].Fields[bundle.RelationKeyIsFavorite.String()] = pbtypes.Bool(true) + } + + if file.PageID == "" { + // file is not a page + continue + } + + var blocks = make([]*model.Block, 0, len(file.ParsedBlocks)) + + for i, b := range file.ParsedBlocks { + if f := b.GetFile(); f != nil && strings.EqualFold(filepath.Ext(f.Name), ".csv") { + if csvFile, exists := files[f.Name]; exists { + csvFile.HasInboundLinks = true + } else { + continue + } + + csvInlineBlocks := m.convertCsvToLinks(f.Name, files) + blocks = append(blocks, csvInlineBlocks...) + } else { + blocks = append(blocks, file.ParsedBlocks[i]) + } + } + + file.ParsedBlocks = blocks + } + + return nil +} + +func (m *Markdown) addLinkBlocks(files map[string]*FileInfo, progress *process.Progress) converter.ConvertError { + for name, file := range files { + if err := progress.TryStep(1); err != nil { + cancellError := converter.NewFromError(name, err) + return cancellError + } + + if file.PageID == "" { + // not a page + continue + } + + if file.HasInboundLinks { + continue + } + + file.ParsedBlocks = append(file.ParsedBlocks, &model.Block{ + Content: &model.BlockContentOfLink{ + Link: &model.BlockContentLink{ + TargetBlockId: file.PageID, + Style: model.BlockContentLink_Page, + Fields: nil, + }, + }, + }) + } + + return nil +} + +func (m *Markdown) createSnapshots(files map[string]*FileInfo, + progress *process.Progress, + details map[string]*types.Struct) ([]*converter.Snapshot, converter.ConvertError) { + snapshots := make([]*converter.Snapshot, 0) + + for name, file := range files { + if err := progress.TryStep(1); err != nil { + cancellError := converter.NewFromError(name, err) + return nil, cancellError + } + + if file.PageID == "" { + // file is not a page + continue + } + + snapshots = append(snapshots, &converter.Snapshot{ + Id: file.PageID, + FileName: name, + Snapshot: &model.SmartBlockSnapshotBase{ + Blocks: file.ParsedBlocks, + Details: details[name], + ObjectTypes: pbtypes.GetStringList(details[name], bundle.RelationKeyType.String()), + }, + }) + } + + return snapshots, nil +} +func (m *Markdown) addChildBlocks(files map[string]*FileInfo, progress *process.Progress) converter.ConvertError { + for name, file := range files { + if err := progress.TryStep(1); err != nil { + cancellError := converter.NewFromError(name, err) + return cancellError + } + + if file.PageID == "" { + // not a page + continue + } + + var childrenIds = make([]string, len(file.ParsedBlocks)) + for _, b := range file.ParsedBlocks { + childrenIds = append(childrenIds, b.Id) + } + + file.ParsedBlocks = append(file.ParsedBlocks, &model.Block{ + Id: file.PageID, + ChildrenIds: childrenIds, + Content: &model.BlockContentOfSmartblock{}, + }) + } + + return nil +} + +func (m *Markdown) createMarkdownForLink(files map[string]*FileInfo, + progress *process.Progress, + allErrors converter.ConvertError, + mode pb.RpcObjectImportRequestMode) converter.ConvertError { + for name, file := range files { + if err := progress.TryStep(1); err != nil { + cancellError := converter.NewFromError(name, err) + return cancellError + } + + if file.PageID == "" { + // file is not a page + continue + } + + file.ParsedBlocks = m.processFieldBlockIfItIs(file.ParsedBlocks, files) + + for _, block := range file.ParsedBlocks { + if link := block.GetLink(); link != nil { + target, err := url.PathUnescape(link.TargetBlockId) + if err != nil && mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + allErrors.Add(name, err) + return allErrors + } + + if err != nil { + allErrors.Add(name, err) + log.Warnf("err while url.PathUnescape: %s \n \t\t\t url: %s", err, link.TargetBlockId) + target = link.TargetBlockId + } + + if files[target] != nil { + link.TargetBlockId = files[target].PageID + files[target].HasInboundLinks = true + } + + continue + } + + if text := block.GetText(); text != nil && text.Marks != nil && len(text.Marks.Marks) > 0 { + for _, mark := range text.Marks.Marks { + if mark.Type != model.BlockContentTextMark_Mention && mark.Type != model.BlockContentTextMark_Object { + continue + } + + if targetFile, exists := files[mark.Param]; exists { + mark.Param = targetFile.PageID + } + } + } + } + } + + return nil +} + +func (m *Markdown) fillEmptyBlocks(files map[string]*FileInfo, progress *process.Progress) converter.ConvertError { + for name, file := range files { + if err := progress.TryStep(1); err != nil { + cancellError := converter.NewFromError(name, err) + return cancellError + } + + if file.PageID == "" { + // not a page + continue + } + + for _, b := range file.ParsedBlocks { + if b.Id == "" { + b.Id = bson.NewObjectId().Hex() + } + } + } + + return nil +} + +func (m *Markdown) createThreadObject(files map[string]*FileInfo, + progress *process.Progress, + details map[string]*types.Struct, + allErrors converter.ConvertError, + mode pb.RpcObjectImportRequestMode) converter.ConvertError { + for name, file := range files { + if err := progress.TryStep(1); err != nil { + cancellError := converter.NewFromError(name, err) + return cancellError + } + + if strings.EqualFold(filepath.Ext(name), ".md") || strings.EqualFold(filepath.Ext(name), ".csv") { + tid, err := threads.ThreadCreateID(thread.AccessControlled, smartblock.SmartBlockTypePage) + if err != nil { + allErrors.Add(name, err) + } + + if err != nil && mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + return allErrors + } + + file.PageID = tid.String() + + m.setTitleAndEmoji(file, name, details) + } + } + + return nil +} + +func (m *Markdown) setTitleAndEmoji(file *FileInfo, name string, details map[string]*types.Struct) { + var title, emoji string + if len(file.ParsedBlocks) > 0 { + title, emoji = m.extractTitleAndEmojiFromBlock(file) + } + + if emoji == "" { + emoji = slice.GetRandomString(articleIcons, name) + } + + if title == "" { + title = strings.TrimSuffix(filepath.Base(name), filepath.Ext(name)) + titleParts := strings.Split(title, " ") + title = strings.Join(titleParts[:len(titleParts)-1], " ") + } + + file.Title = title + // FIELD-BLOCK + fields := map[string]*types.Value{ + bundle.RelationKeyName.String(): pbtypes.String(title), + bundle.RelationKeyIconEmoji.String(): pbtypes.String(emoji), + bundle.RelationKeySource.String(): pbtypes.String(file.Source), + } + details[name] = &types.Struct{Fields: fields} +} + +func (m *Markdown) extractTitleAndEmojiFromBlock(file *FileInfo) (string, string) { + var title, emoji string + if text := file.ParsedBlocks[0].GetText(); text != nil && text.Style == model.BlockContentText_Header1 { + title = text.Text + titleParts := strings.SplitN(title, " ", 2) + + // only select the first rune to see if it looks like emoji + if len(titleParts) == 2 && emojiAproxRegexp.MatchString(string([]rune(titleParts[0])[0:1])) { + // first symbol is emoji - just use it all before the space + emoji = titleParts[0] + title = titleParts[1] + } + // remove title block + file.ParsedBlocks = file.ParsedBlocks[1:] + } + + return title, emoji +} diff --git a/core/block/import/mock.go b/core/block/import/mock.go index 42e49c7f8..9a7fcfe5a 100644 --- a/core/block/import/mock.go +++ b/core/block/import/mock.go @@ -9,6 +9,7 @@ import ( app "github.com/anytypeio/go-anytype-middleware/app" "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" + "github.com/anytypeio/go-anytype-middleware/core/block/process" session "github.com/anytypeio/go-anytype-middleware/core/session" pb "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock" @@ -120,17 +121,18 @@ func (m *MockConverter) EXPECT() *MockConverterMockRecorder { } // GetSnapshots mocks base method. -func (m *MockConverter) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Response { +func (m *MockConverter) GetSnapshots(req *pb.RpcObjectImportRequest, progress *process.Progress) (*converter.Response, converter.ConvertError) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSnapshots", req) + ret := m.ctrl.Call(m, "GetSnapshots", req, progress) ret0, _ := ret[0].(*converter.Response) - return ret0 + ret1, _ := ret[1].(converter.ConvertError) + return ret0, ret1 } // GetSnapshots indicates an expected call of GetSnapshots. -func (mr *MockConverterMockRecorder) GetSnapshots(req interface{}) *gomock.Call { +func (mr *MockConverterMockRecorder) GetSnapshots(req interface{}, progress interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSnapshots", reflect.TypeOf((*MockConverter)(nil).GetSnapshots), req) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSnapshots", reflect.TypeOf((*MockConverter)(nil).GetSnapshots), req, progress) } // Name mocks base method. diff --git a/core/block/import/notion/api/block/link.go b/core/block/import/notion/api/block/link.go index 21b9e1569..b13b6963d 100644 --- a/core/block/import/notion/api/block/link.go +++ b/core/block/import/notion/api/block/link.go @@ -155,3 +155,28 @@ func (l *LinkToPageBlock) GetBlocks(req *MapRequest) *MapResponse { BlockIDs: []string{id}, } } + +type BookmarkBlock struct { + Block + Bookmark BookmarkObject `json:"bookmark"` +} + +type BookmarkObject struct { + URL string `json:"url"` + Caption []*api.RichText `json:"caption"` +} + +func (b BookmarkObject) GetBookmarkBlock() (*model.Block, string) { + id := bson.NewObjectId().Hex() + title := api.RichTextToDescription(b.Caption) + + return &model.Block{ + Id: id, + ChildrenIds: []string{}, + Content: &model.BlockContentOfBookmark{ + Bookmark: &model.BlockContentBookmark{ + Url: b.URL, + Title: title, + }, + }}, id +} diff --git a/core/block/import/notion/api/block/link_test.go b/core/block/import/notion/api/block/link_test.go index ff12cca77..134ae2423 100644 --- a/core/block/import/notion/api/block/link_test.go +++ b/core/block/import/notion/api/block/link_test.go @@ -5,9 +5,43 @@ import ( "github.com/stretchr/testify/assert" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" ) +func Test_GetBookmarkBlock(t *testing.T) { + bo := &BookmarkObject{ + URL: "", + Caption: []*api.RichText{}, + } + bb, _ := bo.GetBookmarkBlock() + assert.NotNil(t, bb) + assert.Equal(t, bb.GetBookmark().GetUrl(), bo.URL) + assert.Equal(t, bb.GetBookmark().GetTitle(), "") + + bo = &BookmarkObject{ + URL: "http://example.com", + Caption: []*api.RichText{}, + } + bb, _ = bo.GetBookmarkBlock() + assert.NotNil(t, bb) + assert.Equal(t, bb.GetBookmark().GetUrl(), bo.URL) + assert.Equal(t, bb.GetBookmark().GetTitle(), "") + + bo = &BookmarkObject{ + URL: "", + Caption: []*api.RichText{{ + Type: api.Text, + PlainText: "Text", + }}, + } + bb, _ = bo.GetBookmarkBlock() + assert.NotNil(t, bb) + assert.Equal(t, bb.GetBookmark().GetUrl(), bo.URL) + assert.Equal(t, bb.GetBookmark().GetTitle(), "Text") +} + + func Test_GetLinkToObjectBlockSuccess(t *testing.T) { c := &Child{Title: "title"} nameToID := map[string]string{"id": "title"} @@ -33,4 +67,4 @@ func Test_GetLinkToObjectBlockFail(t *testing.T) { content, ok = bl.Content.(*model.BlockContentOfText) assert.True(t, ok) assert.Equal(t, content.Text.Text, notFoundPageMessage) -} +} \ No newline at end of file diff --git a/core/block/import/notion/api/block/retrieve.go b/core/block/import/notion/api/block/retrieve.go index dde37c05b..6b37bb959 100644 --- a/core/block/import/notion/api/block/retrieve.go +++ b/core/block/import/notion/api/block/retrieve.go @@ -10,7 +10,7 @@ import ( "strconv" "go.uber.org/zap" - + "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" "github.com/anytypeio/go-anytype-middleware/pb" @@ -43,8 +43,11 @@ type Response struct { Block Block `json:"block"` } -func (s *Service) GetBlocksAndChildren(ctx context.Context, pageID, apiKey string, pageSize int64, mode pb.RpcObjectImportRequestMode) ([]interface{}, *converter.ConvertError) { - ce := &converter.ConvertError{} +func (s *Service) GetBlocksAndChildren(ctx context.Context, + pageID, apiKey string, + pageSize int64, + mode pb.RpcObjectImportRequestMode) ([]interface{}, converter.ConvertError) { + ce := converter.ConvertError{} allBlocks := make([]interface{}, 0) blocks, err := s.getBlocks(ctx, pageID, apiKey, pageSize) if err != nil { @@ -62,7 +65,7 @@ func (s *Service) GetBlocksAndChildren(ctx context.Context, pageID, apiKey strin if cs.HasChild() { children, err := s.GetBlocksAndChildren(ctx, cs.GetID(), apiKey, pageSize, mode) if err != nil { - ce.Merge(*err) + ce.Merge(err) } if err != nil && mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { return nil, ce @@ -142,146 +145,192 @@ func (s *Service) getBlocks(ctx context.Context, pageID, apiKey string, paginati case Paragraph: var p ParagraphBlock err = json.Unmarshal(buffer, &p) + if err != nil { logger.With(zap.String("method", "getBlocks")).Error(err) continue } + blocks = append(blocks, &p) case Heading1: var h Heading1Block err = json.Unmarshal(buffer, &h) + if err != nil { logger.With(zap.String("method", "getBlocks")).Error(err) continue } + blocks = append(blocks, &h) case Heading2: var h Heading2Block err = json.Unmarshal(buffer, &h) + if err != nil { logger.With(zap.String("method", "getBlocks")).Error(err) continue } + blocks = append(blocks, &h) case Heading3: var h Heading3Block err = json.Unmarshal(buffer, &h) + if err != nil { logger.With(zap.String("method", "getBlocks")).Error(err) continue } + blocks = append(blocks, &h) case Callout: var c CalloutBlock err = json.Unmarshal(buffer, &c) + if err != nil { logger.With(zap.String("method", "getBlocks")).Error(err) continue } + blocks = append(blocks, &c) case Quote: var q QuoteBlock err = json.Unmarshal(buffer, &q) + if err != nil { logger.With(zap.String("method", "getBlocks")).Error(err) continue } + blocks = append(blocks, &q) case BulletList: var list BulletedListBlock err = json.Unmarshal(buffer, &list) + if err != nil { logger.With(zap.String("method", "getBlocks")).Error(err) continue } + blocks = append(blocks, &list) case NumberList: var nl NumberedListBlock err = json.Unmarshal(buffer, &nl) + if err != nil { logger.With(zap.String("method", "getBlocks")).Error(err) continue } + blocks = append(blocks, &nl) case Toggle: var t ToggleBlock err = json.Unmarshal(buffer, &t) + if err != nil { logger.With(zap.String("method", "getBlocks")).Error(err) continue } + blocks = append(blocks, &t) case Code: var c CodeBlock err = json.Unmarshal(buffer, &c) + if err != nil { logger.With(zap.String("method", "getBlocks")).Error(err) continue } + blocks = append(blocks, &c) case Equation: var e EquationBlock err = json.Unmarshal(buffer, &e) + if err != nil { logger.With(zap.String("method", "getBlocks")).Error(err) continue } + blocks = append(blocks, &e) case ToDo: var t ToDoBlock err = json.Unmarshal(buffer, &t) + if err != nil { logger.With(zap.String("method", "getBlocks")).Error(err) continue } + blocks = append(blocks, &t) case File: var f FileBlock err = json.Unmarshal(buffer, &f) + if err != nil { logger.With(zap.String("method", "getBlocks")).Error(err) continue } + blocks = append(blocks, &f) case Image: var i ImageBlock err = json.Unmarshal(buffer, &i) + if err != nil { logger.With(zap.String("method", "getBlocks")).Error(err) continue } + blocks = append(blocks, &i) case Video: var v VideoBlock err = json.Unmarshal(buffer, &v) + if err != nil { logger.With(zap.String("method", "getBlocks")).Error(err) continue } + blocks = append(blocks, &v) case Pdf: var p PdfBlock err = json.Unmarshal(buffer, &p) + if err != nil { logger.With(zap.String("method", "getBlocks")).Error(err) continue } + blocks = append(blocks, &p) + case Bookmark: + var b BookmarkBlock + err = json.Unmarshal(buffer, &b) + + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + continue + } + + blocks = append(blocks, &b) case Divider: var d DividerBlock err = json.Unmarshal(buffer, &d) + if err != nil { logger.With(zap.String("method", "getBlocks")).Error(err) continue } + blocks = append(blocks, &d) case TableOfContents: var t TableOfContentsBlock err = json.Unmarshal(buffer, &t) + if err != nil { logger.With(zap.String("method", "getBlocks")).Error(err) continue } + blocks = append(blocks, &t) case Embed: var e EmbedBlock diff --git a/core/block/import/notion/api/database/database.go b/core/block/import/notion/api/database/database.go index f8e6d5393..466a9c5a7 100644 --- a/core/block/import/notion/api/database/database.go +++ b/core/block/import/notion/api/database/database.go @@ -9,6 +9,7 @@ import ( "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + "github.com/anytypeio/go-anytype-middleware/core/block/process" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock" @@ -50,23 +51,29 @@ func (p *Database) GetObjectType() string { } // GetDatabase makes snaphots from notion Database objects -func (ds *Service) GetDatabase(ctx context.Context, mode pb.RpcObjectImportRequestMode, databases []Database) (*converter.Response, map[string]string, map[string]string) { - convereterError := converter.ConvertError{} - return ds.mapDatabasesToSnaphots(ctx, mode, databases, convereterError) -} - -func (ds *Service) mapDatabasesToSnaphots(ctx context.Context, mode pb.RpcObjectImportRequestMode, databases []Database, convereterError converter.ConvertError) (*converter.Response, map[string]string, map[string]string) { +func (ds *Service) GetDatabase(ctx context.Context, + mode pb.RpcObjectImportRequestMode, + databases []Database, + progress *process.Progress) (*converter.Response, map[string]string, map[string]string, converter.ConvertError) { var ( allSnapshots = make([]*converter.Snapshot, 0) notionIdsToAnytype = make(map[string]string, 0) databaseNameToID = make(map[string]string, 0) + convereterError = converter.ConvertError{} ) + + progress.SetProgressMessage("Start creating pages from notion databases") for _, d := range databases { + if err := progress.TryStep(1); err != nil { + ce := converter.NewFromError(d.ID, err) + return nil, nil, nil, ce + } + tid, err := threads.ThreadCreateID(thread.AccessControlled, smartblock.SmartBlockTypePage) if err != nil { convereterError.Add(d.ID, err) if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return &converter.Response{Error: convereterError}, nil, nil + return nil, nil, nil, convereterError } else { continue } @@ -82,9 +89,10 @@ func (ds *Service) mapDatabasesToSnaphots(ctx context.Context, mode pb.RpcObject databaseNameToID[d.ID] = pbtypes.GetString(snapshot.Details, bundle.RelationKeyName.String()) } if convereterError.IsEmpty() { - return &converter.Response{Snapshots: allSnapshots, Error: nil}, notionIdsToAnytype, databaseNameToID + return &converter.Response{Snapshots: allSnapshots}, notionIdsToAnytype, databaseNameToID, nil } - return &converter.Response{Snapshots: allSnapshots, Error: convereterError}, notionIdsToAnytype, databaseNameToID + + return &converter.Response{Snapshots: allSnapshots}, notionIdsToAnytype, databaseNameToID, convereterError } func (ds *Service) transformDatabase(d Database) *model.SmartBlockSnapshotBase { diff --git a/core/block/import/notion/api/page/page.go b/core/block/import/notion/api/page/page.go index 7010836dd..d0a423918 100644 --- a/core/block/import/notion/api/page/page.go +++ b/core/block/import/notion/api/page/page.go @@ -11,6 +11,7 @@ import ( "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/block" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/property" + "github.com/anytypeio/go-anytype-middleware/core/block/process" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock" @@ -65,31 +66,35 @@ func (ds *Service) GetPages(ctx context.Context, apiKey string, mode pb.RpcObjectImportRequestMode, pages []Page, - request *block.MapRequest) (*converter.Response, map[string]string) { - convereterError := converter.ConvertError{} - return ds.mapPagesToSnaphots(ctx, apiKey, mode, pages, convereterError, request) -} + request *block.MapRequest, + progress *process.Progress) (*converter.Response, map[string]string, converter.ConvertError) { + var ( + allSnapshots = make([]*converter.Snapshot, 0) + convereterError converter.ConvertError + notionPagesIdsToAnytype = make(map[string]string, 0) + ) + + progress.SetProgressMessage("Start creating pages from notion") -func (ds *Service) mapPagesToSnaphots(ctx context.Context, - apiKey string, - mode pb.RpcObjectImportRequestMode, - pages []Page, - convereterError converter.ConvertError, - request *block.MapRequest) (*converter.Response, map[string]string) { - var allSnapshots = make([]*converter.Snapshot, 0) - var notionPagesIdsToAnytype = make(map[string]string, 0) for _, p := range pages { + if err := progress.TryStep(1); err != nil { + ce := converter.NewFromError(p.ID, err) + return nil, nil, ce + } + tid, err := threads.ThreadCreateID(thread.AccessControlled, smartblock.SmartBlockTypePage) if err != nil { convereterError.Add(p.ID, err) if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return &converter.Response{Error: convereterError}, nil + return nil, nil, convereterError } else { continue } } notionPagesIdsToAnytype[p.ID] = tid.String() } + + progress.SetProgressMessage("Start creating blocks") relationsToPageID := make(map[string][]*converter.Relation) // Need to collect pages title and notion ids mapping for such blocks as ChildPage and ChildDatabase, // because we only get title in those blocks from API @@ -106,11 +111,15 @@ func (ds *Service) mapPagesToSnaphots(ctx context.Context, request.NotionPageIdsToAnytype = notionPagesIdsToAnytype request.PageNameToID = pageNameToID for _, p := range pages { + if err := progress.TryStep(1); err != nil { + ce := converter.NewFromError(p.ID, err) + return nil, nil, ce + } snapshot, relations, ce := ds.transformPages(ctx, apiKey, p, mode, request) if ce != nil { - convereterError.Merge(*ce) + convereterError.Merge(ce) if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return &converter.Response{Error: convereterError}, nil + return nil, nil, convereterError } else { continue } @@ -124,16 +133,17 @@ func (ds *Service) mapPagesToSnaphots(ctx context.Context, relationsToPageID[pageID] = relations } if convereterError.IsEmpty() { - return &converter.Response{Snapshots: allSnapshots, Relations: relationsToPageID, Error: nil}, notionPagesIdsToAnytype + return &converter.Response{Snapshots: allSnapshots, Relations: relationsToPageID}, notionPagesIdsToAnytype, nil } - return &converter.Response{Snapshots: allSnapshots, Relations: relationsToPageID, Error: convereterError}, notionPagesIdsToAnytype + + return &converter.Response{Snapshots: allSnapshots}, notionPagesIdsToAnytype, convereterError } func (ds *Service) transformPages(ctx context.Context, apiKey string, p Page, mode pb.RpcObjectImportRequestMode, - request *block.MapRequest) (*model.SmartBlockSnapshotBase, []*converter.Relation, *converter.ConvertError) { + request *block.MapRequest) (*model.SmartBlockSnapshotBase, []*converter.Relation, converter.ConvertError) { details := make(map[string]*types.Value, 0) details[bundle.RelationKeySource.String()] = pbtypes.String(p.URL) if p.Icon != nil && p.Icon.Emoji != nil { @@ -142,15 +152,12 @@ func (ds *Service) transformPages(ctx context.Context, details[bundle.RelationKeyIsArchived.String()] = pbtypes.Bool(p.Archived) details[bundle.RelationKeyIsFavorite.String()] = pbtypes.Bool(true) - var ( - allErrors = &converter.ConvertError{} - relations []*converter.Relation - ) - relations = ds.handlePageProperties(apiKey, p.ID, p.Properties, details, request.NotionPageIdsToAnytype, request.NotionDatabaseIdsToAnytype) + allErrors := converter.ConvertError{} + relations := ds.handlePageProperties(apiKey, p.ID, p.Properties, details, request.NotionPageIdsToAnytype, request.NotionDatabaseIdsToAnytype) notionBlocks, blocksAndChildrenErr := ds.blockService.GetBlocksAndChildren(ctx, p.ID, apiKey, pageSize, mode) if blocksAndChildrenErr != nil { - allErrors.Merge(*blocksAndChildrenErr) + allErrors.Merge(blocksAndChildrenErr) if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { return nil, nil, allErrors } diff --git a/core/block/import/notion/api/search/search_test.go b/core/block/import/notion/api/search/search_test.go index 85bc07713..0dabcdae0 100644 --- a/core/block/import/notion/api/search/search_test.go +++ b/core/block/import/notion/api/search/search_test.go @@ -10,14 +10,14 @@ import ( "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/database" - // "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/page" + "github.com/anytypeio/go-anytype-middleware/core/block/process" "github.com/anytypeio/go-anytype-middleware/pb" ) func Test_GetDatabaseSuccess(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(`{"object":"list","results":[{"object":"database","id":"072a11cb-684f-4f2b-9490-79592700c67e","cover":{"type":"external","external":{"url":"https://www.notion.so/images/page-cover/webb1.jpg"}},"icon":{"type":"emoji","emoji":"👜"},"created_time":"2022-10-25T11:44:00.000Z","created_by":{"object":"user","id":"60faafc6-0c5c-4479-a3f7-67d77cd8a56d"},"last_edited_by":{"object":"user","id":"60faafc6-0c5c-4479-a3f7-67d77cd8a56d"},"last_edited_time":"2022-10-31T10:16:00.000Z","title":[{"type":"text","text":{"content":"fsdfsdf","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"fsdfsdf","href":null}],"description":[{"type":"text","text":{"content":"lkjlkjlkjklj","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":true,"code":false,"color":"default"},"plain_text":"lkjlkjlkjklj","href":null},{"type":"text","text":{"content":" lkhlkjl;lk’ ","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":" lkhlkjl;lk’ ","href":null},{"type":"text","text":{"content":"lkjkn ;oj;lj;lk’;l\\\n","link":null},"annotations":{"bold":true,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"lkjkn ;oj;lj;lk’;l\\\n","href":null},{"type":"text","text":{"content":"nb","link":{"url":"/43b4db4f23b846f99909c783b033fb7d"}},"annotations":{"bold":true,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"nb","href":"/43b4db4f23b846f99909c783b033fb7d"},{"type":"text","text":{"content":". \n","link":null},"annotations":{"bold":true,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":". \n","href":null},{"type":"equation","equation":{"expression":"m;lm;’,"},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"m;lm;’,","href":null}],"is_inline":true,"properties":{"Select":{"id":"C%5E%7DO","name":"Select","type":"select","select":{"options":[{"id":"f56c757b-eb58-4a15-b528-055a0e3e85b4","name":"dddd","color":"red"}]}},"Text":{"id":"LwEA","name":"Text","type":"relation","relation":{"database_id":"48f51ca6-f1e3-40ee-97a5-953c2e5d8dda","type":"single_property","single_property":{}}},"ssss":{"id":"MeQJ","name":"ssss","type":"last_edited_time","last_edited_time":{}},"Date":{"id":"VwL%5B","name":"Date","type":"date","date":{}},"Status":{"id":"VwSP","name":"Status","type":"status","status":{"options":[{"id":"d553e1cf-a835-4608-9740-01335bc43a33","name":"Not started","color":"default"},{"id":"e4927bd2-4580-4e37-9095-eb0af45923bc","name":"In progress","color":"blue"},{"id":"631ae48b-ccbd-47fc-83a0-64388237cb90","name":"Done","color":"green"}],"groups":[{"id":"95be5bb3-f557-4e5f-bf80-bc0ba078a5ad","name":"To-do","color":"gray","option_ids":["d553e1cf-a835-4608-9740-01335bc43a33"]},{"id":"c3e8b669-177f-4f6a-a58b-998020b47992","name":"In progress","color":"blue","option_ids":["e4927bd2-4580-4e37-9095-eb0af45923bc"]},{"id":"fdbcab62-2699-49b6-9002-eb10a89806ad","name":"Complete","color":"green","option_ids":["631ae48b-ccbd-47fc-83a0-64388237cb90"]}]}},"Number":{"id":"WxBc","name":"Number","type":"number","number":{"format":"ruble"}},"Last edited time":{"id":"XDl%3D","name":"Last edited time","type":"last_edited_time","last_edited_time":{}},"ww":{"id":"Y%3B%3Bz","name":"ww","type":"rich_text","rich_text":{}},"Multi-select":{"id":"%5D%60%3FX","name":"Multi-select","type":"multi_select","multi_select":{"options":[{"id":"EgfK","name":"ddd","color":"default"},{"id":"QO[c","name":"AAA","color":"purple"},{"id":"UsL>","name":"Option","color":"orange"}]}},"ww (1)":{"id":"%60%3C%3DZ","name":"ww (1)","type":"checkbox","checkbox":{}},"Email":{"id":"bQRa","name":"Email","type":"email","email":{}},"Tags":{"id":"gOGx","name":"Tags","type":"multi_select","multi_select":{"options":[{"id":"21e940af-b7a0-4aae-985b-d3bb38a6ebeb","name":"JJJJ","color":"pink"}]}},"Test test":{"id":"nWZg","name":"Test test","type":"people","people":{}},"Checkbox":{"id":"qVHX","name":"Checkbox","type":"checkbox","checkbox":{}},"Status 1":{"id":"tlUB","name":"Status 1","type":"status","status":{"options":[{"id":"bc2cb10d-92da-40d1-b043-d3c5b52c789e","name":"Not started","color":"default"},{"id":"648b1e10-c0ac-4886-84e0-42d501d36e45","name":"In progress","color":"blue"},{"id":"6f1e3ce8-97db-40b5-8538-13269de69b7f","name":"Done","color":"green"}],"groups":[{"id":"cd0c5f4a-de4d-4662-a2ee-1c78fc0385cd","name":"To-do","color":"gray","option_ids":["bc2cb10d-92da-40d1-b043-d3c5b52c789e"]},{"id":"a341ea69-3102-4d56-b74a-fa3f1c47fa85","name":"In progress","color":"blue","option_ids":["648b1e10-c0ac-4886-84e0-42d501d36e45"]},{"id":"061c2c1f-faa2-49be-996e-f52d74a5b86e","name":"Complete","color":"green","option_ids":["6f1e3ce8-97db-40b5-8538-13269de69b7f"]}]}},"Formula":{"id":"%7Do%40%7B","name":"Formula","type":"formula","formula":{"expression":"log2(prop(\"Number\"))"}},"Name":{"id":"title","name":"Name","type":"title","title":{}}},"parent":{"type":"page_id","page_id":"d6917e78-3212-444d-ae46-97499c021f2d"},"url":"https://www.notion.so/072a11cb684f4f2b949079592700c67e","archived":false}],"next_cursor":null,"has_more":false,"type":"page_or_database","page_or_database":{}}`)) - })) + w.Write([]byte(`{"object":"list","results":[{"object":"database","id":"072a11cb-684f-4f2b-9490-79592700c67e","cover":{"type":"external","external":{"url":"https://www.notion.so/images/page-cover/webb1.jpg"}},"icon":{"type":"emoji","emoji":"👜"},"created_time":"2022-10-25T11:44:00.000Z","created_by":{"object":"user","id":"60faafc6-0c5c-4479-a3f7-67d77cd8a56d"},"last_edited_by":{"object":"user","id":"60faafc6-0c5c-4479-a3f7-67d77cd8a56d"},"last_edited_time":"2022-10-31T10:16:00.000Z","title":[{"type":"text","text":{"content":"fsdfsdf","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"fsdfsdf","href":null}],"description":[{"type":"text","text":{"content":"lkjlkjlkjklj","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":true,"code":false,"color":"default"},"plain_text":"lkjlkjlkjklj","href":null},{"type":"text","text":{"content":" lkhlkjl;lk’ ","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":" lkhlkjl;lk’ ","href":null},{"type":"text","text":{"content":"lkjkn ;oj;lj;lk’;l\\\n","link":null},"annotations":{"bold":true,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"lkjkn ;oj;lj;lk’;l\\\n","href":null},{"type":"text","text":{"content":"nb","link":{"url":"/43b4db4f23b846f99909c783b033fb7d"}},"annotations":{"bold":true,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"nb","href":"/43b4db4f23b846f99909c783b033fb7d"},{"type":"text","text":{"content":". \n","link":null},"annotations":{"bold":true,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":". \n","href":null},{"type":"equation","equation":{"expression":"m;lm;’,"},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"m;lm;’,","href":null}],"is_inline":true,"properties":{"Select":{"id":"C%5E%7DO","name":"Select","type":"select","select":{"options":[{"id":"f56c757b-eb58-4a15-b528-055a0e3e85b4","name":"dddd","color":"red"}]}},"Text":{"id":"LwEA","name":"Text","type":"relation","relation":{"database_id":"48f51ca6-f1e3-40ee-97a5-953c2e5d8dda","type":"single_property","single_property":{}}},"ssss":{"id":"MeQJ","name":"ssss","type":"last_edited_time","last_edited_time":{}},"Date":{"id":"VwL%5B","name":"Date","type":"date","date":{}},"Status":{"id":"VwSP","name":"Status","type":"status","status":{"options":[{"id":"d553e1cf-a835-4608-9740-01335bc43a33","name":"Not started","color":"default"},{"id":"e4927bd2-4580-4e37-9095-eb0af45923bc","name":"In progress","color":"blue"},{"id":"631ae48b-ccbd-47fc-83a0-64388237cb90","name":"Done","color":"green"}],"groups":[{"id":"95be5bb3-f557-4e5f-bf80-bc0ba078a5ad","name":"To-do","color":"gray","option_ids":["d553e1cf-a835-4608-9740-01335bc43a33"]},{"id":"c3e8b669-177f-4f6a-a58b-998020b47992","name":"In progress","color":"blue","option_ids":["e4927bd2-4580-4e37-9095-eb0af45923bc"]},{"id":"fdbcab62-2699-49b6-9002-eb10a89806ad","name":"Complete","color":"green","option_ids":["631ae48b-ccbd-47fc-83a0-64388237cb90"]}]}},"Number":{"id":"WxBc","name":"Number","type":"number","number":{"format":"ruble"}},"Last edited time":{"id":"XDl%3D","name":"Last edited time","type":"last_edited_time","last_edited_time":{}},"ww":{"id":"Y%3B%3Bz","name":"ww","type":"rich_text","rich_text":{}},"Multi-select":{"id":"%5D%60%3FX","name":"Multi-select","type":"multi_select","multi_select":{"options":[{"id":"EgfK","name":"ddd","color":"default"},{"id":"QO[c","name":"AAA","color":"purple"},{"id":"UsL>","name":"Option","color":"orange"}]}},"ww (1)":{"id":"%60%3C%3DZ","name":"ww (1)","type":"checkbox","checkbox":{}},"Email":{"id":"bQRa","name":"Email","type":"email","email":{}},"Tags":{"id":"gOGx","name":"Tags","type":"multi_select","multi_select":{"options":[{"id":"21e940af-b7a0-4aae-985b-d3bb38a6ebeb","name":"JJJJ","color":"pink"}]}},"Test test":{"id":"nWZg","name":"Test test","type":"people","people":{}},"Checkbox":{"id":"qVHX","name":"Checkbox","type":"checkbox","checkbox":{}},"Status 1":{"id":"tlUB","name":"Status 1","type":"status","status":{"options":[{"id":"bc2cb10d-92da-40d1-b043-d3c5b52c789e","name":"Not started","color":"default"},{"id":"648b1e10-c0ac-4886-84e0-42d501d36e45","name":"In progress","color":"blue"},{"id":"6f1e3ce8-97db-40b5-8538-13269de69b7f","name":"Done","color":"green"}],"groups":[{"id":"cd0c5f4a-de4d-4662-a2ee-1c78fc0385cd","name":"To-do","color":"gray","option_ids":["bc2cb10d-92da-40d1-b043-d3c5b52c789e"]},{"id":"a341ea69-3102-4d56-b74a-fa3f1c47fa85","name":"In progress","color":"blue","option_ids":["648b1e10-c0ac-4886-84e0-42d501d36e45"]},{"id":"061c2c1f-faa2-49be-996e-f52d74a5b86e","name":"Complete","color":"green","option_ids":["6f1e3ce8-97db-40b5-8538-13269de69b7f"]}]}},"Formula":{"id":"%7Do%40%7B","name":"Formula","type":"formula","formula":{"expression":"log2(prop(\"Number\"))"}},"Name":{"id":"title","name":"Name","type":"title","title":{}}},"parent":{"type":"page_id","page_id":"d6917e78-3212-444d-ae46-97499c021f2d"},"url":"https://www.notion.so/072a11cb684f4f2b949079592700c67e","archived":false}],"next_cursor":null,"has_more":false,"type":"page_or_database","page_or_database":{}}`)) + })) defer s.Close() pageSize := int64(100) @@ -31,16 +31,16 @@ func Test_GetDatabaseSuccess(t *testing.T) { assert.Nil(t, err) ds := database.New() - databases, _, _ := ds.GetDatabase(context.Background(), pb.RpcObjectImportRequest_ALL_OR_NOTHING, db) + databases, _, _, ce := ds.GetDatabase(context.Background(), pb.RpcObjectImportRequest_ALL_OR_NOTHING, db, process.NewProgress(pb.ModelProcess_Import)) assert.NotNil(t, databases) assert.Len(t, databases.Snapshots, 1) - assert.Nil(t, databases.Error) + assert.Nil(t, ce) } func Test_GetPagesSuccess(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(` + w.Write([]byte(` { "object": "list", "results": [ @@ -310,7 +310,7 @@ func Test_GetPagesSuccess(t *testing.T) { "page_or_database": {} } `)) - })) + })) defer s.Close() pageSize := int64(100) @@ -324,13 +324,12 @@ func Test_GetPagesSuccess(t *testing.T) { assert.Nil(t, err) } - func Test_SearcheFailedRequest(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusBadRequest) - w.Write([]byte(`{"object":"error","status":400,"code":"validation_error","message":"path failed validation: path.database_id should be a valid uuid"}`)) + w.Write([]byte(`{"object":"error","status":400,"code":"validation_error","message":"path failed validation: path.database_id should be a valid uuid"}`)) })) - defer s.Close() + defer s.Close() pageSize := int64(100) c := client.NewClient() c.BasePath = s.URL diff --git a/core/block/import/notion/converter.go b/core/block/import/notion/converter.go index d7888524c..cc8500008 100644 --- a/core/block/import/notion/converter.go +++ b/core/block/import/notion/converter.go @@ -11,15 +11,18 @@ import ( "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/database" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/page" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/search" + "github.com/anytypeio/go-anytype-middleware/core/block/process" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core" ) const ( - name = "Notion" - pageSize = 100 - retryDelay = time.Second - retryAmount = 5 + name = "Notion" + pageSize = 100 + retryDelay = time.Second + retryAmount = 5 + numberOfStepsForPages = 3 // 2 cycles to get snapshots and 1 cycle to create objects + numberOfStepsForDatabases = 2 // 1 cycles to get snapshots and 1 cycle to create objects ) func init() { @@ -41,41 +44,36 @@ func New(core.Service) converter.Converter { } } -func (n *Notion) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Response { +func (n *Notion) GetSnapshots(req *pb.RpcObjectImportRequest, progress *process.Progress) (*converter.Response, converter.ConvertError) { ce := converter.NewError() apiKey := n.getParams(req) if apiKey == "" { ce.Add("apiKey", fmt.Errorf("failed to extract apikey")) - return &converter.Response{ - Error: ce, - } + return nil, ce } databases, pages, err := search.Retry(n.search.Search, retryAmount, retryDelay)(context.TODO(), apiKey, pageSize) if err != nil { ce.Add("/search", fmt.Errorf("failed to get pages and databases %s", err)) - return &converter.Response{ - Error: ce, - } + return nil, ce } - databasesSnapshots, notionIdsToAnytype, databaseNameToID := n.databaseService.GetDatabase(context.TODO(), req.Mode, databases) - if databasesSnapshots.Error != nil && req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - ce.Merge(databasesSnapshots.Error) - return &converter.Response{ - Error: ce, - } + + progress.SetTotal(int64(len(databases)*numberOfStepsForDatabases + len(pages)*numberOfStepsForPages)) + databasesSnapshots, notionIdsToAnytype, databaseNameToID, dbErr := n.databaseService.GetDatabase(context.TODO(), req.Mode, databases, progress) + + if dbErr != nil && req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + ce.Merge(dbErr) + return nil, ce } request := &block.MapRequest{ NotionDatabaseIdsToAnytype: notionIdsToAnytype, DatabaseNameToID: databaseNameToID, } - pagesSnapshots, notionPageIdsToAnytype := n.pageService.GetPages(context.TODO(), apiKey, req.Mode, pages, request) - if pagesSnapshots.Error != nil && req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - ce.Merge(pagesSnapshots.Error) - return &converter.Response{ - Error: ce, - } + pagesSnapshots, notionPageIdsToAnytype, pageErr := n.pageService.GetPages(context.TODO(), apiKey, req.Mode, pages, request, progress) + if pageErr != nil && req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + ce.Merge(pageErr) + return nil, ce } page.SetPageLinksInDatabase(databasesSnapshots, pages, databases, notionPageIdsToAnytype, notionIdsToAnytype) @@ -84,24 +82,19 @@ func (n *Notion) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Respons allSnaphots = append(allSnaphots, pagesSnapshots.Snapshots...) allSnaphots = append(allSnaphots, databasesSnapshots.Snapshots...) relations := mergeMaps(databasesSnapshots.Relations, pagesSnapshots.Relations) - if pagesSnapshots.Error != nil { - ce.Merge(pagesSnapshots.Error) + + if pageErr != nil { + ce.Merge(pageErr) } - if databasesSnapshots.Error != nil { - ce.Merge(databasesSnapshots.Error) + + if dbErr != nil { + ce.Merge(dbErr) } if !ce.IsEmpty() { - return &converter.Response{ - Snapshots: allSnaphots, - Relations: relations, - Error: ce, - } - } - return &converter.Response{ - Snapshots: allSnaphots, - Relations: relations, - Error: nil, + return &converter.Response{Snapshots: allSnaphots, Relations: relations}, ce } + + return &converter.Response{Snapshots: allSnaphots, Relations: relations}, nil } func (n *Notion) getParams(param *pb.RpcObjectImportRequest) string { diff --git a/core/block/import/pb/converter.go b/core/block/import/pb/converter.go index fb3bfb2b5..e4556eafd 100644 --- a/core/block/import/pb/converter.go +++ b/core/block/import/pb/converter.go @@ -12,6 +12,7 @@ import ( "github.com/textileio/go-threads/core/thread" "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" + "github.com/anytypeio/go-anytype-middleware/core/block/process" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core" @@ -33,21 +34,29 @@ func New(core.Service) converter.Converter { return new(Pb) } -func (p *Pb) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Response { +func (p *Pb) GetSnapshots(req *pb.RpcObjectImportRequest, progress *process.Progress) (*converter.Response, converter.ConvertError) { path, e := p.GetParams(req.Params) allErrors := converter.NewError() if e != nil { allErrors.Add(path, e) - return &converter.Response{Error: allErrors} + return nil, allErrors } pbFiles, err := p.readFile(path, req.Mode.String()) if err != nil && req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return &converter.Response{Error: err} + allErrors.Merge(err) + return nil, allErrors } - allErrors.Merge(err) - allSnapshots := make([]*converter.Snapshot, 0) + + progress.SetProgressMessage("Start creating snapshots from files") + progress.SetTotal(int64(len(pbFiles) * 2)) + for name, file := range pbFiles { + if err := progress.TryStep(1); err != nil { + ce := converter.NewFromError(name, err) + return nil, ce + } + id := strings.TrimSuffix(file.Name, filepath.Ext(file.Name)) var ( snapshot *model.SmartBlockSnapshotBase @@ -59,7 +68,7 @@ func (p *Pb) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Response { if errGS != nil { allErrors.Add(file.Name, errGS) if req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return &converter.Response{Error: allErrors} + return nil, allErrors } else { continue } @@ -68,7 +77,7 @@ func (p *Pb) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Response { if err != nil { allErrors.Add(path, e) if req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return &converter.Response{Error: allErrors} + return nil, allErrors } else { continue } @@ -77,7 +86,7 @@ func (p *Pb) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Response { if err != nil { allErrors.Add(path, e) if req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - return &converter.Response{Error: allErrors} + return nil, allErrors } else { continue } @@ -92,10 +101,10 @@ func (p *Pb) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Response { } if allErrors.IsEmpty() { - return &converter.Response{Snapshots: allSnapshots, Error: nil} + return &converter.Response{Snapshots: allSnapshots}, nil } - return &converter.Response{Snapshots: allSnapshots, Error: allErrors} + return &converter.Response{Snapshots: allSnapshots}, allErrors } func (p *Pb) Name() string { diff --git a/core/block/import/pb/converter_test.go b/core/block/import/pb/converter_test.go index e68dd2702..10a45552c 100644 --- a/core/block/import/pb/converter_test.go +++ b/core/block/import/pb/converter_test.go @@ -14,6 +14,7 @@ import ( "github.com/stretchr/testify/assert" + "github.com/anytypeio/go-anytype-middleware/core/block/process" "github.com/anytypeio/go-anytype-middleware/pb" ) @@ -32,14 +33,14 @@ func Test_GetSnapshotsSuccess(t *testing.T) { p := &Pb{} - res := p.GetSnapshots(&pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: wr.Path()}}, + res, ce := p.GetSnapshots(&pb.RpcObjectImportRequest{ + Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: wr.Path()}}, UpdateExistingObjects: false, Type: 0, Mode: 0, - }) + }, process.NewProgress(pb.ModelProcess_Import)) - assert.Nil(t, res.Error) + assert.Nil(t, ce) assert.NotNil(t, res.Snapshots) assert.Len(t, res.Snapshots, 1) } @@ -58,14 +59,14 @@ func Test_GetSnapshotsFailedReadZip(t *testing.T) { p := &Pb{} - res := p.GetSnapshots(&pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "not exists"}}, + _, ce := p.GetSnapshots(&pb.RpcObjectImportRequest{ + Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "not exists"}}, UpdateExistingObjects: false, Type: 0, Mode: 0, - }) + }, process.NewProgress(pb.ModelProcess_Import)) - assert.NotNil(t, res.Error) + assert.NotNil(t, ce) } func Test_GetSnapshotsFailedToGetSnapshot(t *testing.T) { @@ -83,16 +84,16 @@ func Test_GetSnapshotsFailedToGetSnapshot(t *testing.T) { p := &Pb{} - res := p.GetSnapshots(&pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "notexist.zip"}}, + _, ce := p.GetSnapshots(&pb.RpcObjectImportRequest{ + Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: "notexist.zip"}}, UpdateExistingObjects: false, Type: 0, Mode: 0, - }) + }, process.NewProgress(pb.ModelProcess_Import)) - assert.NotNil(t, res.Error) - assert.Len(t, res.Error, 1) - assert.NotEmpty(t, res.Error.Get("notexist.zip")) + assert.NotNil(t, ce) + assert.Len(t, ce, 1) + assert.NotEmpty(t, ce.Get("notexist.zip")) } func Test_GetSnapshotsFailedToGetSnapshotForTwoFiles(t *testing.T) { @@ -117,30 +118,30 @@ func Test_GetSnapshotsFailedToGetSnapshotForTwoFiles(t *testing.T) { p := &Pb{} // ALL_OR_NOTHING mode - res := p.GetSnapshots(&pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: wr.Path()}}, + res, ce := p.GetSnapshots(&pb.RpcObjectImportRequest{ + Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: wr.Path()}}, UpdateExistingObjects: false, Type: 0, Mode: 0, - }) + }, process.NewProgress(pb.ModelProcess_Import)) - assert.NotNil(t, res.Error) - assert.Nil(t, res.Snapshots) - assert.NotEmpty(t, res.Error.Get("test.pb")) + assert.NotNil(t, ce) + assert.Nil(t, res) + assert.NotEmpty(t, ce.Get("test.pb")) // IGNORE_ERRORS mode - res = p.GetSnapshots(&pb.RpcObjectImportRequest{ - Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: wr.Path()}}, + res, ce = p.GetSnapshots(&pb.RpcObjectImportRequest{ + Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: wr.Path()}}, UpdateExistingObjects: false, Type: 0, Mode: 1, - }) + }, process.NewProgress(pb.ModelProcess_Import)) - assert.NotNil(t, res.Error) + assert.NotNil(t, ce) assert.NotNil(t, res.Snapshots) assert.Len(t, res.Snapshots, 1) - assert.Len(t, res.Error, 1) - assert.NotEmpty(t, res.Error.Get("test.pb")) + assert.Len(t, ce, 1) + assert.NotEmpty(t, ce.Get("test.pb")) } func newZipWriter(path string) (*zipWriter, error) { diff --git a/core/block/import/syncer/bookmark.go b/core/block/import/syncer/bookmark.go index 9a04d6254..a7ed6cc88 100644 --- a/core/block/import/syncer/bookmark.go +++ b/core/block/import/syncer/bookmark.go @@ -20,7 +20,7 @@ func NewBookmarkSyncer(service block.Service) *BookmarkSyncer { func (bs *BookmarkSyncer) Sync(ctx *session.Context, id string, b simple.Block) error { err := bs.service.BookmarkFetch(ctx, pb.RpcBlockBookmarkFetchRequest{ ContextId: id, - BlockId: b.Model().GetBookmark().TargetObjectId, + BlockId: b.Model().GetId(), Url: b.Model().GetBookmark().Url, }) if err != nil { diff --git a/core/block/import/web/converter.go b/core/block/import/web/converter.go index 7a97e9e17..520a20666 100644 --- a/core/block/import/web/converter.go +++ b/core/block/import/web/converter.go @@ -5,6 +5,7 @@ import ( "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/core/block/import/web/parsers" + "github.com/anytypeio/go-anytype-middleware/core/block/process" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock" "github.com/anytypeio/go-anytype-middleware/pkg/lib/threads" @@ -29,28 +30,36 @@ func (*Converter) GetParser(url string) parsers.Parser { return nil } -func (c *Converter) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Response { +func (c *Converter) GetSnapshots(req *pb.RpcObjectImportRequest, progress *process.Progress) (*converter.Response, converter.ConvertError) { we := converter.NewError() url, err := c.getParams(req.Params) + + progress.SetTotal(1) + if err != nil { we.Add(url, err) - return &converter.Response{Error: we} + return nil, we } p := c.GetParser(url) if p == nil { we.Add(url, fmt.Errorf("unknown url format")) - return &converter.Response{Error: we} + return nil, we } + + progress.SetProgressMessage("Start parsing url to snapshot") snapshots, err := p.ParseUrl(url) + + progress.AddDone(1) + if err != nil { we.Add(url, err) - return &converter.Response{Error: we} + return nil, we } tid, err := threads.ThreadCreateID(thread.AccessControlled, smartblock.SmartBlockTypePage) if err != nil { we.Add(url, err) - return &converter.Response{Error: we} + return nil, we } s := &converter.Snapshot{ Id: tid.String(), @@ -58,10 +67,10 @@ func (c *Converter) GetSnapshots(req *pb.RpcObjectImportRequest) *converter.Resp Snapshot: snapshots, } res := &converter.Response{ - Snapshots: []*converter.Snapshot{s}, - Error: nil, + Snapshots: []*converter.Snapshot{s}, } - return res + + return res, nil } func (p *Converter) Name() string { @@ -73,4 +82,4 @@ func (p *Converter) getParams(params pb.IsRpcObjectImportRequestParams) (string, return p.BookmarksParams.GetUrl(), nil } return "", fmt.Errorf("PB: GetParams wrong parameters format") -} \ No newline at end of file +} diff --git a/core/block/process/progress.go b/core/block/process/progress.go index 24b214d7e..9daa2515d 100644 --- a/core/block/process/progress.go +++ b/core/block/process/progress.go @@ -1,6 +1,7 @@ package process import ( + "fmt" "sync" "sync/atomic" @@ -106,3 +107,15 @@ func (p *Progress) Info() pb.ModelProcess { func (p *Progress) Done() chan struct{} { return p.done } + +func (p *Progress) TryStep(delta int64) error { + select { + case <-p.Canceled(): + return fmt.Errorf("cancelled import") + default: + } + + p.AddDone(delta) + + return nil +} From 9ffc68696d6681914e3b54de0db02cb3c77477f6 Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Mon, 12 Dec 2022 22:31:04 +0300 Subject: [PATCH 17/68] PROD-344: fix conflicts Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/relationcreator.go | 4 ++-- core/block/import/syncer/icon.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/block/import/relationcreator.go b/core/block/import/relationcreator.go index b4749bc5b..2dab3b828 100644 --- a/core/block/import/relationcreator.go +++ b/core/block/import/relationcreator.go @@ -17,11 +17,11 @@ import ( ) type RelationService struct { - service block.Service + service *block.Service } // NewRelationCreator constructor for RelationService -func NewRelationCreator(service block.Service) RelationCreator { +func NewRelationCreator(service *block.Service) RelationCreator { return &RelationService{ service: service, } diff --git a/core/block/import/syncer/icon.go b/core/block/import/syncer/icon.go index 315066246..1c8fdbc06 100644 --- a/core/block/import/syncer/icon.go +++ b/core/block/import/syncer/icon.go @@ -14,10 +14,10 @@ import ( ) type IconSyncer struct { - service block.Service + service *block.Service } -func NewIconSyncer(service block.Service) *IconSyncer { +func NewIconSyncer(service *block.Service) *IconSyncer { return &IconSyncer{service: service} } From 971488b26134e2591c0f18b67bbe7e9dd3a24a16 Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Mon, 12 Dec 2022 23:13:25 +0300 Subject: [PATCH 18/68] PROD-344: integrate with object types Signed-off-by: AnastasiaShemyakinskaya --- .golangci.yml | 5 ----- core/block/import/importer.go | 2 +- core/block/import/notion/api/client/client.go | 10 +++++----- core/block/import/notion/api/commonobjects.go | 3 ++- .../import/notion/api/property/propertyitem.go | 1 - core/block/import/objectcreator.go | 6 +++--- core/block/import/relationcreator.go | 14 ++++++++++---- core/block/import/syncer/file.go | 2 +- core/block/import/syncer/icon.go | 2 +- core/block/import/syncer/syncer.go | 2 +- core/object.go | 2 +- 11 files changed, 25 insertions(+), 24 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 818781af4..6f336fde9 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -10,11 +10,6 @@ un: go: '1.18' linters-settings: - lll: - line-length: 150 - funlen: - lines: 100 - statements: 50 errcheck: check-blank: true errchkjson: diff --git a/core/block/import/importer.go b/core/block/import/importer.go index 5bb1d2880..0ff0517d9 100644 --- a/core/block/import/importer.go +++ b/core/block/import/importer.go @@ -44,7 +44,7 @@ func (i *Import) Init(a *app.App) (err error) { } factory := syncer.New(syncer.NewFileSyncer(i.s), syncer.NewBookmarkSyncer(i.s), syncer.NewIconSyncer(i.s)) ou := NewObjectUpdater(i.s, core, factory) - relationCreator := NewRelationCreator(i.s) + relationCreator := NewRelationCreator(i.s, core) i.oc = NewCreator(i.s, core, ou, factory, relationCreator) return nil } diff --git a/core/block/import/notion/api/client/client.go b/core/block/import/notion/api/client/client.go index 5f7727770..00d5065bf 100644 --- a/core/block/import/notion/api/client/client.go +++ b/core/block/import/notion/api/client/client.go @@ -9,20 +9,20 @@ import ( ) const ( - notionUrl = "https://api.notion.com/v1" - apiVersion = "2022-06-28" + notionUrl = "https://api.notion.com/v1" + apiVersion = "2022-06-28" ) type Client struct { HttpClient *http.Client - BasePath string + BasePath string } // NewClient is a constructor for Client func NewClient() *Client { c := &Client{ - HttpClient:&http.Client{Timeout: time.Minute}, - BasePath: notionUrl, + HttpClient: &http.Client{Timeout: time.Minute}, + BasePath: notionUrl, } return c } diff --git a/core/block/import/notion/api/commonobjects.go b/core/block/import/notion/api/commonobjects.go index 8607fe788..baeedec69 100644 --- a/core/block/import/notion/api/commonobjects.go +++ b/core/block/import/notion/api/commonobjects.go @@ -5,8 +5,9 @@ import ( "strings" "time" - "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" "github.com/globalsign/mgo/bson" + + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" ) type richTextType string diff --git a/core/block/import/notion/api/property/propertyitem.go b/core/block/import/notion/api/property/propertyitem.go index 52c93eac8..62b492940 100644 --- a/core/block/import/notion/api/property/propertyitem.go +++ b/core/block/import/notion/api/property/propertyitem.go @@ -191,7 +191,6 @@ func (ms *MultiSelectItem) GetFormat() model.RelationFormat { return model.RelationFormat_tag } -//can't support it yet type DateItem struct { Object string `json:"object"` ID string `json:"id"` diff --git a/core/block/import/objectcreator.go b/core/block/import/objectcreator.go index 1cade7eff..2c709115d 100644 --- a/core/block/import/objectcreator.go +++ b/core/block/import/objectcreator.go @@ -25,9 +25,9 @@ import ( ) type ObjectCreator struct { - service *block.Service - core core.Service - updater Updater + service *block.Service + core core.Service + updater Updater relationCreator RelationCreator syncFactory *syncer.Factory } diff --git a/core/block/import/relationcreator.go b/core/block/import/relationcreator.go index 2dab3b828..184e84178 100644 --- a/core/block/import/relationcreator.go +++ b/core/block/import/relationcreator.go @@ -12,18 +12,21 @@ import ( "github.com/anytypeio/go-anytype-middleware/core/session" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/core" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" "github.com/anytypeio/go-anytype-middleware/util/pbtypes" ) type RelationService struct { + core core.Service service *block.Service } // NewRelationCreator constructor for RelationService -func NewRelationCreator(service *block.Service) RelationCreator { +func NewRelationCreator(service *block.Service, core core.Service) RelationCreator { return &RelationService{ service: service, + core: core, } } @@ -46,9 +49,12 @@ func (rc *RelationService) Create(ctx *session.Context, Fields: map[string]*types.Value{ bundle.RelationKeyName.String(): pbtypes.String(r.Name), bundle.RelationKeyRelationFormat.String(): pbtypes.Int64(int64(r.Format)), + bundle.RelationKeyType.String(): pbtypes.String(bundle.TypeKeyRelation.URL()), + bundle.RelationKeyLayout.String(): pbtypes.Float64(float64(model.ObjectType_relation)), }, } - if _, object, err = rc.service.CreateRelation(detail); err != nil && err != editor.ErrSubObjectAlreadyExists { + + if _, object, err = rc.service.CreateSubObjectInWorkspace(detail, rc.core.PredefinedBlocks().Account); err != nil && err != editor.ErrSubObjectAlreadyExists { log.Errorf("create relation %s", err) continue } @@ -104,14 +110,14 @@ func (rc *RelationService) handleListValue(ctx *session.Context, snapshot *model ) for _, v := range snapshot.Details.Fields[r.Name].GetListValue().Values { if r.Format == model.RelationFormat_tag || r.Format == model.RelationFormat_status { - if id, _, err = rc.service.CreateRelationOption(&types.Struct{ + if id, _, err = rc.service.CreateSubObjectInWorkspace(&types.Struct{ Fields: map[string]*types.Value{ bundle.RelationKeyName.String(): pbtypes.String(v.GetStringValue()), bundle.RelationKeyRelationKey.String(): pbtypes.String(relationID), bundle.RelationKeyType.String(): pbtypes.String(bundle.TypeKeyRelationOption.URL()), bundle.RelationKeyLayout.String(): pbtypes.Float64(float64(model.ObjectType_relationOption)), }, - }); err != nil { + }, rc.core.PredefinedBlocks().Account); err != nil { log.Errorf("add extra relation %s", err) } } else { diff --git a/core/block/import/syncer/file.go b/core/block/import/syncer/file.go index c5ff8141f..4efd29d5f 100644 --- a/core/block/import/syncer/file.go +++ b/core/block/import/syncer/file.go @@ -27,7 +27,7 @@ func (fs *FileSyncer) Sync(ctx *session.Context, id string, b simple.Block) erro if strings.HasPrefix(b.Model().GetFile().Name, "http://") || strings.HasPrefix(b.Model().GetFile().Name, "https://") { params = pb.RpcBlockUploadRequest{ Url: b.Model().GetFile().Name, - BlockId: b.Model().Id, + BlockId: b.Model().Id, } } hash, err := fs.service.UploadFileBlockWithHash(ctx, id, params) diff --git a/core/block/import/syncer/icon.go b/core/block/import/syncer/icon.go index 1c8fdbc06..4ec4235f2 100644 --- a/core/block/import/syncer/icon.go +++ b/core/block/import/syncer/icon.go @@ -31,7 +31,7 @@ func (is *IconSyncer) Sync(ctx *session.Context, id string, b simple.Block) erro if err != nil { return fmt.Errorf("failed uploading icon image file: %s", err) } - + err = is.service.Do(id, func(sb smartblock.SmartBlock) error { bs := basic.NewBasic(sb) err := bs.Update(ctx, func(simpleBlock simple.Block) error { diff --git a/core/block/import/syncer/syncer.go b/core/block/import/syncer/syncer.go index a800b6b59..6a575f52c 100644 --- a/core/block/import/syncer/syncer.go +++ b/core/block/import/syncer/syncer.go @@ -9,7 +9,7 @@ type Factory struct { } func New(fs *FileSyncer, bs *BookmarkSyncer, is *IconSyncer) *Factory { - return &Factory{fs:fs, bs: bs, is: is} + return &Factory{fs: fs, bs: bs, is: is} } func (f *Factory) GetSyncer(b simple.Block) Syncer { diff --git a/core/object.go b/core/object.go index b470d1e1d..6ed114127 100644 --- a/core/object.go +++ b/core/object.go @@ -784,7 +784,7 @@ func (mw *Middleware) ObjectSetInternalFlags(cctx context.Context, req *pb.RpcOb } func (mw *Middleware) ObjectImport(cctx context.Context, req *pb.RpcObjectImportRequest) *pb.RpcObjectImportResponse { - ctx := mw.newContext(cctx) + ctx := mw.newContext(cctx) response := func(code pb.RpcObjectImportResponseErrorCode, err error) *pb.RpcObjectImportResponse { m := &pb.RpcObjectImportResponse{Error: &pb.RpcObjectImportResponseError{Code: code}} From 8df4b2e9d3f61b5d206d2ba8b3f8e02c3a6b9869 Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Tue, 13 Dec 2022 13:56:47 +0300 Subject: [PATCH 19/68] PROD-344: fix conflicts Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/notion/api/block/link.go | 16 ++++++++++++++++ core/block/import/notion/api/block/retrieve.go | 2 +- core/block/import/notion/api/block/text.go | 2 +- core/block/import/notion/api/page/page_test.go | 2 +- .../import/notion/api/property/propertyitem.go | 7 ++++--- 5 files changed, 23 insertions(+), 6 deletions(-) diff --git a/core/block/import/notion/api/block/link.go b/core/block/import/notion/api/block/link.go index b13b6963d..f1d61706e 100644 --- a/core/block/import/notion/api/block/link.go +++ b/core/block/import/notion/api/block/link.go @@ -17,6 +17,10 @@ type EmbedBlock struct { Embed LinkToWeb `json:"embed"` } +func (b *EmbedBlock) GetBlocks(req *MapRequest) *MapResponse { + return b.Embed.GetBlocks(req) +} + type LinkToWeb struct { URL string `json:"url"` } @@ -26,6 +30,10 @@ type LinkPreviewBlock struct { LinkPreview LinkToWeb `json:"link_preview"` } +func (b *LinkPreviewBlock) GetBlocks(req *MapRequest) *MapResponse { + return b.LinkPreview.GetBlocks(req) +} + func (b *LinkToWeb) GetBlocks(*MapRequest) *MapResponse { id := bson.NewObjectId().Hex() @@ -161,6 +169,14 @@ type BookmarkBlock struct { Bookmark BookmarkObject `json:"bookmark"` } +func (b *BookmarkBlock) GetBlocks(*MapRequest) *MapResponse { + bl, id := b.Bookmark.GetBookmarkBlock() + return &MapResponse{ + Blocks: []*model.Block{bl}, + BlockIDs: []string{id}, + } +} + type BookmarkObject struct { URL string `json:"url"` Caption []*api.RichText `json:"caption"` diff --git a/core/block/import/notion/api/block/retrieve.go b/core/block/import/notion/api/block/retrieve.go index 6b37bb959..fc3642186 100644 --- a/core/block/import/notion/api/block/retrieve.go +++ b/core/block/import/notion/api/block/retrieve.go @@ -372,7 +372,7 @@ func (s *Service) getBlocks(ctx context.Context, pageID, apiKey string, paginati continue } blocks = append(blocks, &l) - case Unsupported: + case Unsupported, Template, SyncedBlock: var u UnsupportedBlock err = json.Unmarshal(buffer, &u) if err != nil { diff --git a/core/block/import/notion/api/block/text.go b/core/block/import/notion/api/block/text.go index 07c697672..801ffadbd 100644 --- a/core/block/import/notion/api/block/text.go +++ b/core/block/import/notion/api/block/text.go @@ -149,7 +149,7 @@ func (q *QuoteBlock) GetID() string { type NumberedListBlock struct { Block - NumberedList TextObjectWithChildren `json:"bulleted_list_item"` + NumberedList TextObjectWithChildren `json:"numbered_list_item"` } func (n *NumberedListBlock) GetBlocks(req *MapRequest) *MapResponse { diff --git a/core/block/import/notion/api/page/page_test.go b/core/block/import/notion/api/page/page_test.go index 826858b2c..769c83a72 100644 --- a/core/block/import/notion/api/page/page_test.go +++ b/core/block/import/notion/api/page/page_test.go @@ -102,7 +102,7 @@ func Test_handlePagePropertiesNumber(t *testing.T) { details := make(map[string]*types.Value, 0) - num := int64(12) + num := float64(12) p := property.NumberItem{ ID: "id", Type: string(property.PropertyConfigTypeNumber), diff --git a/core/block/import/notion/api/property/propertyitem.go b/core/block/import/notion/api/property/propertyitem.go index 62b492940..4e2169347 100644 --- a/core/block/import/notion/api/property/propertyitem.go +++ b/core/block/import/notion/api/property/propertyitem.go @@ -114,12 +114,12 @@ type NumberItem struct { Object string `json:"object"` ID string `json:"id"` Type string `json:"type"` - Number *int64 `json:"number"` + Number *float64 `json:"number"` } func (np *NumberItem) SetDetail(key string, details map[string]*types.Value) { if np.Number != nil { - details[key] = pbtypes.Int64(*np.Number) + details[key] = pbtypes.Float64(*np.Number) } } @@ -210,6 +210,7 @@ func (dp *DateItem) SetDetail(key string, details map[string]*types.Value) { } date.WriteString(dp.Date.End) } + details[key] = pbtypes.String(date.String()) } } @@ -222,7 +223,7 @@ func (dp *DateItem) GetID() string { } func (dp *DateItem) GetFormat() model.RelationFormat { - return model.RelationFormat_date + return model.RelationFormat_longtext } const ( From 74a8ba59cd1c45ec94158b6b6b8cec220ecda923 Mon Sep 17 00:00:00 2001 From: Anastasia Shemyakinskaya <36507473+AnastasiaShemyakinskaya@users.noreply.github.com> Date: Fri, 16 Dec 2022 11:06:54 +0300 Subject: [PATCH 20/68] GO-477: retrieve tables and columns from notion api (#1638) * GO-475: refactoring Signed-off-by: AnastasiaShemyakinskaya * code improvements Signed-off-by: AnastasiaShemyakinskaya * fix tests Signed-off-by: AnastasiaShemyakinskaya * GO-476: add link blocks Signed-off-by: AnastasiaShemyakinskaya * remove unnessesary code Signed-off-by: AnastasiaShemyakinskaya * GO-478: add child pages and db Signed-off-by: AnastasiaShemyakinskaya * GO-476: fix conflicts Signed-off-by: AnastasiaShemyakinskaya * GO-476: link pages with databases Signed-off-by: AnastasiaShemyakinskaya * GO-476: fix property retrieving Signed-off-by: AnastasiaShemyakinskaya * GO-476: fix Signed-off-by: AnastasiaShemyakinskaya * GO-476: fix linter Signed-off-by: AnastasiaShemyakinskaya * GO-477: add table and column blocks Signed-off-by: AnastasiaShemyakinskaya * GO-476: partially fix comments Signed-off-by: AnastasiaShemyakinskaya * GO-476: fix comments Signed-off-by: AnastasiaShemyakinskaya * GO-476: fix linter Signed-off-by: AnastasiaShemyakinskaya * GO-476: fix comments Signed-off-by: AnastasiaShemyakinskaya * GO-477: fix comments, linter and some bugs Signed-off-by: AnastasiaShemyakinskaya * GO-477: fix makefile Signed-off-by: AnastasiaShemyakinskaya * GO-477: fix test Signed-off-by: AnastasiaShemyakinskaya * GO-477: fix linter Signed-off-by: AnastasiaShemyakinskaya * GO-477: fix conflict Signed-off-by: AnastasiaShemyakinskaya Signed-off-by: AnastasiaShemyakinskaya --- Makefile | 1 + core/block/editor/table/block.go | 2 +- core/block/editor/table/table.go | 20 +- core/block/import/importer.go | 4 +- core/block/import/notion/api/block/columns.go | 51 +++++ .../block/import/notion/api/block/retrieve.go | 32 +++ .../import/notion/api/block/retrieve_test.go | 204 ++++++++++++++++++ core/block/import/notion/api/block/table.go | 185 ++++++++++++++++ .../import/notion/api/block/table_test.go | 92 ++++++++ core/block/import/notion/api/block/text.go | 8 + .../import/notion/api/block/text_test.go | 1 + .../import/notion/api/block/textobject.go | 3 +- core/block/import/notion/api/commonobjects.go | 10 +- .../import/notion/api/database/database.go | 25 +++ core/block/import/notion/api/page/page.go | 18 +- core/block/import/relationcreator.go | 105 ++++++--- 16 files changed, 714 insertions(+), 47 deletions(-) create mode 100644 core/block/import/notion/api/block/columns.go create mode 100644 core/block/import/notion/api/block/table.go create mode 100644 core/block/import/notion/api/block/table_test.go diff --git a/Makefile b/Makefile index ce302f0c5..7394a5938 100644 --- a/Makefile +++ b/Makefile @@ -248,6 +248,7 @@ build-js: setup-go build-server protos-js @echo "Run 'make install-dev-js' instead if you want to build&install into ../js-anytype" install-linter: + @go install github.com/daixiang0/gci@latest @go install github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION) run-linter: diff --git a/core/block/editor/table/block.go b/core/block/editor/table/block.go index 586983cb2..6fad096c0 100644 --- a/core/block/editor/table/block.go +++ b/core/block/editor/table/block.go @@ -129,7 +129,7 @@ func (b *block) Duplicate(s *state.State) (newID string, visitedIds []string, bl visitedIds = append(visitedIds, cellID) cell := s.Pick(cellID) cell = cell.Copy() - cell.Model().Id = makeCellID(row.Model().Id, newColID) + cell.Model().Id = MakeCellID(row.Model().Id, newColID) blocks = append(blocks, cell) row.Model().ChildrenIds[j] = cell.Model().Id diff --git a/core/block/editor/table/table.go b/core/block/editor/table/table.go index 9c70aef7a..d4bd4e2d2 100644 --- a/core/block/editor/table/table.go +++ b/core/block/editor/table/table.go @@ -304,7 +304,7 @@ func (t *Editor) RowDuplicate(s *state.State, req pb.RpcBlockTableRowDuplicateRe } newCell := cell.Copy() - newCell.Model().Id = makeCellID(newRow.Model().Id, colID) + newCell.Model().Id = MakeCellID(newRow.Model().Id, colID) if !s.Add(newCell) { return "", fmt.Errorf("add new cell %s", newCell.Model().Id) } @@ -332,10 +332,10 @@ func (t *Editor) RowListFill(s *state.State, req pb.RpcBlockTableRowListFillRequ return fmt.Errorf("get row %s: %w", rowID, err) } - newIDs := make([]string, 0, len(columns)) + newIds := make([]string, 0, len(columns)) for _, colID := range columns { - id := makeCellID(rowID, colID) - newIDs = append(newIDs, id) + id := MakeCellID(rowID, colID) + newIds = append(newIds, id) if !s.Exists(id) { _, err := addCell(s, rowID, colID) @@ -344,7 +344,7 @@ func (t *Editor) RowListFill(s *state.State, req pb.RpcBlockTableRowListFillRequ } } } - row.Model().ChildrenIds = newIDs + row.Model().ChildrenIds = newIds } return nil } @@ -407,7 +407,7 @@ func (t *Editor) ColumnListFill(s *state.State, req pb.RpcBlockTableColumnListFi for _, colID := range req.BlockIds { for _, rowID := range rows { - id := makeCellID(rowID, colID) + id := MakeCellID(rowID, colID) if s.Exists(id) { continue } @@ -531,7 +531,7 @@ func (t *Editor) cloneColumnStyles(s *state.State, srcColID, targetColID string) } if protoBlock != nil && protoBlock.Model().BackgroundColor != "" { - targetCellID := makeCellID(rowID, targetColID) + targetCellID := MakeCellID(rowID, targetColID) if !s.Exists(targetCellID) { _, err := addCell(s, rowID, targetColID) @@ -613,7 +613,7 @@ func (t *Editor) ColumnDuplicate(s *state.State, req pb.RpcBlockTableColumnDupli return "", fmt.Errorf("cell %s is not found", cellID) } cell = cell.Copy() - cell.Model().Id = makeCellID(rowID, newCol.Model().Id) + cell.Model().Id = MakeCellID(rowID, newCol.Model().Id) if !s.Add(cell) { return "", fmt.Errorf("add cell block") @@ -826,7 +826,7 @@ func pickColumn(s *state.State, id string) (simple.Block, error) { return b, nil } -func makeCellID(rowID, colID string) string { +func MakeCellID(rowID, colID string) string { return fmt.Sprintf("%s-%s", rowID, colID) } @@ -840,7 +840,7 @@ func ParseCellID(id string) (rowID string, colID string, err error) { func addCell(s *state.State, rowID, colID string) (string, error) { c := simple.New(&model.Block{ - Id: makeCellID(rowID, colID), + Id: MakeCellID(rowID, colID), Content: &model.BlockContentOfText{ Text: &model.BlockContentText{}, }, diff --git a/core/block/import/importer.go b/core/block/import/importer.go index 0ff0517d9..d285629b0 100644 --- a/core/block/import/importer.go +++ b/core/block/import/importer.go @@ -16,6 +16,7 @@ import ( "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore/filestore" "github.com/anytypeio/go-anytype-middleware/pkg/lib/logging" ) @@ -44,7 +45,8 @@ func (i *Import) Init(a *app.App) (err error) { } factory := syncer.New(syncer.NewFileSyncer(i.s), syncer.NewBookmarkSyncer(i.s), syncer.NewIconSyncer(i.s)) ou := NewObjectUpdater(i.s, core, factory) - relationCreator := NewRelationCreator(i.s, core) + fs := a.MustComponent(filestore.CName).(filestore.FileStore) + relationCreator := NewRelationCreator(i.s, fs, core) i.oc = NewCreator(i.s, core, ou, factory, relationCreator) return nil } diff --git a/core/block/import/notion/api/block/columns.go b/core/block/import/notion/api/block/columns.go new file mode 100644 index 000000000..6f9d69994 --- /dev/null +++ b/core/block/import/notion/api/block/columns.go @@ -0,0 +1,51 @@ +package block + +type ColumnListBlock struct { + Block + ColumnList interface{} `json:"column_list"` +} + +func (c *ColumnListBlock) GetID() string { + return c.ID +} + +func (c *ColumnListBlock) HasChild() bool { + return c.HasChildren +} + +func (c *ColumnListBlock) SetChildren(children []interface{}) { + c.ColumnList = children +} + +func (c *ColumnListBlock) GetBlocks(req *MapRequest) *MapResponse { + req.Blocks = c.ColumnList.([]interface{}) + resp := MapBlocks(req) + return resp +} + +type ColumnBlock struct { + Block + Column *ColumnObject `json:"column"` +} + +type ColumnObject struct { + Children []interface{} `json:"children"` +} + +func (c *ColumnBlock) GetBlocks(req *MapRequest) *MapResponse { + req.Blocks = c.Column.Children + resp := MapBlocks(req) + return resp +} + +func (c *ColumnBlock) GetID() string { + return c.ID +} + +func (c *ColumnBlock) HasChild() bool { + return c.HasChildren +} + +func (c *ColumnBlock) SetChildren(children []interface{}) { + c.Column.Children = children +} diff --git a/core/block/import/notion/api/block/retrieve.go b/core/block/import/notion/api/block/retrieve.go index fc3642186..300d0816e 100644 --- a/core/block/import/notion/api/block/retrieve.go +++ b/core/block/import/notion/api/block/retrieve.go @@ -380,6 +380,38 @@ func (s *Service) getBlocks(ctx context.Context, pageID, apiKey string, paginati continue } blocks = append(blocks, &u) + case Table: + var t TableBlock + err = json.Unmarshal(buffer, &t) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + continue + } + blocks = append(blocks, &t) + case TableRow: + var t TableRowBlock + err = json.Unmarshal(buffer, &t) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + continue + } + blocks = append(blocks, &t) + case ColumnList: + var cl ColumnListBlock + err = json.Unmarshal(buffer, &cl) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + continue + } + blocks = append(blocks, &cl) + case Column: + var cb ColumnBlock + err = json.Unmarshal(buffer, &cb) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + continue + } + blocks = append(blocks, &cb) } } diff --git a/core/block/import/notion/api/block/retrieve_test.go b/core/block/import/notion/api/block/retrieve_test.go index a2c346632..1f2681c4f 100644 --- a/core/block/import/notion/api/block/retrieve_test.go +++ b/core/block/import/notion/api/block/retrieve_test.go @@ -784,3 +784,207 @@ func Test_GetBlocksAndChildrenSuccessError(t *testing.T) { assert.NotNil(t, err) assert.Empty(t, bl) } + +func TestTableBlocks(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(` + { + "object": "list", + "results": [ + { + "object": "block", + "id": "25377f65-71cf-4779-9829-de3717767148", + "parent": { + "type": "block_id", + "block_id": "049ab49c-17a5-4c03-bdbf-71811b4524b7" + }, + "created_time": "2022-12-09T08:39:00.000Z", + "last_edited_time": "2022-12-09T08:40:00.000Z", + "created_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "last_edited_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "has_children": false, + "archived": false, + "type": "table_row", + "table_row": { + "cells": [ + [ + { + "type": "text", + "text": { + "content": "1", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "1", + "href": null + } + ], + [], + [ + { + "type": "text", + "text": { + "content": "dddd", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "pink" + }, + "plain_text": "dddd", + "href": null + } + ], + [] + ] + } + }, + { + "object": "block", + "id": "f9e3bf51-eb64-45c7-bf68-2776d808e503", + "parent": { + "type": "block_id", + "block_id": "049ab49c-17a5-4c03-bdbf-71811b4524b7" + }, + "created_time": "2022-12-09T08:39:00.000Z", + "last_edited_time": "2022-12-09T08:40:00.000Z", + "created_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "last_edited_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "has_children": false, + "archived": false, + "type": "table_row", + "table_row": { + "cells": [ + [], + [ + { + "type": "text", + "text": { + "content": "fsdf", + "link": null + }, + "annotations": { + "bold": false, + "italic": true, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "fsdf", + "href": null + } + ], + [], + [] + ] + } + }, + { + "object": "block", + "id": "1f68a81c-ba09-4f1a-ae99-a999dee96b07", + "parent": { + "type": "block_id", + "block_id": "049ab49c-17a5-4c03-bdbf-71811b4524b7" + }, + "created_time": "2022-12-09T08:39:00.000Z", + "last_edited_time": "2022-12-09T08:40:00.000Z", + "created_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "last_edited_by": { + "object": "user", + "id": "60faafc6-0c5c-4479-a3f7-67d77cd8a56d" + }, + "has_children": false, + "archived": false, + "type": "table_row", + "table_row": { + "cells": [ + [ + { + "type": "text", + "text": { + "content": "fdsdf", + "link": null + }, + "annotations": { + "bold": true, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "default" + }, + "plain_text": "fdsdf", + "href": null + } + ], + [], + [ + { + "type": "text", + "text": { + "content": "sdf", + "link": null + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false, + "color": "gray_background" + }, + "plain_text": "sdf", + "href": null + } + ], + [] + ] + } + } + ], + "next_cursor": null, + "has_more": false, + "type": "block", + "block": {} + } + `)) + })) + + defer s.Close() + pageSize := int64(100) + c := client.NewClient() + c.BasePath = s.URL + + blockService := New(c) + bl, err := blockService.GetBlocksAndChildren(context.TODO(), "id", "key", pageSize, pb.RpcObjectImportRequest_ALL_OR_NOTHING) + assert.Nil(t, err) + assert.NotNil(t, bl) + assert.Len(t, bl, 3) +} \ No newline at end of file diff --git a/core/block/import/notion/api/block/table.go b/core/block/import/notion/api/block/table.go new file mode 100644 index 000000000..172e17751 --- /dev/null +++ b/core/block/import/notion/api/block/table.go @@ -0,0 +1,185 @@ +package block + +import ( + "github.com/globalsign/mgo/bson" + + "github.com/anytypeio/go-anytype-middleware/core/block/editor/table" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" +) + +// columnLayoutBlock + tableRowLayoutBlock + table +const numberOfDefaultTableBlocks = 3 + +type TableBlock struct { + Block + Table TableObject `json:"table"` +} + +type TableObject struct { + Width int64 `json:"table_width"` + HasColumnHeader bool `json:"has_column_header"` + HasRowHeader bool `json:"has_row_header"` + Children []*TableRowBlock `json:"children"` +} + +type TableRowBlock struct { + Block + TableRowObject TableRowObject `json:"table_row"` +} + +type TableRowObject struct { + Cells [][]api.RichText `json:"cells"` +} + +func (t *TableBlock) GetID() string { + return t.ID +} + +func (t *TableBlock) HasChild() bool { + return t.HasChildren +} + +func (t *TableBlock) SetChildren(children []interface{}) { + t.Table.Children = make([]*TableRowBlock, 0, len(children)) + for _, ch := range children { + t.Table.Children = append(t.Table.Children, ch.(*TableRowBlock)) + } +} + +func (t *TableBlock) GetBlocks(req *MapRequest) *MapResponse { + columnsBlocks, columnsBlocksIDs, columnLayoutBlockID, columnLayoutBlock := t.getColumns() + + tableResponse := &MapResponse{} + tableRowBlocks, tableRowBlocksIDs, rowTextBlocks := t.getRows(req, columnsBlocksIDs, tableResponse) + + tableRowBlockID, tableRowLayoutBlock := t.getLayoutRowBlock(tableRowBlocksIDs) + + rootID, table := t.getTableBlock(columnLayoutBlockID, tableRowBlockID) + + resultNumberOfBlocks := len(columnsBlocks) + len(rowTextBlocks) + len(tableRowBlocks) + numberOfDefaultTableBlocks + allBlocks := make([]*model.Block, 0, resultNumberOfBlocks) + allBlocks = append(allBlocks, table) + allBlocks = append(allBlocks, columnLayoutBlock) + allBlocks = append(allBlocks, columnsBlocks...) + allBlocks = append(allBlocks, tableRowLayoutBlock) + allBlocks = append(allBlocks, tableRowBlocks...) + allBlocks = append(allBlocks, rowTextBlocks...) + + allBlocksIDs := make([]string, 0, resultNumberOfBlocks) + allBlocksIDs = append(allBlocksIDs, rootID) + allBlocksIDs = append(allBlocksIDs, columnLayoutBlockID) + allBlocksIDs = append(allBlocksIDs, columnsBlocksIDs...) + allBlocksIDs = append(allBlocksIDs, tableRowBlockID) + for _, b := range rowTextBlocks { + allBlocksIDs = append(allBlocksIDs, b.Id) + } + + tableResponse.BlockIDs = allBlocksIDs + tableResponse.Blocks = allBlocks + return tableResponse +} + +func (*TableBlock) getTableBlock(columnLayoutBlockID string, tableRowBlockID string) (string, *model.Block) { + rootID := bson.NewObjectId().Hex() + table := &model.Block{ + Id: rootID, + ChildrenIds: []string{columnLayoutBlockID, tableRowBlockID}, + Content: &model.BlockContentOfTable{ + Table: &model.BlockContentTable{}, + }, + } + return rootID, table +} + +func (*TableBlock) getLayoutRowBlock(children []string) (string, *model.Block) { + tableRowBlockID := bson.NewObjectId().Hex() + tableRowLayoutBlock := &model.Block{ + Id: tableRowBlockID, + ChildrenIds: children, + Content: &model.BlockContentOfLayout{ + Layout: &model.BlockContentLayout{ + Style: model.BlockContentLayout_TableRows, + }, + }, + } + return tableRowBlockID, tableRowLayoutBlock +} + +func (t *TableBlock) getRows(req *MapRequest, + columnsBlocksIDs []string, + tableResponse *MapResponse) ([]*model.Block, []string, []*model.Block) { + var ( + needHeader = true + tableRowBlocks = make([]*model.Block, 0, len(t.Table.Children)) + tableRowBlocksIDs = make([]string, 0, len(t.Table.Children)) + rowTextBlocks = make([]*model.Block, 0) + ) + for _, trb := range t.Table.Children { + var childBlockIDsCurrRow []string + id := bson.NewObjectId().Hex() + for i, c := range trb.TableRowObject.Cells { + to := &TextObject{ + RichText: c, + } + resp := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, req) + + resp.BlockIDs = make([]string, 0, len(c)) + for _, b := range resp.Blocks { + b.Id = table.MakeCellID(id, columnsBlocksIDs[i]) + resp.BlockIDs = append(resp.BlockIDs, b.Id) + } + rowTextBlocks = append(rowTextBlocks, resp.Blocks...) + childBlockIDsCurrRow = append(childBlockIDsCurrRow, resp.BlockIDs...) + tableResponse.Relations = append(tableResponse.Relations, resp.Relations...) + tableResponse.MergeDetails(resp.Details) + } + + var isHeader bool + if needHeader { + isHeader = t.Table.HasRowHeader + needHeader = false + } + + tableRowBlocks = append(tableRowBlocks, &model.Block{ + Id: id, + ChildrenIds: childBlockIDsCurrRow, + Content: &model.BlockContentOfTableRow{ + TableRow: &model.BlockContentTableRow{ + IsHeader: isHeader, + }, + }, + }) + tableRowBlocksIDs = append(tableRowBlocksIDs, id) + } + + return tableRowBlocks, tableRowBlocksIDs, rowTextBlocks +} + +func (t *TableBlock) getColumns() ([]*model.Block, []string, string, *model.Block) { + columnsBlocks := make([]*model.Block, 0, t.Table.Width) + columnsBlocksIDs := make([]string, 0, t.Table.Width) + for i := 0; i < int(t.Table.Width); i++ { + id := bson.NewObjectId().Hex() + columnsBlocks = append(columnsBlocks, &model.Block{ + Id: id, + ChildrenIds: []string{}, + Content: &model.BlockContentOfTableColumn{ + TableColumn: &model.BlockContentTableColumn{}, + }, + }) + columnsBlocksIDs = append(columnsBlocksIDs, id) + } + + columnLayoutBlockID := bson.NewObjectId().Hex() + columnLayoutBlock := &model.Block{ + Id: columnLayoutBlockID, + ChildrenIds: columnsBlocksIDs, + Content: &model.BlockContentOfLayout{ + Layout: &model.BlockContentLayout{ + Style: model.BlockContentLayout_TableColumns, + }, + }, + } + return columnsBlocks, columnsBlocksIDs, columnLayoutBlockID, columnLayoutBlock +} diff --git a/core/block/import/notion/api/block/table_test.go b/core/block/import/notion/api/block/table_test.go new file mode 100644 index 000000000..b873c1ce8 --- /dev/null +++ b/core/block/import/notion/api/block/table_test.go @@ -0,0 +1,92 @@ +package block + +import ( + "testing" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + "github.com/stretchr/testify/assert" +) + +func Test_TableWithOneColumnAndRow(t *testing.T) { + + tb := &TableBlock{ + Table: TableObject{ + Width: 1, + HasColumnHeader: false, + HasRowHeader: true, + Children: []*TableRowBlock{ + { + TableRowObject: TableRowObject{}, + }, + }, + }, + } + + resp := tb.GetBlocks(&MapRequest{}) + + assert.NotNil(t, resp) + assert.Len(t, resp.Blocks, 5) // table block + column block + row block + 2 empty text blocks +} + +func Test_TableWithoutContent(t *testing.T) { + + tb := &TableBlock{ + Table: TableObject{ + Width: 3, + HasColumnHeader: false, + HasRowHeader: true, + Children: []*TableRowBlock{ + { + TableRowObject: TableRowObject{}, + }, + { + TableRowObject: TableRowObject{}, + }, + }, + }, + } + + + assert.Len(t, tb.Table.Children, 2) + + resp := tb.GetBlocks(&MapRequest{}) + + assert.NotNil(t, resp) + assert.Len(t, resp.Blocks, 8) // table block + 3 * column block + 1 column layout + 1 row layout + 3 * row block +} + +func Test_TableWithDifferentText(t *testing.T) { + + tb := &TableBlock{ + Table: TableObject{ + Width: 3, + HasColumnHeader: false, + HasRowHeader: true, + Children: []*TableRowBlock{ + { + TableRowObject: TableRowObject{ + Cells: [][]api.RichText{ + { + { + Type: api.Text, + PlainText: "Text", + }, + }, + }, + }, + }, + { + TableRowObject: TableRowObject{}, + }, + }, + }, + } + + + assert.Len(t, tb.Table.Children, 2) + + resp := tb.GetBlocks(&MapRequest{}) + + assert.NotNil(t, resp) + assert.Len(t, resp.Blocks, 9) // table block + 3 * column block + 1 column layout + 1 row layout + 3 * row block + 1 text block +} \ No newline at end of file diff --git a/core/block/import/notion/api/block/text.go b/core/block/import/notion/api/block/text.go index 801ffadbd..3f27b21be 100644 --- a/core/block/import/notion/api/block/text.go +++ b/core/block/import/notion/api/block/text.go @@ -310,3 +310,11 @@ type EquationBlock struct { Block Equation api.EquationObject `json:"equation"` } + +func (e *EquationBlock) GetBlocks(req *MapRequest) *MapResponse { + bl := e.Equation.HandleEquation() + return &MapResponse{ + Blocks: []*model.Block{bl}, + BlockIDs: []string{bl.Id}, + } +} diff --git a/core/block/import/notion/api/block/text_test.go b/core/block/import/notion/api/block/text_test.go index 43d5fba60..d5f548e08 100644 --- a/core/block/import/notion/api/block/text_test.go +++ b/core/block/import/notion/api/block/text_test.go @@ -43,6 +43,7 @@ func Test_GetTextBlocksTextUserMention(t *testing.T) { Name: "Nastya", }, }, + PlainText: "Nastya", }, }, } diff --git a/core/block/import/notion/api/block/textobject.go b/core/block/import/notion/api/block/textobject.go index 8c9f1f9e2..cfb7ace77 100644 --- a/core/block/import/notion/api/block/textobject.go +++ b/core/block/import/notion/api/block/textobject.go @@ -84,7 +84,6 @@ func (t *TextObject) GetTextBlocks(style model.BlockContentTextStyle, childIds [ Style: style, Marks: &model.BlockContentTextMarks{Marks: marks}, Checked: false, - Color: api.NotionColorToAnytype[t.Color], }, }, }) @@ -150,7 +149,7 @@ func (t *TextObject) handleMentionType(rt api.RichText, text *strings.Builder, r func (t *TextObject) handleUserMention(rt api.RichText, text *strings.Builder) []*model.BlockContentTextMark { from := textUtil.UTF16RuneCountString(text.String()) - text.WriteString(rt.Mention.User.Name) + text.WriteString(rt.PlainText) to := textUtil.UTF16RuneCountString(text.String()) return rt.BuildMarkdownFromAnnotations(int32(from), int32(to)) } diff --git a/core/block/import/notion/api/commonobjects.go b/core/block/import/notion/api/commonobjects.go index baeedec69..17a5ee5df 100644 --- a/core/block/import/notion/api/commonobjects.go +++ b/core/block/import/notion/api/commonobjects.go @@ -10,19 +10,19 @@ import ( "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" ) -type richTextType string +type RichTextType string const ( - Text richTextType = "text" - Mention richTextType = "mention" - Equation richTextType = "equation" + Text RichTextType = "text" + Mention RichTextType = "mention" + Equation RichTextType = "equation" ) const NotionBackgroundColorSuffix = "background" // RichText represent RichText object from Notion https://developers.notion.com/reference/rich-text type RichText struct { - Type richTextType `json:"type,omitempty"` + Type RichTextType `json:"type,omitempty"` Text *TextObject `json:"text,omitempty"` Mention *MentionObject `json:"mention,omitempty"` Equation *EquationObject `json:"equation,omitempty"` diff --git a/core/block/import/notion/api/database/database.go b/core/block/import/notion/api/database/database.go index 466a9c5a7..0ed969f41 100644 --- a/core/block/import/notion/api/database/database.go +++ b/core/block/import/notion/api/database/database.go @@ -97,6 +97,7 @@ func (ds *Service) GetDatabase(ctx context.Context, func (ds *Service) transformDatabase(d Database) *model.SmartBlockSnapshotBase { details := make(map[string]*types.Value, 0) + relations := make([]*converter.Relation, 0) details[bundle.RelationKeySource.String()] = pbtypes.String(d.URL) if len(d.Title) > 0 { details[bundle.RelationKeyName.String()] = pbtypes.String(d.Title[0].PlainText) @@ -104,6 +105,30 @@ func (ds *Service) transformDatabase(d Database) *model.SmartBlockSnapshotBase { if d.Icon != nil && d.Icon.Emoji != nil { details[bundle.RelationKeyIconEmoji.String()] = pbtypes.String(*d.Icon.Emoji) } + + if d.Cover != nil { + var relation *converter.Relation + + if d.Cover.Type == api.External { + details[bundle.RelationKeyCoverId.String()] = pbtypes.String(d.Cover.External.URL) + details[bundle.RelationKeyCoverType.String()] = pbtypes.Float64(1) + relation = &converter.Relation{ + Name: bundle.RelationKeyCoverId.String(), + Format: model.RelationFormat_file, + } + } + + if d.Cover.Type == api.File { + details[bundle.RelationKeyCoverId.String()] = pbtypes.String(d.Cover.File.URL) + details[bundle.RelationKeyCoverType.String()] = pbtypes.Float64(1) + relation = &converter.Relation{ + Name: bundle.RelationKeyCoverId.String(), + Format: model.RelationFormat_file, + } + } + + relations = append(relations, relation) + } details[bundle.RelationKeyCreatedDate.String()] = pbtypes.String(d.CreatedTime.String()) details[bundle.RelationKeyCreator.String()] = pbtypes.String(d.CreatedBy.Name) details[bundle.RelationKeyIsArchived.String()] = pbtypes.Bool(d.Archived) diff --git a/core/block/import/notion/api/page/page.go b/core/block/import/notion/api/page/page.go index d0a423918..4010e9c8d 100644 --- a/core/block/import/notion/api/page/page.go +++ b/core/block/import/notion/api/page/page.go @@ -154,7 +154,7 @@ func (ds *Service) transformPages(ctx context.Context, allErrors := converter.ConvertError{} relations := ds.handlePageProperties(apiKey, p.ID, p.Properties, details, request.NotionPageIdsToAnytype, request.NotionDatabaseIdsToAnytype) - + addFCoverDetail(p, details) notionBlocks, blocksAndChildrenErr := ds.blockService.GetBlocksAndChildren(ctx, p.ID, apiKey, pageSize, mode) if blocksAndChildrenErr != nil { allErrors.Merge(blocksAndChildrenErr) @@ -215,3 +215,19 @@ func linkRelationsIDWithAnytypeID(rel *property.RelationItem, notionPagesIdsToAn } } } + +func addFCoverDetail(p Page, details map[string]*types.Value) { + if p.Cover != nil { + if p.Cover.Type == api.External { + details[bundle.RelationKeyCoverId.String()] = pbtypes.String(p.Cover.External.URL) + details[bundle.RelationKeyCoverType.String()] = pbtypes.Float64(1) + } + + if p.Cover.Type == api.File { + details[bundle.RelationKeyCoverId.String()] = pbtypes.String(p.Cover.File.URL) + details[bundle.RelationKeyCoverType.String()] = pbtypes.Float64(1) + } + + } + +} diff --git a/core/block/import/relationcreator.go b/core/block/import/relationcreator.go index 184e84178..5b432cd23 100644 --- a/core/block/import/relationcreator.go +++ b/core/block/import/relationcreator.go @@ -13,6 +13,7 @@ import ( "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore/filestore" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" "github.com/anytypeio/go-anytype-middleware/util/pbtypes" ) @@ -20,13 +21,15 @@ import ( type RelationService struct { core core.Service service *block.Service + store filestore.FileStore } // NewRelationCreator constructor for RelationService -func NewRelationCreator(service *block.Service, core core.Service) RelationCreator { +func NewRelationCreator(service *block.Service, store filestore.FileStore, core core.Service) RelationCreator { return &RelationService{ service: service, core: core, + store: store, } } @@ -76,7 +79,7 @@ func (rc *RelationService) Create(ctx *session.Context, } if r.Format == model.RelationFormat_file { - rc.handleFileRelation(ctx, snapshot, r, filesToDelete) + filesToDelete = append(filesToDelete, rc.handleFileRelation(ctx, snapshot, r.Name)...) } details := make([]*pb.RpcObjectSetDetailsDetail, 0) details = append(details, &pb.RpcObjectSetDetailsDetail{ @@ -99,9 +102,33 @@ func (rc *RelationService) Create(ctx *session.Context, } } } + + if ftd, err := rc.handleCoverRelation(ctx, snapshot, pageID); err != nil { + log.Errorf("failed to upload cover image %s", err) + } else { + filesToDelete = append(filesToDelete, ftd...) + } + return filesToDelete, oldRelationBlockToNew, nil } +func (rc *RelationService) handleCoverRelation(ctx *session.Context, + snapshot *model.SmartBlockSnapshotBase, + pageID string) ([]string, error) { + filesToDelete := rc.handleFileRelation(ctx, snapshot, bundle.RelationKeyCoverId.String()) + details := make([]*pb.RpcObjectSetDetailsDetail, 0) + details = append(details, &pb.RpcObjectSetDetailsDetail{ + Key: bundle.RelationKeyCoverId.String(), + Value: snapshot.Details.Fields[bundle.RelationKeyCoverId.String()], + }) + err := rc.service.SetDetails(ctx, pb.RpcObjectSetDetailsRequest{ + ContextId: pageID, + Details: details, + }) + + return filesToDelete, err +} + func (rc *RelationService) handleListValue(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, r *converter.Relation, relationID string) { var ( optionsIds = make([]string, 0) @@ -130,33 +157,57 @@ func (rc *RelationService) handleListValue(ctx *session.Context, snapshot *model func (rc *RelationService) handleFileRelation(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, - r *converter.Relation, - filesToDelete []string) { - files := snapshot.Details.Fields[r.Name].GetListValue() - - if files == nil { - return - } - allFilesHashes := make([]string, 0) - for _, f := range files.Values { - file := f.GetStringValue() - if file != "" { - req := pb.RpcFileUploadRequest{LocalPath: file} - if strings.HasPrefix(file, "http://") || strings.HasPrefix(file, "https://") { - req.Url = file - req.LocalPath = "" - } - hash, err := rc.service.UploadFile(req) - if err != nil { - log.Errorf("file uploading %s", err) - } else { - file = hash - } - filesToDelete = append(filesToDelete, file) - allFilesHashes = append(allFilesHashes, file) + name string) []string { + var allFiles []string + if files := snapshot.Details.Fields[name].GetListValue(); files != nil { + for _, f := range files.Values { + allFiles = append(allFiles, f.GetStringValue()) } } - snapshot.Details.Fields[r.Name] = pbtypes.StringList(allFilesHashes) + + if files := snapshot.Details.Fields[name].GetStringValue(); files != "" { + allFiles = append(allFiles, files) + } + + allFilesHashes := make([]string, 0) + + filesToDelete := make([]string, 0, len(allFiles)) + for _, f := range allFiles { + if f == "" { + continue + } + if _, err := rc.store.GetByHash(f); err == nil { + allFilesHashes = append(allFilesHashes, f) + continue + } + + req := pb.RpcFileUploadRequest{LocalPath: f} + + if strings.HasPrefix(f, "http://") || strings.HasPrefix(f, "https://") { + req.Url = f + req.LocalPath = "" + } + + hash, err := rc.service.UploadFile(req) + if err != nil { + log.Errorf("file uploading %s", err) + } else { + f = hash + } + + filesToDelete = append(filesToDelete, f) + allFilesHashes = append(allFilesHashes, f) + } + + if snapshot.Details.Fields[name].GetListValue() != nil { + snapshot.Details.Fields[name] = pbtypes.StringList(allFilesHashes) + } + + if snapshot.Details.Fields[name].GetStringValue() != "" && len(allFilesHashes) != 0 { + snapshot.Details.Fields[name] = pbtypes.String(allFilesHashes[0]) + } + + return filesToDelete } func (rc *RelationService) linkRelationsBlocks(snapshot *model.SmartBlockSnapshotBase, oldID, newID string) (*model.Block, *model.Block) { From 1a168b8da475d5992c898df1894a1f28105b507f Mon Sep 17 00:00:00 2001 From: Anastasia Shemyakinskaya <36507473+AnastasiaShemyakinskaya@users.noreply.github.com> Date: Fri, 16 Dec 2022 17:28:20 +0300 Subject: [PATCH 21/68] GO-572 notion import performance impovement, bug fixes and rollup property support (#1655) Signed-off-by: AnastasiaShemyakinskaya --- .golangci.yml | 3 +- core/block/editor/file/uploader.go | 6 +- .../import/notion/api/block/textobject.go | 13 +- core/block/import/notion/api/page/page.go | 75 ++++- .../block/import/notion/api/page/page_test.go | 110 +++++-- .../block/import/notion/api/page/pageslink.go | 1 - .../notion/api/property/propertyitem.go | 86 +++++- .../notion/api/property/propertyobject.go | 277 ++++++++++++++---- core/block/import/relationcreator.go | 132 ++++++--- 9 files changed, 542 insertions(+), 161 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 6f336fde9..32e70f8ab 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,11 +1,10 @@ -un: +run: deadline: 15m timeout: 15m # didn't run linter on tests tests: false # don't check generated protobuf files skip-dirs: - - pb/external_libs - pkg/lib/pb go: '1.18' diff --git a/core/block/editor/file/uploader.go b/core/block/editor/file/uploader.go index 0256c745b..8cb5875c0 100644 --- a/core/block/editor/file/uploader.go +++ b/core/block/editor/file/uploader.go @@ -183,7 +183,11 @@ func (u *uploader) SetUrl(url string) Uploader { return nil, err } - resp, err := http.DefaultClient.Do(req) + // setting timeout to avoid locking for a long time + cl := http.DefaultClient + cl.Timeout = time.Second * 20 + + resp, err := cl.Do(req) if err != nil { return nil, err } diff --git a/core/block/import/notion/api/block/textobject.go b/core/block/import/notion/api/block/textobject.go index cfb7ace77..34259c141 100644 --- a/core/block/import/notion/api/block/textobject.go +++ b/core/block/import/notion/api/block/textobject.go @@ -48,9 +48,11 @@ func (t *TextObject) GetTextBlocks(style model.BlockContentTextStyle, childIds [ relation *converter.Relation ) relationBlock, relation, details, relationBlockID = t.handleDateMention(rt, &text) - allBlocks = append(allBlocks, relationBlock) - allIds = append(allIds, relationBlockID) - relations = append(relations, relation) + if relationBlock != nil { + allBlocks = append(allBlocks, relationBlock) + allIds = append(allIds, relationBlockID) + relations = append(relations, relation) + } continue } marks = append(marks, t.handleMentionType(rt, &text, req)...) @@ -61,9 +63,11 @@ func (t *TextObject) GetTextBlocks(style model.BlockContentTextStyle, childIds [ allIds = append(allIds, eqBlock.Id) } } - var backgroundColor string + var backgroundColor, textColor string if strings.Contains(t.Color, api.NotionBackgroundColorSuffix) { backgroundColor = api.NotionColorToAnytype[t.Color] + } else { + textColor = api.NotionColorToAnytype[t.Color] } if t.isNotTextBlocks() { @@ -84,6 +88,7 @@ func (t *TextObject) GetTextBlocks(style model.BlockContentTextStyle, childIds [ Style: style, Marks: &model.BlockContentTextMarks{Marks: marks}, Checked: false, + Color: textColor, }, }, }) diff --git a/core/block/import/notion/api/page/page.go b/core/block/import/notion/api/page/page.go index 4010e9c8d..78e2de6e8 100644 --- a/core/block/import/notion/api/page/page.go +++ b/core/block/import/notion/api/page/page.go @@ -29,15 +29,17 @@ const ( ) type Service struct { - blockService *block.Service - client *client.Client + blockService *block.Service + client *client.Client + propertyService *property.Service } // New is a constructor for Service func New(client *client.Client) *Service { return &Service{ - blockService: block.New(client), - client: client, + blockService: block.New(client), + client: client, + propertyService: property.New(client), } } @@ -102,9 +104,18 @@ func (ds *Service) GetPages(ctx context.Context, for _, p := range pages { for _, v := range p.Properties { if t, ok := v.(*property.TitleItem); ok { - title := api.RichTextToDescription(t.Title) - pageNameToID[p.ID] = title - break + properties, err := ds.propertyService.GetPropertyObject(ctx, p.ID, t.GetID(), apiKey, t.GetPropertyType()) + if err != nil { + logger.With("method", "handlePageProperties").Errorf("failed to get paginated property, %s", v.GetPropertyType()) + continue + } + title := make([]*api.RichText, 0, len(properties)) + for _, o := range properties { + if t, ok := o.(*api.RichText); ok { + title = append(title, t) + } + } + t.Title = title } } } @@ -153,7 +164,7 @@ func (ds *Service) transformPages(ctx context.Context, details[bundle.RelationKeyIsFavorite.String()] = pbtypes.Bool(true) allErrors := converter.ConvertError{} - relations := ds.handlePageProperties(apiKey, p.ID, p.Properties, details, request.NotionPageIdsToAnytype, request.NotionDatabaseIdsToAnytype) + relations := ds.handlePageProperties(ctx, apiKey, p.ID, p.Properties, details, request) addFCoverDetail(p, details) notionBlocks, blocksAndChildrenErr := ds.blockService.GetBlocksAndChildren(ctx, p.ID, apiKey, pageSize, mode) if blocksAndChildrenErr != nil { @@ -177,14 +188,23 @@ func (ds *Service) transformPages(ctx context.Context, } // handlePageProperties gets properties values by their ids from notion api and transforms them to Details and RelationLinks -func (ds *Service) handlePageProperties(apiKey, pageID string, +func (ds *Service) handlePageProperties(ctx context.Context, + apiKey, pageID string, p property.Properties, d map[string]*types.Value, - notionPagesIdsToAnytype, notionDatabaseIdsToAnytype map[string]string) []*converter.Relation { + req *block.MapRequest) []*converter.Relation { relations := make([]*converter.Relation, 0) for k, v := range p { - if rel, ok := v.(*property.RelationItem); ok { - linkRelationsIDWithAnytypeID(rel, notionPagesIdsToAnytype, notionDatabaseIdsToAnytype) + if isPropertyPaginated(v) { + properties, err := ds.propertyService.GetPropertyObject(ctx, pageID, v.GetID(), apiKey, v.GetPropertyType()) + if err != nil { + logger.With("method", "handlePageProperties").Errorf("failed to get paginated property, %s", v.GetPropertyType()) + continue + } + ds.handlePaginatedProperty(v, properties) + } + if r, ok := v.(*property.RelationItem); ok { + linkRelationsIDWithAnytypeID(r, req.NotionPageIdsToAnytype, req.NotionDatabaseIdsToAnytype) } var ( ds property.DetailSetter @@ -203,6 +223,29 @@ func (ds *Service) handlePageProperties(apiKey, pageID string, return relations } +func (*Service) handlePaginatedProperty(v property.Object, properties []interface{}) { + switch pr := v.(type) { + case *property.RelationItem: + relationItems := make([]*property.Relation, 0, len(properties)) + for _, o := range properties { + relationItems = append(relationItems, o.(*property.Relation)) + } + pr.Relation = relationItems + case *property.RichTextItem: + richText := make([]*api.RichText, 0, len(properties)) + for _, o := range properties { + richText = append(richText, o.(*api.RichText)) + } + pr.RichText = richText + case *property.PeopleItem: + pList := make([]*api.User, 0, len(properties)) + for _, o := range properties { + pList = append(pList, o.(*api.User)) + } + pr.People = pList + } +} + // linkRelationsIDWithAnytypeID take anytype ID based on page/database ID from Notin. In property we get id from Notion, so we somehow need to // map this ID with anytype for correct Relation. We use two maps notionPagesIdsToAnytype, notionDatabaseIdsToAnytype for this func linkRelationsIDWithAnytypeID(rel *property.RelationItem, notionPagesIdsToAnytype, notionDatabaseIdsToAnytype map[string]string) { @@ -231,3 +274,11 @@ func addFCoverDetail(p Page, details map[string]*types.Value) { } } + +func isPropertyPaginated(pr property.Object) bool { + if r, ok := pr.(*property.RelationItem); ok && r.HasMore { + return true + } + return pr.GetPropertyType() == property.PropertyConfigTypeRichText || + pr.GetPropertyType() == property.PropertyConfigTypePeople +} diff --git a/core/block/import/notion/api/page/page_test.go b/core/block/import/notion/api/page/page_test.go index 769c83a72..414c2ea00 100644 --- a/core/block/import/notion/api/page/page_test.go +++ b/core/block/import/notion/api/page/page_test.go @@ -1,6 +1,7 @@ package page import ( + "context" "net/http" "net/http/httptest" "testing" @@ -9,6 +10,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/block" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/property" "github.com/anytypeio/go-anytype-middleware/util/pbtypes" @@ -30,7 +32,7 @@ func Test_handlePagePropertiesSelect(t *testing.T) { }, } pr := property.Properties{"Select": &p} - _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) + _ = ps.handlePageProperties(context.TODO(), "key", "id", pr, details, &block.MapRequest{}) assert.NotEmpty(t, details["Select"]) } @@ -47,14 +49,14 @@ func Test_handlePagePropertiesLastEditedTime(t *testing.T) { LastEditedTime: "2022-12-07", } pr := property.Properties{"LastEditedTime": &p} - _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) + _ = ps.handlePageProperties(context.TODO(), "key", "id", pr, details, &block.MapRequest{}) assert.NotEmpty(t, details["LastEditedTime"]) } func Test_handlePagePropertiesRichText(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(`{"object":"list","results":[{"object":"property_item","type":"rich_text","id":"RPBv","rich_text":{"type":"text","text":{"content":"sdfsdfsdfsdfsdfsdf","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"sdfsdfsdfsdfsdfsdf","href":null}}],"next_cursor":null,"has_more":false,"type":"property_item","property_item":{"id":"RPBv","next_url":null,"type":"rich_text","rich_text":{}}}`)) + w.Write([]byte(`{"object":"list","results":[{"object":"property_item","type":"rich_text","id":"RPBv","rich_text":{"type":"text","text":{"content":"sdfsdfsdfsdfsdfsdf","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"example text","href":null}}],"next_cursor":null,"has_more":false,"type":"property_item","property_item":{"id":"RPBv","next_url":null,"type":"rich_text","rich_text":{}}}`)) })) c := client.NewClient() @@ -65,9 +67,10 @@ func Test_handlePagePropertiesRichText(t *testing.T) { p := property.RichTextItem{ID: "id", Type: string(property.PropertyConfigLastEditedTime)} pr := property.Properties{"RichText": &p} - _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) + _ = ps.handlePageProperties(context.TODO(), "key", "id", pr, details, &block.MapRequest{}) assert.NotEmpty(t, details["RichText"]) + assert.Equal(t, details["RichText"].GetStringValue(), "example text") } func Test_handlePagePropertiesStatus(t *testing.T) { @@ -86,18 +89,13 @@ func Test_handlePagePropertiesStatus(t *testing.T) { }, } pr := property.Properties{"Status": &p} - _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) + _ = ps.handlePageProperties(context.TODO(), "key", "id", pr, details, &block.MapRequest{}) assert.NotEmpty(t, details["Status"]) } func Test_handlePagePropertiesNumber(t *testing.T) { - s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(`{"object":"property_item","type":"number","id":"WxBc","number":3434}`)) - })) - c := client.NewClient() - c.BasePath = s.URL ps := New(c) details := make(map[string]*types.Value, 0) @@ -109,18 +107,13 @@ func Test_handlePagePropertiesNumber(t *testing.T) { Number: &num, } pr := property.Properties{"Number": &p} - _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) + _ = ps.handlePageProperties(context.TODO(), "key", "id", pr, details, &block.MapRequest{}) assert.NotEmpty(t, details["Number"]) } func Test_handlePagePropertiesMultiSelect(t *testing.T) { - s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(`{"object":"property_item","type":"multi_select","id":"%5D%60%3FX","multi_select":[{"id":"EgfK","name":"ddd","color":"default"},{"id":"QO[c","name":"AAA","color":"purple"},{"id":"UsL>","name":"Option","color":"orange"}]}`)) - })) - c := client.NewClient() - c.BasePath = s.URL ps := New(c) details := make(map[string]*types.Value, 0) @@ -137,18 +130,13 @@ func Test_handlePagePropertiesMultiSelect(t *testing.T) { }, } pr := property.Properties{"MultiSelect": &p} - _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) + _ = ps.handlePageProperties(context.TODO(), "key", "id", pr, details, &block.MapRequest{}) assert.NotEmpty(t, details["MultiSelect"]) } func Test_handlePagePropertiesCheckbox(t *testing.T) { - s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(`{"object":"property_item","type":"checkbox","id":"%60%3C%3DZ","checkbox":true}`)) - })) - c := client.NewClient() - c.BasePath = s.URL ps := New(c) details := make(map[string]*types.Value, 0) @@ -159,7 +147,7 @@ func Test_handlePagePropertiesCheckbox(t *testing.T) { Checkbox: true, } pr := property.Properties{"Checkbox": &p} - _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) + _ = ps.handlePageProperties(context.TODO(), "key", "id", pr, details, &block.MapRequest{}) assert.NotEmpty(t, details["Checkbox"]) } @@ -177,7 +165,7 @@ func Test_handlePagePropertiesEmail(t *testing.T) { Email: &email, } pr := property.Properties{"Email": &p} - _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) + _ = ps.handlePageProperties(context.TODO(), "key", "id", pr, details, &block.MapRequest{}) assert.NotEmpty(t, details["Email"]) } @@ -193,11 +181,12 @@ func Test_handlePagePropertiesRelation(t *testing.T) { details := make(map[string]*types.Value, 0) - p := property.RelationItem{ID: "id", Type: string(property.PropertyConfigTypeRelation), Relation: []*property.Relation{{ID: "id"}}} + p := property.RelationItem{ID: "id", Type: string(property.PropertyConfigTypeRelation), HasMore: true, Relation: []*property.Relation{{ID: "id"}}} pr := property.Properties{"Relation": &p} notionPageIdsToAnytype := map[string]string{"id": "anytypeID"} notionDatabaseIdsToAnytype := map[string]string{"id": "anytypeID"} - _ = ps.handlePageProperties("key", "id", pr, details, notionPageIdsToAnytype, notionDatabaseIdsToAnytype) + req := &block.MapRequest{NotionPageIdsToAnytype: notionPageIdsToAnytype, NotionDatabaseIdsToAnytype: notionDatabaseIdsToAnytype} + _ = ps.handlePageProperties(context.TODO(), "key", "id", pr, details, req) assert.NotNil(t, details["Relation"].GetListValue()) assert.Len(t, details["Relation"].GetListValue().Values, 1) @@ -205,7 +194,11 @@ func Test_handlePagePropertiesRelation(t *testing.T) { } func Test_handlePagePropertiesPeople(t *testing.T) { + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(`{"object":"list","results":[{"object":"property_item","type":"people","id":"id","people":{"object":"user","id":"1","name":"Example","avatar_url":"https://example1.com","type":"person","person":{"email":"email1@.com"}}},{"object":"property_item","type":"people","id":"id","people":{"object":"user","id":"2","name":"Example 2","avatar_url":"https://example2.com","type":"person","person":{"email":"email2@.com"}}}],"next_cursor":null,"has_more":false,"type":"property_item","property_item":{"id":"id","next_url":null,"type":"people","people":{}}}`)) + })) c := client.NewClient() + c.BasePath = s.URL ps := New(c) details := make(map[string]*types.Value, 0) @@ -216,9 +209,13 @@ func Test_handlePagePropertiesPeople(t *testing.T) { Type: string(property.PropertyConfigTypePeople), } pr := property.Properties{"People": &p} - _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) + _ = ps.handlePageProperties(context.TODO(), "key", "id", pr, details, &block.MapRequest{}) assert.NotEmpty(t, details["People"]) + assert.Len(t, pbtypes.GetStringListValue(details["People"]), 2) + people := pbtypes.GetStringListValue(details["People"]) + assert.Equal(t, people[0], "Example") + assert.Equal(t, people[1], "Example 2") } func Test_handlePagePropertiesFormula(t *testing.T) { @@ -233,7 +230,7 @@ func Test_handlePagePropertiesFormula(t *testing.T) { Formula: map[string]interface{}{"type": property.NumberFormula, "number": float64(1)}, } pr := property.Properties{"Formula": &p} - _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) + _ = ps.handlePageProperties(context.TODO(), "key", "id", pr, details, &block.MapRequest{}) assert.NotEmpty(t, details["Formula"]) } @@ -250,7 +247,60 @@ func Test_handlePagePropertiesTitle(t *testing.T) { Title: []*api.RichText{{PlainText: "Title"}}, } pr := property.Properties{"Title": &p} - _ = ps.handlePageProperties("key", "id", pr, details, nil, nil) + _ = ps.handlePageProperties(context.TODO(), "key", "id", pr, details, &block.MapRequest{}) assert.NotEmpty(t, details["name"]) -} \ No newline at end of file + assert.NotEmpty(t, details["name"].GetStringValue(), "Title") +} + +func Test_handleRollupProperties(t *testing.T) { + c := client.NewClient() + ps := New(c) + + details := make(map[string]*types.Value, 0) + + p1 := property.RollupItem{ + ID: "id1", + Type: string(property.PropertyConfigTypeRollup), + Rollup: property.RollupObject{ + Type: "number", + Number: 2, + }, + } + + p2 := property.RollupItem{ + ID: "id2", + Type: string(property.PropertyConfigTypeRollup), + Rollup: property.RollupObject{ + Type: "date", + Date: &api.DateObject{ + Start: "12-12-2022", + }, + }, + } + + p3 := property.RollupItem{ + ID: "id3", + Type: string(property.PropertyConfigTypeRollup), + Rollup: property.RollupObject{ + Type: "array", + Array: []interface{}{ + map[string]interface{}{"type": "title", "title": []map[string]string{{"plain_text": "Title"}}}, + }, + }, + } + + pr := property.Properties{"Rollup1": &p1, "Rollup2": &p2, "Rollup3": &p3} + _ = ps.handlePageProperties(context.TODO(), "key", "id", pr, details, &block.MapRequest{}) + + assert.NotEmpty(t, details["Rollup1"]) + assert.NotEmpty(t, details["Rollup1"].GetNumberValue(), float64(2)) + + assert.NotEmpty(t, details["Rollup2"]) + assert.NotEmpty(t, details["Rollup2"].GetStringValue(), "12-12-2022") + + assert.NotEmpty(t, details["Rollup3"]) + assert.Len(t, pbtypes.GetStringListValue(details["Rollup3"]), 1) + rollup := pbtypes.GetStringListValue(details["Rollup3"]) + assert.Equal(t, rollup[0], "Title") +} diff --git a/core/block/import/notion/api/page/pageslink.go b/core/block/import/notion/api/page/pageslink.go index 6e4bbbac7..754807e84 100644 --- a/core/block/import/notion/api/page/pageslink.go +++ b/core/block/import/notion/api/page/pageslink.go @@ -8,7 +8,6 @@ import ( "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" ) -// TODO tests func SetPageLinksInDatabase(databaseSnaphots *converter.Response, pages []Page, databases []database.Database, diff --git a/core/block/import/notion/api/property/propertyitem.go b/core/block/import/notion/api/property/propertyitem.go index 4e2169347..1b6d83bbb 100644 --- a/core/block/import/notion/api/property/propertyitem.go +++ b/core/block/import/notion/api/property/propertyitem.go @@ -8,6 +8,7 @@ import ( "time" "github.com/gogo/protobuf/types" + "go.uber.org/zap" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" "github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle" @@ -61,7 +62,7 @@ func (t *TitleItem) SetDetail(key string, details map[string]*types.Value) { var richText strings.Builder for i, title := range t.Title { richText.WriteString(title.PlainText) - if i != len(title.PlainText)-1 { + if i != len(t.Title)-1 { richText.WriteString("\n") } } @@ -111,9 +112,9 @@ func (rt *RichTextItem) GetFormat() model.RelationFormat { } type NumberItem struct { - Object string `json:"object"` - ID string `json:"id"` - Type string `json:"type"` + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` Number *float64 `json:"number"` } @@ -586,18 +587,89 @@ func (sp *StatusItem) GetFormat() model.RelationFormat { return model.RelationFormat_status } -type RollupItem struct{} +type rollupType string -func (r *RollupItem) SetDetail(key string, details map[string]*types.Value) {} +const ( + rollupNumber rollupType = "number" + rollupDate rollupType = "date" + rollupArray rollupType = "array" +) + +type propertyObjects []interface{} +type RollupItem struct { + ID string `json:"id"` + Type string `json:"type"` + Rollup RollupObject `json:"rollup"` +} + +type RollupObject struct { + Type rollupType `json:"type"` + Number float64 `json:"number"` + Date *api.DateObject `json:"date"` + Array propertyObjects `json:"array"` +} + +func (r *RollupItem) SetDetail(key string, details map[string]*types.Value) { + switch r.Rollup.Type { + case rollupNumber: + details[key] = pbtypes.Float64(r.Rollup.Number) + case rollupDate: + di := DateItem{Date: r.Rollup.Date} + di.SetDetail(key, details) + case rollupArray: + r.handleArrayType(key, details) + } +} + +func (r *RollupItem) handleArrayType(key string, details map[string]*types.Value) { + result := make([]string, 0) + for _, pr := range r.Rollup.Array { + tempDetails := make(map[string]*types.Value, 0) + object, err := getPropertyObject(pr) + if err != nil { + logger.With(zap.String("method", "RollupItem.SetDetail")).Error(err) + continue + } + if ds, ok := object.(DetailSetter); ok { + ds.SetDetail(key, tempDetails) + } + if _, ok := object.(*TitleItem); ok { + name := tempDetails[bundle.RelationKeyName.String()] + result = append(result, name.GetStringValue()) + } + if value, ok := tempDetails[key]; ok && value != nil { + switch value.GetKind().(type) { + case *types.Value_StringValue: + res := value.GetStringValue() + result = append(result, res) + case *types.Value_BoolValue: + res := value.GetBoolValue() + result = append(result, strconv.FormatBool(res)) + case *types.Value_NumberValue: + res := value.GetNumberValue() + result = append(result, strconv.FormatFloat(res, 'f', 0, 64)) + } + } + } + details[key] = pbtypes.StringList(result) +} func (r *RollupItem) GetPropertyType() ConfigType { return PropertyConfigTypeRollup } func (r *RollupItem) GetFormat() model.RelationFormat { + switch r.Rollup.Type { + case rollupNumber: + return model.RelationFormat_number + case rollupDate: + return model.RelationFormat_longtext + case rollupArray: + return model.RelationFormat_tag + } return model.RelationFormat_longtext } func (r *RollupItem) GetID() string { - return "" + return r.ID } diff --git a/core/block/import/notion/api/property/propertyobject.go b/core/block/import/notion/api/property/propertyobject.go index f6e0fada8..9bbf7c726 100644 --- a/core/block/import/notion/api/property/propertyobject.go +++ b/core/block/import/notion/api/property/propertyobject.go @@ -1,10 +1,40 @@ package property import ( + "bytes" + "context" "encoding/json" "fmt" + "io/ioutil" + "net/http" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/logging" ) +var logger = logging.Logger("notion-property-retriever") + +const endpoint = "/pages/%s/properties/%s" + +const endpointWithStartCursor = "/pages/%s/properties/%s?start_cursor=%s" + +type TitleObject struct { + Title api.RichText `json:"title"` +} + +type RichTextObject struct { + RichText api.RichText `json:"rich_text"` +} + +type RelationObject struct { + Relation Relation `json:"relation"` +} + +type PeopleObject struct { + People api.User `json:"people"` +} + type Properties map[string]Object func (p *Properties) UnmarshalJSON(data []byte) error { @@ -24,67 +54,196 @@ func (p *Properties) UnmarshalJSON(data []byte) error { func parsePropertyConfigs(raw map[string]interface{}) (Properties, error) { result := make(Properties) for k, v := range raw { - var p Object - switch rawProperty := v.(type) { - case map[string]interface{}: - switch ConfigType(rawProperty["type"].(string)) { - case PropertyConfigTypeTitle: - p = &TitleItem{} - case PropertyConfigTypeRichText: - p = &RichTextItem{} - case PropertyConfigTypeNumber: - p = &NumberItem{} - case PropertyConfigTypeSelect: - p = &SelectItem{} - case PropertyConfigTypeMultiSelect: - p = &MultiSelectItem{} - case PropertyConfigTypeDate: - p = &DateItem{} - case PropertyConfigTypePeople: - p = &PeopleItem{} - case PropertyConfigTypeFiles: - p = &FileItem{} - case PropertyConfigTypeCheckbox: - p = &CheckboxItem{} - case PropertyConfigTypeURL: - p = &UrlItem{} - case PropertyConfigTypeEmail: - p = &EmailItem{} - case PropertyConfigTypePhoneNumber: - p = &PhoneItem{} - case PropertyConfigTypeFormula: - p = &FormulaItem{} - case PropertyConfigTypeRelation: - p = &RelationItem{} - case PropertyConfigTypeRollup: - p = &RollupItem{} - case PropertyConfigCreatedTime: - p = &CreatedTimeItem{} - case PropertyConfigCreatedBy: - p = &CreatedByItem{} - case PropertyConfigLastEditedTime: - p = &LastEditedTimeItem{} - case PropertyConfigLastEditedBy: - p = &LastEditedByItem{} - case PropertyConfigStatus: - p = &StatusItem{} - default: - return nil, fmt.Errorf("unsupported property type: %s", rawProperty["type"].(string)) - } - b, err := json.Marshal(rawProperty) - if err != nil { - return nil, err - } - - if err = json.Unmarshal(b, &p); err != nil { - return nil, err - } - - result[k] = p - default: - return nil, fmt.Errorf("unsupported property format %T", v) + p, err := getPropertyObject(v) + if err != nil { + return nil, err } + result[k] = p } return result, nil } + +func getPropertyObject(v interface{}) (Object, error) { + var p Object + switch rawProperty := v.(type) { + case map[string]interface{}: + switch ConfigType(rawProperty["type"].(string)) { + case PropertyConfigTypeTitle: + p = &TitleItem{} + case PropertyConfigTypeRichText: + p = &RichTextItem{} + case PropertyConfigTypeNumber: + p = &NumberItem{} + case PropertyConfigTypeSelect: + p = &SelectItem{} + case PropertyConfigTypeMultiSelect: + p = &MultiSelectItem{} + case PropertyConfigTypeDate: + p = &DateItem{} + case PropertyConfigTypePeople: + p = &PeopleItem{} + case PropertyConfigTypeFiles: + p = &FileItem{} + case PropertyConfigTypeCheckbox: + p = &CheckboxItem{} + case PropertyConfigTypeURL: + p = &UrlItem{} + case PropertyConfigTypeEmail: + p = &EmailItem{} + case PropertyConfigTypePhoneNumber: + p = &PhoneItem{} + case PropertyConfigTypeFormula: + p = &FormulaItem{} + case PropertyConfigTypeRelation: + p = &RelationItem{} + case PropertyConfigTypeRollup: + p = &RollupItem{} + case PropertyConfigCreatedTime: + p = &CreatedTimeItem{} + case PropertyConfigCreatedBy: + p = &CreatedByItem{} + case PropertyConfigLastEditedTime: + p = &LastEditedTimeItem{} + case PropertyConfigLastEditedBy: + p = &LastEditedByItem{} + case PropertyConfigStatus: + p = &StatusItem{} + default: + return nil, fmt.Errorf("unsupported property type: %s", rawProperty["type"].(string)) + } + b, err := json.Marshal(rawProperty) + if err != nil { + return nil, err + } + + if err = json.Unmarshal(b, &p); err != nil { + return nil, err + } + + default: + return nil, fmt.Errorf("unsupported property format %T", v) + } + return p, nil +} + +type Service struct { + client *client.Client +} + +func New(client *client.Client) *Service { + return &Service{ + client: client, + } +} + +type propertyPaginatedRespone struct { + Object string `json:"object"` + ID string `json:"id"` + Type string `json:"type"` + Results []interface{} `json:"results"` + Item interface{} `json:"property_item"` + HasMore bool `json:"has_more"` + NextCursor string `json:"next_cursor"` +} + +// GetPropertyObject get from Notion properties values with tyoe People, Title, Relations and Rich text +// because they have pagination +func (s *Service) GetPropertyObject(ctx context.Context, + pageID, propertyID, apiKey string, + propertyType ConfigType) ([]interface{}, error) { + var ( + hasMore = true + body = &bytes.Buffer{} + startCursor string + response propertyPaginatedRespone + properties = make([]interface{}, 0) + ) + + for hasMore { + request := fmt.Sprintf(endpoint, pageID, propertyID) + if startCursor != "" { + request = fmt.Sprintf(endpointWithStartCursor, pageID, propertyID, startCursor) + } + req, err := s.client.PrepareRequest(ctx, apiKey, http.MethodGet, request, body) + + if err != nil { + return nil, fmt.Errorf("GetPropertyObject: %s", err) + } + res, err := s.client.HttpClient.Do(req) + + if err != nil { + return nil, fmt.Errorf("GetPropertyObject: %s", err) + } + defer res.Body.Close() + + b, err := ioutil.ReadAll(res.Body) + + if err != nil { + return nil, err + } + + if res.StatusCode != http.StatusOK { + notionErr := client.TransformHttpCodeToError(b) + if notionErr == nil { + return nil, fmt.Errorf("GetPropertyObject: failed http request, %d code", res.StatusCode) + } + return nil, notionErr + } + + err = json.Unmarshal(b, &response) + if err != nil { + continue + } + result := response.Results + for _, v := range result { + buffer, err := json.Marshal(v) + if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal: %s", err) + continue + } + if propertyType == PropertyConfigTypeTitle { + p := TitleObject{} + err = json.Unmarshal(buffer, &p) + if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal TitleItem: %s", err) + continue + } + properties = append(properties, &p.Title) + } + if propertyType == PropertyConfigTypeRichText { + p := RichTextObject{} + err = json.Unmarshal(buffer, &p) + if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal RichTextItem: %s", err) + continue + } + properties = append(properties, &p.RichText) + } + if propertyType == PropertyConfigTypeRelation { + p := RelationObject{} + err = json.Unmarshal(buffer, &p) + if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal RelationItem: %s", err) + continue + } + properties = append(properties, &p.Relation) + } + if propertyType == PropertyConfigTypePeople { + p := PeopleObject{} + err = json.Unmarshal(buffer, &p) + if err != nil { + logger.Errorf("GetPropertyObject: failed to marshal PeopleItem: %s", err) + continue + } + properties = append(properties, &p.People) + } + } + if response.HasMore { + startCursor = response.NextCursor + continue + } + hasMore = false + } + return properties, nil +} diff --git a/core/block/import/relationcreator.go b/core/block/import/relationcreator.go index 5b432cd23..4bdf9e896 100644 --- a/core/block/import/relationcreator.go +++ b/core/block/import/relationcreator.go @@ -7,7 +7,6 @@ import ( "github.com/gogo/protobuf/types" "github.com/anytypeio/go-anytype-middleware/core/block" - "github.com/anytypeio/go-anytype-middleware/core/block/editor" "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/core/session" "github.com/anytypeio/go-anytype-middleware/pb" @@ -18,18 +17,27 @@ import ( "github.com/anytypeio/go-anytype-middleware/util/pbtypes" ) +type relationIDFormat struct { + ID string + Format model.RelationFormat +} + +type relations []relationIDFormat + type RelationService struct { - core core.Service - service *block.Service - store filestore.FileStore + core core.Service + service *block.Service + createdRelations map[string]relations // need this field to avoid creation of the same relations + store filestore.FileStore } // NewRelationCreator constructor for RelationService func NewRelationCreator(service *block.Service, store filestore.FileStore, core core.Service) RelationCreator { return &RelationService{ - service: service, - core: core, - store: store, + service: service, + core: core, + createdRelations: make(map[string]relations, 0), + store: store, } } @@ -40,61 +48,87 @@ func (rc *RelationService) Create(ctx *session.Context, relations []*converter.Relation, pageID string) ([]string, map[string]*model.Block, error) { var ( - object *types.Struct - relationID string err error filesToDelete = make([]string, 0) oldRelationBlockToNew = make(map[string]*model.Block, 0) + createRequest = make([]*types.Struct, 0) + existedRelationsIDs = make([]string, 0) + setDetailsRequest = make([]*pb.RpcObjectSetDetailsDetail, 0) ) for _, r := range relations { - detail := &types.Struct{ - Fields: map[string]*types.Value{ - bundle.RelationKeyName.String(): pbtypes.String(r.Name), - bundle.RelationKeyRelationFormat.String(): pbtypes.Int64(int64(r.Format)), - bundle.RelationKeyType.String(): pbtypes.String(bundle.TypeKeyRelation.URL()), - bundle.RelationKeyLayout.String(): pbtypes.Float64(float64(model.ObjectType_relation)), - }, + var ( + relationID string + ) + if rel, ok := rc.createdRelations[r.Name]; ok { + for _, v := range rel { + if v.Format == r.Format { + relationID = v.ID + existedRelationsIDs = append(existedRelationsIDs, relationID) + break + } + } } - if _, object, err = rc.service.CreateSubObjectInWorkspace(detail, rc.core.PredefinedBlocks().Account); err != nil && err != editor.ErrSubObjectAlreadyExists { - log.Errorf("create relation %s", err) + if relationID == "" { + detail := &types.Struct{ + Fields: map[string]*types.Value{ + bundle.RelationKeyName.String(): pbtypes.String(r.Name), + bundle.RelationKeyRelationFormat.String(): pbtypes.Int64(int64(r.Format)), + bundle.RelationKeyType.String(): pbtypes.String(bundle.TypeKeyRelation.URL()), + bundle.RelationKeyLayout.String(): pbtypes.Float64(float64(model.ObjectType_relation)), + }, + } + createRequest = append(createRequest, detail) + } + } + var objects []*types.Struct + if _, objects, err = rc.service.CreateSubObjectsInWorkspace(createRequest); err != nil { + log.Errorf("create relation %s", err) + } + + ids := make([]string, 0, len(existedRelationsIDs)+len(objects)) + ids = append(ids, existedRelationsIDs...) + + for _, s := range objects { + name := pbtypes.GetString(s, bundle.RelationKeyName.String()) + id := pbtypes.GetString(s, bundle.RelationKeyRelationKey.String()) + format := model.RelationFormat(pbtypes.GetFloat64(s, bundle.RelationKeyRelationFormat.String())) + rc.createdRelations[name] = append(rc.createdRelations[name], relationIDFormat{ + ID: id, + Format: format, + }) + ids = append(ids, id) + } + + if err = rc.service.AddExtraRelations(ctx, pageID, ids); err != nil { + log.Errorf("add extra relation %s", err) + } + + for _, r := range relations { + var relationID string + if cr, ok := rc.createdRelations[r.Name]; ok { + for _, rel := range cr { + if rel.Format == r.Format { + relationID = rel.ID + } + } + } + if relationID == "" { continue } - - if object != nil && object.Fields != nil && object.Fields[bundle.RelationKeyRelationKey.String()] != nil { - relationID = object.Fields[bundle.RelationKeyRelationKey.String()].GetStringValue() - } else { - continue - } - - if err := rc.service.AddExtraRelations(ctx, pageID, []string{relationID}); err != nil { - log.Errorf("add extra relation %s", err) - continue - } - - if snapshot.Details != nil && snapshot.Details.Fields != nil && object != nil { + if snapshot.Details != nil && snapshot.Details.Fields != nil { if snapshot.Details.Fields[r.Name].GetListValue() != nil { rc.handleListValue(ctx, snapshot, r, relationID) } - if r.Format == model.RelationFormat_file { filesToDelete = append(filesToDelete, rc.handleFileRelation(ctx, snapshot, r.Name)...) } - details := make([]*pb.RpcObjectSetDetailsDetail, 0) - details = append(details, &pb.RpcObjectSetDetailsDetail{ - Key: relationID, - Value: snapshot.Details.Fields[r.Name], - }) - err = rc.service.SetDetails(ctx, pb.RpcObjectSetDetailsRequest{ - ContextId: pageID, - Details: details, - }) - if err != nil { - log.Errorf("set details %s", err) - continue - } } + setDetailsRequest = append(setDetailsRequest, &pb.RpcObjectSetDetailsDetail{ + Key: relationID, + Value: snapshot.Details.Fields[r.Name], + }) if r.BlockID != "" { original, new := rc.linkRelationsBlocks(snapshot, r.BlockID, relationID) if original != nil && new != nil { @@ -103,6 +137,14 @@ func (rc *RelationService) Create(ctx *session.Context, } } + err = rc.service.SetDetails(ctx, pb.RpcObjectSetDetailsRequest{ + ContextId: pageID, + Details: setDetailsRequest, + }) + if err != nil { + log.Errorf("set details %s", err) + } + if ftd, err := rc.handleCoverRelation(ctx, snapshot, pageID); err != nil { log.Errorf("failed to upload cover image %s", err) } else { From fecc62087339c7f4421a21c9b9fd4b7f311fef44 Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Mon, 19 Dec 2022 11:47:02 +0300 Subject: [PATCH 22/68] PROD-344: fix linter Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/markdown/import.go | 3 +- core/block/import/notion/api/block/block.go | 66 +- .../block/import/notion/api/block/retrieve.go | 607 +++++++++--------- .../import/notion/api/block/text_test.go | 18 +- .../import/notion/api/block/textobject.go | 15 +- core/block/import/notion/api/client/client.go | 16 +- core/block/import/notion/api/client/error.go | 4 +- core/block/import/notion/api/commonobjects.go | 2 +- .../import/notion/api/database/database.go | 3 +- core/block/import/notion/api/page/page.go | 20 +- .../block/import/notion/api/page/page_test.go | 2 +- .../notion/api/property/propertyitem.go | 22 +- .../notion/api/property/propertyobject.go | 6 +- core/block/import/notion/api/search/search.go | 8 +- core/block/import/notion/converter.go | 45 +- core/block/import/objectcreator.go | 14 +- core/block/import/pb/converter.go | 3 +- core/block/import/relationcreator.go | 12 +- core/block/import/syncer/icon.go | 4 +- core/block/import/web/converter.go | 3 +- 20 files changed, 443 insertions(+), 430 deletions(-) diff --git a/core/block/import/markdown/import.go b/core/block/import/markdown/import.go index fd38b2d63..d4760bb2f 100644 --- a/core/block/import/markdown/import.go +++ b/core/block/import/markdown/import.go @@ -67,7 +67,8 @@ func (m *Markdown) GetImage() ([]byte, int64, int64, error) { return nil, 0, 0, nil } -func (m *Markdown) GetSnapshots(req *pb.RpcObjectImportRequest, progress *process.Progress) (*converter.Response, converter.ConvertError) { +func (m *Markdown) GetSnapshots(req *pb.RpcObjectImportRequest, + progress *process.Progress) (*converter.Response, converter.ConvertError) { path := m.GetParams(req) files, allErrors := m.blockConverter.MarkdownToBlocks(path, req.GetMode().String()) diff --git a/core/block/import/notion/api/block/block.go b/core/block/import/notion/api/block/block.go index ed18547d4..2e837b61c 100644 --- a/core/block/import/notion/api/block/block.go +++ b/core/block/import/notion/api/block/block.go @@ -7,40 +7,40 @@ import ( "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" ) -type BlockType string +type Type string const ( - Paragraph BlockType = "paragraph" - BulletList BlockType = "bulleted_list_item" - NumberList BlockType = "numbered_list_item" - Toggle BlockType = "toggle" - SyncedBlock BlockType = "synced_block" - Template BlockType = "template" - Column BlockType = "column" - ChildPage BlockType = "child_page" - ChildDatabase BlockType = "child_database" - Table BlockType = "table" - Heading1 BlockType = "heading_1" - Heading2 BlockType = "heading_2" - Heading3 BlockType = "heading_3" - ToDo BlockType = "to_do" - Embed BlockType = "embed" - Image BlockType = "image" - Video BlockType = "video" - File BlockType = "file" - Pdf BlockType = "pdf" - Bookmark BlockType = "bookmark" - Callout BlockType = "callout" - Quote BlockType = "quote" - Equation BlockType = "equation" - Divider BlockType = "divider" - TableOfContents BlockType = "table_of_contents" - ColumnList BlockType = "column_list" - LinkPreview BlockType = "link_preview" - LinkToPage BlockType = "link_to_page" - TableRow BlockType = "table_row" - Code BlockType = "code" - Unsupported BlockType = "unsupported" + Paragraph Type = "paragraph" + BulletList Type = "bulleted_list_item" + NumberList Type = "numbered_list_item" + Toggle Type = "toggle" + SyncedBlock Type = "synced_block" + Template Type = "template" + Column Type = "column" + ChildPage Type = "child_page" + ChildDatabase Type = "child_database" + Table Type = "table" + Heading1 Type = "heading_1" + Heading2 Type = "heading_2" + Heading3 Type = "heading_3" + ToDo Type = "to_do" + Embed Type = "embed" + Image Type = "image" + Video Type = "video" + File Type = "file" + Pdf Type = "pdf" + Bookmark Type = "bookmark" + Callout Type = "callout" + Quote Type = "quote" + Equation Type = "equation" + Divider Type = "divider" + TableOfContents Type = "table_of_contents" + ColumnList Type = "column_list" + LinkPreview Type = "link_preview" + LinkToPage Type = "link_to_page" + TableRow Type = "table_row" + Code Type = "code" + Unsupported Type = "unsupported" ) type Block struct { @@ -53,7 +53,7 @@ type Block struct { Parent api.Parent `json:"parent"` Archived bool `json:"archived"` HasChildren bool `json:"has_children"` - Type BlockType `json:"type"` + Type Type `json:"type"` } type Identifiable interface { diff --git a/core/block/import/notion/api/block/retrieve.go b/core/block/import/notion/api/block/retrieve.go index 300d0816e..e0c48fa64 100644 --- a/core/block/import/notion/api/block/retrieve.go +++ b/core/block/import/notion/api/block/retrieve.go @@ -84,52 +84,12 @@ func (s *Service) MapNotionBlocksToAnytype(req *MapRequest) *MapResponse { func (s *Service) getBlocks(ctx context.Context, pageID, apiKey string, pagination int64) ([]interface{}, error) { var ( hasMore = true - body = &bytes.Buffer{} blocks = make([]interface{}, 0) cursor string ) for hasMore { - url := fmt.Sprintf(endpoint, pageID) - - req, err := s.client.PrepareRequest(ctx, apiKey, http.MethodGet, url, body) - - if err != nil { - return nil, fmt.Errorf("GetBlocks: %s", err) - } - query := req.URL.Query() - - if cursor != "" { - query.Add(startCursor, cursor) - } - - query.Add(pageSize, strconv.FormatInt(pagination, 10)) - - req.URL.RawQuery = query.Encode() - - res, err := s.client.HttpClient.Do(req) - - if err != nil { - return nil, fmt.Errorf("GetBlocks: %s", err) - } - defer res.Body.Close() - - b, err := ioutil.ReadAll(res.Body) - - if err != nil { - return nil, err - } - var objects Response - if res.StatusCode != http.StatusOK { - notionErr := client.TransformHttpCodeToError(b) - if notionErr == nil { - return nil, fmt.Errorf("GetBlocks: failed http request, %d code", res.StatusCode) - } - return nil, notionErr - } - - err = json.Unmarshal(b, &objects) - + objects, err := s.getBlocksResponse(ctx, pageID, apiKey, cursor, pagination) if err != nil { return nil, err } @@ -141,278 +101,7 @@ func (s *Service) getBlocks(ctx context.Context, pageID, apiKey string, paginati continue } blockMap := b.(map[string]interface{}) - switch BlockType(blockMap["type"].(string)) { - case Paragraph: - var p ParagraphBlock - err = json.Unmarshal(buffer, &p) - - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - - blocks = append(blocks, &p) - case Heading1: - var h Heading1Block - err = json.Unmarshal(buffer, &h) - - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - - blocks = append(blocks, &h) - case Heading2: - var h Heading2Block - err = json.Unmarshal(buffer, &h) - - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - - blocks = append(blocks, &h) - case Heading3: - var h Heading3Block - err = json.Unmarshal(buffer, &h) - - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - - blocks = append(blocks, &h) - case Callout: - var c CalloutBlock - err = json.Unmarshal(buffer, &c) - - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - - blocks = append(blocks, &c) - case Quote: - var q QuoteBlock - err = json.Unmarshal(buffer, &q) - - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - - blocks = append(blocks, &q) - case BulletList: - var list BulletedListBlock - err = json.Unmarshal(buffer, &list) - - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - - blocks = append(blocks, &list) - case NumberList: - var nl NumberedListBlock - err = json.Unmarshal(buffer, &nl) - - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - - blocks = append(blocks, &nl) - case Toggle: - var t ToggleBlock - err = json.Unmarshal(buffer, &t) - - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - - blocks = append(blocks, &t) - case Code: - var c CodeBlock - err = json.Unmarshal(buffer, &c) - - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - - blocks = append(blocks, &c) - case Equation: - var e EquationBlock - err = json.Unmarshal(buffer, &e) - - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - - blocks = append(blocks, &e) - case ToDo: - var t ToDoBlock - err = json.Unmarshal(buffer, &t) - - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - - blocks = append(blocks, &t) - case File: - var f FileBlock - err = json.Unmarshal(buffer, &f) - - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - - blocks = append(blocks, &f) - case Image: - var i ImageBlock - err = json.Unmarshal(buffer, &i) - - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - - blocks = append(blocks, &i) - case Video: - var v VideoBlock - err = json.Unmarshal(buffer, &v) - - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - - blocks = append(blocks, &v) - case Pdf: - var p PdfBlock - err = json.Unmarshal(buffer, &p) - - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - - blocks = append(blocks, &p) - case Bookmark: - var b BookmarkBlock - err = json.Unmarshal(buffer, &b) - - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - - blocks = append(blocks, &b) - case Divider: - var d DividerBlock - err = json.Unmarshal(buffer, &d) - - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - - blocks = append(blocks, &d) - case TableOfContents: - var t TableOfContentsBlock - err = json.Unmarshal(buffer, &t) - - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - - blocks = append(blocks, &t) - case Embed: - var e EmbedBlock - err = json.Unmarshal(buffer, &e) - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - blocks = append(blocks, &e) - case LinkPreview: - var lp LinkPreviewBlock - err = json.Unmarshal(buffer, &lp) - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - blocks = append(blocks, &lp) - case ChildDatabase: - var c ChildDatabaseBlock - err = json.Unmarshal(buffer, &c) - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - blocks = append(blocks, &c) - case ChildPage: - var c ChildPageBlock - err = json.Unmarshal(buffer, &c) - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - blocks = append(blocks, &c) - case LinkToPage: - var l LinkToPageBlock - err = json.Unmarshal(buffer, &l) - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - blocks = append(blocks, &l) - case Unsupported, Template, SyncedBlock: - var u UnsupportedBlock - err = json.Unmarshal(buffer, &u) - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - blocks = append(blocks, &u) - case Table: - var t TableBlock - err = json.Unmarshal(buffer, &t) - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - blocks = append(blocks, &t) - case TableRow: - var t TableRowBlock - err = json.Unmarshal(buffer, &t) - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - blocks = append(blocks, &t) - case ColumnList: - var cl ColumnListBlock - err = json.Unmarshal(buffer, &cl) - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - blocks = append(blocks, &cl) - case Column: - var cb ColumnBlock - err = json.Unmarshal(buffer, &cb) - if err != nil { - logger.With(zap.String("method", "getBlocks")).Error(err) - continue - } - blocks = append(blocks, &cb) - } + blocks = append(blocks, s.fillBlocks(Type(blockMap["type"].(string)), buffer)...) } if !objects.HasMore { @@ -425,3 +114,295 @@ func (s *Service) getBlocks(ctx context.Context, pageID, apiKey string, paginati } return blocks, nil } + +// (to avoid error with many statements) +//nolint:funlen +func (*Service) fillBlocks(blockType Type, buffer []byte) []interface{} { + blocks := make([]interface{}, 0) + switch blockType { + case Paragraph: + var p ParagraphBlock + err := json.Unmarshal(buffer, &p) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &p) + case Heading1: + var h Heading1Block + err := json.Unmarshal(buffer, &h) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &h) + case Heading2: + var h Heading2Block + err := json.Unmarshal(buffer, &h) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &h) + case Heading3: + var h Heading3Block + err := json.Unmarshal(buffer, &h) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &h) + case Callout: + var c CalloutBlock + err := json.Unmarshal(buffer, &c) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &c) + case Quote: + var q QuoteBlock + err := json.Unmarshal(buffer, &q) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &q) + case BulletList: + var list BulletedListBlock + err := json.Unmarshal(buffer, &list) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &list) + case NumberList: + var nl NumberedListBlock + err := json.Unmarshal(buffer, &nl) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &nl) + case Toggle: + var t ToggleBlock + err := json.Unmarshal(buffer, &t) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &t) + case Code: + var c CodeBlock + err := json.Unmarshal(buffer, &c) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &c) + case Equation: + var e EquationBlock + err := json.Unmarshal(buffer, &e) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &e) + case ToDo: + var t ToDoBlock + err := json.Unmarshal(buffer, &t) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &t) + case File: + var f FileBlock + err := json.Unmarshal(buffer, &f) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &f) + case Image: + var i ImageBlock + err := json.Unmarshal(buffer, &i) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &i) + case Video: + var v VideoBlock + err := json.Unmarshal(buffer, &v) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &v) + case Pdf: + var p PdfBlock + err := json.Unmarshal(buffer, &p) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &p) + case Bookmark: + var b BookmarkBlock + err := json.Unmarshal(buffer, &b) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &b) + case Divider: + var d DividerBlock + err := json.Unmarshal(buffer, &d) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &d) + case TableOfContents: + var t TableOfContentsBlock + err := json.Unmarshal(buffer, &t) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &t) + case Embed: + var e EmbedBlock + err := json.Unmarshal(buffer, &e) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &e) + case LinkPreview: + var lp LinkPreviewBlock + err := json.Unmarshal(buffer, &lp) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &lp) + case ChildDatabase: + var c ChildDatabaseBlock + err := json.Unmarshal(buffer, &c) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &c) + case ChildPage: + var c ChildPageBlock + err := json.Unmarshal(buffer, &c) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &c) + case LinkToPage: + var l LinkToPageBlock + err := json.Unmarshal(buffer, &l) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &l) + case Unsupported, Template, SyncedBlock: + var u UnsupportedBlock + err := json.Unmarshal(buffer, &u) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &u) + case Table: + var t TableBlock + err := json.Unmarshal(buffer, &t) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &t) + case TableRow: + var t TableRowBlock + err := json.Unmarshal(buffer, &t) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &t) + case ColumnList: + var cl ColumnListBlock + err := json.Unmarshal(buffer, &cl) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &cl) + case Column: + var cb ColumnBlock + err := json.Unmarshal(buffer, &cb) + if err != nil { + logger.With(zap.String("method", "getBlocks")).Error(err) + return blocks + } + blocks = append(blocks, &cb) + } + return blocks +} + +func (s *Service) getBlocksResponse(ctx context.Context, + pageID, apiKey, cursor string, + pagination int64) (Response, error) { + body := &bytes.Buffer{} + + url := fmt.Sprintf(endpoint, pageID) + + req, err := s.client.PrepareRequest(ctx, apiKey, http.MethodGet, url, body) + + if err != nil { + return Response{}, fmt.Errorf("GetBlocks: %s", err) + } + query := req.URL.Query() + + if cursor != "" { + query.Add(startCursor, cursor) + } + + query.Add(pageSize, strconv.FormatInt(pagination, 10)) + + req.URL.RawQuery = query.Encode() + + res, err := s.client.HTTPClient.Do(req) + + if err != nil { + return Response{}, fmt.Errorf("GetBlocks: %s", err) + } + defer res.Body.Close() + + b, err := ioutil.ReadAll(res.Body) + + if err != nil { + return Response{}, err + } + var objects Response + if res.StatusCode != http.StatusOK { + notionErr := client.TransformHTTPCodeToError(b) + if notionErr == nil { + return Response{}, fmt.Errorf("GetBlocks: failed http request, %d code", res.StatusCode) + } + return Response{}, notionErr + } + + err = json.Unmarshal(b, &objects) + + if err != nil { + return Response{}, err + } + return objects, nil +} diff --git a/core/block/import/notion/api/block/text_test.go b/core/block/import/notion/api/block/text_test.go index d5f548e08..f6bf7eb78 100644 --- a/core/block/import/notion/api/block/text_test.go +++ b/core/block/import/notion/api/block/text_test.go @@ -13,15 +13,15 @@ func Test_GetTextBlocksTextSuccess(t *testing.T) { to := &TextObject{ RichText: []api.RichText{ { - Type: api.Text, + Type: api.Text, PlainText: "test", }, { - Type: api.Text, + Type: api.Text, PlainText: "test2", }, }, - Color: api.RedBackGround, + Color: api.RedBackGround, } bl := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, &MapRequest{}) @@ -39,8 +39,8 @@ func Test_GetTextBlocksTextUserMention(t *testing.T) { Mention: &api.MentionObject{ Type: api.UserMention, User: &api.User{ - ID: "id", - Name: "Nastya", + ID: "id", + Name: "Nastya", }, }, PlainText: "Nastya", @@ -136,7 +136,7 @@ func Test_GetTextBlocksLinkPreview(t *testing.T) { Mention: &api.MentionObject{ Type: api.LinkPreview, LinkPreview: &api.Link{ - Url: "ref", + URL: "ref", }, }, }, @@ -171,11 +171,11 @@ func Test_GetTextBlocksEquation(t *testing.T) { } func Test_GetCodeBlocksSuccess(t *testing.T) { - co := &CodeBlock{ + co := &CodeBlock{ Code: CodeObject{ RichText: []api.RichText{ { - Type: api.Text, + Type: api.Text, PlainText: "Code", }, }, @@ -186,4 +186,4 @@ func Test_GetCodeBlocksSuccess(t *testing.T) { assert.NotNil(t, bl) assert.Len(t, bl.Blocks, 1) assert.Equal(t, bl.Blocks[0].GetText().Text, "Code") -} \ No newline at end of file +} diff --git a/core/block/import/notion/api/block/textobject.go b/core/block/import/notion/api/block/textobject.go index 34259c141..1773c2323 100644 --- a/core/block/import/notion/api/block/textobject.go +++ b/core/block/import/notion/api/block/textobject.go @@ -109,14 +109,14 @@ func (t *TextObject) handleTextType(rt api.RichText, notionDatabaseIdsToAnytype map[string]string) []*model.BlockContentTextMark { marks := []*model.BlockContentTextMark{} from := textUtil.UTF16RuneCountString(text.String()) - if rt.Text != nil && rt.Text.Link != nil && rt.Text.Link.Url != "" { + if rt.Text != nil && rt.Text.Link != nil && rt.Text.Link.URL != "" { text.WriteString(rt.Text.Content) } else { text.WriteString(rt.PlainText) } to := textUtil.UTF16RuneCountString(text.String()) - if rt.Text != nil && rt.Text.Link != nil && rt.Text.Link.Url != "" { - url := strings.Trim(rt.Text.Link.Url, "/") + if rt.Text != nil && rt.Text.Link != nil && rt.Text.Link.URL != "" { + url := strings.Trim(rt.Text.Link.URL, "/") if databaseID, ok := notionDatabaseIdsToAnytype[url]; ok { url = databaseID } @@ -136,7 +136,9 @@ func (t *TextObject) handleTextType(rt api.RichText, return marks } -func (t *TextObject) handleMentionType(rt api.RichText, text *strings.Builder, req *MapRequest) []*model.BlockContentTextMark { +func (t *TextObject) handleMentionType(rt api.RichText, + text *strings.Builder, + req *MapRequest) []*model.BlockContentTextMark { if rt.Mention.Type == api.UserMention { return t.handleUserMention(rt, text) } @@ -201,7 +203,8 @@ func (t *TextObject) handlePageMention(rt api.RichText, return marks } -func (t *TextObject) handleDateMention(rt api.RichText, text *strings.Builder) (*model.Block, *converter.Relation, map[string]*types.Value, string) { +func (t *TextObject) handleDateMention(rt api.RichText, + text *strings.Builder) (*model.Block, *converter.Relation, map[string]*types.Value, string) { var textDate string if rt.Mention.Date.Start != "" { textDate = rt.Mention.Date.Start @@ -232,7 +235,7 @@ func (t *TextObject) handleDateMention(rt api.RichText, text *strings.Builder) ( func (t *TextObject) handleLinkPreviewMention(rt api.RichText, text *strings.Builder) []*model.BlockContentTextMark { from := textUtil.UTF16RuneCountString(text.String()) - text.WriteString(rt.Mention.LinkPreview.Url) + text.WriteString(rt.Mention.LinkPreview.URL) to := textUtil.UTF16RuneCountString(text.String()) marks := rt.BuildMarkdownFromAnnotations(int32(from), int32(to)) marks = append(marks, &model.BlockContentTextMark{ diff --git a/core/block/import/notion/api/client/client.go b/core/block/import/notion/api/client/client.go index 00d5065bf..fda78e2ac 100644 --- a/core/block/import/notion/api/client/client.go +++ b/core/block/import/notion/api/client/client.go @@ -9,28 +9,30 @@ import ( ) const ( - notionUrl = "https://api.notion.com/v1" + notionURL = "https://api.notion.com/v1" apiVersion = "2022-06-28" ) type Client struct { - HttpClient *http.Client + HTTPClient *http.Client BasePath string } // NewClient is a constructor for Client func NewClient() *Client { c := &Client{ - HttpClient: &http.Client{Timeout: time.Minute}, - BasePath: notionUrl, + HTTPClient: &http.Client{Timeout: time.Minute}, + BasePath: notionURL, } return c } // PrepareRequest create http.Request based on given method, url and body -func (c *Client) PrepareRequest(ctx context.Context, apiKey, method, url string, body *bytes.Buffer) (*http.Request, error) { - resultUrl := c.BasePath + url - req, err := http.NewRequestWithContext(ctx, method, resultUrl, body) +func (c *Client) PrepareRequest(ctx context.Context, + apiKey, method, url string, + body *bytes.Buffer) (*http.Request, error) { + resultURL := c.BasePath + url + req, err := http.NewRequestWithContext(ctx, method, resultURL, body) if err != nil { return nil, err } diff --git a/core/block/import/notion/api/client/error.go b/core/block/import/notion/api/client/error.go index 97ae5f0eb..e1c8241f7 100644 --- a/core/block/import/notion/api/client/error.go +++ b/core/block/import/notion/api/client/error.go @@ -13,8 +13,8 @@ type NotionErrorResponse struct { Message string `json:"message,omitempty"` } -//TransformHttpCodeToError reads error response and transofrm it to NotionErrorResponse and creates error based on NotionErrorResponse -func TransformHttpCodeToError(response []byte) error { +// and creates error based on NotionErrorResponse +func TransformHTTPCodeToError(response []byte) error { var notionErr NotionErrorResponse if err := json.Unmarshal(response, ¬ionErr); err != nil { logging.Logger("client").Error("failed to parse error response from notion %s", err) diff --git a/core/block/import/notion/api/commonobjects.go b/core/block/import/notion/api/commonobjects.go index 17a5ee5df..d2b396ff8 100644 --- a/core/block/import/notion/api/commonobjects.go +++ b/core/block/import/notion/api/commonobjects.go @@ -52,7 +52,7 @@ func (e *EquationObject) HandleEquation() *model.Block { } type Link struct { - Url string `json:"url,omitempty"` + URL string `json:"url,omitempty"` } func (rt *RichText) BuildMarkdownFromAnnotations(from, to int32) []*model.BlockContentTextMark { diff --git a/core/block/import/notion/api/database/database.go b/core/block/import/notion/api/database/database.go index 0ed969f41..eb62ede3d 100644 --- a/core/block/import/notion/api/database/database.go +++ b/core/block/import/notion/api/database/database.go @@ -74,9 +74,8 @@ func (ds *Service) GetDatabase(ctx context.Context, convereterError.Add(d.ID, err) if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { return nil, nil, nil, convereterError - } else { - continue } + continue } snapshot := ds.transformDatabase(d) diff --git a/core/block/import/notion/api/page/page.go b/core/block/import/notion/api/page/page.go index 78e2de6e8..bb96e75be 100644 --- a/core/block/import/notion/api/page/page.go +++ b/core/block/import/notion/api/page/page.go @@ -89,9 +89,8 @@ func (ds *Service) GetPages(ctx context.Context, convereterError.Add(p.ID, err) if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { return nil, nil, convereterError - } else { - continue } + continue } notionPagesIdsToAnytype[p.ID] = tid.String() } @@ -131,9 +130,8 @@ func (ds *Service) GetPages(ctx context.Context, convereterError.Merge(ce) if mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { return nil, nil, convereterError - } else { - continue } + continue } pageID := notionPagesIdsToAnytype[p.ID] allSnapshots = append(allSnapshots, &converter.Snapshot{ @@ -187,7 +185,8 @@ func (ds *Service) transformPages(ctx context.Context, return snapshot, relations, nil } -// handlePageProperties gets properties values by their ids from notion api and transforms them to Details and RelationLinks +// handlePageProperties gets properties values by their ids from notion api +// and transforms them to Details and RelationLinks func (ds *Service) handlePageProperties(ctx context.Context, apiKey, pageID string, p property.Properties, @@ -211,7 +210,8 @@ func (ds *Service) handlePageProperties(ctx context.Context, ok bool ) if ds, ok = v.(property.DetailSetter); !ok { - logger.With("method", "handlePageProperties").Errorf("failed to convert to interface DetailSetter, %s", v.GetPropertyType()) + logger.With("method", "handlePageProperties"). + Errorf("failed to convert to interface DetailSetter, %s", v.GetPropertyType()) continue } ds.SetDetail(k, d) @@ -246,9 +246,11 @@ func (*Service) handlePaginatedProperty(v property.Object, properties []interfac } } -// linkRelationsIDWithAnytypeID take anytype ID based on page/database ID from Notin. In property we get id from Notion, so we somehow need to -// map this ID with anytype for correct Relation. We use two maps notionPagesIdsToAnytype, notionDatabaseIdsToAnytype for this -func linkRelationsIDWithAnytypeID(rel *property.RelationItem, notionPagesIdsToAnytype, notionDatabaseIdsToAnytype map[string]string) { +// linkRelationsIDWithAnytypeID take anytype ID based on page/database ID from Notin. +// In property we get id from Notion, so we somehow need to map this ID with anytype for correct Relation. +// We use two maps notionPagesIdsToAnytype, notionDatabaseIdsToAnytype for this +func linkRelationsIDWithAnytypeID(rel *property.RelationItem, + notionPagesIdsToAnytype, notionDatabaseIdsToAnytype map[string]string) { for _, r := range rel.Relation { if anytypeID, ok := notionPagesIdsToAnytype[r.ID]; ok { r.ID = anytypeID diff --git a/core/block/import/notion/api/page/page_test.go b/core/block/import/notion/api/page/page_test.go index 414c2ea00..a80e95df2 100644 --- a/core/block/import/notion/api/page/page_test.go +++ b/core/block/import/notion/api/page/page_test.go @@ -46,7 +46,7 @@ func Test_handlePagePropertiesLastEditedTime(t *testing.T) { p := property.LastEditedTimeItem{ ID: "id", Type: string(property.PropertyConfigLastEditedTime), - LastEditedTime: "2022-12-07", + LastEditedTime: "2022-10-24T22:56:00.000Z", } pr := property.Properties{"LastEditedTime": &p} _ = ps.handlePageProperties(context.TODO(), "key", "id", pr, details, &block.MapRequest{}) diff --git a/core/block/import/notion/api/property/propertyitem.go b/core/block/import/notion/api/property/propertyitem.go index 1b6d83bbb..534737383 100644 --- a/core/block/import/notion/api/property/propertyitem.go +++ b/core/block/import/notion/api/property/propertyitem.go @@ -390,28 +390,28 @@ func (c *CheckboxItem) GetFormat() model.RelationFormat { return model.RelationFormat_checkbox } -type UrlItem struct { +type URLItem struct { Object string `json:"object"` ID string `json:"id"` Type string `json:"type"` URL *string `json:"url"` } -func (u *UrlItem) SetDetail(key string, details map[string]*types.Value) { +func (u *URLItem) SetDetail(key string, details map[string]*types.Value) { if u.URL != nil { details[key] = pbtypes.String(*u.URL) } } -func (u *UrlItem) GetPropertyType() ConfigType { +func (u *URLItem) GetPropertyType() ConfigType { return PropertyConfigTypeURL } -func (u *UrlItem) GetID() string { +func (u *URLItem) GetID() string { return u.ID } -func (u *UrlItem) GetFormat() model.RelationFormat { +func (u *URLItem) GetFormat() model.RelationFormat { return model.RelationFormat_url } @@ -473,7 +473,11 @@ type CreatedTimeItem struct { } func (ct *CreatedTimeItem) SetDetail(key string, details map[string]*types.Value) { - t, _ := time.Parse(time.RFC3339, ct.CreatedTime) + t, err := time.Parse(time.RFC3339, ct.CreatedTime) + if err != nil { + logger.With(zap.String("method", "SetDetail")).Errorf("failed to parse time %v", err) + return + } details[key] = pbtypes.Int64(t.Unix()) } @@ -520,7 +524,11 @@ type LastEditedTimeItem struct { } func (le *LastEditedTimeItem) SetDetail(key string, details map[string]*types.Value) { - t, _ := time.Parse(time.RFC3339, le.LastEditedTime) + t, err := time.Parse(time.RFC3339, le.LastEditedTime) + if err != nil { + logger.With(zap.String("method", "SetDetail")).Errorf("failed to parse time %v", err) + return + } details[key] = pbtypes.Int64(t.Unix()) } diff --git a/core/block/import/notion/api/property/propertyobject.go b/core/block/import/notion/api/property/propertyobject.go index 9bbf7c726..d0c1693c8 100644 --- a/core/block/import/notion/api/property/propertyobject.go +++ b/core/block/import/notion/api/property/propertyobject.go @@ -88,7 +88,7 @@ func getPropertyObject(v interface{}) (Object, error) { case PropertyConfigTypeCheckbox: p = &CheckboxItem{} case PropertyConfigTypeURL: - p = &UrlItem{} + p = &URLItem{} case PropertyConfigTypeEmail: p = &EmailItem{} case PropertyConfigTypePhoneNumber: @@ -170,7 +170,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, if err != nil { return nil, fmt.Errorf("GetPropertyObject: %s", err) } - res, err := s.client.HttpClient.Do(req) + res, err := s.client.HTTPClient.Do(req) if err != nil { return nil, fmt.Errorf("GetPropertyObject: %s", err) @@ -184,7 +184,7 @@ func (s *Service) GetPropertyObject(ctx context.Context, } if res.StatusCode != http.StatusOK { - notionErr := client.TransformHttpCodeToError(b) + notionErr := client.TransformHTTPCodeToError(b) if notionErr == nil { return nil, fmt.Errorf("GetPropertyObject: failed http request, %d code", res.StatusCode) } diff --git a/core/block/import/notion/api/search/search.go b/core/block/import/notion/api/search/search.go index 9b74f02d3..381a2d15b 100644 --- a/core/block/import/notion/api/search/search.go +++ b/core/block/import/notion/api/search/search.go @@ -25,7 +25,7 @@ type Service struct { client *client.Client } -type SearchResponse struct { +type Response struct { Results []interface{} `json:"results"` HasMore bool `json:"has_more"` NextCursor *string `json:"next_cursor"` @@ -86,7 +86,7 @@ func (s *Service) Search(ctx context.Context, apiKey string, pageSize int64) ([] if err != nil { return nil, nil, fmt.Errorf("ListDatabases: %s", err) } - res, err := s.client.HttpClient.Do(req) + res, err := s.client.HTTPClient.Do(req) if err != nil { return nil, nil, fmt.Errorf("ListDatabases: %s", err) @@ -98,9 +98,9 @@ func (s *Service) Search(ctx context.Context, apiKey string, pageSize int64) ([] if err != nil { return nil, nil, err } - var objects SearchResponse + var objects Response if res.StatusCode != http.StatusOK { - notionErr := client.TransformHttpCodeToError(b) + notionErr := client.TransformHTTPCodeToError(b) if notionErr == nil { return nil, nil, fmt.Errorf("failed http request, %d code", res.StatusCode) } diff --git a/core/block/import/notion/converter.go b/core/block/import/notion/converter.go index cc8500008..d97b8c6a3 100644 --- a/core/block/import/notion/converter.go +++ b/core/block/import/notion/converter.go @@ -30,61 +30,62 @@ func init() { } type Notion struct { - search *search.Service - databaseService *database.Service - pageService *page.Service + search *search.Service + dbService *database.Service + pgService *page.Service } func New(core.Service) converter.Converter { cl := client.NewClient() return &Notion{ - search: search.New(cl), - databaseService: database.New(), - pageService: page.New(cl), + search: search.New(cl), + dbService: database.New(), + pgService: page.New(cl), } } -func (n *Notion) GetSnapshots(req *pb.RpcObjectImportRequest, progress *process.Progress) (*converter.Response, converter.ConvertError) { +func (n *Notion) GetSnapshots(req *pb.RpcObjectImportRequest, + progress *process.Progress) (*converter.Response, converter.ConvertError) { ce := converter.NewError() apiKey := n.getParams(req) if apiKey == "" { ce.Add("apiKey", fmt.Errorf("failed to extract apikey")) return nil, ce } - databases, pages, err := search.Retry(n.search.Search, retryAmount, retryDelay)(context.TODO(), apiKey, pageSize) + db, pages, err := search.Retry(n.search.Search, retryAmount, retryDelay)(context.TODO(), apiKey, pageSize) if err != nil { ce.Add("/search", fmt.Errorf("failed to get pages and databases %s", err)) return nil, ce } - progress.SetTotal(int64(len(databases)*numberOfStepsForDatabases + len(pages)*numberOfStepsForPages)) - databasesSnapshots, notionIdsToAnytype, databaseNameToID, dbErr := n.databaseService.GetDatabase(context.TODO(), req.Mode, databases, progress) + progress.SetTotal(int64(len(db)*numberOfStepsForDatabases + len(pages)*numberOfStepsForPages)) + dbSnapshots, notionIdsToAnytype, dbNameToID, dbErr := n.dbService.GetDatabase(context.TODO(), req.Mode, db, progress) if dbErr != nil && req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { ce.Merge(dbErr) return nil, ce } - request := &block.MapRequest{ + r := &block.MapRequest{ NotionDatabaseIdsToAnytype: notionIdsToAnytype, - DatabaseNameToID: databaseNameToID, + DatabaseNameToID: dbNameToID, } - pagesSnapshots, notionPageIdsToAnytype, pageErr := n.pageService.GetPages(context.TODO(), apiKey, req.Mode, pages, request, progress) - if pageErr != nil && req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { - ce.Merge(pageErr) + pgSnapshots, notionPageIDToAnytype, pgErr := n.pgService.GetPages(context.TODO(), apiKey, req.Mode, pages, r, progress) + if pgErr != nil && req.Mode == pb.RpcObjectImportRequest_ALL_OR_NOTHING { + ce.Merge(pgErr) return nil, ce } - page.SetPageLinksInDatabase(databasesSnapshots, pages, databases, notionPageIdsToAnytype, notionIdsToAnytype) + page.SetPageLinksInDatabase(dbSnapshots, pages, db, notionPageIDToAnytype, notionIdsToAnytype) - allSnaphots := make([]*converter.Snapshot, 0, len(pagesSnapshots.Snapshots)+len(databasesSnapshots.Snapshots)) - allSnaphots = append(allSnaphots, pagesSnapshots.Snapshots...) - allSnaphots = append(allSnaphots, databasesSnapshots.Snapshots...) - relations := mergeMaps(databasesSnapshots.Relations, pagesSnapshots.Relations) + allSnaphots := make([]*converter.Snapshot, 0, len(pgSnapshots.Snapshots)+len(dbSnapshots.Snapshots)) + allSnaphots = append(allSnaphots, pgSnapshots.Snapshots...) + allSnaphots = append(allSnaphots, dbSnapshots.Snapshots...) + relations := mergeMaps(dbSnapshots.Relations, pgSnapshots.Relations) - if pageErr != nil { - ce.Merge(pageErr) + if pgErr != nil { + ce.Merge(pgErr) } if dbErr != nil { diff --git a/core/block/import/objectcreator.go b/core/block/import/objectcreator.go index 2c709115d..37e26b2f1 100644 --- a/core/block/import/objectcreator.go +++ b/core/block/import/objectcreator.go @@ -32,8 +32,18 @@ type ObjectCreator struct { syncFactory *syncer.Factory } -func NewCreator(service *block.Service, core core.Service, updater Updater, syncFactory *syncer.Factory, relationCreator RelationCreator) Creator { - return &ObjectCreator{service: service, core: core, updater: updater, syncFactory: syncFactory, relationCreator: relationCreator} +func NewCreator(service *block.Service, + core core.Service, + updater Updater, + syncFactory *syncer.Factory, + relationCreator RelationCreator) Creator { + return &ObjectCreator{ + service: service, + core: core, + updater: updater, + syncFactory: syncFactory, + relationCreator: relationCreator, + } } // Create creates smart blocks from given snapshots diff --git a/core/block/import/pb/converter.go b/core/block/import/pb/converter.go index e4556eafd..35673d41f 100644 --- a/core/block/import/pb/converter.go +++ b/core/block/import/pb/converter.go @@ -34,7 +34,8 @@ func New(core.Service) converter.Converter { return new(Pb) } -func (p *Pb) GetSnapshots(req *pb.RpcObjectImportRequest, progress *process.Progress) (*converter.Response, converter.ConvertError) { +func (p *Pb) GetSnapshots(req *pb.RpcObjectImportRequest, + progress *process.Progress) (*converter.Response, converter.ConvertError) { path, e := p.GetParams(req.Params) allErrors := converter.NewError() if e != nil { diff --git a/core/block/import/relationcreator.go b/core/block/import/relationcreator.go index 4bdf9e896..6a1dc92c8 100644 --- a/core/block/import/relationcreator.go +++ b/core/block/import/relationcreator.go @@ -41,8 +41,8 @@ func NewRelationCreator(service *block.Service, store filestore.FileStore, core } } -// Create read relations link from snaphot and create according relations in anytype, also set details for according relation in object -// for files it loads them in ipfs +// Create read relations link from snaphot and create according relations in anytype, +// also set details for according relation in object for files it loads them in ipfs func (rc *RelationService) Create(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, relations []*converter.Relation, @@ -171,7 +171,10 @@ func (rc *RelationService) handleCoverRelation(ctx *session.Context, return filesToDelete, err } -func (rc *RelationService) handleListValue(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, r *converter.Relation, relationID string) { +func (rc *RelationService) handleListValue(ctx *session.Context, + snapshot *model.SmartBlockSnapshotBase, + r *converter.Relation, + relationID string) { var ( optionsIds = make([]string, 0) id string @@ -252,7 +255,8 @@ func (rc *RelationService) handleFileRelation(ctx *session.Context, return filesToDelete } -func (rc *RelationService) linkRelationsBlocks(snapshot *model.SmartBlockSnapshotBase, oldID, newID string) (*model.Block, *model.Block) { +func (rc *RelationService) linkRelationsBlocks(snapshot *model.SmartBlockSnapshotBase, + oldID, newID string) (*model.Block, *model.Block) { for _, b := range snapshot.Blocks { if rel, ok := b.Content.(*model.BlockContentOfRelation); ok && rel.Relation.GetKey() == oldID { return b, &model.Block{ diff --git a/core/block/import/syncer/icon.go b/core/block/import/syncer/icon.go index 4ec4235f2..7b229e19b 100644 --- a/core/block/import/syncer/icon.go +++ b/core/block/import/syncer/icon.go @@ -34,11 +34,11 @@ func (is *IconSyncer) Sync(ctx *session.Context, id string, b simple.Block) erro err = is.service.Do(id, func(sb smartblock.SmartBlock) error { bs := basic.NewBasic(sb) - err := bs.Update(ctx, func(simpleBlock simple.Block) error { + upErr := bs.Update(ctx, func(simpleBlock simple.Block) error { simpleBlock.Model().GetText().IconImage = hash return nil }, b.Model().Id) - if err != nil { + if upErr != nil { return fmt.Errorf("failed to update block: %s", err) } return nil diff --git a/core/block/import/web/converter.go b/core/block/import/web/converter.go index 520a20666..2e680f157 100644 --- a/core/block/import/web/converter.go +++ b/core/block/import/web/converter.go @@ -30,7 +30,8 @@ func (*Converter) GetParser(url string) parsers.Parser { return nil } -func (c *Converter) GetSnapshots(req *pb.RpcObjectImportRequest, progress *process.Progress) (*converter.Response, converter.ConvertError) { +func (c *Converter) GetSnapshots(req *pb.RpcObjectImportRequest, + progress *process.Progress) (*converter.Response, converter.ConvertError) { we := converter.NewError() url, err := c.getParams(req.Params) From f9999fcefef5816cfbcf3993c5cfe9dd4c58d3a4 Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Mon, 19 Dec 2022 12:42:35 +0300 Subject: [PATCH 23/68] PROD-344: fix imports Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/mock.go | 5 ++-- .../import/notion/api/block/link_test.go | 3 +-- .../import/notion/api/block/retrieve_test.go | 5 ++-- .../import/notion/api/block/table_test.go | 23 +++++++++---------- .../import/notion/api/commonobjects_test.go | 3 ++- core/block/import/types.go | 9 ++++---- core/block/import/web/converter.go | 3 ++- core/block/import/web/parsers/mock.go | 3 ++- 8 files changed, 29 insertions(+), 25 deletions(-) diff --git a/core/block/import/mock.go b/core/block/import/mock.go index 9a7fcfe5a..eb5152b96 100644 --- a/core/block/import/mock.go +++ b/core/block/import/mock.go @@ -7,6 +7,9 @@ package importer import ( reflect "reflect" + types "github.com/gogo/protobuf/types" + gomock "github.com/golang/mock/gomock" + app "github.com/anytypeio/go-anytype-middleware/app" "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/core/block/process" @@ -14,8 +17,6 @@ import ( pb "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock" model "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" - types "github.com/gogo/protobuf/types" - gomock "github.com/golang/mock/gomock" ) // MockImporter is a mock of Importer interface. diff --git a/core/block/import/notion/api/block/link_test.go b/core/block/import/notion/api/block/link_test.go index 134ae2423..a0b835a2d 100644 --- a/core/block/import/notion/api/block/link_test.go +++ b/core/block/import/notion/api/block/link_test.go @@ -41,7 +41,6 @@ func Test_GetBookmarkBlock(t *testing.T) { assert.Equal(t, bb.GetBookmark().GetTitle(), "Text") } - func Test_GetLinkToObjectBlockSuccess(t *testing.T) { c := &Child{Title: "title"} nameToID := map[string]string{"id": "title"} @@ -67,4 +66,4 @@ func Test_GetLinkToObjectBlockFail(t *testing.T) { content, ok = bl.Content.(*model.BlockContentOfText) assert.True(t, ok) assert.Equal(t, content.Text.Text, notFoundPageMessage) -} \ No newline at end of file +} diff --git a/core/block/import/notion/api/block/retrieve_test.go b/core/block/import/notion/api/block/retrieve_test.go index 1f2681c4f..d45ebf990 100644 --- a/core/block/import/notion/api/block/retrieve_test.go +++ b/core/block/import/notion/api/block/retrieve_test.go @@ -6,9 +6,10 @@ import ( "net/http/httptest" "testing" + "github.com/stretchr/testify/assert" + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api/client" "github.com/anytypeio/go-anytype-middleware/pb" - "github.com/stretchr/testify/assert" ) func Test_GetBlocksAndChildrenSuccessParagraph(t *testing.T) { @@ -987,4 +988,4 @@ func TestTableBlocks(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, bl) assert.Len(t, bl, 3) -} \ No newline at end of file +} diff --git a/core/block/import/notion/api/block/table_test.go b/core/block/import/notion/api/block/table_test.go index b873c1ce8..cc91e423c 100644 --- a/core/block/import/notion/api/block/table_test.go +++ b/core/block/import/notion/api/block/table_test.go @@ -3,18 +3,19 @@ package block import ( "testing" - "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" "github.com/stretchr/testify/assert" + + "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" ) func Test_TableWithOneColumnAndRow(t *testing.T) { - + tb := &TableBlock{ Table: TableObject{ Width: 1, HasColumnHeader: false, HasRowHeader: true, - Children: []*TableRowBlock{ + Children: []*TableRowBlock{ { TableRowObject: TableRowObject{}, }, @@ -29,13 +30,13 @@ func Test_TableWithOneColumnAndRow(t *testing.T) { } func Test_TableWithoutContent(t *testing.T) { - + tb := &TableBlock{ Table: TableObject{ Width: 3, HasColumnHeader: false, HasRowHeader: true, - Children: []*TableRowBlock{ + Children: []*TableRowBlock{ { TableRowObject: TableRowObject{}, }, @@ -46,29 +47,28 @@ func Test_TableWithoutContent(t *testing.T) { }, } - assert.Len(t, tb.Table.Children, 2) resp := tb.GetBlocks(&MapRequest{}) assert.NotNil(t, resp) - assert.Len(t, resp.Blocks, 8) // table block + 3 * column block + 1 column layout + 1 row layout + 3 * row block + assert.Len(t, resp.Blocks, 8) // table block + 3 * column block + 1 column layout + 1 row layout + 3 * row block } func Test_TableWithDifferentText(t *testing.T) { - + tb := &TableBlock{ Table: TableObject{ Width: 3, HasColumnHeader: false, HasRowHeader: true, - Children: []*TableRowBlock{ + Children: []*TableRowBlock{ { TableRowObject: TableRowObject{ Cells: [][]api.RichText{ { { - Type: api.Text, + Type: api.Text, PlainText: "Text", }, }, @@ -82,11 +82,10 @@ func Test_TableWithDifferentText(t *testing.T) { }, } - assert.Len(t, tb.Table.Children, 2) resp := tb.GetBlocks(&MapRequest{}) assert.NotNil(t, resp) assert.Len(t, resp.Blocks, 9) // table block + 3 * column block + 1 column layout + 1 row layout + 3 * row block + 1 text block -} \ No newline at end of file +} diff --git a/core/block/import/notion/api/commonobjects_test.go b/core/block/import/notion/api/commonobjects_test.go index 37c106933..d1b48d0a2 100644 --- a/core/block/import/notion/api/commonobjects_test.go +++ b/core/block/import/notion/api/commonobjects_test.go @@ -4,8 +4,9 @@ import ( "testing" "time" - "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" "github.com/stretchr/testify/assert" + + "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" ) func Test_BuildMarkdownFromAnnotationsBold(t *testing.T) { diff --git a/core/block/import/types.go b/core/block/import/types.go index f5617803a..a27323e1c 100644 --- a/core/block/import/types.go +++ b/core/block/import/types.go @@ -1,16 +1,17 @@ package importer import ( + "github.com/gogo/protobuf/types" + "github.com/anytypeio/go-anytype-middleware/app" "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" - _ "github.com/anytypeio/go-anytype-middleware/core/block/import/markdown" - _ "github.com/anytypeio/go-anytype-middleware/core/block/import/notion" - _ "github.com/anytypeio/go-anytype-middleware/core/block/import/pb" "github.com/anytypeio/go-anytype-middleware/core/session" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" - "github.com/gogo/protobuf/types" + _ "github.com/anytypeio/go-anytype-middleware/core/block/import/markdown" + _ "github.com/anytypeio/go-anytype-middleware/core/block/import/notion" + _ "github.com/anytypeio/go-anytype-middleware/core/block/import/pb" ) // Importer incapsulate logic with import diff --git a/core/block/import/web/converter.go b/core/block/import/web/converter.go index 2e680f157..4c9f78b54 100644 --- a/core/block/import/web/converter.go +++ b/core/block/import/web/converter.go @@ -3,13 +3,14 @@ package web import ( "fmt" + "github.com/textileio/go-threads/core/thread" + "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/core/block/import/web/parsers" "github.com/anytypeio/go-anytype-middleware/core/block/process" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock" "github.com/anytypeio/go-anytype-middleware/pkg/lib/threads" - "github.com/textileio/go-threads/core/thread" ) const name = "web" diff --git a/core/block/import/web/parsers/mock.go b/core/block/import/web/parsers/mock.go index 7a8b9a8ce..24c257756 100644 --- a/core/block/import/web/parsers/mock.go +++ b/core/block/import/web/parsers/mock.go @@ -7,8 +7,9 @@ package parsers import ( reflect "reflect" - model "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" gomock "github.com/golang/mock/gomock" + + model "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" ) // MockParser is a mock of Parser interface. From 1196a3ebde1f2f045ccd9e342025f946b2dcec8a Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Mon, 19 Dec 2022 13:27:28 +0300 Subject: [PATCH 24/68] PROD-344: fix imports Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/markdown/anymark/blocks_renderer.go | 3 ++- core/block/import/types.go | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/core/block/import/markdown/anymark/blocks_renderer.go b/core/block/import/markdown/anymark/blocks_renderer.go index fbdcc98d0..0b13068bc 100644 --- a/core/block/import/markdown/anymark/blocks_renderer.go +++ b/core/block/import/markdown/anymark/blocks_renderer.go @@ -306,7 +306,8 @@ func (r *blocksRenderer) CloseTextBlock(content model.BlockContentTextStyle) { } if parentBlock != nil { - if parentText := parentBlock.GetText(); parentText != nil && parentText.Text == "" && !isBlockCanHaveChild(closingBlock.Block) && t.Text != "" { + if parentText := parentBlock.GetText(); parentText != nil && parentText.Text == "" && + !isBlockCanHaveChild(closingBlock.Block) && t.Text != "" { parentText.Marks = t.Marks parentText.Checked = t.Checked parentText.Color = t.Color diff --git a/core/block/import/types.go b/core/block/import/types.go index a27323e1c..01f1c0f18 100644 --- a/core/block/import/types.go +++ b/core/block/import/types.go @@ -9,6 +9,8 @@ import ( "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" + + // import plugins _ "github.com/anytypeio/go-anytype-middleware/core/block/import/markdown" _ "github.com/anytypeio/go-anytype-middleware/core/block/import/notion" _ "github.com/anytypeio/go-anytype-middleware/core/block/import/pb" From 2b2e039977ee65442f06d998045065168906690c Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Mon, 19 Dec 2022 13:40:42 +0300 Subject: [PATCH 25/68] PROD-344: fix imports Signed-off-by: AnastasiaShemyakinskaya --- core/block/editor/file/uploader.go | 3 ++- core/block/process/progress.go | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/block/editor/file/uploader.go b/core/block/editor/file/uploader.go index 8cb5875c0..601eb2f2c 100644 --- a/core/block/editor/file/uploader.go +++ b/core/block/editor/file/uploader.go @@ -14,13 +14,14 @@ import ( "strings" "time" + "github.com/h2non/filetype" + "github.com/anytypeio/go-anytype-middleware/core/block/simple" "github.com/anytypeio/go-anytype-middleware/core/block/simple/file" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core" "github.com/anytypeio/go-anytype-middleware/pkg/lib/files" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" "github.com/anytypeio/go-anytype-middleware/util/uri" - "github.com/h2non/filetype" ) var ( diff --git a/core/block/process/progress.go b/core/block/process/progress.go index 9daa2515d..aa87c9ffb 100644 --- a/core/block/process/progress.go +++ b/core/block/process/progress.go @@ -5,8 +5,9 @@ import ( "sync" "sync/atomic" - "github.com/anytypeio/go-anytype-middleware/pb" "github.com/globalsign/mgo/bson" + + "github.com/anytypeio/go-anytype-middleware/pb" ) func NewProgress(pType pb.ModelProcessType) *Progress { From 569e3135ff56cdec419ab83d6c5769ee4f66f537 Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Mon, 19 Dec 2022 13:46:11 +0300 Subject: [PATCH 26/68] GO-344: fix formatting Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/notion/api/database/database_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/core/block/import/notion/api/database/database_test.go b/core/block/import/notion/api/database/database_test.go index f0f56b3b9..636bab89a 100644 --- a/core/block/import/notion/api/database/database_test.go +++ b/core/block/import/notion/api/database/database_test.go @@ -1,2 +1 @@ package database - From 013f058af3573d9553a8777e2114898ada26bfb1 Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Mon, 19 Dec 2022 13:52:37 +0300 Subject: [PATCH 27/68] PROD-344: fix comments Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/notion/api/block/retrieve.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/block/import/notion/api/block/retrieve.go b/core/block/import/notion/api/block/retrieve.go index e0c48fa64..4cdcead75 100644 --- a/core/block/import/notion/api/block/retrieve.go +++ b/core/block/import/notion/api/block/retrieve.go @@ -115,7 +115,7 @@ func (s *Service) getBlocks(ctx context.Context, pageID, apiKey string, paginati return blocks, nil } -// (to avoid error with many statements) +// to avoid error with many statements //nolint:funlen func (*Service) fillBlocks(blockType Type, buffer []byte) []interface{} { blocks := make([]interface{}, 0) From 54f98dfd7c736ae4c0753e3b67d5c4d32f477f3e Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Mon, 19 Dec 2022 13:56:27 +0300 Subject: [PATCH 28/68] PROD-344: remove comments Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/notion/api/block/retrieve.go | 1 - 1 file changed, 1 deletion(-) diff --git a/core/block/import/notion/api/block/retrieve.go b/core/block/import/notion/api/block/retrieve.go index 4cdcead75..4d2d1aab2 100644 --- a/core/block/import/notion/api/block/retrieve.go +++ b/core/block/import/notion/api/block/retrieve.go @@ -115,7 +115,6 @@ func (s *Service) getBlocks(ctx context.Context, pageID, apiKey string, paginati return blocks, nil } -// to avoid error with many statements //nolint:funlen func (*Service) fillBlocks(blockType Type, buffer []byte) []interface{} { blocks := make([]interface{}, 0) From 8f16f3be933618a1323003626d63e9128ecd0dfb Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Wed, 21 Dec 2022 13:04:58 +0300 Subject: [PATCH 29/68] GO-512: update relations if they exists Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/importer.go | 2 +- core/block/import/objectcreator.go | 49 +- core/block/import/objectupdater.go | 56 +- core/block/import/relationcreator.go | 213 +++- core/block/import/types.go | 9 +- pb/commands.pb.go | 1487 +++++++++++++------------- 6 files changed, 993 insertions(+), 823 deletions(-) diff --git a/core/block/import/importer.go b/core/block/import/importer.go index d285629b0..0ac526f4d 100644 --- a/core/block/import/importer.go +++ b/core/block/import/importer.go @@ -44,9 +44,9 @@ func (i *Import) Init(a *app.App) (err error) { i.converters[converter.Name()] = converter } factory := syncer.New(syncer.NewFileSyncer(i.s), syncer.NewBookmarkSyncer(i.s), syncer.NewIconSyncer(i.s)) - ou := NewObjectUpdater(i.s, core, factory) fs := a.MustComponent(filestore.CName).(filestore.FileStore) relationCreator := NewRelationCreator(i.s, fs, core) + ou := NewObjectUpdater(i.s, core, factory, relationCreator) i.oc = NewCreator(i.s, core, ou, factory, relationCreator) return nil } diff --git a/core/block/import/objectcreator.go b/core/block/import/objectcreator.go index 37e26b2f1..01769f49c 100644 --- a/core/block/import/objectcreator.go +++ b/core/block/import/objectcreator.go @@ -9,7 +9,6 @@ import ( "go.uber.org/zap" "github.com/anytypeio/go-anytype-middleware/core/block" - editor "github.com/anytypeio/go-anytype-middleware/core/block/editor/smartblock" "github.com/anytypeio/go-anytype-middleware/core/block/editor/state" "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/core/block/import/syncer" @@ -58,9 +57,18 @@ func (oc *ObjectCreator) Create(ctx *session.Context, var err error if updateExisting { - if details, err := oc.updater.Update(ctx, snapshot, pageID); err == nil { + var ( + filesToDelete []string + details *types.Struct + ) + if details, filesToDelete, err = oc.updater.Update(ctx, snapshot, relations, pageID); err == nil { return details, nil } + if err != nil { + for _, hash := range filesToDelete { + oc.deleteFile(hash) + } + } log.Warn("failed to update existing object: %s", err) } @@ -105,7 +113,7 @@ func (oc *ObjectCreator) Create(ctx *session.Context, } var oldRelationBlocksToNew map[string]*model.Block - filesToDelete, oldRelationBlocksToNew, err = oc.relationCreator.Create(ctx, snapshot, relations, pageID) + filesToDelete, oldRelationBlocksToNew, err = oc.relationCreator.UpdateRelations(ctx, snapshot, pageID, relations, nil) if err != nil { return nil, fmt.Errorf("relation create '%s'", err) @@ -119,7 +127,7 @@ func (oc *ObjectCreator) Create(ctx *session.Context, } } - oc.replaceRelationBlock(ctx, st, oldRelationBlocksToNew, pageID) + oc.relationCreator.ReplaceRelationBlock(ctx, st, oldRelationBlocksToNew, pageID) st.Iterate(func(bl simple.Block) (isContinue bool) { s := oc.syncFactory.GetSyncer(bl) @@ -198,36 +206,3 @@ func (oc *ObjectCreator) deleteFile(hash string) { } } } - -func (oc *ObjectCreator) replaceRelationBlock(ctx *session.Context, - st *state.State, - oldRelationBlocksToNew map[string]*model.Block, - pageID string) { - if err := st.Iterate(func(b simple.Block) (isContinue bool) { - if b.Model().GetRelation() == nil { - return true - } - bl, ok := oldRelationBlocksToNew[b.Model().GetId()] - if !ok { - return true - } - if sbErr := oc.service.Do(pageID, func(sb editor.SmartBlock) error { - s := sb.NewStateCtx(ctx) - simpleBlock := simple.New(bl) - s.Add(simpleBlock) - if err := s.InsertTo(b.Model().GetId(), model.Block_Replace, simpleBlock.Model().GetId()); err != nil { - return err - } - if err := sb.Apply(s); err != nil { - return err - } - return nil - }); sbErr != nil { - log.With(zap.String("object id", pageID)).Errorf("failed to replace relation block: %w", sbErr) - } - - return true - }); err != nil { - log.With(zap.String("object id", pageID)).Errorf("failed to replace relation block: %w", err) - } -} diff --git a/core/block/import/objectupdater.go b/core/block/import/objectupdater.go index 30ae2d08e..580881738 100644 --- a/core/block/import/objectupdater.go +++ b/core/block/import/objectupdater.go @@ -8,6 +8,7 @@ import ( "github.com/anytypeio/go-anytype-middleware/core/block" "github.com/anytypeio/go-anytype-middleware/core/block/editor/basic" sb "github.com/anytypeio/go-anytype-middleware/core/block/editor/smartblock" + "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/core/block/import/syncer" "github.com/anytypeio/go-anytype-middleware/core/block/simple" "github.com/anytypeio/go-anytype-middleware/core/session" @@ -19,20 +20,28 @@ import ( ) type ObjectUpdater struct { - service *block.Service - core core.Service - syncFactory *syncer.Factory + service *block.Service + core core.Service + syncFactory *syncer.Factory + relationCreator RelationCreator } -func NewObjectUpdater(service *block.Service, core core.Service, syncFactory *syncer.Factory) Updater { +func NewObjectUpdater(service *block.Service, + core core.Service, + syncFactory *syncer.Factory, + relationCreator RelationCreator) Updater { return &ObjectUpdater{ - service: service, - core: core, - syncFactory: syncFactory, + service: service, + core: core, + syncFactory: syncFactory, + relationCreator: relationCreator, } } -func (ou *ObjectUpdater) Update(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, pageID string) (*types.Struct, error) { +func (ou *ObjectUpdater) Update(ctx *session.Context, + snapshot *model.SmartBlockSnapshotBase, + relations []*converter.Relation, + pageID string) (*types.Struct, []string, error) { if snapshot.Details != nil && snapshot.Details.Fields[bundle.RelationKeySource.String()] != nil { source := snapshot.Details.Fields[bundle.RelationKeySource.String()].GetStringValue() records, _, err := ou.core.ObjectStore().Query(nil, database.Query{ @@ -47,7 +56,8 @@ func (ou *ObjectUpdater) Update(ctx *session.Context, snapshot *model.SmartBlock }) if err == nil { if len(records) > 0 { - return records[0].Details, ou.update(ctx, snapshot, records, pageID) + filesToDelete, err := ou.update(ctx, snapshot, records, relations, pageID) + return records[0].Details, filesToDelete, err } } } @@ -65,19 +75,25 @@ func (ou *ObjectUpdater) Update(ctx *session.Context, snapshot *model.SmartBlock }) if err == nil { if len(records) > 0 { - return records[0].Details, ou.update(ctx, snapshot, records, pageID) + filesToDelete, err := ou.update(ctx, snapshot, records, relations, pageID) + return records[0].Details, filesToDelete, err } } } - return nil, fmt.Errorf("no source or id details") + return nil, nil, fmt.Errorf("no source or id details") } func (ou *ObjectUpdater) update(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, records []database.Record, - pageID string) error { + relations []*converter.Relation, + pageID string) ([]string, error) { details := records[0] simpleBlocks := make([]simple.Block, 0) + var ( + filesToDelete = make([]string, 0) + oldRelationBlockToNew = make(map[string]*model.Block, 0) + ) id := details.Details.Fields[bundle.RelationKeyId.String()].GetStringValue() if details.Details != nil { allBlocksIds := make([]string, 0) @@ -112,7 +128,19 @@ func (ou *ObjectUpdater) update(ctx *session.Context, } return b.Apply(s) }); err != nil { - return err + return nil, err + } + var err error + filesToDelete, oldRelationBlockToNew, err = ou.relationCreator.UpdateRelations(ctx, snapshot, id, relations, nil) + if err != nil { + return nil, err + } + if err := ou.service.Do(id, func(b sb.SmartBlock) error { + s := b.NewStateCtx(ctx) + ou.relationCreator.ReplaceRelationBlock(ctx, s, oldRelationBlockToNew, id) + return nil + }); err != nil { + return nil, err } for _, b := range simpleBlocks { s := ou.syncFactory.GetSyncer(b) @@ -121,5 +149,5 @@ func (ou *ObjectUpdater) update(ctx *session.Context, } } } - return nil + return filesToDelete, nil } diff --git a/core/block/import/relationcreator.go b/core/block/import/relationcreator.go index 6a1dc92c8..03de61a70 100644 --- a/core/block/import/relationcreator.go +++ b/core/block/import/relationcreator.go @@ -5,13 +5,18 @@ import ( "github.com/globalsign/mgo/bson" "github.com/gogo/protobuf/types" + "go.uber.org/zap" "github.com/anytypeio/go-anytype-middleware/core/block" + editor "github.com/anytypeio/go-anytype-middleware/core/block/editor/smartblock" + "github.com/anytypeio/go-anytype-middleware/core/block/editor/state" "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" + "github.com/anytypeio/go-anytype-middleware/core/block/simple" "github.com/anytypeio/go-anytype-middleware/core/session" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/database" "github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore/filestore" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" "github.com/anytypeio/go-anytype-middleware/util/pbtypes" @@ -41,9 +46,77 @@ func NewRelationCreator(service *block.Service, store filestore.FileStore, core } } +func (rc *RelationService) UpdateRelations(ctx *session.Context, + snapshot *model.SmartBlockSnapshotBase, + pageID string, + relations []*converter.Relation, + relationsLinks pbtypes.RelationLinks) ([]string, map[string]*model.Block, error) { + notExistedRelations := make([]*converter.Relation, 0) + existedRelations := make(map[string]*converter.Relation, 0) + for _, r := range relations { + if strings.EqualFold(r.Name, bundle.RelationKeyName.String()) { + continue + } + if rel, ok := rc.createdRelations[r.Name]; ok { + var exist bool + for _, v := range rel { + if v.Format == r.Format { + existedRelations[v.ID] = r + exist = true + break + } + } + if exist { + continue + } + } + records, _, err := rc.core.ObjectStore().Query(nil, database.Query{ + Filters: []*model.BlockContentDataviewFilter{ + { + Condition: model.BlockContentDataviewFilter_Equal, + RelationKey: bundle.RelationKeyName.String(), + Value: pbtypes.String(r.Name), + Format: r.Format, + }, + }, + Limit: 1, + }) + if err == nil { + if len(records) > 0 { + id := records[0].Details.Fields[bundle.RelationKeyRelationKey.String()].GetStringValue() + existedRelations[id] = r + continue + } + } + notExistedRelations = append(notExistedRelations, r) + } + + filesToDelete, oldRelationBlockToNew, err := rc.update(ctx, snapshot, existedRelations, pageID) + if err != nil { + return nil, nil, err + } + createfilesToDelete, relationsBlocks, err := rc.create(ctx, snapshot, notExistedRelations, pageID) + if err != nil { + return nil, nil, err + } + filesToDelete = append(filesToDelete, createfilesToDelete...) + relationBlocks := make(map[string]*model.Block, len(relationsBlocks)+len(oldRelationBlockToNew)) + if len(oldRelationBlockToNew) == 0 { + for k, b := range oldRelationBlockToNew { + relationBlocks[k] = b + } + } + if len(relationsBlocks) == 0 { + for k, b := range relationsBlocks { + relationBlocks[k] = b + } + } + return filesToDelete, relationBlocks, nil +} + // Create read relations link from snaphot and create according relations in anytype, // also set details for according relation in object for files it loads them in ipfs -func (rc *RelationService) Create(ctx *session.Context, +func (rc *RelationService) create(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, relations []*converter.Relation, pageID string) ([]string, map[string]*model.Block, error) { @@ -57,30 +130,15 @@ func (rc *RelationService) Create(ctx *session.Context, ) for _, r := range relations { - var ( - relationID string - ) - if rel, ok := rc.createdRelations[r.Name]; ok { - for _, v := range rel { - if v.Format == r.Format { - relationID = v.ID - existedRelationsIDs = append(existedRelationsIDs, relationID) - break - } - } - } - - if relationID == "" { - detail := &types.Struct{ - Fields: map[string]*types.Value{ - bundle.RelationKeyName.String(): pbtypes.String(r.Name), - bundle.RelationKeyRelationFormat.String(): pbtypes.Int64(int64(r.Format)), - bundle.RelationKeyType.String(): pbtypes.String(bundle.TypeKeyRelation.URL()), - bundle.RelationKeyLayout.String(): pbtypes.Float64(float64(model.ObjectType_relation)), - }, - } - createRequest = append(createRequest, detail) + detail := &types.Struct{ + Fields: map[string]*types.Value{ + bundle.RelationKeyName.String(): pbtypes.String(r.Name), + bundle.RelationKeyRelationFormat.String(): pbtypes.Int64(int64(r.Format)), + bundle.RelationKeyType.String(): pbtypes.String(bundle.TypeKeyRelation.URL()), + bundle.RelationKeyLayout.String(): pbtypes.Float64(float64(model.ObjectType_relation)), + }, } + createRequest = append(createRequest, detail) } var objects []*types.Struct if _, objects, err = rc.service.CreateSubObjectsInWorkspace(createRequest); err != nil { @@ -154,6 +212,95 @@ func (rc *RelationService) Create(ctx *session.Context, return filesToDelete, oldRelationBlockToNew, nil } +func (rc *RelationService) update(ctx *session.Context, + snapshot *model.SmartBlockSnapshotBase, + relations map[string]*converter.Relation, + pageID string) ([]string, map[string]*model.Block, error) { + var ( + err error + filesToDelete = make([]string, 0) + oldRelationBlockToNew = make(map[string]*model.Block, 0) + setDetailsRequest = make([]*pb.RpcObjectSetDetailsDetail, 0) + ) + + ids := make([]string, 0, len(relations)) + + if err = rc.service.AddExtraRelations(ctx, pageID, ids); err != nil { + log.Errorf("add extra relation %s", err) + } + + for key, r := range relations { + if snapshot.Details != nil && snapshot.Details.Fields != nil { + if snapshot.Details.Fields[r.Name].GetListValue() != nil { + rc.handleListValue(ctx, snapshot, r, key) + } + if r.Format == model.RelationFormat_file { + filesToDelete = append(filesToDelete, rc.handleFileRelation(ctx, snapshot, r.Name)...) + } + } + setDetailsRequest = append(setDetailsRequest, &pb.RpcObjectSetDetailsDetail{ + Key: key, + Value: snapshot.Details.Fields[r.Name], + }) + if r.BlockID != "" { + original, new := rc.linkRelationsBlocks(snapshot, r.BlockID, key) + if original != nil && new != nil { + oldRelationBlockToNew[original.GetId()] = new + } + } + } + + err = rc.service.SetDetails(ctx, pb.RpcObjectSetDetailsRequest{ + ContextId: pageID, + Details: setDetailsRequest, + }) + if err != nil { + log.Errorf("set details %s", err) + } + + if ftd, err := rc.handleCoverRelation(ctx, snapshot, pageID); err != nil { + log.Errorf("failed to upload cover image %s", err) + } else { + filesToDelete = append(filesToDelete, ftd...) + } + + return filesToDelete, oldRelationBlockToNew, nil + +} + +func (rc *RelationService) ReplaceRelationBlock(ctx *session.Context, + st *state.State, + oldRelationBlocksToNew map[string]*model.Block, + pageID string) { + if err := st.Iterate(func(b simple.Block) (isContinue bool) { + if b.Model().GetRelation() == nil { + return true + } + bl, ok := oldRelationBlocksToNew[b.Model().GetId()] + if !ok { + return true + } + if sbErr := rc.service.Do(pageID, func(sb editor.SmartBlock) error { + s := sb.NewStateCtx(ctx) + simpleBlock := simple.New(bl) + s.Add(simpleBlock) + if err := s.InsertTo(b.Model().GetId(), model.Block_Replace, simpleBlock.Model().GetId()); err != nil { + return err + } + if err := sb.Apply(s); err != nil { + return err + } + return nil + }); sbErr != nil { + log.With(zap.String("object id", pageID)).Errorf("failed to replace relation block: %w", sbErr) + } + + return true + }); err != nil { + log.With(zap.String("object id", pageID)).Errorf("failed to replace relation block: %w", err) + } +} + func (rc *RelationService) handleCoverRelation(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, pageID string) ([]string, error) { @@ -176,11 +323,23 @@ func (rc *RelationService) handleListValue(ctx *session.Context, r *converter.Relation, relationID string) { var ( - optionsIds = make([]string, 0) - id string - err error + optionsIds = make([]string, 0) + id string + err error + existedOptions = make(map[string]string, 0) ) + options, err := rc.service.Anytype().ObjectStore().GetAggregatedOptions(relationID) + if err != nil { + log.Errorf("get relations options %s", err) + } + for _, ro := range options { + existedOptions[ro.Text] = ro.Id + } for _, v := range snapshot.Details.Fields[r.Name].GetListValue().Values { + if optionID, ok := existedOptions[v.GetStringValue()]; ok { + optionsIds = append(optionsIds, optionID) + continue + } if r.Format == model.RelationFormat_tag || r.Format == model.RelationFormat_status { if id, _, err = rc.service.CreateSubObjectInWorkspace(&types.Struct{ Fields: map[string]*types.Value{ diff --git a/core/block/import/types.go b/core/block/import/types.go index 01f1c0f18..f42a88759 100644 --- a/core/block/import/types.go +++ b/core/block/import/types.go @@ -4,11 +4,13 @@ import ( "github.com/gogo/protobuf/types" "github.com/anytypeio/go-anytype-middleware/app" + "github.com/anytypeio/go-anytype-middleware/core/block/editor/state" "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/core/session" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" + "github.com/anytypeio/go-anytype-middleware/util/pbtypes" // import plugins _ "github.com/anytypeio/go-anytype-middleware/core/block/import/markdown" @@ -32,11 +34,14 @@ type Creator interface { // Updater is interface for updating existing objects type Updater interface { - Update(ctx *session.Context, cs *model.SmartBlockSnapshotBase, pageID string) (*types.Struct, error) + //nolint: lll + Update(ctx *session.Context, cs *model.SmartBlockSnapshotBase, relations []*converter.Relation, pageID string) (*types.Struct, []string, error) } // RelationCreator incapsulates logic for creation of relations type RelationCreator interface { //nolint: lll - Create(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, relations []*converter.Relation, pageID string) ([]string, map[string]*model.Block, error) + ReplaceRelationBlock(ctx *session.Context, st *state.State, oldRelationBlocksToNew map[string]*model.Block, pageID string) + //nolint: lll + UpdateRelations(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, pageID string, relations []*converter.Relation, relationsLinks pbtypes.RelationLinks) ([]string, map[string]*model.Block, error) } diff --git a/pb/commands.pb.go b/pb/commands.pb.go index 0d2526692..5eb3eb3c6 100644 --- a/pb/commands.pb.go +++ b/pb/commands.pb.go @@ -44128,750 +44128,753 @@ func init() { func init() { proto.RegisterFile("pb/protos/commands.proto", fileDescriptor_8261c968b2e6f45c) } var fileDescriptor_8261c968b2e6f45c = []byte{ - // 11881 bytes of a gzipped FileDescriptorProto + // 11931 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x7d, 0x7d, 0x98, 0x23, 0xc7, 0x59, 0xe7, 0x4a, 0xad, 0x8f, 0x99, 0x77, 0x3e, 0xb6, 0xdd, 0xd9, 0xac, 0x27, 0x65, 0x7b, 0x63, - 0xc6, 0x9f, 0xac, 0xed, 0x59, 0x7b, 0x9d, 0x0f, 0xaf, 0xbf, 0x35, 0x92, 0x66, 0x46, 0xde, 0x19, - 0x69, 0x68, 0x69, 0x76, 0x31, 0x77, 0xdc, 0x5c, 0x8f, 0x54, 0x33, 0xd3, 0x5e, 0x8d, 0x5a, 0xb4, - 0x7a, 0x66, 0x77, 0xf3, 0x3c, 0x77, 0x60, 0xc0, 0xd8, 0xc0, 0x13, 0xc2, 0xe7, 0x05, 0xc3, 0x25, - 0x26, 0x0e, 0x09, 0x84, 0x10, 0x42, 0x08, 0x49, 0x2e, 0x5c, 0x62, 0x2e, 0x24, 0xe1, 0x09, 0x79, - 0x42, 0x1c, 0xf2, 0x0d, 0x97, 0x84, 0xe0, 0x70, 0xb9, 0x70, 0x97, 0x90, 0x27, 0x3c, 0x77, 0xc7, - 0x05, 0x03, 0xb9, 0xa7, 0xab, 0xaa, 0x3f, 0x4a, 0xa3, 0x6e, 0x55, 0x6b, 0xd4, 0x1a, 0xe7, 0xf8, - 0x4b, 0xea, 0xea, 0xea, 0xaa, 0xb7, 0xde, 0xdf, 0x5b, 0x6f, 0x55, 0xbd, 0xf5, 0xd6, 0x5b, 0x30, - 0xd3, 0xde, 0x38, 0xd5, 0x36, 0x0d, 0xcb, 0xe8, 0x9c, 0xaa, 0x1b, 0x3b, 0x3b, 0x5a, 0xab, 0xd1, - 0x99, 0x23, 0xcf, 0x4a, 0x56, 0x6b, 0x5d, 0xb6, 0x2e, 0xb7, 0x31, 0xba, 0xbe, 0x7d, 0x61, 0xeb, - 0x54, 0x53, 0xdf, 0x38, 0xd5, 0xde, 0x38, 0xb5, 0x63, 0x34, 0x70, 0xd3, 0xf9, 0x80, 0x3c, 0xb0, - 0xec, 0xe8, 0xe6, 0xa0, 0x5c, 0x4d, 0xa3, 0xae, 0x35, 0x3b, 0x96, 0x61, 0x62, 0x96, 0xf3, 0xb8, - 0x57, 0x25, 0xde, 0xc3, 0x2d, 0xcb, 0x29, 0xe1, 0xea, 0x2d, 0xc3, 0xd8, 0x6a, 0x62, 0xfa, 0x6e, - 0x63, 0x77, 0xf3, 0x54, 0xc7, 0x32, 0x77, 0xeb, 0x16, 0x7b, 0x7b, 0x6d, 0xf7, 0xdb, 0x06, 0xee, - 0xd4, 0x4d, 0xbd, 0x6d, 0x19, 0x26, 0xcd, 0x31, 0xfb, 0xcf, 0x7f, 0x9b, 0x02, 0x49, 0x6d, 0xd7, - 0xd1, 0xc7, 0xc7, 0x40, 0xca, 0xb5, 0xdb, 0xe8, 0x5b, 0x49, 0x80, 0x45, 0x6c, 0x9d, 0xc3, 0x66, - 0x47, 0x37, 0x5a, 0x68, 0x1c, 0xb2, 0x2a, 0xfe, 0xa1, 0x5d, 0xdc, 0xb1, 0xd0, 0xe7, 0x92, 0x30, - 0xa6, 0xe2, 0x4e, 0xdb, 0x68, 0x75, 0xb0, 0xf2, 0x20, 0xa4, 0xb1, 0x69, 0x1a, 0xe6, 0x4c, 0xe2, - 0xda, 0xc4, 0xcd, 0x13, 0xa7, 0x4f, 0xce, 0xb1, 0x86, 0xcf, 0xa9, 0xed, 0xfa, 0x5c, 0xae, 0xdd, - 0x9e, 0xf3, 0xca, 0x98, 0x73, 0x3e, 0x9a, 0x2b, 0xda, 0x5f, 0xa8, 0xf4, 0x43, 0x65, 0x06, 0xb2, - 0x7b, 0x34, 0xc3, 0x4c, 0xf2, 0xda, 0xc4, 0xcd, 0xe3, 0xaa, 0xf3, 0x68, 0xbf, 0x69, 0x60, 0x4b, - 0xd3, 0x9b, 0x9d, 0x19, 0x89, 0xbe, 0x61, 0x8f, 0xe8, 0xd3, 0x09, 0x48, 0x93, 0x42, 0x94, 0x3c, - 0xa4, 0xea, 0x46, 0x03, 0x93, 0xea, 0xa7, 0x4f, 0x9f, 0x12, 0xaf, 0x7e, 0x2e, 0x6f, 0x34, 0xb0, - 0x4a, 0x3e, 0x56, 0xae, 0x85, 0x09, 0x87, 0x21, 0x1e, 0x19, 0xfe, 0xa4, 0xd9, 0x06, 0xa4, 0xec, - 0xfc, 0xca, 0x18, 0xa4, 0xca, 0x6b, 0xcb, 0xcb, 0xf2, 0x11, 0xe5, 0x0a, 0x98, 0x5a, 0x2b, 0x9f, - 0x2d, 0x57, 0xce, 0x97, 0xd7, 0x8b, 0xaa, 0x5a, 0x51, 0xe5, 0x84, 0x32, 0x05, 0xe3, 0xf3, 0xb9, - 0xc2, 0x7a, 0xa9, 0xbc, 0xba, 0x56, 0x93, 0x93, 0xca, 0x31, 0x90, 0xcf, 0x15, 0xd5, 0x6a, 0xa9, - 0x52, 0x5e, 0x2f, 0x55, 0xd7, 0x8b, 0x2b, 0xab, 0xb5, 0x87, 0x65, 0xc9, 0xce, 0x54, 0xae, 0xd4, - 0xd6, 0x17, 0x2a, 0x6b, 0xe5, 0x82, 0x8c, 0x95, 0x09, 0xc8, 0xd6, 0x4a, 0x2b, 0xc5, 0xca, 0x5a, - 0x4d, 0xde, 0x44, 0xbf, 0x2f, 0xc1, 0x74, 0x15, 0x5b, 0x05, 0xbc, 0xa7, 0xd7, 0x71, 0xd5, 0xd2, - 0x2c, 0x8c, 0x5e, 0x93, 0x70, 0x19, 0xaf, 0xac, 0xd9, 0x64, 0xba, 0xaf, 0x58, 0x93, 0xef, 0xdc, - 0xd7, 0x64, 0xbe, 0x84, 0x39, 0xf6, 0xf5, 0x9c, 0x2f, 0x4d, 0xf5, 0x97, 0x33, 0x7b, 0x1b, 0x4c, - 0xf8, 0xde, 0x29, 0xd3, 0x00, 0xf3, 0xb9, 0xfc, 0xd9, 0x45, 0x95, 0x50, 0x78, 0xc4, 0x7e, 0x5e, - 0xa8, 0xa8, 0x45, 0xf6, 0x9c, 0x40, 0xaf, 0xf1, 0xc3, 0x5f, 0xe0, 0xe1, 0x9f, 0xeb, 0x4f, 0x4c, - 0x0f, 0x11, 0x40, 0xef, 0x73, 0xe1, 0x5c, 0xe4, 0xe0, 0xbc, 0x33, 0x5a, 0x71, 0xd1, 0x20, 0x5d, - 0x1a, 0x0c, 0xd2, 0x72, 0xa5, 0x50, 0x5c, 0xb7, 0x11, 0xac, 0xd6, 0x72, 0x6a, 0xad, 0x58, 0x90, - 0x31, 0xfa, 0xd5, 0x24, 0x8c, 0x55, 0xb7, 0x77, 0xad, 0x86, 0x71, 0x91, 0xeb, 0x28, 0x3f, 0xe6, - 0xe7, 0xd4, 0xfd, 0x3c, 0xa7, 0x6e, 0xde, 0xdf, 0x34, 0x56, 0x42, 0x00, 0x8f, 0xde, 0xed, 0xf2, - 0x28, 0xc7, 0xf1, 0xe8, 0x36, 0xd1, 0x82, 0x0e, 0x8b, 0x3b, 0x9f, 0x99, 0x82, 0xcc, 0x79, 0xad, - 0xd9, 0xc4, 0x16, 0xfa, 0xeb, 0x24, 0x64, 0xf2, 0x26, 0xb6, 0xe5, 0xfa, 0x16, 0x4f, 0xac, 0x11, - 0x8c, 0x99, 0x86, 0x61, 0xad, 0x6a, 0xd6, 0x36, 0x69, 0xd3, 0xb8, 0xea, 0x3e, 0xdf, 0x9d, 0x7a, - 0xe2, 0xab, 0x52, 0x02, 0xfd, 0xb6, 0x9f, 0x91, 0x0f, 0xf0, 0x8c, 0xfc, 0x5e, 0xae, 0xfd, 0xb4, - 0xa2, 0x39, 0x5a, 0x49, 0x80, 0xc2, 0x41, 0x30, 0xb6, 0xd3, 0xc2, 0x3b, 0x46, 0x4b, 0xaf, 0xb3, - 0x96, 0xbb, 0xcf, 0xe8, 0x8f, 0x5c, 0x2e, 0xcf, 0x73, 0x5c, 0x9e, 0x13, 0xae, 0x25, 0x1a, 0x9b, - 0xab, 0x03, 0xb0, 0xf9, 0xa5, 0x70, 0xd5, 0x42, 0xae, 0xb4, 0x5c, 0x2c, 0xac, 0xd7, 0x2a, 0xeb, - 0x79, 0xb5, 0x98, 0xab, 0x15, 0xd7, 0x97, 0x2b, 0xf9, 0xdc, 0xf2, 0xba, 0x5a, 0x5c, 0xad, 0xc8, - 0x18, 0xfd, 0xf7, 0xa4, 0xcd, 0xdc, 0xba, 0xb1, 0x87, 0x4d, 0xb4, 0x28, 0xc4, 0xe7, 0x30, 0x9e, - 0x30, 0x0c, 0x7e, 0x5e, 0x58, 0xeb, 0x33, 0xee, 0x30, 0x0a, 0x02, 0xc4, 0xf9, 0x83, 0x42, 0x1a, - 0x3c, 0xb4, 0xa8, 0x17, 0x00, 0xa7, 0xff, 0x57, 0x12, 0xb2, 0x79, 0xa3, 0xb5, 0x87, 0x4d, 0x0b, - 0x3d, 0xc0, 0x71, 0xda, 0xe5, 0x66, 0x82, 0xe7, 0xa6, 0x3d, 0xa8, 0xe1, 0x96, 0x65, 0x1a, 0xed, - 0xcb, 0xce, 0x70, 0xc7, 0x1e, 0xd1, 0x6f, 0x44, 0xe5, 0x30, 0xab, 0x39, 0x78, 0x5c, 0xed, 0x5d, - 0x11, 0x47, 0x9e, 0xd4, 0xd5, 0x01, 0x9e, 0x8e, 0x82, 0x4b, 0x6f, 0x02, 0xa2, 0xe1, 0x72, 0x3a, - 0x3a, 0x2e, 0xe8, 0x93, 0x49, 0x98, 0xa2, 0x9d, 0xaf, 0x8a, 0x3b, 0x64, 0x7a, 0x72, 0x8b, 0x10, - 0xf3, 0x99, 0x28, 0xff, 0x82, 0x9f, 0xd1, 0x0b, 0x3c, 0xa3, 0x6f, 0x0f, 0xee, 0xe8, 0xac, 0xae, - 0x00, 0x76, 0x1f, 0x83, 0xb4, 0x65, 0x5c, 0xc0, 0x4e, 0x1b, 0xe9, 0x03, 0xfa, 0x4d, 0x97, 0x9d, - 0x25, 0x8e, 0x9d, 0x2f, 0x8f, 0x5a, 0x4d, 0xfc, 0x4c, 0x7d, 0x5b, 0x12, 0x26, 0xf3, 0x4d, 0xa3, - 0xe3, 0xf2, 0xf4, 0xa5, 0x1e, 0x4f, 0xdd, 0xc6, 0x25, 0xfc, 0x8d, 0x7b, 0x3e, 0xe1, 0xe3, 0x63, - 0x91, 0xe7, 0x63, 0x6f, 0x79, 0xf1, 0x15, 0x1f, 0xa0, 0x17, 0x7e, 0xc3, 0x65, 0xd8, 0x12, 0xc7, - 0xb0, 0x97, 0x45, 0x2c, 0x2f, 0x7e, 0x7e, 0xbd, 0xfb, 0x7b, 0x20, 0x9b, 0xab, 0xd7, 0x8d, 0xdd, - 0x96, 0x85, 0xfe, 0x32, 0x01, 0x99, 0xbc, 0xd1, 0xda, 0xd4, 0xb7, 0x94, 0x1b, 0x61, 0x1a, 0xb7, - 0xb4, 0x8d, 0x26, 0x2e, 0x68, 0x96, 0xb6, 0xa7, 0xe3, 0x8b, 0xa4, 0x01, 0x63, 0x6a, 0x57, 0xaa, - 0x4d, 0x14, 0x4b, 0xc1, 0x1b, 0xbb, 0x5b, 0x84, 0xa8, 0x31, 0xd5, 0x9f, 0xa4, 0xdc, 0x05, 0x57, - 0xd2, 0xc7, 0x55, 0x13, 0x9b, 0xb8, 0x89, 0xb5, 0x0e, 0xce, 0x6f, 0x6b, 0xad, 0x16, 0x6e, 0x92, - 0x5e, 0x3b, 0xa6, 0x06, 0xbd, 0x56, 0x66, 0x61, 0x92, 0xbe, 0xaa, 0xb6, 0xb5, 0x3a, 0xee, 0xcc, - 0xa4, 0x48, 0x76, 0x2e, 0x4d, 0xb9, 0x0d, 0xd2, 0xf8, 0x92, 0x65, 0x6a, 0x33, 0x0d, 0x82, 0xd7, - 0x95, 0x73, 0x74, 0x89, 0x30, 0xe7, 0x2c, 0x11, 0xe6, 0xaa, 0x64, 0x01, 0xa1, 0xd2, 0x5c, 0xe8, - 0x83, 0x19, 0x77, 0xe8, 0x7e, 0x83, 0x6f, 0x4a, 0xaa, 0x40, 0xaa, 0xa5, 0xed, 0x60, 0x26, 0x17, - 0xe4, 0xbf, 0x72, 0x12, 0x8e, 0x6a, 0x7b, 0x9a, 0xa5, 0x99, 0xcb, 0xf6, 0xe2, 0x85, 0x0c, 0x37, - 0x84, 0xe5, 0x4b, 0x47, 0xd4, 0xee, 0x17, 0xca, 0xd5, 0x30, 0x4e, 0x56, 0x37, 0x24, 0x17, 0xd5, - 0x45, 0x5e, 0x82, 0x72, 0x33, 0x1c, 0xd5, 0x9a, 0xed, 0x6d, 0xad, 0xd4, 0xda, 0xd3, 0x2d, 0x6c, - 0x23, 0x34, 0x73, 0x8c, 0xe4, 0xe9, 0x4e, 0xa6, 0x1d, 0x7b, 0x7e, 0x0c, 0x32, 0xb4, 0x02, 0xf4, - 0x8b, 0x69, 0xe1, 0x35, 0x0a, 0x85, 0x30, 0x7c, 0xca, 0x70, 0x3b, 0x64, 0x35, 0x9a, 0x8f, 0x34, - 0x65, 0xe2, 0xf4, 0x71, 0xb7, 0x0c, 0xb2, 0x5c, 0x73, 0x4a, 0x51, 0x9d, 0x6c, 0xca, 0x9d, 0x90, - 0xa9, 0x13, 0x81, 0x20, 0xad, 0x9a, 0x38, 0x7d, 0x55, 0xef, 0x4a, 0x49, 0x16, 0x95, 0x65, 0x45, - 0x5f, 0x92, 0x84, 0x96, 0x35, 0x61, 0x14, 0x47, 0x93, 0xfb, 0x6f, 0x24, 0x07, 0x18, 0x15, 0x6f, - 0x85, 0x9b, 0x73, 0xf9, 0x7c, 0x65, 0xad, 0x5c, 0x63, 0x63, 0x62, 0x61, 0x7d, 0x7e, 0xad, 0xb6, - 0xee, 0x8d, 0x94, 0x64, 0xee, 0xb7, 0x6e, 0x4f, 0x05, 0x65, 0x5b, 0x1a, 0x6e, 0xec, 0x93, 0xbb, - 0x58, 0x5b, 0x2f, 0xe7, 0x56, 0x8a, 0xf2, 0xa6, 0x40, 0xc9, 0xc5, 0xda, 0x7a, 0xee, 0x5c, 0xae, - 0x96, 0x53, 0xe5, 0x2d, 0x7e, 0x74, 0xae, 0xd6, 0x2a, 0xab, 0xeb, 0xea, 0x5a, 0xb9, 0x5c, 0x2a, - 0x2f, 0xd2, 0xaa, 0xed, 0x49, 0xcd, 0x71, 0x2f, 0xc3, 0x79, 0xb5, 0x54, 0x2b, 0xae, 0xe7, 0x2b, - 0xe5, 0x85, 0xd2, 0xa2, 0xac, 0xf7, 0x1b, 0xda, 0x1f, 0x51, 0x8e, 0xc1, 0x51, 0xda, 0xe8, 0x73, - 0xf4, 0xbb, 0x42, 0x51, 0xfe, 0xf1, 0xac, 0x32, 0x0d, 0xe3, 0xe5, 0x62, 0x8d, 0x71, 0xe6, 0xb1, - 0xac, 0x72, 0x15, 0x1c, 0xb7, 0x9f, 0xf3, 0x95, 0x72, 0xb9, 0x98, 0xaf, 0xd9, 0x4b, 0x3d, 0xb5, - 0xb8, 0xb0, 0x56, 0x2d, 0x16, 0xe4, 0x9f, 0xc8, 0x2a, 0x32, 0x4c, 0xd8, 0x2f, 0x2b, 0x0b, 0x0b, - 0xcb, 0xa5, 0x72, 0x51, 0x7e, 0x3c, 0x8b, 0xde, 0x94, 0xf2, 0x66, 0x66, 0xbe, 0x85, 0xc2, 0xcf, - 0xa4, 0x7c, 0xd2, 0x9a, 0xe3, 0xa5, 0xf5, 0x96, 0x9e, 0xd8, 0x87, 0x4f, 0xae, 0x9e, 0x71, 0xe5, - 0xa8, 0xc0, 0xc9, 0xd1, 0xed, 0x11, 0xca, 0x8a, 0x26, 0x48, 0x1f, 0x1b, 0x44, 0x90, 0x5e, 0x0c, - 0x57, 0x94, 0x2b, 0xeb, 0x0c, 0xf1, 0xaa, 0xbb, 0x24, 0xbe, 0x16, 0xae, 0x2e, 0x17, 0x29, 0x30, - 0x6a, 0x31, 0x5f, 0x39, 0x57, 0x54, 0xd7, 0xcf, 0xe7, 0x96, 0x97, 0x8b, 0xb5, 0xf5, 0x85, 0x92, - 0x5a, 0xad, 0xc9, 0x9b, 0xfd, 0xc0, 0xdb, 0x52, 0xae, 0x83, 0x97, 0x7a, 0xcf, 0xeb, 0xc5, 0xef, - 0x2f, 0x55, 0x6b, 0x55, 0x22, 0x4a, 0xf9, 0x8a, 0xaa, 0xae, 0xad, 0xda, 0x0b, 0x93, 0x6d, 0xe5, - 0x38, 0x28, 0x5e, 0x29, 0xea, 0x5a, 0x99, 0x8a, 0x8d, 0x6e, 0xd7, 0xcf, 0xea, 0x73, 0xaa, 0xb7, - 0x17, 0x34, 0xab, 0x45, 0x75, 0xa1, 0xa2, 0xae, 0x14, 0x0b, 0xf2, 0x23, 0xfd, 0x24, 0xef, 0x82, - 0x72, 0x23, 0xcc, 0xe6, 0xca, 0x95, 0xda, 0x52, 0x51, 0x5d, 0xcf, 0x95, 0x1f, 0xae, 0x3d, 0xbc, - 0x5a, 0x5c, 0x5f, 0x55, 0x2b, 0xf9, 0x62, 0xb5, 0xba, 0x5e, 0xaa, 0x3a, 0x99, 0xe5, 0xa6, 0x4d, - 0x82, 0x23, 0xf0, 0xa5, 0xea, 0x7a, 0xa1, 0xb8, 0x5c, 0xb4, 0x49, 0xdb, 0x41, 0xaf, 0x96, 0x20, - 0x53, 0xc0, 0x4d, 0x6c, 0x61, 0xf4, 0x3d, 0x9e, 0xb2, 0x3d, 0x0e, 0x19, 0x13, 0xdb, 0x13, 0x2e, - 0x36, 0xa4, 0xb0, 0x27, 0xf4, 0x97, 0xc9, 0xa8, 0xca, 0x8e, 0x96, 0x1d, 0xa0, 0xec, 0x5e, 0x0e, - 0x99, 0x8e, 0xa5, 0x59, 0xbb, 0x1d, 0xa6, 0xeb, 0xae, 0xe9, 0xad, 0xeb, 0xe6, 0xaa, 0x24, 0x93, - 0xca, 0x32, 0xa3, 0x3f, 0x4f, 0x44, 0x51, 0x5e, 0x3d, 0x29, 0x88, 0x26, 0x73, 0xfa, 0x00, 0x22, - 0x77, 0x02, 0x90, 0x8f, 0xe1, 0xb9, 0x65, 0xb5, 0x98, 0x2b, 0x3c, 0xec, 0x32, 0x1e, 0xdb, 0x22, - 0xe9, 0x7f, 0x9f, 0xaf, 0x95, 0xce, 0x15, 0xe5, 0x4d, 0xf4, 0xc1, 0x34, 0x64, 0xaa, 0xb8, 0x89, - 0xeb, 0x16, 0xba, 0xc7, 0xc3, 0x63, 0x1a, 0x92, 0x7a, 0x83, 0x0d, 0x7d, 0x49, 0xbd, 0xc1, 0x2d, - 0xb0, 0x92, 0x3d, 0x17, 0xb2, 0xcf, 0xa7, 0xa2, 0x22, 0x45, 0x6b, 0x3d, 0xdc, 0x61, 0xe9, 0xc3, - 0x91, 0x86, 0xa5, 0x9e, 0x14, 0x47, 0x43, 0xf6, 0xd3, 0xc9, 0x18, 0x16, 0x6b, 0x22, 0x4a, 0x61, - 0x33, 0x40, 0x29, 0x74, 0x0d, 0x36, 0x0b, 0xa5, 0x72, 0x61, 0xdd, 0x95, 0x93, 0xf2, 0x42, 0x45, - 0xde, 0x56, 0xe6, 0xe0, 0xa4, 0xaf, 0x74, 0x5b, 0x63, 0xb0, 0x1a, 0x72, 0xe5, 0xc2, 0xfa, 0x4a, - 0xb9, 0xb8, 0x52, 0x29, 0x97, 0xf2, 0xd4, 0x34, 0x52, 0xac, 0x51, 0x2d, 0xd3, 0xa5, 0x43, 0xaa, - 0xc5, 0x9c, 0x9a, 0x5f, 0x22, 0xea, 0xa6, 0x50, 0x94, 0x1f, 0x51, 0x6e, 0x82, 0xeb, 0x7c, 0xa4, - 0x30, 0x55, 0xb4, 0xaa, 0x16, 0x0b, 0xc5, 0x85, 0x52, 0xd9, 0x1e, 0x1a, 0x97, 0x2b, 0xf9, 0xb3, - 0x55, 0x71, 0x6d, 0x83, 0xfe, 0x21, 0x09, 0xa9, 0xaa, 0x65, 0xb4, 0xd1, 0xf7, 0x7a, 0x32, 0x7c, - 0x02, 0xc0, 0xc4, 0x3b, 0xc6, 0x1e, 0x99, 0x98, 0x32, 0xbd, 0xe2, 0x4b, 0x41, 0x7f, 0x2c, 0x6e, - 0xc3, 0x72, 0xd5, 0x82, 0xd1, 0x0e, 0x18, 0x97, 0xbe, 0x2d, 0x66, 0xc3, 0x0a, 0x2e, 0x28, 0x9a, - 0x18, 0xfd, 0x54, 0x62, 0x00, 0x31, 0x42, 0x70, 0xdc, 0xa7, 0x01, 0x6c, 0xbc, 0x1c, 0x06, 0x62, - 0xe5, 0x4a, 0x78, 0x51, 0x17, 0x66, 0x04, 0xaa, 0x4d, 0xe5, 0x7b, 0xe0, 0x1a, 0x3f, 0x54, 0x2b, - 0x95, 0x73, 0x45, 0x57, 0x3e, 0x0a, 0xb9, 0x5a, 0x4e, 0xde, 0x42, 0x9f, 0x92, 0x20, 0xb5, 0x62, - 0xec, 0x61, 0x74, 0x9d, 0xc7, 0xfc, 0x19, 0xc8, 0xb6, 0xf0, 0x45, 0x9f, 0x41, 0xc6, 0x79, 0x44, - 0x6f, 0x92, 0xa2, 0xb2, 0xdd, 0x2e, 0x3b, 0x80, 0xed, 0x9f, 0x4f, 0x46, 0x61, 0x7b, 0x8f, 0x82, - 0xa2, 0xb1, 0xfd, 0x6f, 0x06, 0x61, 0x7b, 0x00, 0x6b, 0xb1, 0x32, 0x0b, 0x27, 0xbc, 0x17, 0xa5, - 0x42, 0xb1, 0x5c, 0x2b, 0x2d, 0x3c, 0xec, 0x31, 0xb7, 0xa4, 0x0a, 0xb1, 0xbf, 0x9f, 0x76, 0x08, - 0x9f, 0x2c, 0xce, 0xc0, 0x31, 0xef, 0xdd, 0x22, 0x9d, 0xef, 0xd9, 0x6f, 0x1e, 0x41, 0x3f, 0x9f, - 0x86, 0x49, 0xaa, 0x2d, 0xd7, 0xda, 0x0d, 0x7b, 0x71, 0x74, 0x03, 0x67, 0x88, 0xb0, 0xf4, 0x1d, - 0xfc, 0x03, 0x46, 0xcb, 0x59, 0x1f, 0xb9, 0xcf, 0xe8, 0x13, 0xc2, 0x26, 0x08, 0x5e, 0x27, 0xd3, - 0x5a, 0x02, 0x70, 0x7e, 0x5e, 0xc8, 0xd8, 0x20, 0x50, 0x60, 0x34, 0xbc, 0x7f, 0x7c, 0xd8, 0xdd, - 0x2c, 0x18, 0x8a, 0xcd, 0x40, 0x28, 0xb6, 0x66, 0x1f, 0x4f, 0xc2, 0x78, 0x4d, 0xdf, 0xc1, 0xaf, - 0x32, 0x5a, 0xb8, 0xa3, 0x64, 0x41, 0x5a, 0x5c, 0xa9, 0xc9, 0x47, 0xec, 0x3f, 0xc5, 0x7c, 0x4d, - 0x4e, 0x90, 0x3f, 0x45, 0xbb, 0x6a, 0xfb, 0x4f, 0xae, 0x26, 0x4b, 0xf6, 0x9f, 0x95, 0x62, 0x4d, - 0x4e, 0xd9, 0x7f, 0xca, 0xc5, 0x9a, 0x9c, 0xb6, 0xff, 0xac, 0x2e, 0xd7, 0xe4, 0x8c, 0xfd, 0xa7, - 0x54, 0xad, 0xc9, 0x59, 0xfb, 0xcf, 0x7c, 0xb5, 0x26, 0x8f, 0xd9, 0x7f, 0xce, 0x55, 0x6b, 0xf2, - 0xb8, 0xfd, 0x27, 0x5f, 0xab, 0xc9, 0x60, 0xff, 0x79, 0xa8, 0x5a, 0x93, 0x27, 0xec, 0x3f, 0xb9, - 0x7c, 0x4d, 0x9e, 0x24, 0x7f, 0x8a, 0x35, 0x79, 0xca, 0xfe, 0x53, 0xad, 0xd6, 0xe4, 0x69, 0x52, - 0x72, 0xb5, 0x26, 0x1f, 0x25, 0x75, 0x95, 0x6a, 0xb2, 0x6c, 0xff, 0x59, 0xaa, 0xd6, 0xe4, 0x2b, - 0x48, 0xe6, 0x6a, 0x4d, 0x56, 0x48, 0xa5, 0xd5, 0x9a, 0xfc, 0x22, 0x92, 0xa7, 0x5a, 0x93, 0x8f, - 0x91, 0x2a, 0xaa, 0x35, 0xf9, 0xc5, 0x84, 0x8c, 0x62, 0x4d, 0x3e, 0x4e, 0xf2, 0xa8, 0x35, 0xf9, - 0x4a, 0xf2, 0xaa, 0x5c, 0x93, 0x67, 0x08, 0x61, 0xc5, 0x9a, 0xfc, 0x12, 0xf2, 0x47, 0xad, 0xc9, - 0x88, 0xbc, 0xca, 0xd5, 0xe4, 0xab, 0xd0, 0x35, 0x30, 0xbe, 0x88, 0x2d, 0x8a, 0x2f, 0x92, 0x41, - 0x5a, 0xc4, 0x96, 0x7f, 0xb5, 0xf1, 0xba, 0x19, 0x18, 0x3f, 0x6f, 0x98, 0x17, 0x3a, 0x6d, 0xad, - 0x8e, 0xd1, 0x7b, 0xe9, 0x3e, 0x5f, 0x7e, 0xd7, 0x34, 0x71, 0x8b, 0xcb, 0xf7, 0x94, 0xb8, 0x99, - 0xcc, 0x29, 0x6d, 0xce, 0x2b, 0x29, 0x60, 0xca, 0x72, 0x2d, 0x4c, 0x5c, 0x74, 0x72, 0x97, 0x1a, - 0x8e, 0x38, 0xf9, 0x92, 0x44, 0x4d, 0x66, 0xfd, 0xab, 0x8c, 0xdf, 0x04, 0xf4, 0xf6, 0x24, 0x64, - 0x16, 0xb1, 0x95, 0x6b, 0x36, 0xfd, 0x7c, 0x7b, 0xd2, 0xcf, 0xb7, 0x79, 0x9e, 0x6f, 0xb7, 0x06, - 0x37, 0x22, 0xd7, 0x6c, 0x06, 0xf0, 0x6c, 0x16, 0x26, 0x7d, 0x0c, 0xb2, 0xa7, 0xe5, 0xd2, 0xcd, - 0xe3, 0x2a, 0x97, 0x86, 0x7e, 0xdd, 0xe5, 0x5a, 0x91, 0xe3, 0xda, 0x1d, 0x51, 0x2a, 0x8c, 0x9f, - 0x63, 0x1f, 0xf0, 0x76, 0x80, 0xae, 0x09, 0xb5, 0x22, 0xa1, 0xd7, 0x0e, 0xc0, 0xc5, 0x50, 0x1b, - 0x4e, 0x7f, 0xc9, 0x8b, 0xca, 0xc3, 0x21, 0x18, 0x60, 0x06, 0xe1, 0xe1, 0x7b, 0xc7, 0x20, 0x53, - 0xd9, 0x78, 0xc4, 0x5e, 0x8c, 0x3c, 0x9f, 0x04, 0x29, 0xd7, 0x68, 0x74, 0x8d, 0x3a, 0x06, 0x79, - 0x59, 0x72, 0x96, 0x26, 0xee, 0x33, 0xfa, 0xd8, 0x00, 0x3d, 0x9a, 0xd6, 0x34, 0x97, 0x6b, 0x34, - 0x82, 0xb7, 0xd3, 0xdc, 0x0a, 0x93, 0x7c, 0x85, 0xca, 0x1d, 0xfc, 0x0e, 0x7e, 0x88, 0x99, 0xd1, - 0xdd, 0xda, 0x8f, 0xda, 0xfd, 0x03, 0xe9, 0x8b, 0x1f, 0x88, 0xcf, 0x27, 0x21, 0xbb, 0xac, 0x77, - 0x2c, 0x1b, 0x81, 0x9b, 0x3c, 0x04, 0xae, 0x86, 0x71, 0x87, 0x01, 0x9d, 0x99, 0x04, 0xe9, 0xab, - 0x5e, 0x02, 0x7a, 0xa3, 0x1f, 0x83, 0x87, 0x78, 0x0c, 0x5e, 0x16, 0xde, 0x46, 0x56, 0x57, 0x00, - 0x0e, 0x5c, 0xb5, 0xc9, 0xee, 0x6a, 0x7f, 0xdb, 0x65, 0xeb, 0x0a, 0xc7, 0xd6, 0x33, 0x83, 0x54, - 0x19, 0x3f, 0x6b, 0x3f, 0x93, 0x04, 0xb0, 0xeb, 0x56, 0xc9, 0x4a, 0x44, 0x9c, 0xbb, 0xaf, 0xf3, - 0x73, 0x77, 0x85, 0xe7, 0xee, 0x2b, 0xfb, 0x37, 0x95, 0x56, 0x17, 0xc0, 0x60, 0x19, 0x24, 0xdd, - 0x65, 0xad, 0xfd, 0x17, 0xbd, 0xdd, 0x65, 0xea, 0x2a, 0xc7, 0xd4, 0x7b, 0x07, 0xac, 0x29, 0x7e, - 0xbe, 0xfe, 0xcf, 0x24, 0xc8, 0x55, 0x6c, 0x95, 0x3a, 0x4b, 0xfa, 0xd6, 0x76, 0x53, 0xdf, 0xda, - 0xb6, 0x70, 0x03, 0x9d, 0x15, 0xd2, 0x1e, 0xca, 0xf5, 0x30, 0xa5, 0xfb, 0xbf, 0x63, 0x7b, 0x16, - 0x7c, 0x22, 0xfa, 0x49, 0x3f, 0x02, 0xcb, 0x3c, 0x02, 0xaf, 0x08, 0xe0, 0x4b, 0x37, 0x45, 0x01, - 0xf3, 0xdb, 0xdf, 0x71, 0xd9, 0x5d, 0xe1, 0xd8, 0x7d, 0xcf, 0x60, 0xc5, 0x8e, 0x64, 0x4b, 0xcd, - 0x31, 0x1b, 0xf9, 0x36, 0x28, 0xbb, 0x06, 0xa2, 0xc4, 0xfe, 0x81, 0xe8, 0x7f, 0x27, 0xa2, 0x8f, - 0x7d, 0x61, 0x86, 0xa2, 0xc8, 0x23, 0xdb, 0x10, 0x6c, 0x38, 0x83, 0xf0, 0xeb, 0xc7, 0x24, 0xc8, - 0x14, 0x2f, 0xb5, 0x0d, 0x7e, 0x37, 0x5d, 0x81, 0x54, 0xdb, 0x5b, 0x22, 0x93, 0xff, 0x02, 0x83, - 0xf9, 0x7b, 0x06, 0x98, 0x3f, 0xd0, 0xba, 0x03, 0xba, 0xbf, 0x43, 0x46, 0xd2, 0x47, 0xc6, 0xad, - 0x90, 0x26, 0x5e, 0x78, 0x6c, 0x74, 0xf3, 0xcc, 0x6f, 0x4e, 0x11, 0x45, 0xfb, 0xad, 0x4a, 0x33, - 0x45, 0x46, 0xa1, 0x27, 0x39, 0xf1, 0xa3, 0xf0, 0x85, 0x9f, 0x4b, 0xb8, 0x13, 0x8c, 0x9f, 0x4c, - 0x41, 0xaa, 0xd2, 0xc6, 0x2d, 0xf4, 0xb6, 0x04, 0xa7, 0x82, 0xeb, 0x46, 0xcb, 0xc2, 0x97, 0x3c, - 0x2d, 0xe1, 0x25, 0x84, 0xce, 0x07, 0x66, 0x20, 0x6b, 0x99, 0x14, 0x32, 0xe6, 0xd1, 0xc7, 0x1e, - 0x95, 0x32, 0xcc, 0xea, 0xad, 0x7a, 0x73, 0xb7, 0x81, 0x55, 0xdc, 0xd4, 0x6c, 0xda, 0x3b, 0xb9, - 0x4e, 0x01, 0xb7, 0x71, 0xab, 0x81, 0x5b, 0x16, 0xa5, 0xc6, 0xd9, 0xc8, 0x14, 0xc8, 0xc9, 0x2f, - 0xb0, 0xef, 0xe3, 0xe1, 0xbf, 0x89, 0xe3, 0x37, 0x53, 0xca, 0x76, 0x2b, 0x03, 0x90, 0x3f, 0x03, - 0x40, 0x5b, 0x70, 0x4e, 0xc7, 0x17, 0x99, 0xa5, 0xf5, 0x25, 0x5d, 0x96, 0xd6, 0x8a, 0x9b, 0x41, - 0xf5, 0x65, 0x46, 0x7f, 0xe2, 0x42, 0xfe, 0x20, 0x07, 0xf9, 0xad, 0x82, 0x24, 0x44, 0x43, 0xfb, - 0x5f, 0x0f, 0xb0, 0x10, 0xe7, 0xfc, 0x11, 0x25, 0xe5, 0x25, 0xf0, 0x62, 0xc7, 0x86, 0x58, 0x2e, - 0x16, 0x0b, 0xd5, 0xf5, 0xb5, 0xd5, 0x45, 0x35, 0x57, 0x28, 0xca, 0x80, 0xde, 0x97, 0x84, 0x34, - 0xd9, 0x71, 0x47, 0xf9, 0x21, 0xc8, 0x02, 0xfa, 0x46, 0x42, 0xd4, 0xc4, 0xc5, 0xd8, 0x43, 0xea, - 0x0e, 0x50, 0x70, 0xbf, 0x26, 0x64, 0x59, 0x0c, 0x29, 0x28, 0xfe, 0x6e, 0x65, 0x77, 0xa5, 0xea, - 0xb6, 0x71, 0xf1, 0xff, 0xff, 0xae, 0x64, 0xb7, 0xf2, 0x90, 0xbb, 0x52, 0x0f, 0x12, 0x5e, 0x48, - 0x5d, 0xe9, 0xc9, 0x94, 0xbb, 0x0c, 0x7e, 0xca, 0x27, 0x0d, 0xbe, 0xe5, 0x52, 0x42, 0x6c, 0xb9, - 0xa4, 0xe4, 0x60, 0x4a, 0x6f, 0x59, 0xd8, 0x6c, 0x69, 0xcd, 0x85, 0xa6, 0xb6, 0x45, 0xa7, 0xa7, - 0xfe, 0x7d, 0x1d, 0xca, 0xd3, 0x92, 0x2f, 0x8f, 0xca, 0x7f, 0xa1, 0x9c, 0x00, 0xb0, 0xf0, 0x4e, - 0xbb, 0xa9, 0x59, 0x9e, 0x30, 0xf9, 0x52, 0xd0, 0xd7, 0x85, 0xbd, 0x2f, 0x9d, 0xfe, 0xd5, 0xc7, - 0xfb, 0xd2, 0x95, 0x69, 0xa9, 0x4b, 0xa6, 0xdd, 0xe1, 0x34, 0x25, 0x30, 0x9c, 0xfa, 0xb9, 0x95, - 0x16, 0x5c, 0x5c, 0xbe, 0x41, 0xc8, 0xbd, 0x33, 0xac, 0x19, 0xf1, 0xeb, 0x89, 0xa7, 0x24, 0x98, - 0xa6, 0x55, 0xcf, 0x1b, 0xc6, 0x85, 0x1d, 0xcd, 0xbc, 0x80, 0xee, 0x3d, 0x88, 0x88, 0xa0, 0x8f, - 0xfb, 0xf1, 0x5b, 0xe4, 0xf1, 0xbb, 0x23, 0xb8, 0xe1, 0x4e, 0xed, 0xa3, 0x59, 0xf6, 0xbf, 0xc5, - 0x45, 0xe6, 0x21, 0x0e, 0x99, 0x57, 0x44, 0x26, 0x30, 0x7e, 0x84, 0xde, 0xe1, 0x22, 0xe4, 0xa8, - 0xcd, 0x03, 0x22, 0xf4, 0xe5, 0xc1, 0x10, 0x72, 0x6a, 0x1f, 0x00, 0x21, 0x19, 0xa4, 0x0b, 0xf8, - 0x32, 0xeb, 0x80, 0xf6, 0x5f, 0x3f, 0xd9, 0xa9, 0xf8, 0x30, 0x0b, 0x20, 0x79, 0x24, 0x98, 0x1d, - 0xe3, 0x49, 0xa8, 0xb4, 0x87, 0x80, 0xdc, 0x5f, 0x08, 0xdb, 0x1b, 0x7a, 0xb2, 0x81, 0xd2, 0x30, - 0x9a, 0x1e, 0x26, 0x66, 0xac, 0x10, 0x27, 0x33, 0x7e, 0xcc, 0x3e, 0x97, 0x82, 0x71, 0xc7, 0x27, - 0xd6, 0x42, 0xef, 0x49, 0x70, 0x9e, 0x30, 0x1d, 0x63, 0xd7, 0xac, 0x63, 0x66, 0x01, 0x62, 0x4f, - 0x7e, 0xb6, 0x24, 0x05, 0x07, 0xd0, 0x3e, 0xa3, 0xdf, 0xfe, 0x01, 0x36, 0x15, 0x75, 0x80, 0x45, - 0xaf, 0x91, 0x44, 0x97, 0xa2, 0x1c, 0xf7, 0xab, 0xd8, 0x7a, 0x21, 0x8e, 0xa1, 0x1f, 0x10, 0x5a, - 0xc5, 0xf6, 0x69, 0x49, 0x34, 0xe1, 0xa9, 0x0c, 0x30, 0x19, 0xbb, 0x0a, 0xae, 0x74, 0x72, 0x54, - 0xe6, 0x1f, 0x2a, 0xe6, 0x6b, 0xeb, 0x64, 0x26, 0xb6, 0xa6, 0x2e, 0xcb, 0x12, 0x7a, 0x2c, 0x05, - 0x32, 0x25, 0x8d, 0xd2, 0x59, 0xbb, 0xdc, 0xc6, 0xe8, 0x87, 0x0f, 0x79, 0x22, 0x86, 0xbe, 0xe9, - 0x57, 0x26, 0x25, 0x5e, 0x4e, 0xee, 0x0c, 0xe6, 0xae, 0xd7, 0x84, 0x00, 0x71, 0x19, 0xa0, 0x57, - 0x84, 0x48, 0x18, 0xfa, 0x88, 0x2b, 0x00, 0xcb, 0x9c, 0x00, 0xdc, 0x35, 0x00, 0x89, 0x87, 0x2c, - 0x07, 0x1f, 0x4d, 0xc2, 0x94, 0x33, 0x8d, 0x58, 0xc0, 0x56, 0x7d, 0x1b, 0x9d, 0x11, 0x5d, 0x9b, - 0xc9, 0x20, 0xed, 0x9a, 0x4d, 0x46, 0xa5, 0xfd, 0x17, 0xfd, 0x53, 0x42, 0x74, 0x77, 0x85, 0xf1, - 0x86, 0xab, 0x39, 0x60, 0x61, 0x2b, 0xb6, 0x1d, 0x22, 0x50, 0x60, 0xfc, 0xea, 0xfa, 0x8b, 0x49, - 0x80, 0x9a, 0xe1, 0x4e, 0x5a, 0x0f, 0xc0, 0x49, 0xee, 0x80, 0x46, 0x9e, 0xe7, 0x64, 0xcf, 0x15, - 0xbd, 0x57, 0x6d, 0xf4, 0xb1, 0x14, 0xbd, 0xc9, 0x65, 0xf1, 0x02, 0xc7, 0xe2, 0xd3, 0x91, 0x6a, - 0x8a, 0x9f, 0xbf, 0xef, 0x4b, 0xc2, 0x78, 0x61, 0xb7, 0xdd, 0xd4, 0xeb, 0xf6, 0xba, 0xf1, 0x26, - 0x41, 0xf6, 0xa2, 0xc7, 0x92, 0x11, 0x47, 0x1f, 0xb7, 0x8e, 0x00, 0x5e, 0x52, 0xb7, 0xc7, 0xa4, - 0xe3, 0xf6, 0x28, 0x68, 0xd6, 0xec, 0x53, 0xf8, 0x08, 0xc4, 0x53, 0x82, 0xa3, 0x95, 0x36, 0x6e, - 0xcd, 0x9b, 0x58, 0x6b, 0xd4, 0xcd, 0xdd, 0x9d, 0x8d, 0x0e, 0xca, 0x89, 0xca, 0xa8, 0xcf, 0xda, - 0x92, 0xe4, 0xac, 0x2d, 0xe8, 0x27, 0xfc, 0x83, 0xfb, 0x12, 0xcf, 0xde, 0xd3, 0x41, 0x56, 0x3e, - 0x1f, 0x0d, 0x03, 0x4c, 0xfe, 0x22, 0x59, 0x9d, 0xbb, 0x4c, 0x2e, 0xa9, 0x28, 0x26, 0x97, 0xdf, - 0x72, 0x91, 0x3d, 0xcb, 0x21, 0xfb, 0xca, 0xe8, 0xed, 0x1a, 0xc9, 0xe6, 0xc1, 0x74, 0x15, 0x5b, - 0x01, 0xf0, 0x5e, 0x0f, 0x53, 0x1b, 0xde, 0x1b, 0x17, 0x62, 0x3e, 0xb1, 0xc7, 0x16, 0xdf, 0xdb, - 0xa2, 0x2e, 0xcd, 0x78, 0x12, 0x02, 0xd0, 0x75, 0x11, 0x4c, 0x8a, 0xec, 0x1b, 0x44, 0x5a, 0x67, - 0x85, 0xd6, 0x1f, 0x3f, 0x0a, 0x6f, 0x95, 0x60, 0xba, 0xb4, 0xd3, 0x36, 0x4c, 0x6b, 0x45, 0x33, - 0x2f, 0x90, 0x13, 0xd1, 0x8b, 0xa2, 0x9d, 0xec, 0x04, 0x80, 0x4e, 0x3e, 0xf5, 0x79, 0x50, 0xfb, - 0x52, 0xd0, 0xb3, 0x51, 0xb1, 0xe0, 0x09, 0x09, 0xf6, 0x0b, 0x31, 0x0d, 0xc3, 0x5a, 0xd6, 0x5b, - 0x17, 0xbc, 0x9d, 0x73, 0x7f, 0x52, 0xc4, 0x5d, 0x9e, 0x48, 0x68, 0x85, 0x52, 0x18, 0x3f, 0x5a, - 0x1f, 0x4a, 0xc2, 0x44, 0x75, 0x5b, 0x33, 0xf1, 0xfc, 0x65, 0xbb, 0xb1, 0xa2, 0x7e, 0x24, 0xaf, - 0xf6, 0x03, 0xa1, 0x40, 0xaa, 0xa9, 0xb7, 0x2e, 0x38, 0xdb, 0x73, 0xf6, 0x7f, 0x2f, 0x2c, 0x40, - 0xb2, 0x47, 0x58, 0x00, 0xd7, 0x44, 0xeb, 0xd6, 0x1b, 0x30, 0xf7, 0x79, 0xb3, 0x50, 0x58, 0x80, - 0xbe, 0xc5, 0xc5, 0xcf, 0xc6, 0xcf, 0x26, 0xe1, 0x68, 0xae, 0xd1, 0x38, 0xaf, 0x5b, 0xdb, 0x15, - 0x87, 0x47, 0x0f, 0x88, 0x6d, 0xaa, 0xcf, 0x40, 0xb6, 0xad, 0x5d, 0x6e, 0x1a, 0x9a, 0x3b, 0xb0, - 0xb0, 0x47, 0xf4, 0x68, 0x32, 0xe2, 0xc0, 0xd2, 0x45, 0x41, 0x00, 0x53, 0x23, 0xe9, 0xf4, 0xf0, - 0x22, 0xe3, 0x67, 0xec, 0x9f, 0xa6, 0x20, 0x53, 0xc5, 0x9a, 0x59, 0xdf, 0x46, 0xaf, 0x4b, 0x7a, - 0x0c, 0x5d, 0x80, 0xec, 0xa6, 0xde, 0xb4, 0xb0, 0x49, 0x3d, 0x40, 0xfc, 0xf3, 0x18, 0x3a, 0x9e, - 0xcd, 0x37, 0x8d, 0xfa, 0x85, 0xb9, 0xbc, 0xad, 0x59, 0x5a, 0xd6, 0x9c, 0x73, 0xe6, 0x72, 0x6e, - 0x81, 0x7c, 0xa4, 0x3a, 0x1f, 0x2b, 0x0f, 0x42, 0xba, 0x63, 0x98, 0x96, 0xb3, 0x56, 0x3b, 0x29, - 0x56, 0x4a, 0xd5, 0x30, 0x2d, 0x95, 0x7e, 0x68, 0x43, 0xbb, 0xb9, 0xdb, 0x6c, 0xd6, 0xf0, 0x25, - 0xcb, 0x59, 0x27, 0x39, 0xcf, 0xca, 0x71, 0xc8, 0x18, 0x9b, 0x9b, 0x1d, 0x4c, 0x97, 0xe2, 0x69, - 0x95, 0x3d, 0x29, 0xc7, 0x20, 0xdd, 0xd4, 0x77, 0x74, 0x8b, 0xac, 0xb8, 0xd3, 0x2a, 0x7d, 0x50, - 0x4e, 0x82, 0x6c, 0xb8, 0xab, 0x24, 0x4a, 0xe8, 0x4c, 0x86, 0xe8, 0xa2, 0x7d, 0xe9, 0x76, 0x97, - 0xbb, 0x80, 0x2f, 0x77, 0x66, 0xb2, 0xe4, 0x3d, 0xf9, 0x8f, 0x9e, 0x8e, 0x6a, 0xa5, 0xa7, 0x7c, - 0x0d, 0x5e, 0x32, 0x9a, 0xb8, 0x6e, 0x98, 0x0d, 0x87, 0x37, 0xc1, 0x4b, 0x46, 0x96, 0x2f, 0x9a, - 0x6d, 0xbd, 0x67, 0xe5, 0xf1, 0xcb, 0xd3, 0xd3, 0x19, 0x48, 0x2f, 0x9a, 0x5a, 0x7b, 0x1b, 0xfd, - 0x46, 0x62, 0xf8, 0xe2, 0xe4, 0x02, 0x9b, 0xec, 0x07, 0xac, 0xd4, 0x07, 0xd8, 0x94, 0x0f, 0xd8, - 0x27, 0x93, 0x90, 0x2a, 0x36, 0xb6, 0x30, 0x67, 0xf4, 0x4a, 0xf8, 0x8c, 0x5e, 0xc7, 0x21, 0x63, - 0x69, 0xe6, 0x16, 0xb6, 0x18, 0x97, 0xd8, 0x93, 0xeb, 0x55, 0x29, 0xf9, 0xce, 0xe6, 0xbe, 0x12, - 0x52, 0x76, 0xbb, 0x88, 0x44, 0x4e, 0x9f, 0xbe, 0xae, 0x17, 0x34, 0x84, 0x3f, 0x73, 0x76, 0x8d, - 0x73, 0x36, 0x65, 0x2a, 0xf9, 0xa0, 0x1b, 0x8f, 0xf4, 0x3e, 0x3c, 0xec, 0xb1, 0x5d, 0xaf, 0x1b, - 0xad, 0xd2, 0x8e, 0xb6, 0x85, 0x67, 0x32, 0x74, 0x6c, 0x77, 0x13, 0x9c, 0xb7, 0xc5, 0x1d, 0xe3, - 0x11, 0x7d, 0x26, 0xeb, 0xbd, 0x25, 0x09, 0x76, 0x13, 0xb6, 0xf5, 0x46, 0x03, 0xb7, 0x66, 0xc6, - 0xe8, 0xc9, 0x36, 0xfa, 0x34, 0x7b, 0x02, 0x52, 0x36, 0x0d, 0x36, 0xc6, 0xb6, 0x62, 0x97, 0x8f, - 0x28, 0x93, 0xb6, 0x94, 0x53, 0xab, 0xa4, 0x9c, 0x40, 0x9f, 0x4c, 0x46, 0xdc, 0x43, 0xa6, 0x8d, - 0xeb, 0x2d, 0xf3, 0xb7, 0x41, 0xba, 0x65, 0x34, 0x70, 0x5f, 0x89, 0xa7, 0xb9, 0x94, 0x97, 0x41, - 0x1a, 0x37, 0xb6, 0x70, 0x87, 0x80, 0x39, 0x71, 0xfa, 0x44, 0x38, 0x2f, 0x55, 0x9a, 0x39, 0xda, - 0x46, 0x75, 0x2f, 0x6a, 0xe3, 0xef, 0x24, 0xff, 0x37, 0x03, 0x47, 0x69, 0xff, 0xac, 0xee, 0x6e, - 0xd8, 0x45, 0x6d, 0x60, 0xf4, 0x73, 0x12, 0x17, 0x0c, 0xa0, 0xb3, 0xbb, 0xe1, 0x8e, 0x65, 0xf4, - 0xc1, 0xdf, 0x89, 0x92, 0x43, 0xd1, 0xc9, 0xd2, 0xa0, 0x3a, 0x99, 0xd3, 0xaf, 0x92, 0xd3, 0x0d, - 0x3d, 0x6d, 0x9c, 0x21, 0xc9, 0x8e, 0x36, 0xee, 0xa1, 0x4b, 0xed, 0x41, 0x59, 0xdb, 0xb4, 0xb0, - 0x59, 0x6a, 0x10, 0x79, 0x1c, 0x57, 0x9d, 0x47, 0x5b, 0xdf, 0x6f, 0xe0, 0x4d, 0xc3, 0xb4, 0x17, - 0x82, 0xe3, 0x54, 0xdf, 0x3b, 0xcf, 0xbe, 0xfe, 0x09, 0x9c, 0x51, 0xfa, 0x66, 0x38, 0xaa, 0x6f, - 0xb5, 0x0c, 0x13, 0xbb, 0x9e, 0x3d, 0x33, 0x93, 0xf4, 0x14, 0x7b, 0x57, 0xb2, 0x72, 0x2b, 0x5c, - 0xd1, 0x32, 0x0a, 0xb8, 0xcd, 0xf8, 0x4e, 0x51, 0x9d, 0x22, 0x3d, 0x62, 0xff, 0x0b, 0xf4, 0x89, - 0xa8, 0x2b, 0xcf, 0x2e, 0x50, 0x87, 0xa6, 0xfa, 0x95, 0x7b, 0x60, 0xb2, 0xc1, 0xbc, 0x06, 0xea, - 0xba, 0xdb, 0x23, 0x02, 0xbf, 0xe3, 0x32, 0x7b, 0xe2, 0x94, 0xf2, 0x8b, 0xd3, 0x22, 0x8c, 0x91, - 0x63, 0x2a, 0xb6, 0x3c, 0xa5, 0xbb, 0x0e, 0x42, 0x93, 0xe9, 0xb6, 0xdb, 0x28, 0x1f, 0x4b, 0xe6, - 0xf2, 0xec, 0x13, 0xd5, 0xfd, 0x38, 0xda, 0x7c, 0x27, 0x9c, 0x43, 0xf1, 0x77, 0xbd, 0x5f, 0x4c, - 0xc1, 0xd1, 0x45, 0xd3, 0xd8, 0x6d, 0x77, 0xbc, 0xae, 0xe7, 0x0f, 0xb7, 0xd0, 0xbb, 0xeb, 0xd9, - 0x2b, 0x18, 0xa6, 0x13, 0xcf, 0x62, 0x27, 0xda, 0x8b, 0x3f, 0xc9, 0xdf, 0x39, 0xa5, 0x83, 0x74, - 0x4e, 0x4f, 0xc4, 0x53, 0x7e, 0x11, 0x47, 0x5f, 0x88, 0x3a, 0x57, 0xed, 0x6a, 0x64, 0x80, 0x28, - 0xe6, 0x21, 0xb3, 0x45, 0x32, 0x32, 0x49, 0xbc, 0x45, 0x8c, 0x6a, 0x52, 0xb8, 0xca, 0x3e, 0xf5, - 0x78, 0x26, 0xf9, 0x78, 0x16, 0x4d, 0x2c, 0xc2, 0xa9, 0x1d, 0x81, 0x69, 0x23, 0x05, 0x93, 0x6e, - 0xed, 0xa5, 0x46, 0x07, 0x19, 0xfd, 0x44, 0x62, 0x9f, 0x21, 0xc3, 0xd5, 0x73, 0x92, 0x4f, 0xcf, - 0xf5, 0xd0, 0x4c, 0x13, 0x3d, 0x35, 0x13, 0x7a, 0x54, 0x12, 0x0d, 0xf5, 0xc2, 0x77, 0x4b, 0x42, - 0xee, 0x0b, 0x59, 0xd1, 0x08, 0x06, 0x9c, 0xe9, 0xdf, 0xaa, 0xf8, 0xa5, 0xe0, 0x99, 0x24, 0x5c, - 0x41, 0x15, 0xd4, 0x5a, 0xab, 0xe3, 0xaa, 0x07, 0x3e, 0x3e, 0x00, 0x69, 0x53, 0xc7, 0xdd, 0x15, - 0x25, 0x4f, 0xbc, 0x05, 0x38, 0xf4, 0xc8, 0x01, 0xa7, 0x06, 0x7d, 0xb5, 0x04, 0xac, 0x25, 0xc5, - 0x0e, 0x15, 0x08, 0x16, 0x3a, 0x02, 0xed, 0x2a, 0xc1, 0x78, 0x15, 0x5b, 0xcb, 0xda, 0x65, 0x63, - 0xd7, 0x42, 0x9a, 0xa8, 0x59, 0xea, 0x2e, 0xc8, 0x34, 0xc9, 0x27, 0x44, 0x83, 0x4c, 0x9f, 0xbe, - 0xb6, 0xa7, 0xf1, 0x94, 0x6c, 0x6e, 0xd1, 0xa2, 0x55, 0x96, 0x9f, 0x3f, 0xeb, 0x21, 0x62, 0x7a, - 0x77, 0xa9, 0x1b, 0x8a, 0xdd, 0x30, 0x92, 0x61, 0x3e, 0xa8, 0xea, 0xf8, 0x61, 0xf9, 0x09, 0x09, - 0xa6, 0x88, 0xab, 0xfe, 0x82, 0xb6, 0x67, 0x98, 0xba, 0x85, 0xa3, 0x59, 0x0c, 0xdd, 0xcf, 0xd8, - 0x79, 0x04, 0x5f, 0x0a, 0x7a, 0x6b, 0x32, 0xe2, 0x96, 0x1c, 0x47, 0xc7, 0x50, 0x40, 0x88, 0xb4, - 0x81, 0x17, 0x56, 0xfd, 0x08, 0x81, 0xc8, 0x99, 0xf5, 0x6d, 0x7d, 0x0f, 0x37, 0x22, 0x02, 0xe1, - 0x7c, 0xe6, 0x01, 0xe1, 0x16, 0x34, 0x18, 0x10, 0xce, 0xe7, 0x87, 0x04, 0x44, 0x40, 0xf5, 0xf1, - 0x03, 0xf1, 0x16, 0x0a, 0x84, 0xcf, 0x37, 0x61, 0x45, 0x14, 0x88, 0xeb, 0x61, 0xca, 0xb3, 0x2a, - 0xac, 0x99, 0x4d, 0x36, 0xeb, 0xe1, 0x13, 0xd1, 0x47, 0x06, 0x80, 0xa3, 0xaf, 0x9b, 0x41, 0x34, - 0x38, 0x3e, 0x1c, 0x11, 0x8e, 0x17, 0xaa, 0x0b, 0xc1, 0xb3, 0x12, 0x3d, 0x51, 0xc5, 0x79, 0x72, - 0x3c, 0x22, 0x0a, 0xd7, 0x3e, 0xaf, 0x91, 0x6c, 0x64, 0xaf, 0x91, 0x8f, 0x47, 0xf5, 0x1a, 0xe9, - 0xa6, 0x76, 0x28, 0x70, 0x46, 0x72, 0x0a, 0xe9, 0x43, 0xc1, 0x21, 0x23, 0xfa, 0x35, 0x09, 0x80, - 0xc4, 0x19, 0xa6, 0xfe, 0x4e, 0x4b, 0x90, 0xa1, 0x7f, 0x1d, 0xa7, 0xc9, 0x84, 0xe7, 0x34, 0x79, - 0x2b, 0xa4, 0xf7, 0xb4, 0xe6, 0x2e, 0x76, 0x79, 0xd4, 0x3d, 0x11, 0x3d, 0x67, 0xbf, 0x55, 0x69, - 0x26, 0xb4, 0x2d, 0x2a, 0x15, 0x0f, 0xf8, 0x1d, 0x76, 0x6c, 0x79, 0xb8, 0x21, 0x80, 0x8b, 0x8c, - 0xc6, 0x39, 0xfa, 0xeb, 0xf9, 0x68, 0xbd, 0x29, 0xaa, 0x03, 0x85, 0xaf, 0xac, 0x61, 0x48, 0x43, - 0x24, 0x97, 0x8a, 0xc0, 0xba, 0xe3, 0x57, 0xb4, 0x1f, 0x4f, 0x42, 0xba, 0x66, 0x54, 0x31, 0x77, - 0xde, 0x2c, 0x1c, 0x1b, 0x6f, 0x09, 0x9c, 0xe4, 0x96, 0xc0, 0x3f, 0x16, 0xd5, 0x14, 0x49, 0xea, - 0x0d, 0x0e, 0x26, 0xda, 0xc1, 0xde, 0xd6, 0x3f, 0x7d, 0x88, 0x66, 0x3b, 0xec, 0x55, 0x7c, 0xfc, - 0x0c, 0x3d, 0x03, 0x47, 0xd7, 0x5a, 0x0d, 0x43, 0xc5, 0x0d, 0x83, 0xd9, 0x62, 0xec, 0x85, 0xe7, - 0x6e, 0xab, 0x61, 0x10, 0x5a, 0xd3, 0x2a, 0xf9, 0x6f, 0xa7, 0x99, 0xb8, 0x61, 0x30, 0x43, 0x39, - 0xf9, 0x8f, 0x5e, 0x2f, 0x41, 0xca, 0xfe, 0x56, 0xdc, 0xb3, 0xe5, 0xeb, 0x51, 0x0f, 0xa6, 0xd8, - 0xc5, 0x0f, 0x43, 0xbe, 0x95, 0x07, 0x7c, 0xd6, 0x29, 0xba, 0x29, 0x7c, 0x5d, 0x50, 0x7d, 0x3e, - 0x56, 0xf8, 0xac, 0x52, 0xef, 0x88, 0x72, 0x98, 0xa5, 0x07, 0xd9, 0xd1, 0x90, 0x2c, 0x0c, 0xa0, - 0x22, 0x65, 0x98, 0xcc, 0xe7, 0xca, 0x24, 0x32, 0xcb, 0x4a, 0xe5, 0x5c, 0x51, 0x96, 0x08, 0x40, - 0x76, 0x6b, 0x62, 0x04, 0xc8, 0x2e, 0xfe, 0xbb, 0x10, 0xa0, 0x1e, 0x64, 0x1f, 0x06, 0x40, 0x1f, - 0x4d, 0xc2, 0xd4, 0xb2, 0xde, 0xb1, 0x82, 0x9c, 0xc4, 0x42, 0xce, 0xcd, 0xbf, 0x26, 0xea, 0x84, - 0x90, 0xab, 0x47, 0xf8, 0xc0, 0x7c, 0xa4, 0x39, 0x78, 0x58, 0x15, 0xa3, 0xf1, 0x66, 0x24, 0x14, - 0xd0, 0x30, 0x8c, 0xc2, 0x9c, 0x8c, 0x3c, 0xf4, 0x7a, 0x95, 0x8c, 0x7e, 0xe8, 0x0d, 0xac, 0x3b, - 0x7e, 0xfe, 0xfe, 0x75, 0x12, 0xae, 0xb0, 0xab, 0x0f, 0x5b, 0x70, 0x06, 0xb3, 0xb9, 0xef, 0x82, - 0x33, 0xb2, 0xcd, 0x6b, 0x1f, 0x2d, 0xc3, 0xb0, 0x79, 0xf5, 0x2b, 0x74, 0xc4, 0x6c, 0x0e, 0x30, - 0xb0, 0xf4, 0x63, 0x73, 0x88, 0x81, 0x65, 0x70, 0x36, 0x87, 0x1b, 0x59, 0x06, 0x64, 0xf3, 0xa1, - 0x99, 0x4e, 0x3e, 0x9f, 0x84, 0xa9, 0x5c, 0xbb, 0xdd, 0xbc, 0x5c, 0x63, 0x27, 0x47, 0x22, 0x99, - 0x4e, 0x7c, 0x07, 0x50, 0x92, 0xfb, 0x8e, 0x5f, 0x46, 0x76, 0x2b, 0xe7, 0xe8, 0x18, 0x86, 0x5b, - 0x79, 0x58, 0x81, 0xf1, 0xb3, 0xf6, 0xd5, 0x69, 0xaa, 0x88, 0x59, 0x60, 0x88, 0xcf, 0x26, 0xc2, - 0x23, 0x43, 0x84, 0x86, 0xc1, 0x51, 0xee, 0x83, 0xcc, 0xa6, 0x61, 0xee, 0x68, 0x8e, 0x2d, 0xf7, - 0x86, 0x20, 0x71, 0x62, 0xb1, 0x17, 0x16, 0x48, 0x66, 0x95, 0x7d, 0x64, 0x8f, 0x68, 0xaf, 0xd2, - 0xdb, 0xec, 0xec, 0xb4, 0xfd, 0x97, 0x04, 0x45, 0xa1, 0x47, 0xa8, 0xcb, 0xb8, 0x63, 0xe1, 0x06, - 0xd9, 0xac, 0x1c, 0x53, 0xf9, 0x44, 0x65, 0x16, 0x26, 0x59, 0xc2, 0x82, 0xde, 0xc4, 0x1d, 0xb2, - 0x05, 0x3d, 0xa6, 0x72, 0x69, 0xe8, 0x53, 0x83, 0x0c, 0x1c, 0x91, 0x23, 0x56, 0xcc, 0x40, 0xb6, - 0xb3, 0x5b, 0xaf, 0x63, 0xdc, 0x60, 0x5e, 0x49, 0xce, 0x63, 0x44, 0x2f, 0xc7, 0xc8, 0xc3, 0xcc, - 0xe1, 0x04, 0xb3, 0x98, 0x5d, 0x85, 0x0c, 0xc5, 0x50, 0x99, 0x84, 0x31, 0xc7, 0xcf, 0x92, 0xfa, - 0x91, 0xac, 0xb2, 0x45, 0xba, 0x9c, 0xb0, 0x4b, 0x7c, 0xa8, 0x5a, 0x29, 0xd3, 0xe0, 0x80, 0x85, - 0x0a, 0x0b, 0x0e, 0x58, 0x3d, 0xb7, 0x28, 0xa7, 0x94, 0x69, 0x80, 0x45, 0x35, 0xb7, 0xba, 0xb4, - 0x4e, 0x72, 0xa4, 0xd1, 0xb3, 0x59, 0xc8, 0x50, 0xb7, 0x4d, 0xf4, 0x4c, 0xda, 0x7f, 0x39, 0xd3, - 0x64, 0xcb, 0xb0, 0xc9, 0x5c, 0xd5, 0x4c, 0x6d, 0xa7, 0x13, 0xb6, 0x37, 0x46, 0xbf, 0x76, 0x2f, - 0x66, 0x2a, 0xfb, 0x3e, 0x5b, 0x3a, 0xa2, 0x72, 0xc5, 0x28, 0xff, 0x06, 0x8e, 0x6e, 0xb0, 0x03, - 0x07, 0x1d, 0x56, 0x72, 0x32, 0x78, 0x5b, 0xb5, 0xab, 0xe4, 0x79, 0xfe, 0xcb, 0xa5, 0x23, 0x6a, - 0x77, 0x61, 0x4a, 0x09, 0xc6, 0x3b, 0x2d, 0xad, 0xdd, 0xd9, 0x36, 0x5c, 0x97, 0x8b, 0x5b, 0x04, - 0x4a, 0xae, 0xb2, 0x6f, 0x54, 0xef, 0x6b, 0xe5, 0x65, 0xf0, 0xe2, 0x5d, 0x12, 0x4d, 0xb2, 0x78, - 0x49, 0xef, 0x58, 0x7a, 0x6b, 0x8b, 0x0f, 0x35, 0xd0, 0xfb, 0xa5, 0x72, 0x0f, 0xf3, 0x48, 0x4a, - 0x13, 0xf1, 0xb9, 0x49, 0xa0, 0x6e, 0x9f, 0x57, 0xd2, 0x3d, 0x90, 0xda, 0xb1, 0x65, 0x2f, 0x23, - 0xfc, 0xf1, 0x0a, 0x11, 0x38, 0xfb, 0x23, 0x34, 0x0b, 0x93, 0x7e, 0xd6, 0xf7, 0xd2, 0x26, 0xe8, - 0x3a, 0x38, 0xda, 0xc5, 0x44, 0xe7, 0xb8, 0x4a, 0xc2, 0x3b, 0xae, 0xf2, 0x83, 0x30, 0xe6, 0xf0, - 0x63, 0x5f, 0x4c, 0xe8, 0x1c, 0x8c, 0x39, 0x1c, 0x62, 0xc0, 0xdd, 0xd0, 0x65, 0xdb, 0xab, 0xee, - 0x68, 0xa6, 0x45, 0x76, 0xb2, 0x9d, 0x42, 0xe6, 0xb5, 0x0e, 0x56, 0xdd, 0xcf, 0x66, 0x6f, 0x83, - 0x94, 0x4d, 0xb5, 0xa2, 0xc0, 0x74, 0x6e, 0x79, 0x79, 0xbd, 0x42, 0xe2, 0x91, 0x2f, 0x95, 0xca, - 0x8b, 0xb4, 0x03, 0x94, 0x16, 0xcb, 0x15, 0xb5, 0x48, 0xe5, 0xbf, 0x2a, 0x27, 0x66, 0xaf, 0x65, - 0x3e, 0x53, 0x00, 0x19, 0xda, 0x3c, 0x2a, 0xed, 0xc5, 0x4b, 0xd4, 0xe0, 0x26, 0x93, 0x6b, 0x12, - 0xda, 0xa4, 0x2d, 0xbc, 0xd1, 0x42, 0xc4, 0x69, 0xd0, 0xe5, 0x66, 0xaf, 0x41, 0xe5, 0x5d, 0x51, - 0x3c, 0x00, 0x7b, 0x96, 0x14, 0x4d, 0x1f, 0x2c, 0xec, 0xd3, 0x07, 0x0a, 0x4c, 0x97, 0xca, 0xb5, - 0xa2, 0x5a, 0xce, 0x2d, 0xbb, 0x0a, 0x61, 0x9f, 0x8e, 0x48, 0xf2, 0x3a, 0x42, 0x42, 0x5f, 0x97, - 0x00, 0x28, 0x39, 0xb6, 0xa2, 0xf2, 0x87, 0x72, 0xfc, 0x6c, 0x54, 0x9d, 0xec, 0x15, 0x13, 0xa0, - 0x93, 0x4b, 0x30, 0x66, 0xb2, 0x17, 0xcc, 0xb6, 0xd7, 0xaf, 0x1c, 0xfa, 0xd7, 0x29, 0x4d, 0x75, - 0x3f, 0x47, 0xef, 0x8d, 0xa2, 0x82, 0x03, 0x09, 0x3b, 0x1c, 0x96, 0xbf, 0xca, 0x39, 0x25, 0xe0, - 0x9b, 0xd9, 0x50, 0x3d, 0x20, 0xd6, 0x06, 0xfe, 0x63, 0x9f, 0x4a, 0x08, 0x12, 0x7f, 0x57, 0xf5, - 0x27, 0xd0, 0x87, 0x8e, 0xc2, 0x34, 0x2d, 0xd1, 0x3d, 0xbe, 0xff, 0x8f, 0x2c, 0x8e, 0xe2, 0x59, - 0xd1, 0x49, 0xdb, 0x2c, 0x4c, 0xfa, 0xfc, 0x6b, 0xdc, 0x90, 0x9c, 0xfe, 0x34, 0xfe, 0x3e, 0xa7, - 0xd0, 0x8b, 0xf2, 0x78, 0x6a, 0x42, 0x62, 0x2d, 0x46, 0x5b, 0x0a, 0x46, 0xf1, 0x9f, 0x0f, 0xa9, - 0x3c, 0xfe, 0x29, 0xde, 0x63, 0xde, 0x75, 0x07, 0x43, 0x45, 0x20, 0xea, 0xe1, 0x1d, 0x97, 0x09, - 0x62, 0xeb, 0xf1, 0xa1, 0x1f, 0x07, 0x09, 0xaf, 0x3f, 0x7e, 0x1c, 0xbe, 0xc3, 0x0c, 0x48, 0xb9, - 0x3d, 0x4d, 0x6f, 0x6a, 0x1b, 0xcd, 0x08, 0xa7, 0x0c, 0x3f, 0xe4, 0x67, 0x75, 0x99, 0x67, 0xf5, - 0x5d, 0x61, 0x4d, 0xe5, 0xea, 0x0b, 0xbc, 0x91, 0x62, 0xdc, 0xc1, 0xd5, 0xf3, 0x15, 0xe2, 0x47, - 0x51, 0xa7, 0x3c, 0xd5, 0xcb, 0x89, 0x7e, 0xd7, 0x65, 0xfd, 0xf7, 0x71, 0xac, 0xbf, 0x6f, 0x50, - 0x7a, 0xe2, 0x47, 0xe0, 0x67, 0x24, 0x98, 0xc8, 0x35, 0x1a, 0x0b, 0x58, 0xb3, 0x76, 0x4d, 0xdc, - 0x40, 0x45, 0xd1, 0xee, 0x70, 0x75, 0x37, 0x8b, 0xc6, 0xfd, 0x9c, 0x78, 0x8f, 0x70, 0x50, 0xc6, - 0xfd, 0xda, 0xc0, 0xa1, 0x65, 0x28, 0x2a, 0x49, 0x2c, 0x84, 0xa3, 0x30, 0x11, 0xf1, 0x03, 0xf2, - 0x5a, 0x09, 0xa6, 0x69, 0xac, 0xce, 0x61, 0x63, 0xf2, 0x7e, 0x3f, 0x26, 0x15, 0x1e, 0x93, 0x33, - 0x61, 0xec, 0xe0, 0xc9, 0x19, 0x0a, 0x2c, 0x9e, 0xb5, 0x5b, 0xe5, 0x60, 0xb9, 0x7f, 0x60, 0x3a, - 0xe2, 0x47, 0xe6, 0x1b, 0x00, 0xe0, 0xf3, 0x90, 0xf8, 0x12, 0x78, 0x27, 0x03, 0xd0, 0xc7, 0x25, - 0x3a, 0x9e, 0x57, 0xb9, 0x03, 0xa0, 0xbc, 0x63, 0x44, 0xa2, 0x87, 0x63, 0x84, 0xd0, 0xa8, 0xf2, - 0xad, 0x88, 0x1b, 0xee, 0xcc, 0x67, 0xa1, 0xef, 0xe0, 0x3e, 0xa0, 0x96, 0x7b, 0x2e, 0xc2, 0xce, - 0x7b, 0x3f, 0x52, 0xe2, 0xbf, 0x80, 0x27, 0x6c, 0xe7, 0x5d, 0x99, 0x81, 0x63, 0x6a, 0x31, 0x57, - 0xa8, 0x94, 0x97, 0x1f, 0xf6, 0xbf, 0x95, 0x53, 0xe8, 0xd7, 0x24, 0xc8, 0xb0, 0x58, 0xc0, 0xb1, - 0x60, 0xfa, 0x5f, 0x22, 0x2a, 0x48, 0x9e, 0x91, 0x61, 0x61, 0x83, 0xd1, 0x7f, 0x8b, 0xa0, 0xf2, - 0x04, 0x8a, 0x7d, 0xc1, 0x42, 0xf4, 0x45, 0x09, 0x52, 0x64, 0xfd, 0xb4, 0x1b, 0x15, 0xa0, 0x02, - 0x5c, 0xa3, 0xb5, 0xdb, 0xb8, 0xd5, 0x70, 0xa3, 0x10, 0x2e, 0x98, 0xc6, 0x4e, 0xc5, 0xda, 0xc6, - 0xa6, 0x9d, 0xa5, 0xc3, 0xec, 0xce, 0xe1, 0x99, 0xd0, 0x17, 0x23, 0x9a, 0xa2, 0x79, 0x5e, 0x87, - 0x2c, 0xd9, 0xce, 0xec, 0xef, 0x97, 0x57, 0x05, 0xf4, 0xcb, 0x65, 0xbd, 0x75, 0xc1, 0xdf, 0x37, - 0xff, 0x24, 0x82, 0x15, 0xbb, 0x2f, 0x3d, 0x87, 0xec, 0x16, 0xf3, 0x68, 0xc6, 0xa7, 0x60, 0x7f, - 0x52, 0x02, 0xd9, 0x0b, 0x63, 0xcd, 0x42, 0x69, 0x55, 0xf8, 0x5d, 0x05, 0x92, 0xe8, 0xdf, 0x55, - 0x70, 0x12, 0x94, 0x1b, 0x61, 0xba, 0xbe, 0x8d, 0xeb, 0x17, 0x4a, 0x2d, 0xc7, 0x44, 0x44, 0x11, - 0xee, 0x4a, 0xe5, 0xfd, 0x67, 0xcf, 0xf2, 0x90, 0xf2, 0x96, 0x6a, 0x8e, 0x6f, 0x7e, 0xa2, 0x02, - 0x3a, 0xa5, 0x07, 0x4c, 0x99, 0x03, 0xe6, 0xee, 0x81, 0x4a, 0x8d, 0x86, 0x4c, 0x79, 0xb0, 0xeb, - 0x52, 0x2a, 0xab, 0xe4, 0x7e, 0xc1, 0xb5, 0x6a, 0xb1, 0xb0, 0x3e, 0xef, 0x74, 0xbe, 0xaa, 0x2c, - 0xa1, 0xaf, 0x25, 0x21, 0x4b, 0xc9, 0xea, 0x74, 0x85, 0x99, 0xf6, 0x9f, 0x0a, 0x49, 0xec, 0x3b, - 0x15, 0x82, 0xde, 0x2e, 0xec, 0x9e, 0xec, 0x32, 0x82, 0xd5, 0x13, 0xd0, 0x53, 0xee, 0x82, 0x2c, - 0x05, 0xd9, 0x31, 0x52, 0x9e, 0x08, 0xe8, 0x27, 0xac, 0x18, 0xd5, 0xc9, 0x2e, 0xe8, 0xaa, 0xdc, - 0x87, 0x8c, 0xf8, 0xe7, 0x1c, 0x6f, 0x9e, 0x80, 0xec, 0x92, 0xde, 0xb1, 0x0c, 0xf3, 0x32, 0x7a, - 0x53, 0x02, 0xb2, 0xe7, 0xb0, 0xd9, 0xd1, 0x8d, 0xd6, 0x3e, 0xab, 0xdf, 0xb5, 0x30, 0xd1, 0x36, - 0xf1, 0x9e, 0x6e, 0xec, 0x76, 0x7c, 0x31, 0x05, 0x7c, 0x49, 0x0a, 0x82, 0x31, 0x6d, 0xd7, 0xda, - 0x36, 0x4c, 0x2f, 0xc0, 0x92, 0xf3, 0xac, 0x9c, 0x00, 0xa0, 0xff, 0xcb, 0xda, 0x0e, 0x66, 0xa7, - 0x15, 0x7c, 0x29, 0x8a, 0x02, 0x29, 0x4b, 0xdf, 0xc1, 0xec, 0x7c, 0x1b, 0xf9, 0xaf, 0xcc, 0x40, - 0x96, 0x9c, 0x77, 0x29, 0x35, 0xd8, 0xf9, 0x36, 0xe7, 0x11, 0xfd, 0xa6, 0x04, 0x13, 0x8b, 0xd8, - 0x62, 0xa4, 0x76, 0xfc, 0x7e, 0xef, 0x7d, 0xa2, 0xbd, 0x37, 0xb5, 0x8e, 0xf3, 0x99, 0xbb, 0x33, - 0xc5, 0x27, 0x7a, 0x67, 0xed, 0x24, 0xdf, 0x91, 0x57, 0xf4, 0xae, 0xa4, 0xe8, 0x69, 0x11, 0xc6, - 0xcc, 0x39, 0x1f, 0x81, 0x81, 0xb2, 0x35, 0xb6, 0xc7, 0x72, 0x30, 0x25, 0x7c, 0x75, 0xcf, 0x92, - 0x58, 0x31, 0xaa, 0x9b, 0x5b, 0xf0, 0x84, 0x47, 0x7f, 0x4a, 0xe2, 0x17, 0xaf, 0xbf, 0x97, 0x60, - 0xa2, 0xba, 0x6d, 0x5c, 0x64, 0x04, 0xa0, 0x1f, 0x14, 0x83, 0xea, 0x6a, 0x18, 0xdf, 0xeb, 0x82, - 0xc9, 0x4b, 0x08, 0x0e, 0x14, 0x8c, 0x9e, 0x90, 0xa2, 0xc2, 0xe4, 0x23, 0x6e, 0xe8, 0x01, 0x7e, - 0x95, 0x57, 0x40, 0x96, 0x51, 0xcd, 0x2c, 0x2b, 0xe1, 0x00, 0x3b, 0x99, 0xfd, 0x0d, 0x4c, 0xf1, - 0x0d, 0x8c, 0x86, 0x7c, 0x70, 0xe3, 0x46, 0x10, 0xe8, 0x20, 0x49, 0x7c, 0x4e, 0x1d, 0xe0, 0xf3, - 0x43, 0x00, 0x1e, 0x7d, 0x3b, 0x21, 0x6a, 0x7f, 0x74, 0x39, 0xe0, 0x52, 0x70, 0xa0, 0x88, 0x1c, - 0x7d, 0x8b, 0x8b, 0x9f, 0x9f, 0x3f, 0x7a, 0x05, 0xa4, 0x16, 0xf4, 0x26, 0xb6, 0xd7, 0xef, 0xd9, - 0xca, 0xe6, 0x26, 0x89, 0xa8, 0x51, 0x0c, 0xbe, 0xba, 0xf3, 0x24, 0xc8, 0xce, 0x8e, 0xad, 0x61, - 0xad, 0xea, 0xad, 0x96, 0xeb, 0x54, 0xb2, 0x2f, 0x9d, 0x37, 0x75, 0x85, 0x7a, 0x7a, 0xda, 0x14, - 0xcc, 0xb1, 0xda, 0x03, 0xfa, 0xcb, 0x8d, 0x30, 0xbd, 0x71, 0xd9, 0xc2, 0x1d, 0x96, 0x8b, 0x55, - 0x9b, 0x52, 0xbb, 0x52, 0xd1, 0xb3, 0x42, 0xbe, 0x9f, 0x21, 0x15, 0x46, 0xe3, 0xb9, 0x36, 0xc0, - 0x1c, 0xe5, 0x18, 0xc8, 0xe5, 0x4a, 0xa1, 0x48, 0xef, 0xb8, 0xac, 0xe5, 0xd4, 0x5a, 0xb1, 0x20, - 0x6f, 0x91, 0x8b, 0xfd, 0x4a, 0xcb, 0x34, 0xf5, 0xe1, 0x62, 0x6d, 0x7d, 0xb5, 0x54, 0x2e, 0x17, - 0x0b, 0xf2, 0x36, 0x7a, 0x9f, 0x04, 0x13, 0xf6, 0xbc, 0xca, 0x41, 0xa7, 0xc2, 0xdd, 0x8b, 0x68, - 0xb4, 0x9a, 0x97, 0xbd, 0xb9, 0xa3, 0xf3, 0x18, 0x09, 0xa7, 0xff, 0x2a, 0x3c, 0xbd, 0x21, 0x6c, - 0xf3, 0xd1, 0x12, 0x8c, 0xd5, 0xa6, 0xde, 0xec, 0xc6, 0x2a, 0xad, 0x76, 0xa5, 0xf6, 0xc0, 0x54, - 0xea, 0x89, 0xe9, 0x1f, 0x08, 0x4d, 0x7a, 0xfa, 0x10, 0x17, 0x0d, 0xd7, 0xa5, 0x61, 0xe1, 0x8a, - 0xbe, 0x29, 0x41, 0x66, 0xad, 0x4d, 0x90, 0x7b, 0xce, 0xe7, 0x92, 0xb1, 0x6f, 0x77, 0xd4, 0x56, - 0x52, 0x4d, 0xfe, 0x22, 0x78, 0xd5, 0x4b, 0x50, 0xee, 0x66, 0xdb, 0x3e, 0xd4, 0x1d, 0xe3, 0xc6, - 0xd0, 0x03, 0xbe, 0x84, 0x13, 0xbe, 0xdd, 0xdf, 0x5b, 0xe1, 0x8a, 0x86, 0xde, 0xd1, 0x36, 0x9a, - 0xb8, 0xd8, 0xaa, 0x9b, 0x97, 0x69, 0xa3, 0xe9, 0x66, 0xf3, 0xfe, 0x17, 0xca, 0x7d, 0x90, 0xee, - 0x58, 0x97, 0x9b, 0xfb, 0x77, 0x9a, 0x03, 0xab, 0xaa, 0xda, 0xd9, 0x55, 0xfa, 0x15, 0xfa, 0x4e, - 0x42, 0xd4, 0x97, 0x95, 0x7c, 0x4b, 0x59, 0x13, 0xec, 0x98, 0xb1, 0xad, 0x75, 0x5c, 0xc7, 0x0c, - 0xfb, 0x3f, 0x7a, 0x4a, 0xc8, 0xe1, 0x34, 0xb8, 0xec, 0x11, 0xdc, 0x0b, 0x92, 0x84, 0xb1, 0x82, - 0x71, 0xb1, 0x45, 0x30, 0xbf, 0x83, 0xf3, 0xc2, 0x21, 0xad, 0x49, 0x78, 0xad, 0xe9, 0xe5, 0x7a, - 0x82, 0xfe, 0xa3, 0xf0, 0x66, 0x33, 0x69, 0xa5, 0x53, 0x55, 0xf0, 0x75, 0x57, 0xc1, 0x62, 0xe5, - 0x33, 0xfd, 0x87, 0x6d, 0x45, 0x87, 0xd5, 0x13, 0x8d, 0x9f, 0xb9, 0x03, 0x5f, 0x17, 0x80, 0x9e, - 0x95, 0x20, 0x55, 0x30, 0x8d, 0x36, 0xfa, 0x9d, 0x44, 0x84, 0x3d, 0xb0, 0x86, 0x69, 0xb4, 0x6b, - 0x24, 0xde, 0x8b, 0x3b, 0x05, 0xe0, 0xd2, 0x94, 0x33, 0x30, 0xd6, 0x36, 0x3a, 0xba, 0xe5, 0x4c, - 0xab, 0xa6, 0xf7, 0xdd, 0xe7, 0x4d, 0x25, 0x7f, 0x95, 0x65, 0x52, 0xdd, 0xec, 0xb6, 0x1e, 0x23, - 0x1c, 0xb5, 0xd9, 0x64, 0x73, 0xd5, 0x89, 0x4b, 0xd3, 0x95, 0x8a, 0x7e, 0xc9, 0x0f, 0xec, 0x3d, - 0x3c, 0xb0, 0x37, 0xf4, 0x60, 0xb8, 0x19, 0x74, 0x41, 0x70, 0x44, 0xab, 0xf5, 0xeb, 0x5c, 0x90, - 0xef, 0xe7, 0x40, 0x3e, 0x29, 0x54, 0x67, 0xfc, 0x1d, 0xe6, 0xeb, 0x59, 0x80, 0xb2, 0xb6, 0xa7, - 0x6f, 0x51, 0x9b, 0xc9, 0xe7, 0x9c, 0x01, 0x8f, 0x59, 0x37, 0x7e, 0xc6, 0x87, 0xf3, 0x19, 0xc8, - 0x32, 0x58, 0x59, 0x1b, 0x5e, 0xca, 0xb5, 0xc1, 0x2b, 0x85, 0x6a, 0xa8, 0x4b, 0x96, 0xea, 0xe4, - 0xe7, 0x42, 0x50, 0x25, 0xbb, 0x42, 0x50, 0xf5, 0x5c, 0x9e, 0x05, 0x05, 0xa6, 0x42, 0xef, 0x16, - 0x8e, 0xe2, 0xe0, 0xa3, 0xc7, 0xd7, 0xa2, 0x00, 0x50, 0xef, 0x84, 0xac, 0xe1, 0x9a, 0x79, 0xa4, - 0xc0, 0xf5, 0x40, 0xa9, 0xb5, 0x69, 0xa8, 0x4e, 0x4e, 0xc1, 0xf8, 0x0c, 0x42, 0x74, 0xc4, 0x0f, - 0xf4, 0x27, 0x24, 0x38, 0xbe, 0xe8, 0x1c, 0x51, 0xb4, 0xdb, 0x71, 0x5e, 0xb7, 0xb6, 0x97, 0xf5, - 0xd6, 0x85, 0x0e, 0xfa, 0xb7, 0x62, 0x33, 0x79, 0x1f, 0xfe, 0xc9, 0x68, 0xf8, 0xf3, 0x7e, 0x83, - 0x55, 0x1e, 0xb5, 0xfb, 0x82, 0x4a, 0xe9, 0x4d, 0x6d, 0x00, 0x80, 0x77, 0x43, 0x86, 0x12, 0xca, - 0xba, 0xe5, 0x6c, 0x20, 0x7e, 0x6e, 0x49, 0x2a, 0xfb, 0xc2, 0xe7, 0x13, 0x74, 0x8e, 0xc3, 0x71, - 0xfe, 0x40, 0x94, 0xc5, 0xef, 0x37, 0x78, 0x07, 0x64, 0x19, 0xa7, 0x95, 0x69, 0x7f, 0x2f, 0x96, - 0x8f, 0x28, 0x00, 0x99, 0x15, 0x63, 0x0f, 0xd7, 0x0c, 0x39, 0x61, 0xff, 0xb7, 0xe9, 0xab, 0x19, - 0x72, 0x12, 0xfd, 0x0f, 0x80, 0x31, 0xd7, 0xfd, 0xf7, 0x33, 0x49, 0x27, 0xc2, 0x38, 0x31, 0x53, - 0x53, 0x66, 0x08, 0xef, 0xa6, 0xbf, 0x56, 0xd8, 0xf0, 0xe9, 0xba, 0xe5, 0x76, 0x57, 0x26, 0x18, - 0xbc, 0xf7, 0x6d, 0x42, 0x86, 0x50, 0xd1, 0x5a, 0xe2, 0xef, 0x6a, 0x5f, 0x49, 0x3a, 0xf7, 0x38, - 0x78, 0x44, 0x90, 0xfd, 0x3f, 0xfe, 0x4e, 0x7b, 0x6f, 0x83, 0x81, 0x31, 0xd7, 0x97, 0xc2, 0x5f, - 0x6c, 0x1c, 0xba, 0xf3, 0x1a, 0xd8, 0xee, 0x90, 0x63, 0xd0, 0xdd, 0x1c, 0x16, 0xdb, 0x5b, 0x8d, - 0x52, 0x53, 0xfc, 0x5c, 0xfe, 0x7d, 0x7a, 0xd5, 0x57, 0x2b, 0x82, 0x03, 0x08, 0x17, 0xae, 0xf2, - 0x41, 0x9e, 0xa9, 0x27, 0x03, 0x9a, 0x6a, 0xd7, 0x20, 0xc8, 0xc5, 0xa7, 0x5d, 0x2e, 0xe6, 0x39, - 0x2e, 0x9e, 0x12, 0x2f, 0x3a, 0x7e, 0xb6, 0x7d, 0x2d, 0x09, 0xe3, 0xd4, 0xcf, 0x39, 0xd7, 0x6c, - 0x76, 0x5d, 0x70, 0xbc, 0xcf, 0xb5, 0xf4, 0x3f, 0x0b, 0xbb, 0x87, 0xb9, 0xad, 0x72, 0xcb, 0x8e, - 0xed, 0x8a, 0x42, 0x31, 0x03, 0x4f, 0x5f, 0x82, 0x46, 0x12, 0x72, 0x75, 0xc2, 0xd6, 0xbc, 0xab, - 0x26, 0xde, 0xd3, 0xf1, 0x45, 0x74, 0x55, 0xc8, 0x12, 0x14, 0xbd, 0x45, 0xf8, 0x1c, 0xa2, 0xaf, - 0xc8, 0x00, 0x1e, 0xdf, 0x0b, 0x13, 0x4d, 0x2f, 0x13, 0x1b, 0x11, 0x51, 0xd7, 0x88, 0xe8, 0x2b, - 0x46, 0xf5, 0x67, 0x17, 0x5c, 0xe5, 0x05, 0x53, 0x11, 0x3f, 0x63, 0xbf, 0x9a, 0x81, 0xb1, 0xb5, - 0x56, 0xa7, 0xdd, 0xb4, 0x17, 0xa5, 0xff, 0x28, 0xb9, 0xf1, 0x57, 0x5f, 0xce, 0x85, 0x9c, 0xfa, - 0xa1, 0x5d, 0x6c, 0x3a, 0x7b, 0x4a, 0xf4, 0xa1, 0x77, 0xf4, 0x4b, 0xf4, 0x07, 0x7e, 0x1b, 0x73, - 0x8e, 0x67, 0x3d, 0xef, 0x68, 0xee, 0x54, 0x1a, 0x1e, 0x98, 0xb4, 0x04, 0x63, 0x6d, 0xbd, 0x6e, - 0xed, 0x9a, 0x6e, 0x9c, 0xc6, 0xdb, 0xc4, 0x4a, 0x59, 0xa5, 0x5f, 0xa9, 0xee, 0xe7, 0x48, 0x83, - 0x2c, 0x4b, 0xdc, 0x67, 0x0e, 0xdc, 0x77, 0x25, 0x81, 0x3d, 0x67, 0xd6, 0x4c, 0x4b, 0xef, 0x38, - 0x61, 0x5e, 0xd9, 0x93, 0xad, 0x14, 0xe9, 0xbf, 0x35, 0xb3, 0xc9, 0xcc, 0xcf, 0x5e, 0x02, 0x7a, - 0x9f, 0x0b, 0x77, 0x81, 0x83, 0xfb, 0xf6, 0x08, 0x2d, 0x8f, 0x06, 0xf9, 0xd9, 0x01, 0x16, 0xa2, - 0x57, 0xc2, 0x8b, 0xd4, 0x5c, 0xad, 0xb8, 0xbe, 0x5c, 0x5a, 0x29, 0xd5, 0xd6, 0x8b, 0xdf, 0x9f, - 0x2f, 0x16, 0x0b, 0xc5, 0x82, 0xdc, 0x20, 0xb7, 0x1b, 0xb9, 0x2b, 0x7e, 0x7e, 0x24, 0x60, 0x5c, - 0xf4, 0x46, 0x02, 0x37, 0x01, 0xfd, 0xba, 0xb0, 0xd3, 0xb4, 0xdb, 0xf0, 0x3e, 0x6b, 0xfd, 0x5e, - 0xf6, 0x92, 0x67, 0x84, 0xbc, 0x9f, 0xfb, 0xd5, 0x70, 0x88, 0xcc, 0x7d, 0xe7, 0x0f, 0x40, 0x9a, - 0x2c, 0xbd, 0xd1, 0xef, 0x91, 0xe0, 0x9a, 0xed, 0xa6, 0x56, 0xc7, 0x68, 0x27, 0xc2, 0x8d, 0x04, - 0x1b, 0xf6, 0xd7, 0xde, 0x8d, 0x04, 0xec, 0x51, 0x39, 0x09, 0x69, 0xf2, 0x97, 0x69, 0xfc, 0x63, - 0xbd, 0x96, 0xfb, 0x2a, 0xcd, 0xc2, 0x3b, 0x06, 0x86, 0xda, 0x64, 0xa8, 0x95, 0x80, 0x91, 0x19, - 0x80, 0x53, 0x30, 0x4d, 0xd1, 0x46, 0x21, 0xb1, 0x50, 0xc2, 0x61, 0x14, 0xc5, 0xaf, 0x27, 0xff, - 0x22, 0x05, 0xe9, 0x6a, 0xbb, 0xa9, 0x5b, 0xe8, 0x57, 0x92, 0x43, 0xc1, 0xcc, 0xd4, 0x5a, 0x5b, - 0x38, 0x00, 0x33, 0xd5, 0x7e, 0xa7, 0xd2, 0x2c, 0x9e, 0x21, 0x33, 0x25, 0x60, 0xc8, 0xac, 0xe1, - 0x4b, 0x16, 0x67, 0xc8, 0x54, 0xce, 0xb0, 0x33, 0x33, 0xe9, 0x1e, 0x07, 0xe0, 0xe8, 0xb7, 0xa4, - 0x59, 0x3d, 0x4e, 0xcc, 0xcc, 0xde, 0xc1, 0x4e, 0xa2, 0x00, 0x64, 0xe6, 0x2b, 0xb5, 0x5a, 0x65, - 0x45, 0x3e, 0xa2, 0x64, 0x41, 0xaa, 0x55, 0x56, 0xe5, 0x84, 0x32, 0x0e, 0xe9, 0x52, 0xb9, 0x5c, - 0x54, 0xe5, 0xa4, 0xfd, 0xb7, 0x56, 0xaa, 0x2d, 0x17, 0x65, 0x09, 0xbd, 0x53, 0x78, 0xe8, 0xe5, - 0xeb, 0x8e, 0x53, 0xbc, 0xc4, 0x06, 0xe1, 0x60, 0x7a, 0xe2, 0x17, 0xae, 0xff, 0x20, 0x41, 0x7a, - 0x05, 0x9b, 0x5b, 0x18, 0xfd, 0x50, 0x04, 0x5b, 0xe0, 0xa6, 0x6e, 0x76, 0xe8, 0x49, 0x22, 0xcf, - 0x16, 0xe8, 0x4f, 0x53, 0xae, 0x87, 0xa9, 0x0e, 0xae, 0x1b, 0xad, 0x86, 0x93, 0x89, 0x05, 0x87, - 0xe2, 0x12, 0xd1, 0x93, 0x11, 0x21, 0x23, 0x84, 0x0e, 0xc5, 0xa0, 0x17, 0x05, 0x98, 0x5e, 0xb5, - 0xc6, 0x0f, 0xcc, 0xff, 0x91, 0xec, 0x8f, 0xda, 0x97, 0xd1, 0x93, 0xc2, 0x46, 0xda, 0x5b, 0x21, - 0x43, 0xc4, 0xd4, 0x99, 0xaf, 0xf4, 0xd6, 0xc7, 0x2c, 0x8f, 0x32, 0x0f, 0x57, 0x74, 0xc8, 0xe5, - 0xeb, 0xb8, 0x61, 0x77, 0x5d, 0xb5, 0xaf, 0x52, 0xd8, 0x9f, 0x1d, 0xfd, 0x99, 0x1f, 0xc0, 0x7b, - 0x79, 0x00, 0x6f, 0xec, 0xc1, 0x4a, 0xbb, 0x41, 0xc1, 0xd7, 0xd0, 0xd8, 0xcd, 0xa8, 0x36, 0x0d, - 0xd7, 0xb8, 0xe8, 0x3c, 0xdb, 0xef, 0xb6, 0xad, 0x9d, 0x26, 0x79, 0xc7, 0x5c, 0x58, 0x9c, 0x67, - 0x65, 0x0e, 0xb2, 0x5a, 0xeb, 0x32, 0x79, 0x95, 0x0a, 0x69, 0xb5, 0x93, 0x09, 0xbd, 0xde, 0x45, - 0xfe, 0x01, 0x0e, 0xf9, 0x5b, 0xc4, 0xc8, 0x8d, 0x1f, 0xf8, 0xbf, 0xcb, 0x40, 0x7a, 0x55, 0xeb, - 0x58, 0x18, 0x7d, 0x49, 0x12, 0x45, 0xfe, 0x46, 0x98, 0xde, 0x34, 0xea, 0xbb, 0x1d, 0xdc, 0xe0, - 0x3b, 0x65, 0x57, 0xea, 0x30, 0x30, 0x57, 0x4e, 0x82, 0xec, 0x24, 0xb2, 0x62, 0x1d, 0x6b, 0xfd, - 0xbe, 0x74, 0x72, 0x66, 0xb9, 0xb3, 0xaa, 0x99, 0x56, 0x65, 0x93, 0xa4, 0xb9, 0x67, 0x96, 0xfd, - 0x89, 0x1c, 0xf4, 0x99, 0x10, 0xe8, 0xb3, 0xc1, 0xd0, 0x8f, 0x09, 0x40, 0xaf, 0xe4, 0x60, 0x6c, - 0x53, 0x6f, 0x62, 0xf2, 0xc1, 0x78, 0x8f, 0x68, 0x57, 0x6c, 0x7b, 0xc2, 0xe6, 0xbd, 0x3b, 0x26, - 0x2d, 0xe8, 0x4d, 0xac, 0xba, 0x9f, 0xa1, 0x65, 0xba, 0xd9, 0xef, 0x46, 0xbc, 0x4f, 0xf8, 0x22, - 0xde, 0x2b, 0x90, 0x6a, 0x68, 0x96, 0x46, 0x58, 0x3f, 0xa9, 0x92, 0xff, 0xfc, 0xde, 0x91, 0xd4, - 0xbd, 0x77, 0xf4, 0xb8, 0x14, 0x4d, 0xff, 0x39, 0xa4, 0x05, 0xf4, 0x9f, 0x0d, 0x07, 0x0e, 0xea, - 0x05, 0xe6, 0x3e, 0xdb, 0x30, 0xd4, 0x35, 0x13, 0x5b, 0xab, 0xfe, 0xed, 0x99, 0xb4, 0xca, 0x27, - 0x92, 0x1d, 0xef, 0x4e, 0x55, 0xdb, 0xc1, 0xa4, 0xb2, 0xbc, 0xfd, 0x8e, 0xed, 0x71, 0xee, 0x4b, - 0xf7, 0xb4, 0x6d, 0x7a, 0xd8, 0xda, 0xb6, 0x57, 0x1b, 0xe3, 0xef, 0x74, 0x6f, 0x48, 0x81, 0x94, - 0xdf, 0xb5, 0x5e, 0xd0, 0xca, 0xf6, 0x9f, 0x84, 0x37, 0xbf, 0x98, 0xf6, 0xda, 0xb5, 0x0e, 0x57, - 0xd7, 0x46, 0x94, 0x12, 0xb1, 0x4d, 0xb6, 0xa0, 0xb6, 0x8d, 0xe4, 0x80, 0x8e, 0xe3, 0x87, 0x60, - 0x1c, 0x7c, 0x1e, 0x8e, 0xa8, 0x32, 0xf2, 0x29, 0x06, 0xf7, 0xd9, 0x31, 0x0a, 0xa4, 0x3c, 0xbb, - 0xd2, 0xaf, 0x0a, 0x7b, 0x02, 0x51, 0xfe, 0x84, 0x3a, 0x05, 0x44, 0x9b, 0x2a, 0x89, 0xc5, 0x82, - 0x0b, 0xa9, 0x36, 0x7e, 0x64, 0xbe, 0xe9, 0xb7, 0x1e, 0xe4, 0x0e, 0x8c, 0x0d, 0x6f, 0xb6, 0x0f, - 0xb5, 0x30, 0xd3, 0x66, 0xf7, 0x31, 0x2a, 0x44, 0xe3, 0xb7, 0x98, 0xfd, 0x39, 0xb4, 0xe2, 0x11, - 0x1c, 0x89, 0x92, 0x20, 0x43, 0xf7, 0x0f, 0xd0, 0x6f, 0x09, 0xab, 0x4c, 0x5b, 0xed, 0xf0, 0x0e, - 0x04, 0xee, 0x73, 0x14, 0x53, 0x02, 0xe7, 0x68, 0x90, 0x8a, 0xe4, 0x68, 0xc0, 0xfb, 0x0b, 0x0b, - 0xf4, 0xa3, 0x9e, 0x37, 0xf3, 0x0f, 0x7b, 0x95, 0x18, 0xa5, 0x87, 0xf5, 0x24, 0x28, 0x7e, 0xbc, - 0x9f, 0x4d, 0xc1, 0x24, 0xad, 0xfa, 0xbc, 0xde, 0xd8, 0xc2, 0x16, 0xfa, 0x87, 0xef, 0x22, 0xd4, - 0x95, 0x32, 0x4c, 0x5e, 0x24, 0x64, 0xd3, 0xb8, 0xe3, 0xcc, 0x20, 0x11, 0x7e, 0xe1, 0x0b, 0x6d, - 0xa7, 0x13, 0x67, 0x9d, 0xfb, 0x1e, 0x7d, 0x40, 0x78, 0x43, 0xc5, 0x0f, 0x1a, 0x2b, 0x31, 0x5e, - 0x59, 0x12, 0xdb, 0x56, 0xe9, 0x4b, 0xd6, 0x08, 0x3c, 0xd0, 0xf9, 0xa8, 0x77, 0xf9, 0x08, 0xe2, - 0x14, 0x34, 0xcf, 0x8d, 0x10, 0x05, 0x9f, 0x32, 0x60, 0xc8, 0x01, 0xf1, 0xc4, 0x8e, 0x96, 0xf4, - 0xa9, 0x3a, 0x7e, 0xce, 0xbf, 0x91, 0x5e, 0x4e, 0xb0, 0xa0, 0xe3, 0x66, 0xa3, 0x83, 0xcc, 0x83, - 0x4f, 0x65, 0x4e, 0x41, 0x66, 0x93, 0x14, 0xc6, 0x44, 0x34, 0xf0, 0x96, 0x0c, 0x96, 0x0d, 0xbd, - 0x21, 0x29, 0xba, 0x55, 0xc3, 0x4c, 0x63, 0x0e, 0xb5, 0x43, 0x81, 0xe9, 0x8d, 0x42, 0x5b, 0x25, - 0xe1, 0x35, 0xc7, 0x8f, 0xd2, 0xdb, 0x25, 0x98, 0x64, 0xd1, 0xe6, 0x72, 0x4d, 0x7d, 0xab, 0xe5, - 0x3f, 0xec, 0x38, 0x70, 0x0f, 0x51, 0x6e, 0x87, 0xb4, 0x66, 0x97, 0xc6, 0x1c, 0xf4, 0x50, 0x4f, - 0x15, 0x48, 0xea, 0x53, 0x69, 0xc6, 0x08, 0xb1, 0x45, 0x3c, 0xc1, 0x76, 0x68, 0x1e, 0x61, 0x6c, - 0x91, 0xbe, 0x95, 0xc7, 0x8f, 0xd8, 0x97, 0x25, 0x38, 0xc6, 0x08, 0x38, 0x87, 0x4d, 0x4b, 0xaf, - 0x6b, 0x4d, 0x8a, 0xdc, 0xab, 0x13, 0xc3, 0x80, 0x6e, 0x09, 0xa6, 0xf6, 0xfc, 0xc5, 0x32, 0x08, - 0x67, 0x7b, 0x42, 0xc8, 0x11, 0xa0, 0xf2, 0x1f, 0x46, 0x88, 0xd1, 0xc0, 0x71, 0x95, 0x2b, 0x73, - 0x84, 0x31, 0x1a, 0x84, 0x89, 0x88, 0x1f, 0xe2, 0x5f, 0x4a, 0xd1, 0xb0, 0x25, 0x9e, 0xfa, 0xfc, - 0x9c, 0x30, 0xb6, 0x6b, 0x30, 0x41, 0xb0, 0xa4, 0x1f, 0x32, 0xab, 0x41, 0x88, 0x10, 0xbb, 0x7a, - 0x87, 0x45, 0x58, 0x73, 0xbf, 0x55, 0xfd, 0xe5, 0xa0, 0xf3, 0x00, 0xde, 0x2b, 0xbf, 0x92, 0x4e, - 0x04, 0x29, 0xe9, 0xa4, 0x98, 0x92, 0x7e, 0x8b, 0xf0, 0xd1, 0xba, 0xde, 0x64, 0x1f, 0x5c, 0x3c, - 0xc4, 0x0e, 0x55, 0xf5, 0xaf, 0x3d, 0x7e, 0xb9, 0x78, 0x7d, 0xaa, 0x3b, 0x1e, 0xf2, 0x87, 0x86, - 0x32, 0x3f, 0xf6, 0xeb, 0x03, 0xa9, 0x4b, 0x1f, 0x1c, 0x60, 0x3e, 0x7c, 0x33, 0x1c, 0xa5, 0x55, - 0xe4, 0x5d, 0xb2, 0xe8, 0x35, 0x9b, 0xdd, 0xc9, 0xe8, 0xc3, 0x03, 0x08, 0x41, 0xbf, 0x60, 0xcd, - 0x61, 0x4a, 0x2e, 0xda, 0x64, 0x37, 0xaa, 0x80, 0x1c, 0x5e, 0x8c, 0xe7, 0xaf, 0xa5, 0xe8, 0x6c, - 0x77, 0x8d, 0x44, 0x26, 0x44, 0x7f, 0x9e, 0x1a, 0xc6, 0x88, 0xf0, 0x20, 0xa4, 0x2c, 0xe7, 0x3a, - 0xe0, 0xde, 0x86, 0x09, 0xaf, 0x4a, 0x2f, 0xa6, 0x21, 0xbe, 0x64, 0x2d, 0x1d, 0x51, 0xc9, 0x97, - 0xca, 0x49, 0x38, 0xba, 0xa1, 0xd5, 0x2f, 0x6c, 0x99, 0xc6, 0x6e, 0xab, 0x91, 0x37, 0x9a, 0x86, - 0x49, 0x8d, 0x4e, 0x24, 0x7e, 0x23, 0xff, 0x42, 0x39, 0xed, 0x4c, 0x1d, 0xd2, 0xfd, 0xa6, 0x0e, - 0x4b, 0x47, 0xd8, 0xe4, 0x41, 0xb9, 0xc3, 0x55, 0x3a, 0x99, 0x50, 0xa5, 0xb3, 0x74, 0xc4, 0x51, - 0x3b, 0x4a, 0x01, 0xc6, 0x1a, 0xfa, 0x1e, 0xd9, 0x47, 0x26, 0x06, 0xff, 0x7e, 0x47, 0x75, 0x0a, - 0xfa, 0x1e, 0xdd, 0x75, 0x5e, 0x3a, 0xa2, 0xba, 0x5f, 0x2a, 0x8b, 0x30, 0x4e, 0x6c, 0xf6, 0xa4, - 0x98, 0xb1, 0x48, 0xc7, 0x70, 0x96, 0x8e, 0xa8, 0xde, 0xb7, 0xf6, 0xec, 0x23, 0x45, 0x1c, 0xdc, - 0x1f, 0x70, 0xf6, 0xc2, 0x13, 0x91, 0xf6, 0xc2, 0x6d, 0x5e, 0xd0, 0xdd, 0xf0, 0xe3, 0x90, 0xae, - 0x13, 0x0e, 0x27, 0x19, 0x87, 0xe9, 0xa3, 0x72, 0x2f, 0xa4, 0x76, 0x34, 0xd3, 0x59, 0x02, 0xdf, - 0xd8, 0xbf, 0xdc, 0x15, 0xcd, 0xbc, 0x60, 0x23, 0x68, 0x7f, 0x35, 0x9f, 0x85, 0x34, 0x61, 0x9c, - 0xfb, 0x07, 0x3d, 0xcb, 0xa6, 0x21, 0x79, 0xa3, 0x65, 0x0f, 0xfb, 0x35, 0xc3, 0x39, 0x05, 0x50, - 0x1f, 0x86, 0xcc, 0xf1, 0x1e, 0xaf, 0xd2, 0x3e, 0x8f, 0xd7, 0x3f, 0x1b, 0x60, 0x6e, 0xd1, 0x4d, - 0x69, 0xf0, 0x12, 0xb9, 0xc9, 0x5d, 0x9d, 0xef, 0x3c, 0x46, 0xd4, 0x1a, 0x51, 0x67, 0x1d, 0x7d, - 0xc8, 0x8b, 0x5f, 0x79, 0xbc, 0x35, 0x05, 0x33, 0x36, 0x21, 0xd4, 0x17, 0x9c, 0x0f, 0x6b, 0x8a, - 0x3e, 0x36, 0x94, 0xc9, 0x65, 0x8f, 0x11, 0x41, 0xea, 0x39, 0x22, 0xec, 0x3b, 0x09, 0x94, 0xea, - 0x73, 0x12, 0x28, 0x1d, 0xcd, 0x40, 0xf7, 0x87, 0x7e, 0xf9, 0x59, 0xe5, 0xe5, 0xe7, 0xee, 0x00, - 0x80, 0x7a, 0xf1, 0x65, 0x28, 0x13, 0x90, 0xdf, 0x73, 0x25, 0xa5, 0xca, 0x49, 0xca, 0x03, 0x83, - 0x13, 0x12, 0xbf, 0xb4, 0xbc, 0x3f, 0x05, 0x2f, 0xf2, 0x88, 0x29, 0xe3, 0x8b, 0x4c, 0x50, 0x3e, - 0x33, 0x14, 0x41, 0xb9, 0xc3, 0xbb, 0x30, 0xa8, 0xcf, 0x62, 0xdf, 0xc9, 0x17, 0xb7, 0xc4, 0xfc, - 0xa9, 0xf0, 0x09, 0x86, 0x6e, 0xa0, 0x5c, 0xde, 0x04, 0x08, 0xcb, 0x71, 0xc8, 0x50, 0x0d, 0xe3, - 0x5c, 0x77, 0x4e, 0x9f, 0x22, 0xaa, 0x1b, 0xb1, 0x73, 0x0f, 0xa2, 0xb4, 0x8d, 0x40, 0x7e, 0x98, - 0xe1, 0xa1, 0xb6, 0x6b, 0xb6, 0x4a, 0x2d, 0xcb, 0x40, 0x3f, 0x3a, 0x14, 0xc1, 0x71, 0x7d, 0xc9, - 0xa4, 0x41, 0x7c, 0xc9, 0x06, 0x32, 0x43, 0x38, 0x2d, 0x38, 0x14, 0x33, 0x44, 0x40, 0xe5, 0xf1, - 0xe3, 0xf7, 0x0e, 0x09, 0x8e, 0xb3, 0xd5, 0xd0, 0x3c, 0x3f, 0x85, 0x43, 0x0f, 0x0f, 0x03, 0xc8, - 0x63, 0xce, 0x3c, 0x86, 0xdd, 0x72, 0x4c, 0x1e, 0xf8, 0x33, 0x06, 0xa1, 0x51, 0x39, 0xb9, 0xf5, - 0x5a, 0x17, 0x85, 0x43, 0x41, 0x4a, 0x2c, 0x18, 0x67, 0x04, 0x32, 0xe2, 0xc7, 0xec, 0xe7, 0x24, - 0xc8, 0xb0, 0x5b, 0x07, 0xd6, 0x62, 0x71, 0x40, 0xe0, 0x23, 0x30, 0x09, 0x6c, 0x7c, 0x45, 0x0e, - 0xf7, 0x1f, 0xdf, 0x96, 0xd7, 0xe1, 0xc4, 0xf3, 0x47, 0x4f, 0x4a, 0xcc, 0xb2, 0xb2, 0xac, 0x59, - 0xf8, 0x12, 0xfa, 0x29, 0x09, 0xb2, 0x55, 0x6c, 0xd9, 0x9a, 0x49, 0x1c, 0xa3, 0x60, 0x9b, 0xb9, - 0xe2, 0x5b, 0xbb, 0x8d, 0xd3, 0xd5, 0x58, 0x54, 0x1d, 0x47, 0xe8, 0x9a, 0x63, 0x34, 0x8d, 0x5a, - 0xc7, 0x85, 0x55, 0x3e, 0x82, 0xf3, 0xce, 0xd7, 0xc3, 0x38, 0x21, 0x83, 0xc0, 0xf1, 0x11, 0x1f, - 0x34, 0xbf, 0x98, 0x88, 0x05, 0x1b, 0x7b, 0xf8, 0x22, 0xa1, 0xf9, 0xc9, 0xec, 0x65, 0x42, 0x64, - 0xf8, 0xb2, 0x97, 0x69, 0x1d, 0x95, 0x7e, 0x15, 0xe1, 0xae, 0x26, 0xb7, 0x59, 0x43, 0x45, 0x56, - 0xec, 0x12, 0x8d, 0x7e, 0x75, 0x8f, 0xe0, 0x0a, 0x16, 0x09, 0xc6, 0xaa, 0xf6, 0x72, 0xc3, 0x1e, - 0x53, 0xce, 0x1f, 0x1c, 0xca, 0xde, 0x83, 0x55, 0xc4, 0x8e, 0xe6, 0x70, 0x64, 0x78, 0x43, 0x54, - 0x84, 0x8e, 0x16, 0x56, 0x79, 0xfc, 0x78, 0xbc, 0x93, 0xe2, 0x41, 0x64, 0x19, 0xbd, 0x59, 0x02, - 0x69, 0x11, 0x5b, 0x43, 0x3a, 0x39, 0x22, 0x7a, 0x0a, 0x81, 0x1f, 0xba, 0x42, 0x83, 0x05, 0x70, - 0x0c, 0x23, 0x34, 0xcf, 0x2d, 0xe2, 0xe1, 0x74, 0x20, 0xb1, 0x28, 0x01, 0x42, 0x04, 0xc4, 0x8f, - 0xda, 0x7b, 0x28, 0x6a, 0xd4, 0x82, 0xf5, 0x23, 0x43, 0xd0, 0x88, 0xa3, 0x9d, 0xbc, 0x3b, 0x0c, - 0x24, 0x65, 0x1c, 0x56, 0x7f, 0xeb, 0x55, 0xf9, 0x48, 0x7c, 0x0c, 0xc1, 0xee, 0xec, 0xdb, 0xb8, - 0x7e, 0x01, 0x37, 0xd0, 0xbf, 0x3a, 0x38, 0x74, 0x33, 0x90, 0xad, 0xd3, 0xd2, 0x08, 0x78, 0x63, - 0xaa, 0xf3, 0x18, 0xe1, 0xa6, 0x74, 0x5e, 0x11, 0xd1, 0xcf, 0x47, 0x78, 0x53, 0xba, 0x40, 0xf5, - 0xf1, 0x23, 0xf3, 0xbb, 0x74, 0x92, 0x51, 0xaa, 0x1b, 0x2d, 0xf4, 0xef, 0x0e, 0x0e, 0xcb, 0xd5, - 0x30, 0xae, 0xd7, 0x8d, 0x56, 0x69, 0x47, 0xdb, 0x72, 0xcc, 0xa8, 0x5e, 0x82, 0xf3, 0xb6, 0xb8, - 0x63, 0x3c, 0xa2, 0xb3, 0xad, 0x19, 0x2f, 0x61, 0xd0, 0xc9, 0x84, 0x4d, 0xfa, 0x61, 0x4d, 0x26, - 0x7a, 0xd4, 0x1d, 0x3f, 0x64, 0x1f, 0xf6, 0x5c, 0x28, 0xa8, 0x2a, 0x7c, 0x41, 0x58, 0x32, 0x06, - 0x19, 0xce, 0xfc, 0xad, 0x38, 0x94, 0xe1, 0x2c, 0x84, 0x80, 0xf8, 0x71, 0xfc, 0x55, 0x0f, 0xc7, - 0xd8, 0xed, 0x18, 0x07, 0x40, 0x67, 0x78, 0xd3, 0xc3, 0x01, 0xd1, 0x39, 0x9c, 0x29, 0xe2, 0x33, - 0x2c, 0xd8, 0x14, 0x9b, 0xf1, 0xa0, 0x1f, 0x1e, 0x06, 0x38, 0x77, 0x0f, 0xb2, 0x29, 0x46, 0xb7, - 0xc4, 0x22, 0xdc, 0xc5, 0xb3, 0x8f, 0x83, 0x76, 0x29, 0x43, 0x41, 0x50, 0xec, 0x2e, 0x1e, 0x91, - 0xfa, 0xe3, 0x07, 0xf0, 0xa7, 0x25, 0x98, 0x26, 0xfb, 0x5c, 0x4d, 0xac, 0x99, 0x54, 0x51, 0x0e, - 0xc5, 0x1b, 0xf3, 0x9d, 0xc2, 0x61, 0xf2, 0x79, 0x3e, 0x78, 0x74, 0x0c, 0x05, 0x0a, 0xb1, 0xfb, - 0x5d, 0x05, 0x49, 0x18, 0x89, 0x29, 0x50, 0x76, 0x49, 0x60, 0x22, 0x3e, 0x1c, 0x3c, 0x22, 0xba, - 0x7d, 0xf1, 0xcc, 0x70, 0x3a, 0xdb, 0x88, 0xdd, 0xbe, 0x44, 0x88, 0x18, 0x41, 0x30, 0xf6, 0xdb, - 0x99, 0x29, 0xb0, 0x46, 0xae, 0xaa, 0x7a, 0x2a, 0xe5, 0x1e, 0x7e, 0xf8, 0xe4, 0x50, 0xdc, 0x7c, - 0x0e, 0x10, 0x39, 0x51, 0x81, 0x94, 0x69, 0x5c, 0xa4, 0x66, 0xa9, 0x29, 0x95, 0xfc, 0x27, 0x53, - 0x7e, 0xa3, 0xb9, 0xbb, 0xd3, 0xea, 0x90, 0xb9, 0xe3, 0x94, 0xea, 0x3c, 0x2a, 0xd7, 0xc3, 0xd4, - 0x45, 0xdd, 0xda, 0x5e, 0xc2, 0x5a, 0x03, 0x9b, 0xaa, 0x71, 0x91, 0x5d, 0x0f, 0xcb, 0x27, 0xf2, - 0x7b, 0xb0, 0x02, 0xf3, 0x4b, 0x72, 0x7f, 0xd5, 0x48, 0x4e, 0x4a, 0x44, 0x99, 0x79, 0x06, 0x53, - 0x15, 0xbf, 0xc0, 0xbc, 0x57, 0x82, 0x71, 0xd5, 0xb8, 0xc8, 0x84, 0xe4, 0xdf, 0x1f, 0xae, 0x8c, - 0x44, 0x5e, 0xe8, 0xd1, 0xfb, 0xc8, 0x1c, 0xf2, 0x47, 0xbe, 0xd0, 0x0b, 0xad, 0x7e, 0x24, 0xee, - 0xf1, 0x93, 0xaa, 0x71, 0xb1, 0x8a, 0x2d, 0xda, 0x23, 0xd0, 0xfa, 0x90, 0x3c, 0xf9, 0xf4, 0x0e, - 0x2d, 0x90, 0xad, 0xc3, 0xdd, 0x67, 0xf4, 0x0e, 0xe1, 0x6b, 0x9e, 0x78, 0x06, 0xb9, 0x24, 0x0e, - 0x05, 0xa2, 0xb7, 0x0a, 0xdd, 0xee, 0x24, 0x46, 0x41, 0xfc, 0x28, 0xfd, 0xb8, 0x04, 0x13, 0xaa, - 0x71, 0xd1, 0x1e, 0x1a, 0x16, 0xf4, 0x66, 0x73, 0x38, 0x23, 0x64, 0xd4, 0xc9, 0xbf, 0xc3, 0x06, - 0x87, 0x8a, 0x91, 0x4f, 0xfe, 0xfb, 0x10, 0x10, 0x3f, 0x0c, 0x8f, 0xd3, 0xce, 0xe2, 0x8c, 0xd0, - 0xad, 0xe1, 0xe0, 0x30, 0x68, 0x87, 0x70, 0xc9, 0x38, 0xb4, 0x0e, 0x11, 0x44, 0xc1, 0x48, 0x76, - 0x4e, 0xa6, 0xf3, 0x64, 0x98, 0x1f, 0x6e, 0x9f, 0x78, 0x57, 0x34, 0xf7, 0x1a, 0x36, 0xec, 0x72, - 0x84, 0x0c, 0x05, 0x8d, 0x08, 0x6e, 0x34, 0x02, 0x34, 0xc4, 0x8f, 0xc7, 0x1f, 0x49, 0x30, 0x49, - 0x49, 0x78, 0x81, 0xcc, 0x02, 0x06, 0xea, 0x54, 0xfe, 0x16, 0x1c, 0x4e, 0xa7, 0x0a, 0xa1, 0x20, - 0x7e, 0x10, 0xff, 0x39, 0x49, 0xe6, 0x71, 0x03, 0x9c, 0x51, 0x0c, 0x42, 0x70, 0xe0, 0xc9, 0xd8, - 0x10, 0xcf, 0x29, 0x0e, 0x32, 0x19, 0x3b, 0xa4, 0xb3, 0x8a, 0x8f, 0xbb, 0xbd, 0x68, 0x98, 0x18, - 0x1c, 0xa0, 0x2b, 0x0c, 0x11, 0x86, 0x01, 0xbb, 0xc2, 0x21, 0x21, 0xf1, 0x57, 0x12, 0x00, 0x25, - 0x60, 0xc5, 0xd8, 0xc3, 0xe8, 0xe9, 0xa1, 0x2c, 0x7c, 0xbb, 0x5d, 0x43, 0xa5, 0x3e, 0xae, 0xa1, - 0x11, 0x4f, 0xfb, 0x47, 0xb5, 0x04, 0xfa, 0xb8, 0xbc, 0x12, 0x78, 0xcd, 0x66, 0x8c, 0x96, 0xc0, - 0xf0, 0xfa, 0xe3, 0xc7, 0xf8, 0x8b, 0x74, 0x36, 0xe7, 0x9d, 0x62, 0xfa, 0xe5, 0xa1, 0xa0, 0xec, - 0x5b, 0xfd, 0x4b, 0xfc, 0xea, 0xff, 0x00, 0xd8, 0x0e, 0x3a, 0x47, 0xec, 0x77, 0x3a, 0x29, 0xfe, - 0x39, 0xe2, 0xe1, 0x9d, 0x42, 0xfa, 0x91, 0x14, 0x1c, 0x65, 0x4a, 0xe4, 0xbb, 0x01, 0xe2, 0x88, - 0x67, 0x49, 0x38, 0x25, 0xd9, 0x07, 0xe5, 0x61, 0x19, 0xa4, 0xa2, 0x98, 0x32, 0x05, 0xc8, 0x1b, - 0x89, 0x75, 0x23, 0x53, 0xbc, 0xd4, 0xd6, 0x5a, 0x0d, 0xf1, 0x80, 0x8f, 0x7d, 0x80, 0x77, 0x6c, - 0x8d, 0x12, 0x6f, 0x6b, 0xec, 0x61, 0x99, 0x8c, 0xbc, 0x73, 0x4d, 0x58, 0x46, 0xc9, 0x1d, 0xf9, - 0xce, 0x75, 0x70, 0xdd, 0xf1, 0xa3, 0xf4, 0x2e, 0x09, 0x52, 0x55, 0xc3, 0xb4, 0xd0, 0x13, 0x51, - 0x7a, 0x27, 0xe5, 0xbc, 0x07, 0x92, 0xf3, 0xac, 0xe4, 0xb9, 0xab, 0xaf, 0x4e, 0x85, 0x9f, 0xa7, - 0xd3, 0x2c, 0x8d, 0x84, 0x03, 0xb7, 0xeb, 0xf7, 0xdd, 0x81, 0x15, 0x35, 0x68, 0x03, 0xe5, 0x5f, - 0x35, 0xd8, 0x89, 0x38, 0xb6, 0xa0, 0x0d, 0x81, 0x35, 0x8f, 0xc0, 0xee, 0x3b, 0xc1, 0xfc, 0x52, - 0xc9, 0x8d, 0x80, 0x4f, 0x50, 0x97, 0x91, 0xb2, 0xb6, 0x83, 0x87, 0xe4, 0x32, 0x4c, 0x62, 0x0e, - 0x4a, 0x5e, 0xcc, 0xc1, 0xa8, 0x1d, 0x8a, 0x9e, 0x72, 0xa4, 0x24, 0x8d, 0xba, 0x43, 0x85, 0xd4, - 0x1d, 0x3f, 0x30, 0x9f, 0xb7, 0x47, 0x3e, 0xb2, 0x86, 0xcc, 0xb5, 0x1a, 0x2c, 0x88, 0xdb, 0xdf, - 0x1d, 0xf6, 0xde, 0xcd, 0xbe, 0x30, 0x6f, 0x7c, 0xb8, 0xc8, 0x74, 0xf7, 0x0d, 0x76, 0xf3, 0x34, - 0x64, 0x1c, 0x39, 0x79, 0x99, 0x89, 0x74, 0x8b, 0x9d, 0xfb, 0x1d, 0x7a, 0x36, 0x9a, 0x39, 0x87, - 0x14, 0xd1, 0xc5, 0xb8, 0x98, 0x87, 0xd4, 0x08, 0x86, 0x1e, 0x01, 0xea, 0xfe, 0x65, 0x78, 0x19, - 0xed, 0xbf, 0x44, 0x30, 0xa2, 0x29, 0xdb, 0xbd, 0xfa, 0xf1, 0xb0, 0xbc, 0x8c, 0xfa, 0x11, 0x30, - 0x82, 0x10, 0x67, 0x69, 0xb6, 0xc9, 0x4b, 0x5c, 0xf0, 0xd0, 0x17, 0x92, 0xb1, 0x2b, 0x6f, 0xf1, - 0x6b, 0x73, 0x3d, 0xba, 0xc2, 0xb5, 0x77, 0x14, 0x47, 0xd7, 0xb0, 0xe2, 0x46, 0x60, 0x4e, 0x48, - 0x12, 0x17, 0xe5, 0xf3, 0x7a, 0xc3, 0xda, 0x1e, 0x92, 0xa3, 0xff, 0x45, 0xbb, 0x2c, 0xe7, 0xfe, - 0x39, 0xf2, 0x80, 0x9e, 0x4f, 0x44, 0x0a, 0x5f, 0xe1, 0xb2, 0x84, 0x90, 0x15, 0xc0, 0xe2, 0x08, - 0x41, 0x27, 0x42, 0xcb, 0x1b, 0xa1, 0x44, 0x9f, 0xd3, 0x1b, 0xd8, 0x78, 0x01, 0x4a, 0x34, 0xa1, - 0x6b, 0x78, 0x12, 0x1d, 0x56, 0xdc, 0xbf, 0x50, 0x89, 0x76, 0x59, 0x32, 0x24, 0x89, 0x0e, 0x2d, - 0x6f, 0x04, 0xb1, 0xd1, 0x81, 0xcd, 0xaf, 0x97, 0xf5, 0xd6, 0x05, 0xf4, 0xd1, 0xb4, 0x73, 0xf3, - 0xdd, 0x79, 0xdd, 0xda, 0x66, 0xc7, 0xdc, 0x3f, 0x2c, 0x7c, 0x47, 0xc6, 0x00, 0x47, 0xd9, 0x4f, - 0x00, 0x58, 0xec, 0x46, 0x2a, 0x37, 0x66, 0x8e, 0x2f, 0x45, 0xc9, 0xc1, 0x94, 0xde, 0xb2, 0xb0, - 0xd9, 0xd2, 0x9a, 0x0b, 0x4d, 0x6d, 0xab, 0x33, 0x93, 0x25, 0x47, 0x33, 0xaf, 0xea, 0x1a, 0xbc, - 0x4b, 0xbe, 0x3c, 0x2a, 0xff, 0x85, 0xf0, 0x5c, 0x33, 0x62, 0xc8, 0x9f, 0x53, 0x82, 0x91, 0x58, - 0xdc, 0xf0, 0x4f, 0xdf, 0x88, 0x66, 0x7c, 0xb1, 0x01, 0x99, 0xeb, 0x06, 0x23, 0xf2, 0x4c, 0xd1, - 0xdf, 0x78, 0xa9, 0xab, 0xf1, 0xee, 0xd4, 0x23, 0x35, 0x64, 0xc3, 0x8c, 0x08, 0xe9, 0x23, 0x38, - 0xf9, 0x91, 0x86, 0x2b, 0x9c, 0xf0, 0x75, 0xed, 0x36, 0xd6, 0x4c, 0xad, 0x55, 0xc7, 0x11, 0xa4, - 0x39, 0x6c, 0x2e, 0xb9, 0x00, 0x63, 0x7a, 0xdd, 0x68, 0x55, 0xf5, 0x57, 0x39, 0x57, 0xb9, 0x84, - 0xc7, 0x3e, 0x25, 0x1c, 0x29, 0xb1, 0x2f, 0x54, 0xf7, 0x5b, 0xa5, 0x04, 0xe3, 0x75, 0xcd, 0x6c, - 0x54, 0x7d, 0x97, 0x5b, 0xdf, 0xd2, 0xbf, 0xa0, 0xbc, 0xf3, 0x89, 0xea, 0x7d, 0xad, 0x54, 0x78, - 0x26, 0x66, 0xba, 0x4e, 0xff, 0x06, 0x16, 0x56, 0xf0, 0x3e, 0xe2, 0x78, 0x6e, 0x73, 0xc7, 0xc4, - 0x4d, 0x72, 0x73, 0x26, 0xed, 0x76, 0xe3, 0xaa, 0x97, 0x80, 0xde, 0xeb, 0x97, 0xe6, 0x15, 0x5e, - 0x9a, 0x5f, 0x19, 0x20, 0x12, 0xfb, 0xd0, 0x18, 0xca, 0x9c, 0xf8, 0xed, 0xae, 0x60, 0xae, 0x72, - 0x82, 0x79, 0xef, 0x80, 0x54, 0xc4, 0x2f, 0x99, 0xbf, 0x97, 0x81, 0x29, 0x7a, 0x98, 0x9c, 0xb1, - 0x13, 0xfd, 0x34, 0xb9, 0xac, 0xcd, 0x3a, 0x8b, 0x2f, 0xa3, 0xea, 0xc1, 0x07, 0x3a, 0x19, 0xa4, - 0x0b, 0xf8, 0x32, 0xeb, 0xef, 0xf6, 0xdf, 0xa8, 0x7b, 0xa4, 0x0e, 0x5d, 0x73, 0x94, 0xa6, 0x51, - 0xef, 0x91, 0x86, 0x57, 0x1f, 0x3f, 0x3e, 0x3f, 0x2f, 0x81, 0x94, 0x6b, 0x34, 0xc4, 0xe3, 0x3b, - 0x05, 0x43, 0x71, 0x2d, 0x4c, 0x38, 0x7d, 0xe6, 0xac, 0x0b, 0x89, 0x3f, 0x29, 0xaa, 0xc1, 0xc9, - 0xe5, 0x4d, 0xae, 0x31, 0x72, 0x0b, 0x6e, 0x48, 0xdd, 0xf1, 0x83, 0xf2, 0xcb, 0x59, 0xd6, 0x69, - 0xe6, 0x0d, 0xe3, 0x02, 0x39, 0x96, 0xf0, 0x84, 0x04, 0xe9, 0x05, 0x6c, 0xd5, 0xb7, 0x87, 0xd4, - 0x67, 0x76, 0xcd, 0xa6, 0xd3, 0x67, 0xf6, 0xdd, 0x3c, 0xd9, 0x7f, 0x62, 0xe8, 0x90, 0x35, 0x47, - 0x48, 0x1a, 0x75, 0xb8, 0xc6, 0xd0, 0xda, 0xe3, 0x07, 0xe7, 0x79, 0x09, 0xa6, 0x5d, 0xb3, 0x11, - 0xc5, 0xe4, 0x67, 0x5f, 0x70, 0xc6, 0x40, 0xf4, 0x99, 0x68, 0x21, 0x55, 0x5c, 0x9e, 0xf2, 0x2d, - 0x8b, 0xd9, 0x5a, 0x17, 0x21, 0xd8, 0x8a, 0x18, 0x81, 0x23, 0x58, 0x16, 0x4b, 0x30, 0x46, 0x08, - 0x2a, 0xe8, 0x7b, 0xc4, 0x4d, 0x8b, 0xb3, 0xde, 0x3d, 0x3a, 0x14, 0xeb, 0xdd, 0xbd, 0xbc, 0xf5, - 0x4e, 0x30, 0x84, 0xa1, 0x63, 0xbc, 0x8b, 0xe8, 0xb7, 0x60, 0x7f, 0x3f, 0x74, 0xdb, 0x5d, 0x04, - 0xbf, 0x85, 0x3e, 0xf5, 0x8f, 0xe0, 0x8a, 0xde, 0x93, 0x4c, 0xd9, 0x3a, 0x9b, 0x57, 0xe8, 0x51, - 0x05, 0x52, 0xe7, 0xec, 0x3f, 0x5f, 0xf0, 0x2e, 0xaa, 0x78, 0x74, 0x08, 0x07, 0xe1, 0xef, 0x87, - 0x14, 0xb9, 0x8c, 0x37, 0xd5, 0x15, 0x72, 0x33, 0x74, 0x27, 0xcd, 0x26, 0x44, 0x25, 0xdf, 0x45, - 0x0d, 0x56, 0xc6, 0x15, 0x31, 0x37, 0x3c, 0x37, 0x3c, 0xe5, 0x38, 0x64, 0xec, 0x72, 0xdd, 0x65, - 0x16, 0x7b, 0x8a, 0x62, 0x7c, 0x17, 0xa0, 0x2d, 0x7e, 0xe4, 0xbf, 0x40, 0xee, 0xe4, 0x21, 0x31, - 0x55, 0x9f, 0x1c, 0x02, 0xbc, 0x01, 0x6c, 0x39, 0x30, 0xec, 0xef, 0x3a, 0x08, 0xec, 0x6e, 0x00, - 0xd7, 0x91, 0x3a, 0xd1, 0x0a, 0xd0, 0x30, 0x92, 0x93, 0xbf, 0x19, 0xe6, 0xf8, 0xf7, 0xf0, 0x30, - 0xd1, 0x4d, 0x71, 0x42, 0x7f, 0x20, 0x74, 0x86, 0xe8, 0x10, 0x38, 0x30, 0x3a, 0x87, 0xe4, 0x12, - 0xf8, 0xc7, 0x12, 0x4c, 0x54, 0xbd, 0x0b, 0xe4, 0xc4, 0x6f, 0x28, 0x88, 0x0c, 0x91, 0x3d, 0xd6, - 0x72, 0xf1, 0x21, 0xa7, 0x06, 0x0f, 0x19, 0xca, 0xb3, 0xce, 0x47, 0xff, 0xa8, 0x43, 0x86, 0x8a, - 0x12, 0x12, 0x3f, 0x90, 0x9f, 0xa2, 0x37, 0x82, 0xe4, 0xea, 0x96, 0xbe, 0x87, 0xd1, 0xe3, 0x31, - 0x2a, 0xd2, 0xe3, 0x90, 0x31, 0x36, 0x37, 0x3b, 0xec, 0x66, 0xc1, 0x29, 0x95, 0x3d, 0x79, 0x57, - 0xba, 0x53, 0x70, 0xd9, 0x95, 0xee, 0x11, 0x83, 0x0a, 0xee, 0x63, 0x28, 0x6d, 0xd0, 0xa8, 0x83, - 0x0a, 0x8a, 0x91, 0x31, 0x82, 0xb0, 0xc1, 0x60, 0x73, 0x8f, 0x99, 0x6c, 0xde, 0xcc, 0x8c, 0x04, - 0xf8, 0xe0, 0xd8, 0xce, 0xc2, 0xa4, 0xcf, 0x22, 0xe0, 0x04, 0xa6, 0xe7, 0xd2, 0xa2, 0x9e, 0x35, - 0x76, 0x59, 0x36, 0x74, 0x7b, 0x41, 0x04, 0x3b, 0xb0, 0x08, 0x11, 0x23, 0xb9, 0xf7, 0xc5, 0x19, - 0xf2, 0x46, 0x84, 0xd5, 0xfb, 0xfd, 0x58, 0x55, 0x78, 0xac, 0xce, 0x88, 0xb0, 0x49, 0x6c, 0x08, - 0x14, 0x5a, 0x4e, 0xbe, 0xc3, 0x85, 0x4b, 0xe5, 0xe0, 0xba, 0x7f, 0x60, 0x3a, 0xe2, 0x47, 0xec, - 0x83, 0x12, 0xbd, 0xfc, 0x21, 0xb7, 0xa7, 0xe9, 0x4d, 0x72, 0x40, 0x7c, 0x08, 0x57, 0x10, 0xfe, - 0xad, 0x1f, 0x94, 0x73, 0x3c, 0x28, 0x0f, 0x8a, 0x30, 0x83, 0xa3, 0x28, 0x00, 0x9b, 0x97, 0xfb, - 0x6d, 0xe6, 0x34, 0x8a, 0xe8, 0x95, 0xdd, 0x91, 0xd8, 0xd8, 0x7b, 0xbf, 0x31, 0xfd, 0x93, 0x2e, - 0x48, 0x0f, 0x73, 0x20, 0x15, 0x0f, 0x4a, 0x57, 0x34, 0xac, 0x96, 0xa3, 0x63, 0xa5, 0xcc, 0xc0, - 0xb1, 0x72, 0xa5, 0xb6, 0x9e, 0x5b, 0x2f, 0xe4, 0x6a, 0xb9, 0x73, 0xa5, 0xe2, 0xf9, 0xf5, 0xf9, - 0xe5, 0x4a, 0xfe, 0xac, 0x2c, 0xa1, 0x5f, 0xa1, 0x63, 0x60, 0xd5, 0xd8, 0x35, 0xeb, 0xc3, 0x9a, - 0x6d, 0x76, 0x48, 0x61, 0xac, 0xd3, 0xb1, 0xa7, 0xa8, 0x8e, 0xeb, 0x9e, 0x3f, 0xa6, 0x43, 0x5c, - 0xbf, 0x8e, 0x96, 0x1a, 0xb2, 0xe3, 0x7a, 0x5f, 0x0a, 0xe2, 0xef, 0x62, 0xdf, 0x92, 0x00, 0x16, - 0x4d, 0x63, 0xb7, 0x5d, 0x31, 0x1b, 0xd8, 0x44, 0xcf, 0x79, 0xab, 0xbe, 0x5f, 0x18, 0xc2, 0x64, - 0x65, 0x15, 0x60, 0xcb, 0x2d, 0x9c, 0xe9, 0xa9, 0xdb, 0xc5, 0xd6, 0x78, 0x1e, 0x51, 0xaa, 0xaf, - 0x0c, 0xfe, 0x82, 0xc0, 0xef, 0xe3, 0x31, 0x0e, 0x1b, 0x79, 0xbc, 0xe2, 0x86, 0xb9, 0xea, 0x7b, - 0xa7, 0x8b, 0x75, 0x8d, 0xc3, 0xfa, 0xc1, 0x03, 0x50, 0x12, 0x3f, 0xe6, 0xdf, 0x96, 0x60, 0x82, - 0xee, 0xc5, 0x52, 0x9e, 0xfe, 0x8d, 0x07, 0xfa, 0x2f, 0x0f, 0x01, 0xf4, 0x35, 0x98, 0x34, 0xbc, - 0xd2, 0xe9, 0xc8, 0xe8, 0xb7, 0xae, 0x85, 0xc2, 0xee, 0xa3, 0x4b, 0xe5, 0x8a, 0x41, 0x1f, 0xf4, - 0x23, 0xaf, 0xf2, 0xc8, 0xdf, 0x1b, 0xc2, 0x6f, 0x5f, 0x89, 0xc3, 0x84, 0xfe, 0xf7, 0x5d, 0xe8, - 0xd7, 0x38, 0xe8, 0x73, 0x07, 0x21, 0x25, 0x7e, 0xec, 0x1f, 0x73, 0x0d, 0xf4, 0xee, 0xf6, 0x49, - 0x2c, 0x9b, 0x26, 0xaf, 0x1b, 0x70, 0x81, 0xc1, 0xd3, 0x16, 0x80, 0xd4, 0x34, 0x24, 0x75, 0x87, - 0x86, 0xa4, 0xde, 0x18, 0x68, 0x09, 0x11, 0x5a, 0x51, 0xfc, 0x38, 0xfc, 0xfa, 0x4b, 0x20, 0x5d, - 0xc0, 0x1b, 0xbb, 0x5b, 0xe8, 0x2d, 0x12, 0x64, 0x9b, 0xc6, 0x56, 0xa9, 0xb5, 0x69, 0xb0, 0x86, - 0x25, 0x9c, 0x86, 0x29, 0x0a, 0xa4, 0xb6, 0xb1, 0xe6, 0x34, 0x95, 0xfc, 0x57, 0x6e, 0x84, 0x69, - 0xfb, 0xd7, 0xb9, 0xa0, 0xd8, 0x8d, 0x3e, 0xd9, 0x95, 0x6a, 0x4f, 0x50, 0x2d, 0xc3, 0xd2, 0x9a, - 0x2a, 0xae, 0x1b, 0x66, 0x83, 0x9e, 0x16, 0x49, 0xab, 0x5c, 0x9a, 0x8d, 0x37, 0x79, 0x26, 0xfe, - 0x0b, 0x69, 0x92, 0xc1, 0x4b, 0x50, 0xae, 0x87, 0xa9, 0x4d, 0xdd, 0xec, 0x58, 0x34, 0x77, 0x8d, - 0x3a, 0xb8, 0xa4, 0x55, 0x3e, 0xd1, 0xa6, 0xc7, 0x97, 0x70, 0x0e, 0x9b, 0xe4, 0x72, 0xa1, 0xb4, - 0xda, 0x95, 0x6a, 0xd3, 0xd3, 0xd4, 0x7c, 0x85, 0x8d, 0x51, 0x7a, 0xfc, 0x69, 0x76, 0x8d, 0xde, - 0xb3, 0x5d, 0xd4, 0x38, 0xad, 0x91, 0x4b, 0xb4, 0x6b, 0xb4, 0x13, 0x56, 0x77, 0x9b, 0xcd, 0x2a, - 0xae, 0xe7, 0xb6, 0x8c, 0x19, 0xa0, 0x35, 0xf2, 0xa9, 0x0a, 0x82, 0xb1, 0xdd, 0x76, 0xd5, 0xd2, - 0xac, 0xdd, 0xce, 0xcc, 0x04, 0xdd, 0x4f, 0x72, 0x9e, 0x95, 0x13, 0x00, 0x0d, 0xe3, 0x62, 0x8b, - 0xbd, 0x9d, 0xa4, 0xfe, 0x46, 0x5e, 0x8a, 0xbd, 0x6c, 0xa6, 0x22, 0x3b, 0x45, 0x63, 0xd8, 0x51, - 0x7f, 0xae, 0x4f, 0x4b, 0x00, 0xd6, 0xb6, 0x89, 0xb5, 0x46, 0x4f, 0xb8, 0x5e, 0x01, 0xc7, 0x9b, - 0xc6, 0x56, 0xe7, 0xbc, 0x6e, 0x6d, 0x7b, 0x40, 0x2c, 0x39, 0x00, 0xa6, 0xd5, 0x80, 0xb7, 0xca, - 0x83, 0x70, 0x95, 0xf3, 0xe6, 0xfc, 0xb6, 0xd1, 0xc4, 0x35, 0x13, 0xe3, 0x2e, 0x7c, 0xd3, 0x6a, - 0x58, 0x16, 0x65, 0x0e, 0x52, 0xf6, 0x6b, 0x76, 0x79, 0x3c, 0xe2, 0xe4, 0x9e, 0x88, 0xd9, 0x1c, - 0x13, 0x31, 0x95, 0xe4, 0x53, 0xee, 0x82, 0x2b, 0x8d, 0x8b, 0xad, 0x65, 0x63, 0x6b, 0x49, 0xeb, - 0xe4, 0xb5, 0x4d, 0xac, 0x62, 0x7a, 0x6c, 0xca, 0x30, 0x89, 0x18, 0x8c, 0xa9, 0x41, 0xaf, 0x95, - 0x39, 0x50, 0xea, 0xda, 0x26, 0x5e, 0xe6, 0x01, 0xa0, 0x92, 0xd1, 0xe3, 0x8d, 0x0d, 0xbb, 0x9d, - 0xba, 0xe6, 0x00, 0x91, 0xa5, 0x07, 0x51, 0xfd, 0x69, 0x36, 0xa0, 0xf6, 0x73, 0xc1, 0x03, 0x64, - 0x8c, 0xe4, 0xea, 0x4a, 0xdd, 0x27, 0xd2, 0xe3, 0xfd, 0x44, 0x1a, 0xba, 0x45, 0xda, 0x85, 0x75, - 0xc2, 0x0f, 0xeb, 0xe7, 0xd2, 0x90, 0xaa, 0x5e, 0x6e, 0xd5, 0xd1, 0x1b, 0x7d, 0xc3, 0xdf, 0x69, - 0x38, 0x66, 0xd2, 0x32, 0x6b, 0xa6, 0xb6, 0x87, 0xcd, 0x0e, 0x5e, 0x26, 0x76, 0x94, 0x04, 0x29, - 0xb3, 0xe7, 0x3b, 0x5b, 0x7e, 0x3b, 0x17, 0xf4, 0x76, 0x71, 0xa7, 0x6d, 0x5d, 0x5e, 0xb6, 0xf1, - 0x48, 0xd2, 0x28, 0x50, 0x5c, 0xa2, 0x72, 0x3f, 0x20, 0xcb, 0xbc, 0x5c, 0x33, 0x1c, 0xfc, 0x54, - 0xbc, 0x63, 0x58, 0xd8, 0x69, 0x14, 0xed, 0xcd, 0x21, 0x39, 0xd0, 0x6f, 0xa6, 0x7c, 0xba, 0xf5, - 0x5e, 0x5e, 0xb7, 0xde, 0xd8, 0x03, 0x7a, 0xbb, 0x69, 0x01, 0x9a, 0xf4, 0x95, 0x90, 0xa5, 0xf2, - 0xec, 0xac, 0x52, 0xae, 0xe9, 0xf1, 0xbd, 0x27, 0xf1, 0xaa, 0x93, 0xdb, 0xee, 0x5b, 0x0d, 0xbc, - 0xa7, 0xd7, 0xb1, 0xe7, 0x4f, 0xe6, 0x3c, 0xbb, 0x30, 0xd5, 0x58, 0xc9, 0x7e, 0xcd, 0xc3, 0xd2, - 0x08, 0x0f, 0xe8, 0x5f, 0x5b, 0xa4, 0x8d, 0x5d, 0xcb, 0x16, 0xb1, 0x52, 0xab, 0x42, 0xa4, 0x8e, - 0xa9, 0xa2, 0x90, 0x1c, 0xca, 0x3c, 0x5c, 0xcd, 0xbf, 0x5d, 0xe2, 0x75, 0x22, 0x15, 0xc8, 0xd0, - 0x3c, 0xfb, 0xc4, 0x29, 0xdb, 0x4f, 0x9c, 0xc6, 0xba, 0xc4, 0x09, 0xbd, 0xde, 0x1d, 0x78, 0x1e, - 0xe0, 0x06, 0x9e, 0x5b, 0xc4, 0x50, 0x18, 0x49, 0xb8, 0xac, 0x0c, 0x65, 0x39, 0xfa, 0x69, 0x9f, - 0x6c, 0x23, 0x18, 0x63, 0xa0, 0x3a, 0xea, 0xcb, 0x7d, 0x1e, 0x91, 0x0c, 0xff, 0x9a, 0xf0, 0xad, - 0x19, 0x94, 0x7b, 0xb4, 0x11, 0x01, 0x52, 0x7c, 0x07, 0xa4, 0xf4, 0xd6, 0xa6, 0xc1, 0x26, 0x6e, - 0x7d, 0x44, 0x98, 0x64, 0x15, 0xbc, 0x26, 0x23, 0xa4, 0xee, 0xf8, 0xb1, 0x7b, 0x8d, 0x04, 0x29, - 0x5b, 0xcd, 0xfb, 0xe3, 0x7e, 0x22, 0x18, 0xa3, 0x93, 0x62, 0x0f, 0x38, 0xe7, 0xb9, 0xe7, 0xdd, - 0x21, 0xb3, 0x30, 0xb9, 0xdb, 0xd2, 0x5a, 0x46, 0xeb, 0xf2, 0x8e, 0xfe, 0x2a, 0x77, 0xaa, 0xc0, - 0xa5, 0xd9, 0xd4, 0x6f, 0xe1, 0x16, 0x36, 0x35, 0x0b, 0x57, 0xf7, 0xb6, 0x48, 0x6f, 0x1d, 0x53, - 0xfd, 0x49, 0xe8, 0xb1, 0x64, 0x34, 0x85, 0x63, 0x53, 0x1d, 0x7c, 0x45, 0xe5, 0xa6, 0xde, 0xc4, - 0xc4, 0xbf, 0x9d, 0xf9, 0x78, 0x38, 0xcf, 0x91, 0x7a, 0x53, 0x8f, 0x2a, 0x46, 0x82, 0x88, 0x4c, - 0xef, 0x4c, 0x59, 0x36, 0xea, 0x5a, 0xb3, 0x63, 0x19, 0x26, 0x46, 0x2f, 0xf7, 0xd0, 0x71, 0x10, - 0x48, 0xf8, 0x10, 0x38, 0x0e, 0x99, 0x86, 0x51, 0xf7, 0x3c, 0x19, 0xd8, 0x13, 0xbf, 0x9c, 0x09, - 0x3d, 0x46, 0x44, 0x1b, 0xdc, 0x5d, 0x6f, 0x6c, 0x17, 0xc8, 0x88, 0x1d, 0x2d, 0x12, 0x22, 0x6a, - 0x04, 0x71, 0x15, 0x92, 0x90, 0x5a, 0xd5, 0x5b, 0x5b, 0xfe, 0x45, 0xcc, 0x31, 0x48, 0xeb, 0xad, - 0x06, 0xbe, 0xc4, 0x46, 0x6a, 0xfa, 0x60, 0x0f, 0xe7, 0xad, 0xdd, 0x9d, 0x0d, 0x6c, 0x56, 0x36, - 0x49, 0x73, 0x3b, 0x35, 0xa3, 0x8a, 0x5b, 0xce, 0xcc, 0xac, 0xe7, 0x3b, 0xf4, 0x9d, 0x44, 0x34, - 0xb9, 0xb7, 0x29, 0x09, 0xc0, 0xc5, 0x25, 0x2a, 0xe9, 0x23, 0x2a, 0x92, 0xc4, 0xf7, 0x28, 0x3c, - 0x7e, 0xfe, 0x7e, 0x34, 0x09, 0xd9, 0x15, 0x6c, 0x99, 0x7a, 0xbd, 0x83, 0x9e, 0x49, 0xc2, 0x54, - 0x15, 0x5b, 0xab, 0x9a, 0xa9, 0xed, 0x60, 0xcb, 0x5e, 0x92, 0xdf, 0xc2, 0x29, 0xa6, 0x76, 0x53, - 0xb3, 0x36, 0x0d, 0x73, 0xc7, 0x51, 0x4c, 0xce, 0xf3, 0xdd, 0xa9, 0x27, 0xbe, 0x2a, 0x25, 0x78, - 0x66, 0x86, 0xba, 0xde, 0xb0, 0x0a, 0xe7, 0xb8, 0xca, 0x02, 0x4e, 0x58, 0x88, 0x39, 0xd3, 0x88, - 0x94, 0x18, 0x3f, 0x33, 0xff, 0x50, 0x02, 0x69, 0xd9, 0xd8, 0x42, 0xef, 0x91, 0x20, 0x45, 0xe4, - 0xeb, 0xb7, 0x7c, 0x43, 0xf2, 0x0c, 0x64, 0x77, 0x70, 0xa7, 0xa3, 0x6d, 0x61, 0xe7, 0x7e, 0x69, - 0xf6, 0xa8, 0x9c, 0x81, 0x74, 0x13, 0xef, 0xe1, 0x26, 0x21, 0x63, 0xfa, 0xf4, 0x75, 0x5c, 0xcb, - 0x96, 0x8d, 0xad, 0x39, 0xbb, 0x2c, 0xf7, 0x16, 0xda, 0x65, 0x3b, 0xab, 0x4a, 0xbf, 0x98, 0x7d, - 0x08, 0xd2, 0xe4, 0x59, 0x19, 0x87, 0x74, 0xa1, 0x38, 0xbf, 0xb6, 0x28, 0x1f, 0xb1, 0xff, 0x3a, - 0xf4, 0x8d, 0x43, 0x7a, 0x21, 0x57, 0xcb, 0x2d, 0xcb, 0x49, 0xbb, 0x1d, 0xa5, 0xf2, 0x42, 0x45, - 0x96, 0xec, 0xc4, 0xd5, 0x5c, 0xb9, 0x94, 0x97, 0x53, 0xca, 0x04, 0x64, 0xcf, 0xe7, 0xd4, 0x72, - 0xa9, 0xbc, 0x28, 0xa7, 0xd1, 0xa3, 0x7e, 0x85, 0x75, 0x37, 0x8f, 0xdf, 0xf5, 0x41, 0x34, 0xf5, - 0x82, 0xec, 0x3f, 0xb9, 0x90, 0xdd, 0xc7, 0x41, 0xf6, 0xbd, 0x22, 0x85, 0x44, 0x43, 0xa9, 0x3c, - 0x80, 0x21, 0x7b, 0x0a, 0xc6, 0xcb, 0x95, 0xda, 0xfa, 0x42, 0x65, 0xad, 0x5c, 0x90, 0xb1, 0xcd, - 0x83, 0x5a, 0x69, 0xa5, 0x58, 0x59, 0xab, 0xc9, 0x9b, 0xe8, 0x8d, 0x49, 0xc8, 0xae, 0x9a, 0x46, - 0x1d, 0x77, 0x3a, 0xe8, 0xb5, 0x49, 0xc8, 0xe4, 0xb5, 0x56, 0x1d, 0x37, 0xd1, 0x4b, 0x3c, 0x18, - 0xbb, 0x96, 0x84, 0xe8, 0x5b, 0x7e, 0xa9, 0x7f, 0x90, 0xe7, 0x1a, 0x7f, 0xaf, 0x30, 0x2b, 0x77, - 0x8e, 0x96, 0x19, 0xc0, 0xbb, 0xa7, 0x5d, 0xde, 0xe5, 0x39, 0xde, 0x9d, 0x12, 0x2f, 0x2a, 0x7e, - 0x39, 0xff, 0xfb, 0x04, 0x1c, 0x5b, 0xb4, 0xa7, 0x0f, 0x7a, 0x9d, 0x12, 0xef, 0xb4, 0xff, 0x3e, - 0xbe, 0xfd, 0x37, 0x71, 0x44, 0xf7, 0xfa, 0x82, 0x6f, 0xfc, 0x53, 0x6e, 0xe3, 0x1f, 0xe4, 0x1a, - 0x7f, 0xab, 0x60, 0x39, 0xb1, 0xb7, 0x7c, 0x36, 0x0b, 0x69, 0x32, 0x45, 0x9e, 0xbd, 0x01, 0xa6, - 0xaa, 0x96, 0x89, 0xb5, 0x1d, 0xdf, 0xa0, 0x64, 0x19, 0x17, 0x70, 0x8b, 0x89, 0x06, 0x7d, 0xb8, - 0xfb, 0x0c, 0x64, 0x5b, 0xc6, 0xba, 0xb6, 0x6b, 0x6d, 0x2b, 0x2f, 0xdd, 0x77, 0x6c, 0x68, 0x85, - 0xf6, 0xff, 0x4a, 0x9b, 0xee, 0x22, 0xfd, 0xd5, 0xbd, 0x64, 0x62, 0x96, 0x69, 0x19, 0xb9, 0x5d, - 0x6b, 0x7b, 0xfe, 0xea, 0x8f, 0x3c, 0x77, 0x22, 0xf1, 0x89, 0xe7, 0x4e, 0x24, 0xbe, 0xfc, 0xdc, - 0x89, 0xc4, 0xcf, 0x7e, 0xe5, 0xc4, 0x91, 0x4f, 0x7c, 0xe5, 0xc4, 0x91, 0xcf, 0x7f, 0xe5, 0xc4, - 0x91, 0x1f, 0x48, 0xb6, 0x37, 0x36, 0x32, 0xa4, 0x94, 0x3b, 0xff, 0x5f, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xaf, 0x86, 0x70, 0xda, 0xde, 0x38, 0x01, 0x00, + 0xc6, 0xf6, 0xda, 0xac, 0xed, 0x59, 0x7b, 0x9d, 0x0f, 0xaf, 0xbf, 0x35, 0x92, 0x66, 0x46, 0xde, + 0x19, 0x69, 0x68, 0x69, 0x76, 0x31, 0x1c, 0x37, 0xd7, 0x23, 0xd5, 0xcc, 0xb4, 0x57, 0xa3, 0x16, + 0xad, 0x9e, 0xd9, 0xdd, 0x3c, 0xcf, 0x1d, 0x18, 0x30, 0x36, 0xf0, 0x84, 0x40, 0x80, 0x0b, 0x86, + 0x4b, 0x4c, 0x1c, 0x12, 0x08, 0x21, 0x84, 0x10, 0x42, 0x2e, 0x5c, 0x08, 0x07, 0x49, 0x78, 0x42, + 0x1e, 0x88, 0x43, 0xbe, 0xe1, 0x92, 0x10, 0x9c, 0x5c, 0x2e, 0xdc, 0x25, 0x97, 0x0b, 0xcf, 0xdd, + 0x71, 0xc1, 0x70, 0xb9, 0xa7, 0xab, 0xaa, 0x3f, 0x4a, 0xa3, 0x6e, 0x55, 0x6b, 0xd4, 0x1a, 0xe7, + 0xf8, 0x4b, 0xea, 0xea, 0xea, 0xaa, 0xb7, 0xde, 0xdf, 0x5b, 0x6f, 0x55, 0xbd, 0xf5, 0xd6, 0x5b, + 0x30, 0xd3, 0xde, 0x38, 0xdd, 0x36, 0x0d, 0xcb, 0xe8, 0x9c, 0xae, 0x1b, 0x3b, 0x3b, 0x5a, 0xab, + 0xd1, 0x99, 0x23, 0xcf, 0x4a, 0x56, 0x6b, 0x5d, 0xb1, 0xae, 0xb4, 0x31, 0xba, 0xb1, 0x7d, 0x71, + 0xeb, 0x74, 0x53, 0xdf, 0x38, 0xdd, 0xde, 0x38, 0xbd, 0x63, 0x34, 0x70, 0xd3, 0xf9, 0x80, 0x3c, + 0xb0, 0xec, 0xe8, 0x96, 0xa0, 0x5c, 0x4d, 0xa3, 0xae, 0x35, 0x3b, 0x96, 0x61, 0x62, 0x96, 0xf3, + 0xb8, 0x57, 0x25, 0xde, 0xc3, 0x2d, 0xcb, 0x29, 0xe1, 0xda, 0x2d, 0xc3, 0xd8, 0x6a, 0x62, 0xfa, + 0x6e, 0x63, 0x77, 0xf3, 0x74, 0xc7, 0x32, 0x77, 0xeb, 0x16, 0x7b, 0x7b, 0x7d, 0xf7, 0xdb, 0x06, + 0xee, 0xd4, 0x4d, 0xbd, 0x6d, 0x19, 0x26, 0xcd, 0x31, 0xfb, 0x73, 0xff, 0x23, 0x05, 0x92, 0xda, + 0xae, 0xa3, 0x8f, 0x8e, 0x81, 0x94, 0x6b, 0xb7, 0xd1, 0x37, 0x93, 0x00, 0x8b, 0xd8, 0x3a, 0x8f, + 0xcd, 0x8e, 0x6e, 0xb4, 0xd0, 0x38, 0x64, 0x55, 0xfc, 0x83, 0xbb, 0xb8, 0x63, 0xa1, 0xcf, 0x24, + 0x61, 0x4c, 0xc5, 0x9d, 0xb6, 0xd1, 0xea, 0x60, 0xe5, 0x21, 0x48, 0x63, 0xd3, 0x34, 0xcc, 0x99, + 0xc4, 0xf5, 0x89, 0x5b, 0x26, 0xce, 0x9c, 0x9a, 0x63, 0x0d, 0x9f, 0x53, 0xdb, 0xf5, 0xb9, 0x5c, + 0xbb, 0x3d, 0xe7, 0x95, 0x31, 0xe7, 0x7c, 0x34, 0x57, 0xb4, 0xbf, 0x50, 0xe9, 0x87, 0xca, 0x0c, + 0x64, 0xf7, 0x68, 0x86, 0x99, 0xe4, 0xf5, 0x89, 0x5b, 0xc6, 0x55, 0xe7, 0xd1, 0x7e, 0xd3, 0xc0, + 0x96, 0xa6, 0x37, 0x3b, 0x33, 0x12, 0x7d, 0xc3, 0x1e, 0xd1, 0x27, 0x13, 0x90, 0x26, 0x85, 0x28, + 0x79, 0x48, 0xd5, 0x8d, 0x06, 0x26, 0xd5, 0x4f, 0x9f, 0x39, 0x2d, 0x5e, 0xfd, 0x5c, 0xde, 0x68, + 0x60, 0x95, 0x7c, 0xac, 0x5c, 0x0f, 0x13, 0x0e, 0x43, 0x3c, 0x32, 0xfc, 0x49, 0xb3, 0x0d, 0x48, + 0xd9, 0xf9, 0x95, 0x31, 0x48, 0x95, 0xd7, 0x96, 0x97, 0xe5, 0x23, 0xca, 0x55, 0x30, 0xb5, 0x56, + 0x3e, 0x57, 0xae, 0x5c, 0x28, 0xaf, 0x17, 0x55, 0xb5, 0xa2, 0xca, 0x09, 0x65, 0x0a, 0xc6, 0xe7, + 0x73, 0x85, 0xf5, 0x52, 0x79, 0x75, 0xad, 0x26, 0x27, 0x95, 0x63, 0x20, 0x9f, 0x2f, 0xaa, 0xd5, + 0x52, 0xa5, 0xbc, 0x5e, 0xaa, 0xae, 0x17, 0x57, 0x56, 0x6b, 0x8f, 0xc8, 0x92, 0x9d, 0xa9, 0x5c, + 0xa9, 0xad, 0x2f, 0x54, 0xd6, 0xca, 0x05, 0x19, 0x2b, 0x13, 0x90, 0xad, 0x95, 0x56, 0x8a, 0x95, + 0xb5, 0x9a, 0xbc, 0x89, 0x7e, 0x57, 0x82, 0xe9, 0x2a, 0xb6, 0x0a, 0x78, 0x4f, 0xaf, 0xe3, 0xaa, + 0xa5, 0x59, 0x18, 0xbd, 0x26, 0xe1, 0x32, 0x5e, 0x59, 0xb3, 0xc9, 0x74, 0x5f, 0xb1, 0x26, 0xdf, + 0xb5, 0xaf, 0xc9, 0x7c, 0x09, 0x73, 0xec, 0xeb, 0x39, 0x5f, 0x9a, 0xea, 0x2f, 0x67, 0xf6, 0x76, + 0x98, 0xf0, 0xbd, 0x53, 0xa6, 0x01, 0xe6, 0x73, 0xf9, 0x73, 0x8b, 0x2a, 0xa1, 0xf0, 0x88, 0xfd, + 0xbc, 0x50, 0x51, 0x8b, 0xec, 0x39, 0x81, 0x5e, 0xe3, 0x87, 0xbf, 0xc0, 0xc3, 0x3f, 0xd7, 0x9f, + 0x98, 0x1e, 0x22, 0x80, 0xde, 0xe7, 0xc2, 0xb9, 0xc8, 0xc1, 0x79, 0x57, 0xb4, 0xe2, 0xa2, 0x41, + 0xba, 0x34, 0x18, 0xa4, 0xe5, 0x4a, 0xa1, 0xb8, 0x6e, 0x23, 0x58, 0xad, 0xe5, 0xd4, 0x5a, 0xb1, + 0x20, 0x63, 0xf4, 0xcb, 0x49, 0x18, 0xab, 0x6e, 0xef, 0x5a, 0x0d, 0xe3, 0x12, 0xd7, 0x51, 0x7e, + 0xd4, 0xcf, 0xa9, 0x07, 0x78, 0x4e, 0xdd, 0xb2, 0xbf, 0x69, 0xac, 0x84, 0x00, 0x1e, 0xfd, 0x9e, + 0xcb, 0xa3, 0x1c, 0xc7, 0xa3, 0xdb, 0x45, 0x0b, 0x3a, 0x2c, 0xee, 0x7c, 0x6a, 0x0a, 0x32, 0x17, + 0xb4, 0x66, 0x13, 0x5b, 0xe8, 0xcb, 0x49, 0xc8, 0xe4, 0x4d, 0x6c, 0xcb, 0xf5, 0xad, 0x9e, 0x58, + 0x23, 0x18, 0x33, 0x0d, 0xc3, 0x5a, 0xd5, 0xac, 0x6d, 0xd2, 0xa6, 0x71, 0xd5, 0x7d, 0xbe, 0x27, + 0xf5, 0xe4, 0x57, 0xa4, 0x04, 0xfa, 0x4d, 0x3f, 0x23, 0x1f, 0xe4, 0x19, 0xf9, 0xdd, 0x5c, 0xfb, + 0x69, 0x45, 0x73, 0xb4, 0x92, 0x00, 0x85, 0x83, 0x60, 0x6c, 0xa7, 0x85, 0x77, 0x8c, 0x96, 0x5e, + 0x67, 0x2d, 0x77, 0x9f, 0xd1, 0x1f, 0xbb, 0x5c, 0x9e, 0xe7, 0xb8, 0x3c, 0x27, 0x5c, 0x4b, 0x34, + 0x36, 0x57, 0x07, 0x60, 0xf3, 0x4b, 0xe1, 0x9a, 0x85, 0x5c, 0x69, 0xb9, 0x58, 0x58, 0xaf, 0x55, + 0xd6, 0xf3, 0x6a, 0x31, 0x57, 0x2b, 0xae, 0x2f, 0x57, 0xf2, 0xb9, 0xe5, 0x75, 0xb5, 0xb8, 0x5a, + 0x91, 0x31, 0xfa, 0x2f, 0x49, 0x9b, 0xb9, 0x75, 0x63, 0x0f, 0x9b, 0x68, 0x51, 0x88, 0xcf, 0x61, + 0x3c, 0x61, 0x18, 0xbc, 0x56, 0x58, 0xeb, 0x33, 0xee, 0x30, 0x0a, 0x02, 0xc4, 0xf9, 0x03, 0x42, + 0x1a, 0x3c, 0xb4, 0xa8, 0x17, 0x00, 0xa7, 0xff, 0x67, 0x12, 0xb2, 0x79, 0xa3, 0xb5, 0x87, 0x4d, + 0x0b, 0x3d, 0xc8, 0x71, 0xda, 0xe5, 0x66, 0x82, 0xe7, 0xa6, 0x3d, 0xa8, 0xe1, 0x96, 0x65, 0x1a, + 0xed, 0x2b, 0xce, 0x70, 0xc7, 0x1e, 0xd1, 0xaf, 0x45, 0xe5, 0x30, 0xab, 0x39, 0x78, 0x5c, 0xed, + 0x5d, 0x11, 0x47, 0x9e, 0xd4, 0xd5, 0x01, 0x9e, 0x89, 0x82, 0x4b, 0x6f, 0x02, 0xa2, 0xe1, 0x72, + 0x26, 0x3a, 0x2e, 0xe8, 0xe3, 0x49, 0x98, 0xa2, 0x9d, 0xaf, 0x8a, 0x3b, 0x64, 0x7a, 0x72, 0xab, + 0x10, 0xf3, 0x99, 0x28, 0xff, 0x9c, 0x9f, 0xd1, 0x0b, 0x3c, 0xa3, 0xef, 0x08, 0xee, 0xe8, 0xac, + 0xae, 0x00, 0x76, 0x1f, 0x83, 0xb4, 0x65, 0x5c, 0xc4, 0x4e, 0x1b, 0xe9, 0x03, 0xfa, 0x75, 0x97, + 0x9d, 0x25, 0x8e, 0x9d, 0x2f, 0x8f, 0x5a, 0x4d, 0xfc, 0x4c, 0x7d, 0x7b, 0x12, 0x26, 0xf3, 0x4d, + 0xa3, 0xe3, 0xf2, 0xf4, 0xa5, 0x1e, 0x4f, 0xdd, 0xc6, 0x25, 0xfc, 0x8d, 0x7b, 0x3e, 0xe1, 0xe3, + 0x63, 0x91, 0xe7, 0x63, 0x6f, 0x79, 0xf1, 0x15, 0x1f, 0xa0, 0x17, 0x7e, 0xcd, 0x65, 0xd8, 0x12, + 0xc7, 0xb0, 0x97, 0x45, 0x2c, 0x2f, 0x7e, 0x7e, 0xfd, 0xde, 0x77, 0x41, 0x36, 0x57, 0xaf, 0x1b, + 0xbb, 0x2d, 0x0b, 0xfd, 0x75, 0x02, 0x32, 0x79, 0xa3, 0xb5, 0xa9, 0x6f, 0x29, 0x27, 0x61, 0x1a, + 0xb7, 0xb4, 0x8d, 0x26, 0x2e, 0x68, 0x96, 0xb6, 0xa7, 0xe3, 0x4b, 0xa4, 0x01, 0x63, 0x6a, 0x57, + 0xaa, 0x4d, 0x14, 0x4b, 0xc1, 0x1b, 0xbb, 0x5b, 0x84, 0xa8, 0x31, 0xd5, 0x9f, 0xa4, 0xdc, 0x0d, + 0x57, 0xd3, 0xc7, 0x55, 0x13, 0x9b, 0xb8, 0x89, 0xb5, 0x0e, 0xce, 0x6f, 0x6b, 0xad, 0x16, 0x6e, + 0x92, 0x5e, 0x3b, 0xa6, 0x06, 0xbd, 0x56, 0x66, 0x61, 0x92, 0xbe, 0xaa, 0xb6, 0xb5, 0x3a, 0xee, + 0xcc, 0xa4, 0x48, 0x76, 0x2e, 0x4d, 0xb9, 0x1d, 0xd2, 0xf8, 0xb2, 0x65, 0x6a, 0x33, 0x0d, 0x82, + 0xd7, 0xd5, 0x73, 0x74, 0x89, 0x30, 0xe7, 0x2c, 0x11, 0xe6, 0xaa, 0x64, 0x01, 0xa1, 0xd2, 0x5c, + 0xe8, 0x03, 0x19, 0x77, 0xe8, 0x7e, 0xa3, 0x6f, 0x4a, 0xaa, 0x40, 0xaa, 0xa5, 0xed, 0x60, 0x26, + 0x17, 0xe4, 0xbf, 0x72, 0x0a, 0x8e, 0x6a, 0x7b, 0x9a, 0xa5, 0x99, 0xcb, 0xf6, 0xe2, 0x85, 0x0c, + 0x37, 0x84, 0xe5, 0x4b, 0x47, 0xd4, 0xee, 0x17, 0xca, 0xb5, 0x30, 0x4e, 0x56, 0x37, 0x24, 0x17, + 0xd5, 0x45, 0x5e, 0x82, 0x72, 0x0b, 0x1c, 0xd5, 0x9a, 0xed, 0x6d, 0xad, 0xd4, 0xda, 0xd3, 0x2d, + 0x6c, 0x23, 0x34, 0x73, 0x8c, 0xe4, 0xe9, 0x4e, 0xa6, 0x1d, 0x7b, 0x7e, 0x0c, 0x32, 0xb4, 0x02, + 0xf4, 0xf3, 0x69, 0xe1, 0x35, 0x0a, 0x85, 0x30, 0x7c, 0xca, 0x70, 0x07, 0x64, 0x35, 0x9a, 0x8f, + 0x34, 0x65, 0xe2, 0xcc, 0x71, 0xb7, 0x0c, 0xb2, 0x5c, 0x73, 0x4a, 0x51, 0x9d, 0x6c, 0xca, 0x5d, + 0x90, 0xa9, 0x13, 0x81, 0x20, 0xad, 0x9a, 0x38, 0x73, 0x4d, 0xef, 0x4a, 0x49, 0x16, 0x95, 0x65, + 0x45, 0x5f, 0x90, 0x84, 0x96, 0x35, 0x61, 0x14, 0x47, 0x93, 0xfb, 0xaf, 0x27, 0x07, 0x18, 0x15, + 0x6f, 0x83, 0x5b, 0x72, 0xf9, 0x7c, 0x65, 0xad, 0x5c, 0x63, 0x63, 0x62, 0x61, 0x7d, 0x7e, 0xad, + 0xb6, 0xee, 0x8d, 0x94, 0x64, 0xee, 0xb7, 0x6e, 0x4f, 0x05, 0x65, 0x5b, 0x1a, 0x4e, 0xf6, 0xc9, + 0x5d, 0xac, 0xad, 0x97, 0x73, 0x2b, 0x45, 0x79, 0x53, 0xa0, 0xe4, 0x62, 0x6d, 0x3d, 0x77, 0x3e, + 0x57, 0xcb, 0xa9, 0xf2, 0x16, 0x3f, 0x3a, 0x57, 0x6b, 0x95, 0xd5, 0x75, 0x75, 0xad, 0x5c, 0x2e, + 0x95, 0x17, 0x69, 0xd5, 0xf6, 0xa4, 0xe6, 0xb8, 0x97, 0xe1, 0x82, 0x5a, 0xaa, 0x15, 0xd7, 0xf3, + 0x95, 0xf2, 0x42, 0x69, 0x51, 0xd6, 0xfb, 0x0d, 0xed, 0x8f, 0x2a, 0xc7, 0xe0, 0x28, 0x6d, 0xf4, + 0x79, 0xfa, 0x5d, 0xa1, 0x28, 0xff, 0x58, 0x56, 0x99, 0x86, 0xf1, 0x72, 0xb1, 0xc6, 0x38, 0xf3, + 0x78, 0x56, 0xb9, 0x06, 0x8e, 0xdb, 0xcf, 0xf9, 0x4a, 0xb9, 0x5c, 0xcc, 0xd7, 0xec, 0xa5, 0x9e, + 0x5a, 0x5c, 0x58, 0xab, 0x16, 0x0b, 0xf2, 0x8f, 0x67, 0x15, 0x19, 0x26, 0xec, 0x97, 0x95, 0x85, + 0x85, 0xe5, 0x52, 0xb9, 0x28, 0x3f, 0x91, 0x45, 0x6f, 0x4e, 0x79, 0x33, 0x33, 0xdf, 0x42, 0xe1, + 0xa7, 0x53, 0x3e, 0x69, 0xcd, 0xf1, 0xd2, 0x7a, 0x6b, 0x4f, 0xec, 0xc3, 0x27, 0x57, 0xef, 0x77, + 0xe5, 0xa8, 0xc0, 0xc9, 0xd1, 0x1d, 0x11, 0xca, 0x8a, 0x26, 0x48, 0x7f, 0x36, 0x88, 0x20, 0xbd, + 0x18, 0xae, 0x2a, 0x57, 0xd6, 0x19, 0xe2, 0x55, 0x77, 0x49, 0x7c, 0x3d, 0x5c, 0x5b, 0x2e, 0x52, + 0x60, 0xd4, 0x62, 0xbe, 0x72, 0xbe, 0xa8, 0xae, 0x5f, 0xc8, 0x2d, 0x2f, 0x17, 0x6b, 0xeb, 0x0b, + 0x25, 0xb5, 0x5a, 0x93, 0x37, 0xfb, 0x81, 0xb7, 0xa5, 0xdc, 0x00, 0x2f, 0xf5, 0x9e, 0xd7, 0x8b, + 0xdf, 0x5b, 0xaa, 0xd6, 0xaa, 0x44, 0x94, 0xf2, 0x15, 0x55, 0x5d, 0x5b, 0xb5, 0x17, 0x26, 0xdb, + 0xca, 0x71, 0x50, 0xbc, 0x52, 0xd4, 0xb5, 0x32, 0x15, 0x1b, 0xdd, 0xae, 0x9f, 0xd5, 0xe7, 0x54, + 0x6f, 0x2f, 0x68, 0x56, 0x8b, 0xea, 0x42, 0x45, 0x5d, 0x29, 0x16, 0xe4, 0x47, 0xfb, 0x49, 0xde, + 0x45, 0xe5, 0x24, 0xcc, 0xe6, 0xca, 0x95, 0xda, 0x52, 0x51, 0x5d, 0xcf, 0x95, 0x1f, 0xa9, 0x3d, + 0xb2, 0x5a, 0x5c, 0x5f, 0x55, 0x2b, 0xf9, 0x62, 0xb5, 0xba, 0x5e, 0xaa, 0x3a, 0x99, 0xe5, 0xa6, + 0x4d, 0x82, 0x23, 0xf0, 0xa5, 0xea, 0x7a, 0xa1, 0xb8, 0x5c, 0xb4, 0x49, 0xdb, 0x41, 0xaf, 0x96, + 0x20, 0x53, 0xc0, 0x4d, 0x6c, 0x61, 0xf4, 0x5d, 0x9e, 0xb2, 0x3d, 0x0e, 0x19, 0x13, 0xdb, 0x13, + 0x2e, 0x36, 0xa4, 0xb0, 0x27, 0xf4, 0xd7, 0xc9, 0xa8, 0xca, 0x8e, 0x96, 0x1d, 0xa0, 0xec, 0x5e, + 0x0e, 0x99, 0x8e, 0xa5, 0x59, 0xbb, 0x1d, 0xa6, 0xeb, 0xae, 0xeb, 0xad, 0xeb, 0xe6, 0xaa, 0x24, + 0x93, 0xca, 0x32, 0xa3, 0xbf, 0x4c, 0x44, 0x51, 0x5e, 0x3d, 0x29, 0x88, 0x26, 0x73, 0xfa, 0x00, + 0x22, 0x77, 0x02, 0x90, 0x8f, 0xe1, 0xb9, 0x65, 0xb5, 0x98, 0x2b, 0x3c, 0xe2, 0x32, 0x1e, 0xdb, + 0x22, 0xe9, 0x7f, 0x9f, 0xaf, 0x95, 0xce, 0x17, 0xe5, 0x4d, 0xf4, 0x81, 0x34, 0x64, 0xaa, 0xb8, + 0x89, 0xeb, 0x16, 0xba, 0xd7, 0xc3, 0x63, 0x1a, 0x92, 0x7a, 0x83, 0x0d, 0x7d, 0x49, 0xbd, 0xc1, + 0x2d, 0xb0, 0x92, 0x3d, 0x17, 0xb2, 0xcf, 0xa7, 0xa2, 0x22, 0x45, 0x6b, 0x3d, 0xdc, 0x61, 0xe9, + 0x43, 0x91, 0x86, 0xa5, 0x9e, 0x14, 0x47, 0x43, 0xf6, 0x93, 0xc9, 0x18, 0x16, 0x6b, 0x22, 0x4a, + 0x61, 0x33, 0x40, 0x29, 0x74, 0x0d, 0x36, 0x0b, 0xa5, 0x72, 0x61, 0xdd, 0x95, 0x93, 0xf2, 0x42, + 0x45, 0xde, 0x56, 0xe6, 0xe0, 0x94, 0xaf, 0x74, 0x5b, 0x63, 0xb0, 0x1a, 0x72, 0xe5, 0xc2, 0xfa, + 0x4a, 0xb9, 0xb8, 0x52, 0x29, 0x97, 0xf2, 0xd4, 0x34, 0x52, 0xac, 0x51, 0x2d, 0xd3, 0xa5, 0x43, + 0xaa, 0xc5, 0x9c, 0x9a, 0x5f, 0x22, 0xea, 0xa6, 0x50, 0x94, 0x1f, 0x55, 0x6e, 0x86, 0x1b, 0x7c, + 0xa4, 0x30, 0x55, 0xb4, 0xaa, 0x16, 0x0b, 0xc5, 0x85, 0x52, 0xd9, 0x1e, 0x1a, 0x97, 0x2b, 0xf9, + 0x73, 0x55, 0x71, 0x6d, 0x83, 0xfe, 0x21, 0x09, 0xa9, 0xaa, 0x65, 0xb4, 0xd1, 0x77, 0x7b, 0x32, + 0x7c, 0x02, 0xc0, 0xc4, 0x3b, 0xc6, 0x1e, 0x99, 0x98, 0x32, 0xbd, 0xe2, 0x4b, 0x41, 0x7f, 0x22, + 0x6e, 0xc3, 0x72, 0xd5, 0x82, 0xd1, 0x0e, 0x18, 0x97, 0xbe, 0x25, 0x66, 0xc3, 0x0a, 0x2e, 0x28, + 0x9a, 0x18, 0xfd, 0x64, 0x62, 0x00, 0x31, 0x42, 0x70, 0xdc, 0xa7, 0x01, 0x6c, 0xbc, 0x1c, 0x06, + 0x62, 0xe5, 0x6a, 0x78, 0x51, 0x17, 0x66, 0x04, 0xaa, 0x4d, 0xe5, 0xbb, 0xe0, 0x3a, 0x3f, 0x54, + 0x2b, 0x95, 0xf3, 0x45, 0x57, 0x3e, 0x0a, 0xb9, 0x5a, 0x4e, 0xde, 0x42, 0x9f, 0x90, 0x20, 0xb5, + 0x62, 0xec, 0x61, 0x74, 0x83, 0xc7, 0xfc, 0x19, 0xc8, 0xb6, 0xf0, 0x25, 0x9f, 0x41, 0xc6, 0x79, + 0x44, 0x6f, 0x96, 0xa2, 0xb2, 0xdd, 0x2e, 0x3b, 0x80, 0xed, 0x9f, 0x4d, 0x46, 0x61, 0x7b, 0x8f, + 0x82, 0xa2, 0xb1, 0xfd, 0x6f, 0x07, 0x61, 0x7b, 0x00, 0x6b, 0xb1, 0x32, 0x0b, 0x27, 0xbc, 0x17, + 0xa5, 0x42, 0xb1, 0x5c, 0x2b, 0x2d, 0x3c, 0xe2, 0x31, 0xb7, 0xa4, 0x0a, 0xb1, 0xbf, 0x9f, 0x76, + 0x08, 0x9f, 0x2c, 0xce, 0xc0, 0x31, 0xef, 0xdd, 0x22, 0x9d, 0xef, 0xd9, 0x6f, 0x1e, 0x45, 0xaf, + 0x4d, 0xc3, 0x24, 0xd5, 0x96, 0x6b, 0xed, 0x86, 0xbd, 0x38, 0xba, 0x89, 0x33, 0x44, 0x58, 0xfa, + 0x0e, 0xfe, 0x3e, 0xa3, 0xe5, 0xac, 0x8f, 0xdc, 0x67, 0xf4, 0x31, 0x61, 0x13, 0x04, 0xaf, 0x93, + 0x69, 0x2d, 0x01, 0x38, 0x3f, 0x2f, 0x64, 0x6c, 0x10, 0x28, 0x30, 0x1a, 0xde, 0x3f, 0x36, 0xec, + 0x6e, 0x16, 0x0c, 0xc5, 0x66, 0x20, 0x14, 0x5b, 0xb3, 0x4f, 0x24, 0x61, 0xbc, 0xa6, 0xef, 0xe0, + 0x57, 0x19, 0x2d, 0xdc, 0x51, 0xb2, 0x20, 0x2d, 0xae, 0xd4, 0xe4, 0x23, 0xf6, 0x9f, 0x62, 0xbe, + 0x26, 0x27, 0xc8, 0x9f, 0xa2, 0x5d, 0xb5, 0xfd, 0x27, 0x57, 0x93, 0x25, 0xfb, 0xcf, 0x4a, 0xb1, + 0x26, 0xa7, 0xec, 0x3f, 0xe5, 0x62, 0x4d, 0x4e, 0xdb, 0x7f, 0x56, 0x97, 0x6b, 0x72, 0xc6, 0xfe, + 0x53, 0xaa, 0xd6, 0xe4, 0xac, 0xfd, 0x67, 0xbe, 0x5a, 0x93, 0xc7, 0xec, 0x3f, 0xe7, 0xab, 0x35, + 0x79, 0xdc, 0xfe, 0x93, 0xaf, 0xd5, 0x64, 0xb0, 0xff, 0x3c, 0x5c, 0xad, 0xc9, 0x13, 0xf6, 0x9f, + 0x5c, 0xbe, 0x26, 0x4f, 0x92, 0x3f, 0xc5, 0x9a, 0x3c, 0x65, 0xff, 0xa9, 0x56, 0x6b, 0xf2, 0x34, + 0x29, 0xb9, 0x5a, 0x93, 0x8f, 0x92, 0xba, 0x4a, 0x35, 0x59, 0xb6, 0xff, 0x2c, 0x55, 0x6b, 0xf2, + 0x55, 0x24, 0x73, 0xb5, 0x26, 0x2b, 0xa4, 0xd2, 0x6a, 0x4d, 0x7e, 0x11, 0xc9, 0x53, 0xad, 0xc9, + 0xc7, 0x48, 0x15, 0xd5, 0x9a, 0xfc, 0x62, 0x42, 0x46, 0xb1, 0x26, 0x1f, 0x27, 0x79, 0xd4, 0x9a, + 0x7c, 0x35, 0x79, 0x55, 0xae, 0xc9, 0x33, 0x84, 0xb0, 0x62, 0x4d, 0x7e, 0x09, 0xf9, 0xa3, 0xd6, + 0x64, 0x44, 0x5e, 0xe5, 0x6a, 0xf2, 0x35, 0xe8, 0x3a, 0x18, 0x5f, 0xc4, 0x16, 0xc5, 0x17, 0xc9, + 0x20, 0x2d, 0x62, 0xcb, 0xbf, 0xda, 0x78, 0xfd, 0x0c, 0x8c, 0x5f, 0x30, 0xcc, 0x8b, 0x9d, 0xb6, + 0x56, 0xc7, 0xe8, 0xbd, 0x74, 0x9f, 0x2f, 0xbf, 0x6b, 0x9a, 0xb8, 0xc5, 0xe5, 0x7b, 0x5a, 0xdc, + 0x4c, 0xe6, 0x94, 0x36, 0xe7, 0x95, 0x14, 0x30, 0x65, 0xb9, 0x1e, 0x26, 0x2e, 0x39, 0xb9, 0x4b, + 0x0d, 0x47, 0x9c, 0x7c, 0x49, 0xa2, 0x26, 0xb3, 0xfe, 0x55, 0xc6, 0x6f, 0x02, 0x7a, 0x47, 0x12, + 0x32, 0x8b, 0xd8, 0xca, 0x35, 0x9b, 0x7e, 0xbe, 0x3d, 0xe5, 0xe7, 0xdb, 0x3c, 0xcf, 0xb7, 0xdb, + 0x82, 0x1b, 0x91, 0x6b, 0x36, 0x03, 0x78, 0x36, 0x0b, 0x93, 0x3e, 0x06, 0xd9, 0xd3, 0x72, 0xe9, + 0x96, 0x71, 0x95, 0x4b, 0x43, 0xbf, 0xea, 0x72, 0xad, 0xc8, 0x71, 0xed, 0xce, 0x28, 0x15, 0xc6, + 0xcf, 0xb1, 0x3f, 0xf2, 0x76, 0x80, 0xae, 0x0b, 0xb5, 0x22, 0xa1, 0xd7, 0x0d, 0xc0, 0xc5, 0x50, + 0x1b, 0x4e, 0x7f, 0xc9, 0x8b, 0xca, 0xc3, 0x21, 0x18, 0x60, 0x06, 0xe1, 0xe1, 0x7b, 0xc7, 0x20, + 0x53, 0xd9, 0x78, 0xd4, 0x5e, 0x8c, 0x3c, 0x9f, 0x04, 0x29, 0xd7, 0x68, 0x74, 0x8d, 0x3a, 0x06, + 0x79, 0x59, 0x72, 0x96, 0x26, 0xee, 0x33, 0xfa, 0xb3, 0x01, 0x7a, 0x34, 0xad, 0x69, 0x2e, 0xd7, + 0x68, 0x04, 0x6f, 0xa7, 0xb9, 0x15, 0x26, 0xf9, 0x0a, 0x95, 0x3b, 0xf9, 0x1d, 0xfc, 0x10, 0x33, + 0xa3, 0xbb, 0xb5, 0x1f, 0xb5, 0xfb, 0x07, 0xd2, 0x17, 0x3f, 0x10, 0x9f, 0x4d, 0x42, 0x76, 0x59, + 0xef, 0x58, 0x36, 0x02, 0x37, 0x7b, 0x08, 0x5c, 0x0b, 0xe3, 0x0e, 0x03, 0x3a, 0x33, 0x09, 0xd2, + 0x57, 0xbd, 0x04, 0xf4, 0x26, 0x3f, 0x06, 0x0f, 0xf3, 0x18, 0xbc, 0x2c, 0xbc, 0x8d, 0xac, 0xae, + 0x00, 0x1c, 0xb8, 0x6a, 0x93, 0xdd, 0xd5, 0xfe, 0xa6, 0xcb, 0xd6, 0x15, 0x8e, 0xad, 0x67, 0x07, + 0xa9, 0x32, 0x7e, 0xd6, 0x7e, 0x2a, 0x09, 0x60, 0xd7, 0xad, 0x92, 0x95, 0x88, 0x38, 0x77, 0x5f, + 0xef, 0xe7, 0xee, 0x0a, 0xcf, 0xdd, 0x57, 0xf6, 0x6f, 0x2a, 0xad, 0x2e, 0x80, 0xc1, 0x32, 0x48, + 0xba, 0xcb, 0x5a, 0xfb, 0x2f, 0x7a, 0x87, 0xcb, 0xd4, 0x55, 0x8e, 0xa9, 0xf7, 0x0d, 0x58, 0x53, + 0xfc, 0x7c, 0xfd, 0x6f, 0x49, 0x90, 0xab, 0xd8, 0x2a, 0x75, 0x96, 0xf4, 0xad, 0xed, 0xa6, 0xbe, + 0xb5, 0x6d, 0xe1, 0x06, 0x3a, 0x27, 0xa4, 0x3d, 0x94, 0x1b, 0x61, 0x4a, 0xf7, 0x7f, 0xc7, 0xf6, + 0x2c, 0xf8, 0x44, 0xf4, 0x13, 0x7e, 0x04, 0x96, 0x79, 0x04, 0x5e, 0x11, 0xc0, 0x97, 0x6e, 0x8a, + 0x02, 0xe6, 0xb7, 0xbf, 0xe5, 0xb2, 0xbb, 0xc2, 0xb1, 0xfb, 0xde, 0xc1, 0x8a, 0x1d, 0xc9, 0x96, + 0x9a, 0x63, 0x36, 0xf2, 0x6d, 0x50, 0x76, 0x0d, 0x44, 0x89, 0xfd, 0x03, 0xd1, 0xff, 0x4a, 0x44, + 0x1f, 0xfb, 0xc2, 0x0c, 0x45, 0x91, 0x47, 0xb6, 0x21, 0xd8, 0x70, 0x06, 0xe1, 0xd7, 0x8f, 0x4a, + 0x90, 0x29, 0x5e, 0x6e, 0x1b, 0xfc, 0x6e, 0xba, 0x02, 0xa9, 0xb6, 0xb7, 0x44, 0x26, 0xff, 0x05, + 0x06, 0xf3, 0xf7, 0x0c, 0x30, 0x7f, 0xa0, 0x75, 0x07, 0x74, 0x7f, 0x87, 0x8c, 0xa4, 0x8f, 0x8c, + 0xdb, 0x20, 0x4d, 0xbc, 0xf0, 0xd8, 0xe8, 0xe6, 0x99, 0xdf, 0x9c, 0x22, 0x8a, 0xf6, 0x5b, 0x95, + 0x66, 0x8a, 0x8c, 0x42, 0x4f, 0x72, 0xe2, 0x47, 0xe1, 0x9b, 0xaf, 0x4d, 0xb8, 0x13, 0x8c, 0x9f, + 0x48, 0x41, 0xaa, 0xd2, 0xc6, 0x2d, 0xf4, 0xf6, 0x04, 0xa7, 0x82, 0xeb, 0x46, 0xcb, 0xc2, 0x97, + 0x3d, 0x2d, 0xe1, 0x25, 0x84, 0xce, 0x07, 0x66, 0x20, 0x6b, 0x99, 0x14, 0x32, 0xe6, 0xd1, 0xc7, + 0x1e, 0x95, 0x32, 0xcc, 0xea, 0xad, 0x7a, 0x73, 0xb7, 0x81, 0x55, 0xdc, 0xd4, 0x6c, 0xda, 0x3b, + 0xb9, 0x4e, 0x01, 0xb7, 0x71, 0xab, 0x81, 0x5b, 0x16, 0xa5, 0xc6, 0xd9, 0xc8, 0x14, 0xc8, 0xc9, + 0x2f, 0xb0, 0xef, 0xe7, 0xe1, 0xbf, 0x99, 0xe3, 0x37, 0x53, 0xca, 0x76, 0x2b, 0x03, 0x90, 0x3f, + 0x0b, 0x40, 0x5b, 0x70, 0x5e, 0xc7, 0x97, 0x98, 0xa5, 0xf5, 0x25, 0x5d, 0x96, 0xd6, 0x8a, 0x9b, + 0x41, 0xf5, 0x65, 0x46, 0x7f, 0xea, 0x42, 0xfe, 0x10, 0x07, 0xf9, 0x6d, 0x82, 0x24, 0x44, 0x43, + 0xfb, 0x5f, 0x0c, 0xb0, 0x10, 0xe7, 0xfc, 0x11, 0x25, 0xe5, 0x25, 0xf0, 0x62, 0xc7, 0x86, 0x58, + 0x2e, 0x16, 0x0b, 0xd5, 0xf5, 0xb5, 0xd5, 0x45, 0x35, 0x57, 0x28, 0xca, 0x80, 0xde, 0x97, 0x84, + 0x34, 0xd9, 0x71, 0x47, 0xf9, 0x21, 0xc8, 0x02, 0xfa, 0x7a, 0x42, 0xd4, 0xc4, 0xc5, 0xd8, 0x43, + 0xea, 0x0e, 0x50, 0x70, 0xbf, 0x22, 0x64, 0x59, 0x0c, 0x29, 0x28, 0xfe, 0x6e, 0x65, 0x77, 0xa5, + 0xea, 0xb6, 0x71, 0xe9, 0xff, 0xff, 0xae, 0x64, 0xb7, 0xf2, 0x90, 0xbb, 0x52, 0x0f, 0x12, 0x5e, + 0x48, 0x5d, 0xe9, 0xa9, 0x94, 0xbb, 0x0c, 0x7e, 0xda, 0x27, 0x0d, 0xbe, 0xe5, 0x52, 0x42, 0x6c, + 0xb9, 0xa4, 0xe4, 0x60, 0x4a, 0x6f, 0x59, 0xd8, 0x6c, 0x69, 0xcd, 0x85, 0xa6, 0xb6, 0x45, 0xa7, + 0xa7, 0xfe, 0x7d, 0x1d, 0xca, 0xd3, 0x92, 0x2f, 0x8f, 0xca, 0x7f, 0xa1, 0x9c, 0x00, 0xb0, 0xf0, + 0x4e, 0xbb, 0xa9, 0x59, 0x9e, 0x30, 0xf9, 0x52, 0xd0, 0xd7, 0x84, 0xbd, 0x2f, 0x9d, 0xfe, 0xd5, + 0xc7, 0xfb, 0xd2, 0x95, 0x69, 0xa9, 0x4b, 0xa6, 0xdd, 0xe1, 0x34, 0x25, 0x30, 0x9c, 0xfa, 0xb9, + 0x95, 0x16, 0x5c, 0x5c, 0xbe, 0x51, 0xc8, 0xbd, 0x33, 0xac, 0x19, 0xf1, 0xeb, 0x89, 0xa7, 0x25, + 0x98, 0xa6, 0x55, 0xcf, 0x1b, 0xc6, 0xc5, 0x1d, 0xcd, 0xbc, 0x88, 0xee, 0x3b, 0x88, 0x88, 0xa0, + 0x8f, 0xfa, 0xf1, 0x5b, 0xe4, 0xf1, 0xbb, 0x33, 0xb8, 0xe1, 0x4e, 0xed, 0xa3, 0x59, 0xf6, 0xbf, + 0xd5, 0x45, 0xe6, 0x61, 0x0e, 0x99, 0x57, 0x44, 0x26, 0x30, 0x7e, 0x84, 0xde, 0xe9, 0x22, 0xe4, + 0xa8, 0xcd, 0x03, 0x22, 0xf4, 0xc5, 0xc1, 0x10, 0x72, 0x6a, 0x1f, 0x00, 0x21, 0x19, 0xa4, 0x8b, + 0xf8, 0x0a, 0xeb, 0x80, 0xf6, 0x5f, 0x3f, 0xd9, 0xa9, 0xf8, 0x30, 0x0b, 0x20, 0x79, 0x24, 0x98, + 0x1d, 0xe3, 0x49, 0xa8, 0xb4, 0x87, 0x80, 0xdc, 0x5f, 0x09, 0xdb, 0x1b, 0x7a, 0xb2, 0x81, 0xd2, + 0x30, 0x9a, 0x1e, 0x26, 0x66, 0xac, 0x10, 0x27, 0x33, 0x7e, 0xcc, 0x3e, 0x93, 0x82, 0x71, 0xc7, + 0x27, 0xd6, 0x42, 0xef, 0x49, 0x70, 0x9e, 0x30, 0x1d, 0x63, 0xd7, 0xac, 0x63, 0x66, 0x01, 0x62, + 0x4f, 0x7e, 0xb6, 0x24, 0x05, 0x07, 0xd0, 0x3e, 0xa3, 0xdf, 0xfe, 0x01, 0x36, 0x15, 0x75, 0x80, + 0x45, 0xaf, 0x91, 0x44, 0x97, 0xa2, 0x1c, 0xf7, 0xab, 0xd8, 0x7a, 0x21, 0x8e, 0xa1, 0x7f, 0x24, + 0xb4, 0x8a, 0xed, 0xd3, 0x92, 0x68, 0xc2, 0x53, 0x19, 0x60, 0x32, 0x76, 0x0d, 0x5c, 0xed, 0xe4, + 0xa8, 0xcc, 0x3f, 0x5c, 0xcc, 0xd7, 0xd6, 0xc9, 0x4c, 0x6c, 0x4d, 0x5d, 0x96, 0x25, 0xf4, 0x78, + 0x0a, 0x64, 0x4a, 0x1a, 0xa5, 0xb3, 0x76, 0xa5, 0x8d, 0xd1, 0x0f, 0x1d, 0xf2, 0x44, 0x0c, 0x7d, + 0xc3, 0xaf, 0x4c, 0x4a, 0xbc, 0x9c, 0xdc, 0x15, 0xcc, 0x5d, 0xaf, 0x09, 0x01, 0xe2, 0x32, 0x40, + 0xaf, 0x08, 0x91, 0x30, 0xf4, 0x61, 0x57, 0x00, 0x96, 0x39, 0x01, 0xb8, 0x7b, 0x00, 0x12, 0x0f, + 0x59, 0x0e, 0x3e, 0x92, 0x84, 0x29, 0x67, 0x1a, 0xb1, 0x80, 0xad, 0xfa, 0x36, 0x3a, 0x2b, 0xba, + 0x36, 0x93, 0x41, 0xda, 0x35, 0x9b, 0x8c, 0x4a, 0xfb, 0x2f, 0xfa, 0xa7, 0x84, 0xe8, 0xee, 0x0a, + 0xe3, 0x0d, 0x57, 0x73, 0xc0, 0xc2, 0x56, 0x6c, 0x3b, 0x44, 0xa0, 0xc0, 0xf8, 0xd5, 0xf5, 0xe7, + 0x93, 0x00, 0x35, 0xc3, 0x9d, 0xb4, 0x1e, 0x80, 0x93, 0xdc, 0x01, 0x8d, 0x3c, 0xcf, 0xc9, 0x9e, + 0x2b, 0x7a, 0xaf, 0xda, 0xe8, 0x63, 0x29, 0x7a, 0xb3, 0xcb, 0xe2, 0x05, 0x8e, 0xc5, 0x67, 0x22, + 0xd5, 0x14, 0x3f, 0x7f, 0xdf, 0x97, 0x84, 0xf1, 0xc2, 0x6e, 0xbb, 0xa9, 0xd7, 0xed, 0x75, 0xe3, + 0xcd, 0x82, 0xec, 0x45, 0x8f, 0x27, 0x23, 0x8e, 0x3e, 0x6e, 0x1d, 0x01, 0xbc, 0xa4, 0x6e, 0x8f, + 0x49, 0xc7, 0xed, 0x51, 0xd0, 0xac, 0xd9, 0xa7, 0xf0, 0x11, 0x88, 0xa7, 0x04, 0x47, 0x2b, 0x6d, + 0xdc, 0x9a, 0x37, 0xb1, 0xd6, 0xa8, 0x9b, 0xbb, 0x3b, 0x1b, 0x1d, 0x94, 0x13, 0x95, 0x51, 0x9f, + 0xb5, 0x25, 0xc9, 0x59, 0x5b, 0xd0, 0x8f, 0xfb, 0x07, 0xf7, 0x25, 0x9e, 0xbd, 0x67, 0x82, 0xac, + 0x7c, 0x3e, 0x1a, 0x06, 0x98, 0xfc, 0x45, 0xb2, 0x3a, 0x77, 0x99, 0x5c, 0x52, 0x51, 0x4c, 0x2e, + 0xbf, 0xe1, 0x22, 0x7b, 0x8e, 0x43, 0xf6, 0x95, 0xd1, 0xdb, 0x35, 0x92, 0xcd, 0x83, 0xe9, 0x2a, + 0xb6, 0x02, 0xe0, 0xbd, 0x11, 0xa6, 0x36, 0xbc, 0x37, 0x2e, 0xc4, 0x7c, 0x62, 0x8f, 0x2d, 0xbe, + 0xb7, 0x47, 0x5d, 0x9a, 0xf1, 0x24, 0x04, 0xa0, 0xeb, 0x22, 0x98, 0x14, 0xd9, 0x37, 0x88, 0xb4, + 0xce, 0x0a, 0xad, 0x3f, 0x7e, 0x14, 0xde, 0x26, 0xc1, 0x74, 0x69, 0xa7, 0x6d, 0x98, 0xd6, 0x8a, + 0x66, 0x5e, 0x24, 0x27, 0xa2, 0x17, 0x45, 0x3b, 0xd9, 0x09, 0x00, 0x9d, 0x7c, 0xea, 0xf3, 0xa0, + 0xf6, 0xa5, 0xa0, 0x67, 0xa3, 0x62, 0xc1, 0x13, 0x12, 0xec, 0x17, 0x62, 0x1a, 0x86, 0xb5, 0xac, + 0xb7, 0x2e, 0x7a, 0x3b, 0xe7, 0xfe, 0xa4, 0x88, 0xbb, 0x3c, 0x91, 0xd0, 0x0a, 0xa5, 0x30, 0x7e, + 0xb4, 0x3e, 0x98, 0x84, 0x89, 0xea, 0xb6, 0x66, 0xe2, 0xf9, 0x2b, 0x76, 0x63, 0x45, 0xfd, 0x48, + 0x5e, 0xed, 0x07, 0x42, 0x81, 0x54, 0x53, 0x6f, 0x5d, 0x74, 0xb6, 0xe7, 0xec, 0xff, 0x5e, 0x58, + 0x80, 0x64, 0x8f, 0xb0, 0x00, 0xae, 0x89, 0xd6, 0xad, 0x37, 0x60, 0xee, 0xf3, 0x16, 0xa1, 0xb0, + 0x00, 0x7d, 0x8b, 0x8b, 0x9f, 0x8d, 0x9f, 0x4e, 0xc2, 0xd1, 0x5c, 0xa3, 0x71, 0x41, 0xb7, 0xb6, + 0x2b, 0x0e, 0x8f, 0x1e, 0x14, 0xdb, 0x54, 0x9f, 0x81, 0x6c, 0x5b, 0xbb, 0xd2, 0x34, 0x34, 0x77, + 0x60, 0x61, 0x8f, 0xe8, 0xb1, 0x64, 0xc4, 0x81, 0xa5, 0x8b, 0x82, 0x00, 0xa6, 0x46, 0xd2, 0xe9, + 0xe1, 0x45, 0xc6, 0xcf, 0xd8, 0x3f, 0x4f, 0x41, 0xa6, 0x8a, 0x35, 0xb3, 0xbe, 0x8d, 0x5e, 0x9f, + 0xf4, 0x18, 0xba, 0x00, 0xd9, 0x4d, 0xbd, 0x69, 0x61, 0x93, 0x7a, 0x80, 0xf8, 0xe7, 0x31, 0x74, + 0x3c, 0x9b, 0x6f, 0x1a, 0xf5, 0x8b, 0x73, 0x79, 0x5b, 0xb3, 0xb4, 0xac, 0x39, 0xe7, 0xcc, 0xe5, + 0xdc, 0x02, 0xf9, 0x48, 0x75, 0x3e, 0x56, 0x1e, 0x82, 0x74, 0xc7, 0x30, 0x2d, 0x67, 0xad, 0x76, + 0x4a, 0xac, 0x94, 0xaa, 0x61, 0x5a, 0x2a, 0xfd, 0xd0, 0x86, 0x76, 0x73, 0xb7, 0xd9, 0xac, 0xe1, + 0xcb, 0x96, 0xb3, 0x4e, 0x72, 0x9e, 0x95, 0xe3, 0x90, 0x31, 0x36, 0x37, 0x3b, 0x98, 0x2e, 0xc5, + 0xd3, 0x2a, 0x7b, 0x52, 0x8e, 0x41, 0xba, 0xa9, 0xef, 0xe8, 0x16, 0x59, 0x71, 0xa7, 0x55, 0xfa, + 0xa0, 0x9c, 0x02, 0xd9, 0x70, 0x57, 0x49, 0x94, 0xd0, 0x99, 0x0c, 0xd1, 0x45, 0xfb, 0xd2, 0xed, + 0x2e, 0x77, 0x11, 0x5f, 0xe9, 0xcc, 0x64, 0xc9, 0x7b, 0xf2, 0x1f, 0x3d, 0x13, 0xd5, 0x4a, 0x4f, + 0xf9, 0x1a, 0xbc, 0x64, 0x34, 0x71, 0xdd, 0x30, 0x1b, 0x0e, 0x6f, 0x82, 0x97, 0x8c, 0x2c, 0x5f, + 0x34, 0xdb, 0x7a, 0xcf, 0xca, 0xe3, 0x97, 0xa7, 0x67, 0x32, 0x90, 0x5e, 0x34, 0xb5, 0xf6, 0x36, + 0xfa, 0xb5, 0xc4, 0xf0, 0xc5, 0xc9, 0x05, 0x36, 0xd9, 0x0f, 0x58, 0xa9, 0x0f, 0xb0, 0x29, 0x1f, + 0xb0, 0x4f, 0x25, 0x21, 0x55, 0x6c, 0x6c, 0x61, 0xce, 0xe8, 0x95, 0xf0, 0x19, 0xbd, 0x8e, 0x43, + 0xc6, 0xd2, 0xcc, 0x2d, 0x6c, 0x31, 0x2e, 0xb1, 0x27, 0xd7, 0xab, 0x52, 0xf2, 0x9d, 0xcd, 0x7d, + 0x25, 0xa4, 0xec, 0x76, 0x11, 0x89, 0x9c, 0x3e, 0x73, 0x43, 0x2f, 0x68, 0x08, 0x7f, 0xe6, 0xec, + 0x1a, 0xe7, 0x6c, 0xca, 0x54, 0xf2, 0x41, 0x37, 0x1e, 0xe9, 0x7d, 0x78, 0xd8, 0x63, 0xbb, 0x5e, + 0x37, 0x5a, 0xa5, 0x1d, 0x6d, 0x0b, 0xcf, 0x64, 0xe8, 0xd8, 0xee, 0x26, 0x38, 0x6f, 0x8b, 0x3b, + 0xc6, 0xa3, 0xfa, 0x4c, 0xd6, 0x7b, 0x4b, 0x12, 0xec, 0x26, 0x6c, 0xeb, 0x8d, 0x06, 0x6e, 0xcd, + 0x8c, 0xd1, 0x93, 0x6d, 0xf4, 0x69, 0xf6, 0x04, 0xa4, 0x6c, 0x1a, 0x6c, 0x8c, 0x6d, 0xc5, 0x2e, + 0x1f, 0x51, 0x26, 0x6d, 0x29, 0xa7, 0x56, 0x49, 0x39, 0x81, 0x3e, 0x9e, 0x8c, 0xb8, 0x87, 0x4c, + 0x1b, 0xd7, 0x5b, 0xe6, 0x6f, 0x87, 0x74, 0xcb, 0x68, 0xe0, 0xbe, 0x12, 0x4f, 0x73, 0x29, 0x2f, + 0x83, 0x34, 0x6e, 0x6c, 0xe1, 0x0e, 0x01, 0x73, 0xe2, 0xcc, 0x89, 0x70, 0x5e, 0xaa, 0x34, 0x73, + 0xb4, 0x8d, 0xea, 0x5e, 0xd4, 0xc6, 0xdf, 0x49, 0xfe, 0x4f, 0x06, 0x8e, 0xd2, 0xfe, 0x59, 0xdd, + 0xdd, 0xb0, 0x8b, 0xda, 0xc0, 0xe8, 0x67, 0x25, 0x2e, 0x18, 0x40, 0x67, 0x77, 0xc3, 0x1d, 0xcb, + 0xe8, 0x83, 0xbf, 0x13, 0x25, 0x87, 0xa2, 0x93, 0xa5, 0x41, 0x75, 0x32, 0xa7, 0x5f, 0x25, 0xa7, + 0x1b, 0x7a, 0xda, 0x38, 0x43, 0x92, 0x1d, 0x6d, 0xdc, 0x43, 0x97, 0xda, 0x83, 0xb2, 0xb6, 0x69, + 0x61, 0xb3, 0xd4, 0x20, 0xf2, 0x38, 0xae, 0x3a, 0x8f, 0xb6, 0xbe, 0xdf, 0xc0, 0x9b, 0x86, 0x69, + 0x2f, 0x04, 0xc7, 0xa9, 0xbe, 0x77, 0x9e, 0x7d, 0xfd, 0x13, 0x38, 0xa3, 0xf4, 0x2d, 0x70, 0x54, + 0xdf, 0x6a, 0x19, 0x26, 0x76, 0x3d, 0x7b, 0x66, 0x26, 0xe9, 0x29, 0xf6, 0xae, 0x64, 0xe5, 0x36, + 0xb8, 0xaa, 0x65, 0x14, 0x70, 0x9b, 0xf1, 0x9d, 0xa2, 0x3a, 0x45, 0x7a, 0xc4, 0xfe, 0x17, 0xe8, + 0x63, 0x51, 0x57, 0x9e, 0x5d, 0xa0, 0x0e, 0x4d, 0xf5, 0x2b, 0xf7, 0xc2, 0x64, 0x83, 0x79, 0x0d, + 0xd4, 0x75, 0xb7, 0x47, 0x04, 0x7e, 0xc7, 0x65, 0xf6, 0xc4, 0x29, 0xe5, 0x17, 0xa7, 0x45, 0x18, + 0x23, 0xc7, 0x54, 0x6c, 0x79, 0x4a, 0x77, 0x1d, 0x84, 0x26, 0xd3, 0x6d, 0xb7, 0x51, 0x3e, 0x96, + 0xcc, 0xe5, 0xd9, 0x27, 0xaa, 0xfb, 0x71, 0xb4, 0xf9, 0x4e, 0x38, 0x87, 0xe2, 0xef, 0x7a, 0x3f, + 0x9f, 0x82, 0xa3, 0x8b, 0xa6, 0xb1, 0xdb, 0xee, 0x78, 0x5d, 0xcf, 0x1f, 0x6e, 0xa1, 0x77, 0xd7, + 0xb3, 0x57, 0x30, 0x4c, 0x27, 0x9e, 0xc3, 0x4e, 0xb4, 0x17, 0x7f, 0x92, 0xbf, 0x73, 0x4a, 0x07, + 0xe9, 0x9c, 0x9e, 0x88, 0xa7, 0xfc, 0x22, 0x8e, 0x3e, 0x17, 0x75, 0xae, 0xda, 0xd5, 0xc8, 0x00, + 0x51, 0xcc, 0x43, 0x66, 0x8b, 0x64, 0x64, 0x92, 0x78, 0xab, 0x18, 0xd5, 0xa4, 0x70, 0x95, 0x7d, + 0xea, 0xf1, 0x4c, 0xf2, 0xf1, 0x2c, 0x9a, 0x58, 0x84, 0x53, 0x3b, 0x02, 0xd3, 0x46, 0x0a, 0x26, + 0xdd, 0xda, 0x4b, 0x8d, 0x0e, 0x32, 0xfa, 0x89, 0xc4, 0x3e, 0x43, 0x86, 0xab, 0xe7, 0x24, 0x9f, + 0x9e, 0xeb, 0xa1, 0x99, 0x26, 0x7a, 0x6a, 0x26, 0xf4, 0x98, 0x24, 0x1a, 0xea, 0x85, 0xef, 0x96, + 0x84, 0xdc, 0x17, 0xb2, 0xa2, 0x11, 0x0c, 0x38, 0xd3, 0xbf, 0x55, 0xf1, 0x4b, 0xc1, 0xfb, 0x93, + 0x70, 0x15, 0x55, 0x50, 0x6b, 0xad, 0x8e, 0xab, 0x1e, 0xf8, 0xf8, 0x00, 0xa4, 0x4d, 0x1d, 0x77, + 0x57, 0x94, 0x3c, 0xf1, 0x16, 0xe0, 0xd0, 0x23, 0x07, 0x9c, 0x1a, 0xf4, 0xd5, 0x12, 0xb0, 0x96, + 0x14, 0x3b, 0x54, 0x20, 0x58, 0xe8, 0x08, 0xb4, 0xab, 0x04, 0xe3, 0x55, 0x6c, 0x2d, 0x6b, 0x57, + 0x8c, 0x5d, 0x0b, 0x69, 0xa2, 0x66, 0xa9, 0xbb, 0x21, 0xd3, 0x24, 0x9f, 0x10, 0x0d, 0x32, 0x7d, + 0xe6, 0xfa, 0x9e, 0xc6, 0x53, 0xb2, 0xb9, 0x45, 0x8b, 0x56, 0x59, 0x7e, 0xfe, 0xac, 0x87, 0x88, + 0xe9, 0xdd, 0xa5, 0x6e, 0x28, 0x76, 0xc3, 0x48, 0x86, 0xf9, 0xa0, 0xaa, 0xe3, 0x87, 0xe5, 0xc7, + 0x25, 0x98, 0x22, 0xae, 0xfa, 0x0b, 0xda, 0x9e, 0x61, 0xea, 0x16, 0x8e, 0x66, 0x31, 0x74, 0x3f, + 0x63, 0xe7, 0x11, 0x7c, 0x29, 0xe8, 0x6d, 0xc9, 0x88, 0x5b, 0x72, 0x1c, 0x1d, 0x43, 0x01, 0x21, + 0xd2, 0x06, 0x5e, 0x58, 0xf5, 0x23, 0x04, 0x22, 0x67, 0xd6, 0xb7, 0xf5, 0x3d, 0xdc, 0x88, 0x08, + 0x84, 0xf3, 0x99, 0x07, 0x84, 0x5b, 0xd0, 0x60, 0x40, 0x38, 0x9f, 0x1f, 0x12, 0x10, 0x01, 0xd5, + 0xc7, 0x0f, 0xc4, 0x5b, 0x29, 0x10, 0x3e, 0xdf, 0x84, 0x15, 0x51, 0x20, 0x6e, 0x84, 0x29, 0xcf, + 0xaa, 0xb0, 0x66, 0x36, 0xd9, 0xac, 0x87, 0x4f, 0x44, 0x1f, 0x1e, 0x00, 0x8e, 0xbe, 0x6e, 0x06, + 0xd1, 0xe0, 0xf8, 0x50, 0x44, 0x38, 0x5e, 0xa8, 0x2e, 0x04, 0xcf, 0x4a, 0xf4, 0x44, 0x15, 0xe7, + 0xc9, 0xf1, 0xa8, 0x28, 0x5c, 0xfb, 0xbc, 0x46, 0xb2, 0x91, 0xbd, 0x46, 0x3e, 0x1a, 0xd5, 0x6b, + 0xa4, 0x9b, 0xda, 0xa1, 0xc0, 0x19, 0xc9, 0x29, 0xa4, 0x0f, 0x05, 0x87, 0x8c, 0xe8, 0x57, 0x25, + 0x00, 0x12, 0x67, 0x98, 0xfa, 0x3b, 0x2d, 0x41, 0x86, 0xfe, 0x75, 0x9c, 0x26, 0x13, 0x9e, 0xd3, + 0xe4, 0x6d, 0x90, 0xde, 0xd3, 0x9a, 0xbb, 0xd8, 0xe5, 0x51, 0xf7, 0x44, 0xf4, 0xbc, 0xfd, 0x56, + 0xa5, 0x99, 0xd0, 0xb6, 0xa8, 0x54, 0x3c, 0xe8, 0x77, 0xd8, 0xb1, 0xe5, 0xe1, 0xa6, 0x00, 0x2e, + 0x32, 0x1a, 0xe7, 0xe8, 0xaf, 0xe7, 0xa3, 0xf5, 0xe6, 0xa8, 0x0e, 0x14, 0xbe, 0xb2, 0x86, 0x21, + 0x0d, 0x91, 0x5c, 0x2a, 0x02, 0xeb, 0x8e, 0x5f, 0xd1, 0x7e, 0x34, 0x09, 0xe9, 0x9a, 0x51, 0xc5, + 0xdc, 0x79, 0xb3, 0x70, 0x6c, 0xbc, 0x25, 0x70, 0x92, 0x5b, 0x02, 0xff, 0x68, 0x54, 0x53, 0x24, + 0xa9, 0x37, 0x38, 0x98, 0x68, 0x07, 0x7b, 0x5b, 0xff, 0xf4, 0x21, 0x9a, 0xed, 0xb0, 0x57, 0xf1, + 0xf1, 0x33, 0xf4, 0x2c, 0x1c, 0x5d, 0x6b, 0x35, 0x0c, 0x15, 0x37, 0x0c, 0x66, 0x8b, 0xb1, 0x17, + 0x9e, 0xbb, 0xad, 0x86, 0x41, 0x68, 0x4d, 0xab, 0xe4, 0xbf, 0x9d, 0x66, 0xe2, 0x86, 0xc1, 0x0c, + 0xe5, 0xe4, 0x3f, 0x7a, 0x83, 0x04, 0x29, 0xfb, 0x5b, 0x71, 0xcf, 0x96, 0xaf, 0x45, 0x3d, 0x98, + 0x62, 0x17, 0x3f, 0x0c, 0xf9, 0x56, 0x1e, 0xf4, 0x59, 0xa7, 0xe8, 0xa6, 0xf0, 0x0d, 0x41, 0xf5, + 0xf9, 0x58, 0xe1, 0xb3, 0x4a, 0xbd, 0x33, 0xca, 0x61, 0x96, 0x1e, 0x64, 0x47, 0x43, 0xb2, 0x30, + 0x80, 0x8a, 0x94, 0x61, 0x32, 0x9f, 0x2b, 0x93, 0xc8, 0x2c, 0x2b, 0x95, 0xf3, 0x45, 0x59, 0x22, + 0x00, 0xd9, 0xad, 0x89, 0x11, 0x20, 0xbb, 0xf8, 0xef, 0x40, 0x80, 0x7a, 0x90, 0x7d, 0x18, 0x00, + 0x7d, 0x24, 0x09, 0x53, 0xcb, 0x7a, 0xc7, 0x0a, 0x72, 0x12, 0x0b, 0x39, 0x37, 0xff, 0x9a, 0xa8, + 0x13, 0x42, 0xae, 0x1e, 0xe1, 0x03, 0xf3, 0x91, 0xe6, 0xe0, 0x61, 0x55, 0x8c, 0xc6, 0x9b, 0x91, + 0x50, 0x40, 0xc3, 0x30, 0x0a, 0x73, 0x32, 0xf2, 0xd0, 0xeb, 0x55, 0x32, 0xfa, 0xa1, 0x37, 0xb0, + 0xee, 0xf8, 0xf9, 0xfb, 0xe5, 0x24, 0x5c, 0x65, 0x57, 0x1f, 0xb6, 0xe0, 0x0c, 0x66, 0x73, 0xdf, + 0x05, 0x67, 0x64, 0x9b, 0xd7, 0x3e, 0x5a, 0x86, 0x61, 0xf3, 0xea, 0x57, 0xe8, 0x88, 0xd9, 0x1c, + 0x60, 0x60, 0xe9, 0xc7, 0xe6, 0x10, 0x03, 0xcb, 0xe0, 0x6c, 0x0e, 0x37, 0xb2, 0x0c, 0xc8, 0xe6, + 0x43, 0x33, 0x9d, 0x7c, 0x36, 0x09, 0x53, 0xb9, 0x76, 0xbb, 0x79, 0xa5, 0xc6, 0x4e, 0x8e, 0x44, + 0x32, 0x9d, 0xf8, 0x0e, 0xa0, 0x24, 0xf7, 0x1d, 0xbf, 0x8c, 0xec, 0x56, 0xce, 0xd1, 0x31, 0x0c, + 0xb7, 0xf2, 0xb0, 0x02, 0xe3, 0x67, 0xed, 0xab, 0xd3, 0x54, 0x11, 0xb3, 0xc0, 0x10, 0x9f, 0x4e, + 0x84, 0x47, 0x86, 0x08, 0x0d, 0x83, 0xa3, 0xdc, 0x0f, 0x99, 0x4d, 0xc3, 0xdc, 0xd1, 0x1c, 0x5b, + 0xee, 0x4d, 0x41, 0xe2, 0xc4, 0x62, 0x2f, 0x2c, 0x90, 0xcc, 0x2a, 0xfb, 0xc8, 0x1e, 0xd1, 0x5e, + 0xa5, 0xb7, 0xd9, 0xd9, 0x69, 0xfb, 0x2f, 0x09, 0x8a, 0x42, 0x8f, 0x50, 0x97, 0x71, 0xc7, 0xc2, + 0x0d, 0xb2, 0x59, 0x39, 0xa6, 0xf2, 0x89, 0xca, 0x2c, 0x4c, 0xb2, 0x84, 0x05, 0xbd, 0x89, 0x3b, + 0x64, 0x0b, 0x7a, 0x4c, 0xe5, 0xd2, 0xd0, 0x27, 0x06, 0x19, 0x38, 0x22, 0x47, 0xac, 0x98, 0x81, + 0x6c, 0x67, 0xb7, 0x5e, 0xc7, 0xb8, 0xc1, 0xbc, 0x92, 0x9c, 0xc7, 0x88, 0x5e, 0x8e, 0x91, 0x87, + 0x99, 0xc3, 0x09, 0x66, 0x31, 0xbb, 0x0a, 0x19, 0x8a, 0xa1, 0x32, 0x09, 0x63, 0x8e, 0x9f, 0x25, + 0xf5, 0x23, 0x59, 0x65, 0x8b, 0x74, 0x39, 0x61, 0x97, 0xf8, 0x70, 0xb5, 0x52, 0xa6, 0xc1, 0x01, + 0x0b, 0x15, 0x16, 0x1c, 0xb0, 0x7a, 0x7e, 0x51, 0x4e, 0x29, 0xd3, 0x00, 0x8b, 0x6a, 0x6e, 0x75, + 0x69, 0x9d, 0xe4, 0x48, 0xa3, 0x2f, 0x8f, 0x41, 0x86, 0xba, 0x6d, 0xa2, 0x4f, 0x64, 0xfc, 0x97, + 0x33, 0x4d, 0xb6, 0x0c, 0x9b, 0xcc, 0x55, 0xcd, 0xd4, 0x76, 0x3a, 0x61, 0x7b, 0x63, 0xf4, 0x6b, + 0xf7, 0x62, 0xa6, 0xb2, 0xef, 0xb3, 0xa5, 0x23, 0x2a, 0x57, 0x8c, 0xf2, 0x2f, 0xe1, 0xe8, 0x06, + 0x3b, 0x70, 0xd0, 0x61, 0x25, 0x27, 0x83, 0xb7, 0x55, 0xbb, 0x4a, 0x9e, 0xe7, 0xbf, 0x5c, 0x3a, + 0xa2, 0x76, 0x17, 0xa6, 0x7c, 0x3f, 0x4c, 0xef, 0x30, 0xae, 0xb0, 0xe2, 0xa5, 0x7e, 0xfe, 0xb4, + 0x6e, 0xf1, 0x2b, 0xdc, 0x87, 0x4b, 0x47, 0xd4, 0xae, 0xa2, 0x94, 0x12, 0x8c, 0x77, 0x5a, 0x5a, + 0xbb, 0xb3, 0x6d, 0x58, 0xce, 0xb9, 0xb9, 0x5b, 0x05, 0xca, 0xad, 0xb2, 0x6f, 0x54, 0xef, 0x6b, + 0xe5, 0x65, 0xf0, 0xe2, 0x5d, 0x12, 0xaa, 0xb2, 0x78, 0x59, 0xef, 0x58, 0x7a, 0x6b, 0xcb, 0x89, + 0x63, 0x40, 0xfb, 0x5b, 0xef, 0x97, 0xca, 0xbd, 0xcc, 0xdd, 0x29, 0x43, 0x64, 0xf3, 0x66, 0x81, + 0xba, 0x7d, 0x2e, 0x4f, 0xf7, 0x42, 0x6a, 0xc7, 0x16, 0xec, 0xac, 0xf0, 0xc7, 0x2b, 0x44, 0x9a, + 0xed, 0x8f, 0xd0, 0x49, 0x98, 0xf4, 0xe3, 0xaa, 0x1c, 0x87, 0x8c, 0xd6, 0xd6, 0xcf, 0xb9, 0xe6, + 0x23, 0xf6, 0x84, 0x6e, 0x84, 0x69, 0x9e, 0x8d, 0xbd, 0x94, 0x1a, 0xba, 0x01, 0x8e, 0x76, 0x61, + 0xe9, 0x9c, 0x9a, 0x49, 0x78, 0xa7, 0x66, 0x7e, 0x00, 0xc6, 0x1c, 0xce, 0xed, 0x0b, 0x4d, 0x9d, + 0x83, 0x31, 0x87, 0x97, 0x4c, 0x7e, 0x6e, 0xea, 0x32, 0x31, 0x56, 0x77, 0x34, 0xd3, 0x22, 0x1b, + 0xea, 0x4e, 0x21, 0xf3, 0x5a, 0x07, 0xab, 0xee, 0x67, 0xb3, 0xb7, 0x43, 0xca, 0x6e, 0x9f, 0xa2, + 0xc0, 0x74, 0x6e, 0x79, 0x79, 0xbd, 0x42, 0xc2, 0xa2, 0x2f, 0x95, 0xca, 0x8b, 0xb4, 0x1f, 0x96, + 0x16, 0xcb, 0x15, 0xb5, 0x48, 0xbb, 0x61, 0x55, 0x4e, 0xcc, 0xce, 0x31, 0xd7, 0x2d, 0x80, 0x0c, + 0x65, 0x04, 0xed, 0x74, 0x6e, 0x17, 0x4c, 0xd8, 0x4f, 0xc5, 0xcb, 0xd4, 0x0a, 0x28, 0x27, 0xe7, + 0xc7, 0x20, 0xd3, 0x26, 0x2d, 0xe3, 0x2d, 0x29, 0x22, 0x9e, 0x8c, 0x2e, 0x0a, 0xbd, 0x46, 0xba, + 0x77, 0x47, 0x71, 0x4b, 0xec, 0x59, 0x52, 0x34, 0x25, 0xb5, 0xb0, 0x4f, 0x49, 0x29, 0x30, 0x5d, + 0x2a, 0xd7, 0x8a, 0x6a, 0x39, 0xb7, 0xec, 0x6a, 0xa9, 0x7d, 0x8a, 0x2b, 0xc9, 0x2b, 0x2e, 0x09, + 0x7d, 0x4d, 0x02, 0xa0, 0xe4, 0xd8, 0xda, 0xd3, 0x1f, 0x5f, 0xf2, 0xd3, 0x51, 0x07, 0x0a, 0xaf, + 0x98, 0x80, 0x81, 0xa2, 0x04, 0x63, 0x26, 0x7b, 0xc1, 0x0c, 0x8e, 0xfd, 0xca, 0xa1, 0x7f, 0x9d, + 0xd2, 0x54, 0xf7, 0x73, 0xf4, 0xde, 0x28, 0xe3, 0x42, 0x20, 0x61, 0x87, 0xc3, 0xf2, 0x57, 0x39, + 0x47, 0x17, 0x7c, 0xd3, 0x2d, 0xaa, 0x3f, 0xc4, 0xda, 0xc0, 0x7f, 0xec, 0x53, 0x25, 0xb3, 0xd7, + 0xf7, 0xeb, 0x0c, 0xe8, 0x83, 0x47, 0x61, 0x9a, 0x96, 0xe8, 0xc6, 0x14, 0xf8, 0x47, 0x16, 0xdc, + 0xf1, 0x9c, 0xe8, 0x4c, 0x72, 0x16, 0x26, 0x7d, 0x4e, 0x3f, 0x6e, 0x9c, 0x50, 0x7f, 0x1a, 0x7f, + 0xc9, 0x54, 0xe8, 0xed, 0x7d, 0x3c, 0x35, 0x21, 0x01, 0x20, 0xa3, 0xad, 0x4f, 0xa3, 0x38, 0xf5, + 0x87, 0x54, 0x1e, 0xff, 0xbc, 0xf3, 0x71, 0xef, 0x0e, 0x86, 0xa1, 0x22, 0x10, 0xf5, 0x44, 0x91, + 0xcb, 0x04, 0x31, 0x23, 0xc1, 0xd0, 0xcf, 0xa8, 0x84, 0xd7, 0x1f, 0x3f, 0x0e, 0xdf, 0x66, 0x56, + 0xad, 0xdc, 0x9e, 0xa6, 0x37, 0xb5, 0x8d, 0x66, 0x84, 0xa3, 0x8f, 0x1f, 0xf4, 0xb3, 0xba, 0xcc, + 0xb3, 0xfa, 0xee, 0xb0, 0xa6, 0x72, 0xf5, 0x05, 0x5e, 0x93, 0x31, 0xee, 0xe0, 0xea, 0x39, 0x30, + 0xf1, 0x63, 0xaa, 0x53, 0x9e, 0xea, 0xe5, 0x44, 0xbf, 0xed, 0xb2, 0xfe, 0x7b, 0x38, 0xd6, 0xdf, + 0x3f, 0x28, 0x3d, 0xf1, 0x23, 0xf0, 0xd3, 0x12, 0x4c, 0xe4, 0x1a, 0x8d, 0x05, 0xac, 0x59, 0xbb, + 0x26, 0x6e, 0xa0, 0xa2, 0x68, 0x77, 0xb8, 0xb6, 0x9b, 0x45, 0xe3, 0x7e, 0x4e, 0xbc, 0x47, 0x38, + 0x52, 0xe4, 0x7e, 0x6d, 0xe0, 0xd0, 0x32, 0x14, 0x95, 0x24, 0x16, 0x57, 0x52, 0x98, 0x88, 0xf8, + 0x01, 0x79, 0x9d, 0x04, 0xd3, 0x34, 0x80, 0xe8, 0xb0, 0x31, 0xf9, 0x03, 0x3f, 0x26, 0x15, 0x1e, + 0x93, 0xb3, 0x61, 0xec, 0xe0, 0xc9, 0x19, 0x0a, 0x2c, 0x9e, 0x09, 0x5e, 0xe5, 0x60, 0x79, 0x60, + 0x60, 0x3a, 0xe2, 0x47, 0xe6, 0xeb, 0x00, 0xe0, 0x73, 0xdb, 0xf8, 0x02, 0x78, 0xc7, 0x15, 0xd0, + 0x47, 0x25, 0x3a, 0x9e, 0x57, 0xb9, 0x53, 0xa9, 0xbc, 0xb7, 0x46, 0xa2, 0x87, 0xb7, 0x86, 0xd0, + 0xa8, 0xf2, 0xcd, 0x88, 0x5e, 0x00, 0xcc, 0x91, 0xa2, 0xef, 0xe0, 0x3e, 0xa0, 0x96, 0x7b, 0x2e, + 0x82, 0x3b, 0x40, 0x3f, 0x52, 0xe2, 0xbf, 0x15, 0x28, 0xcc, 0x1d, 0x40, 0x99, 0x81, 0x63, 0x6a, + 0x31, 0x57, 0xa8, 0x94, 0x97, 0x1f, 0xf1, 0xbf, 0x95, 0x53, 0xe8, 0x57, 0x24, 0xc8, 0xb0, 0x00, + 0xc5, 0xb1, 0x60, 0xfa, 0x1f, 0x23, 0x2a, 0x48, 0x9e, 0x91, 0x61, 0xb1, 0x8c, 0xd1, 0x7f, 0x8e, + 0xa0, 0xf2, 0x04, 0x8a, 0x7d, 0xc1, 0x42, 0xf4, 0x79, 0x09, 0x52, 0x64, 0xfd, 0xb4, 0x1b, 0x15, + 0xa0, 0x02, 0x5c, 0xa7, 0xb5, 0xdb, 0xb8, 0xd5, 0x70, 0x43, 0x23, 0x2e, 0x98, 0xc6, 0x4e, 0xc5, + 0xda, 0xc6, 0xa6, 0x9d, 0xa5, 0xc3, 0x8c, 0xe1, 0xe1, 0x99, 0xd0, 0xe7, 0x23, 0xda, 0xc7, 0x79, + 0x5e, 0x87, 0x2c, 0xd9, 0xce, 0xee, 0xef, 0x97, 0xd7, 0x04, 0xf4, 0xcb, 0x65, 0xbd, 0x75, 0xd1, + 0xdf, 0x37, 0xff, 0x34, 0x82, 0x69, 0xbd, 0x2f, 0x3d, 0x87, 0xec, 0xab, 0xf3, 0x58, 0xc6, 0xa7, + 0x60, 0x7f, 0x42, 0x02, 0xd9, 0x8b, 0xad, 0xcd, 0xe2, 0x7b, 0x55, 0xf8, 0xad, 0x0e, 0x92, 0xe8, + 0xdf, 0xea, 0x70, 0x12, 0x94, 0x93, 0x30, 0x5d, 0xdf, 0xc6, 0xf5, 0x8b, 0xa5, 0x96, 0x63, 0x5a, + 0xa2, 0x08, 0x77, 0xa5, 0xf2, 0x4e, 0xbd, 0xe7, 0x78, 0x48, 0x79, 0xf3, 0x39, 0xc7, 0x37, 0x3f, + 0x51, 0x01, 0x9d, 0xd2, 0x03, 0xa6, 0xcc, 0x01, 0x73, 0xcf, 0x40, 0xa5, 0x46, 0x43, 0xa6, 0x3c, + 0xd8, 0x1d, 0x2e, 0x95, 0x55, 0x72, 0xe9, 0xe1, 0x5a, 0xb5, 0x58, 0x58, 0x9f, 0x77, 0x3a, 0x5f, + 0x55, 0x96, 0xd0, 0x57, 0x93, 0x90, 0xa5, 0x64, 0x75, 0xba, 0x62, 0x5f, 0xfb, 0x8f, 0xaa, 0x24, + 0xf6, 0x1d, 0x55, 0x41, 0xef, 0x10, 0xf6, 0x99, 0x76, 0x19, 0xc1, 0xea, 0x09, 0xe8, 0x29, 0x77, + 0x43, 0x96, 0x82, 0xec, 0x58, 0x4e, 0x4f, 0x04, 0xf4, 0x13, 0x56, 0x8c, 0xea, 0x64, 0x17, 0xf4, + 0x9f, 0xee, 0x43, 0x46, 0xfc, 0x73, 0x8e, 0xb7, 0x4c, 0x40, 0x76, 0x49, 0xef, 0x58, 0x86, 0x79, + 0x05, 0xbd, 0x39, 0x01, 0xd9, 0xf3, 0xd8, 0xec, 0xe8, 0x46, 0x6b, 0x9f, 0x0d, 0xf0, 0x7a, 0x98, + 0x68, 0x9b, 0x78, 0x4f, 0x37, 0x76, 0x3b, 0xbe, 0x40, 0x07, 0xbe, 0x24, 0x05, 0xc1, 0x98, 0xb6, + 0x6b, 0x6d, 0x1b, 0xa6, 0x17, 0xf5, 0xc9, 0x79, 0x56, 0x4e, 0x00, 0xd0, 0xff, 0x65, 0x6d, 0x07, + 0xb3, 0x23, 0x14, 0xbe, 0x14, 0x45, 0x81, 0x94, 0xa5, 0xef, 0x60, 0x76, 0xe8, 0x8e, 0xfc, 0x57, + 0x66, 0x20, 0x4b, 0x0e, 0xe1, 0x94, 0x1a, 0xec, 0xd0, 0x9d, 0xf3, 0x88, 0x7e, 0x5d, 0x82, 0x89, + 0x45, 0x6c, 0x31, 0x52, 0x3b, 0x7e, 0x67, 0xfc, 0x3e, 0x21, 0xe8, 0x9b, 0x5a, 0xc7, 0xf9, 0xcc, + 0xdd, 0x2e, 0xe3, 0x13, 0xbd, 0x03, 0x80, 0x92, 0xef, 0x1c, 0x2e, 0x7a, 0x77, 0x52, 0xf4, 0x08, + 0x0b, 0x63, 0xe6, 0x9c, 0x8f, 0xc0, 0x40, 0xd9, 0x1a, 0xdb, 0x63, 0x39, 0x98, 0x12, 0xbe, 0xb6, + 0x67, 0x49, 0xac, 0x18, 0xd5, 0xcd, 0x2d, 0x78, 0xec, 0xa4, 0x3f, 0x25, 0xf1, 0x8b, 0xd7, 0xdf, + 0x4b, 0x30, 0x51, 0xdd, 0x36, 0x2e, 0x31, 0x02, 0xd0, 0x0f, 0x88, 0x41, 0x75, 0x2d, 0x8c, 0xef, + 0x75, 0xc1, 0xe4, 0x25, 0x04, 0x47, 0x2f, 0x46, 0x4f, 0x4a, 0x51, 0x61, 0xf2, 0x11, 0x37, 0xf4, + 0xa8, 0xc3, 0xca, 0x2b, 0x20, 0xcb, 0xa8, 0x66, 0x96, 0x95, 0x70, 0x80, 0x9d, 0xcc, 0xfe, 0x06, + 0xa6, 0xf8, 0x06, 0x46, 0x43, 0x3e, 0xb8, 0x71, 0x23, 0x88, 0xbe, 0x90, 0x24, 0x8e, 0xb0, 0x0e, + 0xf0, 0xf9, 0x21, 0x00, 0x8f, 0xbe, 0x95, 0x10, 0xb5, 0x3f, 0xba, 0x1c, 0x70, 0x29, 0x38, 0x50, + 0x98, 0x90, 0xbe, 0xc5, 0xc5, 0xcf, 0xcf, 0x1f, 0xb9, 0x0a, 0x52, 0x0b, 0x7a, 0x13, 0xdb, 0xeb, + 0xf7, 0x6c, 0x65, 0x73, 0x93, 0x84, 0xf9, 0x28, 0x06, 0xdf, 0x27, 0x7a, 0x0a, 0x64, 0x67, 0x1b, + 0xd9, 0xb0, 0x56, 0xf5, 0x56, 0xcb, 0xf5, 0x74, 0xd9, 0x97, 0xce, 0x9b, 0xba, 0x42, 0xdd, 0x4f, + 0x6d, 0x0a, 0xe6, 0x58, 0xed, 0x01, 0xfd, 0xe5, 0x24, 0x4c, 0x6f, 0x5c, 0xb1, 0x70, 0x87, 0xe5, + 0x62, 0xd5, 0xa6, 0xd4, 0xae, 0x54, 0xf4, 0xac, 0x90, 0x43, 0x6a, 0x48, 0x85, 0xd1, 0x78, 0xae, + 0x0d, 0x30, 0x47, 0x39, 0x06, 0x72, 0xb9, 0x52, 0x28, 0xd2, 0x8b, 0x37, 0x6b, 0x39, 0xb5, 0x56, + 0x2c, 0xc8, 0x5b, 0xe4, 0xb6, 0xc1, 0xd2, 0x32, 0x4d, 0x7d, 0xa4, 0x58, 0x5b, 0x5f, 0x2d, 0x95, + 0xcb, 0xc5, 0x82, 0xbc, 0x8d, 0xde, 0x27, 0xc1, 0x84, 0x3d, 0xaf, 0x72, 0xd0, 0xa9, 0x70, 0x97, + 0x35, 0x1a, 0xad, 0xe6, 0x15, 0x6f, 0xee, 0xe8, 0x3c, 0x46, 0xc2, 0xe9, 0x3f, 0x09, 0x4f, 0x6f, + 0x08, 0xdb, 0x7c, 0xb4, 0x04, 0x63, 0xb5, 0xa9, 0x37, 0xbb, 0xb1, 0x4a, 0xab, 0x5d, 0xa9, 0x3d, + 0x30, 0x95, 0x7a, 0x62, 0xfa, 0xfb, 0x42, 0x93, 0x9e, 0x3e, 0xc4, 0x45, 0xc3, 0x75, 0x69, 0x58, + 0xb8, 0xa2, 0x6f, 0x48, 0x90, 0x59, 0x6b, 0x13, 0xe4, 0x9e, 0xf3, 0xf9, 0x89, 0xec, 0xdb, 0x2b, + 0xb5, 0x95, 0x54, 0x93, 0xbf, 0x9d, 0x5e, 0xf5, 0x12, 0x94, 0x7b, 0xd8, 0xb6, 0x0f, 0xf5, 0x11, + 0x39, 0x19, 0x7a, 0xea, 0x98, 0x70, 0xc2, 0xb7, 0x6b, 0x7c, 0x1b, 0x5c, 0xd5, 0xd0, 0x3b, 0xda, + 0x46, 0x13, 0x17, 0x5b, 0x75, 0xf3, 0x0a, 0x6d, 0x34, 0x75, 0x18, 0xd9, 0xff, 0x42, 0xb9, 0x1f, + 0xd2, 0x1d, 0xeb, 0x4a, 0x93, 0x4e, 0x9b, 0xfc, 0x9b, 0xcc, 0x81, 0x55, 0x55, 0xed, 0xec, 0x2a, + 0xfd, 0x0a, 0x7d, 0x3b, 0x21, 0xea, 0x60, 0x4b, 0xbe, 0xa5, 0xac, 0x09, 0xf6, 0x16, 0xd9, 0xd6, + 0x3a, 0xae, 0xb7, 0x88, 0xfd, 0x1f, 0x3d, 0x2d, 0xe4, 0x05, 0x1b, 0x5c, 0x76, 0xfc, 0x3a, 0xf5, + 0x73, 0x49, 0x18, 0x2b, 0x18, 0x97, 0x5a, 0x04, 0xf3, 0x3b, 0x39, 0xd7, 0x20, 0xd2, 0x9a, 0x84, + 0xd7, 0x9a, 0x5e, 0xfe, 0x30, 0xe8, 0xdf, 0x09, 0x6f, 0x36, 0x93, 0x56, 0x3a, 0x55, 0x05, 0xdf, + 0xc1, 0x15, 0x2c, 0x56, 0x3e, 0xd3, 0x7f, 0xd8, 0x56, 0x74, 0x58, 0x3d, 0xd1, 0xf8, 0x99, 0x3b, + 0xf0, 0x1d, 0x06, 0xe8, 0x59, 0x09, 0x52, 0x05, 0xd3, 0x68, 0xa3, 0xdf, 0x4a, 0x44, 0xd8, 0x03, + 0x6b, 0x98, 0x46, 0xbb, 0x46, 0x82, 0xd0, 0xb8, 0x53, 0x00, 0x2e, 0x4d, 0x39, 0x0b, 0x63, 0x6d, + 0xa3, 0xa3, 0x5b, 0xce, 0xb4, 0x6a, 0x7a, 0xdf, 0x25, 0xe3, 0x54, 0xf2, 0x57, 0x59, 0x26, 0xd5, + 0xcd, 0x6e, 0xeb, 0x31, 0xc2, 0x51, 0x9b, 0x4d, 0x36, 0x57, 0x9d, 0x60, 0x39, 0x5d, 0xa9, 0xe8, + 0x17, 0xfc, 0xc0, 0xde, 0xcb, 0x03, 0x7b, 0x53, 0x0f, 0x86, 0x9b, 0x41, 0xb7, 0x16, 0x47, 0xb4, + 0x5a, 0xbf, 0xde, 0x05, 0xf9, 0x01, 0x0e, 0xe4, 0x53, 0x42, 0x75, 0xc6, 0xdf, 0x61, 0xbe, 0x96, + 0x05, 0x28, 0x6b, 0x7b, 0xfa, 0x16, 0xb5, 0x99, 0x7c, 0xc6, 0x19, 0xf0, 0x98, 0x75, 0xe3, 0xa7, + 0x7d, 0x38, 0x9f, 0x85, 0x2c, 0x83, 0x95, 0xb5, 0xe1, 0xa5, 0x5c, 0x1b, 0xbc, 0x52, 0xa8, 0x86, + 0xba, 0x6c, 0xa9, 0x4e, 0x7e, 0x2e, 0x2e, 0x56, 0xb2, 0x2b, 0x2e, 0x56, 0xcf, 0xe5, 0x59, 0x50, + 0xb4, 0x2c, 0xf4, 0x7b, 0xc2, 0xa1, 0x25, 0x7c, 0xf4, 0xf8, 0x5a, 0x14, 0x00, 0xea, 0x5d, 0x90, + 0x35, 0x5c, 0x33, 0x8f, 0x14, 0xb8, 0x1e, 0x28, 0xb5, 0x36, 0x0d, 0xd5, 0xc9, 0x29, 0x18, 0x34, + 0x42, 0x88, 0x8e, 0xf8, 0x81, 0xfe, 0x98, 0x04, 0xc7, 0x17, 0x9d, 0x73, 0x93, 0x76, 0x3b, 0x2e, + 0xe8, 0xd6, 0xf6, 0xb2, 0xde, 0xba, 0xd8, 0x41, 0xff, 0x4a, 0x6c, 0x26, 0xef, 0xc3, 0x3f, 0x19, + 0x0d, 0x7f, 0xde, 0x99, 0xb1, 0xca, 0xa3, 0x76, 0x7f, 0x50, 0x29, 0xbd, 0xa9, 0x0d, 0x00, 0xf0, + 0x1e, 0xc8, 0x50, 0x42, 0x59, 0xb7, 0x9c, 0x0d, 0xc4, 0xcf, 0x2d, 0x49, 0x65, 0x5f, 0xf8, 0x7c, + 0x82, 0xce, 0x73, 0x38, 0xce, 0x1f, 0x88, 0xb2, 0xf8, 0x9d, 0x19, 0xef, 0x84, 0x2c, 0xe3, 0xb4, + 0x32, 0xed, 0xef, 0xc5, 0xf2, 0x11, 0x05, 0x20, 0xb3, 0x62, 0xec, 0xe1, 0x9a, 0x21, 0x27, 0xec, + 0xff, 0x36, 0x7d, 0x35, 0x43, 0x4e, 0xa2, 0xff, 0x0a, 0x30, 0xe6, 0xfa, 0x24, 0x7f, 0x2a, 0xe9, + 0x84, 0x3d, 0x27, 0x66, 0x6a, 0xca, 0x0c, 0xe1, 0xdd, 0xf4, 0xd7, 0x09, 0x1b, 0x3e, 0x5d, 0x5f, + 0xe1, 0xee, 0xca, 0x04, 0x23, 0x0a, 0xbf, 0x5d, 0xc8, 0x10, 0x2a, 0x5a, 0x4b, 0xfc, 0x5d, 0xed, + 0x4b, 0x49, 0xe7, 0x72, 0x09, 0x8f, 0x08, 0xb2, 0xff, 0xc7, 0x5f, 0xb4, 0xef, 0x6d, 0x30, 0x30, + 0xe6, 0xfa, 0x52, 0xf8, 0xdb, 0x96, 0x43, 0x77, 0x5e, 0x03, 0xdb, 0x1d, 0x72, 0x36, 0xbb, 0x9b, + 0xc3, 0x62, 0x7b, 0xab, 0x51, 0x6a, 0x8a, 0x9f, 0xcb, 0xbf, 0x4b, 0xef, 0x1f, 0x6b, 0x45, 0x70, + 0x00, 0xe1, 0x62, 0x68, 0x3e, 0xc4, 0x33, 0xf5, 0x54, 0x40, 0x53, 0xed, 0x1a, 0x04, 0xb9, 0xf8, + 0x8c, 0xcb, 0xc5, 0x3c, 0xc7, 0xc5, 0xd3, 0xe2, 0x45, 0xc7, 0xcf, 0xb6, 0xaf, 0x26, 0x61, 0x9c, + 0x3a, 0x5f, 0xe7, 0x9a, 0xcd, 0xae, 0x5b, 0x97, 0xf7, 0x39, 0x9a, 0xfe, 0x07, 0x61, 0xf7, 0x30, + 0xb7, 0x55, 0x6e, 0xd9, 0xb1, 0xdd, 0x9b, 0x28, 0x66, 0xe0, 0xe9, 0x4b, 0xd0, 0x48, 0xe2, 0xc0, + 0x4e, 0xd8, 0x9a, 0x77, 0xd5, 0xc4, 0x7b, 0x3a, 0xbe, 0x84, 0xae, 0x09, 0x59, 0x82, 0xa2, 0xb7, + 0x0a, 0x1f, 0x8e, 0xf4, 0x15, 0x19, 0xc0, 0xe3, 0xfb, 0x60, 0xa2, 0xe9, 0x65, 0x62, 0x23, 0x22, + 0xea, 0x1a, 0x11, 0x7d, 0xc5, 0xa8, 0xfe, 0xec, 0x82, 0xab, 0xbc, 0x60, 0x2a, 0xe2, 0x67, 0xec, + 0x57, 0x32, 0x30, 0xb6, 0xd6, 0xea, 0xb4, 0x9b, 0xf6, 0xa2, 0xf4, 0x1f, 0x25, 0x37, 0x28, 0xec, + 0xcb, 0xb9, 0x38, 0x58, 0x3f, 0xb8, 0x8b, 0x4d, 0x67, 0x4f, 0x89, 0x3e, 0xf4, 0x0e, 0xc9, 0x89, + 0x7e, 0xdf, 0x6f, 0x63, 0xce, 0xf1, 0xac, 0xe7, 0x1d, 0xd4, 0x9d, 0x4a, 0xc3, 0xa3, 0xa5, 0x96, + 0x60, 0xac, 0xad, 0xd7, 0xad, 0x5d, 0xd3, 0x0d, 0x1e, 0x79, 0xbb, 0x58, 0x29, 0xab, 0xf4, 0x2b, + 0xd5, 0xfd, 0x1c, 0x69, 0x90, 0x65, 0x89, 0xfb, 0xcc, 0x81, 0xfb, 0xee, 0x49, 0x20, 0x4e, 0xe5, + 0xa6, 0xa5, 0x77, 0x9c, 0xd8, 0xb3, 0xec, 0xc9, 0x56, 0x8a, 0xf4, 0xdf, 0x9a, 0xd9, 0x64, 0xe6, + 0x67, 0x2f, 0x01, 0xbd, 0xcf, 0x85, 0xbb, 0xc0, 0xc1, 0x7d, 0x47, 0x84, 0x96, 0x47, 0x83, 0xfc, + 0xdc, 0x00, 0x0b, 0xd1, 0xab, 0xe1, 0x45, 0x6a, 0xae, 0x56, 0x5c, 0x5f, 0x2e, 0xad, 0x94, 0x6a, + 0xeb, 0xc5, 0xef, 0xcd, 0x17, 0x8b, 0x85, 0x62, 0x41, 0x6e, 0x90, 0x2b, 0x97, 0xdc, 0x15, 0x3f, + 0x3f, 0x12, 0x30, 0x2e, 0x7a, 0x23, 0x81, 0x9b, 0x80, 0x7e, 0x55, 0xd8, 0x69, 0xda, 0x6d, 0x78, + 0x9f, 0xb5, 0x7e, 0x2f, 0x7b, 0xc9, 0xfb, 0x85, 0xbc, 0x9f, 0xfb, 0xd5, 0x70, 0x88, 0xcc, 0x7d, + 0xd7, 0xf7, 0x41, 0x9a, 0x2c, 0xbd, 0xd1, 0xef, 0x90, 0x88, 0x9f, 0xed, 0xa6, 0x56, 0xc7, 0x68, + 0x27, 0xc2, 0x35, 0x09, 0x1b, 0xf6, 0xd7, 0xde, 0x35, 0x09, 0xec, 0x51, 0x39, 0x05, 0x69, 0xf2, + 0x97, 0x69, 0xfc, 0x63, 0xbd, 0x96, 0xfb, 0x2a, 0xcd, 0xc2, 0x3b, 0x06, 0x86, 0xda, 0x64, 0xa8, + 0x95, 0x80, 0x91, 0x19, 0x80, 0x53, 0x30, 0x4d, 0xd1, 0x46, 0x21, 0xb1, 0xf8, 0xc6, 0x61, 0x14, + 0xc5, 0xaf, 0x27, 0xff, 0x2a, 0x05, 0xe9, 0x6a, 0xbb, 0xa9, 0x5b, 0xe8, 0x97, 0x92, 0x43, 0xc1, + 0xcc, 0xd4, 0x5a, 0x5b, 0x38, 0x00, 0x33, 0xd5, 0x7e, 0xa7, 0xd2, 0x2c, 0x9e, 0x21, 0x33, 0x25, + 0x60, 0xc8, 0xac, 0xe1, 0xcb, 0x16, 0x67, 0xc8, 0x54, 0xce, 0xb2, 0xb3, 0x36, 0xe9, 0x1e, 0xa7, + 0xf2, 0xe8, 0xb7, 0xa4, 0x59, 0x3d, 0x4e, 0xda, 0xcc, 0xde, 0xc9, 0xce, 0xa5, 0x00, 0x64, 0xe6, + 0x2b, 0xb5, 0x5a, 0x65, 0x45, 0x3e, 0xa2, 0x64, 0x41, 0xaa, 0x55, 0x56, 0xe5, 0x84, 0x32, 0x0e, + 0xe9, 0x52, 0xb9, 0x5c, 0x54, 0xe5, 0xa4, 0xfd, 0xb7, 0x56, 0xaa, 0x2d, 0x17, 0x65, 0x09, 0xbd, + 0x4b, 0x78, 0xe8, 0xe5, 0xeb, 0x8e, 0x53, 0xbc, 0xc4, 0x06, 0xe1, 0x60, 0x7a, 0xe2, 0x17, 0xae, + 0x7f, 0x2b, 0x41, 0x7a, 0x05, 0x9b, 0x5b, 0x18, 0xfd, 0x60, 0x04, 0x5b, 0xe0, 0xa6, 0x6e, 0x76, + 0xe8, 0xb9, 0x22, 0xcf, 0x16, 0xe8, 0x4f, 0x53, 0x6e, 0x84, 0xa9, 0x0e, 0xae, 0x1b, 0xad, 0x86, + 0x93, 0x89, 0x45, 0xac, 0xe2, 0x12, 0xd1, 0x53, 0x11, 0x21, 0x23, 0x84, 0x0e, 0xc5, 0xa0, 0x17, + 0x05, 0x98, 0x5e, 0xb5, 0xc6, 0x0f, 0xcc, 0xff, 0x96, 0xec, 0x8f, 0xda, 0x57, 0xd0, 0x53, 0xc2, + 0x46, 0xda, 0xdb, 0x20, 0x43, 0xc4, 0xd4, 0x99, 0xaf, 0xf4, 0xd6, 0xc7, 0x2c, 0x8f, 0x32, 0x0f, + 0x57, 0x75, 0xc8, 0x8d, 0xf0, 0xb8, 0x61, 0x77, 0x5d, 0xb5, 0xaf, 0x52, 0xd8, 0x9f, 0x1d, 0xfd, + 0x85, 0x1f, 0xc0, 0xfb, 0x78, 0x00, 0x4f, 0xf6, 0x60, 0xa5, 0xdd, 0xa0, 0xe0, 0xbb, 0x71, 0xec, + 0x66, 0x54, 0x9b, 0x86, 0x6b, 0x5c, 0x74, 0x9e, 0xed, 0x77, 0xdb, 0xd6, 0x4e, 0x93, 0xbc, 0x63, + 0x2e, 0x2c, 0xce, 0xb3, 0x32, 0x07, 0x59, 0xad, 0x75, 0x85, 0xbc, 0x4a, 0x85, 0xb4, 0xda, 0xc9, + 0x84, 0xde, 0xe0, 0x22, 0xff, 0x20, 0x87, 0xfc, 0xad, 0x62, 0xe4, 0xc6, 0x0f, 0xfc, 0xdf, 0x65, + 0x20, 0xbd, 0xaa, 0x75, 0x2c, 0x8c, 0xbe, 0x20, 0x89, 0x22, 0x7f, 0x12, 0xa6, 0x37, 0x8d, 0xfa, + 0x6e, 0x07, 0x37, 0xf8, 0x4e, 0xd9, 0x95, 0x3a, 0x0c, 0xcc, 0x95, 0x53, 0x20, 0x3b, 0x89, 0xac, + 0x58, 0xc7, 0x5a, 0xbf, 0x2f, 0x9d, 0x1c, 0xa4, 0xee, 0xac, 0x6a, 0xa6, 0x55, 0xd9, 0x24, 0x69, + 0xee, 0x41, 0x6a, 0x7f, 0x22, 0x07, 0x7d, 0x26, 0x04, 0xfa, 0x6c, 0x30, 0xf4, 0x63, 0x02, 0xd0, + 0x2b, 0x39, 0x18, 0xdb, 0xd4, 0x9b, 0x98, 0x7c, 0x30, 0xde, 0x23, 0x04, 0x17, 0xdb, 0x9e, 0xb0, + 0x79, 0xef, 0x8e, 0x49, 0x0b, 0x7a, 0x13, 0xab, 0xee, 0x67, 0x68, 0x99, 0x6e, 0xf6, 0xbb, 0x61, + 0xf8, 0x13, 0xbe, 0x30, 0xfc, 0x0a, 0xa4, 0x1a, 0x9a, 0xa5, 0x11, 0xd6, 0x4f, 0xaa, 0xe4, 0x3f, + 0xbf, 0x77, 0x24, 0x75, 0xef, 0x1d, 0x3d, 0x21, 0x45, 0xd3, 0x7f, 0x0e, 0x69, 0x01, 0xfd, 0x67, + 0xc3, 0x81, 0x83, 0x7a, 0x81, 0xb9, 0xcf, 0x36, 0x0c, 0x75, 0xcd, 0xc4, 0xd6, 0xaa, 0x7f, 0x7b, + 0x26, 0xad, 0xf2, 0x89, 0x64, 0xc7, 0xbb, 0x53, 0xd5, 0x76, 0x30, 0xa9, 0x2c, 0x6f, 0xbf, 0x63, + 0x7b, 0x9c, 0xfb, 0xd2, 0x3d, 0x6d, 0x9b, 0x1e, 0xb6, 0xb6, 0xed, 0xd5, 0xc6, 0xf8, 0x3b, 0xdd, + 0x1b, 0x53, 0x20, 0xe5, 0x77, 0xad, 0x17, 0xb4, 0xb2, 0xfd, 0x27, 0xe1, 0xcd, 0x2f, 0xa6, 0xbd, + 0x76, 0xad, 0xc3, 0xd5, 0xb5, 0x11, 0xa5, 0x44, 0x6c, 0x93, 0x2d, 0xa8, 0x6d, 0x23, 0x39, 0xa0, + 0xe3, 0xf8, 0x21, 0x18, 0x07, 0x9f, 0x87, 0x23, 0xaa, 0x8c, 0x7c, 0x8a, 0xc1, 0x7d, 0x76, 0x8c, + 0x02, 0x29, 0xcf, 0xae, 0xf4, 0xcb, 0xc2, 0x9e, 0x40, 0x94, 0x3f, 0xa1, 0x4e, 0x01, 0xd1, 0xa6, + 0x4a, 0x62, 0x01, 0xea, 0x42, 0xaa, 0x8d, 0x1f, 0x99, 0x6f, 0xf8, 0xad, 0x07, 0xb9, 0x03, 0x63, + 0xc3, 0x9b, 0xed, 0x43, 0x2d, 0xcc, 0xb4, 0xd9, 0x7d, 0x8c, 0x0a, 0xd1, 0xf8, 0x2d, 0x66, 0x7f, + 0x0e, 0xad, 0x78, 0x04, 0x47, 0xa2, 0x24, 0xc8, 0xd0, 0xfd, 0x03, 0xf4, 0x1b, 0xc2, 0x2a, 0xd3, + 0x56, 0x3b, 0xbc, 0x03, 0x81, 0xfb, 0x1c, 0xc5, 0x94, 0xc0, 0x39, 0x1a, 0xa4, 0x22, 0x39, 0x1a, + 0xf0, 0xfe, 0xc2, 0x02, 0xfd, 0x88, 0xb6, 0x31, 0xe6, 0x55, 0x62, 0x94, 0x1e, 0xd6, 0x93, 0xa0, + 0xf8, 0xf1, 0x7e, 0x36, 0x05, 0x93, 0xb4, 0xea, 0x0b, 0x7a, 0x63, 0x0b, 0x5b, 0xe8, 0x1f, 0xbe, + 0x83, 0x50, 0x57, 0xca, 0x30, 0x79, 0x89, 0x90, 0x4d, 0x83, 0xa1, 0x33, 0x83, 0x44, 0xf8, 0x2d, + 0x34, 0xb4, 0x9d, 0x4e, 0xf0, 0x77, 0xee, 0x7b, 0xf4, 0x47, 0xc2, 0x1b, 0x2a, 0x7e, 0xd0, 0x58, + 0x89, 0xf1, 0xca, 0x92, 0xd8, 0xb6, 0x4a, 0x5f, 0xb2, 0x46, 0xe0, 0x81, 0xce, 0x87, 0xe2, 0xcb, + 0x47, 0x10, 0xa7, 0xa0, 0x79, 0x6e, 0x84, 0xd0, 0xfc, 0x94, 0x01, 0x43, 0x8e, 0xd2, 0x27, 0x76, + 0xb4, 0xa4, 0x4f, 0xd5, 0xf1, 0x73, 0xfe, 0x4d, 0xf4, 0xc6, 0x84, 0x05, 0x1d, 0x37, 0x1b, 0x1d, + 0x64, 0x1e, 0x7c, 0x2a, 0x73, 0x1a, 0x32, 0x9b, 0xa4, 0x30, 0x26, 0xa2, 0x81, 0x57, 0x77, 0xb0, + 0x6c, 0xe8, 0x8d, 0x49, 0xd1, 0xad, 0x1a, 0x66, 0x1a, 0x73, 0xa8, 0x1d, 0x0a, 0x4c, 0x6f, 0x12, + 0xda, 0x2a, 0x09, 0xaf, 0x39, 0x7e, 0x94, 0xde, 0x21, 0xc1, 0x24, 0x0b, 0x81, 0x97, 0x6b, 0xea, + 0x5b, 0x2d, 0xff, 0x61, 0xc7, 0x81, 0x7b, 0x88, 0x72, 0x07, 0xa4, 0x35, 0xbb, 0x34, 0xe6, 0xa0, + 0x87, 0x7a, 0xaa, 0x40, 0x52, 0x9f, 0x4a, 0x33, 0x46, 0x88, 0x2d, 0xe2, 0x09, 0xb6, 0x43, 0xf3, + 0x08, 0x63, 0x8b, 0xf4, 0xad, 0x3c, 0x7e, 0xc4, 0xbe, 0x28, 0xc1, 0x31, 0x46, 0xc0, 0x79, 0x6c, + 0x5a, 0x7a, 0x5d, 0x6b, 0x52, 0xe4, 0x5e, 0x9d, 0x18, 0x06, 0x74, 0x4b, 0x30, 0xb5, 0xe7, 0x2f, + 0x96, 0x41, 0x38, 0xdb, 0x13, 0x42, 0x8e, 0x00, 0x95, 0xff, 0x30, 0x42, 0x8c, 0x06, 0x8e, 0xab, + 0x5c, 0x99, 0x23, 0x8c, 0xd1, 0x20, 0x4c, 0x44, 0xfc, 0x10, 0xff, 0x42, 0x8a, 0x86, 0x2d, 0xf1, + 0xd4, 0xe7, 0x67, 0x84, 0xb1, 0x5d, 0x83, 0x09, 0x82, 0x25, 0xfd, 0x90, 0x59, 0x0d, 0x42, 0x84, + 0xd8, 0xd5, 0x3b, 0x2c, 0xec, 0x9b, 0xfb, 0xad, 0xea, 0x2f, 0x07, 0x5d, 0x00, 0xf0, 0x5e, 0xf9, + 0x95, 0x74, 0x22, 0x48, 0x49, 0x27, 0xc5, 0x94, 0xf4, 0x5b, 0x85, 0x8f, 0xd6, 0xf5, 0x26, 0xfb, + 0xe0, 0xe2, 0x21, 0x76, 0xa8, 0xaa, 0x7f, 0xed, 0xf1, 0xcb, 0xc5, 0x1b, 0x52, 0xdd, 0x41, 0x9a, + 0x3f, 0x38, 0x94, 0xf9, 0xb1, 0x5f, 0x1f, 0x48, 0x5d, 0xfa, 0xe0, 0x00, 0xf3, 0xe1, 0x5b, 0xe0, + 0x28, 0xad, 0x22, 0xef, 0x92, 0x45, 0xef, 0xfe, 0xec, 0x4e, 0x46, 0x1f, 0x1a, 0x40, 0x08, 0xfa, + 0x45, 0x90, 0x0e, 0x53, 0x72, 0xd1, 0x26, 0xbb, 0x51, 0x05, 0xe4, 0xf0, 0x02, 0x4f, 0x7f, 0x35, + 0x45, 0x67, 0xbb, 0x6b, 0x24, 0xa2, 0x21, 0xfa, 0xcb, 0xd4, 0x30, 0x46, 0x84, 0x87, 0x20, 0x65, + 0x39, 0x77, 0x14, 0xf7, 0x36, 0x4c, 0x78, 0x55, 0x7a, 0xb1, 0x10, 0xf1, 0x65, 0x6b, 0xe9, 0x88, + 0x4a, 0xbe, 0x54, 0x4e, 0xc1, 0xd1, 0x0d, 0xad, 0x7e, 0x71, 0xcb, 0x34, 0x76, 0x5b, 0x8d, 0xbc, + 0xd1, 0x34, 0x4c, 0x6a, 0x74, 0x22, 0x41, 0x25, 0xf9, 0x17, 0xca, 0x19, 0x67, 0xea, 0x90, 0xee, + 0x37, 0x75, 0x58, 0x3a, 0xc2, 0x26, 0x0f, 0xca, 0x9d, 0xae, 0xd2, 0xc9, 0x84, 0x2a, 0x9d, 0xa5, + 0x23, 0x8e, 0xda, 0x51, 0x0a, 0x30, 0xd6, 0xd0, 0xf7, 0xc8, 0x3e, 0x32, 0x0b, 0xd2, 0x18, 0x7e, + 0x54, 0xa7, 0xa0, 0xef, 0xd1, 0x5d, 0xe7, 0xa5, 0x23, 0xaa, 0xfb, 0xa5, 0xb2, 0x08, 0xe3, 0xc4, + 0x66, 0x4f, 0x8a, 0x19, 0x8b, 0x74, 0x0c, 0x67, 0xe9, 0x88, 0xea, 0x7d, 0x6b, 0xcf, 0x3e, 0x52, + 0xc4, 0xc1, 0xfd, 0x41, 0x67, 0x2f, 0x3c, 0x11, 0x69, 0x2f, 0xdc, 0xe6, 0x05, 0xdd, 0x0d, 0x3f, + 0x0e, 0xe9, 0x3a, 0xe1, 0x70, 0x92, 0x71, 0x98, 0x3e, 0x2a, 0xf7, 0x41, 0x6a, 0x47, 0x33, 0x9d, + 0x25, 0xf0, 0xc9, 0xfe, 0xe5, 0xae, 0x68, 0xe6, 0x45, 0x1b, 0x41, 0xfb, 0xab, 0xf9, 0x2c, 0xa4, + 0x09, 0xe3, 0xdc, 0x3f, 0xe8, 0x59, 0x36, 0x0d, 0xc9, 0x1b, 0x2d, 0x7b, 0xd8, 0xaf, 0x19, 0xce, + 0x29, 0x80, 0xfa, 0x30, 0x64, 0x8e, 0xf7, 0x78, 0x95, 0xf6, 0x79, 0xbc, 0xfe, 0xc5, 0x00, 0x73, + 0x8b, 0x6e, 0x4a, 0x83, 0x97, 0xc8, 0x4d, 0xee, 0x3e, 0x7f, 0xe7, 0x31, 0xa2, 0xd6, 0x88, 0x3a, + 0xeb, 0xe8, 0x43, 0x5e, 0xfc, 0xca, 0xe3, 0x6d, 0x29, 0x98, 0xb1, 0x09, 0xa1, 0xbe, 0xe0, 0x7c, + 0x38, 0x54, 0xf4, 0x67, 0x43, 0x99, 0x5c, 0xf6, 0x18, 0x11, 0xa4, 0x9e, 0x23, 0xc2, 0xbe, 0x93, + 0x40, 0xa9, 0x3e, 0x27, 0x81, 0xd2, 0xd1, 0x0c, 0x74, 0x7f, 0xe8, 0x97, 0x9f, 0x55, 0x5e, 0x7e, + 0xee, 0x09, 0x00, 0xa8, 0x17, 0x5f, 0x86, 0x32, 0x01, 0xf9, 0x1d, 0x57, 0x52, 0xaa, 0x9c, 0xa4, + 0x3c, 0x38, 0x38, 0x21, 0xf1, 0x4b, 0xcb, 0x1f, 0xa4, 0xe0, 0x45, 0x1e, 0x31, 0x65, 0x7c, 0x89, + 0x09, 0xca, 0xa7, 0x86, 0x22, 0x28, 0x77, 0x7a, 0xb7, 0x18, 0xf5, 0x59, 0xec, 0x3b, 0xf9, 0xe2, + 0x96, 0x98, 0x3f, 0x17, 0x3e, 0xc1, 0xd0, 0x0d, 0x94, 0xcb, 0x9b, 0x00, 0x61, 0x39, 0x0e, 0x19, + 0xaa, 0x61, 0x9c, 0x3b, 0xd8, 0xe9, 0x53, 0x44, 0x75, 0x23, 0x76, 0xee, 0x41, 0x94, 0xb6, 0x11, + 0xc8, 0x0f, 0x33, 0x3c, 0xd4, 0x76, 0xcd, 0x56, 0xa9, 0x65, 0x19, 0xe8, 0x47, 0x86, 0x22, 0x38, + 0xae, 0x2f, 0x99, 0x34, 0x88, 0x2f, 0xd9, 0x40, 0x66, 0x08, 0xa7, 0x05, 0x87, 0x62, 0x86, 0x08, + 0xa8, 0x3c, 0x7e, 0xfc, 0xde, 0x29, 0xc1, 0x71, 0xb6, 0x1a, 0x9a, 0xe7, 0xa7, 0x70, 0xe8, 0x91, + 0x61, 0x00, 0x79, 0xcc, 0x99, 0xc7, 0xb0, 0xab, 0x97, 0xc9, 0x03, 0x7f, 0xc6, 0x20, 0x34, 0x2a, + 0x27, 0xb7, 0x5e, 0xeb, 0xa2, 0x70, 0x28, 0x48, 0x89, 0x05, 0xe3, 0x8c, 0x40, 0x46, 0xfc, 0x98, + 0xfd, 0xac, 0x04, 0x19, 0x76, 0x15, 0xc2, 0x5a, 0x2c, 0x0e, 0x08, 0x7c, 0x04, 0x26, 0x81, 0x8d, + 0xaf, 0xc8, 0x77, 0x10, 0xc4, 0xb7, 0xe5, 0x75, 0x38, 0x97, 0x0c, 0xa0, 0xa7, 0x24, 0x66, 0x59, + 0x59, 0xd6, 0x2c, 0x7c, 0x19, 0xfd, 0xa4, 0x04, 0xd9, 0x2a, 0xb6, 0x6c, 0xcd, 0x24, 0x8e, 0x51, + 0xb0, 0xcd, 0x5c, 0xf1, 0xad, 0xdd, 0xc6, 0xe9, 0x6a, 0x2c, 0xaa, 0x8e, 0x23, 0x74, 0xcd, 0x31, + 0x9a, 0x46, 0xad, 0xe3, 0xc2, 0x2a, 0x1f, 0xc1, 0x79, 0xe7, 0x1b, 0x61, 0x9c, 0x90, 0x41, 0xe0, + 0xf8, 0xb0, 0x0f, 0x9a, 0x9f, 0x4f, 0xc4, 0x82, 0x8d, 0x3d, 0x7c, 0x91, 0x40, 0xfd, 0x64, 0xf6, + 0x32, 0x21, 0x32, 0x7c, 0xd9, 0xcb, 0xb4, 0x8e, 0x4a, 0xbf, 0x8a, 0x70, 0x81, 0x94, 0xdb, 0xac, + 0xa1, 0x22, 0x2b, 0x76, 0xb3, 0x47, 0xbf, 0xba, 0x47, 0x70, 0x2f, 0x8c, 0x04, 0x63, 0x55, 0x7b, + 0xb9, 0x61, 0x8f, 0x29, 0x17, 0x0e, 0x0e, 0x65, 0xef, 0xc1, 0x2a, 0x62, 0x47, 0x73, 0x38, 0x32, + 0xbc, 0x21, 0x2a, 0x42, 0x47, 0x0b, 0xab, 0x3c, 0x7e, 0x3c, 0xde, 0x45, 0xf1, 0x20, 0xb2, 0x8c, + 0xde, 0x22, 0x81, 0xb4, 0x88, 0xad, 0x21, 0x9d, 0x1c, 0x11, 0x3d, 0x85, 0xc0, 0x0f, 0x5d, 0xa1, + 0xc1, 0x02, 0x38, 0x86, 0x11, 0x9a, 0xe7, 0x16, 0xf1, 0x70, 0x3a, 0x90, 0x58, 0x94, 0x00, 0x21, + 0x02, 0xe2, 0x47, 0xed, 0x3d, 0x14, 0x35, 0x6a, 0xc1, 0xfa, 0xe1, 0x21, 0x68, 0xc4, 0xd1, 0x4e, + 0xde, 0x1d, 0x06, 0x92, 0x32, 0x0e, 0xab, 0xbf, 0xf5, 0xaa, 0x7c, 0x24, 0x3e, 0x86, 0x60, 0x77, + 0xf6, 0x6d, 0x5c, 0xbf, 0x88, 0x1b, 0xe8, 0xfb, 0x0f, 0x0e, 0xdd, 0x0c, 0x64, 0xeb, 0xb4, 0x34, + 0x02, 0xde, 0x98, 0xea, 0x3c, 0x46, 0xb8, 0xbe, 0x9d, 0x57, 0x44, 0xf4, 0xf3, 0x11, 0x5e, 0xdf, + 0x2e, 0x50, 0x7d, 0xfc, 0xc8, 0xfc, 0x36, 0x9d, 0x64, 0x94, 0xea, 0x46, 0x0b, 0xfd, 0xeb, 0x83, + 0xc3, 0x72, 0x2d, 0x8c, 0xeb, 0x75, 0xa3, 0x55, 0xda, 0xd1, 0xb6, 0x1c, 0x33, 0xaa, 0x97, 0xe0, + 0xbc, 0x2d, 0xee, 0x18, 0x8f, 0xea, 0x6c, 0x6b, 0xc6, 0x4b, 0x18, 0x74, 0x32, 0x61, 0x93, 0x7e, + 0x58, 0x93, 0x89, 0x1e, 0x75, 0xc7, 0x0f, 0xd9, 0x87, 0x3c, 0x17, 0x0a, 0xaa, 0x0a, 0x5f, 0x10, + 0x96, 0x8c, 0x41, 0x86, 0x33, 0x7f, 0x2b, 0x0e, 0x65, 0x38, 0x0b, 0x21, 0x20, 0x7e, 0x1c, 0x7f, + 0xd9, 0xc3, 0x31, 0x76, 0x3b, 0xc6, 0x01, 0xd0, 0x19, 0xde, 0xf4, 0x70, 0x40, 0x74, 0x0e, 0x67, + 0x8a, 0xf8, 0x7e, 0x16, 0x6c, 0x8a, 0xcd, 0x78, 0xd0, 0x0f, 0x0d, 0x03, 0x9c, 0x7b, 0x06, 0xd9, + 0x14, 0xa3, 0x5b, 0x62, 0x11, 0xee, 0xe2, 0xd9, 0xc7, 0x41, 0xbb, 0x94, 0xa1, 0x20, 0x28, 0x76, + 0x17, 0x8f, 0x48, 0xfd, 0xf1, 0x03, 0xf8, 0x53, 0x12, 0x4c, 0x93, 0x7d, 0xae, 0x26, 0xd6, 0x4c, + 0xaa, 0x28, 0x87, 0xe2, 0x8d, 0xf9, 0x2e, 0xe1, 0x30, 0xf9, 0x3c, 0x1f, 0x3c, 0x3a, 0x86, 0x02, + 0x85, 0xd8, 0xa5, 0xb3, 0x82, 0x24, 0x8c, 0xc4, 0x14, 0x28, 0xbb, 0x24, 0x30, 0x11, 0x1f, 0x0e, + 0x1e, 0x11, 0xdd, 0xbe, 0x78, 0x66, 0x38, 0x9d, 0x6d, 0xc4, 0x6e, 0x5f, 0x22, 0x44, 0x8c, 0x20, + 0x18, 0xfb, 0x1d, 0xcc, 0x14, 0x58, 0x23, 0x57, 0x55, 0x3d, 0x9d, 0x72, 0x0f, 0x3f, 0x7c, 0x7c, + 0x28, 0x6e, 0x3e, 0x07, 0x88, 0x9c, 0xa8, 0x40, 0xca, 0x34, 0x2e, 0x51, 0xb3, 0xd4, 0x94, 0x4a, + 0xfe, 0x93, 0x29, 0xbf, 0xd1, 0xdc, 0xdd, 0x69, 0xd1, 0x8b, 0x34, 0xa7, 0x54, 0xe7, 0x51, 0xb9, + 0x11, 0xa6, 0x2e, 0xe9, 0xd6, 0xf6, 0x12, 0xd6, 0x1a, 0xd8, 0x54, 0x8d, 0x4b, 0xec, 0xce, 0x5a, + 0x3e, 0x91, 0xdf, 0x83, 0x15, 0x98, 0x5f, 0x92, 0xfb, 0xab, 0x46, 0x72, 0x52, 0x22, 0xca, 0xcc, + 0x33, 0x98, 0xaa, 0xf8, 0x05, 0xe6, 0xbd, 0x12, 0x8c, 0xab, 0xc6, 0x25, 0x26, 0x24, 0xff, 0xe6, + 0x70, 0x65, 0x24, 0xf2, 0x42, 0x8f, 0xde, 0x47, 0xe6, 0x90, 0x3f, 0xf2, 0x85, 0x5e, 0x68, 0xf5, + 0x23, 0x71, 0x8f, 0x9f, 0x54, 0x8d, 0x4b, 0x55, 0x6c, 0xd1, 0x1e, 0x81, 0xd6, 0x87, 0xe4, 0xc9, + 0xa7, 0x77, 0x68, 0x81, 0x6c, 0x1d, 0xee, 0x3e, 0xa3, 0x77, 0x0a, 0x5f, 0xf3, 0xc4, 0x33, 0xc8, + 0x25, 0x71, 0x28, 0x10, 0xbd, 0x4d, 0xe8, 0x76, 0x27, 0x31, 0x0a, 0xe2, 0x47, 0xe9, 0xc7, 0x24, + 0x98, 0x50, 0x8d, 0x4b, 0xf6, 0xd0, 0xb0, 0xa0, 0x37, 0x9b, 0xc3, 0x19, 0x21, 0xa3, 0x4e, 0xfe, + 0x1d, 0x36, 0x38, 0x54, 0x8c, 0x7c, 0xf2, 0xdf, 0x87, 0x80, 0xf8, 0x61, 0x78, 0x82, 0x76, 0x16, + 0x67, 0x84, 0x6e, 0x0d, 0x07, 0x87, 0x41, 0x3b, 0x84, 0x4b, 0xc6, 0xa1, 0x75, 0x88, 0x20, 0x0a, + 0x46, 0xb2, 0x73, 0x32, 0x9d, 0x27, 0xc3, 0xfc, 0x70, 0xfb, 0xc4, 0xbb, 0xa3, 0xb9, 0xd7, 0xb0, + 0x61, 0x97, 0x23, 0x64, 0x28, 0x68, 0x44, 0x70, 0xa3, 0x11, 0xa0, 0x21, 0x7e, 0x3c, 0xfe, 0x58, + 0x82, 0x49, 0x4a, 0xc2, 0x0b, 0x64, 0x16, 0x30, 0x50, 0xa7, 0xf2, 0xb7, 0xe0, 0x70, 0x3a, 0x55, + 0x08, 0x05, 0xf1, 0x83, 0xf8, 0x7f, 0x93, 0x64, 0x1e, 0x37, 0xc0, 0x19, 0xc5, 0x20, 0x04, 0x07, + 0x9e, 0x8c, 0x0d, 0xf1, 0x9c, 0xe2, 0x20, 0x93, 0xb1, 0x43, 0x3a, 0xab, 0xf8, 0x84, 0xdb, 0x8b, + 0x86, 0x89, 0xc1, 0x01, 0xba, 0xc2, 0x10, 0x61, 0x18, 0xb0, 0x2b, 0x1c, 0x12, 0x12, 0x7f, 0x23, + 0x01, 0x50, 0x02, 0x56, 0x8c, 0x3d, 0x8c, 0x9e, 0x19, 0xca, 0xc2, 0xb7, 0xdb, 0x35, 0x54, 0xea, + 0xe3, 0x1a, 0x1a, 0xf1, 0xb4, 0x7f, 0x54, 0x4b, 0xa0, 0x8f, 0xcb, 0x2b, 0x81, 0xd7, 0x6c, 0xc6, + 0x68, 0x09, 0x0c, 0xaf, 0x3f, 0x7e, 0x8c, 0x3f, 0x4f, 0x67, 0x73, 0xde, 0x29, 0xa6, 0x5f, 0x1c, + 0x0a, 0xca, 0xbe, 0xd5, 0xbf, 0xc4, 0xaf, 0xfe, 0x0f, 0x80, 0xed, 0xa0, 0x73, 0xc4, 0x7e, 0xa7, + 0x93, 0xe2, 0x9f, 0x23, 0x1e, 0xde, 0x29, 0xa4, 0x1f, 0x4e, 0xc1, 0x51, 0xa6, 0x44, 0xbe, 0x13, + 0x20, 0x8e, 0x78, 0x96, 0x84, 0x53, 0x92, 0x7d, 0x50, 0x1e, 0x96, 0x41, 0x2a, 0x8a, 0x29, 0x53, + 0x80, 0xbc, 0x91, 0x58, 0x37, 0x32, 0xc5, 0xcb, 0x6d, 0xad, 0xd5, 0x10, 0x0f, 0xf8, 0xd8, 0x07, + 0x78, 0xc7, 0xd6, 0x28, 0xf1, 0xb6, 0xc6, 0x1e, 0x96, 0xc9, 0xc8, 0x3b, 0xd7, 0x84, 0x65, 0x94, + 0xdc, 0x91, 0xef, 0x5c, 0x07, 0xd7, 0x1d, 0x3f, 0x4a, 0xef, 0x96, 0x20, 0x55, 0x35, 0x4c, 0x0b, + 0x3d, 0x19, 0xa5, 0x77, 0x52, 0xce, 0x7b, 0x20, 0x39, 0xcf, 0x4a, 0x9e, 0xbb, 0xfa, 0xea, 0x74, + 0xf8, 0x79, 0x3a, 0xcd, 0xd2, 0x48, 0x38, 0x70, 0xbb, 0x7e, 0xdf, 0x1d, 0x58, 0x51, 0x83, 0x36, + 0x50, 0xfe, 0x55, 0x83, 0x9d, 0x88, 0x63, 0x0b, 0xda, 0x10, 0x58, 0xf3, 0x08, 0xec, 0xbe, 0x13, + 0xcc, 0x2f, 0x95, 0xdc, 0x08, 0xf8, 0x24, 0x75, 0x19, 0x29, 0x6b, 0x3b, 0x78, 0x48, 0x2e, 0xc3, + 0x24, 0xe6, 0xa0, 0xe4, 0xc5, 0x1c, 0x8c, 0xda, 0xa1, 0xe8, 0x29, 0x47, 0x4a, 0xd2, 0xa8, 0x3b, + 0x54, 0x48, 0xdd, 0xf1, 0x03, 0xf3, 0x59, 0x7b, 0xe4, 0x23, 0x6b, 0xc8, 0x5c, 0xab, 0xc1, 0x82, + 0xb8, 0xfd, 0xdd, 0x61, 0xef, 0xdd, 0xec, 0x0b, 0xf3, 0xc6, 0x87, 0x8b, 0x4c, 0x77, 0xdf, 0x60, + 0x37, 0x4f, 0x43, 0xc6, 0x91, 0x93, 0x97, 0x99, 0x48, 0xb7, 0xd8, 0xb9, 0xdf, 0xa1, 0x67, 0xa3, + 0x99, 0x73, 0x48, 0x11, 0x5d, 0x8c, 0x8b, 0x79, 0x48, 0x8d, 0x60, 0xe8, 0x11, 0xa0, 0xee, 0x9f, + 0x87, 0x97, 0xd1, 0xfe, 0x4b, 0x04, 0x23, 0x9a, 0xb2, 0xdd, 0xab, 0x1f, 0x0f, 0xcb, 0xcb, 0xa8, + 0x1f, 0x01, 0x23, 0x08, 0x71, 0x96, 0x66, 0x9b, 0xbc, 0xc4, 0x05, 0x0f, 0x7d, 0x2e, 0x19, 0xbb, + 0xf2, 0x16, 0xbf, 0x36, 0xd7, 0xa3, 0x2b, 0x5c, 0x7b, 0x47, 0x71, 0x74, 0x0d, 0x2b, 0x6e, 0x04, + 0xe6, 0x84, 0x24, 0x71, 0x51, 0xbe, 0xa0, 0x37, 0xac, 0xed, 0x21, 0x39, 0xfa, 0x5f, 0xb2, 0xcb, + 0x72, 0xee, 0x9f, 0x23, 0x0f, 0xe8, 0xf9, 0x44, 0xa4, 0xf0, 0x15, 0x2e, 0x4b, 0x08, 0x59, 0x01, + 0x2c, 0x8e, 0x10, 0x74, 0x22, 0xb4, 0xbc, 0x11, 0x4a, 0xf4, 0x79, 0xbd, 0x81, 0x8d, 0x17, 0xa0, + 0x44, 0x13, 0xba, 0x86, 0x27, 0xd1, 0x61, 0xc5, 0xfd, 0x33, 0x95, 0x68, 0x97, 0x25, 0x43, 0x92, + 0xe8, 0xd0, 0xf2, 0x46, 0x10, 0x1b, 0x1d, 0xd8, 0xfc, 0x7a, 0x59, 0x6f, 0x5d, 0x44, 0x1f, 0x49, + 0x3b, 0x37, 0xdf, 0x5d, 0xd0, 0xad, 0x6d, 0x76, 0xcc, 0xfd, 0x43, 0xc2, 0x77, 0x64, 0x0c, 0x70, + 0x94, 0xfd, 0x04, 0x80, 0xc5, 0x6e, 0xa4, 0x72, 0x63, 0xe6, 0xf8, 0x52, 0x94, 0x1c, 0x4c, 0xe9, + 0x2d, 0x0b, 0x9b, 0x2d, 0xad, 0xb9, 0xd0, 0xd4, 0xb6, 0x3a, 0x33, 0x59, 0x72, 0x34, 0xf3, 0x9a, + 0xae, 0xc1, 0xbb, 0xe4, 0xcb, 0xa3, 0xf2, 0x5f, 0x08, 0xcf, 0x35, 0x23, 0x86, 0xfc, 0x39, 0x2d, + 0x18, 0x89, 0xc5, 0x0d, 0xff, 0xf4, 0xf5, 0x68, 0xc6, 0x17, 0x1b, 0x90, 0xb9, 0x6e, 0x30, 0x22, + 0xcf, 0x14, 0xfd, 0x8d, 0x97, 0xba, 0x1a, 0xef, 0x4e, 0x3d, 0x52, 0x43, 0x36, 0xcc, 0x88, 0x90, + 0x3e, 0x82, 0x93, 0x1f, 0x69, 0xb8, 0xca, 0x09, 0x5f, 0xd7, 0x6e, 0x63, 0xcd, 0xd4, 0x5a, 0x75, + 0x1c, 0x41, 0x9a, 0xc3, 0xe6, 0x92, 0x0b, 0x30, 0xa6, 0xd7, 0x8d, 0x56, 0x55, 0x7f, 0x95, 0x73, + 0x95, 0x4b, 0x78, 0xec, 0x53, 0xc2, 0x91, 0x12, 0xfb, 0x42, 0x75, 0xbf, 0x55, 0x4a, 0x30, 0x5e, + 0xd7, 0xcc, 0x46, 0xd5, 0x77, 0xb9, 0xf5, 0xad, 0xfd, 0x0b, 0xca, 0x3b, 0x9f, 0xa8, 0xde, 0xd7, + 0x4a, 0x85, 0x67, 0x62, 0xa6, 0xeb, 0xf4, 0x6f, 0x60, 0x61, 0x05, 0xef, 0x23, 0x8e, 0xe7, 0x36, + 0x77, 0x4c, 0xdc, 0x24, 0x37, 0x67, 0xd2, 0x6e, 0x37, 0xae, 0x7a, 0x09, 0xe8, 0xbd, 0x7e, 0x69, + 0x5e, 0xe1, 0xa5, 0xf9, 0x95, 0x01, 0x22, 0xb1, 0x0f, 0x8d, 0xa1, 0xcc, 0x89, 0xdf, 0xe1, 0x0a, + 0xe6, 0x2a, 0x27, 0x98, 0xf7, 0x0d, 0x48, 0x45, 0xfc, 0x92, 0xf9, 0x3b, 0x19, 0x98, 0xa2, 0x87, + 0xc9, 0x19, 0x3b, 0xd1, 0x4f, 0x91, 0xcb, 0xda, 0xac, 0x73, 0xf8, 0x0a, 0xaa, 0x1e, 0x7c, 0xa0, + 0x93, 0x41, 0xba, 0x88, 0xaf, 0xb0, 0xfe, 0x6e, 0xff, 0x8d, 0xba, 0x47, 0xea, 0xd0, 0x35, 0x47, + 0x69, 0x1a, 0xf5, 0x1e, 0x69, 0x78, 0xf5, 0xf1, 0xe3, 0xf3, 0x5a, 0x09, 0xa4, 0x5c, 0xa3, 0x21, + 0x1e, 0xdf, 0x29, 0x18, 0x8a, 0xeb, 0x61, 0xc2, 0xe9, 0x33, 0xe7, 0x5c, 0x48, 0xfc, 0x49, 0x51, + 0x0d, 0x4e, 0x2e, 0x6f, 0x72, 0x8d, 0x91, 0x5b, 0x70, 0x43, 0xea, 0x8e, 0x1f, 0x94, 0x5f, 0xcc, + 0xb2, 0x4e, 0x33, 0x6f, 0x18, 0x17, 0xc9, 0xb1, 0x84, 0x27, 0x25, 0x48, 0x2f, 0x60, 0xab, 0xbe, + 0x3d, 0xa4, 0x3e, 0xb3, 0x6b, 0x36, 0x9d, 0x3e, 0xb3, 0xef, 0xe6, 0xc9, 0xfe, 0x13, 0x43, 0x87, + 0xac, 0x39, 0x42, 0xd2, 0xa8, 0xc3, 0x35, 0x86, 0xd6, 0x1e, 0x3f, 0x38, 0xcf, 0x4b, 0x30, 0xed, + 0x9a, 0x8d, 0x28, 0x26, 0x3f, 0xf3, 0x82, 0x33, 0x06, 0xa2, 0x4f, 0x45, 0x0b, 0xa9, 0xe2, 0xf2, + 0x94, 0x6f, 0x59, 0xcc, 0xd6, 0xba, 0x08, 0xc1, 0x56, 0xc4, 0x08, 0x1c, 0xc1, 0xb2, 0x58, 0x82, + 0x31, 0x42, 0x50, 0x41, 0xdf, 0x23, 0x6e, 0x5a, 0x9c, 0xf5, 0xee, 0xb1, 0xa1, 0x58, 0xef, 0xee, + 0xe3, 0xad, 0x77, 0x82, 0x21, 0x0c, 0x1d, 0xe3, 0x5d, 0x44, 0xbf, 0x05, 0xfb, 0xfb, 0xa1, 0xdb, + 0xee, 0x22, 0xf8, 0x2d, 0xf4, 0xa9, 0x7f, 0x04, 0x57, 0xf4, 0x9e, 0x62, 0xca, 0xd6, 0xd9, 0xbc, + 0x42, 0x8f, 0x29, 0x90, 0x3a, 0x6f, 0xff, 0xf9, 0x9c, 0x77, 0x51, 0xc5, 0x63, 0x43, 0x38, 0x08, + 0xff, 0x00, 0xa4, 0xc8, 0x65, 0xbc, 0xa9, 0xae, 0x90, 0x9b, 0xa1, 0x3b, 0x69, 0x36, 0x21, 0x2a, + 0xf9, 0x2e, 0x6a, 0xb0, 0x32, 0xae, 0x88, 0xb9, 0xe1, 0xb9, 0xe1, 0x29, 0xc7, 0x21, 0x63, 0x97, + 0xeb, 0x2e, 0xb3, 0xd8, 0x53, 0x14, 0xe3, 0xbb, 0x00, 0x6d, 0xf1, 0x23, 0xff, 0x39, 0x72, 0x27, + 0x0f, 0x89, 0xa9, 0xfa, 0xd4, 0x10, 0xe0, 0x0d, 0x60, 0xcb, 0x81, 0x61, 0x7f, 0xf7, 0x41, 0x60, + 0x77, 0x03, 0xb8, 0x8e, 0xd4, 0x89, 0x56, 0x80, 0x86, 0x91, 0x9c, 0xfc, 0xcd, 0x30, 0xc7, 0xbf, + 0x47, 0x86, 0x89, 0x6e, 0x8a, 0x13, 0xfa, 0x03, 0xa1, 0x33, 0x44, 0x87, 0xc0, 0x81, 0xd1, 0x39, + 0x24, 0x97, 0xc0, 0x3f, 0x91, 0x60, 0xa2, 0xea, 0x5d, 0x20, 0x27, 0x7e, 0x43, 0x41, 0x64, 0x88, + 0xec, 0xb1, 0x96, 0x8b, 0x0f, 0x39, 0x35, 0x78, 0xc8, 0x50, 0x9e, 0x75, 0x3e, 0xfa, 0x47, 0x1d, + 0x32, 0x54, 0x94, 0x90, 0xf8, 0x81, 0xfc, 0x04, 0xbd, 0x11, 0x24, 0x57, 0xb7, 0xf4, 0x3d, 0x8c, + 0x9e, 0x88, 0x51, 0x91, 0x1e, 0x87, 0x8c, 0xb1, 0xb9, 0xd9, 0x61, 0x37, 0x0b, 0x4e, 0xa9, 0xec, + 0xc9, 0xbb, 0xd2, 0x9d, 0x82, 0xcb, 0xae, 0x74, 0x8f, 0x18, 0x54, 0x70, 0x1f, 0x43, 0x69, 0x83, + 0x46, 0x1d, 0x54, 0x50, 0x8c, 0x8c, 0x11, 0x84, 0x0d, 0x06, 0x9b, 0x7b, 0xcc, 0x64, 0xf3, 0x16, + 0x66, 0x24, 0xc0, 0x07, 0xc7, 0x76, 0x16, 0x26, 0x7d, 0x16, 0x01, 0x27, 0x30, 0x3d, 0x97, 0x16, + 0xf5, 0xac, 0xb1, 0xcb, 0xb2, 0xa1, 0xdb, 0x0b, 0x22, 0xd8, 0x81, 0x45, 0x88, 0x18, 0xc9, 0xbd, + 0x2f, 0xce, 0x90, 0x37, 0x22, 0xac, 0xfe, 0xc0, 0x8f, 0x55, 0x85, 0xc7, 0xea, 0xac, 0x08, 0x9b, + 0xc4, 0x86, 0x40, 0xa1, 0xe5, 0xe4, 0x3b, 0x5d, 0xb8, 0x54, 0x0e, 0xae, 0x07, 0x06, 0xa6, 0x23, + 0x7e, 0xc4, 0x3e, 0x20, 0xd1, 0xcb, 0x1f, 0x72, 0x7b, 0x9a, 0xde, 0x24, 0x07, 0xc4, 0x87, 0x70, + 0x05, 0xe1, 0x7f, 0xf7, 0x83, 0x72, 0x9e, 0x07, 0xe5, 0x21, 0x11, 0x66, 0x70, 0x14, 0x05, 0x60, + 0xf3, 0x72, 0xbf, 0xcd, 0x9c, 0x46, 0x11, 0xbd, 0xba, 0x3b, 0x12, 0x1b, 0x7b, 0xef, 0x37, 0xa6, + 0x7f, 0xdc, 0x05, 0xe9, 0x11, 0x0e, 0xa4, 0xe2, 0x41, 0xe9, 0x8a, 0x86, 0xd5, 0x72, 0x74, 0xac, + 0x94, 0x19, 0x38, 0x56, 0xae, 0xd4, 0xd6, 0x73, 0xeb, 0x85, 0x5c, 0x2d, 0x77, 0xbe, 0x54, 0xbc, + 0xb0, 0x3e, 0xbf, 0x5c, 0xc9, 0x9f, 0x93, 0x25, 0xf4, 0x4b, 0x74, 0x0c, 0xac, 0x1a, 0xbb, 0x66, + 0x7d, 0x58, 0xb3, 0xcd, 0x0e, 0x29, 0x8c, 0x75, 0x3a, 0xf6, 0x14, 0xd5, 0x71, 0xdd, 0xf3, 0xc7, + 0x74, 0x88, 0xeb, 0xd7, 0xd1, 0x52, 0x43, 0x76, 0x5c, 0xef, 0x4b, 0x41, 0xfc, 0x5d, 0xec, 0x9b, + 0x12, 0xc0, 0xa2, 0x69, 0xec, 0xb6, 0x2b, 0x66, 0x03, 0x9b, 0xe8, 0x39, 0x6f, 0xd5, 0xf7, 0x73, + 0x43, 0x98, 0xac, 0xac, 0x02, 0x6c, 0xb9, 0x85, 0x33, 0x3d, 0x75, 0x87, 0xd8, 0x1a, 0xcf, 0x23, + 0x4a, 0xf5, 0x95, 0xc1, 0x5f, 0x10, 0xf8, 0x3d, 0x3c, 0xc6, 0x61, 0x23, 0x8f, 0x57, 0xdc, 0x30, + 0x57, 0x7d, 0xef, 0x72, 0xb1, 0xae, 0x71, 0x58, 0x3f, 0x74, 0x00, 0x4a, 0xe2, 0xc7, 0xfc, 0x5b, + 0x12, 0x4c, 0xd0, 0xbd, 0x58, 0xca, 0xd3, 0xbf, 0xf5, 0x40, 0xff, 0xc5, 0x21, 0x80, 0xbe, 0x06, + 0x93, 0x86, 0x57, 0x3a, 0x1d, 0x19, 0xfd, 0xd6, 0xb5, 0x50, 0xd8, 0x7d, 0x74, 0xa9, 0x5c, 0x31, + 0xe8, 0x03, 0x7e, 0xe4, 0x55, 0x1e, 0xf9, 0xfb, 0x42, 0xf8, 0xed, 0x2b, 0x71, 0x98, 0xd0, 0xff, + 0xae, 0x0b, 0xfd, 0x1a, 0x07, 0x7d, 0xee, 0x20, 0xa4, 0xc4, 0x8f, 0xfd, 0xe3, 0xae, 0x81, 0xde, + 0xdd, 0x3e, 0x89, 0x65, 0xd3, 0xe4, 0xf5, 0x03, 0x2e, 0x30, 0x78, 0xda, 0x02, 0x90, 0x9a, 0x86, + 0xa4, 0xee, 0xd0, 0x90, 0xd4, 0x1b, 0x03, 0x2d, 0x21, 0x42, 0x2b, 0x8a, 0x1f, 0x87, 0x5f, 0x7d, + 0x09, 0xa4, 0x0b, 0x78, 0x63, 0x77, 0x0b, 0xbd, 0x55, 0x82, 0x6c, 0xd3, 0xd8, 0x2a, 0xb5, 0x36, + 0x0d, 0xd6, 0xb0, 0x84, 0xd3, 0x30, 0x45, 0x81, 0xd4, 0x36, 0xd6, 0x9c, 0xa6, 0x92, 0xff, 0xca, + 0x49, 0x98, 0xb6, 0x7f, 0x9d, 0x0b, 0x8a, 0xdd, 0xe8, 0x93, 0x5d, 0xa9, 0xf6, 0x04, 0xd5, 0x32, + 0x2c, 0xad, 0xa9, 0xe2, 0xba, 0x61, 0x36, 0xe8, 0x69, 0x91, 0xb4, 0xca, 0xa5, 0xd9, 0x78, 0x93, + 0x67, 0xe2, 0xbf, 0x90, 0x26, 0x19, 0xbc, 0x04, 0xe5, 0x46, 0x98, 0xda, 0xd4, 0xcd, 0x8e, 0x45, + 0x73, 0xd7, 0xa8, 0x83, 0x4b, 0x5a, 0xe5, 0x13, 0x6d, 0x7a, 0x7c, 0x09, 0xe7, 0xb1, 0x49, 0x2e, + 0x17, 0x4a, 0xab, 0x5d, 0xa9, 0x36, 0x3d, 0x4d, 0xcd, 0x57, 0xd8, 0x18, 0xa5, 0xc7, 0x9f, 0x66, + 0xd7, 0xe8, 0x3d, 0xdb, 0x45, 0x8d, 0xd3, 0x1a, 0xb9, 0x44, 0xbb, 0x46, 0x3b, 0x61, 0x75, 0xb7, + 0xd9, 0xac, 0xe2, 0x7a, 0x6e, 0xcb, 0x98, 0x01, 0x5a, 0x23, 0x9f, 0xaa, 0x20, 0x18, 0xdb, 0x6d, + 0x57, 0x2d, 0xcd, 0xda, 0xed, 0xcc, 0x4c, 0xd0, 0xfd, 0x24, 0xe7, 0x59, 0x39, 0x01, 0xd0, 0x30, + 0x2e, 0xb5, 0xd8, 0xdb, 0x49, 0xea, 0x6f, 0xe4, 0xa5, 0xd8, 0xcb, 0x66, 0x2a, 0xb2, 0x53, 0x34, + 0x86, 0x1d, 0xf5, 0xe7, 0xfa, 0xa4, 0x04, 0x60, 0x6d, 0x9b, 0x58, 0x6b, 0xf4, 0x84, 0xeb, 0x15, + 0x70, 0xbc, 0x69, 0x6c, 0x75, 0x2e, 0xe8, 0xd6, 0xb6, 0x07, 0xc4, 0x92, 0x03, 0x60, 0x5a, 0x0d, + 0x78, 0xab, 0x3c, 0x04, 0xd7, 0x38, 0x6f, 0x2e, 0x6c, 0x1b, 0x4d, 0x5c, 0x33, 0x31, 0xee, 0xc2, + 0x37, 0xad, 0x86, 0x65, 0x51, 0xe6, 0x20, 0x65, 0xbf, 0x66, 0x97, 0xc7, 0x23, 0x4e, 0xee, 0x89, + 0x98, 0xcd, 0x31, 0x11, 0x53, 0x49, 0x3e, 0xe5, 0x6e, 0xb8, 0xda, 0xb8, 0xd4, 0x5a, 0x36, 0xb6, + 0x96, 0xb4, 0x4e, 0x5e, 0xdb, 0xc4, 0x2a, 0xa6, 0xc7, 0xa6, 0x0c, 0x93, 0x88, 0xc1, 0x98, 0x1a, + 0xf4, 0x5a, 0x99, 0x03, 0xa5, 0xae, 0x6d, 0xe2, 0x65, 0x1e, 0x00, 0x2a, 0x19, 0x3d, 0xde, 0xd8, + 0xb0, 0xdb, 0xa9, 0x6b, 0x0e, 0x10, 0x59, 0x7a, 0x10, 0xd5, 0x9f, 0x66, 0x03, 0x6a, 0x3f, 0x17, + 0x3c, 0x40, 0xc6, 0x48, 0xae, 0xae, 0xd4, 0x7d, 0x22, 0x3d, 0xde, 0x4f, 0xa4, 0xa1, 0x5b, 0xa4, + 0x5d, 0x58, 0x27, 0xfc, 0xb0, 0x7e, 0x26, 0x0d, 0xa9, 0xea, 0x95, 0x56, 0x1d, 0xbd, 0xc9, 0x37, + 0xfc, 0x9d, 0x81, 0x63, 0x26, 0x2d, 0xb3, 0x66, 0x6a, 0x7b, 0xd8, 0xec, 0xe0, 0x65, 0x62, 0x47, + 0x49, 0x90, 0x32, 0x7b, 0xbe, 0xb3, 0xe5, 0xb7, 0x73, 0x51, 0x6f, 0x17, 0x77, 0xda, 0xd6, 0x95, + 0x65, 0x1b, 0x8f, 0x24, 0x8d, 0x02, 0xc5, 0x25, 0x2a, 0x0f, 0x00, 0xb2, 0xcc, 0x2b, 0x35, 0xc3, + 0xc1, 0x4f, 0xc5, 0x3b, 0x86, 0x85, 0x9d, 0x46, 0xd1, 0xde, 0x1c, 0x92, 0x03, 0xfd, 0x7a, 0xca, + 0xa7, 0x5b, 0xef, 0xe3, 0x75, 0xeb, 0xc9, 0x1e, 0xd0, 0xdb, 0x4d, 0x0b, 0xd0, 0xa4, 0xaf, 0x84, + 0x2c, 0x95, 0x67, 0x67, 0x95, 0x72, 0x5d, 0x8f, 0xef, 0x3d, 0x89, 0x57, 0x9d, 0xdc, 0x76, 0xdf, + 0x6a, 0xe0, 0x3d, 0xbd, 0x8e, 0x3d, 0x7f, 0x32, 0xe7, 0xd9, 0x85, 0xa9, 0xc6, 0x4a, 0xf6, 0x6b, + 0x1e, 0x96, 0x46, 0x78, 0x40, 0xff, 0xda, 0x22, 0x6d, 0xec, 0x5a, 0xb6, 0x88, 0x95, 0x5a, 0x15, + 0x22, 0x75, 0x4c, 0x15, 0x85, 0xe4, 0x50, 0xe6, 0xe1, 0x5a, 0xfe, 0xed, 0x12, 0xaf, 0x13, 0xa9, + 0x40, 0x86, 0xe6, 0xd9, 0x27, 0x4e, 0xd9, 0x7e, 0xe2, 0x34, 0xd6, 0x25, 0x4e, 0xe8, 0x0d, 0xee, + 0xc0, 0xf3, 0x20, 0x37, 0xf0, 0xdc, 0x2a, 0x86, 0xc2, 0x48, 0xc2, 0x65, 0x65, 0x28, 0xcb, 0xd1, + 0x4f, 0xf9, 0x64, 0x1b, 0xc1, 0x18, 0x03, 0xd5, 0x51, 0x5f, 0xee, 0xf3, 0x88, 0x64, 0xf8, 0x57, + 0x84, 0x6f, 0xcd, 0xa0, 0xdc, 0xa3, 0x8d, 0x08, 0x90, 0xe2, 0x3b, 0x21, 0xa5, 0xb7, 0x36, 0x0d, + 0x36, 0x71, 0xeb, 0x23, 0xc2, 0x24, 0xab, 0xe0, 0x35, 0x19, 0x21, 0x75, 0xc7, 0x8f, 0xdd, 0x6b, + 0x24, 0x48, 0xd9, 0x6a, 0xde, 0x1f, 0xf7, 0x13, 0xc1, 0x18, 0x9d, 0x14, 0x7b, 0xc0, 0x39, 0xcf, + 0x3d, 0xef, 0x0e, 0x99, 0x85, 0xc9, 0xdd, 0x96, 0xd6, 0x32, 0x5a, 0x57, 0x76, 0xf4, 0x57, 0xb9, + 0x53, 0x05, 0x2e, 0xcd, 0xa6, 0x7e, 0x0b, 0xb7, 0xb0, 0xa9, 0x59, 0xb8, 0xba, 0xb7, 0x45, 0x7a, + 0xeb, 0x98, 0xea, 0x4f, 0x42, 0x8f, 0x27, 0xa3, 0x29, 0x1c, 0x9b, 0xea, 0xe0, 0x2b, 0x2a, 0x37, + 0xf5, 0x26, 0x26, 0xfe, 0xed, 0xcc, 0xc7, 0xc3, 0x79, 0x8e, 0xd4, 0x9b, 0x7a, 0x54, 0x31, 0x12, + 0x44, 0x64, 0x7a, 0x67, 0xca, 0xb2, 0x51, 0xd7, 0x9a, 0x1d, 0xcb, 0x30, 0x31, 0x7a, 0xb9, 0x87, + 0x8e, 0x83, 0x40, 0xc2, 0x87, 0xc0, 0x71, 0xc8, 0x34, 0x8c, 0xba, 0xe7, 0xc9, 0xc0, 0x9e, 0xf8, + 0xe5, 0x4c, 0xe8, 0x31, 0x22, 0xda, 0xe0, 0xee, 0x7a, 0x63, 0xbb, 0x40, 0x46, 0xec, 0x68, 0x91, + 0x10, 0x51, 0x23, 0x88, 0xab, 0x90, 0x84, 0xd4, 0xaa, 0xde, 0xda, 0xf2, 0x2f, 0x62, 0x8e, 0x41, + 0x5a, 0x6f, 0x35, 0xf0, 0x65, 0x36, 0x52, 0xd3, 0x07, 0x7b, 0x38, 0x6f, 0xed, 0xee, 0x6c, 0x60, + 0xb3, 0xb2, 0x49, 0x9a, 0xdb, 0xa9, 0x19, 0x55, 0xdc, 0x72, 0x66, 0x66, 0x3d, 0xdf, 0xa1, 0x6f, + 0x27, 0xa2, 0xc9, 0xbd, 0x4d, 0x49, 0x00, 0x2e, 0x2e, 0x51, 0x49, 0x1f, 0x51, 0x91, 0x24, 0xbe, + 0x47, 0xe1, 0xf1, 0xf3, 0xf7, 0x23, 0x49, 0xc8, 0xae, 0x60, 0xcb, 0xd4, 0xeb, 0x1d, 0xf4, 0xfe, + 0x24, 0x4c, 0x55, 0xb1, 0xb5, 0xaa, 0x99, 0xda, 0x0e, 0xb6, 0xec, 0x25, 0xf9, 0xad, 0x9c, 0x62, + 0x6a, 0x37, 0x35, 0x6b, 0xd3, 0x30, 0x77, 0x1c, 0xc5, 0xe4, 0x3c, 0xdf, 0x93, 0x7a, 0xf2, 0x2b, + 0x52, 0x82, 0x67, 0x66, 0xa8, 0xeb, 0x0d, 0xab, 0x70, 0x8e, 0xab, 0x2c, 0xe0, 0x84, 0x85, 0x98, + 0x33, 0x8d, 0x48, 0x89, 0xf1, 0x33, 0xf3, 0x0f, 0x25, 0x90, 0x96, 0x8d, 0x2d, 0xf4, 0x1e, 0x09, + 0x52, 0x44, 0xbe, 0x7e, 0xc3, 0x37, 0x24, 0xcf, 0x40, 0x76, 0x07, 0x77, 0x3a, 0xda, 0x16, 0x76, + 0xee, 0x97, 0x66, 0x8f, 0xca, 0x59, 0x48, 0x37, 0xf1, 0x1e, 0x6e, 0x12, 0x32, 0xa6, 0xcf, 0xdc, + 0xc0, 0xb5, 0x6c, 0xd9, 0xd8, 0x9a, 0xb3, 0xcb, 0x72, 0x6f, 0xa1, 0x5d, 0xb6, 0xb3, 0xaa, 0xf4, + 0x8b, 0xd9, 0x87, 0x21, 0x4d, 0x9e, 0x95, 0x71, 0x48, 0x17, 0x8a, 0xf3, 0x6b, 0x8b, 0xf2, 0x11, + 0xfb, 0xaf, 0x43, 0xdf, 0x38, 0xa4, 0x17, 0x72, 0xb5, 0xdc, 0xb2, 0x9c, 0xb4, 0xdb, 0x51, 0x2a, + 0x2f, 0x54, 0x64, 0xc9, 0x4e, 0x5c, 0xcd, 0x95, 0x4b, 0x79, 0x39, 0xa5, 0x4c, 0x40, 0xf6, 0x42, + 0x4e, 0x2d, 0x97, 0xca, 0x8b, 0x72, 0x1a, 0x3d, 0xe6, 0x57, 0x58, 0xf7, 0xf0, 0xf8, 0xdd, 0x18, + 0x44, 0x53, 0x2f, 0xc8, 0xfe, 0xbd, 0x0b, 0xd9, 0xfd, 0x1c, 0x64, 0xdf, 0x2d, 0x52, 0x48, 0x34, + 0x94, 0xca, 0x03, 0x18, 0xb2, 0xa7, 0x60, 0xbc, 0x5c, 0xa9, 0xad, 0x2f, 0x54, 0xd6, 0xca, 0x05, + 0x19, 0xdb, 0x3c, 0xa8, 0x95, 0x56, 0x8a, 0x95, 0xb5, 0x9a, 0xbc, 0x89, 0xde, 0x94, 0x84, 0xec, + 0xaa, 0x69, 0xd4, 0x71, 0xa7, 0x83, 0x5e, 0x97, 0x84, 0x4c, 0x5e, 0x6b, 0xd5, 0x71, 0x13, 0xbd, + 0xc4, 0x83, 0xb1, 0x6b, 0x49, 0x88, 0xbe, 0xe9, 0x97, 0xfa, 0x87, 0x78, 0xae, 0xf1, 0xf7, 0x0a, + 0xb3, 0x72, 0xe7, 0x68, 0x99, 0x01, 0xbc, 0x7b, 0xc6, 0xe5, 0x5d, 0x9e, 0xe3, 0xdd, 0x69, 0xf1, + 0xa2, 0xe2, 0x97, 0xf3, 0xbf, 0x4f, 0xc0, 0xb1, 0x45, 0x7b, 0xfa, 0xa0, 0xd7, 0x29, 0xf1, 0x4e, + 0xfb, 0xef, 0xe7, 0xdb, 0x7f, 0x33, 0x47, 0x74, 0xaf, 0x2f, 0xf8, 0xc6, 0x3f, 0xed, 0x36, 0xfe, + 0x21, 0xae, 0xf1, 0xb7, 0x09, 0x96, 0x13, 0x7b, 0xcb, 0x67, 0xb3, 0x90, 0x26, 0x53, 0xe4, 0xd9, + 0x9b, 0x60, 0xaa, 0x6a, 0x99, 0x58, 0xdb, 0xf1, 0x0d, 0x4a, 0x96, 0x71, 0x11, 0xb7, 0x98, 0x68, + 0xd0, 0x87, 0x7b, 0xce, 0x42, 0xb6, 0x65, 0xac, 0x6b, 0xbb, 0xd6, 0xb6, 0xf2, 0xd2, 0x7d, 0xc7, + 0x86, 0x56, 0x68, 0xff, 0xaf, 0xb4, 0xe9, 0x2e, 0xd2, 0xdf, 0xdc, 0x47, 0x26, 0x66, 0x99, 0x96, + 0x91, 0xdb, 0xb5, 0xb6, 0xe7, 0xaf, 0xfd, 0xf0, 0x73, 0x27, 0x12, 0x1f, 0x7b, 0xee, 0x44, 0xe2, + 0x8b, 0xcf, 0x9d, 0x48, 0xfc, 0xcc, 0x97, 0x4e, 0x1c, 0xf9, 0xd8, 0x97, 0x4e, 0x1c, 0xf9, 0xec, + 0x97, 0x4e, 0x1c, 0xf9, 0xbe, 0x64, 0x7b, 0x63, 0x23, 0x43, 0x4a, 0xb9, 0xeb, 0xff, 0x05, 0x00, + 0x00, 0xff, 0xff, 0xd3, 0x4c, 0x7e, 0x8a, 0x73, 0x39, 0x01, 0x00, } func (m *Rpc) Marshal() (dAtA []byte, err error) { From 5e67fdc4d1d7c9719caf3517893bf6bdc00735c7 Mon Sep 17 00:00:00 2001 From: kirillston Date: Wed, 21 Dec 2022 11:11:10 +0100 Subject: [PATCH 30/68] GO-677 Unify URL validation --- core/block/editor/bookmark/bookmark.go | 2 +- core/block/editor/file/uploader.go | 2 +- core/block/editor/import/import.go | 3 +- core/block/import/markdown/blockconverter.go | 4 +- core/block/service.go | 4 +- core/block/simple/text/text.go | 10 +- core/converter/md/md.go | 6 +- core/linkpreview.go | 17 +-- core/relation/service.go | 4 +- util/linkpreview/linkpreview.go | 5 +- util/unsplash/unsplash.go | 4 +- util/uri/uri.go | 114 ++++++++++--------- 12 files changed, 89 insertions(+), 86 deletions(-) diff --git a/core/block/editor/bookmark/bookmark.go b/core/block/editor/bookmark/bookmark.go index efdf69a0b..b0e3f408c 100644 --- a/core/block/editor/bookmark/bookmark.go +++ b/core/block/editor/bookmark/bookmark.go @@ -61,7 +61,7 @@ func (b *sbookmark) fetch(s *state.State, id, url string, isSync bool) (err erro if b == nil { return smartblock.ErrSimpleBlockNotFound } - url, err = uri.ProcessURI(url) + url, err = uri.URIManager.ValidateAndNormalizeURI(url) if err != nil { // Do nothing } diff --git a/core/block/editor/file/uploader.go b/core/block/editor/file/uploader.go index 0256c745b..a2253e395 100644 --- a/core/block/editor/file/uploader.go +++ b/core/block/editor/file/uploader.go @@ -175,7 +175,7 @@ func (u *uploader) AddOptions(options ...files.AddOption) Uploader { } func (u *uploader) SetUrl(url string) Uploader { - url, _ = uri.ProcessURI(url) + url = uri.URIManager.NormalizeURI(url) u.name = strings.Split(filepath.Base(url), "?")[0] u.getReader = func(ctx context.Context) (*fileReader, error) { req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) diff --git a/core/block/editor/import/import.go b/core/block/editor/import/import.go index 41c4f0e3e..eaad7498d 100644 --- a/core/block/editor/import/import.go +++ b/core/block/editor/import/import.go @@ -27,6 +27,7 @@ import ( "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" "github.com/anytypeio/go-anytype-middleware/util/pbtypes" "github.com/anytypeio/go-anytype-middleware/util/slice" + "github.com/anytypeio/go-anytype-middleware/util/uri" ) var ( @@ -669,7 +670,7 @@ func (imp *importImpl) convertTextToPageLink(block *model.Block) { } func (imp *importImpl) convertTextToBookmark(block *model.Block) { - if _, err := url.Parse(block.GetText().Marks.Marks[0].Param); err != nil { + if err := uri.URIManager.Validate(block.GetText().Marks.Marks[0].Param); err != nil { return } diff --git a/core/block/import/markdown/blockconverter.go b/core/block/import/markdown/blockconverter.go index 05c2f8200..a7f56f2b3 100644 --- a/core/block/import/markdown/blockconverter.go +++ b/core/block/import/markdown/blockconverter.go @@ -6,7 +6,6 @@ import ( "fmt" "io" "io/ioutil" - "net/url" "os" "path/filepath" "strings" @@ -18,6 +17,7 @@ import ( "github.com/anytypeio/go-anytype-middleware/core/block/import/markdown/anymark" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" + "github.com/anytypeio/go-anytype-middleware/util/uri" ) type Service interface { @@ -258,7 +258,7 @@ func (m *mdConverter) convertTextToPageLink(block *model.Block) { } func (m *mdConverter) convertTextToBookmark(block *model.Block) { - if _, err := url.Parse(block.GetText().Marks.Marks[0].Param); err != nil { + if err := uri.URIManager.Validate(block.GetText().Marks.Marks[0].Param); err != nil { return } diff --git a/core/block/service.go b/core/block/service.go index 212d40e47..935ebe885 100644 --- a/core/block/service.go +++ b/core/block/service.go @@ -1593,7 +1593,7 @@ func (s *Service) fetchBookmarkContent(url string) bookmarksvc.ContentFuture { func (s *Service) ObjectCreateBookmark( req pb.RpcObjectCreateBookmarkRequest, ) (objectId string, newDetails *types.Struct, err error) { - u, err := uri.ProcessURI(pbtypes.GetString(req.Details, bundle.RelationKeySource.String())) + u, err := uri.URIManager.ValidateAndNormalizeURI(pbtypes.GetString(req.Details, bundle.RelationKeySource.String())) if err != nil { return "", nil, fmt.Errorf("process uri: %w", err) } @@ -1602,7 +1602,7 @@ func (s *Service) ObjectCreateBookmark( } func (s *Service) ObjectBookmarkFetch(req pb.RpcObjectBookmarkFetchRequest) (err error) { - url, err := uri.ProcessURI(req.Url) + url, err := uri.URIManager.ValidateAndNormalizeURI(req.Url) if err != nil { return fmt.Errorf("process uri: %w", err) } diff --git a/core/block/simple/text/text.go b/core/block/simple/text/text.go index 9a28b5281..7f81c0945 100644 --- a/core/block/simple/text/text.go +++ b/core/block/simple/text/text.go @@ -234,7 +234,7 @@ func (t *Text) SetText(text string, marks *model.BlockContentTextMarks) (err err } else { for mI, _ := range marks.Marks { if marks.Marks[mI].Type == model.BlockContentTextMark_Link { - m, err := uri.ProcessURI(marks.Marks[mI].Param) + m, err := uri.URIManager.ValidateAndNormalizeURI(marks.Marks[mI].Param) if err == nil { marks.Marks[mI].Param = m } @@ -700,10 +700,10 @@ func (t *Text) IsEmpty() bool { return false } -func isIncompatibleType(firstType, secondType model.BlockContentTextMarkType ) bool { - if (firstType == model.BlockContentTextMark_Link && secondType == model.BlockContentTextMark_Object) || - (secondType == model.BlockContentTextMark_Link && firstType == model.BlockContentTextMark_Object) { +func isIncompatibleType(firstType, secondType model.BlockContentTextMarkType) bool { + if (firstType == model.BlockContentTextMark_Link && secondType == model.BlockContentTextMark_Object) || + (secondType == model.BlockContentTextMark_Link && firstType == model.BlockContentTextMark_Object) { return true } return false -} \ No newline at end of file +} diff --git a/core/converter/md/md.go b/core/converter/md/md.go index 7452d518d..e6b2620e1 100644 --- a/core/converter/md/md.go +++ b/core/converter/md/md.go @@ -5,7 +5,6 @@ import ( "fmt" "html" "io" - "net/url" "path/filepath" "sort" "strings" @@ -21,6 +20,7 @@ import ( "github.com/anytypeio/go-anytype-middleware/pkg/lib/core" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" "github.com/anytypeio/go-anytype-middleware/util/pbtypes" + "github.com/anytypeio/go-anytype-middleware/util/uri" ) type FileNamer interface { @@ -217,7 +217,7 @@ func (h *MD) renderBookmark(buf writer, in *renderState, b *model.Block) { bm := b.GetBookmark() if bm != nil && bm.Url != "" { buf.WriteString(in.indent) - url, e := url.Parse(bm.Url) + url, e := uri.URIManager.ValidateAndParseURI(bm.Url) if e == nil { fmt.Fprintf(buf, "[%s](%s) \n", escape.MarkdownCharacters(html.EscapeString(bm.Title)), url.String()) } @@ -411,7 +411,7 @@ func (mw *marksWriter) writeMarks(buf writer, pos int) { if start { buf.WriteString("[") } else { - urlP, e := url.Parse(m.Param) + urlP, e := uri.URIManager.ValidateAndParseURI(m.Param) urlS := m.Param if e == nil { urlS = urlP.String() diff --git a/core/linkpreview.go b/core/linkpreview.go index 62fc6c3e4..73cd10e15 100644 --- a/core/linkpreview.go +++ b/core/linkpreview.go @@ -2,7 +2,7 @@ package core import ( "context" - "net/url" + "fmt" "strings" "time" @@ -15,25 +15,16 @@ func (mw *Middleware) LinkPreview(cctx context.Context, req *pb.RpcLinkPreviewRe ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() - urlStr, err := uri.ProcessURI(req.Url) + urlStr, err := uri.URIManager.ValidateAndNormalizeURI(req.Url) if err != nil { return &pb.RpcLinkPreviewResponse{ Error: &pb.RpcLinkPreviewResponseError{ Code: pb.RpcLinkPreviewResponseError_UNKNOWN_ERROR, - Description: err.Error(), - }, - } - } - - u, err := url.Parse(urlStr) - if err != nil { - return &pb.RpcLinkPreviewResponse{ - Error: &pb.RpcLinkPreviewResponseError{ - Code: pb.RpcLinkPreviewResponseError_UNKNOWN_ERROR, - Description: "failed to parse url", + Description: fmt.Sprintf("failed to parse url: %v", err), }, } } + u := uri.URIManager.ParseURI(urlStr) mw.m.RLock() defer mw.m.RUnlock() diff --git a/core/relation/service.go b/core/relation/service.go index 212a4e959..d7aaa6899 100644 --- a/core/relation/service.go +++ b/core/relation/service.go @@ -3,7 +3,6 @@ package relation import ( "errors" "fmt" - "net/url" "strings" "sync" @@ -20,6 +19,7 @@ import ( "github.com/anytypeio/go-anytype-middleware/pkg/lib/logging" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" "github.com/anytypeio/go-anytype-middleware/util/pbtypes" + "github.com/anytypeio/go-anytype-middleware/util/uri" ) const CName = "relation" @@ -379,7 +379,7 @@ func (s *service) ValidateFormat(key string, v *types.Value) error { return fmt.Errorf("incorrect type: %T instead of string", v.Kind) } - _, err := url.Parse(strings.TrimSpace(v.GetStringValue())) + err := uri.URIManager.Validate(strings.TrimSpace(v.GetStringValue())) if err != nil { return fmt.Errorf("failed to parse URL: %s", err.Error()) } diff --git a/util/linkpreview/linkpreview.go b/util/linkpreview/linkpreview.go index 7798dac68..cf85965bc 100644 --- a/util/linkpreview/linkpreview.go +++ b/util/linkpreview/linkpreview.go @@ -5,7 +5,6 @@ import ( "github.com/anytypeio/go-anytype-middleware/util/text" "io" "net/http" - "net/url" "path/filepath" "strings" "unicode/utf8" @@ -87,7 +86,7 @@ func (l *linkPreview) convertOGToInfo(fetchUrl string, og *opengraph.OpenGraph) } if len(og.Image) != 0 { - url, err := uri.ProcessURI(og.Image[0].URL) + url, err := uri.URIManager.ValidateAndNormalizeURI(og.Image[0].URL) if err == nil { i.ImageUrl = url } @@ -127,7 +126,7 @@ func (l *linkPreview) makeNonHtml(fetchUrl string, resp *http.Response) (i model } else { i.Type = model.LinkPreview_Unknown } - pUrl, e := url.Parse(fetchUrl) + pUrl, e := uri.URIManager.ValidateAndParseURI(fetchUrl) if e == nil { pUrl.Path = "favicon.ico" pUrl.RawQuery = "" diff --git a/util/unsplash/unsplash.go b/util/unsplash/unsplash.go index 3fef7624e..90f55f490 100644 --- a/util/unsplash/unsplash.go +++ b/util/unsplash/unsplash.go @@ -8,6 +8,7 @@ import ( "github.com/anytypeio/go-anytype-middleware/pkg/lib/logging" "github.com/anytypeio/go-anytype-middleware/util/ocache" "github.com/anytypeio/go-anytype-middleware/util/pbtypes" + "github.com/anytypeio/go-anytype-middleware/util/uri" "github.com/dsoprea/go-exif/v3" jpegstructure "github.com/dsoprea/go-jpeg-image-structure/v2" "github.com/hbagdi/go-unsplash/unsplash" @@ -15,7 +16,6 @@ import ( "io" "io/ioutil" "net/http" - "net/url" "os" "path/filepath" "regexp" @@ -111,7 +111,7 @@ func newFromPhoto(v unsplash.Photo) (Result, error) { fUrl := v.Urls.Regular.String() // hack to have full hd instead of 1080w, // in case unsplash will change the URL format it will not break things - u, _ := url.Parse(fUrl) + u := uri.URIManager.ParseURI(fUrl) if u != nil { if q := u.Query(); q.Get("w") != "" { q.Set("w", "1920") diff --git a/util/uri/uri.go b/util/uri/uri.go index d9739fb44..b0e3ffbe3 100644 --- a/util/uri/uri.go +++ b/util/uri/uri.go @@ -2,11 +2,10 @@ package uri import ( "fmt" + "net/url" "os" "regexp" "strings" - - "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" ) var ( @@ -19,63 +18,76 @@ var ( winFilepathPrefixRegex = regexp.MustCompile(`^[a-zA-Z]:[\\\/]`) ) -func ValidateEmail(email string) bool { - if len(email) == 0 { - return false - } - - return noPrefixEmailRegexp.MatchString(email) +type Validator interface { + Validate(string) error } -func ValidatePhone(phone string) bool { - if len(phone) == 0 { - return false - } - - return noPrefixTelRegexp.MatchString(phone) +type Parser interface { + ParseURI(string) *url.URL } -// ProcessURI tries to verify the web URI and return the normalized URI -func ProcessURI(url string) (urlOut string, err error) { - if len(url) == 0 { - return url, fmt.Errorf("url is empty") - - } else if noPrefixEmailRegexp.MatchString(url) { - return "mailto:" + url, nil - - } else if noPrefixTelRegexp.MatchString(url) { - return "tel:" + url, nil - - } else if winFilepathPrefixRegex.MatchString(url) { - return "", fmt.Errorf("filepath not supported") - - } else if strings.HasPrefix(url, string(os.PathSeparator)) || strings.HasPrefix(url, ".") { - return "", fmt.Errorf("filepath not supported") - - } else if noPrefixHttpRegex.MatchString(url) { - return "http://" + url, nil - - } else if haveUriSchemeRegex.MatchString(url) { - return url, nil - } - - return url, fmt.Errorf("not a uri") +type Normalizer interface { + NormalizeURI(string) string } -func ProcessAllURI(blocks []*model.Block) []*model.Block { - for bI, _ := range blocks { - if blocks[bI].GetText() != nil && blocks[bI].GetText().Marks != nil && len(blocks[bI].GetText().Marks.Marks) > 0 { - marks := blocks[bI].GetText().Marks.Marks +type Manager struct { + Validator + Parser + Normalizer +} - for mI, _ := range marks { - if marks[mI].Type == model.BlockContentTextMark_Link { - marks[mI].Param, _ = ProcessURI(marks[mI].Param) - } - } +var URIManager Manager - blocks[bI].GetText().Marks.Marks = marks - } +func (m Manager) Validate(uri string) error { + uri = strings.TrimSpace(uri) + + if len(uri) == 0 { + return fmt.Errorf("url is empty") + } else if winFilepathPrefixRegex.MatchString(uri) { + return fmt.Errorf("filepath not supported") + } else if strings.HasPrefix(uri, string(os.PathSeparator)) || strings.HasPrefix(uri, ".") { + return fmt.Errorf("filepath not supported") } - return blocks + _, err := url.Parse(uri) + return err +} + +func (m Manager) ParseURI(uri string) *url.URL { + u, _ := url.Parse(uri) + return u +} + +func (m Manager) NormalizeURI(uri string) string { + if noPrefixEmailRegexp.MatchString(uri) { + return "mailto:" + uri + } else if noPrefixTelRegexp.MatchString(uri) { + return "tel:" + uri + } else if noPrefixHttpRegex.MatchString(uri) { + return "http://" + uri + } + return uri +} + +func (m Manager) ValidateAndParseURI(uri string) (*url.URL, error) { + uri = strings.TrimSpace(uri) + + if len(uri) == 0 { + return nil, fmt.Errorf("url is empty") + } else if winFilepathPrefixRegex.MatchString(uri) { + return nil, fmt.Errorf("filepath not supported") + } else if strings.HasPrefix(uri, string(os.PathSeparator)) || strings.HasPrefix(uri, ".") { + return nil, fmt.Errorf("filepath not supported") + } + + _, err := url.Parse(uri) + return nil, err +} + +func (m Manager) ValidateAndNormalizeURI(uri string) (string, error) { + err := m.Validate(uri) + if err != nil { + return "", err + } + return m.NormalizeURI(uri), nil } From f559fde9be2620c815c7bd407b610512da7411e8 Mon Sep 17 00:00:00 2001 From: kirillston Date: Wed, 21 Dec 2022 11:57:20 +0100 Subject: [PATCH 31/68] GO-677 Exclude interfaces and struct defs --- core/block/editor/bookmark/bookmark.go | 2 +- core/block/editor/file/uploader.go | 2 +- core/block/editor/import/import.go | 2 +- core/block/import/markdown/blockconverter.go | 2 +- core/block/service.go | 4 +-- core/block/simple/text/text.go | 2 +- core/converter/md/md.go | 4 +-- core/linkpreview.go | 4 +-- core/relation/service.go | 2 +- util/linkpreview/linkpreview.go | 4 +-- util/unsplash/unsplash.go | 2 +- util/uri/uri.go | 34 ++++---------------- 12 files changed, 22 insertions(+), 42 deletions(-) diff --git a/core/block/editor/bookmark/bookmark.go b/core/block/editor/bookmark/bookmark.go index b0e3f408c..0e12ab3a3 100644 --- a/core/block/editor/bookmark/bookmark.go +++ b/core/block/editor/bookmark/bookmark.go @@ -61,7 +61,7 @@ func (b *sbookmark) fetch(s *state.State, id, url string, isSync bool) (err erro if b == nil { return smartblock.ErrSimpleBlockNotFound } - url, err = uri.URIManager.ValidateAndNormalizeURI(url) + url, err = uri.ValidateAndNormalizeURI(url) if err != nil { // Do nothing } diff --git a/core/block/editor/file/uploader.go b/core/block/editor/file/uploader.go index a2253e395..b0de714b4 100644 --- a/core/block/editor/file/uploader.go +++ b/core/block/editor/file/uploader.go @@ -175,7 +175,7 @@ func (u *uploader) AddOptions(options ...files.AddOption) Uploader { } func (u *uploader) SetUrl(url string) Uploader { - url = uri.URIManager.NormalizeURI(url) + url = uri.NormalizeURI(url) u.name = strings.Split(filepath.Base(url), "?")[0] u.getReader = func(ctx context.Context) (*fileReader, error) { req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) diff --git a/core/block/editor/import/import.go b/core/block/editor/import/import.go index eaad7498d..6941c956c 100644 --- a/core/block/editor/import/import.go +++ b/core/block/editor/import/import.go @@ -670,7 +670,7 @@ func (imp *importImpl) convertTextToPageLink(block *model.Block) { } func (imp *importImpl) convertTextToBookmark(block *model.Block) { - if err := uri.URIManager.Validate(block.GetText().Marks.Marks[0].Param); err != nil { + if err := uri.ValidateURI(block.GetText().Marks.Marks[0].Param); err != nil { return } diff --git a/core/block/import/markdown/blockconverter.go b/core/block/import/markdown/blockconverter.go index a7f56f2b3..b89611b54 100644 --- a/core/block/import/markdown/blockconverter.go +++ b/core/block/import/markdown/blockconverter.go @@ -258,7 +258,7 @@ func (m *mdConverter) convertTextToPageLink(block *model.Block) { } func (m *mdConverter) convertTextToBookmark(block *model.Block) { - if err := uri.URIManager.Validate(block.GetText().Marks.Marks[0].Param); err != nil { + if err := uri.ValidateURI(block.GetText().Marks.Marks[0].Param); err != nil { return } diff --git a/core/block/service.go b/core/block/service.go index 935ebe885..2080ba951 100644 --- a/core/block/service.go +++ b/core/block/service.go @@ -1593,7 +1593,7 @@ func (s *Service) fetchBookmarkContent(url string) bookmarksvc.ContentFuture { func (s *Service) ObjectCreateBookmark( req pb.RpcObjectCreateBookmarkRequest, ) (objectId string, newDetails *types.Struct, err error) { - u, err := uri.URIManager.ValidateAndNormalizeURI(pbtypes.GetString(req.Details, bundle.RelationKeySource.String())) + u, err := uri.ValidateAndNormalizeURI(pbtypes.GetString(req.Details, bundle.RelationKeySource.String())) if err != nil { return "", nil, fmt.Errorf("process uri: %w", err) } @@ -1602,7 +1602,7 @@ func (s *Service) ObjectCreateBookmark( } func (s *Service) ObjectBookmarkFetch(req pb.RpcObjectBookmarkFetchRequest) (err error) { - url, err := uri.URIManager.ValidateAndNormalizeURI(req.Url) + url, err := uri.ValidateAndNormalizeURI(req.Url) if err != nil { return fmt.Errorf("process uri: %w", err) } diff --git a/core/block/simple/text/text.go b/core/block/simple/text/text.go index 7f81c0945..17c5abf6c 100644 --- a/core/block/simple/text/text.go +++ b/core/block/simple/text/text.go @@ -234,7 +234,7 @@ func (t *Text) SetText(text string, marks *model.BlockContentTextMarks) (err err } else { for mI, _ := range marks.Marks { if marks.Marks[mI].Type == model.BlockContentTextMark_Link { - m, err := uri.URIManager.ValidateAndNormalizeURI(marks.Marks[mI].Param) + m, err := uri.ValidateAndNormalizeURI(marks.Marks[mI].Param) if err == nil { marks.Marks[mI].Param = m } diff --git a/core/converter/md/md.go b/core/converter/md/md.go index e6b2620e1..ec5593cac 100644 --- a/core/converter/md/md.go +++ b/core/converter/md/md.go @@ -217,7 +217,7 @@ func (h *MD) renderBookmark(buf writer, in *renderState, b *model.Block) { bm := b.GetBookmark() if bm != nil && bm.Url != "" { buf.WriteString(in.indent) - url, e := uri.URIManager.ValidateAndParseURI(bm.Url) + url, e := uri.ValidateAndParseURI(bm.Url) if e == nil { fmt.Fprintf(buf, "[%s](%s) \n", escape.MarkdownCharacters(html.EscapeString(bm.Title)), url.String()) } @@ -411,7 +411,7 @@ func (mw *marksWriter) writeMarks(buf writer, pos int) { if start { buf.WriteString("[") } else { - urlP, e := uri.URIManager.ValidateAndParseURI(m.Param) + urlP, e := uri.ValidateAndParseURI(m.Param) urlS := m.Param if e == nil { urlS = urlP.String() diff --git a/core/linkpreview.go b/core/linkpreview.go index 73cd10e15..85a98bb1e 100644 --- a/core/linkpreview.go +++ b/core/linkpreview.go @@ -15,7 +15,7 @@ func (mw *Middleware) LinkPreview(cctx context.Context, req *pb.RpcLinkPreviewRe ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() - urlStr, err := uri.URIManager.ValidateAndNormalizeURI(req.Url) + urlStr, err := uri.ValidateAndNormalizeURI(req.Url) if err != nil { return &pb.RpcLinkPreviewResponse{ Error: &pb.RpcLinkPreviewResponseError{ @@ -24,7 +24,7 @@ func (mw *Middleware) LinkPreview(cctx context.Context, req *pb.RpcLinkPreviewRe }, } } - u := uri.URIManager.ParseURI(urlStr) + u := uri.ParseURI(urlStr) mw.m.RLock() defer mw.m.RUnlock() diff --git a/core/relation/service.go b/core/relation/service.go index d7aaa6899..e3ea2b477 100644 --- a/core/relation/service.go +++ b/core/relation/service.go @@ -379,7 +379,7 @@ func (s *service) ValidateFormat(key string, v *types.Value) error { return fmt.Errorf("incorrect type: %T instead of string", v.Kind) } - err := uri.URIManager.Validate(strings.TrimSpace(v.GetStringValue())) + err := uri.ValidateURI(strings.TrimSpace(v.GetStringValue())) if err != nil { return fmt.Errorf("failed to parse URL: %s", err.Error()) } diff --git a/util/linkpreview/linkpreview.go b/util/linkpreview/linkpreview.go index cf85965bc..01019d2ae 100644 --- a/util/linkpreview/linkpreview.go +++ b/util/linkpreview/linkpreview.go @@ -86,7 +86,7 @@ func (l *linkPreview) convertOGToInfo(fetchUrl string, og *opengraph.OpenGraph) } if len(og.Image) != 0 { - url, err := uri.URIManager.ValidateAndNormalizeURI(og.Image[0].URL) + url, err := uri.ValidateAndNormalizeURI(og.Image[0].URL) if err == nil { i.ImageUrl = url } @@ -126,7 +126,7 @@ func (l *linkPreview) makeNonHtml(fetchUrl string, resp *http.Response) (i model } else { i.Type = model.LinkPreview_Unknown } - pUrl, e := uri.URIManager.ValidateAndParseURI(fetchUrl) + pUrl, e := uri.ValidateAndParseURI(fetchUrl) if e == nil { pUrl.Path = "favicon.ico" pUrl.RawQuery = "" diff --git a/util/unsplash/unsplash.go b/util/unsplash/unsplash.go index 90f55f490..2209ef409 100644 --- a/util/unsplash/unsplash.go +++ b/util/unsplash/unsplash.go @@ -111,7 +111,7 @@ func newFromPhoto(v unsplash.Photo) (Result, error) { fUrl := v.Urls.Regular.String() // hack to have full hd instead of 1080w, // in case unsplash will change the URL format it will not break things - u := uri.URIManager.ParseURI(fUrl) + u := uri.ParseURI(fUrl) if u != nil { if q := u.Query(); q.Get("w") != "" { q.Set("w", "1920") diff --git a/util/uri/uri.go b/util/uri/uri.go index b0e3ffbe3..3200db505 100644 --- a/util/uri/uri.go +++ b/util/uri/uri.go @@ -18,27 +18,7 @@ var ( winFilepathPrefixRegex = regexp.MustCompile(`^[a-zA-Z]:[\\\/]`) ) -type Validator interface { - Validate(string) error -} - -type Parser interface { - ParseURI(string) *url.URL -} - -type Normalizer interface { - NormalizeURI(string) string -} - -type Manager struct { - Validator - Parser - Normalizer -} - -var URIManager Manager - -func (m Manager) Validate(uri string) error { +func ValidateURI(uri string) error { uri = strings.TrimSpace(uri) if len(uri) == 0 { @@ -53,12 +33,12 @@ func (m Manager) Validate(uri string) error { return err } -func (m Manager) ParseURI(uri string) *url.URL { +func ParseURI(uri string) *url.URL { u, _ := url.Parse(uri) return u } -func (m Manager) NormalizeURI(uri string) string { +func NormalizeURI(uri string) string { if noPrefixEmailRegexp.MatchString(uri) { return "mailto:" + uri } else if noPrefixTelRegexp.MatchString(uri) { @@ -69,7 +49,7 @@ func (m Manager) NormalizeURI(uri string) string { return uri } -func (m Manager) ValidateAndParseURI(uri string) (*url.URL, error) { +func ValidateAndParseURI(uri string) (*url.URL, error) { uri = strings.TrimSpace(uri) if len(uri) == 0 { @@ -84,10 +64,10 @@ func (m Manager) ValidateAndParseURI(uri string) (*url.URL, error) { return nil, err } -func (m Manager) ValidateAndNormalizeURI(uri string) (string, error) { - err := m.Validate(uri) +func ValidateAndNormalizeURI(uri string) (string, error) { + err := ValidateURI(uri) if err != nil { return "", err } - return m.NormalizeURI(uri), nil + return NormalizeURI(uri), nil } From 5a01d5495a28c4376a960738bdefb525b71b0dc8 Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Wed, 21 Dec 2022 14:55:32 +0300 Subject: [PATCH 32/68] GO-512: update relations if exists Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/objectcreator.go | 2 +- core/block/import/objectupdater.go | 2 +- core/block/import/relationcreator.go | 40 +++++++++++++++------------- core/block/import/types.go | 2 +- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/core/block/import/objectcreator.go b/core/block/import/objectcreator.go index 01769f49c..6c8ffa345 100644 --- a/core/block/import/objectcreator.go +++ b/core/block/import/objectcreator.go @@ -113,7 +113,7 @@ func (oc *ObjectCreator) Create(ctx *session.Context, } var oldRelationBlocksToNew map[string]*model.Block - filesToDelete, oldRelationBlocksToNew, err = oc.relationCreator.UpdateRelations(ctx, snapshot, pageID, relations, nil) + filesToDelete, oldRelationBlocksToNew, err = oc.relationCreator.CreateRelations(ctx, snapshot, pageID, relations, nil) if err != nil { return nil, fmt.Errorf("relation create '%s'", err) diff --git a/core/block/import/objectupdater.go b/core/block/import/objectupdater.go index 580881738..e225f2e50 100644 --- a/core/block/import/objectupdater.go +++ b/core/block/import/objectupdater.go @@ -131,7 +131,7 @@ func (ou *ObjectUpdater) update(ctx *session.Context, return nil, err } var err error - filesToDelete, oldRelationBlockToNew, err = ou.relationCreator.UpdateRelations(ctx, snapshot, id, relations, nil) + filesToDelete, oldRelationBlockToNew, err = ou.relationCreator.CreateRelations(ctx, snapshot, id, relations, nil) if err != nil { return nil, err } diff --git a/core/block/import/relationcreator.go b/core/block/import/relationcreator.go index 03de61a70..215e48723 100644 --- a/core/block/import/relationcreator.go +++ b/core/block/import/relationcreator.go @@ -46,7 +46,7 @@ func NewRelationCreator(service *block.Service, store filestore.FileStore, core } } -func (rc *RelationService) UpdateRelations(ctx *session.Context, +func (rc *RelationService) CreateRelations(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, pageID string, relations []*converter.Relation, @@ -91,10 +91,11 @@ func (rc *RelationService) UpdateRelations(ctx *session.Context, notExistedRelations = append(notExistedRelations, r) } - filesToDelete, oldRelationBlockToNew, err := rc.update(ctx, snapshot, existedRelations, pageID) + filesToDelete, oldRelationBlockToNew, failedRelations, err := rc.update(ctx, snapshot, existedRelations, pageID) if err != nil { return nil, nil, err } + notExistedRelations = append(notExistedRelations, failedRelations...) createfilesToDelete, relationsBlocks, err := rc.create(ctx, snapshot, notExistedRelations, pageID) if err != nil { return nil, nil, err @@ -215,21 +216,21 @@ func (rc *RelationService) create(ctx *session.Context, func (rc *RelationService) update(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, relations map[string]*converter.Relation, - pageID string) ([]string, map[string]*model.Block, error) { + pageID string) ([]string, map[string]*model.Block, []*converter.Relation, error) { var ( err error filesToDelete = make([]string, 0) oldRelationBlockToNew = make(map[string]*model.Block, 0) - setDetailsRequest = make([]*pb.RpcObjectSetDetailsDetail, 0) + failedRelations = make([]*converter.Relation, 0) ) - ids := make([]string, 0, len(relations)) - - if err = rc.service.AddExtraRelations(ctx, pageID, ids); err != nil { - log.Errorf("add extra relation %s", err) - } - + // to get failed relations and fallback them to create function for key, r := range relations { + if err = rc.service.AddExtraRelations(ctx, pageID, []string{key}); err != nil { + log.Errorf("add extra relation %s", err) + failedRelations = append(failedRelations, r) + continue + } if snapshot.Details != nil && snapshot.Details.Fields != nil { if snapshot.Details.Fields[r.Name].GetListValue() != nil { rc.handleListValue(ctx, snapshot, r, key) @@ -238,6 +239,7 @@ func (rc *RelationService) update(ctx *session.Context, filesToDelete = append(filesToDelete, rc.handleFileRelation(ctx, snapshot, r.Name)...) } } + setDetailsRequest := make([]*pb.RpcObjectSetDetailsDetail, 0) setDetailsRequest = append(setDetailsRequest, &pb.RpcObjectSetDetailsDetail{ Key: key, Value: snapshot.Details.Fields[r.Name], @@ -248,14 +250,14 @@ func (rc *RelationService) update(ctx *session.Context, oldRelationBlockToNew[original.GetId()] = new } } - } - - err = rc.service.SetDetails(ctx, pb.RpcObjectSetDetailsRequest{ - ContextId: pageID, - Details: setDetailsRequest, - }) - if err != nil { - log.Errorf("set details %s", err) + err = rc.service.SetDetails(ctx, pb.RpcObjectSetDetailsRequest{ + ContextId: pageID, + Details: setDetailsRequest, + }) + if err != nil { + log.Errorf("set details %s", err) + failedRelations = append(failedRelations, r) + } } if ftd, err := rc.handleCoverRelation(ctx, snapshot, pageID); err != nil { @@ -264,7 +266,7 @@ func (rc *RelationService) update(ctx *session.Context, filesToDelete = append(filesToDelete, ftd...) } - return filesToDelete, oldRelationBlockToNew, nil + return filesToDelete, oldRelationBlockToNew, failedRelations, nil } diff --git a/core/block/import/types.go b/core/block/import/types.go index f42a88759..010729c78 100644 --- a/core/block/import/types.go +++ b/core/block/import/types.go @@ -43,5 +43,5 @@ type RelationCreator interface { //nolint: lll ReplaceRelationBlock(ctx *session.Context, st *state.State, oldRelationBlocksToNew map[string]*model.Block, pageID string) //nolint: lll - UpdateRelations(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, pageID string, relations []*converter.Relation, relationsLinks pbtypes.RelationLinks) ([]string, map[string]*model.Block, error) + CreateRelations(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, pageID string, relations []*converter.Relation, relationsLinks pbtypes.RelationLinks) ([]string, map[string]*model.Block, error) } From 1194b4cba428950e1a5e059df7aff6b198498b6e Mon Sep 17 00:00:00 2001 From: kirillston Date: Wed, 21 Dec 2022 12:58:33 +0100 Subject: [PATCH 33/68] GO-677 Add unit tests --- util/uri/uri.go | 14 ++++-- util/uri/uri_test.go | 111 ++++++++++++++++++++++++------------------- 2 files changed, 70 insertions(+), 55 deletions(-) diff --git a/util/uri/uri.go b/util/uri/uri.go index 3200db505..853b38476 100644 --- a/util/uri/uri.go +++ b/util/uri/uri.go @@ -16,6 +16,10 @@ var ( noPrefixHttpRegex = regexp.MustCompile(`^[\pL\d.-]+(?:\.[\pL\\d.-]+)+[\pL\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.\/\d]+$`) haveUriSchemeRegex = regexp.MustCompile(`^([a-zA-Z][A-Za-z0-9+.-]*):[\S]+`) winFilepathPrefixRegex = regexp.MustCompile(`^[a-zA-Z]:[\\\/]`) + + // errors + urlEmptyError = fmt.Errorf("url is empty") + filepathNotSupportedError = fmt.Errorf("filepath not supported") ) func ValidateURI(uri string) error { @@ -53,15 +57,15 @@ func ValidateAndParseURI(uri string) (*url.URL, error) { uri = strings.TrimSpace(uri) if len(uri) == 0 { - return nil, fmt.Errorf("url is empty") + return nil, urlEmptyError } else if winFilepathPrefixRegex.MatchString(uri) { - return nil, fmt.Errorf("filepath not supported") + return nil, filepathNotSupportedError } else if strings.HasPrefix(uri, string(os.PathSeparator)) || strings.HasPrefix(uri, ".") { - return nil, fmt.Errorf("filepath not supported") + return nil, filepathNotSupportedError } - _, err := url.Parse(uri) - return nil, err + u, err := url.Parse(uri) + return u, err } func ValidateAndNormalizeURI(uri string) (string, error) { diff --git a/util/uri/uri_test.go b/util/uri/uri_test.go index 545f74ec6..77086e5f0 100644 --- a/util/uri/uri_test.go +++ b/util/uri/uri_test.go @@ -6,95 +6,106 @@ import ( "github.com/stretchr/testify/assert" ) -func TestURI_ProcessURI(t *testing.T) { +func TestURI_NormalizeURI(t *testing.T) { t.Run("should process mailto uri", func(t *testing.T) { uri := "john@doe.com" - processedUri, err := ProcessURI(uri) + processedUri := NormalizeURI(uri) assert.Equal(t, "mailto:"+uri, processedUri) - assert.NoError(t, err) }) t.Run("should process tel uri", func(t *testing.T) { uri := "+491234567" - processedUri, err := ProcessURI(uri) + processedUri := NormalizeURI(uri) assert.Equal(t, "tel:"+uri, processedUri) - assert.NoError(t, err) }) t.Run("should process url", func(t *testing.T) { uri := "website.com" - processedUri, err := ProcessURI(uri) + processedUri := NormalizeURI(uri) assert.Equal(t, "http://"+uri, processedUri) - assert.NoError(t, err) }) t.Run("should process url with additional content 1", func(t *testing.T) { uri := "website.com/123/456" - processedUri, err := ProcessURI(uri) + processedUri := NormalizeURI(uri) assert.Equal(t, "http://"+uri, processedUri) - assert.NoError(t, err) }) t.Run("should process url with additional content 2", func(t *testing.T) { uri := "website.com?content=11" - processedUri, err := ProcessURI(uri) + processedUri := NormalizeURI(uri) assert.Equal(t, "http://"+uri, processedUri) - assert.NoError(t, err) }) t.Run("should process url with additional content and numbers", func(t *testing.T) { uri := "webs1te.com/123/456" - processedUri, err := ProcessURI(uri) + processedUri := NormalizeURI(uri) assert.Equal(t, "http://"+uri, processedUri) - assert.NoError(t, err) }) - t.Run("should return error if it is not a uri", func(t *testing.T) { - uri := "website" - processedUri, err := ProcessURI(uri) - assert.Equal(t, uri, processedUri) - assert.Error(t, err) - }) - - t.Run("should not process url with http://", func(t *testing.T) { + t.Run("should not modify url with http://", func(t *testing.T) { uri := "http://website.com" - processedUri, err := ProcessURI(uri) + processedUri := NormalizeURI(uri) assert.Equal(t, uri, processedUri) - assert.NoError(t, err) }) - t.Run("should not process url with https://", func(t *testing.T) { + t.Run("should not modify url with https://", func(t *testing.T) { uri := "https://website.com" - processedUri, err := ProcessURI(uri) + processedUri := NormalizeURI(uri) assert.Equal(t, uri, processedUri) - assert.NoError(t, err) }) - t.Run("should not process non url/tel/mailto uri", func(t *testing.T) { + t.Run("should not modify non url/tel/mailto uri", func(t *testing.T) { uri := "type:content" - processedUri, err := ProcessURI(uri) + processedUri := NormalizeURI(uri) assert.Equal(t, uri, processedUri) - assert.NoError(t, err) - }) - - t.Run("should gives error on win filepath", func(t *testing.T) { - uri := "D://folder//file.txt" - processedUri, err := ProcessURI(uri) - assert.Equal(t, "", processedUri) - assert.NotNil(t, err) - }) - - t.Run("should gives error on unix abs filepath", func(t *testing.T) { - uri := "/folder/file.txt" - processedUri, err := ProcessURI(uri) - assert.Equal(t, "", processedUri) - assert.NotNil(t, err) - }) - - t.Run("should gives error on unix rel filepath", func(t *testing.T) { - uri := "../folder/file.txt" - processedUri, err := ProcessURI(uri) - assert.Equal(t, "", processedUri) - assert.NotNil(t, err) + }) +} + +func TestURI_ValidateURI(t *testing.T) { + t.Run("should return error on empty string", func(t *testing.T) { + uri := "" + err := ValidateURI(uri) + assert.Error(t, err) + assert.Equal(t, err, urlEmptyError) + }) + + t.Run("should return error on win filepath", func(t *testing.T) { + uri := "D://folder//file.txt" + err := ValidateURI(uri) + assert.Error(t, err) + assert.Equal(t, err, filepathNotSupportedError) + }) + + t.Run("should return error on unix abs filepath", func(t *testing.T) { + uri := "/folder/file.txt" + err := ValidateURI(uri) + assert.Error(t, err) + assert.Equal(t, err, filepathNotSupportedError) + }) + + t.Run("should return error on unix rel filepath", func(t *testing.T) { + uri := "../folder/file.txt" + err := ValidateURI(uri) + assert.Error(t, err) + assert.Equal(t, err, filepathNotSupportedError) + }) + + t.Run("should not return error if url is surrounded by whitespaces", func(t *testing.T) { + uri := " \t\n\v\r\f https://brutal-site.org \t\n\v\r\f " + err := ValidateURI(uri) + assert.NoError(t, err) + }) + + t.Run("should not return error if url has spaces inside", func(t *testing.T) { + uri := "I do love enough space.org" + err := ValidateURI(uri) + assert.NoError(t, err) + }) + + t.Run("should not return error if url contains emojis", func(t *testing.T) { + uri := "merry 🎄 and a happy 🎁.kevin.blog" + err := ValidateURI(uri) + assert.NoError(t, err) }) } From 7a9a9f43454e9bf46ede7008f561c89620ac315e Mon Sep 17 00:00:00 2001 From: kirillston Date: Wed, 21 Dec 2022 14:02:01 +0100 Subject: [PATCH 34/68] GO-677 fix lint --- util/linkpreview/linkpreview.go | 8 +++--- util/uri/uri.go | 31 ++++++++++++++--------- util/uri/uri_test.go | 44 ++++++++++++++++----------------- 3 files changed, 45 insertions(+), 38 deletions(-) diff --git a/util/linkpreview/linkpreview.go b/util/linkpreview/linkpreview.go index 01019d2ae..3b3436b4c 100644 --- a/util/linkpreview/linkpreview.go +++ b/util/linkpreview/linkpreview.go @@ -126,11 +126,11 @@ func (l *linkPreview) makeNonHtml(fetchUrl string, resp *http.Response) (i model } else { i.Type = model.LinkPreview_Unknown } - pUrl, e := uri.ValidateAndParseURI(fetchUrl) + pURL, e := uri.ValidateAndParseURI(fetchUrl) if e == nil { - pUrl.Path = "favicon.ico" - pUrl.RawQuery = "" - i.FaviconUrl = pUrl.String() + pURL.Path = "favicon.ico" + pURL.RawQuery = "" + i.FaviconUrl = pURL.String() } return } diff --git a/util/uri/uri.go b/util/uri/uri.go index 853b38476..20550274f 100644 --- a/util/uri/uri.go +++ b/util/uri/uri.go @@ -18,8 +18,8 @@ var ( winFilepathPrefixRegex = regexp.MustCompile(`^[a-zA-Z]:[\\\/]`) // errors - urlEmptyError = fmt.Errorf("url is empty") - filepathNotSupportedError = fmt.Errorf("filepath not supported") + errUrlEmpty = fmt.Errorf("url is empty") + errFilepathNotSupported = fmt.Errorf("filepath not supported") ) func ValidateURI(uri string) error { @@ -38,16 +38,20 @@ func ValidateURI(uri string) error { } func ParseURI(uri string) *url.URL { - u, _ := url.Parse(uri) + u, err := url.Parse(uri) + if err != nil { + // do nothing as validation is implemented in ValidateAndParseURI + } return u } func NormalizeURI(uri string) string { - if noPrefixEmailRegexp.MatchString(uri) { + switch { + case noPrefixEmailRegexp.MatchString(uri): return "mailto:" + uri - } else if noPrefixTelRegexp.MatchString(uri) { + case noPrefixTelRegexp.MatchString(uri): return "tel:" + uri - } else if noPrefixHttpRegex.MatchString(uri) { + case noPrefixHttpRegex.MatchString(uri): return "http://" + uri } return uri @@ -56,12 +60,15 @@ func NormalizeURI(uri string) string { func ValidateAndParseURI(uri string) (*url.URL, error) { uri = strings.TrimSpace(uri) - if len(uri) == 0 { - return nil, urlEmptyError - } else if winFilepathPrefixRegex.MatchString(uri) { - return nil, filepathNotSupportedError - } else if strings.HasPrefix(uri, string(os.PathSeparator)) || strings.HasPrefix(uri, ".") { - return nil, filepathNotSupportedError + switch { + case len(uri) == 0: + return nil, errUrlEmpty + case winFilepathPrefixRegex.MatchString(uri): + return nil, errFilepathNotSupported + case strings.HasPrefix(uri, string(os.PathSeparator)): + return nil, errFilepathNotSupported + case strings.HasPrefix(uri, "."): + return nil, errFilepathNotSupported } u, err := url.Parse(uri) diff --git a/util/uri/uri_test.go b/util/uri/uri_test.go index 77086e5f0..9c693ce53 100644 --- a/util/uri/uri_test.go +++ b/util/uri/uri_test.go @@ -9,56 +9,56 @@ import ( func TestURI_NormalizeURI(t *testing.T) { t.Run("should process mailto uri", func(t *testing.T) { uri := "john@doe.com" - processedUri := NormalizeURI(uri) - assert.Equal(t, "mailto:"+uri, processedUri) + processedURI := NormalizeURI(uri) + assert.Equal(t, "mailto:"+uri, processedURI) }) t.Run("should process tel uri", func(t *testing.T) { uri := "+491234567" - processedUri := NormalizeURI(uri) - assert.Equal(t, "tel:"+uri, processedUri) + processedURI := NormalizeURI(uri) + assert.Equal(t, "tel:"+uri, processedURI) }) t.Run("should process url", func(t *testing.T) { uri := "website.com" - processedUri := NormalizeURI(uri) - assert.Equal(t, "http://"+uri, processedUri) + processedURI := NormalizeURI(uri) + assert.Equal(t, "http://"+uri, processedURI) }) t.Run("should process url with additional content 1", func(t *testing.T) { uri := "website.com/123/456" - processedUri := NormalizeURI(uri) - assert.Equal(t, "http://"+uri, processedUri) + processedURI := NormalizeURI(uri) + assert.Equal(t, "http://"+uri, processedURI) }) t.Run("should process url with additional content 2", func(t *testing.T) { uri := "website.com?content=11" - processedUri := NormalizeURI(uri) - assert.Equal(t, "http://"+uri, processedUri) + processedURI := NormalizeURI(uri) + assert.Equal(t, "http://"+uri, processedURI) }) t.Run("should process url with additional content and numbers", func(t *testing.T) { uri := "webs1te.com/123/456" - processedUri := NormalizeURI(uri) - assert.Equal(t, "http://"+uri, processedUri) + processedURI := NormalizeURI(uri) + assert.Equal(t, "http://"+uri, processedURI) }) t.Run("should not modify url with http://", func(t *testing.T) { uri := "http://website.com" - processedUri := NormalizeURI(uri) - assert.Equal(t, uri, processedUri) + processedURI := NormalizeURI(uri) + assert.Equal(t, uri, processedURI) }) t.Run("should not modify url with https://", func(t *testing.T) { uri := "https://website.com" - processedUri := NormalizeURI(uri) - assert.Equal(t, uri, processedUri) + processedURI := NormalizeURI(uri) + assert.Equal(t, uri, processedURI) }) t.Run("should not modify non url/tel/mailto uri", func(t *testing.T) { uri := "type:content" - processedUri := NormalizeURI(uri) - assert.Equal(t, uri, processedUri) + processedURI := NormalizeURI(uri) + assert.Equal(t, uri, processedURI) }) } @@ -67,28 +67,28 @@ func TestURI_ValidateURI(t *testing.T) { uri := "" err := ValidateURI(uri) assert.Error(t, err) - assert.Equal(t, err, urlEmptyError) + assert.Equal(t, err, errUrlEmpty) }) t.Run("should return error on win filepath", func(t *testing.T) { uri := "D://folder//file.txt" err := ValidateURI(uri) assert.Error(t, err) - assert.Equal(t, err, filepathNotSupportedError) + assert.Equal(t, err, errFilepathNotSupported) }) t.Run("should return error on unix abs filepath", func(t *testing.T) { uri := "/folder/file.txt" err := ValidateURI(uri) assert.Error(t, err) - assert.Equal(t, err, filepathNotSupportedError) + assert.Equal(t, err, errFilepathNotSupported) }) t.Run("should return error on unix rel filepath", func(t *testing.T) { uri := "../folder/file.txt" err := ValidateURI(uri) assert.Error(t, err) - assert.Equal(t, err, filepathNotSupportedError) + assert.Equal(t, err, errFilepathNotSupported) }) t.Run("should not return error if url is surrounded by whitespaces", func(t *testing.T) { From d8209fcbcb7046827cd0115dd09a731038b25949 Mon Sep 17 00:00:00 2001 From: kirillston Date: Wed, 21 Dec 2022 14:13:51 +0100 Subject: [PATCH 35/68] GO-677 fix lint 2 --- util/uri/uri.go | 19 +++++++++++-------- util/uri/uri_test.go | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/util/uri/uri.go b/util/uri/uri.go index 20550274f..424390890 100644 --- a/util/uri/uri.go +++ b/util/uri/uri.go @@ -18,19 +18,22 @@ var ( winFilepathPrefixRegex = regexp.MustCompile(`^[a-zA-Z]:[\\\/]`) // errors - errUrlEmpty = fmt.Errorf("url is empty") + errURLEmpty = fmt.Errorf("url is empty") errFilepathNotSupported = fmt.Errorf("filepath not supported") ) func ValidateURI(uri string) error { uri = strings.TrimSpace(uri) - if len(uri) == 0 { - return fmt.Errorf("url is empty") - } else if winFilepathPrefixRegex.MatchString(uri) { - return fmt.Errorf("filepath not supported") - } else if strings.HasPrefix(uri, string(os.PathSeparator)) || strings.HasPrefix(uri, ".") { - return fmt.Errorf("filepath not supported") + switch { + case len(uri) == 0: + return errURLEmpty + case winFilepathPrefixRegex.MatchString(uri): + return errFilepathNotSupported + case strings.HasPrefix(uri, string(os.PathSeparator)): + return errFilepathNotSupported + case strings.HasPrefix(uri, "."): + return errFilepathNotSupported } _, err := url.Parse(uri) @@ -62,7 +65,7 @@ func ValidateAndParseURI(uri string) (*url.URL, error) { switch { case len(uri) == 0: - return nil, errUrlEmpty + return nil, errURLEmpty case winFilepathPrefixRegex.MatchString(uri): return nil, errFilepathNotSupported case strings.HasPrefix(uri, string(os.PathSeparator)): diff --git a/util/uri/uri_test.go b/util/uri/uri_test.go index 9c693ce53..613b7a211 100644 --- a/util/uri/uri_test.go +++ b/util/uri/uri_test.go @@ -67,7 +67,7 @@ func TestURI_ValidateURI(t *testing.T) { uri := "" err := ValidateURI(uri) assert.Error(t, err) - assert.Equal(t, err, errUrlEmpty) + assert.Equal(t, err, errURLEmpty) }) t.Run("should return error on win filepath", func(t *testing.T) { From 7136d54edb021d4221b3b30831157dc50353819d Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Thu, 22 Dec 2022 13:01:38 +0300 Subject: [PATCH 36/68] GO-564: fix colors of tags and date mention Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/converter/types.go | 4 +- core/block/import/notion/api/block/mapper.go | 16 - core/block/import/notion/api/block/table.go | 2 - .../import/notion/api/block/text_test.go | 6 +- .../import/notion/api/block/textobject.go | 70 +- .../import/notion/api/database/database.go | 12 +- core/block/import/notion/api/page/page.go | 49 +- core/block/import/relationcreator.go | 25 +- pb/commands.pb.go | 1487 +++++++++-------- 9 files changed, 834 insertions(+), 837 deletions(-) diff --git a/core/block/import/converter/types.go b/core/block/import/converter/types.go index bc41df3d2..3ff8d5a9b 100644 --- a/core/block/import/converter/types.go +++ b/core/block/import/converter/types.go @@ -42,12 +42,10 @@ type Snapshot struct { Snapshot *model.SmartBlockSnapshotBase } -// Relation incapsulate name and relations format. We need this structure, so we don't create relations in Anytype // during GetSnapshots step in converter and create them in RelationCreator type Relation struct { BlockID string // if relations is used as a block - Name string - Format model.RelationFormat + *model.Relation } // Response expected response of each converter, incapsulate blocks snapshots and converting errors diff --git a/core/block/import/notion/api/block/mapper.go b/core/block/import/notion/api/block/mapper.go index 9430639cb..70b8e4ae9 100644 --- a/core/block/import/notion/api/block/mapper.go +++ b/core/block/import/notion/api/block/mapper.go @@ -1,9 +1,6 @@ package block import ( - "github.com/gogo/protobuf/types" - - "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" ) @@ -20,26 +17,13 @@ type MapRequest struct { type MapResponse struct { Blocks []*model.Block - Relations []*converter.Relation - Details map[string]*types.Value BlockIDs []string } func (m *MapResponse) Merge(mergedResp *MapResponse) { if mergedResp != nil { m.BlockIDs = append(m.BlockIDs, mergedResp.BlockIDs...) - m.Relations = append(m.Relations, mergedResp.Relations...) m.Blocks = append(m.Blocks, mergedResp.Blocks...) - m.MergeDetails(mergedResp.Details) - } -} - -func (m *MapResponse) MergeDetails(mergeDetails map[string]*types.Value) { - if m.Details == nil { - m.Details = make(map[string]*types.Value, 0) - } - for k, v := range mergeDetails { - m.Details[k] = v } } diff --git a/core/block/import/notion/api/block/table.go b/core/block/import/notion/api/block/table.go index 172e17751..868d063b9 100644 --- a/core/block/import/notion/api/block/table.go +++ b/core/block/import/notion/api/block/table.go @@ -131,8 +131,6 @@ func (t *TableBlock) getRows(req *MapRequest, } rowTextBlocks = append(rowTextBlocks, resp.Blocks...) childBlockIDsCurrRow = append(childBlockIDsCurrRow, resp.BlockIDs...) - tableResponse.Relations = append(tableResponse.Relations, resp.Relations...) - tableResponse.MergeDetails(resp.Details) } var isHeader bool diff --git a/core/block/import/notion/api/block/text_test.go b/core/block/import/notion/api/block/text_test.go index f6bf7eb78..d2a0f5d4e 100644 --- a/core/block/import/notion/api/block/text_test.go +++ b/core/block/import/notion/api/block/text_test.go @@ -124,8 +124,10 @@ func Test_GetTextBlocksDateMention(t *testing.T) { bl := to.GetTextBlocks(model.BlockContentText_Paragraph, nil, &MapRequest{}) assert.Len(t, bl.Blocks, 1) - assert.NotNil(t, bl.Blocks[0].GetRelation()) - assert.Len(t, bl.Relations, 1) + assert.Equal(t, bl.Blocks[0].GetText().Style, model.BlockContentText_Paragraph) + assert.Len(t, bl.Blocks[0].GetText().Marks.Marks, 1) + assert.Equal(t, bl.Blocks[0].GetText().Marks.Marks[0].Type, model.BlockContentTextMark_Mention) + assert.Equal(t, bl.Blocks[0].GetText().Marks.Marks[0].Param, "_date_2022-11-14") } func Test_GetTextBlocksLinkPreview(t *testing.T) { diff --git a/core/block/import/notion/api/block/textobject.go b/core/block/import/notion/api/block/textobject.go index 1773c2323..695a45a1b 100644 --- a/core/block/import/notion/api/block/textobject.go +++ b/core/block/import/notion/api/block/textobject.go @@ -5,12 +5,10 @@ import ( "time" "github.com/globalsign/mgo/bson" - "github.com/gogo/protobuf/types" - "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/core/block/import/notion/api" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore/addr" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" - "github.com/anytypeio/go-anytype-middleware/util/pbtypes" textUtil "github.com/anytypeio/go-anytype-middleware/util/text" ) @@ -31,30 +29,13 @@ func (t *TextObject) GetTextBlocks(style model.BlockContentTextStyle, childIds [ allBlocks := make([]*model.Block, 0) allIds := make([]string, 0) var ( - text strings.Builder - relations []*converter.Relation - details map[string]*types.Value + text strings.Builder ) for _, rt := range t.RichText { if rt.Type == api.Text { marks = append(marks, t.handleTextType(rt, &text, req.NotionPageIdsToAnytype, req.NotionDatabaseIdsToAnytype)...) } if rt.Type == api.Mention { - // Return Relation block for Date mention - if rt.Mention.Type == api.Date { - var ( - relationBlock *model.Block - relationBlockID string - relation *converter.Relation - ) - relationBlock, relation, details, relationBlockID = t.handleDateMention(rt, &text) - if relationBlock != nil { - allBlocks = append(allBlocks, relationBlock) - allIds = append(allIds, relationBlockID) - relations = append(relations, relation) - } - continue - } marks = append(marks, t.handleMentionType(rt, &text, req)...) } if rt.Type == api.Equation { @@ -72,10 +53,8 @@ func (t *TextObject) GetTextBlocks(style model.BlockContentTextStyle, childIds [ if t.isNotTextBlocks() { return &MapResponse{ - Blocks: allBlocks, - Relations: relations, - Details: details, - BlockIDs: allIds, + Blocks: allBlocks, + BlockIDs: allIds, } } allBlocks = append(allBlocks, &model.Block{ @@ -96,10 +75,8 @@ func (t *TextObject) GetTextBlocks(style model.BlockContentTextStyle, childIds [ allIds = append(allIds, b.Id) } return &MapResponse{ - Blocks: allBlocks, - Relations: relations, - Details: details, - BlockIDs: allIds, + Blocks: allBlocks, + BlockIDs: allIds, } } @@ -151,6 +128,9 @@ func (t *TextObject) handleMentionType(rt api.RichText, if rt.Mention.Type == api.LinkPreview { return t.handleLinkPreviewMention(rt, text) } + if rt.Mention.Type == api.Date { + return t.handleDateMention(rt, text) + } return nil } @@ -204,33 +184,30 @@ func (t *TextObject) handlePageMention(rt api.RichText, } func (t *TextObject) handleDateMention(rt api.RichText, - text *strings.Builder) (*model.Block, *converter.Relation, map[string]*types.Value, string) { + text *strings.Builder) []*model.BlockContentTextMark { var textDate string if rt.Mention.Date.Start != "" { textDate = rt.Mention.Date.Start } if rt.Mention.Date.End != "" { - textDate += " " + rt.Mention.Date.End + textDate = rt.Mention.Date.End } date, err := time.Parse(DateMentionTimeFormat, textDate) if err != nil { - return nil, nil, nil, "" + return nil } - rel := converter.Relation{ - BlockID: bson.NewObjectId().Hex(), - Name: "Date", - Format: model.RelationFormat_date, - } - id := bson.NewObjectId().Hex() - details := map[string]*types.Value{rel.Name: pbtypes.Int64(date.Unix())} - return &model.Block{ - Id: id, - Content: &model.BlockContentOfRelation{ - Relation: &model.BlockContentRelation{ - Key: rel.BlockID, + from := textUtil.UTF16RuneCountString(text.String()) + to := textUtil.UTF16RuneCountString(text.String()) + return []*model.BlockContentTextMark{ + { + Range: &model.Range{ + From: int32(from), + To: int32(to), }, + Type: model.BlockContentTextMark_Mention, + Param: addr.TimeToID(date), }, - }, &rel, details, id + } } func (t *TextObject) handleLinkPreviewMention(rt api.RichText, text *strings.Builder) []*model.BlockContentTextMark { @@ -249,8 +226,7 @@ func (t *TextObject) handleLinkPreviewMention(rt api.RichText, text *strings.Bui } func (t *TextObject) isNotTextBlocks() bool { - return (len(t.RichText) == 1 && t.RichText[0].Type == api.Mention && t.RichText[0].Mention.Type == api.Date) || - len(t.RichText) == 1 && t.RichText[0].Type == api.Equation + return len(t.RichText) == 1 && t.RichText[0].Type == api.Equation } type TextObjectWithChildren struct { diff --git a/core/block/import/notion/api/database/database.go b/core/block/import/notion/api/database/database.go index eb62ede3d..82f7fa1e8 100644 --- a/core/block/import/notion/api/database/database.go +++ b/core/block/import/notion/api/database/database.go @@ -112,8 +112,10 @@ func (ds *Service) transformDatabase(d Database) *model.SmartBlockSnapshotBase { details[bundle.RelationKeyCoverId.String()] = pbtypes.String(d.Cover.External.URL) details[bundle.RelationKeyCoverType.String()] = pbtypes.Float64(1) relation = &converter.Relation{ - Name: bundle.RelationKeyCoverId.String(), - Format: model.RelationFormat_file, + Relation: &model.Relation{ + Name: bundle.RelationKeyCoverId.String(), + Format: model.RelationFormat_file, + }, } } @@ -121,8 +123,10 @@ func (ds *Service) transformDatabase(d Database) *model.SmartBlockSnapshotBase { details[bundle.RelationKeyCoverId.String()] = pbtypes.String(d.Cover.File.URL) details[bundle.RelationKeyCoverType.String()] = pbtypes.Float64(1) relation = &converter.Relation{ - Name: bundle.RelationKeyCoverId.String(), - Format: model.RelationFormat_file, + Relation: &model.Relation{ + Name: bundle.RelationKeyCoverId.String(), + Format: model.RelationFormat_file, + }, } } diff --git a/core/block/import/notion/api/page/page.go b/core/block/import/notion/api/page/page.go index bb96e75be..337311517 100644 --- a/core/block/import/notion/api/page/page.go +++ b/core/block/import/notion/api/page/page.go @@ -174,11 +174,9 @@ func (ds *Service) transformPages(ctx context.Context, request.Blocks = notionBlocks resp := ds.blockService.MapNotionBlocksToAnytype(request) - resp.MergeDetails(details) - relations = append(relations, resp.Relations...) snapshot := &model.SmartBlockSnapshotBase{ Blocks: resp.Blocks, - Details: &types.Struct{Fields: resp.Details}, + Details: &types.Struct{Fields: details}, ObjectTypes: []string{bundle.TypeKeyPage.URL()}, } @@ -215,10 +213,17 @@ func (ds *Service) handlePageProperties(ctx context.Context, continue } ds.SetDetail(k, d) - relations = append(relations, &converter.Relation{ - Name: k, - Format: v.GetFormat(), - }) + + rel := &converter.Relation{ + Relation: &model.Relation{ + Name: k, + Format: v.GetFormat(), + }, + } + if isPropertyTag(v) { + setOptionsForListRelation(v, rel.Relation) + } + relations = append(relations, rel) } return relations } @@ -284,3 +289,33 @@ func isPropertyPaginated(pr property.Object) bool { return pr.GetPropertyType() == property.PropertyConfigTypeRichText || pr.GetPropertyType() == property.PropertyConfigTypePeople } + +func isPropertyTag(pr property.Object) bool { + return pr.GetPropertyType() == property.PropertyConfigTypeMultiSelect || + pr.GetPropertyType() == property.PropertyConfigTypeSelect || + pr.GetPropertyType() == property.PropertyConfigStatus +} + +func setOptionsForListRelation(pr property.Object, rel *model.Relation) { + var text, color []string + switch property := pr.(type) { + case *property.StatusItem: + text = append(text, property.Status.Name) + color = append(color, api.NotionColorToAnytype[property.Status.Color]) + case *property.SelectItem: + text = append(text, property.Select.Name) + color = append(color, api.NotionColorToAnytype[property.Select.Color]) + case *property.MultiSelectItem: + for _, so := range property.MultiSelect { + text = append(text, so.Name) + color = append(color, api.NotionColorToAnytype[so.Color]) + } + } + + for i := 0; i < len(text); i++ { + rel.SelectDict = append(rel.SelectDict, &model.RelationOption{ + Text: text[i], + Color: color[i], + }) + } +} diff --git a/core/block/import/relationcreator.go b/core/block/import/relationcreator.go index 6a1dc92c8..63df7ff0d 100644 --- a/core/block/import/relationcreator.go +++ b/core/block/import/relationcreator.go @@ -180,20 +180,17 @@ func (rc *RelationService) handleListValue(ctx *session.Context, id string err error ) - for _, v := range snapshot.Details.Fields[r.Name].GetListValue().Values { - if r.Format == model.RelationFormat_tag || r.Format == model.RelationFormat_status { - if id, _, err = rc.service.CreateSubObjectInWorkspace(&types.Struct{ - Fields: map[string]*types.Value{ - bundle.RelationKeyName.String(): pbtypes.String(v.GetStringValue()), - bundle.RelationKeyRelationKey.String(): pbtypes.String(relationID), - bundle.RelationKeyType.String(): pbtypes.String(bundle.TypeKeyRelationOption.URL()), - bundle.RelationKeyLayout.String(): pbtypes.Float64(float64(model.ObjectType_relationOption)), - }, - }, rc.core.PredefinedBlocks().Account); err != nil { - log.Errorf("add extra relation %s", err) - } - } else { - id = v.GetStringValue() + for _, tag := range r.SelectDict { + if id, _, err = rc.service.CreateSubObjectInWorkspace(&types.Struct{ + Fields: map[string]*types.Value{ + bundle.RelationKeyName.String(): pbtypes.String(tag.Text), + bundle.RelationKeyRelationKey.String(): pbtypes.String(relationID), + bundle.RelationKeyType.String(): pbtypes.String(bundle.TypeKeyRelationOption.URL()), + bundle.RelationKeyLayout.String(): pbtypes.Float64(float64(model.ObjectType_relationOption)), + bundle.RelationKeyRelationOptionColor.String(): pbtypes.String(tag.Color), + }, + }, rc.core.PredefinedBlocks().Account); err != nil { + log.Errorf("add extra relation %s", err) } optionsIds = append(optionsIds, id) } diff --git a/pb/commands.pb.go b/pb/commands.pb.go index 0d2526692..5eb3eb3c6 100644 --- a/pb/commands.pb.go +++ b/pb/commands.pb.go @@ -44128,750 +44128,753 @@ func init() { func init() { proto.RegisterFile("pb/protos/commands.proto", fileDescriptor_8261c968b2e6f45c) } var fileDescriptor_8261c968b2e6f45c = []byte{ - // 11881 bytes of a gzipped FileDescriptorProto + // 11931 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x7d, 0x7d, 0x98, 0x23, 0xc7, 0x59, 0xe7, 0x4a, 0xad, 0x8f, 0x99, 0x77, 0x3e, 0xb6, 0xdd, 0xd9, 0xac, 0x27, 0x65, 0x7b, 0x63, - 0xc6, 0x9f, 0xac, 0xed, 0x59, 0x7b, 0x9d, 0x0f, 0xaf, 0xbf, 0x35, 0x92, 0x66, 0x46, 0xde, 0x19, - 0x69, 0x68, 0x69, 0x76, 0x31, 0x77, 0xdc, 0x5c, 0x8f, 0x54, 0x33, 0xd3, 0x5e, 0x8d, 0x5a, 0xb4, - 0x7a, 0x66, 0x77, 0xf3, 0x3c, 0x77, 0x60, 0xc0, 0xd8, 0xc0, 0x13, 0xc2, 0xe7, 0x05, 0xc3, 0x25, - 0x26, 0x0e, 0x09, 0x84, 0x10, 0x42, 0x08, 0x49, 0x2e, 0x5c, 0x62, 0x2e, 0x24, 0xe1, 0x09, 0x79, - 0x42, 0x1c, 0xf2, 0x0d, 0x97, 0x84, 0xe0, 0x70, 0xb9, 0x70, 0x97, 0x90, 0x27, 0x3c, 0x77, 0xc7, - 0x05, 0x03, 0xb9, 0xa7, 0xab, 0xaa, 0x3f, 0x4a, 0xa3, 0x6e, 0x55, 0x6b, 0xd4, 0x1a, 0xe7, 0xf8, - 0x4b, 0xea, 0xea, 0xea, 0xaa, 0xb7, 0xde, 0xdf, 0x5b, 0x6f, 0x55, 0xbd, 0xf5, 0xd6, 0x5b, 0x30, - 0xd3, 0xde, 0x38, 0xd5, 0x36, 0x0d, 0xcb, 0xe8, 0x9c, 0xaa, 0x1b, 0x3b, 0x3b, 0x5a, 0xab, 0xd1, - 0x99, 0x23, 0xcf, 0x4a, 0x56, 0x6b, 0x5d, 0xb6, 0x2e, 0xb7, 0x31, 0xba, 0xbe, 0x7d, 0x61, 0xeb, - 0x54, 0x53, 0xdf, 0x38, 0xd5, 0xde, 0x38, 0xb5, 0x63, 0x34, 0x70, 0xd3, 0xf9, 0x80, 0x3c, 0xb0, - 0xec, 0xe8, 0xe6, 0xa0, 0x5c, 0x4d, 0xa3, 0xae, 0x35, 0x3b, 0x96, 0x61, 0x62, 0x96, 0xf3, 0xb8, - 0x57, 0x25, 0xde, 0xc3, 0x2d, 0xcb, 0x29, 0xe1, 0xea, 0x2d, 0xc3, 0xd8, 0x6a, 0x62, 0xfa, 0x6e, - 0x63, 0x77, 0xf3, 0x54, 0xc7, 0x32, 0x77, 0xeb, 0x16, 0x7b, 0x7b, 0x6d, 0xf7, 0xdb, 0x06, 0xee, - 0xd4, 0x4d, 0xbd, 0x6d, 0x19, 0x26, 0xcd, 0x31, 0xfb, 0xcf, 0x7f, 0x9b, 0x02, 0x49, 0x6d, 0xd7, - 0xd1, 0xc7, 0xc7, 0x40, 0xca, 0xb5, 0xdb, 0xe8, 0x5b, 0x49, 0x80, 0x45, 0x6c, 0x9d, 0xc3, 0x66, - 0x47, 0x37, 0x5a, 0x68, 0x1c, 0xb2, 0x2a, 0xfe, 0xa1, 0x5d, 0xdc, 0xb1, 0xd0, 0xe7, 0x92, 0x30, - 0xa6, 0xe2, 0x4e, 0xdb, 0x68, 0x75, 0xb0, 0xf2, 0x20, 0xa4, 0xb1, 0x69, 0x1a, 0xe6, 0x4c, 0xe2, - 0xda, 0xc4, 0xcd, 0x13, 0xa7, 0x4f, 0xce, 0xb1, 0x86, 0xcf, 0xa9, 0xed, 0xfa, 0x5c, 0xae, 0xdd, - 0x9e, 0xf3, 0xca, 0x98, 0x73, 0x3e, 0x9a, 0x2b, 0xda, 0x5f, 0xa8, 0xf4, 0x43, 0x65, 0x06, 0xb2, - 0x7b, 0x34, 0xc3, 0x4c, 0xf2, 0xda, 0xc4, 0xcd, 0xe3, 0xaa, 0xf3, 0x68, 0xbf, 0x69, 0x60, 0x4b, - 0xd3, 0x9b, 0x9d, 0x19, 0x89, 0xbe, 0x61, 0x8f, 0xe8, 0xd3, 0x09, 0x48, 0x93, 0x42, 0x94, 0x3c, - 0xa4, 0xea, 0x46, 0x03, 0x93, 0xea, 0xa7, 0x4f, 0x9f, 0x12, 0xaf, 0x7e, 0x2e, 0x6f, 0x34, 0xb0, - 0x4a, 0x3e, 0x56, 0xae, 0x85, 0x09, 0x87, 0x21, 0x1e, 0x19, 0xfe, 0xa4, 0xd9, 0x06, 0xa4, 0xec, - 0xfc, 0xca, 0x18, 0xa4, 0xca, 0x6b, 0xcb, 0xcb, 0xf2, 0x11, 0xe5, 0x0a, 0x98, 0x5a, 0x2b, 0x9f, - 0x2d, 0x57, 0xce, 0x97, 0xd7, 0x8b, 0xaa, 0x5a, 0x51, 0xe5, 0x84, 0x32, 0x05, 0xe3, 0xf3, 0xb9, - 0xc2, 0x7a, 0xa9, 0xbc, 0xba, 0x56, 0x93, 0x93, 0xca, 0x31, 0x90, 0xcf, 0x15, 0xd5, 0x6a, 0xa9, - 0x52, 0x5e, 0x2f, 0x55, 0xd7, 0x8b, 0x2b, 0xab, 0xb5, 0x87, 0x65, 0xc9, 0xce, 0x54, 0xae, 0xd4, - 0xd6, 0x17, 0x2a, 0x6b, 0xe5, 0x82, 0x8c, 0x95, 0x09, 0xc8, 0xd6, 0x4a, 0x2b, 0xc5, 0xca, 0x5a, - 0x4d, 0xde, 0x44, 0xbf, 0x2f, 0xc1, 0x74, 0x15, 0x5b, 0x05, 0xbc, 0xa7, 0xd7, 0x71, 0xd5, 0xd2, - 0x2c, 0x8c, 0x5e, 0x93, 0x70, 0x19, 0xaf, 0xac, 0xd9, 0x64, 0xba, 0xaf, 0x58, 0x93, 0xef, 0xdc, - 0xd7, 0x64, 0xbe, 0x84, 0x39, 0xf6, 0xf5, 0x9c, 0x2f, 0x4d, 0xf5, 0x97, 0x33, 0x7b, 0x1b, 0x4c, - 0xf8, 0xde, 0x29, 0xd3, 0x00, 0xf3, 0xb9, 0xfc, 0xd9, 0x45, 0x95, 0x50, 0x78, 0xc4, 0x7e, 0x5e, - 0xa8, 0xa8, 0x45, 0xf6, 0x9c, 0x40, 0xaf, 0xf1, 0xc3, 0x5f, 0xe0, 0xe1, 0x9f, 0xeb, 0x4f, 0x4c, - 0x0f, 0x11, 0x40, 0xef, 0x73, 0xe1, 0x5c, 0xe4, 0xe0, 0xbc, 0x33, 0x5a, 0x71, 0xd1, 0x20, 0x5d, - 0x1a, 0x0c, 0xd2, 0x72, 0xa5, 0x50, 0x5c, 0xb7, 0x11, 0xac, 0xd6, 0x72, 0x6a, 0xad, 0x58, 0x90, - 0x31, 0xfa, 0xd5, 0x24, 0x8c, 0x55, 0xb7, 0x77, 0xad, 0x86, 0x71, 0x91, 0xeb, 0x28, 0x3f, 0xe6, - 0xe7, 0xd4, 0xfd, 0x3c, 0xa7, 0x6e, 0xde, 0xdf, 0x34, 0x56, 0x42, 0x00, 0x8f, 0xde, 0xed, 0xf2, - 0x28, 0xc7, 0xf1, 0xe8, 0x36, 0xd1, 0x82, 0x0e, 0x8b, 0x3b, 0x9f, 0x99, 0x82, 0xcc, 0x79, 0xad, - 0xd9, 0xc4, 0x16, 0xfa, 0xeb, 0x24, 0x64, 0xf2, 0x26, 0xb6, 0xe5, 0xfa, 0x16, 0x4f, 0xac, 0x11, - 0x8c, 0x99, 0x86, 0x61, 0xad, 0x6a, 0xd6, 0x36, 0x69, 0xd3, 0xb8, 0xea, 0x3e, 0xdf, 0x9d, 0x7a, - 0xe2, 0xab, 0x52, 0x02, 0xfd, 0xb6, 0x9f, 0x91, 0x0f, 0xf0, 0x8c, 0xfc, 0x5e, 0xae, 0xfd, 0xb4, - 0xa2, 0x39, 0x5a, 0x49, 0x80, 0xc2, 0x41, 0x30, 0xb6, 0xd3, 0xc2, 0x3b, 0x46, 0x4b, 0xaf, 0xb3, - 0x96, 0xbb, 0xcf, 0xe8, 0x8f, 0x5c, 0x2e, 0xcf, 0x73, 0x5c, 0x9e, 0x13, 0xae, 0x25, 0x1a, 0x9b, - 0xab, 0x03, 0xb0, 0xf9, 0xa5, 0x70, 0xd5, 0x42, 0xae, 0xb4, 0x5c, 0x2c, 0xac, 0xd7, 0x2a, 0xeb, - 0x79, 0xb5, 0x98, 0xab, 0x15, 0xd7, 0x97, 0x2b, 0xf9, 0xdc, 0xf2, 0xba, 0x5a, 0x5c, 0xad, 0xc8, - 0x18, 0xfd, 0xf7, 0xa4, 0xcd, 0xdc, 0xba, 0xb1, 0x87, 0x4d, 0xb4, 0x28, 0xc4, 0xe7, 0x30, 0x9e, - 0x30, 0x0c, 0x7e, 0x5e, 0x58, 0xeb, 0x33, 0xee, 0x30, 0x0a, 0x02, 0xc4, 0xf9, 0x83, 0x42, 0x1a, - 0x3c, 0xb4, 0xa8, 0x17, 0x00, 0xa7, 0xff, 0x57, 0x12, 0xb2, 0x79, 0xa3, 0xb5, 0x87, 0x4d, 0x0b, - 0x3d, 0xc0, 0x71, 0xda, 0xe5, 0x66, 0x82, 0xe7, 0xa6, 0x3d, 0xa8, 0xe1, 0x96, 0x65, 0x1a, 0xed, - 0xcb, 0xce, 0x70, 0xc7, 0x1e, 0xd1, 0x6f, 0x44, 0xe5, 0x30, 0xab, 0x39, 0x78, 0x5c, 0xed, 0x5d, - 0x11, 0x47, 0x9e, 0xd4, 0xd5, 0x01, 0x9e, 0x8e, 0x82, 0x4b, 0x6f, 0x02, 0xa2, 0xe1, 0x72, 0x3a, - 0x3a, 0x2e, 0xe8, 0x93, 0x49, 0x98, 0xa2, 0x9d, 0xaf, 0x8a, 0x3b, 0x64, 0x7a, 0x72, 0x8b, 0x10, - 0xf3, 0x99, 0x28, 0xff, 0x82, 0x9f, 0xd1, 0x0b, 0x3c, 0xa3, 0x6f, 0x0f, 0xee, 0xe8, 0xac, 0xae, - 0x00, 0x76, 0x1f, 0x83, 0xb4, 0x65, 0x5c, 0xc0, 0x4e, 0x1b, 0xe9, 0x03, 0xfa, 0x4d, 0x97, 0x9d, - 0x25, 0x8e, 0x9d, 0x2f, 0x8f, 0x5a, 0x4d, 0xfc, 0x4c, 0x7d, 0x5b, 0x12, 0x26, 0xf3, 0x4d, 0xa3, - 0xe3, 0xf2, 0xf4, 0xa5, 0x1e, 0x4f, 0xdd, 0xc6, 0x25, 0xfc, 0x8d, 0x7b, 0x3e, 0xe1, 0xe3, 0x63, - 0x91, 0xe7, 0x63, 0x6f, 0x79, 0xf1, 0x15, 0x1f, 0xa0, 0x17, 0x7e, 0xc3, 0x65, 0xd8, 0x12, 0xc7, - 0xb0, 0x97, 0x45, 0x2c, 0x2f, 0x7e, 0x7e, 0xbd, 0xfb, 0x7b, 0x20, 0x9b, 0xab, 0xd7, 0x8d, 0xdd, - 0x96, 0x85, 0xfe, 0x32, 0x01, 0x99, 0xbc, 0xd1, 0xda, 0xd4, 0xb7, 0x94, 0x1b, 0x61, 0x1a, 0xb7, - 0xb4, 0x8d, 0x26, 0x2e, 0x68, 0x96, 0xb6, 0xa7, 0xe3, 0x8b, 0xa4, 0x01, 0x63, 0x6a, 0x57, 0xaa, - 0x4d, 0x14, 0x4b, 0xc1, 0x1b, 0xbb, 0x5b, 0x84, 0xa8, 0x31, 0xd5, 0x9f, 0xa4, 0xdc, 0x05, 0x57, - 0xd2, 0xc7, 0x55, 0x13, 0x9b, 0xb8, 0x89, 0xb5, 0x0e, 0xce, 0x6f, 0x6b, 0xad, 0x16, 0x6e, 0x92, - 0x5e, 0x3b, 0xa6, 0x06, 0xbd, 0x56, 0x66, 0x61, 0x92, 0xbe, 0xaa, 0xb6, 0xb5, 0x3a, 0xee, 0xcc, - 0xa4, 0x48, 0x76, 0x2e, 0x4d, 0xb9, 0x0d, 0xd2, 0xf8, 0x92, 0x65, 0x6a, 0x33, 0x0d, 0x82, 0xd7, - 0x95, 0x73, 0x74, 0x89, 0x30, 0xe7, 0x2c, 0x11, 0xe6, 0xaa, 0x64, 0x01, 0xa1, 0xd2, 0x5c, 0xe8, - 0x83, 0x19, 0x77, 0xe8, 0x7e, 0x83, 0x6f, 0x4a, 0xaa, 0x40, 0xaa, 0xa5, 0xed, 0x60, 0x26, 0x17, - 0xe4, 0xbf, 0x72, 0x12, 0x8e, 0x6a, 0x7b, 0x9a, 0xa5, 0x99, 0xcb, 0xf6, 0xe2, 0x85, 0x0c, 0x37, - 0x84, 0xe5, 0x4b, 0x47, 0xd4, 0xee, 0x17, 0xca, 0xd5, 0x30, 0x4e, 0x56, 0x37, 0x24, 0x17, 0xd5, - 0x45, 0x5e, 0x82, 0x72, 0x33, 0x1c, 0xd5, 0x9a, 0xed, 0x6d, 0xad, 0xd4, 0xda, 0xd3, 0x2d, 0x6c, - 0x23, 0x34, 0x73, 0x8c, 0xe4, 0xe9, 0x4e, 0xa6, 0x1d, 0x7b, 0x7e, 0x0c, 0x32, 0xb4, 0x02, 0xf4, - 0x8b, 0x69, 0xe1, 0x35, 0x0a, 0x85, 0x30, 0x7c, 0xca, 0x70, 0x3b, 0x64, 0x35, 0x9a, 0x8f, 0x34, - 0x65, 0xe2, 0xf4, 0x71, 0xb7, 0x0c, 0xb2, 0x5c, 0x73, 0x4a, 0x51, 0x9d, 0x6c, 0xca, 0x9d, 0x90, - 0xa9, 0x13, 0x81, 0x20, 0xad, 0x9a, 0x38, 0x7d, 0x55, 0xef, 0x4a, 0x49, 0x16, 0x95, 0x65, 0x45, - 0x5f, 0x92, 0x84, 0x96, 0x35, 0x61, 0x14, 0x47, 0x93, 0xfb, 0x6f, 0x24, 0x07, 0x18, 0x15, 0x6f, - 0x85, 0x9b, 0x73, 0xf9, 0x7c, 0x65, 0xad, 0x5c, 0x63, 0x63, 0x62, 0x61, 0x7d, 0x7e, 0xad, 0xb6, - 0xee, 0x8d, 0x94, 0x64, 0xee, 0xb7, 0x6e, 0x4f, 0x05, 0x65, 0x5b, 0x1a, 0x6e, 0xec, 0x93, 0xbb, - 0x58, 0x5b, 0x2f, 0xe7, 0x56, 0x8a, 0xf2, 0xa6, 0x40, 0xc9, 0xc5, 0xda, 0x7a, 0xee, 0x5c, 0xae, - 0x96, 0x53, 0xe5, 0x2d, 0x7e, 0x74, 0xae, 0xd6, 0x2a, 0xab, 0xeb, 0xea, 0x5a, 0xb9, 0x5c, 0x2a, - 0x2f, 0xd2, 0xaa, 0xed, 0x49, 0xcd, 0x71, 0x2f, 0xc3, 0x79, 0xb5, 0x54, 0x2b, 0xae, 0xe7, 0x2b, - 0xe5, 0x85, 0xd2, 0xa2, 0xac, 0xf7, 0x1b, 0xda, 0x1f, 0x51, 0x8e, 0xc1, 0x51, 0xda, 0xe8, 0x73, - 0xf4, 0xbb, 0x42, 0x51, 0xfe, 0xf1, 0xac, 0x32, 0x0d, 0xe3, 0xe5, 0x62, 0x8d, 0x71, 0xe6, 0xb1, - 0xac, 0x72, 0x15, 0x1c, 0xb7, 0x9f, 0xf3, 0x95, 0x72, 0xb9, 0x98, 0xaf, 0xd9, 0x4b, 0x3d, 0xb5, - 0xb8, 0xb0, 0x56, 0x2d, 0x16, 0xe4, 0x9f, 0xc8, 0x2a, 0x32, 0x4c, 0xd8, 0x2f, 0x2b, 0x0b, 0x0b, - 0xcb, 0xa5, 0x72, 0x51, 0x7e, 0x3c, 0x8b, 0xde, 0x94, 0xf2, 0x66, 0x66, 0xbe, 0x85, 0xc2, 0xcf, - 0xa4, 0x7c, 0xd2, 0x9a, 0xe3, 0xa5, 0xf5, 0x96, 0x9e, 0xd8, 0x87, 0x4f, 0xae, 0x9e, 0x71, 0xe5, - 0xa8, 0xc0, 0xc9, 0xd1, 0xed, 0x11, 0xca, 0x8a, 0x26, 0x48, 0x1f, 0x1b, 0x44, 0x90, 0x5e, 0x0c, - 0x57, 0x94, 0x2b, 0xeb, 0x0c, 0xf1, 0xaa, 0xbb, 0x24, 0xbe, 0x16, 0xae, 0x2e, 0x17, 0x29, 0x30, - 0x6a, 0x31, 0x5f, 0x39, 0x57, 0x54, 0xd7, 0xcf, 0xe7, 0x96, 0x97, 0x8b, 0xb5, 0xf5, 0x85, 0x92, - 0x5a, 0xad, 0xc9, 0x9b, 0xfd, 0xc0, 0xdb, 0x52, 0xae, 0x83, 0x97, 0x7a, 0xcf, 0xeb, 0xc5, 0xef, - 0x2f, 0x55, 0x6b, 0x55, 0x22, 0x4a, 0xf9, 0x8a, 0xaa, 0xae, 0xad, 0xda, 0x0b, 0x93, 0x6d, 0xe5, - 0x38, 0x28, 0x5e, 0x29, 0xea, 0x5a, 0x99, 0x8a, 0x8d, 0x6e, 0xd7, 0xcf, 0xea, 0x73, 0xaa, 0xb7, - 0x17, 0x34, 0xab, 0x45, 0x75, 0xa1, 0xa2, 0xae, 0x14, 0x0b, 0xf2, 0x23, 0xfd, 0x24, 0xef, 0x82, - 0x72, 0x23, 0xcc, 0xe6, 0xca, 0x95, 0xda, 0x52, 0x51, 0x5d, 0xcf, 0x95, 0x1f, 0xae, 0x3d, 0xbc, - 0x5a, 0x5c, 0x5f, 0x55, 0x2b, 0xf9, 0x62, 0xb5, 0xba, 0x5e, 0xaa, 0x3a, 0x99, 0xe5, 0xa6, 0x4d, - 0x82, 0x23, 0xf0, 0xa5, 0xea, 0x7a, 0xa1, 0xb8, 0x5c, 0xb4, 0x49, 0xdb, 0x41, 0xaf, 0x96, 0x20, - 0x53, 0xc0, 0x4d, 0x6c, 0x61, 0xf4, 0x3d, 0x9e, 0xb2, 0x3d, 0x0e, 0x19, 0x13, 0xdb, 0x13, 0x2e, - 0x36, 0xa4, 0xb0, 0x27, 0xf4, 0x97, 0xc9, 0xa8, 0xca, 0x8e, 0x96, 0x1d, 0xa0, 0xec, 0x5e, 0x0e, - 0x99, 0x8e, 0xa5, 0x59, 0xbb, 0x1d, 0xa6, 0xeb, 0xae, 0xe9, 0xad, 0xeb, 0xe6, 0xaa, 0x24, 0x93, - 0xca, 0x32, 0xa3, 0x3f, 0x4f, 0x44, 0x51, 0x5e, 0x3d, 0x29, 0x88, 0x26, 0x73, 0xfa, 0x00, 0x22, - 0x77, 0x02, 0x90, 0x8f, 0xe1, 0xb9, 0x65, 0xb5, 0x98, 0x2b, 0x3c, 0xec, 0x32, 0x1e, 0xdb, 0x22, - 0xe9, 0x7f, 0x9f, 0xaf, 0x95, 0xce, 0x15, 0xe5, 0x4d, 0xf4, 0xc1, 0x34, 0x64, 0xaa, 0xb8, 0x89, - 0xeb, 0x16, 0xba, 0xc7, 0xc3, 0x63, 0x1a, 0x92, 0x7a, 0x83, 0x0d, 0x7d, 0x49, 0xbd, 0xc1, 0x2d, - 0xb0, 0x92, 0x3d, 0x17, 0xb2, 0xcf, 0xa7, 0xa2, 0x22, 0x45, 0x6b, 0x3d, 0xdc, 0x61, 0xe9, 0xc3, - 0x91, 0x86, 0xa5, 0x9e, 0x14, 0x47, 0x43, 0xf6, 0xd3, 0xc9, 0x18, 0x16, 0x6b, 0x22, 0x4a, 0x61, - 0x33, 0x40, 0x29, 0x74, 0x0d, 0x36, 0x0b, 0xa5, 0x72, 0x61, 0xdd, 0x95, 0x93, 0xf2, 0x42, 0x45, - 0xde, 0x56, 0xe6, 0xe0, 0xa4, 0xaf, 0x74, 0x5b, 0x63, 0xb0, 0x1a, 0x72, 0xe5, 0xc2, 0xfa, 0x4a, - 0xb9, 0xb8, 0x52, 0x29, 0x97, 0xf2, 0xd4, 0x34, 0x52, 0xac, 0x51, 0x2d, 0xd3, 0xa5, 0x43, 0xaa, - 0xc5, 0x9c, 0x9a, 0x5f, 0x22, 0xea, 0xa6, 0x50, 0x94, 0x1f, 0x51, 0x6e, 0x82, 0xeb, 0x7c, 0xa4, - 0x30, 0x55, 0xb4, 0xaa, 0x16, 0x0b, 0xc5, 0x85, 0x52, 0xd9, 0x1e, 0x1a, 0x97, 0x2b, 0xf9, 0xb3, - 0x55, 0x71, 0x6d, 0x83, 0xfe, 0x21, 0x09, 0xa9, 0xaa, 0x65, 0xb4, 0xd1, 0xf7, 0x7a, 0x32, 0x7c, - 0x02, 0xc0, 0xc4, 0x3b, 0xc6, 0x1e, 0x99, 0x98, 0x32, 0xbd, 0xe2, 0x4b, 0x41, 0x7f, 0x2c, 0x6e, - 0xc3, 0x72, 0xd5, 0x82, 0xd1, 0x0e, 0x18, 0x97, 0xbe, 0x2d, 0x66, 0xc3, 0x0a, 0x2e, 0x28, 0x9a, - 0x18, 0xfd, 0x54, 0x62, 0x00, 0x31, 0x42, 0x70, 0xdc, 0xa7, 0x01, 0x6c, 0xbc, 0x1c, 0x06, 0x62, - 0xe5, 0x4a, 0x78, 0x51, 0x17, 0x66, 0x04, 0xaa, 0x4d, 0xe5, 0x7b, 0xe0, 0x1a, 0x3f, 0x54, 0x2b, - 0x95, 0x73, 0x45, 0x57, 0x3e, 0x0a, 0xb9, 0x5a, 0x4e, 0xde, 0x42, 0x9f, 0x92, 0x20, 0xb5, 0x62, - 0xec, 0x61, 0x74, 0x9d, 0xc7, 0xfc, 0x19, 0xc8, 0xb6, 0xf0, 0x45, 0x9f, 0x41, 0xc6, 0x79, 0x44, - 0x6f, 0x92, 0xa2, 0xb2, 0xdd, 0x2e, 0x3b, 0x80, 0xed, 0x9f, 0x4f, 0x46, 0x61, 0x7b, 0x8f, 0x82, - 0xa2, 0xb1, 0xfd, 0x6f, 0x06, 0x61, 0x7b, 0x00, 0x6b, 0xb1, 0x32, 0x0b, 0x27, 0xbc, 0x17, 0xa5, - 0x42, 0xb1, 0x5c, 0x2b, 0x2d, 0x3c, 0xec, 0x31, 0xb7, 0xa4, 0x0a, 0xb1, 0xbf, 0x9f, 0x76, 0x08, - 0x9f, 0x2c, 0xce, 0xc0, 0x31, 0xef, 0xdd, 0x22, 0x9d, 0xef, 0xd9, 0x6f, 0x1e, 0x41, 0x3f, 0x9f, - 0x86, 0x49, 0xaa, 0x2d, 0xd7, 0xda, 0x0d, 0x7b, 0x71, 0x74, 0x03, 0x67, 0x88, 0xb0, 0xf4, 0x1d, - 0xfc, 0x03, 0x46, 0xcb, 0x59, 0x1f, 0xb9, 0xcf, 0xe8, 0x13, 0xc2, 0x26, 0x08, 0x5e, 0x27, 0xd3, - 0x5a, 0x02, 0x70, 0x7e, 0x5e, 0xc8, 0xd8, 0x20, 0x50, 0x60, 0x34, 0xbc, 0x7f, 0x7c, 0xd8, 0xdd, - 0x2c, 0x18, 0x8a, 0xcd, 0x40, 0x28, 0xb6, 0x66, 0x1f, 0x4f, 0xc2, 0x78, 0x4d, 0xdf, 0xc1, 0xaf, - 0x32, 0x5a, 0xb8, 0xa3, 0x64, 0x41, 0x5a, 0x5c, 0xa9, 0xc9, 0x47, 0xec, 0x3f, 0xc5, 0x7c, 0x4d, - 0x4e, 0x90, 0x3f, 0x45, 0xbb, 0x6a, 0xfb, 0x4f, 0xae, 0x26, 0x4b, 0xf6, 0x9f, 0x95, 0x62, 0x4d, - 0x4e, 0xd9, 0x7f, 0xca, 0xc5, 0x9a, 0x9c, 0xb6, 0xff, 0xac, 0x2e, 0xd7, 0xe4, 0x8c, 0xfd, 0xa7, - 0x54, 0xad, 0xc9, 0x59, 0xfb, 0xcf, 0x7c, 0xb5, 0x26, 0x8f, 0xd9, 0x7f, 0xce, 0x55, 0x6b, 0xf2, - 0xb8, 0xfd, 0x27, 0x5f, 0xab, 0xc9, 0x60, 0xff, 0x79, 0xa8, 0x5a, 0x93, 0x27, 0xec, 0x3f, 0xb9, - 0x7c, 0x4d, 0x9e, 0x24, 0x7f, 0x8a, 0x35, 0x79, 0xca, 0xfe, 0x53, 0xad, 0xd6, 0xe4, 0x69, 0x52, - 0x72, 0xb5, 0x26, 0x1f, 0x25, 0x75, 0x95, 0x6a, 0xb2, 0x6c, 0xff, 0x59, 0xaa, 0xd6, 0xe4, 0x2b, - 0x48, 0xe6, 0x6a, 0x4d, 0x56, 0x48, 0xa5, 0xd5, 0x9a, 0xfc, 0x22, 0x92, 0xa7, 0x5a, 0x93, 0x8f, - 0x91, 0x2a, 0xaa, 0x35, 0xf9, 0xc5, 0x84, 0x8c, 0x62, 0x4d, 0x3e, 0x4e, 0xf2, 0xa8, 0x35, 0xf9, - 0x4a, 0xf2, 0xaa, 0x5c, 0x93, 0x67, 0x08, 0x61, 0xc5, 0x9a, 0xfc, 0x12, 0xf2, 0x47, 0xad, 0xc9, - 0x88, 0xbc, 0xca, 0xd5, 0xe4, 0xab, 0xd0, 0x35, 0x30, 0xbe, 0x88, 0x2d, 0x8a, 0x2f, 0x92, 0x41, - 0x5a, 0xc4, 0x96, 0x7f, 0xb5, 0xf1, 0xba, 0x19, 0x18, 0x3f, 0x6f, 0x98, 0x17, 0x3a, 0x6d, 0xad, - 0x8e, 0xd1, 0x7b, 0xe9, 0x3e, 0x5f, 0x7e, 0xd7, 0x34, 0x71, 0x8b, 0xcb, 0xf7, 0x94, 0xb8, 0x99, - 0xcc, 0x29, 0x6d, 0xce, 0x2b, 0x29, 0x60, 0xca, 0x72, 0x2d, 0x4c, 0x5c, 0x74, 0x72, 0x97, 0x1a, - 0x8e, 0x38, 0xf9, 0x92, 0x44, 0x4d, 0x66, 0xfd, 0xab, 0x8c, 0xdf, 0x04, 0xf4, 0xf6, 0x24, 0x64, - 0x16, 0xb1, 0x95, 0x6b, 0x36, 0xfd, 0x7c, 0x7b, 0xd2, 0xcf, 0xb7, 0x79, 0x9e, 0x6f, 0xb7, 0x06, - 0x37, 0x22, 0xd7, 0x6c, 0x06, 0xf0, 0x6c, 0x16, 0x26, 0x7d, 0x0c, 0xb2, 0xa7, 0xe5, 0xd2, 0xcd, - 0xe3, 0x2a, 0x97, 0x86, 0x7e, 0xdd, 0xe5, 0x5a, 0x91, 0xe3, 0xda, 0x1d, 0x51, 0x2a, 0x8c, 0x9f, - 0x63, 0x1f, 0xf0, 0x76, 0x80, 0xae, 0x09, 0xb5, 0x22, 0xa1, 0xd7, 0x0e, 0xc0, 0xc5, 0x50, 0x1b, - 0x4e, 0x7f, 0xc9, 0x8b, 0xca, 0xc3, 0x21, 0x18, 0x60, 0x06, 0xe1, 0xe1, 0x7b, 0xc7, 0x20, 0x53, - 0xd9, 0x78, 0xc4, 0x5e, 0x8c, 0x3c, 0x9f, 0x04, 0x29, 0xd7, 0x68, 0x74, 0x8d, 0x3a, 0x06, 0x79, - 0x59, 0x72, 0x96, 0x26, 0xee, 0x33, 0xfa, 0xd8, 0x00, 0x3d, 0x9a, 0xd6, 0x34, 0x97, 0x6b, 0x34, - 0x82, 0xb7, 0xd3, 0xdc, 0x0a, 0x93, 0x7c, 0x85, 0xca, 0x1d, 0xfc, 0x0e, 0x7e, 0x88, 0x99, 0xd1, - 0xdd, 0xda, 0x8f, 0xda, 0xfd, 0x03, 0xe9, 0x8b, 0x1f, 0x88, 0xcf, 0x27, 0x21, 0xbb, 0xac, 0x77, - 0x2c, 0x1b, 0x81, 0x9b, 0x3c, 0x04, 0xae, 0x86, 0x71, 0x87, 0x01, 0x9d, 0x99, 0x04, 0xe9, 0xab, - 0x5e, 0x02, 0x7a, 0xa3, 0x1f, 0x83, 0x87, 0x78, 0x0c, 0x5e, 0x16, 0xde, 0x46, 0x56, 0x57, 0x00, - 0x0e, 0x5c, 0xb5, 0xc9, 0xee, 0x6a, 0x7f, 0xdb, 0x65, 0xeb, 0x0a, 0xc7, 0xd6, 0x33, 0x83, 0x54, - 0x19, 0x3f, 0x6b, 0x3f, 0x93, 0x04, 0xb0, 0xeb, 0x56, 0xc9, 0x4a, 0x44, 0x9c, 0xbb, 0xaf, 0xf3, - 0x73, 0x77, 0x85, 0xe7, 0xee, 0x2b, 0xfb, 0x37, 0x95, 0x56, 0x17, 0xc0, 0x60, 0x19, 0x24, 0xdd, - 0x65, 0xad, 0xfd, 0x17, 0xbd, 0xdd, 0x65, 0xea, 0x2a, 0xc7, 0xd4, 0x7b, 0x07, 0xac, 0x29, 0x7e, - 0xbe, 0xfe, 0xcf, 0x24, 0xc8, 0x55, 0x6c, 0x95, 0x3a, 0x4b, 0xfa, 0xd6, 0x76, 0x53, 0xdf, 0xda, - 0xb6, 0x70, 0x03, 0x9d, 0x15, 0xd2, 0x1e, 0xca, 0xf5, 0x30, 0xa5, 0xfb, 0xbf, 0x63, 0x7b, 0x16, - 0x7c, 0x22, 0xfa, 0x49, 0x3f, 0x02, 0xcb, 0x3c, 0x02, 0xaf, 0x08, 0xe0, 0x4b, 0x37, 0x45, 0x01, - 0xf3, 0xdb, 0xdf, 0x71, 0xd9, 0x5d, 0xe1, 0xd8, 0x7d, 0xcf, 0x60, 0xc5, 0x8e, 0x64, 0x4b, 0xcd, - 0x31, 0x1b, 0xf9, 0x36, 0x28, 0xbb, 0x06, 0xa2, 0xc4, 0xfe, 0x81, 0xe8, 0x7f, 0x27, 0xa2, 0x8f, - 0x7d, 0x61, 0x86, 0xa2, 0xc8, 0x23, 0xdb, 0x10, 0x6c, 0x38, 0x83, 0xf0, 0xeb, 0xc7, 0x24, 0xc8, - 0x14, 0x2f, 0xb5, 0x0d, 0x7e, 0x37, 0x5d, 0x81, 0x54, 0xdb, 0x5b, 0x22, 0x93, 0xff, 0x02, 0x83, - 0xf9, 0x7b, 0x06, 0x98, 0x3f, 0xd0, 0xba, 0x03, 0xba, 0xbf, 0x43, 0x46, 0xd2, 0x47, 0xc6, 0xad, - 0x90, 0x26, 0x5e, 0x78, 0x6c, 0x74, 0xf3, 0xcc, 0x6f, 0x4e, 0x11, 0x45, 0xfb, 0xad, 0x4a, 0x33, - 0x45, 0x46, 0xa1, 0x27, 0x39, 0xf1, 0xa3, 0xf0, 0x85, 0x9f, 0x4b, 0xb8, 0x13, 0x8c, 0x9f, 0x4c, - 0x41, 0xaa, 0xd2, 0xc6, 0x2d, 0xf4, 0xb6, 0x04, 0xa7, 0x82, 0xeb, 0x46, 0xcb, 0xc2, 0x97, 0x3c, - 0x2d, 0xe1, 0x25, 0x84, 0xce, 0x07, 0x66, 0x20, 0x6b, 0x99, 0x14, 0x32, 0xe6, 0xd1, 0xc7, 0x1e, - 0x95, 0x32, 0xcc, 0xea, 0xad, 0x7a, 0x73, 0xb7, 0x81, 0x55, 0xdc, 0xd4, 0x6c, 0xda, 0x3b, 0xb9, - 0x4e, 0x01, 0xb7, 0x71, 0xab, 0x81, 0x5b, 0x16, 0xa5, 0xc6, 0xd9, 0xc8, 0x14, 0xc8, 0xc9, 0x2f, - 0xb0, 0xef, 0xe3, 0xe1, 0xbf, 0x89, 0xe3, 0x37, 0x53, 0xca, 0x76, 0x2b, 0x03, 0x90, 0x3f, 0x03, - 0x40, 0x5b, 0x70, 0x4e, 0xc7, 0x17, 0x99, 0xa5, 0xf5, 0x25, 0x5d, 0x96, 0xd6, 0x8a, 0x9b, 0x41, - 0xf5, 0x65, 0x46, 0x7f, 0xe2, 0x42, 0xfe, 0x20, 0x07, 0xf9, 0xad, 0x82, 0x24, 0x44, 0x43, 0xfb, - 0x5f, 0x0f, 0xb0, 0x10, 0xe7, 0xfc, 0x11, 0x25, 0xe5, 0x25, 0xf0, 0x62, 0xc7, 0x86, 0x58, 0x2e, - 0x16, 0x0b, 0xd5, 0xf5, 0xb5, 0xd5, 0x45, 0x35, 0x57, 0x28, 0xca, 0x80, 0xde, 0x97, 0x84, 0x34, - 0xd9, 0x71, 0x47, 0xf9, 0x21, 0xc8, 0x02, 0xfa, 0x46, 0x42, 0xd4, 0xc4, 0xc5, 0xd8, 0x43, 0xea, - 0x0e, 0x50, 0x70, 0xbf, 0x26, 0x64, 0x59, 0x0c, 0x29, 0x28, 0xfe, 0x6e, 0x65, 0x77, 0xa5, 0xea, - 0xb6, 0x71, 0xf1, 0xff, 0xff, 0xae, 0x64, 0xb7, 0xf2, 0x90, 0xbb, 0x52, 0x0f, 0x12, 0x5e, 0x48, - 0x5d, 0xe9, 0xc9, 0x94, 0xbb, 0x0c, 0x7e, 0xca, 0x27, 0x0d, 0xbe, 0xe5, 0x52, 0x42, 0x6c, 0xb9, - 0xa4, 0xe4, 0x60, 0x4a, 0x6f, 0x59, 0xd8, 0x6c, 0x69, 0xcd, 0x85, 0xa6, 0xb6, 0x45, 0xa7, 0xa7, - 0xfe, 0x7d, 0x1d, 0xca, 0xd3, 0x92, 0x2f, 0x8f, 0xca, 0x7f, 0xa1, 0x9c, 0x00, 0xb0, 0xf0, 0x4e, - 0xbb, 0xa9, 0x59, 0x9e, 0x30, 0xf9, 0x52, 0xd0, 0xd7, 0x85, 0xbd, 0x2f, 0x9d, 0xfe, 0xd5, 0xc7, - 0xfb, 0xd2, 0x95, 0x69, 0xa9, 0x4b, 0xa6, 0xdd, 0xe1, 0x34, 0x25, 0x30, 0x9c, 0xfa, 0xb9, 0x95, - 0x16, 0x5c, 0x5c, 0xbe, 0x41, 0xc8, 0xbd, 0x33, 0xac, 0x19, 0xf1, 0xeb, 0x89, 0xa7, 0x24, 0x98, - 0xa6, 0x55, 0xcf, 0x1b, 0xc6, 0x85, 0x1d, 0xcd, 0xbc, 0x80, 0xee, 0x3d, 0x88, 0x88, 0xa0, 0x8f, - 0xfb, 0xf1, 0x5b, 0xe4, 0xf1, 0xbb, 0x23, 0xb8, 0xe1, 0x4e, 0xed, 0xa3, 0x59, 0xf6, 0xbf, 0xc5, - 0x45, 0xe6, 0x21, 0x0e, 0x99, 0x57, 0x44, 0x26, 0x30, 0x7e, 0x84, 0xde, 0xe1, 0x22, 0xe4, 0xa8, - 0xcd, 0x03, 0x22, 0xf4, 0xe5, 0xc1, 0x10, 0x72, 0x6a, 0x1f, 0x00, 0x21, 0x19, 0xa4, 0x0b, 0xf8, - 0x32, 0xeb, 0x80, 0xf6, 0x5f, 0x3f, 0xd9, 0xa9, 0xf8, 0x30, 0x0b, 0x20, 0x79, 0x24, 0x98, 0x1d, - 0xe3, 0x49, 0xa8, 0xb4, 0x87, 0x80, 0xdc, 0x5f, 0x08, 0xdb, 0x1b, 0x7a, 0xb2, 0x81, 0xd2, 0x30, - 0x9a, 0x1e, 0x26, 0x66, 0xac, 0x10, 0x27, 0x33, 0x7e, 0xcc, 0x3e, 0x97, 0x82, 0x71, 0xc7, 0x27, - 0xd6, 0x42, 0xef, 0x49, 0x70, 0x9e, 0x30, 0x1d, 0x63, 0xd7, 0xac, 0x63, 0x66, 0x01, 0x62, 0x4f, - 0x7e, 0xb6, 0x24, 0x05, 0x07, 0xd0, 0x3e, 0xa3, 0xdf, 0xfe, 0x01, 0x36, 0x15, 0x75, 0x80, 0x45, - 0xaf, 0x91, 0x44, 0x97, 0xa2, 0x1c, 0xf7, 0xab, 0xd8, 0x7a, 0x21, 0x8e, 0xa1, 0x1f, 0x10, 0x5a, - 0xc5, 0xf6, 0x69, 0x49, 0x34, 0xe1, 0xa9, 0x0c, 0x30, 0x19, 0xbb, 0x0a, 0xae, 0x74, 0x72, 0x54, - 0xe6, 0x1f, 0x2a, 0xe6, 0x6b, 0xeb, 0x64, 0x26, 0xb6, 0xa6, 0x2e, 0xcb, 0x12, 0x7a, 0x2c, 0x05, - 0x32, 0x25, 0x8d, 0xd2, 0x59, 0xbb, 0xdc, 0xc6, 0xe8, 0x87, 0x0f, 0x79, 0x22, 0x86, 0xbe, 0xe9, - 0x57, 0x26, 0x25, 0x5e, 0x4e, 0xee, 0x0c, 0xe6, 0xae, 0xd7, 0x84, 0x00, 0x71, 0x19, 0xa0, 0x57, - 0x84, 0x48, 0x18, 0xfa, 0x88, 0x2b, 0x00, 0xcb, 0x9c, 0x00, 0xdc, 0x35, 0x00, 0x89, 0x87, 0x2c, - 0x07, 0x1f, 0x4d, 0xc2, 0x94, 0x33, 0x8d, 0x58, 0xc0, 0x56, 0x7d, 0x1b, 0x9d, 0x11, 0x5d, 0x9b, - 0xc9, 0x20, 0xed, 0x9a, 0x4d, 0x46, 0xa5, 0xfd, 0x17, 0xfd, 0x53, 0x42, 0x74, 0x77, 0x85, 0xf1, - 0x86, 0xab, 0x39, 0x60, 0x61, 0x2b, 0xb6, 0x1d, 0x22, 0x50, 0x60, 0xfc, 0xea, 0xfa, 0x8b, 0x49, - 0x80, 0x9a, 0xe1, 0x4e, 0x5a, 0x0f, 0xc0, 0x49, 0xee, 0x80, 0x46, 0x9e, 0xe7, 0x64, 0xcf, 0x15, - 0xbd, 0x57, 0x6d, 0xf4, 0xb1, 0x14, 0xbd, 0xc9, 0x65, 0xf1, 0x02, 0xc7, 0xe2, 0xd3, 0x91, 0x6a, - 0x8a, 0x9f, 0xbf, 0xef, 0x4b, 0xc2, 0x78, 0x61, 0xb7, 0xdd, 0xd4, 0xeb, 0xf6, 0xba, 0xf1, 0x26, - 0x41, 0xf6, 0xa2, 0xc7, 0x92, 0x11, 0x47, 0x1f, 0xb7, 0x8e, 0x00, 0x5e, 0x52, 0xb7, 0xc7, 0xa4, - 0xe3, 0xf6, 0x28, 0x68, 0xd6, 0xec, 0x53, 0xf8, 0x08, 0xc4, 0x53, 0x82, 0xa3, 0x95, 0x36, 0x6e, - 0xcd, 0x9b, 0x58, 0x6b, 0xd4, 0xcd, 0xdd, 0x9d, 0x8d, 0x0e, 0xca, 0x89, 0xca, 0xa8, 0xcf, 0xda, - 0x92, 0xe4, 0xac, 0x2d, 0xe8, 0x27, 0xfc, 0x83, 0xfb, 0x12, 0xcf, 0xde, 0xd3, 0x41, 0x56, 0x3e, - 0x1f, 0x0d, 0x03, 0x4c, 0xfe, 0x22, 0x59, 0x9d, 0xbb, 0x4c, 0x2e, 0xa9, 0x28, 0x26, 0x97, 0xdf, - 0x72, 0x91, 0x3d, 0xcb, 0x21, 0xfb, 0xca, 0xe8, 0xed, 0x1a, 0xc9, 0xe6, 0xc1, 0x74, 0x15, 0x5b, - 0x01, 0xf0, 0x5e, 0x0f, 0x53, 0x1b, 0xde, 0x1b, 0x17, 0x62, 0x3e, 0xb1, 0xc7, 0x16, 0xdf, 0xdb, - 0xa2, 0x2e, 0xcd, 0x78, 0x12, 0x02, 0xd0, 0x75, 0x11, 0x4c, 0x8a, 0xec, 0x1b, 0x44, 0x5a, 0x67, - 0x85, 0xd6, 0x1f, 0x3f, 0x0a, 0x6f, 0x95, 0x60, 0xba, 0xb4, 0xd3, 0x36, 0x4c, 0x6b, 0x45, 0x33, - 0x2f, 0x90, 0x13, 0xd1, 0x8b, 0xa2, 0x9d, 0xec, 0x04, 0x80, 0x4e, 0x3e, 0xf5, 0x79, 0x50, 0xfb, - 0x52, 0xd0, 0xb3, 0x51, 0xb1, 0xe0, 0x09, 0x09, 0xf6, 0x0b, 0x31, 0x0d, 0xc3, 0x5a, 0xd6, 0x5b, - 0x17, 0xbc, 0x9d, 0x73, 0x7f, 0x52, 0xc4, 0x5d, 0x9e, 0x48, 0x68, 0x85, 0x52, 0x18, 0x3f, 0x5a, - 0x1f, 0x4a, 0xc2, 0x44, 0x75, 0x5b, 0x33, 0xf1, 0xfc, 0x65, 0xbb, 0xb1, 0xa2, 0x7e, 0x24, 0xaf, - 0xf6, 0x03, 0xa1, 0x40, 0xaa, 0xa9, 0xb7, 0x2e, 0x38, 0xdb, 0x73, 0xf6, 0x7f, 0x2f, 0x2c, 0x40, - 0xb2, 0x47, 0x58, 0x00, 0xd7, 0x44, 0xeb, 0xd6, 0x1b, 0x30, 0xf7, 0x79, 0xb3, 0x50, 0x58, 0x80, - 0xbe, 0xc5, 0xc5, 0xcf, 0xc6, 0xcf, 0x26, 0xe1, 0x68, 0xae, 0xd1, 0x38, 0xaf, 0x5b, 0xdb, 0x15, - 0x87, 0x47, 0x0f, 0x88, 0x6d, 0xaa, 0xcf, 0x40, 0xb6, 0xad, 0x5d, 0x6e, 0x1a, 0x9a, 0x3b, 0xb0, - 0xb0, 0x47, 0xf4, 0x68, 0x32, 0xe2, 0xc0, 0xd2, 0x45, 0x41, 0x00, 0x53, 0x23, 0xe9, 0xf4, 0xf0, - 0x22, 0xe3, 0x67, 0xec, 0x9f, 0xa6, 0x20, 0x53, 0xc5, 0x9a, 0x59, 0xdf, 0x46, 0xaf, 0x4b, 0x7a, - 0x0c, 0x5d, 0x80, 0xec, 0xa6, 0xde, 0xb4, 0xb0, 0x49, 0x3d, 0x40, 0xfc, 0xf3, 0x18, 0x3a, 0x9e, - 0xcd, 0x37, 0x8d, 0xfa, 0x85, 0xb9, 0xbc, 0xad, 0x59, 0x5a, 0xd6, 0x9c, 0x73, 0xe6, 0x72, 0x6e, - 0x81, 0x7c, 0xa4, 0x3a, 0x1f, 0x2b, 0x0f, 0x42, 0xba, 0x63, 0x98, 0x96, 0xb3, 0x56, 0x3b, 0x29, - 0x56, 0x4a, 0xd5, 0x30, 0x2d, 0x95, 0x7e, 0x68, 0x43, 0xbb, 0xb9, 0xdb, 0x6c, 0xd6, 0xf0, 0x25, - 0xcb, 0x59, 0x27, 0x39, 0xcf, 0xca, 0x71, 0xc8, 0x18, 0x9b, 0x9b, 0x1d, 0x4c, 0x97, 0xe2, 0x69, - 0x95, 0x3d, 0x29, 0xc7, 0x20, 0xdd, 0xd4, 0x77, 0x74, 0x8b, 0xac, 0xb8, 0xd3, 0x2a, 0x7d, 0x50, - 0x4e, 0x82, 0x6c, 0xb8, 0xab, 0x24, 0x4a, 0xe8, 0x4c, 0x86, 0xe8, 0xa2, 0x7d, 0xe9, 0x76, 0x97, - 0xbb, 0x80, 0x2f, 0x77, 0x66, 0xb2, 0xe4, 0x3d, 0xf9, 0x8f, 0x9e, 0x8e, 0x6a, 0xa5, 0xa7, 0x7c, - 0x0d, 0x5e, 0x32, 0x9a, 0xb8, 0x6e, 0x98, 0x0d, 0x87, 0x37, 0xc1, 0x4b, 0x46, 0x96, 0x2f, 0x9a, - 0x6d, 0xbd, 0x67, 0xe5, 0xf1, 0xcb, 0xd3, 0xd3, 0x19, 0x48, 0x2f, 0x9a, 0x5a, 0x7b, 0x1b, 0xfd, - 0x46, 0x62, 0xf8, 0xe2, 0xe4, 0x02, 0x9b, 0xec, 0x07, 0xac, 0xd4, 0x07, 0xd8, 0x94, 0x0f, 0xd8, - 0x27, 0x93, 0x90, 0x2a, 0x36, 0xb6, 0x30, 0x67, 0xf4, 0x4a, 0xf8, 0x8c, 0x5e, 0xc7, 0x21, 0x63, - 0x69, 0xe6, 0x16, 0xb6, 0x18, 0x97, 0xd8, 0x93, 0xeb, 0x55, 0x29, 0xf9, 0xce, 0xe6, 0xbe, 0x12, - 0x52, 0x76, 0xbb, 0x88, 0x44, 0x4e, 0x9f, 0xbe, 0xae, 0x17, 0x34, 0x84, 0x3f, 0x73, 0x76, 0x8d, - 0x73, 0x36, 0x65, 0x2a, 0xf9, 0xa0, 0x1b, 0x8f, 0xf4, 0x3e, 0x3c, 0xec, 0xb1, 0x5d, 0xaf, 0x1b, - 0xad, 0xd2, 0x8e, 0xb6, 0x85, 0x67, 0x32, 0x74, 0x6c, 0x77, 0x13, 0x9c, 0xb7, 0xc5, 0x1d, 0xe3, - 0x11, 0x7d, 0x26, 0xeb, 0xbd, 0x25, 0x09, 0x76, 0x13, 0xb6, 0xf5, 0x46, 0x03, 0xb7, 0x66, 0xc6, - 0xe8, 0xc9, 0x36, 0xfa, 0x34, 0x7b, 0x02, 0x52, 0x36, 0x0d, 0x36, 0xc6, 0xb6, 0x62, 0x97, 0x8f, - 0x28, 0x93, 0xb6, 0x94, 0x53, 0xab, 0xa4, 0x9c, 0x40, 0x9f, 0x4c, 0x46, 0xdc, 0x43, 0xa6, 0x8d, - 0xeb, 0x2d, 0xf3, 0xb7, 0x41, 0xba, 0x65, 0x34, 0x70, 0x5f, 0x89, 0xa7, 0xb9, 0x94, 0x97, 0x41, - 0x1a, 0x37, 0xb6, 0x70, 0x87, 0x80, 0x39, 0x71, 0xfa, 0x44, 0x38, 0x2f, 0x55, 0x9a, 0x39, 0xda, - 0x46, 0x75, 0x2f, 0x6a, 0xe3, 0xef, 0x24, 0xff, 0x37, 0x03, 0x47, 0x69, 0xff, 0xac, 0xee, 0x6e, - 0xd8, 0x45, 0x6d, 0x60, 0xf4, 0x73, 0x12, 0x17, 0x0c, 0xa0, 0xb3, 0xbb, 0xe1, 0x8e, 0x65, 0xf4, - 0xc1, 0xdf, 0x89, 0x92, 0x43, 0xd1, 0xc9, 0xd2, 0xa0, 0x3a, 0x99, 0xd3, 0xaf, 0x92, 0xd3, 0x0d, - 0x3d, 0x6d, 0x9c, 0x21, 0xc9, 0x8e, 0x36, 0xee, 0xa1, 0x4b, 0xed, 0x41, 0x59, 0xdb, 0xb4, 0xb0, - 0x59, 0x6a, 0x10, 0x79, 0x1c, 0x57, 0x9d, 0x47, 0x5b, 0xdf, 0x6f, 0xe0, 0x4d, 0xc3, 0xb4, 0x17, - 0x82, 0xe3, 0x54, 0xdf, 0x3b, 0xcf, 0xbe, 0xfe, 0x09, 0x9c, 0x51, 0xfa, 0x66, 0x38, 0xaa, 0x6f, - 0xb5, 0x0c, 0x13, 0xbb, 0x9e, 0x3d, 0x33, 0x93, 0xf4, 0x14, 0x7b, 0x57, 0xb2, 0x72, 0x2b, 0x5c, - 0xd1, 0x32, 0x0a, 0xb8, 0xcd, 0xf8, 0x4e, 0x51, 0x9d, 0x22, 0x3d, 0x62, 0xff, 0x0b, 0xf4, 0x89, - 0xa8, 0x2b, 0xcf, 0x2e, 0x50, 0x87, 0xa6, 0xfa, 0x95, 0x7b, 0x60, 0xb2, 0xc1, 0xbc, 0x06, 0xea, - 0xba, 0xdb, 0x23, 0x02, 0xbf, 0xe3, 0x32, 0x7b, 0xe2, 0x94, 0xf2, 0x8b, 0xd3, 0x22, 0x8c, 0x91, - 0x63, 0x2a, 0xb6, 0x3c, 0xa5, 0xbb, 0x0e, 0x42, 0x93, 0xe9, 0xb6, 0xdb, 0x28, 0x1f, 0x4b, 0xe6, - 0xf2, 0xec, 0x13, 0xd5, 0xfd, 0x38, 0xda, 0x7c, 0x27, 0x9c, 0x43, 0xf1, 0x77, 0xbd, 0x5f, 0x4c, - 0xc1, 0xd1, 0x45, 0xd3, 0xd8, 0x6d, 0x77, 0xbc, 0xae, 0xe7, 0x0f, 0xb7, 0xd0, 0xbb, 0xeb, 0xd9, - 0x2b, 0x18, 0xa6, 0x13, 0xcf, 0x62, 0x27, 0xda, 0x8b, 0x3f, 0xc9, 0xdf, 0x39, 0xa5, 0x83, 0x74, - 0x4e, 0x4f, 0xc4, 0x53, 0x7e, 0x11, 0x47, 0x5f, 0x88, 0x3a, 0x57, 0xed, 0x6a, 0x64, 0x80, 0x28, - 0xe6, 0x21, 0xb3, 0x45, 0x32, 0x32, 0x49, 0xbc, 0x45, 0x8c, 0x6a, 0x52, 0xb8, 0xca, 0x3e, 0xf5, - 0x78, 0x26, 0xf9, 0x78, 0x16, 0x4d, 0x2c, 0xc2, 0xa9, 0x1d, 0x81, 0x69, 0x23, 0x05, 0x93, 0x6e, - 0xed, 0xa5, 0x46, 0x07, 0x19, 0xfd, 0x44, 0x62, 0x9f, 0x21, 0xc3, 0xd5, 0x73, 0x92, 0x4f, 0xcf, - 0xf5, 0xd0, 0x4c, 0x13, 0x3d, 0x35, 0x13, 0x7a, 0x54, 0x12, 0x0d, 0xf5, 0xc2, 0x77, 0x4b, 0x42, - 0xee, 0x0b, 0x59, 0xd1, 0x08, 0x06, 0x9c, 0xe9, 0xdf, 0xaa, 0xf8, 0xa5, 0xe0, 0x99, 0x24, 0x5c, - 0x41, 0x15, 0xd4, 0x5a, 0xab, 0xe3, 0xaa, 0x07, 0x3e, 0x3e, 0x00, 0x69, 0x53, 0xc7, 0xdd, 0x15, - 0x25, 0x4f, 0xbc, 0x05, 0x38, 0xf4, 0xc8, 0x01, 0xa7, 0x06, 0x7d, 0xb5, 0x04, 0xac, 0x25, 0xc5, - 0x0e, 0x15, 0x08, 0x16, 0x3a, 0x02, 0xed, 0x2a, 0xc1, 0x78, 0x15, 0x5b, 0xcb, 0xda, 0x65, 0x63, - 0xd7, 0x42, 0x9a, 0xa8, 0x59, 0xea, 0x2e, 0xc8, 0x34, 0xc9, 0x27, 0x44, 0x83, 0x4c, 0x9f, 0xbe, - 0xb6, 0xa7, 0xf1, 0x94, 0x6c, 0x6e, 0xd1, 0xa2, 0x55, 0x96, 0x9f, 0x3f, 0xeb, 0x21, 0x62, 0x7a, - 0x77, 0xa9, 0x1b, 0x8a, 0xdd, 0x30, 0x92, 0x61, 0x3e, 0xa8, 0xea, 0xf8, 0x61, 0xf9, 0x09, 0x09, - 0xa6, 0x88, 0xab, 0xfe, 0x82, 0xb6, 0x67, 0x98, 0xba, 0x85, 0xa3, 0x59, 0x0c, 0xdd, 0xcf, 0xd8, - 0x79, 0x04, 0x5f, 0x0a, 0x7a, 0x6b, 0x32, 0xe2, 0x96, 0x1c, 0x47, 0xc7, 0x50, 0x40, 0x88, 0xb4, - 0x81, 0x17, 0x56, 0xfd, 0x08, 0x81, 0xc8, 0x99, 0xf5, 0x6d, 0x7d, 0x0f, 0x37, 0x22, 0x02, 0xe1, - 0x7c, 0xe6, 0x01, 0xe1, 0x16, 0x34, 0x18, 0x10, 0xce, 0xe7, 0x87, 0x04, 0x44, 0x40, 0xf5, 0xf1, - 0x03, 0xf1, 0x16, 0x0a, 0x84, 0xcf, 0x37, 0x61, 0x45, 0x14, 0x88, 0xeb, 0x61, 0xca, 0xb3, 0x2a, - 0xac, 0x99, 0x4d, 0x36, 0xeb, 0xe1, 0x13, 0xd1, 0x47, 0x06, 0x80, 0xa3, 0xaf, 0x9b, 0x41, 0x34, - 0x38, 0x3e, 0x1c, 0x11, 0x8e, 0x17, 0xaa, 0x0b, 0xc1, 0xb3, 0x12, 0x3d, 0x51, 0xc5, 0x79, 0x72, - 0x3c, 0x22, 0x0a, 0xd7, 0x3e, 0xaf, 0x91, 0x6c, 0x64, 0xaf, 0x91, 0x8f, 0x47, 0xf5, 0x1a, 0xe9, - 0xa6, 0x76, 0x28, 0x70, 0x46, 0x72, 0x0a, 0xe9, 0x43, 0xc1, 0x21, 0x23, 0xfa, 0x35, 0x09, 0x80, - 0xc4, 0x19, 0xa6, 0xfe, 0x4e, 0x4b, 0x90, 0xa1, 0x7f, 0x1d, 0xa7, 0xc9, 0x84, 0xe7, 0x34, 0x79, - 0x2b, 0xa4, 0xf7, 0xb4, 0xe6, 0x2e, 0x76, 0x79, 0xd4, 0x3d, 0x11, 0x3d, 0x67, 0xbf, 0x55, 0x69, - 0x26, 0xb4, 0x2d, 0x2a, 0x15, 0x0f, 0xf8, 0x1d, 0x76, 0x6c, 0x79, 0xb8, 0x21, 0x80, 0x8b, 0x8c, - 0xc6, 0x39, 0xfa, 0xeb, 0xf9, 0x68, 0xbd, 0x29, 0xaa, 0x03, 0x85, 0xaf, 0xac, 0x61, 0x48, 0x43, - 0x24, 0x97, 0x8a, 0xc0, 0xba, 0xe3, 0x57, 0xb4, 0x1f, 0x4f, 0x42, 0xba, 0x66, 0x54, 0x31, 0x77, - 0xde, 0x2c, 0x1c, 0x1b, 0x6f, 0x09, 0x9c, 0xe4, 0x96, 0xc0, 0x3f, 0x16, 0xd5, 0x14, 0x49, 0xea, - 0x0d, 0x0e, 0x26, 0xda, 0xc1, 0xde, 0xd6, 0x3f, 0x7d, 0x88, 0x66, 0x3b, 0xec, 0x55, 0x7c, 0xfc, - 0x0c, 0x3d, 0x03, 0x47, 0xd7, 0x5a, 0x0d, 0x43, 0xc5, 0x0d, 0x83, 0xd9, 0x62, 0xec, 0x85, 0xe7, - 0x6e, 0xab, 0x61, 0x10, 0x5a, 0xd3, 0x2a, 0xf9, 0x6f, 0xa7, 0x99, 0xb8, 0x61, 0x30, 0x43, 0x39, - 0xf9, 0x8f, 0x5e, 0x2f, 0x41, 0xca, 0xfe, 0x56, 0xdc, 0xb3, 0xe5, 0xeb, 0x51, 0x0f, 0xa6, 0xd8, - 0xc5, 0x0f, 0x43, 0xbe, 0x95, 0x07, 0x7c, 0xd6, 0x29, 0xba, 0x29, 0x7c, 0x5d, 0x50, 0x7d, 0x3e, - 0x56, 0xf8, 0xac, 0x52, 0xef, 0x88, 0x72, 0x98, 0xa5, 0x07, 0xd9, 0xd1, 0x90, 0x2c, 0x0c, 0xa0, - 0x22, 0x65, 0x98, 0xcc, 0xe7, 0xca, 0x24, 0x32, 0xcb, 0x4a, 0xe5, 0x5c, 0x51, 0x96, 0x08, 0x40, - 0x76, 0x6b, 0x62, 0x04, 0xc8, 0x2e, 0xfe, 0xbb, 0x10, 0xa0, 0x1e, 0x64, 0x1f, 0x06, 0x40, 0x1f, - 0x4d, 0xc2, 0xd4, 0xb2, 0xde, 0xb1, 0x82, 0x9c, 0xc4, 0x42, 0xce, 0xcd, 0xbf, 0x26, 0xea, 0x84, - 0x90, 0xab, 0x47, 0xf8, 0xc0, 0x7c, 0xa4, 0x39, 0x78, 0x58, 0x15, 0xa3, 0xf1, 0x66, 0x24, 0x14, - 0xd0, 0x30, 0x8c, 0xc2, 0x9c, 0x8c, 0x3c, 0xf4, 0x7a, 0x95, 0x8c, 0x7e, 0xe8, 0x0d, 0xac, 0x3b, - 0x7e, 0xfe, 0xfe, 0x75, 0x12, 0xae, 0xb0, 0xab, 0x0f, 0x5b, 0x70, 0x06, 0xb3, 0xb9, 0xef, 0x82, - 0x33, 0xb2, 0xcd, 0x6b, 0x1f, 0x2d, 0xc3, 0xb0, 0x79, 0xf5, 0x2b, 0x74, 0xc4, 0x6c, 0x0e, 0x30, - 0xb0, 0xf4, 0x63, 0x73, 0x88, 0x81, 0x65, 0x70, 0x36, 0x87, 0x1b, 0x59, 0x06, 0x64, 0xf3, 0xa1, - 0x99, 0x4e, 0x3e, 0x9f, 0x84, 0xa9, 0x5c, 0xbb, 0xdd, 0xbc, 0x5c, 0x63, 0x27, 0x47, 0x22, 0x99, - 0x4e, 0x7c, 0x07, 0x50, 0x92, 0xfb, 0x8e, 0x5f, 0x46, 0x76, 0x2b, 0xe7, 0xe8, 0x18, 0x86, 0x5b, - 0x79, 0x58, 0x81, 0xf1, 0xb3, 0xf6, 0xd5, 0x69, 0xaa, 0x88, 0x59, 0x60, 0x88, 0xcf, 0x26, 0xc2, - 0x23, 0x43, 0x84, 0x86, 0xc1, 0x51, 0xee, 0x83, 0xcc, 0xa6, 0x61, 0xee, 0x68, 0x8e, 0x2d, 0xf7, - 0x86, 0x20, 0x71, 0x62, 0xb1, 0x17, 0x16, 0x48, 0x66, 0x95, 0x7d, 0x64, 0x8f, 0x68, 0xaf, 0xd2, - 0xdb, 0xec, 0xec, 0xb4, 0xfd, 0x97, 0x04, 0x45, 0xa1, 0x47, 0xa8, 0xcb, 0xb8, 0x63, 0xe1, 0x06, - 0xd9, 0xac, 0x1c, 0x53, 0xf9, 0x44, 0x65, 0x16, 0x26, 0x59, 0xc2, 0x82, 0xde, 0xc4, 0x1d, 0xb2, - 0x05, 0x3d, 0xa6, 0x72, 0x69, 0xe8, 0x53, 0x83, 0x0c, 0x1c, 0x91, 0x23, 0x56, 0xcc, 0x40, 0xb6, - 0xb3, 0x5b, 0xaf, 0x63, 0xdc, 0x60, 0x5e, 0x49, 0xce, 0x63, 0x44, 0x2f, 0xc7, 0xc8, 0xc3, 0xcc, - 0xe1, 0x04, 0xb3, 0x98, 0x5d, 0x85, 0x0c, 0xc5, 0x50, 0x99, 0x84, 0x31, 0xc7, 0xcf, 0x92, 0xfa, - 0x91, 0xac, 0xb2, 0x45, 0xba, 0x9c, 0xb0, 0x4b, 0x7c, 0xa8, 0x5a, 0x29, 0xd3, 0xe0, 0x80, 0x85, - 0x0a, 0x0b, 0x0e, 0x58, 0x3d, 0xb7, 0x28, 0xa7, 0x94, 0x69, 0x80, 0x45, 0x35, 0xb7, 0xba, 0xb4, - 0x4e, 0x72, 0xa4, 0xd1, 0xb3, 0x59, 0xc8, 0x50, 0xb7, 0x4d, 0xf4, 0x4c, 0xda, 0x7f, 0x39, 0xd3, - 0x64, 0xcb, 0xb0, 0xc9, 0x5c, 0xd5, 0x4c, 0x6d, 0xa7, 0x13, 0xb6, 0x37, 0x46, 0xbf, 0x76, 0x2f, - 0x66, 0x2a, 0xfb, 0x3e, 0x5b, 0x3a, 0xa2, 0x72, 0xc5, 0x28, 0xff, 0x06, 0x8e, 0x6e, 0xb0, 0x03, - 0x07, 0x1d, 0x56, 0x72, 0x32, 0x78, 0x5b, 0xb5, 0xab, 0xe4, 0x79, 0xfe, 0xcb, 0xa5, 0x23, 0x6a, - 0x77, 0x61, 0x4a, 0x09, 0xc6, 0x3b, 0x2d, 0xad, 0xdd, 0xd9, 0x36, 0x5c, 0x97, 0x8b, 0x5b, 0x04, - 0x4a, 0xae, 0xb2, 0x6f, 0x54, 0xef, 0x6b, 0xe5, 0x65, 0xf0, 0xe2, 0x5d, 0x12, 0x4d, 0xb2, 0x78, - 0x49, 0xef, 0x58, 0x7a, 0x6b, 0x8b, 0x0f, 0x35, 0xd0, 0xfb, 0xa5, 0x72, 0x0f, 0xf3, 0x48, 0x4a, - 0x13, 0xf1, 0xb9, 0x49, 0xa0, 0x6e, 0x9f, 0x57, 0xd2, 0x3d, 0x90, 0xda, 0xb1, 0x65, 0x2f, 0x23, - 0xfc, 0xf1, 0x0a, 0x11, 0x38, 0xfb, 0x23, 0x34, 0x0b, 0x93, 0x7e, 0xd6, 0xf7, 0xd2, 0x26, 0xe8, - 0x3a, 0x38, 0xda, 0xc5, 0x44, 0xe7, 0xb8, 0x4a, 0xc2, 0x3b, 0xae, 0xf2, 0x83, 0x30, 0xe6, 0xf0, - 0x63, 0x5f, 0x4c, 0xe8, 0x1c, 0x8c, 0x39, 0x1c, 0x62, 0xc0, 0xdd, 0xd0, 0x65, 0xdb, 0xab, 0xee, - 0x68, 0xa6, 0x45, 0x76, 0xb2, 0x9d, 0x42, 0xe6, 0xb5, 0x0e, 0x56, 0xdd, 0xcf, 0x66, 0x6f, 0x83, - 0x94, 0x4d, 0xb5, 0xa2, 0xc0, 0x74, 0x6e, 0x79, 0x79, 0xbd, 0x42, 0xe2, 0x91, 0x2f, 0x95, 0xca, - 0x8b, 0xb4, 0x03, 0x94, 0x16, 0xcb, 0x15, 0xb5, 0x48, 0xe5, 0xbf, 0x2a, 0x27, 0x66, 0xaf, 0x65, - 0x3e, 0x53, 0x00, 0x19, 0xda, 0x3c, 0x2a, 0xed, 0xc5, 0x4b, 0xd4, 0xe0, 0x26, 0x93, 0x6b, 0x12, - 0xda, 0xa4, 0x2d, 0xbc, 0xd1, 0x42, 0xc4, 0x69, 0xd0, 0xe5, 0x66, 0xaf, 0x41, 0xe5, 0x5d, 0x51, - 0x3c, 0x00, 0x7b, 0x96, 0x14, 0x4d, 0x1f, 0x2c, 0xec, 0xd3, 0x07, 0x0a, 0x4c, 0x97, 0xca, 0xb5, - 0xa2, 0x5a, 0xce, 0x2d, 0xbb, 0x0a, 0x61, 0x9f, 0x8e, 0x48, 0xf2, 0x3a, 0x42, 0x42, 0x5f, 0x97, - 0x00, 0x28, 0x39, 0xb6, 0xa2, 0xf2, 0x87, 0x72, 0xfc, 0x6c, 0x54, 0x9d, 0xec, 0x15, 0x13, 0xa0, - 0x93, 0x4b, 0x30, 0x66, 0xb2, 0x17, 0xcc, 0xb6, 0xd7, 0xaf, 0x1c, 0xfa, 0xd7, 0x29, 0x4d, 0x75, - 0x3f, 0x47, 0xef, 0x8d, 0xa2, 0x82, 0x03, 0x09, 0x3b, 0x1c, 0x96, 0xbf, 0xca, 0x39, 0x25, 0xe0, - 0x9b, 0xd9, 0x50, 0x3d, 0x20, 0xd6, 0x06, 0xfe, 0x63, 0x9f, 0x4a, 0x08, 0x12, 0x7f, 0x57, 0xf5, - 0x27, 0xd0, 0x87, 0x8e, 0xc2, 0x34, 0x2d, 0xd1, 0x3d, 0xbe, 0xff, 0x8f, 0x2c, 0x8e, 0xe2, 0x59, - 0xd1, 0x49, 0xdb, 0x2c, 0x4c, 0xfa, 0xfc, 0x6b, 0xdc, 0x90, 0x9c, 0xfe, 0x34, 0xfe, 0x3e, 0xa7, - 0xd0, 0x8b, 0xf2, 0x78, 0x6a, 0x42, 0x62, 0x2d, 0x46, 0x5b, 0x0a, 0x46, 0xf1, 0x9f, 0x0f, 0xa9, - 0x3c, 0xfe, 0x29, 0xde, 0x63, 0xde, 0x75, 0x07, 0x43, 0x45, 0x20, 0xea, 0xe1, 0x1d, 0x97, 0x09, - 0x62, 0xeb, 0xf1, 0xa1, 0x1f, 0x07, 0x09, 0xaf, 0x3f, 0x7e, 0x1c, 0xbe, 0xc3, 0x0c, 0x48, 0xb9, - 0x3d, 0x4d, 0x6f, 0x6a, 0x1b, 0xcd, 0x08, 0xa7, 0x0c, 0x3f, 0xe4, 0x67, 0x75, 0x99, 0x67, 0xf5, - 0x5d, 0x61, 0x4d, 0xe5, 0xea, 0x0b, 0xbc, 0x91, 0x62, 0xdc, 0xc1, 0xd5, 0xf3, 0x15, 0xe2, 0x47, - 0x51, 0xa7, 0x3c, 0xd5, 0xcb, 0x89, 0x7e, 0xd7, 0x65, 0xfd, 0xf7, 0x71, 0xac, 0xbf, 0x6f, 0x50, - 0x7a, 0xe2, 0x47, 0xe0, 0x67, 0x24, 0x98, 0xc8, 0x35, 0x1a, 0x0b, 0x58, 0xb3, 0x76, 0x4d, 0xdc, - 0x40, 0x45, 0xd1, 0xee, 0x70, 0x75, 0x37, 0x8b, 0xc6, 0xfd, 0x9c, 0x78, 0x8f, 0x70, 0x50, 0xc6, - 0xfd, 0xda, 0xc0, 0xa1, 0x65, 0x28, 0x2a, 0x49, 0x2c, 0x84, 0xa3, 0x30, 0x11, 0xf1, 0x03, 0xf2, - 0x5a, 0x09, 0xa6, 0x69, 0xac, 0xce, 0x61, 0x63, 0xf2, 0x7e, 0x3f, 0x26, 0x15, 0x1e, 0x93, 0x33, - 0x61, 0xec, 0xe0, 0xc9, 0x19, 0x0a, 0x2c, 0x9e, 0xb5, 0x5b, 0xe5, 0x60, 0xb9, 0x7f, 0x60, 0x3a, - 0xe2, 0x47, 0xe6, 0x1b, 0x00, 0xe0, 0xf3, 0x90, 0xf8, 0x12, 0x78, 0x27, 0x03, 0xd0, 0xc7, 0x25, - 0x3a, 0x9e, 0x57, 0xb9, 0x03, 0xa0, 0xbc, 0x63, 0x44, 0xa2, 0x87, 0x63, 0x84, 0xd0, 0xa8, 0xf2, - 0xad, 0x88, 0x1b, 0xee, 0xcc, 0x67, 0xa1, 0xef, 0xe0, 0x3e, 0xa0, 0x96, 0x7b, 0x2e, 0xc2, 0xce, - 0x7b, 0x3f, 0x52, 0xe2, 0xbf, 0x80, 0x27, 0x6c, 0xe7, 0x5d, 0x99, 0x81, 0x63, 0x6a, 0x31, 0x57, - 0xa8, 0x94, 0x97, 0x1f, 0xf6, 0xbf, 0x95, 0x53, 0xe8, 0xd7, 0x24, 0xc8, 0xb0, 0x58, 0xc0, 0xb1, - 0x60, 0xfa, 0x5f, 0x22, 0x2a, 0x48, 0x9e, 0x91, 0x61, 0x61, 0x83, 0xd1, 0x7f, 0x8b, 0xa0, 0xf2, - 0x04, 0x8a, 0x7d, 0xc1, 0x42, 0xf4, 0x45, 0x09, 0x52, 0x64, 0xfd, 0xb4, 0x1b, 0x15, 0xa0, 0x02, - 0x5c, 0xa3, 0xb5, 0xdb, 0xb8, 0xd5, 0x70, 0xa3, 0x10, 0x2e, 0x98, 0xc6, 0x4e, 0xc5, 0xda, 0xc6, - 0xa6, 0x9d, 0xa5, 0xc3, 0xec, 0xce, 0xe1, 0x99, 0xd0, 0x17, 0x23, 0x9a, 0xa2, 0x79, 0x5e, 0x87, - 0x2c, 0xd9, 0xce, 0xec, 0xef, 0x97, 0x57, 0x05, 0xf4, 0xcb, 0x65, 0xbd, 0x75, 0xc1, 0xdf, 0x37, - 0xff, 0x24, 0x82, 0x15, 0xbb, 0x2f, 0x3d, 0x87, 0xec, 0x16, 0xf3, 0x68, 0xc6, 0xa7, 0x60, 0x7f, - 0x52, 0x02, 0xd9, 0x0b, 0x63, 0xcd, 0x42, 0x69, 0x55, 0xf8, 0x5d, 0x05, 0x92, 0xe8, 0xdf, 0x55, - 0x70, 0x12, 0x94, 0x1b, 0x61, 0xba, 0xbe, 0x8d, 0xeb, 0x17, 0x4a, 0x2d, 0xc7, 0x44, 0x44, 0x11, - 0xee, 0x4a, 0xe5, 0xfd, 0x67, 0xcf, 0xf2, 0x90, 0xf2, 0x96, 0x6a, 0x8e, 0x6f, 0x7e, 0xa2, 0x02, - 0x3a, 0xa5, 0x07, 0x4c, 0x99, 0x03, 0xe6, 0xee, 0x81, 0x4a, 0x8d, 0x86, 0x4c, 0x79, 0xb0, 0xeb, - 0x52, 0x2a, 0xab, 0xe4, 0x7e, 0xc1, 0xb5, 0x6a, 0xb1, 0xb0, 0x3e, 0xef, 0x74, 0xbe, 0xaa, 0x2c, - 0xa1, 0xaf, 0x25, 0x21, 0x4b, 0xc9, 0xea, 0x74, 0x85, 0x99, 0xf6, 0x9f, 0x0a, 0x49, 0xec, 0x3b, - 0x15, 0x82, 0xde, 0x2e, 0xec, 0x9e, 0xec, 0x32, 0x82, 0xd5, 0x13, 0xd0, 0x53, 0xee, 0x82, 0x2c, - 0x05, 0xd9, 0x31, 0x52, 0x9e, 0x08, 0xe8, 0x27, 0xac, 0x18, 0xd5, 0xc9, 0x2e, 0xe8, 0xaa, 0xdc, - 0x87, 0x8c, 0xf8, 0xe7, 0x1c, 0x6f, 0x9e, 0x80, 0xec, 0x92, 0xde, 0xb1, 0x0c, 0xf3, 0x32, 0x7a, - 0x53, 0x02, 0xb2, 0xe7, 0xb0, 0xd9, 0xd1, 0x8d, 0xd6, 0x3e, 0xab, 0xdf, 0xb5, 0x30, 0xd1, 0x36, - 0xf1, 0x9e, 0x6e, 0xec, 0x76, 0x7c, 0x31, 0x05, 0x7c, 0x49, 0x0a, 0x82, 0x31, 0x6d, 0xd7, 0xda, - 0x36, 0x4c, 0x2f, 0xc0, 0x92, 0xf3, 0xac, 0x9c, 0x00, 0xa0, 0xff, 0xcb, 0xda, 0x0e, 0x66, 0xa7, - 0x15, 0x7c, 0x29, 0x8a, 0x02, 0x29, 0x4b, 0xdf, 0xc1, 0xec, 0x7c, 0x1b, 0xf9, 0xaf, 0xcc, 0x40, - 0x96, 0x9c, 0x77, 0x29, 0x35, 0xd8, 0xf9, 0x36, 0xe7, 0x11, 0xfd, 0xa6, 0x04, 0x13, 0x8b, 0xd8, - 0x62, 0xa4, 0x76, 0xfc, 0x7e, 0xef, 0x7d, 0xa2, 0xbd, 0x37, 0xb5, 0x8e, 0xf3, 0x99, 0xbb, 0x33, - 0xc5, 0x27, 0x7a, 0x67, 0xed, 0x24, 0xdf, 0x91, 0x57, 0xf4, 0xae, 0xa4, 0xe8, 0x69, 0x11, 0xc6, - 0xcc, 0x39, 0x1f, 0x81, 0x81, 0xb2, 0x35, 0xb6, 0xc7, 0x72, 0x30, 0x25, 0x7c, 0x75, 0xcf, 0x92, - 0x58, 0x31, 0xaa, 0x9b, 0x5b, 0xf0, 0x84, 0x47, 0x7f, 0x4a, 0xe2, 0x17, 0xaf, 0xbf, 0x97, 0x60, - 0xa2, 0xba, 0x6d, 0x5c, 0x64, 0x04, 0xa0, 0x1f, 0x14, 0x83, 0xea, 0x6a, 0x18, 0xdf, 0xeb, 0x82, - 0xc9, 0x4b, 0x08, 0x0e, 0x14, 0x8c, 0x9e, 0x90, 0xa2, 0xc2, 0xe4, 0x23, 0x6e, 0xe8, 0x01, 0x7e, - 0x95, 0x57, 0x40, 0x96, 0x51, 0xcd, 0x2c, 0x2b, 0xe1, 0x00, 0x3b, 0x99, 0xfd, 0x0d, 0x4c, 0xf1, - 0x0d, 0x8c, 0x86, 0x7c, 0x70, 0xe3, 0x46, 0x10, 0xe8, 0x20, 0x49, 0x7c, 0x4e, 0x1d, 0xe0, 0xf3, - 0x43, 0x00, 0x1e, 0x7d, 0x3b, 0x21, 0x6a, 0x7f, 0x74, 0x39, 0xe0, 0x52, 0x70, 0xa0, 0x88, 0x1c, - 0x7d, 0x8b, 0x8b, 0x9f, 0x9f, 0x3f, 0x7a, 0x05, 0xa4, 0x16, 0xf4, 0x26, 0xb6, 0xd7, 0xef, 0xd9, - 0xca, 0xe6, 0x26, 0x89, 0xa8, 0x51, 0x0c, 0xbe, 0xba, 0xf3, 0x24, 0xc8, 0xce, 0x8e, 0xad, 0x61, - 0xad, 0xea, 0xad, 0x96, 0xeb, 0x54, 0xb2, 0x2f, 0x9d, 0x37, 0x75, 0x85, 0x7a, 0x7a, 0xda, 0x14, - 0xcc, 0xb1, 0xda, 0x03, 0xfa, 0xcb, 0x8d, 0x30, 0xbd, 0x71, 0xd9, 0xc2, 0x1d, 0x96, 0x8b, 0x55, - 0x9b, 0x52, 0xbb, 0x52, 0xd1, 0xb3, 0x42, 0xbe, 0x9f, 0x21, 0x15, 0x46, 0xe3, 0xb9, 0x36, 0xc0, - 0x1c, 0xe5, 0x18, 0xc8, 0xe5, 0x4a, 0xa1, 0x48, 0xef, 0xb8, 0xac, 0xe5, 0xd4, 0x5a, 0xb1, 0x20, - 0x6f, 0x91, 0x8b, 0xfd, 0x4a, 0xcb, 0x34, 0xf5, 0xe1, 0x62, 0x6d, 0x7d, 0xb5, 0x54, 0x2e, 0x17, - 0x0b, 0xf2, 0x36, 0x7a, 0x9f, 0x04, 0x13, 0xf6, 0xbc, 0xca, 0x41, 0xa7, 0xc2, 0xdd, 0x8b, 0x68, - 0xb4, 0x9a, 0x97, 0xbd, 0xb9, 0xa3, 0xf3, 0x18, 0x09, 0xa7, 0xff, 0x2a, 0x3c, 0xbd, 0x21, 0x6c, - 0xf3, 0xd1, 0x12, 0x8c, 0xd5, 0xa6, 0xde, 0xec, 0xc6, 0x2a, 0xad, 0x76, 0xa5, 0xf6, 0xc0, 0x54, - 0xea, 0x89, 0xe9, 0x1f, 0x08, 0x4d, 0x7a, 0xfa, 0x10, 0x17, 0x0d, 0xd7, 0xa5, 0x61, 0xe1, 0x8a, - 0xbe, 0x29, 0x41, 0x66, 0xad, 0x4d, 0x90, 0x7b, 0xce, 0xe7, 0x92, 0xb1, 0x6f, 0x77, 0xd4, 0x56, - 0x52, 0x4d, 0xfe, 0x22, 0x78, 0xd5, 0x4b, 0x50, 0xee, 0x66, 0xdb, 0x3e, 0xd4, 0x1d, 0xe3, 0xc6, - 0xd0, 0x03, 0xbe, 0x84, 0x13, 0xbe, 0xdd, 0xdf, 0x5b, 0xe1, 0x8a, 0x86, 0xde, 0xd1, 0x36, 0x9a, - 0xb8, 0xd8, 0xaa, 0x9b, 0x97, 0x69, 0xa3, 0xe9, 0x66, 0xf3, 0xfe, 0x17, 0xca, 0x7d, 0x90, 0xee, - 0x58, 0x97, 0x9b, 0xfb, 0x77, 0x9a, 0x03, 0xab, 0xaa, 0xda, 0xd9, 0x55, 0xfa, 0x15, 0xfa, 0x4e, - 0x42, 0xd4, 0x97, 0x95, 0x7c, 0x4b, 0x59, 0x13, 0xec, 0x98, 0xb1, 0xad, 0x75, 0x5c, 0xc7, 0x0c, - 0xfb, 0x3f, 0x7a, 0x4a, 0xc8, 0xe1, 0x34, 0xb8, 0xec, 0x11, 0xdc, 0x0b, 0x92, 0x84, 0xb1, 0x82, - 0x71, 0xb1, 0x45, 0x30, 0xbf, 0x83, 0xf3, 0xc2, 0x21, 0xad, 0x49, 0x78, 0xad, 0xe9, 0xe5, 0x7a, - 0x82, 0xfe, 0xa3, 0xf0, 0x66, 0x33, 0x69, 0xa5, 0x53, 0x55, 0xf0, 0x75, 0x57, 0xc1, 0x62, 0xe5, - 0x33, 0xfd, 0x87, 0x6d, 0x45, 0x87, 0xd5, 0x13, 0x8d, 0x9f, 0xb9, 0x03, 0x5f, 0x17, 0x80, 0x9e, - 0x95, 0x20, 0x55, 0x30, 0x8d, 0x36, 0xfa, 0x9d, 0x44, 0x84, 0x3d, 0xb0, 0x86, 0x69, 0xb4, 0x6b, - 0x24, 0xde, 0x8b, 0x3b, 0x05, 0xe0, 0xd2, 0x94, 0x33, 0x30, 0xd6, 0x36, 0x3a, 0xba, 0xe5, 0x4c, - 0xab, 0xa6, 0xf7, 0xdd, 0xe7, 0x4d, 0x25, 0x7f, 0x95, 0x65, 0x52, 0xdd, 0xec, 0xb6, 0x1e, 0x23, - 0x1c, 0xb5, 0xd9, 0x64, 0x73, 0xd5, 0x89, 0x4b, 0xd3, 0x95, 0x8a, 0x7e, 0xc9, 0x0f, 0xec, 0x3d, - 0x3c, 0xb0, 0x37, 0xf4, 0x60, 0xb8, 0x19, 0x74, 0x41, 0x70, 0x44, 0xab, 0xf5, 0xeb, 0x5c, 0x90, - 0xef, 0xe7, 0x40, 0x3e, 0x29, 0x54, 0x67, 0xfc, 0x1d, 0xe6, 0xeb, 0x59, 0x80, 0xb2, 0xb6, 0xa7, - 0x6f, 0x51, 0x9b, 0xc9, 0xe7, 0x9c, 0x01, 0x8f, 0x59, 0x37, 0x7e, 0xc6, 0x87, 0xf3, 0x19, 0xc8, - 0x32, 0x58, 0x59, 0x1b, 0x5e, 0xca, 0xb5, 0xc1, 0x2b, 0x85, 0x6a, 0xa8, 0x4b, 0x96, 0xea, 0xe4, - 0xe7, 0x42, 0x50, 0x25, 0xbb, 0x42, 0x50, 0xf5, 0x5c, 0x9e, 0x05, 0x05, 0xa6, 0x42, 0xef, 0x16, - 0x8e, 0xe2, 0xe0, 0xa3, 0xc7, 0xd7, 0xa2, 0x00, 0x50, 0xef, 0x84, 0xac, 0xe1, 0x9a, 0x79, 0xa4, - 0xc0, 0xf5, 0x40, 0xa9, 0xb5, 0x69, 0xa8, 0x4e, 0x4e, 0xc1, 0xf8, 0x0c, 0x42, 0x74, 0xc4, 0x0f, - 0xf4, 0x27, 0x24, 0x38, 0xbe, 0xe8, 0x1c, 0x51, 0xb4, 0xdb, 0x71, 0x5e, 0xb7, 0xb6, 0x97, 0xf5, - 0xd6, 0x85, 0x0e, 0xfa, 0xb7, 0x62, 0x33, 0x79, 0x1f, 0xfe, 0xc9, 0x68, 0xf8, 0xf3, 0x7e, 0x83, - 0x55, 0x1e, 0xb5, 0xfb, 0x82, 0x4a, 0xe9, 0x4d, 0x6d, 0x00, 0x80, 0x77, 0x43, 0x86, 0x12, 0xca, - 0xba, 0xe5, 0x6c, 0x20, 0x7e, 0x6e, 0x49, 0x2a, 0xfb, 0xc2, 0xe7, 0x13, 0x74, 0x8e, 0xc3, 0x71, - 0xfe, 0x40, 0x94, 0xc5, 0xef, 0x37, 0x78, 0x07, 0x64, 0x19, 0xa7, 0x95, 0x69, 0x7f, 0x2f, 0x96, - 0x8f, 0x28, 0x00, 0x99, 0x15, 0x63, 0x0f, 0xd7, 0x0c, 0x39, 0x61, 0xff, 0xb7, 0xe9, 0xab, 0x19, - 0x72, 0x12, 0xfd, 0x0f, 0x80, 0x31, 0xd7, 0xfd, 0xf7, 0x33, 0x49, 0x27, 0xc2, 0x38, 0x31, 0x53, - 0x53, 0x66, 0x08, 0xef, 0xa6, 0xbf, 0x56, 0xd8, 0xf0, 0xe9, 0xba, 0xe5, 0x76, 0x57, 0x26, 0x18, - 0xbc, 0xf7, 0x6d, 0x42, 0x86, 0x50, 0xd1, 0x5a, 0xe2, 0xef, 0x6a, 0x5f, 0x49, 0x3a, 0xf7, 0x38, - 0x78, 0x44, 0x90, 0xfd, 0x3f, 0xfe, 0x4e, 0x7b, 0x6f, 0x83, 0x81, 0x31, 0xd7, 0x97, 0xc2, 0x5f, - 0x6c, 0x1c, 0xba, 0xf3, 0x1a, 0xd8, 0xee, 0x90, 0x63, 0xd0, 0xdd, 0x1c, 0x16, 0xdb, 0x5b, 0x8d, - 0x52, 0x53, 0xfc, 0x5c, 0xfe, 0x7d, 0x7a, 0xd5, 0x57, 0x2b, 0x82, 0x03, 0x08, 0x17, 0xae, 0xf2, - 0x41, 0x9e, 0xa9, 0x27, 0x03, 0x9a, 0x6a, 0xd7, 0x20, 0xc8, 0xc5, 0xa7, 0x5d, 0x2e, 0xe6, 0x39, - 0x2e, 0x9e, 0x12, 0x2f, 0x3a, 0x7e, 0xb6, 0x7d, 0x2d, 0x09, 0xe3, 0xd4, 0xcf, 0x39, 0xd7, 0x6c, - 0x76, 0x5d, 0x70, 0xbc, 0xcf, 0xb5, 0xf4, 0x3f, 0x0b, 0xbb, 0x87, 0xb9, 0xad, 0x72, 0xcb, 0x8e, - 0xed, 0x8a, 0x42, 0x31, 0x03, 0x4f, 0x5f, 0x82, 0x46, 0x12, 0x72, 0x75, 0xc2, 0xd6, 0xbc, 0xab, - 0x26, 0xde, 0xd3, 0xf1, 0x45, 0x74, 0x55, 0xc8, 0x12, 0x14, 0xbd, 0x45, 0xf8, 0x1c, 0xa2, 0xaf, - 0xc8, 0x00, 0x1e, 0xdf, 0x0b, 0x13, 0x4d, 0x2f, 0x13, 0x1b, 0x11, 0x51, 0xd7, 0x88, 0xe8, 0x2b, - 0x46, 0xf5, 0x67, 0x17, 0x5c, 0xe5, 0x05, 0x53, 0x11, 0x3f, 0x63, 0xbf, 0x9a, 0x81, 0xb1, 0xb5, - 0x56, 0xa7, 0xdd, 0xb4, 0x17, 0xa5, 0xff, 0x28, 0xb9, 0xf1, 0x57, 0x5f, 0xce, 0x85, 0x9c, 0xfa, - 0xa1, 0x5d, 0x6c, 0x3a, 0x7b, 0x4a, 0xf4, 0xa1, 0x77, 0xf4, 0x4b, 0xf4, 0x07, 0x7e, 0x1b, 0x73, - 0x8e, 0x67, 0x3d, 0xef, 0x68, 0xee, 0x54, 0x1a, 0x1e, 0x98, 0xb4, 0x04, 0x63, 0x6d, 0xbd, 0x6e, - 0xed, 0x9a, 0x6e, 0x9c, 0xc6, 0xdb, 0xc4, 0x4a, 0x59, 0xa5, 0x5f, 0xa9, 0xee, 0xe7, 0x48, 0x83, - 0x2c, 0x4b, 0xdc, 0x67, 0x0e, 0xdc, 0x77, 0x25, 0x81, 0x3d, 0x67, 0xd6, 0x4c, 0x4b, 0xef, 0x38, - 0x61, 0x5e, 0xd9, 0x93, 0xad, 0x14, 0xe9, 0xbf, 0x35, 0xb3, 0xc9, 0xcc, 0xcf, 0x5e, 0x02, 0x7a, - 0x9f, 0x0b, 0x77, 0x81, 0x83, 0xfb, 0xf6, 0x08, 0x2d, 0x8f, 0x06, 0xf9, 0xd9, 0x01, 0x16, 0xa2, - 0x57, 0xc2, 0x8b, 0xd4, 0x5c, 0xad, 0xb8, 0xbe, 0x5c, 0x5a, 0x29, 0xd5, 0xd6, 0x8b, 0xdf, 0x9f, - 0x2f, 0x16, 0x0b, 0xc5, 0x82, 0xdc, 0x20, 0xb7, 0x1b, 0xb9, 0x2b, 0x7e, 0x7e, 0x24, 0x60, 0x5c, - 0xf4, 0x46, 0x02, 0x37, 0x01, 0xfd, 0xba, 0xb0, 0xd3, 0xb4, 0xdb, 0xf0, 0x3e, 0x6b, 0xfd, 0x5e, - 0xf6, 0x92, 0x67, 0x84, 0xbc, 0x9f, 0xfb, 0xd5, 0x70, 0x88, 0xcc, 0x7d, 0xe7, 0x0f, 0x40, 0x9a, - 0x2c, 0xbd, 0xd1, 0xef, 0x91, 0xe0, 0x9a, 0xed, 0xa6, 0x56, 0xc7, 0x68, 0x27, 0xc2, 0x8d, 0x04, - 0x1b, 0xf6, 0xd7, 0xde, 0x8d, 0x04, 0xec, 0x51, 0x39, 0x09, 0x69, 0xf2, 0x97, 0x69, 0xfc, 0x63, - 0xbd, 0x96, 0xfb, 0x2a, 0xcd, 0xc2, 0x3b, 0x06, 0x86, 0xda, 0x64, 0xa8, 0x95, 0x80, 0x91, 0x19, - 0x80, 0x53, 0x30, 0x4d, 0xd1, 0x46, 0x21, 0xb1, 0x50, 0xc2, 0x61, 0x14, 0xc5, 0xaf, 0x27, 0xff, - 0x22, 0x05, 0xe9, 0x6a, 0xbb, 0xa9, 0x5b, 0xe8, 0x57, 0x92, 0x43, 0xc1, 0xcc, 0xd4, 0x5a, 0x5b, - 0x38, 0x00, 0x33, 0xd5, 0x7e, 0xa7, 0xd2, 0x2c, 0x9e, 0x21, 0x33, 0x25, 0x60, 0xc8, 0xac, 0xe1, - 0x4b, 0x16, 0x67, 0xc8, 0x54, 0xce, 0xb0, 0x33, 0x33, 0xe9, 0x1e, 0x07, 0xe0, 0xe8, 0xb7, 0xa4, - 0x59, 0x3d, 0x4e, 0xcc, 0xcc, 0xde, 0xc1, 0x4e, 0xa2, 0x00, 0x64, 0xe6, 0x2b, 0xb5, 0x5a, 0x65, - 0x45, 0x3e, 0xa2, 0x64, 0x41, 0xaa, 0x55, 0x56, 0xe5, 0x84, 0x32, 0x0e, 0xe9, 0x52, 0xb9, 0x5c, - 0x54, 0xe5, 0xa4, 0xfd, 0xb7, 0x56, 0xaa, 0x2d, 0x17, 0x65, 0x09, 0xbd, 0x53, 0x78, 0xe8, 0xe5, - 0xeb, 0x8e, 0x53, 0xbc, 0xc4, 0x06, 0xe1, 0x60, 0x7a, 0xe2, 0x17, 0xae, 0xff, 0x20, 0x41, 0x7a, - 0x05, 0x9b, 0x5b, 0x18, 0xfd, 0x50, 0x04, 0x5b, 0xe0, 0xa6, 0x6e, 0x76, 0xe8, 0x49, 0x22, 0xcf, - 0x16, 0xe8, 0x4f, 0x53, 0xae, 0x87, 0xa9, 0x0e, 0xae, 0x1b, 0xad, 0x86, 0x93, 0x89, 0x05, 0x87, - 0xe2, 0x12, 0xd1, 0x93, 0x11, 0x21, 0x23, 0x84, 0x0e, 0xc5, 0xa0, 0x17, 0x05, 0x98, 0x5e, 0xb5, - 0xc6, 0x0f, 0xcc, 0xff, 0x91, 0xec, 0x8f, 0xda, 0x97, 0xd1, 0x93, 0xc2, 0x46, 0xda, 0x5b, 0x21, - 0x43, 0xc4, 0xd4, 0x99, 0xaf, 0xf4, 0xd6, 0xc7, 0x2c, 0x8f, 0x32, 0x0f, 0x57, 0x74, 0xc8, 0xe5, - 0xeb, 0xb8, 0x61, 0x77, 0x5d, 0xb5, 0xaf, 0x52, 0xd8, 0x9f, 0x1d, 0xfd, 0x99, 0x1f, 0xc0, 0x7b, - 0x79, 0x00, 0x6f, 0xec, 0xc1, 0x4a, 0xbb, 0x41, 0xc1, 0xd7, 0xd0, 0xd8, 0xcd, 0xa8, 0x36, 0x0d, - 0xd7, 0xb8, 0xe8, 0x3c, 0xdb, 0xef, 0xb6, 0xad, 0x9d, 0x26, 0x79, 0xc7, 0x5c, 0x58, 0x9c, 0x67, - 0x65, 0x0e, 0xb2, 0x5a, 0xeb, 0x32, 0x79, 0x95, 0x0a, 0x69, 0xb5, 0x93, 0x09, 0xbd, 0xde, 0x45, - 0xfe, 0x01, 0x0e, 0xf9, 0x5b, 0xc4, 0xc8, 0x8d, 0x1f, 0xf8, 0xbf, 0xcb, 0x40, 0x7a, 0x55, 0xeb, - 0x58, 0x18, 0x7d, 0x49, 0x12, 0x45, 0xfe, 0x46, 0x98, 0xde, 0x34, 0xea, 0xbb, 0x1d, 0xdc, 0xe0, - 0x3b, 0x65, 0x57, 0xea, 0x30, 0x30, 0x57, 0x4e, 0x82, 0xec, 0x24, 0xb2, 0x62, 0x1d, 0x6b, 0xfd, - 0xbe, 0x74, 0x72, 0x66, 0xb9, 0xb3, 0xaa, 0x99, 0x56, 0x65, 0x93, 0xa4, 0xb9, 0x67, 0x96, 0xfd, - 0x89, 0x1c, 0xf4, 0x99, 0x10, 0xe8, 0xb3, 0xc1, 0xd0, 0x8f, 0x09, 0x40, 0xaf, 0xe4, 0x60, 0x6c, - 0x53, 0x6f, 0x62, 0xf2, 0xc1, 0x78, 0x8f, 0x68, 0x57, 0x6c, 0x7b, 0xc2, 0xe6, 0xbd, 0x3b, 0x26, - 0x2d, 0xe8, 0x4d, 0xac, 0xba, 0x9f, 0xa1, 0x65, 0xba, 0xd9, 0xef, 0x46, 0xbc, 0x4f, 0xf8, 0x22, - 0xde, 0x2b, 0x90, 0x6a, 0x68, 0x96, 0x46, 0x58, 0x3f, 0xa9, 0x92, 0xff, 0xfc, 0xde, 0x91, 0xd4, - 0xbd, 0x77, 0xf4, 0xb8, 0x14, 0x4d, 0xff, 0x39, 0xa4, 0x05, 0xf4, 0x9f, 0x0d, 0x07, 0x0e, 0xea, - 0x05, 0xe6, 0x3e, 0xdb, 0x30, 0xd4, 0x35, 0x13, 0x5b, 0xab, 0xfe, 0xed, 0x99, 0xb4, 0xca, 0x27, - 0x92, 0x1d, 0xef, 0x4e, 0x55, 0xdb, 0xc1, 0xa4, 0xb2, 0xbc, 0xfd, 0x8e, 0xed, 0x71, 0xee, 0x4b, - 0xf7, 0xb4, 0x6d, 0x7a, 0xd8, 0xda, 0xb6, 0x57, 0x1b, 0xe3, 0xef, 0x74, 0x6f, 0x48, 0x81, 0x94, - 0xdf, 0xb5, 0x5e, 0xd0, 0xca, 0xf6, 0x9f, 0x84, 0x37, 0xbf, 0x98, 0xf6, 0xda, 0xb5, 0x0e, 0x57, - 0xd7, 0x46, 0x94, 0x12, 0xb1, 0x4d, 0xb6, 0xa0, 0xb6, 0x8d, 0xe4, 0x80, 0x8e, 0xe3, 0x87, 0x60, - 0x1c, 0x7c, 0x1e, 0x8e, 0xa8, 0x32, 0xf2, 0x29, 0x06, 0xf7, 0xd9, 0x31, 0x0a, 0xa4, 0x3c, 0xbb, - 0xd2, 0xaf, 0x0a, 0x7b, 0x02, 0x51, 0xfe, 0x84, 0x3a, 0x05, 0x44, 0x9b, 0x2a, 0x89, 0xc5, 0x82, - 0x0b, 0xa9, 0x36, 0x7e, 0x64, 0xbe, 0xe9, 0xb7, 0x1e, 0xe4, 0x0e, 0x8c, 0x0d, 0x6f, 0xb6, 0x0f, - 0xb5, 0x30, 0xd3, 0x66, 0xf7, 0x31, 0x2a, 0x44, 0xe3, 0xb7, 0x98, 0xfd, 0x39, 0xb4, 0xe2, 0x11, - 0x1c, 0x89, 0x92, 0x20, 0x43, 0xf7, 0x0f, 0xd0, 0x6f, 0x09, 0xab, 0x4c, 0x5b, 0xed, 0xf0, 0x0e, - 0x04, 0xee, 0x73, 0x14, 0x53, 0x02, 0xe7, 0x68, 0x90, 0x8a, 0xe4, 0x68, 0xc0, 0xfb, 0x0b, 0x0b, - 0xf4, 0xa3, 0x9e, 0x37, 0xf3, 0x0f, 0x7b, 0x95, 0x18, 0xa5, 0x87, 0xf5, 0x24, 0x28, 0x7e, 0xbc, - 0x9f, 0x4d, 0xc1, 0x24, 0xad, 0xfa, 0xbc, 0xde, 0xd8, 0xc2, 0x16, 0xfa, 0x87, 0xef, 0x22, 0xd4, - 0x95, 0x32, 0x4c, 0x5e, 0x24, 0x64, 0xd3, 0xb8, 0xe3, 0xcc, 0x20, 0x11, 0x7e, 0xe1, 0x0b, 0x6d, - 0xa7, 0x13, 0x67, 0x9d, 0xfb, 0x1e, 0x7d, 0x40, 0x78, 0x43, 0xc5, 0x0f, 0x1a, 0x2b, 0x31, 0x5e, - 0x59, 0x12, 0xdb, 0x56, 0xe9, 0x4b, 0xd6, 0x08, 0x3c, 0xd0, 0xf9, 0xa8, 0x77, 0xf9, 0x08, 0xe2, - 0x14, 0x34, 0xcf, 0x8d, 0x10, 0x05, 0x9f, 0x32, 0x60, 0xc8, 0x01, 0xf1, 0xc4, 0x8e, 0x96, 0xf4, - 0xa9, 0x3a, 0x7e, 0xce, 0xbf, 0x91, 0x5e, 0x4e, 0xb0, 0xa0, 0xe3, 0x66, 0xa3, 0x83, 0xcc, 0x83, - 0x4f, 0x65, 0x4e, 0x41, 0x66, 0x93, 0x14, 0xc6, 0x44, 0x34, 0xf0, 0x96, 0x0c, 0x96, 0x0d, 0xbd, - 0x21, 0x29, 0xba, 0x55, 0xc3, 0x4c, 0x63, 0x0e, 0xb5, 0x43, 0x81, 0xe9, 0x8d, 0x42, 0x5b, 0x25, - 0xe1, 0x35, 0xc7, 0x8f, 0xd2, 0xdb, 0x25, 0x98, 0x64, 0xd1, 0xe6, 0x72, 0x4d, 0x7d, 0xab, 0xe5, - 0x3f, 0xec, 0x38, 0x70, 0x0f, 0x51, 0x6e, 0x87, 0xb4, 0x66, 0x97, 0xc6, 0x1c, 0xf4, 0x50, 0x4f, - 0x15, 0x48, 0xea, 0x53, 0x69, 0xc6, 0x08, 0xb1, 0x45, 0x3c, 0xc1, 0x76, 0x68, 0x1e, 0x61, 0x6c, - 0x91, 0xbe, 0x95, 0xc7, 0x8f, 0xd8, 0x97, 0x25, 0x38, 0xc6, 0x08, 0x38, 0x87, 0x4d, 0x4b, 0xaf, - 0x6b, 0x4d, 0x8a, 0xdc, 0xab, 0x13, 0xc3, 0x80, 0x6e, 0x09, 0xa6, 0xf6, 0xfc, 0xc5, 0x32, 0x08, - 0x67, 0x7b, 0x42, 0xc8, 0x11, 0xa0, 0xf2, 0x1f, 0x46, 0x88, 0xd1, 0xc0, 0x71, 0x95, 0x2b, 0x73, - 0x84, 0x31, 0x1a, 0x84, 0x89, 0x88, 0x1f, 0xe2, 0x5f, 0x4a, 0xd1, 0xb0, 0x25, 0x9e, 0xfa, 0xfc, - 0x9c, 0x30, 0xb6, 0x6b, 0x30, 0x41, 0xb0, 0xa4, 0x1f, 0x32, 0xab, 0x41, 0x88, 0x10, 0xbb, 0x7a, - 0x87, 0x45, 0x58, 0x73, 0xbf, 0x55, 0xfd, 0xe5, 0xa0, 0xf3, 0x00, 0xde, 0x2b, 0xbf, 0x92, 0x4e, - 0x04, 0x29, 0xe9, 0xa4, 0x98, 0x92, 0x7e, 0x8b, 0xf0, 0xd1, 0xba, 0xde, 0x64, 0x1f, 0x5c, 0x3c, - 0xc4, 0x0e, 0x55, 0xf5, 0xaf, 0x3d, 0x7e, 0xb9, 0x78, 0x7d, 0xaa, 0x3b, 0x1e, 0xf2, 0x87, 0x86, - 0x32, 0x3f, 0xf6, 0xeb, 0x03, 0xa9, 0x4b, 0x1f, 0x1c, 0x60, 0x3e, 0x7c, 0x33, 0x1c, 0xa5, 0x55, - 0xe4, 0x5d, 0xb2, 0xe8, 0x35, 0x9b, 0xdd, 0xc9, 0xe8, 0xc3, 0x03, 0x08, 0x41, 0xbf, 0x60, 0xcd, - 0x61, 0x4a, 0x2e, 0xda, 0x64, 0x37, 0xaa, 0x80, 0x1c, 0x5e, 0x8c, 0xe7, 0xaf, 0xa5, 0xe8, 0x6c, - 0x77, 0x8d, 0x44, 0x26, 0x44, 0x7f, 0x9e, 0x1a, 0xc6, 0x88, 0xf0, 0x20, 0xa4, 0x2c, 0xe7, 0x3a, - 0xe0, 0xde, 0x86, 0x09, 0xaf, 0x4a, 0x2f, 0xa6, 0x21, 0xbe, 0x64, 0x2d, 0x1d, 0x51, 0xc9, 0x97, - 0xca, 0x49, 0x38, 0xba, 0xa1, 0xd5, 0x2f, 0x6c, 0x99, 0xc6, 0x6e, 0xab, 0x91, 0x37, 0x9a, 0x86, - 0x49, 0x8d, 0x4e, 0x24, 0x7e, 0x23, 0xff, 0x42, 0x39, 0xed, 0x4c, 0x1d, 0xd2, 0xfd, 0xa6, 0x0e, - 0x4b, 0x47, 0xd8, 0xe4, 0x41, 0xb9, 0xc3, 0x55, 0x3a, 0x99, 0x50, 0xa5, 0xb3, 0x74, 0xc4, 0x51, - 0x3b, 0x4a, 0x01, 0xc6, 0x1a, 0xfa, 0x1e, 0xd9, 0x47, 0x26, 0x06, 0xff, 0x7e, 0x47, 0x75, 0x0a, - 0xfa, 0x1e, 0xdd, 0x75, 0x5e, 0x3a, 0xa2, 0xba, 0x5f, 0x2a, 0x8b, 0x30, 0x4e, 0x6c, 0xf6, 0xa4, - 0x98, 0xb1, 0x48, 0xc7, 0x70, 0x96, 0x8e, 0xa8, 0xde, 0xb7, 0xf6, 0xec, 0x23, 0x45, 0x1c, 0xdc, - 0x1f, 0x70, 0xf6, 0xc2, 0x13, 0x91, 0xf6, 0xc2, 0x6d, 0x5e, 0xd0, 0xdd, 0xf0, 0xe3, 0x90, 0xae, - 0x13, 0x0e, 0x27, 0x19, 0x87, 0xe9, 0xa3, 0x72, 0x2f, 0xa4, 0x76, 0x34, 0xd3, 0x59, 0x02, 0xdf, - 0xd8, 0xbf, 0xdc, 0x15, 0xcd, 0xbc, 0x60, 0x23, 0x68, 0x7f, 0x35, 0x9f, 0x85, 0x34, 0x61, 0x9c, - 0xfb, 0x07, 0x3d, 0xcb, 0xa6, 0x21, 0x79, 0xa3, 0x65, 0x0f, 0xfb, 0x35, 0xc3, 0x39, 0x05, 0x50, - 0x1f, 0x86, 0xcc, 0xf1, 0x1e, 0xaf, 0xd2, 0x3e, 0x8f, 0xd7, 0x3f, 0x1b, 0x60, 0x6e, 0xd1, 0x4d, - 0x69, 0xf0, 0x12, 0xb9, 0xc9, 0x5d, 0x9d, 0xef, 0x3c, 0x46, 0xd4, 0x1a, 0x51, 0x67, 0x1d, 0x7d, - 0xc8, 0x8b, 0x5f, 0x79, 0xbc, 0x35, 0x05, 0x33, 0x36, 0x21, 0xd4, 0x17, 0x9c, 0x0f, 0x6b, 0x8a, - 0x3e, 0x36, 0x94, 0xc9, 0x65, 0x8f, 0x11, 0x41, 0xea, 0x39, 0x22, 0xec, 0x3b, 0x09, 0x94, 0xea, - 0x73, 0x12, 0x28, 0x1d, 0xcd, 0x40, 0xf7, 0x87, 0x7e, 0xf9, 0x59, 0xe5, 0xe5, 0xe7, 0xee, 0x00, - 0x80, 0x7a, 0xf1, 0x65, 0x28, 0x13, 0x90, 0xdf, 0x73, 0x25, 0xa5, 0xca, 0x49, 0xca, 0x03, 0x83, - 0x13, 0x12, 0xbf, 0xb4, 0xbc, 0x3f, 0x05, 0x2f, 0xf2, 0x88, 0x29, 0xe3, 0x8b, 0x4c, 0x50, 0x3e, - 0x33, 0x14, 0x41, 0xb9, 0xc3, 0xbb, 0x30, 0xa8, 0xcf, 0x62, 0xdf, 0xc9, 0x17, 0xb7, 0xc4, 0xfc, - 0xa9, 0xf0, 0x09, 0x86, 0x6e, 0xa0, 0x5c, 0xde, 0x04, 0x08, 0xcb, 0x71, 0xc8, 0x50, 0x0d, 0xe3, - 0x5c, 0x77, 0x4e, 0x9f, 0x22, 0xaa, 0x1b, 0xb1, 0x73, 0x0f, 0xa2, 0xb4, 0x8d, 0x40, 0x7e, 0x98, - 0xe1, 0xa1, 0xb6, 0x6b, 0xb6, 0x4a, 0x2d, 0xcb, 0x40, 0x3f, 0x3a, 0x14, 0xc1, 0x71, 0x7d, 0xc9, - 0xa4, 0x41, 0x7c, 0xc9, 0x06, 0x32, 0x43, 0x38, 0x2d, 0x38, 0x14, 0x33, 0x44, 0x40, 0xe5, 0xf1, - 0xe3, 0xf7, 0x0e, 0x09, 0x8e, 0xb3, 0xd5, 0xd0, 0x3c, 0x3f, 0x85, 0x43, 0x0f, 0x0f, 0x03, 0xc8, - 0x63, 0xce, 0x3c, 0x86, 0xdd, 0x72, 0x4c, 0x1e, 0xf8, 0x33, 0x06, 0xa1, 0x51, 0x39, 0xb9, 0xf5, - 0x5a, 0x17, 0x85, 0x43, 0x41, 0x4a, 0x2c, 0x18, 0x67, 0x04, 0x32, 0xe2, 0xc7, 0xec, 0xe7, 0x24, - 0xc8, 0xb0, 0x5b, 0x07, 0xd6, 0x62, 0x71, 0x40, 0xe0, 0x23, 0x30, 0x09, 0x6c, 0x7c, 0x45, 0x0e, - 0xf7, 0x1f, 0xdf, 0x96, 0xd7, 0xe1, 0xc4, 0xf3, 0x47, 0x4f, 0x4a, 0xcc, 0xb2, 0xb2, 0xac, 0x59, - 0xf8, 0x12, 0xfa, 0x29, 0x09, 0xb2, 0x55, 0x6c, 0xd9, 0x9a, 0x49, 0x1c, 0xa3, 0x60, 0x9b, 0xb9, - 0xe2, 0x5b, 0xbb, 0x8d, 0xd3, 0xd5, 0x58, 0x54, 0x1d, 0x47, 0xe8, 0x9a, 0x63, 0x34, 0x8d, 0x5a, - 0xc7, 0x85, 0x55, 0x3e, 0x82, 0xf3, 0xce, 0xd7, 0xc3, 0x38, 0x21, 0x83, 0xc0, 0xf1, 0x11, 0x1f, - 0x34, 0xbf, 0x98, 0x88, 0x05, 0x1b, 0x7b, 0xf8, 0x22, 0xa1, 0xf9, 0xc9, 0xec, 0x65, 0x42, 0x64, - 0xf8, 0xb2, 0x97, 0x69, 0x1d, 0x95, 0x7e, 0x15, 0xe1, 0xae, 0x26, 0xb7, 0x59, 0x43, 0x45, 0x56, - 0xec, 0x12, 0x8d, 0x7e, 0x75, 0x8f, 0xe0, 0x0a, 0x16, 0x09, 0xc6, 0xaa, 0xf6, 0x72, 0xc3, 0x1e, - 0x53, 0xce, 0x1f, 0x1c, 0xca, 0xde, 0x83, 0x55, 0xc4, 0x8e, 0xe6, 0x70, 0x64, 0x78, 0x43, 0x54, - 0x84, 0x8e, 0x16, 0x56, 0x79, 0xfc, 0x78, 0xbc, 0x93, 0xe2, 0x41, 0x64, 0x19, 0xbd, 0x59, 0x02, - 0x69, 0x11, 0x5b, 0x43, 0x3a, 0x39, 0x22, 0x7a, 0x0a, 0x81, 0x1f, 0xba, 0x42, 0x83, 0x05, 0x70, - 0x0c, 0x23, 0x34, 0xcf, 0x2d, 0xe2, 0xe1, 0x74, 0x20, 0xb1, 0x28, 0x01, 0x42, 0x04, 0xc4, 0x8f, - 0xda, 0x7b, 0x28, 0x6a, 0xd4, 0x82, 0xf5, 0x23, 0x43, 0xd0, 0x88, 0xa3, 0x9d, 0xbc, 0x3b, 0x0c, - 0x24, 0x65, 0x1c, 0x56, 0x7f, 0xeb, 0x55, 0xf9, 0x48, 0x7c, 0x0c, 0xc1, 0xee, 0xec, 0xdb, 0xb8, - 0x7e, 0x01, 0x37, 0xd0, 0xbf, 0x3a, 0x38, 0x74, 0x33, 0x90, 0xad, 0xd3, 0xd2, 0x08, 0x78, 0x63, - 0xaa, 0xf3, 0x18, 0xe1, 0xa6, 0x74, 0x5e, 0x11, 0xd1, 0xcf, 0x47, 0x78, 0x53, 0xba, 0x40, 0xf5, - 0xf1, 0x23, 0xf3, 0xbb, 0x74, 0x92, 0x51, 0xaa, 0x1b, 0x2d, 0xf4, 0xef, 0x0e, 0x0e, 0xcb, 0xd5, - 0x30, 0xae, 0xd7, 0x8d, 0x56, 0x69, 0x47, 0xdb, 0x72, 0xcc, 0xa8, 0x5e, 0x82, 0xf3, 0xb6, 0xb8, - 0x63, 0x3c, 0xa2, 0xb3, 0xad, 0x19, 0x2f, 0x61, 0xd0, 0xc9, 0x84, 0x4d, 0xfa, 0x61, 0x4d, 0x26, - 0x7a, 0xd4, 0x1d, 0x3f, 0x64, 0x1f, 0xf6, 0x5c, 0x28, 0xa8, 0x2a, 0x7c, 0x41, 0x58, 0x32, 0x06, - 0x19, 0xce, 0xfc, 0xad, 0x38, 0x94, 0xe1, 0x2c, 0x84, 0x80, 0xf8, 0x71, 0xfc, 0x55, 0x0f, 0xc7, - 0xd8, 0xed, 0x18, 0x07, 0x40, 0x67, 0x78, 0xd3, 0xc3, 0x01, 0xd1, 0x39, 0x9c, 0x29, 0xe2, 0x33, - 0x2c, 0xd8, 0x14, 0x9b, 0xf1, 0xa0, 0x1f, 0x1e, 0x06, 0x38, 0x77, 0x0f, 0xb2, 0x29, 0x46, 0xb7, - 0xc4, 0x22, 0xdc, 0xc5, 0xb3, 0x8f, 0x83, 0x76, 0x29, 0x43, 0x41, 0x50, 0xec, 0x2e, 0x1e, 0x91, - 0xfa, 0xe3, 0x07, 0xf0, 0xa7, 0x25, 0x98, 0x26, 0xfb, 0x5c, 0x4d, 0xac, 0x99, 0x54, 0x51, 0x0e, - 0xc5, 0x1b, 0xf3, 0x9d, 0xc2, 0x61, 0xf2, 0x79, 0x3e, 0x78, 0x74, 0x0c, 0x05, 0x0a, 0xb1, 0xfb, - 0x5d, 0x05, 0x49, 0x18, 0x89, 0x29, 0x50, 0x76, 0x49, 0x60, 0x22, 0x3e, 0x1c, 0x3c, 0x22, 0xba, - 0x7d, 0xf1, 0xcc, 0x70, 0x3a, 0xdb, 0x88, 0xdd, 0xbe, 0x44, 0x88, 0x18, 0x41, 0x30, 0xf6, 0xdb, - 0x99, 0x29, 0xb0, 0x46, 0xae, 0xaa, 0x7a, 0x2a, 0xe5, 0x1e, 0x7e, 0xf8, 0xe4, 0x50, 0xdc, 0x7c, - 0x0e, 0x10, 0x39, 0x51, 0x81, 0x94, 0x69, 0x5c, 0xa4, 0x66, 0xa9, 0x29, 0x95, 0xfc, 0x27, 0x53, - 0x7e, 0xa3, 0xb9, 0xbb, 0xd3, 0xea, 0x90, 0xb9, 0xe3, 0x94, 0xea, 0x3c, 0x2a, 0xd7, 0xc3, 0xd4, - 0x45, 0xdd, 0xda, 0x5e, 0xc2, 0x5a, 0x03, 0x9b, 0xaa, 0x71, 0x91, 0x5d, 0x0f, 0xcb, 0x27, 0xf2, - 0x7b, 0xb0, 0x02, 0xf3, 0x4b, 0x72, 0x7f, 0xd5, 0x48, 0x4e, 0x4a, 0x44, 0x99, 0x79, 0x06, 0x53, - 0x15, 0xbf, 0xc0, 0xbc, 0x57, 0x82, 0x71, 0xd5, 0xb8, 0xc8, 0x84, 0xe4, 0xdf, 0x1f, 0xae, 0x8c, - 0x44, 0x5e, 0xe8, 0xd1, 0xfb, 0xc8, 0x1c, 0xf2, 0x47, 0xbe, 0xd0, 0x0b, 0xad, 0x7e, 0x24, 0xee, - 0xf1, 0x93, 0xaa, 0x71, 0xb1, 0x8a, 0x2d, 0xda, 0x23, 0xd0, 0xfa, 0x90, 0x3c, 0xf9, 0xf4, 0x0e, - 0x2d, 0x90, 0xad, 0xc3, 0xdd, 0x67, 0xf4, 0x0e, 0xe1, 0x6b, 0x9e, 0x78, 0x06, 0xb9, 0x24, 0x0e, - 0x05, 0xa2, 0xb7, 0x0a, 0xdd, 0xee, 0x24, 0x46, 0x41, 0xfc, 0x28, 0xfd, 0xb8, 0x04, 0x13, 0xaa, - 0x71, 0xd1, 0x1e, 0x1a, 0x16, 0xf4, 0x66, 0x73, 0x38, 0x23, 0x64, 0xd4, 0xc9, 0xbf, 0xc3, 0x06, - 0x87, 0x8a, 0x91, 0x4f, 0xfe, 0xfb, 0x10, 0x10, 0x3f, 0x0c, 0x8f, 0xd3, 0xce, 0xe2, 0x8c, 0xd0, - 0xad, 0xe1, 0xe0, 0x30, 0x68, 0x87, 0x70, 0xc9, 0x38, 0xb4, 0x0e, 0x11, 0x44, 0xc1, 0x48, 0x76, - 0x4e, 0xa6, 0xf3, 0x64, 0x98, 0x1f, 0x6e, 0x9f, 0x78, 0x57, 0x34, 0xf7, 0x1a, 0x36, 0xec, 0x72, - 0x84, 0x0c, 0x05, 0x8d, 0x08, 0x6e, 0x34, 0x02, 0x34, 0xc4, 0x8f, 0xc7, 0x1f, 0x49, 0x30, 0x49, - 0x49, 0x78, 0x81, 0xcc, 0x02, 0x06, 0xea, 0x54, 0xfe, 0x16, 0x1c, 0x4e, 0xa7, 0x0a, 0xa1, 0x20, - 0x7e, 0x10, 0xff, 0x39, 0x49, 0xe6, 0x71, 0x03, 0x9c, 0x51, 0x0c, 0x42, 0x70, 0xe0, 0xc9, 0xd8, - 0x10, 0xcf, 0x29, 0x0e, 0x32, 0x19, 0x3b, 0xa4, 0xb3, 0x8a, 0x8f, 0xbb, 0xbd, 0x68, 0x98, 0x18, - 0x1c, 0xa0, 0x2b, 0x0c, 0x11, 0x86, 0x01, 0xbb, 0xc2, 0x21, 0x21, 0xf1, 0x57, 0x12, 0x00, 0x25, - 0x60, 0xc5, 0xd8, 0xc3, 0xe8, 0xe9, 0xa1, 0x2c, 0x7c, 0xbb, 0x5d, 0x43, 0xa5, 0x3e, 0xae, 0xa1, - 0x11, 0x4f, 0xfb, 0x47, 0xb5, 0x04, 0xfa, 0xb8, 0xbc, 0x12, 0x78, 0xcd, 0x66, 0x8c, 0x96, 0xc0, - 0xf0, 0xfa, 0xe3, 0xc7, 0xf8, 0x8b, 0x74, 0x36, 0xe7, 0x9d, 0x62, 0xfa, 0xe5, 0xa1, 0xa0, 0xec, - 0x5b, 0xfd, 0x4b, 0xfc, 0xea, 0xff, 0x00, 0xd8, 0x0e, 0x3a, 0x47, 0xec, 0x77, 0x3a, 0x29, 0xfe, - 0x39, 0xe2, 0xe1, 0x9d, 0x42, 0xfa, 0x91, 0x14, 0x1c, 0x65, 0x4a, 0xe4, 0xbb, 0x01, 0xe2, 0x88, - 0x67, 0x49, 0x38, 0x25, 0xd9, 0x07, 0xe5, 0x61, 0x19, 0xa4, 0xa2, 0x98, 0x32, 0x05, 0xc8, 0x1b, - 0x89, 0x75, 0x23, 0x53, 0xbc, 0xd4, 0xd6, 0x5a, 0x0d, 0xf1, 0x80, 0x8f, 0x7d, 0x80, 0x77, 0x6c, - 0x8d, 0x12, 0x6f, 0x6b, 0xec, 0x61, 0x99, 0x8c, 0xbc, 0x73, 0x4d, 0x58, 0x46, 0xc9, 0x1d, 0xf9, - 0xce, 0x75, 0x70, 0xdd, 0xf1, 0xa3, 0xf4, 0x2e, 0x09, 0x52, 0x55, 0xc3, 0xb4, 0xd0, 0x13, 0x51, - 0x7a, 0x27, 0xe5, 0xbc, 0x07, 0x92, 0xf3, 0xac, 0xe4, 0xb9, 0xab, 0xaf, 0x4e, 0x85, 0x9f, 0xa7, - 0xd3, 0x2c, 0x8d, 0x84, 0x03, 0xb7, 0xeb, 0xf7, 0xdd, 0x81, 0x15, 0x35, 0x68, 0x03, 0xe5, 0x5f, - 0x35, 0xd8, 0x89, 0x38, 0xb6, 0xa0, 0x0d, 0x81, 0x35, 0x8f, 0xc0, 0xee, 0x3b, 0xc1, 0xfc, 0x52, - 0xc9, 0x8d, 0x80, 0x4f, 0x50, 0x97, 0x91, 0xb2, 0xb6, 0x83, 0x87, 0xe4, 0x32, 0x4c, 0x62, 0x0e, - 0x4a, 0x5e, 0xcc, 0xc1, 0xa8, 0x1d, 0x8a, 0x9e, 0x72, 0xa4, 0x24, 0x8d, 0xba, 0x43, 0x85, 0xd4, - 0x1d, 0x3f, 0x30, 0x9f, 0xb7, 0x47, 0x3e, 0xb2, 0x86, 0xcc, 0xb5, 0x1a, 0x2c, 0x88, 0xdb, 0xdf, - 0x1d, 0xf6, 0xde, 0xcd, 0xbe, 0x30, 0x6f, 0x7c, 0xb8, 0xc8, 0x74, 0xf7, 0x0d, 0x76, 0xf3, 0x34, - 0x64, 0x1c, 0x39, 0x79, 0x99, 0x89, 0x74, 0x8b, 0x9d, 0xfb, 0x1d, 0x7a, 0x36, 0x9a, 0x39, 0x87, - 0x14, 0xd1, 0xc5, 0xb8, 0x98, 0x87, 0xd4, 0x08, 0x86, 0x1e, 0x01, 0xea, 0xfe, 0x65, 0x78, 0x19, - 0xed, 0xbf, 0x44, 0x30, 0xa2, 0x29, 0xdb, 0xbd, 0xfa, 0xf1, 0xb0, 0xbc, 0x8c, 0xfa, 0x11, 0x30, - 0x82, 0x10, 0x67, 0x69, 0xb6, 0xc9, 0x4b, 0x5c, 0xf0, 0xd0, 0x17, 0x92, 0xb1, 0x2b, 0x6f, 0xf1, - 0x6b, 0x73, 0x3d, 0xba, 0xc2, 0xb5, 0x77, 0x14, 0x47, 0xd7, 0xb0, 0xe2, 0x46, 0x60, 0x4e, 0x48, - 0x12, 0x17, 0xe5, 0xf3, 0x7a, 0xc3, 0xda, 0x1e, 0x92, 0xa3, 0xff, 0x45, 0xbb, 0x2c, 0xe7, 0xfe, - 0x39, 0xf2, 0x80, 0x9e, 0x4f, 0x44, 0x0a, 0x5f, 0xe1, 0xb2, 0x84, 0x90, 0x15, 0xc0, 0xe2, 0x08, - 0x41, 0x27, 0x42, 0xcb, 0x1b, 0xa1, 0x44, 0x9f, 0xd3, 0x1b, 0xd8, 0x78, 0x01, 0x4a, 0x34, 0xa1, - 0x6b, 0x78, 0x12, 0x1d, 0x56, 0xdc, 0xbf, 0x50, 0x89, 0x76, 0x59, 0x32, 0x24, 0x89, 0x0e, 0x2d, - 0x6f, 0x04, 0xb1, 0xd1, 0x81, 0xcd, 0xaf, 0x97, 0xf5, 0xd6, 0x05, 0xf4, 0xd1, 0xb4, 0x73, 0xf3, - 0xdd, 0x79, 0xdd, 0xda, 0x66, 0xc7, 0xdc, 0x3f, 0x2c, 0x7c, 0x47, 0xc6, 0x00, 0x47, 0xd9, 0x4f, - 0x00, 0x58, 0xec, 0x46, 0x2a, 0x37, 0x66, 0x8e, 0x2f, 0x45, 0xc9, 0xc1, 0x94, 0xde, 0xb2, 0xb0, - 0xd9, 0xd2, 0x9a, 0x0b, 0x4d, 0x6d, 0xab, 0x33, 0x93, 0x25, 0x47, 0x33, 0xaf, 0xea, 0x1a, 0xbc, - 0x4b, 0xbe, 0x3c, 0x2a, 0xff, 0x85, 0xf0, 0x5c, 0x33, 0x62, 0xc8, 0x9f, 0x53, 0x82, 0x91, 0x58, - 0xdc, 0xf0, 0x4f, 0xdf, 0x88, 0x66, 0x7c, 0xb1, 0x01, 0x99, 0xeb, 0x06, 0x23, 0xf2, 0x4c, 0xd1, - 0xdf, 0x78, 0xa9, 0xab, 0xf1, 0xee, 0xd4, 0x23, 0x35, 0x64, 0xc3, 0x8c, 0x08, 0xe9, 0x23, 0x38, - 0xf9, 0x91, 0x86, 0x2b, 0x9c, 0xf0, 0x75, 0xed, 0x36, 0xd6, 0x4c, 0xad, 0x55, 0xc7, 0x11, 0xa4, - 0x39, 0x6c, 0x2e, 0xb9, 0x00, 0x63, 0x7a, 0xdd, 0x68, 0x55, 0xf5, 0x57, 0x39, 0x57, 0xb9, 0x84, - 0xc7, 0x3e, 0x25, 0x1c, 0x29, 0xb1, 0x2f, 0x54, 0xf7, 0x5b, 0xa5, 0x04, 0xe3, 0x75, 0xcd, 0x6c, - 0x54, 0x7d, 0x97, 0x5b, 0xdf, 0xd2, 0xbf, 0xa0, 0xbc, 0xf3, 0x89, 0xea, 0x7d, 0xad, 0x54, 0x78, - 0x26, 0x66, 0xba, 0x4e, 0xff, 0x06, 0x16, 0x56, 0xf0, 0x3e, 0xe2, 0x78, 0x6e, 0x73, 0xc7, 0xc4, - 0x4d, 0x72, 0x73, 0x26, 0xed, 0x76, 0xe3, 0xaa, 0x97, 0x80, 0xde, 0xeb, 0x97, 0xe6, 0x15, 0x5e, - 0x9a, 0x5f, 0x19, 0x20, 0x12, 0xfb, 0xd0, 0x18, 0xca, 0x9c, 0xf8, 0xed, 0xae, 0x60, 0xae, 0x72, - 0x82, 0x79, 0xef, 0x80, 0x54, 0xc4, 0x2f, 0x99, 0xbf, 0x97, 0x81, 0x29, 0x7a, 0x98, 0x9c, 0xb1, - 0x13, 0xfd, 0x34, 0xb9, 0xac, 0xcd, 0x3a, 0x8b, 0x2f, 0xa3, 0xea, 0xc1, 0x07, 0x3a, 0x19, 0xa4, - 0x0b, 0xf8, 0x32, 0xeb, 0xef, 0xf6, 0xdf, 0xa8, 0x7b, 0xa4, 0x0e, 0x5d, 0x73, 0x94, 0xa6, 0x51, - 0xef, 0x91, 0x86, 0x57, 0x1f, 0x3f, 0x3e, 0x3f, 0x2f, 0x81, 0x94, 0x6b, 0x34, 0xc4, 0xe3, 0x3b, - 0x05, 0x43, 0x71, 0x2d, 0x4c, 0x38, 0x7d, 0xe6, 0xac, 0x0b, 0x89, 0x3f, 0x29, 0xaa, 0xc1, 0xc9, - 0xe5, 0x4d, 0xae, 0x31, 0x72, 0x0b, 0x6e, 0x48, 0xdd, 0xf1, 0x83, 0xf2, 0xcb, 0x59, 0xd6, 0x69, - 0xe6, 0x0d, 0xe3, 0x02, 0x39, 0x96, 0xf0, 0x84, 0x04, 0xe9, 0x05, 0x6c, 0xd5, 0xb7, 0x87, 0xd4, - 0x67, 0x76, 0xcd, 0xa6, 0xd3, 0x67, 0xf6, 0xdd, 0x3c, 0xd9, 0x7f, 0x62, 0xe8, 0x90, 0x35, 0x47, - 0x48, 0x1a, 0x75, 0xb8, 0xc6, 0xd0, 0xda, 0xe3, 0x07, 0xe7, 0x79, 0x09, 0xa6, 0x5d, 0xb3, 0x11, - 0xc5, 0xe4, 0x67, 0x5f, 0x70, 0xc6, 0x40, 0xf4, 0x99, 0x68, 0x21, 0x55, 0x5c, 0x9e, 0xf2, 0x2d, - 0x8b, 0xd9, 0x5a, 0x17, 0x21, 0xd8, 0x8a, 0x18, 0x81, 0x23, 0x58, 0x16, 0x4b, 0x30, 0x46, 0x08, - 0x2a, 0xe8, 0x7b, 0xc4, 0x4d, 0x8b, 0xb3, 0xde, 0x3d, 0x3a, 0x14, 0xeb, 0xdd, 0xbd, 0xbc, 0xf5, - 0x4e, 0x30, 0x84, 0xa1, 0x63, 0xbc, 0x8b, 0xe8, 0xb7, 0x60, 0x7f, 0x3f, 0x74, 0xdb, 0x5d, 0x04, - 0xbf, 0x85, 0x3e, 0xf5, 0x8f, 0xe0, 0x8a, 0xde, 0x93, 0x4c, 0xd9, 0x3a, 0x9b, 0x57, 0xe8, 0x51, - 0x05, 0x52, 0xe7, 0xec, 0x3f, 0x5f, 0xf0, 0x2e, 0xaa, 0x78, 0x74, 0x08, 0x07, 0xe1, 0xef, 0x87, - 0x14, 0xb9, 0x8c, 0x37, 0xd5, 0x15, 0x72, 0x33, 0x74, 0x27, 0xcd, 0x26, 0x44, 0x25, 0xdf, 0x45, - 0x0d, 0x56, 0xc6, 0x15, 0x31, 0x37, 0x3c, 0x37, 0x3c, 0xe5, 0x38, 0x64, 0xec, 0x72, 0xdd, 0x65, - 0x16, 0x7b, 0x8a, 0x62, 0x7c, 0x17, 0xa0, 0x2d, 0x7e, 0xe4, 0xbf, 0x40, 0xee, 0xe4, 0x21, 0x31, - 0x55, 0x9f, 0x1c, 0x02, 0xbc, 0x01, 0x6c, 0x39, 0x30, 0xec, 0xef, 0x3a, 0x08, 0xec, 0x6e, 0x00, - 0xd7, 0x91, 0x3a, 0xd1, 0x0a, 0xd0, 0x30, 0x92, 0x93, 0xbf, 0x19, 0xe6, 0xf8, 0xf7, 0xf0, 0x30, - 0xd1, 0x4d, 0x71, 0x42, 0x7f, 0x20, 0x74, 0x86, 0xe8, 0x10, 0x38, 0x30, 0x3a, 0x87, 0xe4, 0x12, - 0xf8, 0xc7, 0x12, 0x4c, 0x54, 0xbd, 0x0b, 0xe4, 0xc4, 0x6f, 0x28, 0x88, 0x0c, 0x91, 0x3d, 0xd6, - 0x72, 0xf1, 0x21, 0xa7, 0x06, 0x0f, 0x19, 0xca, 0xb3, 0xce, 0x47, 0xff, 0xa8, 0x43, 0x86, 0x8a, - 0x12, 0x12, 0x3f, 0x90, 0x9f, 0xa2, 0x37, 0x82, 0xe4, 0xea, 0x96, 0xbe, 0x87, 0xd1, 0xe3, 0x31, - 0x2a, 0xd2, 0xe3, 0x90, 0x31, 0x36, 0x37, 0x3b, 0xec, 0x66, 0xc1, 0x29, 0x95, 0x3d, 0x79, 0x57, - 0xba, 0x53, 0x70, 0xd9, 0x95, 0xee, 0x11, 0x83, 0x0a, 0xee, 0x63, 0x28, 0x6d, 0xd0, 0xa8, 0x83, - 0x0a, 0x8a, 0x91, 0x31, 0x82, 0xb0, 0xc1, 0x60, 0x73, 0x8f, 0x99, 0x6c, 0xde, 0xcc, 0x8c, 0x04, - 0xf8, 0xe0, 0xd8, 0xce, 0xc2, 0xa4, 0xcf, 0x22, 0xe0, 0x04, 0xa6, 0xe7, 0xd2, 0xa2, 0x9e, 0x35, - 0x76, 0x59, 0x36, 0x74, 0x7b, 0x41, 0x04, 0x3b, 0xb0, 0x08, 0x11, 0x23, 0xb9, 0xf7, 0xc5, 0x19, - 0xf2, 0x46, 0x84, 0xd5, 0xfb, 0xfd, 0x58, 0x55, 0x78, 0xac, 0xce, 0x88, 0xb0, 0x49, 0x6c, 0x08, - 0x14, 0x5a, 0x4e, 0xbe, 0xc3, 0x85, 0x4b, 0xe5, 0xe0, 0xba, 0x7f, 0x60, 0x3a, 0xe2, 0x47, 0xec, - 0x83, 0x12, 0xbd, 0xfc, 0x21, 0xb7, 0xa7, 0xe9, 0x4d, 0x72, 0x40, 0x7c, 0x08, 0x57, 0x10, 0xfe, - 0xad, 0x1f, 0x94, 0x73, 0x3c, 0x28, 0x0f, 0x8a, 0x30, 0x83, 0xa3, 0x28, 0x00, 0x9b, 0x97, 0xfb, - 0x6d, 0xe6, 0x34, 0x8a, 0xe8, 0x95, 0xdd, 0x91, 0xd8, 0xd8, 0x7b, 0xbf, 0x31, 0xfd, 0x93, 0x2e, - 0x48, 0x0f, 0x73, 0x20, 0x15, 0x0f, 0x4a, 0x57, 0x34, 0xac, 0x96, 0xa3, 0x63, 0xa5, 0xcc, 0xc0, - 0xb1, 0x72, 0xa5, 0xb6, 0x9e, 0x5b, 0x2f, 0xe4, 0x6a, 0xb9, 0x73, 0xa5, 0xe2, 0xf9, 0xf5, 0xf9, - 0xe5, 0x4a, 0xfe, 0xac, 0x2c, 0xa1, 0x5f, 0xa1, 0x63, 0x60, 0xd5, 0xd8, 0x35, 0xeb, 0xc3, 0x9a, - 0x6d, 0x76, 0x48, 0x61, 0xac, 0xd3, 0xb1, 0xa7, 0xa8, 0x8e, 0xeb, 0x9e, 0x3f, 0xa6, 0x43, 0x5c, - 0xbf, 0x8e, 0x96, 0x1a, 0xb2, 0xe3, 0x7a, 0x5f, 0x0a, 0xe2, 0xef, 0x62, 0xdf, 0x92, 0x00, 0x16, - 0x4d, 0x63, 0xb7, 0x5d, 0x31, 0x1b, 0xd8, 0x44, 0xcf, 0x79, 0xab, 0xbe, 0x5f, 0x18, 0xc2, 0x64, - 0x65, 0x15, 0x60, 0xcb, 0x2d, 0x9c, 0xe9, 0xa9, 0xdb, 0xc5, 0xd6, 0x78, 0x1e, 0x51, 0xaa, 0xaf, - 0x0c, 0xfe, 0x82, 0xc0, 0xef, 0xe3, 0x31, 0x0e, 0x1b, 0x79, 0xbc, 0xe2, 0x86, 0xb9, 0xea, 0x7b, - 0xa7, 0x8b, 0x75, 0x8d, 0xc3, 0xfa, 0xc1, 0x03, 0x50, 0x12, 0x3f, 0xe6, 0xdf, 0x96, 0x60, 0x82, - 0xee, 0xc5, 0x52, 0x9e, 0xfe, 0x8d, 0x07, 0xfa, 0x2f, 0x0f, 0x01, 0xf4, 0x35, 0x98, 0x34, 0xbc, - 0xd2, 0xe9, 0xc8, 0xe8, 0xb7, 0xae, 0x85, 0xc2, 0xee, 0xa3, 0x4b, 0xe5, 0x8a, 0x41, 0x1f, 0xf4, - 0x23, 0xaf, 0xf2, 0xc8, 0xdf, 0x1b, 0xc2, 0x6f, 0x5f, 0x89, 0xc3, 0x84, 0xfe, 0xf7, 0x5d, 0xe8, - 0xd7, 0x38, 0xe8, 0x73, 0x07, 0x21, 0x25, 0x7e, 0xec, 0x1f, 0x73, 0x0d, 0xf4, 0xee, 0xf6, 0x49, - 0x2c, 0x9b, 0x26, 0xaf, 0x1b, 0x70, 0x81, 0xc1, 0xd3, 0x16, 0x80, 0xd4, 0x34, 0x24, 0x75, 0x87, - 0x86, 0xa4, 0xde, 0x18, 0x68, 0x09, 0x11, 0x5a, 0x51, 0xfc, 0x38, 0xfc, 0xfa, 0x4b, 0x20, 0x5d, - 0xc0, 0x1b, 0xbb, 0x5b, 0xe8, 0x2d, 0x12, 0x64, 0x9b, 0xc6, 0x56, 0xa9, 0xb5, 0x69, 0xb0, 0x86, - 0x25, 0x9c, 0x86, 0x29, 0x0a, 0xa4, 0xb6, 0xb1, 0xe6, 0x34, 0x95, 0xfc, 0x57, 0x6e, 0x84, 0x69, - 0xfb, 0xd7, 0xb9, 0xa0, 0xd8, 0x8d, 0x3e, 0xd9, 0x95, 0x6a, 0x4f, 0x50, 0x2d, 0xc3, 0xd2, 0x9a, - 0x2a, 0xae, 0x1b, 0x66, 0x83, 0x9e, 0x16, 0x49, 0xab, 0x5c, 0x9a, 0x8d, 0x37, 0x79, 0x26, 0xfe, - 0x0b, 0x69, 0x92, 0xc1, 0x4b, 0x50, 0xae, 0x87, 0xa9, 0x4d, 0xdd, 0xec, 0x58, 0x34, 0x77, 0x8d, - 0x3a, 0xb8, 0xa4, 0x55, 0x3e, 0xd1, 0xa6, 0xc7, 0x97, 0x70, 0x0e, 0x9b, 0xe4, 0x72, 0xa1, 0xb4, - 0xda, 0x95, 0x6a, 0xd3, 0xd3, 0xd4, 0x7c, 0x85, 0x8d, 0x51, 0x7a, 0xfc, 0x69, 0x76, 0x8d, 0xde, - 0xb3, 0x5d, 0xd4, 0x38, 0xad, 0x91, 0x4b, 0xb4, 0x6b, 0xb4, 0x13, 0x56, 0x77, 0x9b, 0xcd, 0x2a, - 0xae, 0xe7, 0xb6, 0x8c, 0x19, 0xa0, 0x35, 0xf2, 0xa9, 0x0a, 0x82, 0xb1, 0xdd, 0x76, 0xd5, 0xd2, - 0xac, 0xdd, 0xce, 0xcc, 0x04, 0xdd, 0x4f, 0x72, 0x9e, 0x95, 0x13, 0x00, 0x0d, 0xe3, 0x62, 0x8b, - 0xbd, 0x9d, 0xa4, 0xfe, 0x46, 0x5e, 0x8a, 0xbd, 0x6c, 0xa6, 0x22, 0x3b, 0x45, 0x63, 0xd8, 0x51, - 0x7f, 0xae, 0x4f, 0x4b, 0x00, 0xd6, 0xb6, 0x89, 0xb5, 0x46, 0x4f, 0xb8, 0x5e, 0x01, 0xc7, 0x9b, - 0xc6, 0x56, 0xe7, 0xbc, 0x6e, 0x6d, 0x7b, 0x40, 0x2c, 0x39, 0x00, 0xa6, 0xd5, 0x80, 0xb7, 0xca, - 0x83, 0x70, 0x95, 0xf3, 0xe6, 0xfc, 0xb6, 0xd1, 0xc4, 0x35, 0x13, 0xe3, 0x2e, 0x7c, 0xd3, 0x6a, - 0x58, 0x16, 0x65, 0x0e, 0x52, 0xf6, 0x6b, 0x76, 0x79, 0x3c, 0xe2, 0xe4, 0x9e, 0x88, 0xd9, 0x1c, - 0x13, 0x31, 0x95, 0xe4, 0x53, 0xee, 0x82, 0x2b, 0x8d, 0x8b, 0xad, 0x65, 0x63, 0x6b, 0x49, 0xeb, - 0xe4, 0xb5, 0x4d, 0xac, 0x62, 0x7a, 0x6c, 0xca, 0x30, 0x89, 0x18, 0x8c, 0xa9, 0x41, 0xaf, 0x95, - 0x39, 0x50, 0xea, 0xda, 0x26, 0x5e, 0xe6, 0x01, 0xa0, 0x92, 0xd1, 0xe3, 0x8d, 0x0d, 0xbb, 0x9d, - 0xba, 0xe6, 0x00, 0x91, 0xa5, 0x07, 0x51, 0xfd, 0x69, 0x36, 0xa0, 0xf6, 0x73, 0xc1, 0x03, 0x64, - 0x8c, 0xe4, 0xea, 0x4a, 0xdd, 0x27, 0xd2, 0xe3, 0xfd, 0x44, 0x1a, 0xba, 0x45, 0xda, 0x85, 0x75, - 0xc2, 0x0f, 0xeb, 0xe7, 0xd2, 0x90, 0xaa, 0x5e, 0x6e, 0xd5, 0xd1, 0x1b, 0x7d, 0xc3, 0xdf, 0x69, - 0x38, 0x66, 0xd2, 0x32, 0x6b, 0xa6, 0xb6, 0x87, 0xcd, 0x0e, 0x5e, 0x26, 0x76, 0x94, 0x04, 0x29, - 0xb3, 0xe7, 0x3b, 0x5b, 0x7e, 0x3b, 0x17, 0xf4, 0x76, 0x71, 0xa7, 0x6d, 0x5d, 0x5e, 0xb6, 0xf1, - 0x48, 0xd2, 0x28, 0x50, 0x5c, 0xa2, 0x72, 0x3f, 0x20, 0xcb, 0xbc, 0x5c, 0x33, 0x1c, 0xfc, 0x54, - 0xbc, 0x63, 0x58, 0xd8, 0x69, 0x14, 0xed, 0xcd, 0x21, 0x39, 0xd0, 0x6f, 0xa6, 0x7c, 0xba, 0xf5, - 0x5e, 0x5e, 0xb7, 0xde, 0xd8, 0x03, 0x7a, 0xbb, 0x69, 0x01, 0x9a, 0xf4, 0x95, 0x90, 0xa5, 0xf2, - 0xec, 0xac, 0x52, 0xae, 0xe9, 0xf1, 0xbd, 0x27, 0xf1, 0xaa, 0x93, 0xdb, 0xee, 0x5b, 0x0d, 0xbc, - 0xa7, 0xd7, 0xb1, 0xe7, 0x4f, 0xe6, 0x3c, 0xbb, 0x30, 0xd5, 0x58, 0xc9, 0x7e, 0xcd, 0xc3, 0xd2, - 0x08, 0x0f, 0xe8, 0x5f, 0x5b, 0xa4, 0x8d, 0x5d, 0xcb, 0x16, 0xb1, 0x52, 0xab, 0x42, 0xa4, 0x8e, - 0xa9, 0xa2, 0x90, 0x1c, 0xca, 0x3c, 0x5c, 0xcd, 0xbf, 0x5d, 0xe2, 0x75, 0x22, 0x15, 0xc8, 0xd0, - 0x3c, 0xfb, 0xc4, 0x29, 0xdb, 0x4f, 0x9c, 0xc6, 0xba, 0xc4, 0x09, 0xbd, 0xde, 0x1d, 0x78, 0x1e, - 0xe0, 0x06, 0x9e, 0x5b, 0xc4, 0x50, 0x18, 0x49, 0xb8, 0xac, 0x0c, 0x65, 0x39, 0xfa, 0x69, 0x9f, - 0x6c, 0x23, 0x18, 0x63, 0xa0, 0x3a, 0xea, 0xcb, 0x7d, 0x1e, 0x91, 0x0c, 0xff, 0x9a, 0xf0, 0xad, - 0x19, 0x94, 0x7b, 0xb4, 0x11, 0x01, 0x52, 0x7c, 0x07, 0xa4, 0xf4, 0xd6, 0xa6, 0xc1, 0x26, 0x6e, - 0x7d, 0x44, 0x98, 0x64, 0x15, 0xbc, 0x26, 0x23, 0xa4, 0xee, 0xf8, 0xb1, 0x7b, 0x8d, 0x04, 0x29, - 0x5b, 0xcd, 0xfb, 0xe3, 0x7e, 0x22, 0x18, 0xa3, 0x93, 0x62, 0x0f, 0x38, 0xe7, 0xb9, 0xe7, 0xdd, - 0x21, 0xb3, 0x30, 0xb9, 0xdb, 0xd2, 0x5a, 0x46, 0xeb, 0xf2, 0x8e, 0xfe, 0x2a, 0x77, 0xaa, 0xc0, - 0xa5, 0xd9, 0xd4, 0x6f, 0xe1, 0x16, 0x36, 0x35, 0x0b, 0x57, 0xf7, 0xb6, 0x48, 0x6f, 0x1d, 0x53, - 0xfd, 0x49, 0xe8, 0xb1, 0x64, 0x34, 0x85, 0x63, 0x53, 0x1d, 0x7c, 0x45, 0xe5, 0xa6, 0xde, 0xc4, - 0xc4, 0xbf, 0x9d, 0xf9, 0x78, 0x38, 0xcf, 0x91, 0x7a, 0x53, 0x8f, 0x2a, 0x46, 0x82, 0x88, 0x4c, - 0xef, 0x4c, 0x59, 0x36, 0xea, 0x5a, 0xb3, 0x63, 0x19, 0x26, 0x46, 0x2f, 0xf7, 0xd0, 0x71, 0x10, - 0x48, 0xf8, 0x10, 0x38, 0x0e, 0x99, 0x86, 0x51, 0xf7, 0x3c, 0x19, 0xd8, 0x13, 0xbf, 0x9c, 0x09, - 0x3d, 0x46, 0x44, 0x1b, 0xdc, 0x5d, 0x6f, 0x6c, 0x17, 0xc8, 0x88, 0x1d, 0x2d, 0x12, 0x22, 0x6a, - 0x04, 0x71, 0x15, 0x92, 0x90, 0x5a, 0xd5, 0x5b, 0x5b, 0xfe, 0x45, 0xcc, 0x31, 0x48, 0xeb, 0xad, - 0x06, 0xbe, 0xc4, 0x46, 0x6a, 0xfa, 0x60, 0x0f, 0xe7, 0xad, 0xdd, 0x9d, 0x0d, 0x6c, 0x56, 0x36, - 0x49, 0x73, 0x3b, 0x35, 0xa3, 0x8a, 0x5b, 0xce, 0xcc, 0xac, 0xe7, 0x3b, 0xf4, 0x9d, 0x44, 0x34, - 0xb9, 0xb7, 0x29, 0x09, 0xc0, 0xc5, 0x25, 0x2a, 0xe9, 0x23, 0x2a, 0x92, 0xc4, 0xf7, 0x28, 0x3c, - 0x7e, 0xfe, 0x7e, 0x34, 0x09, 0xd9, 0x15, 0x6c, 0x99, 0x7a, 0xbd, 0x83, 0x9e, 0x49, 0xc2, 0x54, - 0x15, 0x5b, 0xab, 0x9a, 0xa9, 0xed, 0x60, 0xcb, 0x5e, 0x92, 0xdf, 0xc2, 0x29, 0xa6, 0x76, 0x53, - 0xb3, 0x36, 0x0d, 0x73, 0xc7, 0x51, 0x4c, 0xce, 0xf3, 0xdd, 0xa9, 0x27, 0xbe, 0x2a, 0x25, 0x78, - 0x66, 0x86, 0xba, 0xde, 0xb0, 0x0a, 0xe7, 0xb8, 0xca, 0x02, 0x4e, 0x58, 0x88, 0x39, 0xd3, 0x88, - 0x94, 0x18, 0x3f, 0x33, 0xff, 0x50, 0x02, 0x69, 0xd9, 0xd8, 0x42, 0xef, 0x91, 0x20, 0x45, 0xe4, - 0xeb, 0xb7, 0x7c, 0x43, 0xf2, 0x0c, 0x64, 0x77, 0x70, 0xa7, 0xa3, 0x6d, 0x61, 0xe7, 0x7e, 0x69, - 0xf6, 0xa8, 0x9c, 0x81, 0x74, 0x13, 0xef, 0xe1, 0x26, 0x21, 0x63, 0xfa, 0xf4, 0x75, 0x5c, 0xcb, - 0x96, 0x8d, 0xad, 0x39, 0xbb, 0x2c, 0xf7, 0x16, 0xda, 0x65, 0x3b, 0xab, 0x4a, 0xbf, 0x98, 0x7d, - 0x08, 0xd2, 0xe4, 0x59, 0x19, 0x87, 0x74, 0xa1, 0x38, 0xbf, 0xb6, 0x28, 0x1f, 0xb1, 0xff, 0x3a, - 0xf4, 0x8d, 0x43, 0x7a, 0x21, 0x57, 0xcb, 0x2d, 0xcb, 0x49, 0xbb, 0x1d, 0xa5, 0xf2, 0x42, 0x45, - 0x96, 0xec, 0xc4, 0xd5, 0x5c, 0xb9, 0x94, 0x97, 0x53, 0xca, 0x04, 0x64, 0xcf, 0xe7, 0xd4, 0x72, - 0xa9, 0xbc, 0x28, 0xa7, 0xd1, 0xa3, 0x7e, 0x85, 0x75, 0x37, 0x8f, 0xdf, 0xf5, 0x41, 0x34, 0xf5, - 0x82, 0xec, 0x3f, 0xb9, 0x90, 0xdd, 0xc7, 0x41, 0xf6, 0xbd, 0x22, 0x85, 0x44, 0x43, 0xa9, 0x3c, - 0x80, 0x21, 0x7b, 0x0a, 0xc6, 0xcb, 0x95, 0xda, 0xfa, 0x42, 0x65, 0xad, 0x5c, 0x90, 0xb1, 0xcd, - 0x83, 0x5a, 0x69, 0xa5, 0x58, 0x59, 0xab, 0xc9, 0x9b, 0xe8, 0x8d, 0x49, 0xc8, 0xae, 0x9a, 0x46, - 0x1d, 0x77, 0x3a, 0xe8, 0xb5, 0x49, 0xc8, 0xe4, 0xb5, 0x56, 0x1d, 0x37, 0xd1, 0x4b, 0x3c, 0x18, - 0xbb, 0x96, 0x84, 0xe8, 0x5b, 0x7e, 0xa9, 0x7f, 0x90, 0xe7, 0x1a, 0x7f, 0xaf, 0x30, 0x2b, 0x77, - 0x8e, 0x96, 0x19, 0xc0, 0xbb, 0xa7, 0x5d, 0xde, 0xe5, 0x39, 0xde, 0x9d, 0x12, 0x2f, 0x2a, 0x7e, - 0x39, 0xff, 0xfb, 0x04, 0x1c, 0x5b, 0xb4, 0xa7, 0x0f, 0x7a, 0x9d, 0x12, 0xef, 0xb4, 0xff, 0x3e, - 0xbe, 0xfd, 0x37, 0x71, 0x44, 0xf7, 0xfa, 0x82, 0x6f, 0xfc, 0x53, 0x6e, 0xe3, 0x1f, 0xe4, 0x1a, - 0x7f, 0xab, 0x60, 0x39, 0xb1, 0xb7, 0x7c, 0x36, 0x0b, 0x69, 0x32, 0x45, 0x9e, 0xbd, 0x01, 0xa6, - 0xaa, 0x96, 0x89, 0xb5, 0x1d, 0xdf, 0xa0, 0x64, 0x19, 0x17, 0x70, 0x8b, 0x89, 0x06, 0x7d, 0xb8, - 0xfb, 0x0c, 0x64, 0x5b, 0xc6, 0xba, 0xb6, 0x6b, 0x6d, 0x2b, 0x2f, 0xdd, 0x77, 0x6c, 0x68, 0x85, - 0xf6, 0xff, 0x4a, 0x9b, 0xee, 0x22, 0xfd, 0xd5, 0xbd, 0x64, 0x62, 0x96, 0x69, 0x19, 0xb9, 0x5d, - 0x6b, 0x7b, 0xfe, 0xea, 0x8f, 0x3c, 0x77, 0x22, 0xf1, 0x89, 0xe7, 0x4e, 0x24, 0xbe, 0xfc, 0xdc, - 0x89, 0xc4, 0xcf, 0x7e, 0xe5, 0xc4, 0x91, 0x4f, 0x7c, 0xe5, 0xc4, 0x91, 0xcf, 0x7f, 0xe5, 0xc4, - 0x91, 0x1f, 0x48, 0xb6, 0x37, 0x36, 0x32, 0xa4, 0x94, 0x3b, 0xff, 0x5f, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xaf, 0x86, 0x70, 0xda, 0xde, 0x38, 0x01, 0x00, + 0xc6, 0xf6, 0xda, 0xac, 0xed, 0x59, 0x7b, 0x9d, 0x0f, 0xaf, 0xbf, 0x35, 0x92, 0x66, 0x46, 0xde, + 0x19, 0x69, 0x68, 0x69, 0x76, 0x31, 0x1c, 0x37, 0xd7, 0x23, 0xd5, 0xcc, 0xb4, 0x57, 0xa3, 0x16, + 0xad, 0x9e, 0xd9, 0xdd, 0x3c, 0xcf, 0x1d, 0x18, 0x30, 0x36, 0xf0, 0x84, 0x40, 0x80, 0x0b, 0x86, + 0x4b, 0x4c, 0x1c, 0x12, 0x08, 0x21, 0x84, 0x10, 0x42, 0x2e, 0x5c, 0x08, 0x07, 0x49, 0x78, 0x42, + 0x1e, 0x88, 0x43, 0xbe, 0xe1, 0x92, 0x10, 0x9c, 0x5c, 0x2e, 0xdc, 0x25, 0x97, 0x0b, 0xcf, 0xdd, + 0x71, 0xc1, 0x70, 0xb9, 0xa7, 0xab, 0xaa, 0x3f, 0x4a, 0xa3, 0x6e, 0x55, 0x6b, 0xd4, 0x1a, 0xe7, + 0xf8, 0x4b, 0xea, 0xea, 0xea, 0xaa, 0xb7, 0xde, 0xdf, 0x5b, 0x6f, 0x55, 0xbd, 0xf5, 0xd6, 0x5b, + 0x30, 0xd3, 0xde, 0x38, 0xdd, 0x36, 0x0d, 0xcb, 0xe8, 0x9c, 0xae, 0x1b, 0x3b, 0x3b, 0x5a, 0xab, + 0xd1, 0x99, 0x23, 0xcf, 0x4a, 0x56, 0x6b, 0x5d, 0xb1, 0xae, 0xb4, 0x31, 0xba, 0xb1, 0x7d, 0x71, + 0xeb, 0x74, 0x53, 0xdf, 0x38, 0xdd, 0xde, 0x38, 0xbd, 0x63, 0x34, 0x70, 0xd3, 0xf9, 0x80, 0x3c, + 0xb0, 0xec, 0xe8, 0x96, 0xa0, 0x5c, 0x4d, 0xa3, 0xae, 0x35, 0x3b, 0x96, 0x61, 0x62, 0x96, 0xf3, + 0xb8, 0x57, 0x25, 0xde, 0xc3, 0x2d, 0xcb, 0x29, 0xe1, 0xda, 0x2d, 0xc3, 0xd8, 0x6a, 0x62, 0xfa, + 0x6e, 0x63, 0x77, 0xf3, 0x74, 0xc7, 0x32, 0x77, 0xeb, 0x16, 0x7b, 0x7b, 0x7d, 0xf7, 0xdb, 0x06, + 0xee, 0xd4, 0x4d, 0xbd, 0x6d, 0x19, 0x26, 0xcd, 0x31, 0xfb, 0x73, 0xff, 0x23, 0x05, 0x92, 0xda, + 0xae, 0xa3, 0x8f, 0x8e, 0x81, 0x94, 0x6b, 0xb7, 0xd1, 0x37, 0x93, 0x00, 0x8b, 0xd8, 0x3a, 0x8f, + 0xcd, 0x8e, 0x6e, 0xb4, 0xd0, 0x38, 0x64, 0x55, 0xfc, 0x83, 0xbb, 0xb8, 0x63, 0xa1, 0xcf, 0x24, + 0x61, 0x4c, 0xc5, 0x9d, 0xb6, 0xd1, 0xea, 0x60, 0xe5, 0x21, 0x48, 0x63, 0xd3, 0x34, 0xcc, 0x99, + 0xc4, 0xf5, 0x89, 0x5b, 0x26, 0xce, 0x9c, 0x9a, 0x63, 0x0d, 0x9f, 0x53, 0xdb, 0xf5, 0xb9, 0x5c, + 0xbb, 0x3d, 0xe7, 0x95, 0x31, 0xe7, 0x7c, 0x34, 0x57, 0xb4, 0xbf, 0x50, 0xe9, 0x87, 0xca, 0x0c, + 0x64, 0xf7, 0x68, 0x86, 0x99, 0xe4, 0xf5, 0x89, 0x5b, 0xc6, 0x55, 0xe7, 0xd1, 0x7e, 0xd3, 0xc0, + 0x96, 0xa6, 0x37, 0x3b, 0x33, 0x12, 0x7d, 0xc3, 0x1e, 0xd1, 0x27, 0x13, 0x90, 0x26, 0x85, 0x28, + 0x79, 0x48, 0xd5, 0x8d, 0x06, 0x26, 0xd5, 0x4f, 0x9f, 0x39, 0x2d, 0x5e, 0xfd, 0x5c, 0xde, 0x68, + 0x60, 0x95, 0x7c, 0xac, 0x5c, 0x0f, 0x13, 0x0e, 0x43, 0x3c, 0x32, 0xfc, 0x49, 0xb3, 0x0d, 0x48, + 0xd9, 0xf9, 0x95, 0x31, 0x48, 0x95, 0xd7, 0x96, 0x97, 0xe5, 0x23, 0xca, 0x55, 0x30, 0xb5, 0x56, + 0x3e, 0x57, 0xae, 0x5c, 0x28, 0xaf, 0x17, 0x55, 0xb5, 0xa2, 0xca, 0x09, 0x65, 0x0a, 0xc6, 0xe7, + 0x73, 0x85, 0xf5, 0x52, 0x79, 0x75, 0xad, 0x26, 0x27, 0x95, 0x63, 0x20, 0x9f, 0x2f, 0xaa, 0xd5, + 0x52, 0xa5, 0xbc, 0x5e, 0xaa, 0xae, 0x17, 0x57, 0x56, 0x6b, 0x8f, 0xc8, 0x92, 0x9d, 0xa9, 0x5c, + 0xa9, 0xad, 0x2f, 0x54, 0xd6, 0xca, 0x05, 0x19, 0x2b, 0x13, 0x90, 0xad, 0x95, 0x56, 0x8a, 0x95, + 0xb5, 0x9a, 0xbc, 0x89, 0x7e, 0x57, 0x82, 0xe9, 0x2a, 0xb6, 0x0a, 0x78, 0x4f, 0xaf, 0xe3, 0xaa, + 0xa5, 0x59, 0x18, 0xbd, 0x26, 0xe1, 0x32, 0x5e, 0x59, 0xb3, 0xc9, 0x74, 0x5f, 0xb1, 0x26, 0xdf, + 0xb5, 0xaf, 0xc9, 0x7c, 0x09, 0x73, 0xec, 0xeb, 0x39, 0x5f, 0x9a, 0xea, 0x2f, 0x67, 0xf6, 0x76, + 0x98, 0xf0, 0xbd, 0x53, 0xa6, 0x01, 0xe6, 0x73, 0xf9, 0x73, 0x8b, 0x2a, 0xa1, 0xf0, 0x88, 0xfd, + 0xbc, 0x50, 0x51, 0x8b, 0xec, 0x39, 0x81, 0x5e, 0xe3, 0x87, 0xbf, 0xc0, 0xc3, 0x3f, 0xd7, 0x9f, + 0x98, 0x1e, 0x22, 0x80, 0xde, 0xe7, 0xc2, 0xb9, 0xc8, 0xc1, 0x79, 0x57, 0xb4, 0xe2, 0xa2, 0x41, + 0xba, 0x34, 0x18, 0xa4, 0xe5, 0x4a, 0xa1, 0xb8, 0x6e, 0x23, 0x58, 0xad, 0xe5, 0xd4, 0x5a, 0xb1, + 0x20, 0x63, 0xf4, 0xcb, 0x49, 0x18, 0xab, 0x6e, 0xef, 0x5a, 0x0d, 0xe3, 0x12, 0xd7, 0x51, 0x7e, + 0xd4, 0xcf, 0xa9, 0x07, 0x78, 0x4e, 0xdd, 0xb2, 0xbf, 0x69, 0xac, 0x84, 0x00, 0x1e, 0xfd, 0x9e, + 0xcb, 0xa3, 0x1c, 0xc7, 0xa3, 0xdb, 0x45, 0x0b, 0x3a, 0x2c, 0xee, 0x7c, 0x6a, 0x0a, 0x32, 0x17, + 0xb4, 0x66, 0x13, 0x5b, 0xe8, 0xcb, 0x49, 0xc8, 0xe4, 0x4d, 0x6c, 0xcb, 0xf5, 0xad, 0x9e, 0x58, + 0x23, 0x18, 0x33, 0x0d, 0xc3, 0x5a, 0xd5, 0xac, 0x6d, 0xd2, 0xa6, 0x71, 0xd5, 0x7d, 0xbe, 0x27, + 0xf5, 0xe4, 0x57, 0xa4, 0x04, 0xfa, 0x4d, 0x3f, 0x23, 0x1f, 0xe4, 0x19, 0xf9, 0xdd, 0x5c, 0xfb, + 0x69, 0x45, 0x73, 0xb4, 0x92, 0x00, 0x85, 0x83, 0x60, 0x6c, 0xa7, 0x85, 0x77, 0x8c, 0x96, 0x5e, + 0x67, 0x2d, 0x77, 0x9f, 0xd1, 0x1f, 0xbb, 0x5c, 0x9e, 0xe7, 0xb8, 0x3c, 0x27, 0x5c, 0x4b, 0x34, + 0x36, 0x57, 0x07, 0x60, 0xf3, 0x4b, 0xe1, 0x9a, 0x85, 0x5c, 0x69, 0xb9, 0x58, 0x58, 0xaf, 0x55, + 0xd6, 0xf3, 0x6a, 0x31, 0x57, 0x2b, 0xae, 0x2f, 0x57, 0xf2, 0xb9, 0xe5, 0x75, 0xb5, 0xb8, 0x5a, + 0x91, 0x31, 0xfa, 0x2f, 0x49, 0x9b, 0xb9, 0x75, 0x63, 0x0f, 0x9b, 0x68, 0x51, 0x88, 0xcf, 0x61, + 0x3c, 0x61, 0x18, 0xbc, 0x56, 0x58, 0xeb, 0x33, 0xee, 0x30, 0x0a, 0x02, 0xc4, 0xf9, 0x03, 0x42, + 0x1a, 0x3c, 0xb4, 0xa8, 0x17, 0x00, 0xa7, 0xff, 0x67, 0x12, 0xb2, 0x79, 0xa3, 0xb5, 0x87, 0x4d, + 0x0b, 0x3d, 0xc8, 0x71, 0xda, 0xe5, 0x66, 0x82, 0xe7, 0xa6, 0x3d, 0xa8, 0xe1, 0x96, 0x65, 0x1a, + 0xed, 0x2b, 0xce, 0x70, 0xc7, 0x1e, 0xd1, 0xaf, 0x45, 0xe5, 0x30, 0xab, 0x39, 0x78, 0x5c, 0xed, + 0x5d, 0x11, 0x47, 0x9e, 0xd4, 0xd5, 0x01, 0x9e, 0x89, 0x82, 0x4b, 0x6f, 0x02, 0xa2, 0xe1, 0x72, + 0x26, 0x3a, 0x2e, 0xe8, 0xe3, 0x49, 0x98, 0xa2, 0x9d, 0xaf, 0x8a, 0x3b, 0x64, 0x7a, 0x72, 0xab, + 0x10, 0xf3, 0x99, 0x28, 0xff, 0x9c, 0x9f, 0xd1, 0x0b, 0x3c, 0xa3, 0xef, 0x08, 0xee, 0xe8, 0xac, + 0xae, 0x00, 0x76, 0x1f, 0x83, 0xb4, 0x65, 0x5c, 0xc4, 0x4e, 0x1b, 0xe9, 0x03, 0xfa, 0x75, 0x97, + 0x9d, 0x25, 0x8e, 0x9d, 0x2f, 0x8f, 0x5a, 0x4d, 0xfc, 0x4c, 0x7d, 0x7b, 0x12, 0x26, 0xf3, 0x4d, + 0xa3, 0xe3, 0xf2, 0xf4, 0xa5, 0x1e, 0x4f, 0xdd, 0xc6, 0x25, 0xfc, 0x8d, 0x7b, 0x3e, 0xe1, 0xe3, + 0x63, 0x91, 0xe7, 0x63, 0x6f, 0x79, 0xf1, 0x15, 0x1f, 0xa0, 0x17, 0x7e, 0xcd, 0x65, 0xd8, 0x12, + 0xc7, 0xb0, 0x97, 0x45, 0x2c, 0x2f, 0x7e, 0x7e, 0xfd, 0xde, 0x77, 0x41, 0x36, 0x57, 0xaf, 0x1b, + 0xbb, 0x2d, 0x0b, 0xfd, 0x75, 0x02, 0x32, 0x79, 0xa3, 0xb5, 0xa9, 0x6f, 0x29, 0x27, 0x61, 0x1a, + 0xb7, 0xb4, 0x8d, 0x26, 0x2e, 0x68, 0x96, 0xb6, 0xa7, 0xe3, 0x4b, 0xa4, 0x01, 0x63, 0x6a, 0x57, + 0xaa, 0x4d, 0x14, 0x4b, 0xc1, 0x1b, 0xbb, 0x5b, 0x84, 0xa8, 0x31, 0xd5, 0x9f, 0xa4, 0xdc, 0x0d, + 0x57, 0xd3, 0xc7, 0x55, 0x13, 0x9b, 0xb8, 0x89, 0xb5, 0x0e, 0xce, 0x6f, 0x6b, 0xad, 0x16, 0x6e, + 0x92, 0x5e, 0x3b, 0xa6, 0x06, 0xbd, 0x56, 0x66, 0x61, 0x92, 0xbe, 0xaa, 0xb6, 0xb5, 0x3a, 0xee, + 0xcc, 0xa4, 0x48, 0x76, 0x2e, 0x4d, 0xb9, 0x1d, 0xd2, 0xf8, 0xb2, 0x65, 0x6a, 0x33, 0x0d, 0x82, + 0xd7, 0xd5, 0x73, 0x74, 0x89, 0x30, 0xe7, 0x2c, 0x11, 0xe6, 0xaa, 0x64, 0x01, 0xa1, 0xd2, 0x5c, + 0xe8, 0x03, 0x19, 0x77, 0xe8, 0x7e, 0xa3, 0x6f, 0x4a, 0xaa, 0x40, 0xaa, 0xa5, 0xed, 0x60, 0x26, + 0x17, 0xe4, 0xbf, 0x72, 0x0a, 0x8e, 0x6a, 0x7b, 0x9a, 0xa5, 0x99, 0xcb, 0xf6, 0xe2, 0x85, 0x0c, + 0x37, 0x84, 0xe5, 0x4b, 0x47, 0xd4, 0xee, 0x17, 0xca, 0xb5, 0x30, 0x4e, 0x56, 0x37, 0x24, 0x17, + 0xd5, 0x45, 0x5e, 0x82, 0x72, 0x0b, 0x1c, 0xd5, 0x9a, 0xed, 0x6d, 0xad, 0xd4, 0xda, 0xd3, 0x2d, + 0x6c, 0x23, 0x34, 0x73, 0x8c, 0xe4, 0xe9, 0x4e, 0xa6, 0x1d, 0x7b, 0x7e, 0x0c, 0x32, 0xb4, 0x02, + 0xf4, 0xf3, 0x69, 0xe1, 0x35, 0x0a, 0x85, 0x30, 0x7c, 0xca, 0x70, 0x07, 0x64, 0x35, 0x9a, 0x8f, + 0x34, 0x65, 0xe2, 0xcc, 0x71, 0xb7, 0x0c, 0xb2, 0x5c, 0x73, 0x4a, 0x51, 0x9d, 0x6c, 0xca, 0x5d, + 0x90, 0xa9, 0x13, 0x81, 0x20, 0xad, 0x9a, 0x38, 0x73, 0x4d, 0xef, 0x4a, 0x49, 0x16, 0x95, 0x65, + 0x45, 0x5f, 0x90, 0x84, 0x96, 0x35, 0x61, 0x14, 0x47, 0x93, 0xfb, 0xaf, 0x27, 0x07, 0x18, 0x15, + 0x6f, 0x83, 0x5b, 0x72, 0xf9, 0x7c, 0x65, 0xad, 0x5c, 0x63, 0x63, 0x62, 0x61, 0x7d, 0x7e, 0xad, + 0xb6, 0xee, 0x8d, 0x94, 0x64, 0xee, 0xb7, 0x6e, 0x4f, 0x05, 0x65, 0x5b, 0x1a, 0x4e, 0xf6, 0xc9, + 0x5d, 0xac, 0xad, 0x97, 0x73, 0x2b, 0x45, 0x79, 0x53, 0xa0, 0xe4, 0x62, 0x6d, 0x3d, 0x77, 0x3e, + 0x57, 0xcb, 0xa9, 0xf2, 0x16, 0x3f, 0x3a, 0x57, 0x6b, 0x95, 0xd5, 0x75, 0x75, 0xad, 0x5c, 0x2e, + 0x95, 0x17, 0x69, 0xd5, 0xf6, 0xa4, 0xe6, 0xb8, 0x97, 0xe1, 0x82, 0x5a, 0xaa, 0x15, 0xd7, 0xf3, + 0x95, 0xf2, 0x42, 0x69, 0x51, 0xd6, 0xfb, 0x0d, 0xed, 0x8f, 0x2a, 0xc7, 0xe0, 0x28, 0x6d, 0xf4, + 0x79, 0xfa, 0x5d, 0xa1, 0x28, 0xff, 0x58, 0x56, 0x99, 0x86, 0xf1, 0x72, 0xb1, 0xc6, 0x38, 0xf3, + 0x78, 0x56, 0xb9, 0x06, 0x8e, 0xdb, 0xcf, 0xf9, 0x4a, 0xb9, 0x5c, 0xcc, 0xd7, 0xec, 0xa5, 0x9e, + 0x5a, 0x5c, 0x58, 0xab, 0x16, 0x0b, 0xf2, 0x8f, 0x67, 0x15, 0x19, 0x26, 0xec, 0x97, 0x95, 0x85, + 0x85, 0xe5, 0x52, 0xb9, 0x28, 0x3f, 0x91, 0x45, 0x6f, 0x4e, 0x79, 0x33, 0x33, 0xdf, 0x42, 0xe1, + 0xa7, 0x53, 0x3e, 0x69, 0xcd, 0xf1, 0xd2, 0x7a, 0x6b, 0x4f, 0xec, 0xc3, 0x27, 0x57, 0xef, 0x77, + 0xe5, 0xa8, 0xc0, 0xc9, 0xd1, 0x1d, 0x11, 0xca, 0x8a, 0x26, 0x48, 0x7f, 0x36, 0x88, 0x20, 0xbd, + 0x18, 0xae, 0x2a, 0x57, 0xd6, 0x19, 0xe2, 0x55, 0x77, 0x49, 0x7c, 0x3d, 0x5c, 0x5b, 0x2e, 0x52, + 0x60, 0xd4, 0x62, 0xbe, 0x72, 0xbe, 0xa8, 0xae, 0x5f, 0xc8, 0x2d, 0x2f, 0x17, 0x6b, 0xeb, 0x0b, + 0x25, 0xb5, 0x5a, 0x93, 0x37, 0xfb, 0x81, 0xb7, 0xa5, 0xdc, 0x00, 0x2f, 0xf5, 0x9e, 0xd7, 0x8b, + 0xdf, 0x5b, 0xaa, 0xd6, 0xaa, 0x44, 0x94, 0xf2, 0x15, 0x55, 0x5d, 0x5b, 0xb5, 0x17, 0x26, 0xdb, + 0xca, 0x71, 0x50, 0xbc, 0x52, 0xd4, 0xb5, 0x32, 0x15, 0x1b, 0xdd, 0xae, 0x9f, 0xd5, 0xe7, 0x54, + 0x6f, 0x2f, 0x68, 0x56, 0x8b, 0xea, 0x42, 0x45, 0x5d, 0x29, 0x16, 0xe4, 0x47, 0xfb, 0x49, 0xde, + 0x45, 0xe5, 0x24, 0xcc, 0xe6, 0xca, 0x95, 0xda, 0x52, 0x51, 0x5d, 0xcf, 0x95, 0x1f, 0xa9, 0x3d, + 0xb2, 0x5a, 0x5c, 0x5f, 0x55, 0x2b, 0xf9, 0x62, 0xb5, 0xba, 0x5e, 0xaa, 0x3a, 0x99, 0xe5, 0xa6, + 0x4d, 0x82, 0x23, 0xf0, 0xa5, 0xea, 0x7a, 0xa1, 0xb8, 0x5c, 0xb4, 0x49, 0xdb, 0x41, 0xaf, 0x96, + 0x20, 0x53, 0xc0, 0x4d, 0x6c, 0x61, 0xf4, 0x5d, 0x9e, 0xb2, 0x3d, 0x0e, 0x19, 0x13, 0xdb, 0x13, + 0x2e, 0x36, 0xa4, 0xb0, 0x27, 0xf4, 0xd7, 0xc9, 0xa8, 0xca, 0x8e, 0x96, 0x1d, 0xa0, 0xec, 0x5e, + 0x0e, 0x99, 0x8e, 0xa5, 0x59, 0xbb, 0x1d, 0xa6, 0xeb, 0xae, 0xeb, 0xad, 0xeb, 0xe6, 0xaa, 0x24, + 0x93, 0xca, 0x32, 0xa3, 0xbf, 0x4c, 0x44, 0x51, 0x5e, 0x3d, 0x29, 0x88, 0x26, 0x73, 0xfa, 0x00, + 0x22, 0x77, 0x02, 0x90, 0x8f, 0xe1, 0xb9, 0x65, 0xb5, 0x98, 0x2b, 0x3c, 0xe2, 0x32, 0x1e, 0xdb, + 0x22, 0xe9, 0x7f, 0x9f, 0xaf, 0x95, 0xce, 0x17, 0xe5, 0x4d, 0xf4, 0x81, 0x34, 0x64, 0xaa, 0xb8, + 0x89, 0xeb, 0x16, 0xba, 0xd7, 0xc3, 0x63, 0x1a, 0x92, 0x7a, 0x83, 0x0d, 0x7d, 0x49, 0xbd, 0xc1, + 0x2d, 0xb0, 0x92, 0x3d, 0x17, 0xb2, 0xcf, 0xa7, 0xa2, 0x22, 0x45, 0x6b, 0x3d, 0xdc, 0x61, 0xe9, + 0x43, 0x91, 0x86, 0xa5, 0x9e, 0x14, 0x47, 0x43, 0xf6, 0x93, 0xc9, 0x18, 0x16, 0x6b, 0x22, 0x4a, + 0x61, 0x33, 0x40, 0x29, 0x74, 0x0d, 0x36, 0x0b, 0xa5, 0x72, 0x61, 0xdd, 0x95, 0x93, 0xf2, 0x42, + 0x45, 0xde, 0x56, 0xe6, 0xe0, 0x94, 0xaf, 0x74, 0x5b, 0x63, 0xb0, 0x1a, 0x72, 0xe5, 0xc2, 0xfa, + 0x4a, 0xb9, 0xb8, 0x52, 0x29, 0x97, 0xf2, 0xd4, 0x34, 0x52, 0xac, 0x51, 0x2d, 0xd3, 0xa5, 0x43, + 0xaa, 0xc5, 0x9c, 0x9a, 0x5f, 0x22, 0xea, 0xa6, 0x50, 0x94, 0x1f, 0x55, 0x6e, 0x86, 0x1b, 0x7c, + 0xa4, 0x30, 0x55, 0xb4, 0xaa, 0x16, 0x0b, 0xc5, 0x85, 0x52, 0xd9, 0x1e, 0x1a, 0x97, 0x2b, 0xf9, + 0x73, 0x55, 0x71, 0x6d, 0x83, 0xfe, 0x21, 0x09, 0xa9, 0xaa, 0x65, 0xb4, 0xd1, 0x77, 0x7b, 0x32, + 0x7c, 0x02, 0xc0, 0xc4, 0x3b, 0xc6, 0x1e, 0x99, 0x98, 0x32, 0xbd, 0xe2, 0x4b, 0x41, 0x7f, 0x22, + 0x6e, 0xc3, 0x72, 0xd5, 0x82, 0xd1, 0x0e, 0x18, 0x97, 0xbe, 0x25, 0x66, 0xc3, 0x0a, 0x2e, 0x28, + 0x9a, 0x18, 0xfd, 0x64, 0x62, 0x00, 0x31, 0x42, 0x70, 0xdc, 0xa7, 0x01, 0x6c, 0xbc, 0x1c, 0x06, + 0x62, 0xe5, 0x6a, 0x78, 0x51, 0x17, 0x66, 0x04, 0xaa, 0x4d, 0xe5, 0xbb, 0xe0, 0x3a, 0x3f, 0x54, + 0x2b, 0x95, 0xf3, 0x45, 0x57, 0x3e, 0x0a, 0xb9, 0x5a, 0x4e, 0xde, 0x42, 0x9f, 0x90, 0x20, 0xb5, + 0x62, 0xec, 0x61, 0x74, 0x83, 0xc7, 0xfc, 0x19, 0xc8, 0xb6, 0xf0, 0x25, 0x9f, 0x41, 0xc6, 0x79, + 0x44, 0x6f, 0x96, 0xa2, 0xb2, 0xdd, 0x2e, 0x3b, 0x80, 0xed, 0x9f, 0x4d, 0x46, 0x61, 0x7b, 0x8f, + 0x82, 0xa2, 0xb1, 0xfd, 0x6f, 0x07, 0x61, 0x7b, 0x00, 0x6b, 0xb1, 0x32, 0x0b, 0x27, 0xbc, 0x17, + 0xa5, 0x42, 0xb1, 0x5c, 0x2b, 0x2d, 0x3c, 0xe2, 0x31, 0xb7, 0xa4, 0x0a, 0xb1, 0xbf, 0x9f, 0x76, + 0x08, 0x9f, 0x2c, 0xce, 0xc0, 0x31, 0xef, 0xdd, 0x22, 0x9d, 0xef, 0xd9, 0x6f, 0x1e, 0x45, 0xaf, + 0x4d, 0xc3, 0x24, 0xd5, 0x96, 0x6b, 0xed, 0x86, 0xbd, 0x38, 0xba, 0x89, 0x33, 0x44, 0x58, 0xfa, + 0x0e, 0xfe, 0x3e, 0xa3, 0xe5, 0xac, 0x8f, 0xdc, 0x67, 0xf4, 0x31, 0x61, 0x13, 0x04, 0xaf, 0x93, + 0x69, 0x2d, 0x01, 0x38, 0x3f, 0x2f, 0x64, 0x6c, 0x10, 0x28, 0x30, 0x1a, 0xde, 0x3f, 0x36, 0xec, + 0x6e, 0x16, 0x0c, 0xc5, 0x66, 0x20, 0x14, 0x5b, 0xb3, 0x4f, 0x24, 0x61, 0xbc, 0xa6, 0xef, 0xe0, + 0x57, 0x19, 0x2d, 0xdc, 0x51, 0xb2, 0x20, 0x2d, 0xae, 0xd4, 0xe4, 0x23, 0xf6, 0x9f, 0x62, 0xbe, + 0x26, 0x27, 0xc8, 0x9f, 0xa2, 0x5d, 0xb5, 0xfd, 0x27, 0x57, 0x93, 0x25, 0xfb, 0xcf, 0x4a, 0xb1, + 0x26, 0xa7, 0xec, 0x3f, 0xe5, 0x62, 0x4d, 0x4e, 0xdb, 0x7f, 0x56, 0x97, 0x6b, 0x72, 0xc6, 0xfe, + 0x53, 0xaa, 0xd6, 0xe4, 0xac, 0xfd, 0x67, 0xbe, 0x5a, 0x93, 0xc7, 0xec, 0x3f, 0xe7, 0xab, 0x35, + 0x79, 0xdc, 0xfe, 0x93, 0xaf, 0xd5, 0x64, 0xb0, 0xff, 0x3c, 0x5c, 0xad, 0xc9, 0x13, 0xf6, 0x9f, + 0x5c, 0xbe, 0x26, 0x4f, 0x92, 0x3f, 0xc5, 0x9a, 0x3c, 0x65, 0xff, 0xa9, 0x56, 0x6b, 0xf2, 0x34, + 0x29, 0xb9, 0x5a, 0x93, 0x8f, 0x92, 0xba, 0x4a, 0x35, 0x59, 0xb6, 0xff, 0x2c, 0x55, 0x6b, 0xf2, + 0x55, 0x24, 0x73, 0xb5, 0x26, 0x2b, 0xa4, 0xd2, 0x6a, 0x4d, 0x7e, 0x11, 0xc9, 0x53, 0xad, 0xc9, + 0xc7, 0x48, 0x15, 0xd5, 0x9a, 0xfc, 0x62, 0x42, 0x46, 0xb1, 0x26, 0x1f, 0x27, 0x79, 0xd4, 0x9a, + 0x7c, 0x35, 0x79, 0x55, 0xae, 0xc9, 0x33, 0x84, 0xb0, 0x62, 0x4d, 0x7e, 0x09, 0xf9, 0xa3, 0xd6, + 0x64, 0x44, 0x5e, 0xe5, 0x6a, 0xf2, 0x35, 0xe8, 0x3a, 0x18, 0x5f, 0xc4, 0x16, 0xc5, 0x17, 0xc9, + 0x20, 0x2d, 0x62, 0xcb, 0xbf, 0xda, 0x78, 0xfd, 0x0c, 0x8c, 0x5f, 0x30, 0xcc, 0x8b, 0x9d, 0xb6, + 0x56, 0xc7, 0xe8, 0xbd, 0x74, 0x9f, 0x2f, 0xbf, 0x6b, 0x9a, 0xb8, 0xc5, 0xe5, 0x7b, 0x5a, 0xdc, + 0x4c, 0xe6, 0x94, 0x36, 0xe7, 0x95, 0x14, 0x30, 0x65, 0xb9, 0x1e, 0x26, 0x2e, 0x39, 0xb9, 0x4b, + 0x0d, 0x47, 0x9c, 0x7c, 0x49, 0xa2, 0x26, 0xb3, 0xfe, 0x55, 0xc6, 0x6f, 0x02, 0x7a, 0x47, 0x12, + 0x32, 0x8b, 0xd8, 0xca, 0x35, 0x9b, 0x7e, 0xbe, 0x3d, 0xe5, 0xe7, 0xdb, 0x3c, 0xcf, 0xb7, 0xdb, + 0x82, 0x1b, 0x91, 0x6b, 0x36, 0x03, 0x78, 0x36, 0x0b, 0x93, 0x3e, 0x06, 0xd9, 0xd3, 0x72, 0xe9, + 0x96, 0x71, 0x95, 0x4b, 0x43, 0xbf, 0xea, 0x72, 0xad, 0xc8, 0x71, 0xed, 0xce, 0x28, 0x15, 0xc6, + 0xcf, 0xb1, 0x3f, 0xf2, 0x76, 0x80, 0xae, 0x0b, 0xb5, 0x22, 0xa1, 0xd7, 0x0d, 0xc0, 0xc5, 0x50, + 0x1b, 0x4e, 0x7f, 0xc9, 0x8b, 0xca, 0xc3, 0x21, 0x18, 0x60, 0x06, 0xe1, 0xe1, 0x7b, 0xc7, 0x20, + 0x53, 0xd9, 0x78, 0xd4, 0x5e, 0x8c, 0x3c, 0x9f, 0x04, 0x29, 0xd7, 0x68, 0x74, 0x8d, 0x3a, 0x06, + 0x79, 0x59, 0x72, 0x96, 0x26, 0xee, 0x33, 0xfa, 0xb3, 0x01, 0x7a, 0x34, 0xad, 0x69, 0x2e, 0xd7, + 0x68, 0x04, 0x6f, 0xa7, 0xb9, 0x15, 0x26, 0xf9, 0x0a, 0x95, 0x3b, 0xf9, 0x1d, 0xfc, 0x10, 0x33, + 0xa3, 0xbb, 0xb5, 0x1f, 0xb5, 0xfb, 0x07, 0xd2, 0x17, 0x3f, 0x10, 0x9f, 0x4d, 0x42, 0x76, 0x59, + 0xef, 0x58, 0x36, 0x02, 0x37, 0x7b, 0x08, 0x5c, 0x0b, 0xe3, 0x0e, 0x03, 0x3a, 0x33, 0x09, 0xd2, + 0x57, 0xbd, 0x04, 0xf4, 0x26, 0x3f, 0x06, 0x0f, 0xf3, 0x18, 0xbc, 0x2c, 0xbc, 0x8d, 0xac, 0xae, + 0x00, 0x1c, 0xb8, 0x6a, 0x93, 0xdd, 0xd5, 0xfe, 0xa6, 0xcb, 0xd6, 0x15, 0x8e, 0xad, 0x67, 0x07, + 0xa9, 0x32, 0x7e, 0xd6, 0x7e, 0x2a, 0x09, 0x60, 0xd7, 0xad, 0x92, 0x95, 0x88, 0x38, 0x77, 0x5f, + 0xef, 0xe7, 0xee, 0x0a, 0xcf, 0xdd, 0x57, 0xf6, 0x6f, 0x2a, 0xad, 0x2e, 0x80, 0xc1, 0x32, 0x48, + 0xba, 0xcb, 0x5a, 0xfb, 0x2f, 0x7a, 0x87, 0xcb, 0xd4, 0x55, 0x8e, 0xa9, 0xf7, 0x0d, 0x58, 0x53, + 0xfc, 0x7c, 0xfd, 0x6f, 0x49, 0x90, 0xab, 0xd8, 0x2a, 0x75, 0x96, 0xf4, 0xad, 0xed, 0xa6, 0xbe, + 0xb5, 0x6d, 0xe1, 0x06, 0x3a, 0x27, 0xa4, 0x3d, 0x94, 0x1b, 0x61, 0x4a, 0xf7, 0x7f, 0xc7, 0xf6, + 0x2c, 0xf8, 0x44, 0xf4, 0x13, 0x7e, 0x04, 0x96, 0x79, 0x04, 0x5e, 0x11, 0xc0, 0x97, 0x6e, 0x8a, + 0x02, 0xe6, 0xb7, 0xbf, 0xe5, 0xb2, 0xbb, 0xc2, 0xb1, 0xfb, 0xde, 0xc1, 0x8a, 0x1d, 0xc9, 0x96, + 0x9a, 0x63, 0x36, 0xf2, 0x6d, 0x50, 0x76, 0x0d, 0x44, 0x89, 0xfd, 0x03, 0xd1, 0xff, 0x4a, 0x44, + 0x1f, 0xfb, 0xc2, 0x0c, 0x45, 0x91, 0x47, 0xb6, 0x21, 0xd8, 0x70, 0x06, 0xe1, 0xd7, 0x8f, 0x4a, + 0x90, 0x29, 0x5e, 0x6e, 0x1b, 0xfc, 0x6e, 0xba, 0x02, 0xa9, 0xb6, 0xb7, 0x44, 0x26, 0xff, 0x05, + 0x06, 0xf3, 0xf7, 0x0c, 0x30, 0x7f, 0xa0, 0x75, 0x07, 0x74, 0x7f, 0x87, 0x8c, 0xa4, 0x8f, 0x8c, + 0xdb, 0x20, 0x4d, 0xbc, 0xf0, 0xd8, 0xe8, 0xe6, 0x99, 0xdf, 0x9c, 0x22, 0x8a, 0xf6, 0x5b, 0x95, + 0x66, 0x8a, 0x8c, 0x42, 0x4f, 0x72, 0xe2, 0x47, 0xe1, 0x9b, 0xaf, 0x4d, 0xb8, 0x13, 0x8c, 0x9f, + 0x48, 0x41, 0xaa, 0xd2, 0xc6, 0x2d, 0xf4, 0xf6, 0x04, 0xa7, 0x82, 0xeb, 0x46, 0xcb, 0xc2, 0x97, + 0x3d, 0x2d, 0xe1, 0x25, 0x84, 0xce, 0x07, 0x66, 0x20, 0x6b, 0x99, 0x14, 0x32, 0xe6, 0xd1, 0xc7, + 0x1e, 0x95, 0x32, 0xcc, 0xea, 0xad, 0x7a, 0x73, 0xb7, 0x81, 0x55, 0xdc, 0xd4, 0x6c, 0xda, 0x3b, + 0xb9, 0x4e, 0x01, 0xb7, 0x71, 0xab, 0x81, 0x5b, 0x16, 0xa5, 0xc6, 0xd9, 0xc8, 0x14, 0xc8, 0xc9, + 0x2f, 0xb0, 0xef, 0xe7, 0xe1, 0xbf, 0x99, 0xe3, 0x37, 0x53, 0xca, 0x76, 0x2b, 0x03, 0x90, 0x3f, + 0x0b, 0x40, 0x5b, 0x70, 0x5e, 0xc7, 0x97, 0x98, 0xa5, 0xf5, 0x25, 0x5d, 0x96, 0xd6, 0x8a, 0x9b, + 0x41, 0xf5, 0x65, 0x46, 0x7f, 0xea, 0x42, 0xfe, 0x10, 0x07, 0xf9, 0x6d, 0x82, 0x24, 0x44, 0x43, + 0xfb, 0x5f, 0x0c, 0xb0, 0x10, 0xe7, 0xfc, 0x11, 0x25, 0xe5, 0x25, 0xf0, 0x62, 0xc7, 0x86, 0x58, + 0x2e, 0x16, 0x0b, 0xd5, 0xf5, 0xb5, 0xd5, 0x45, 0x35, 0x57, 0x28, 0xca, 0x80, 0xde, 0x97, 0x84, + 0x34, 0xd9, 0x71, 0x47, 0xf9, 0x21, 0xc8, 0x02, 0xfa, 0x7a, 0x42, 0xd4, 0xc4, 0xc5, 0xd8, 0x43, + 0xea, 0x0e, 0x50, 0x70, 0xbf, 0x22, 0x64, 0x59, 0x0c, 0x29, 0x28, 0xfe, 0x6e, 0x65, 0x77, 0xa5, + 0xea, 0xb6, 0x71, 0xe9, 0xff, 0xff, 0xae, 0x64, 0xb7, 0xf2, 0x90, 0xbb, 0x52, 0x0f, 0x12, 0x5e, + 0x48, 0x5d, 0xe9, 0xa9, 0x94, 0xbb, 0x0c, 0x7e, 0xda, 0x27, 0x0d, 0xbe, 0xe5, 0x52, 0x42, 0x6c, + 0xb9, 0xa4, 0xe4, 0x60, 0x4a, 0x6f, 0x59, 0xd8, 0x6c, 0x69, 0xcd, 0x85, 0xa6, 0xb6, 0x45, 0xa7, + 0xa7, 0xfe, 0x7d, 0x1d, 0xca, 0xd3, 0x92, 0x2f, 0x8f, 0xca, 0x7f, 0xa1, 0x9c, 0x00, 0xb0, 0xf0, + 0x4e, 0xbb, 0xa9, 0x59, 0x9e, 0x30, 0xf9, 0x52, 0xd0, 0xd7, 0x84, 0xbd, 0x2f, 0x9d, 0xfe, 0xd5, + 0xc7, 0xfb, 0xd2, 0x95, 0x69, 0xa9, 0x4b, 0xa6, 0xdd, 0xe1, 0x34, 0x25, 0x30, 0x9c, 0xfa, 0xb9, + 0x95, 0x16, 0x5c, 0x5c, 0xbe, 0x51, 0xc8, 0xbd, 0x33, 0xac, 0x19, 0xf1, 0xeb, 0x89, 0xa7, 0x25, + 0x98, 0xa6, 0x55, 0xcf, 0x1b, 0xc6, 0xc5, 0x1d, 0xcd, 0xbc, 0x88, 0xee, 0x3b, 0x88, 0x88, 0xa0, + 0x8f, 0xfa, 0xf1, 0x5b, 0xe4, 0xf1, 0xbb, 0x33, 0xb8, 0xe1, 0x4e, 0xed, 0xa3, 0x59, 0xf6, 0xbf, + 0xd5, 0x45, 0xe6, 0x61, 0x0e, 0x99, 0x57, 0x44, 0x26, 0x30, 0x7e, 0x84, 0xde, 0xe9, 0x22, 0xe4, + 0xa8, 0xcd, 0x03, 0x22, 0xf4, 0xc5, 0xc1, 0x10, 0x72, 0x6a, 0x1f, 0x00, 0x21, 0x19, 0xa4, 0x8b, + 0xf8, 0x0a, 0xeb, 0x80, 0xf6, 0x5f, 0x3f, 0xd9, 0xa9, 0xf8, 0x30, 0x0b, 0x20, 0x79, 0x24, 0x98, + 0x1d, 0xe3, 0x49, 0xa8, 0xb4, 0x87, 0x80, 0xdc, 0x5f, 0x09, 0xdb, 0x1b, 0x7a, 0xb2, 0x81, 0xd2, + 0x30, 0x9a, 0x1e, 0x26, 0x66, 0xac, 0x10, 0x27, 0x33, 0x7e, 0xcc, 0x3e, 0x93, 0x82, 0x71, 0xc7, + 0x27, 0xd6, 0x42, 0xef, 0x49, 0x70, 0x9e, 0x30, 0x1d, 0x63, 0xd7, 0xac, 0x63, 0x66, 0x01, 0x62, + 0x4f, 0x7e, 0xb6, 0x24, 0x05, 0x07, 0xd0, 0x3e, 0xa3, 0xdf, 0xfe, 0x01, 0x36, 0x15, 0x75, 0x80, + 0x45, 0xaf, 0x91, 0x44, 0x97, 0xa2, 0x1c, 0xf7, 0xab, 0xd8, 0x7a, 0x21, 0x8e, 0xa1, 0x7f, 0x24, + 0xb4, 0x8a, 0xed, 0xd3, 0x92, 0x68, 0xc2, 0x53, 0x19, 0x60, 0x32, 0x76, 0x0d, 0x5c, 0xed, 0xe4, + 0xa8, 0xcc, 0x3f, 0x5c, 0xcc, 0xd7, 0xd6, 0xc9, 0x4c, 0x6c, 0x4d, 0x5d, 0x96, 0x25, 0xf4, 0x78, + 0x0a, 0x64, 0x4a, 0x1a, 0xa5, 0xb3, 0x76, 0xa5, 0x8d, 0xd1, 0x0f, 0x1d, 0xf2, 0x44, 0x0c, 0x7d, + 0xc3, 0xaf, 0x4c, 0x4a, 0xbc, 0x9c, 0xdc, 0x15, 0xcc, 0x5d, 0xaf, 0x09, 0x01, 0xe2, 0x32, 0x40, + 0xaf, 0x08, 0x91, 0x30, 0xf4, 0x61, 0x57, 0x00, 0x96, 0x39, 0x01, 0xb8, 0x7b, 0x00, 0x12, 0x0f, + 0x59, 0x0e, 0x3e, 0x92, 0x84, 0x29, 0x67, 0x1a, 0xb1, 0x80, 0xad, 0xfa, 0x36, 0x3a, 0x2b, 0xba, + 0x36, 0x93, 0x41, 0xda, 0x35, 0x9b, 0x8c, 0x4a, 0xfb, 0x2f, 0xfa, 0xa7, 0x84, 0xe8, 0xee, 0x0a, + 0xe3, 0x0d, 0x57, 0x73, 0xc0, 0xc2, 0x56, 0x6c, 0x3b, 0x44, 0xa0, 0xc0, 0xf8, 0xd5, 0xf5, 0xe7, + 0x93, 0x00, 0x35, 0xc3, 0x9d, 0xb4, 0x1e, 0x80, 0x93, 0xdc, 0x01, 0x8d, 0x3c, 0xcf, 0xc9, 0x9e, + 0x2b, 0x7a, 0xaf, 0xda, 0xe8, 0x63, 0x29, 0x7a, 0xb3, 0xcb, 0xe2, 0x05, 0x8e, 0xc5, 0x67, 0x22, + 0xd5, 0x14, 0x3f, 0x7f, 0xdf, 0x97, 0x84, 0xf1, 0xc2, 0x6e, 0xbb, 0xa9, 0xd7, 0xed, 0x75, 0xe3, + 0xcd, 0x82, 0xec, 0x45, 0x8f, 0x27, 0x23, 0x8e, 0x3e, 0x6e, 0x1d, 0x01, 0xbc, 0xa4, 0x6e, 0x8f, + 0x49, 0xc7, 0xed, 0x51, 0xd0, 0xac, 0xd9, 0xa7, 0xf0, 0x11, 0x88, 0xa7, 0x04, 0x47, 0x2b, 0x6d, + 0xdc, 0x9a, 0x37, 0xb1, 0xd6, 0xa8, 0x9b, 0xbb, 0x3b, 0x1b, 0x1d, 0x94, 0x13, 0x95, 0x51, 0x9f, + 0xb5, 0x25, 0xc9, 0x59, 0x5b, 0xd0, 0x8f, 0xfb, 0x07, 0xf7, 0x25, 0x9e, 0xbd, 0x67, 0x82, 0xac, + 0x7c, 0x3e, 0x1a, 0x06, 0x98, 0xfc, 0x45, 0xb2, 0x3a, 0x77, 0x99, 0x5c, 0x52, 0x51, 0x4c, 0x2e, + 0xbf, 0xe1, 0x22, 0x7b, 0x8e, 0x43, 0xf6, 0x95, 0xd1, 0xdb, 0x35, 0x92, 0xcd, 0x83, 0xe9, 0x2a, + 0xb6, 0x02, 0xe0, 0xbd, 0x11, 0xa6, 0x36, 0xbc, 0x37, 0x2e, 0xc4, 0x7c, 0x62, 0x8f, 0x2d, 0xbe, + 0xb7, 0x47, 0x5d, 0x9a, 0xf1, 0x24, 0x04, 0xa0, 0xeb, 0x22, 0x98, 0x14, 0xd9, 0x37, 0x88, 0xb4, + 0xce, 0x0a, 0xad, 0x3f, 0x7e, 0x14, 0xde, 0x26, 0xc1, 0x74, 0x69, 0xa7, 0x6d, 0x98, 0xd6, 0x8a, + 0x66, 0x5e, 0x24, 0x27, 0xa2, 0x17, 0x45, 0x3b, 0xd9, 0x09, 0x00, 0x9d, 0x7c, 0xea, 0xf3, 0xa0, + 0xf6, 0xa5, 0xa0, 0x67, 0xa3, 0x62, 0xc1, 0x13, 0x12, 0xec, 0x17, 0x62, 0x1a, 0x86, 0xb5, 0xac, + 0xb7, 0x2e, 0x7a, 0x3b, 0xe7, 0xfe, 0xa4, 0x88, 0xbb, 0x3c, 0x91, 0xd0, 0x0a, 0xa5, 0x30, 0x7e, + 0xb4, 0x3e, 0x98, 0x84, 0x89, 0xea, 0xb6, 0x66, 0xe2, 0xf9, 0x2b, 0x76, 0x63, 0x45, 0xfd, 0x48, + 0x5e, 0xed, 0x07, 0x42, 0x81, 0x54, 0x53, 0x6f, 0x5d, 0x74, 0xb6, 0xe7, 0xec, 0xff, 0x5e, 0x58, + 0x80, 0x64, 0x8f, 0xb0, 0x00, 0xae, 0x89, 0xd6, 0xad, 0x37, 0x60, 0xee, 0xf3, 0x16, 0xa1, 0xb0, + 0x00, 0x7d, 0x8b, 0x8b, 0x9f, 0x8d, 0x9f, 0x4e, 0xc2, 0xd1, 0x5c, 0xa3, 0x71, 0x41, 0xb7, 0xb6, + 0x2b, 0x0e, 0x8f, 0x1e, 0x14, 0xdb, 0x54, 0x9f, 0x81, 0x6c, 0x5b, 0xbb, 0xd2, 0x34, 0x34, 0x77, + 0x60, 0x61, 0x8f, 0xe8, 0xb1, 0x64, 0xc4, 0x81, 0xa5, 0x8b, 0x82, 0x00, 0xa6, 0x46, 0xd2, 0xe9, + 0xe1, 0x45, 0xc6, 0xcf, 0xd8, 0x3f, 0x4f, 0x41, 0xa6, 0x8a, 0x35, 0xb3, 0xbe, 0x8d, 0x5e, 0x9f, + 0xf4, 0x18, 0xba, 0x00, 0xd9, 0x4d, 0xbd, 0x69, 0x61, 0x93, 0x7a, 0x80, 0xf8, 0xe7, 0x31, 0x74, + 0x3c, 0x9b, 0x6f, 0x1a, 0xf5, 0x8b, 0x73, 0x79, 0x5b, 0xb3, 0xb4, 0xac, 0x39, 0xe7, 0xcc, 0xe5, + 0xdc, 0x02, 0xf9, 0x48, 0x75, 0x3e, 0x56, 0x1e, 0x82, 0x74, 0xc7, 0x30, 0x2d, 0x67, 0xad, 0x76, + 0x4a, 0xac, 0x94, 0xaa, 0x61, 0x5a, 0x2a, 0xfd, 0xd0, 0x86, 0x76, 0x73, 0xb7, 0xd9, 0xac, 0xe1, + 0xcb, 0x96, 0xb3, 0x4e, 0x72, 0x9e, 0x95, 0xe3, 0x90, 0x31, 0x36, 0x37, 0x3b, 0x98, 0x2e, 0xc5, + 0xd3, 0x2a, 0x7b, 0x52, 0x8e, 0x41, 0xba, 0xa9, 0xef, 0xe8, 0x16, 0x59, 0x71, 0xa7, 0x55, 0xfa, + 0xa0, 0x9c, 0x02, 0xd9, 0x70, 0x57, 0x49, 0x94, 0xd0, 0x99, 0x0c, 0xd1, 0x45, 0xfb, 0xd2, 0xed, + 0x2e, 0x77, 0x11, 0x5f, 0xe9, 0xcc, 0x64, 0xc9, 0x7b, 0xf2, 0x1f, 0x3d, 0x13, 0xd5, 0x4a, 0x4f, + 0xf9, 0x1a, 0xbc, 0x64, 0x34, 0x71, 0xdd, 0x30, 0x1b, 0x0e, 0x6f, 0x82, 0x97, 0x8c, 0x2c, 0x5f, + 0x34, 0xdb, 0x7a, 0xcf, 0xca, 0xe3, 0x97, 0xa7, 0x67, 0x32, 0x90, 0x5e, 0x34, 0xb5, 0xf6, 0x36, + 0xfa, 0xb5, 0xc4, 0xf0, 0xc5, 0xc9, 0x05, 0x36, 0xd9, 0x0f, 0x58, 0xa9, 0x0f, 0xb0, 0x29, 0x1f, + 0xb0, 0x4f, 0x25, 0x21, 0x55, 0x6c, 0x6c, 0x61, 0xce, 0xe8, 0x95, 0xf0, 0x19, 0xbd, 0x8e, 0x43, + 0xc6, 0xd2, 0xcc, 0x2d, 0x6c, 0x31, 0x2e, 0xb1, 0x27, 0xd7, 0xab, 0x52, 0xf2, 0x9d, 0xcd, 0x7d, + 0x25, 0xa4, 0xec, 0x76, 0x11, 0x89, 0x9c, 0x3e, 0x73, 0x43, 0x2f, 0x68, 0x08, 0x7f, 0xe6, 0xec, + 0x1a, 0xe7, 0x6c, 0xca, 0x54, 0xf2, 0x41, 0x37, 0x1e, 0xe9, 0x7d, 0x78, 0xd8, 0x63, 0xbb, 0x5e, + 0x37, 0x5a, 0xa5, 0x1d, 0x6d, 0x0b, 0xcf, 0x64, 0xe8, 0xd8, 0xee, 0x26, 0x38, 0x6f, 0x8b, 0x3b, + 0xc6, 0xa3, 0xfa, 0x4c, 0xd6, 0x7b, 0x4b, 0x12, 0xec, 0x26, 0x6c, 0xeb, 0x8d, 0x06, 0x6e, 0xcd, + 0x8c, 0xd1, 0x93, 0x6d, 0xf4, 0x69, 0xf6, 0x04, 0xa4, 0x6c, 0x1a, 0x6c, 0x8c, 0x6d, 0xc5, 0x2e, + 0x1f, 0x51, 0x26, 0x6d, 0x29, 0xa7, 0x56, 0x49, 0x39, 0x81, 0x3e, 0x9e, 0x8c, 0xb8, 0x87, 0x4c, + 0x1b, 0xd7, 0x5b, 0xe6, 0x6f, 0x87, 0x74, 0xcb, 0x68, 0xe0, 0xbe, 0x12, 0x4f, 0x73, 0x29, 0x2f, + 0x83, 0x34, 0x6e, 0x6c, 0xe1, 0x0e, 0x01, 0x73, 0xe2, 0xcc, 0x89, 0x70, 0x5e, 0xaa, 0x34, 0x73, + 0xb4, 0x8d, 0xea, 0x5e, 0xd4, 0xc6, 0xdf, 0x49, 0xfe, 0x4f, 0x06, 0x8e, 0xd2, 0xfe, 0x59, 0xdd, + 0xdd, 0xb0, 0x8b, 0xda, 0xc0, 0xe8, 0x67, 0x25, 0x2e, 0x18, 0x40, 0x67, 0x77, 0xc3, 0x1d, 0xcb, + 0xe8, 0x83, 0xbf, 0x13, 0x25, 0x87, 0xa2, 0x93, 0xa5, 0x41, 0x75, 0x32, 0xa7, 0x5f, 0x25, 0xa7, + 0x1b, 0x7a, 0xda, 0x38, 0x43, 0x92, 0x1d, 0x6d, 0xdc, 0x43, 0x97, 0xda, 0x83, 0xb2, 0xb6, 0x69, + 0x61, 0xb3, 0xd4, 0x20, 0xf2, 0x38, 0xae, 0x3a, 0x8f, 0xb6, 0xbe, 0xdf, 0xc0, 0x9b, 0x86, 0x69, + 0x2f, 0x04, 0xc7, 0xa9, 0xbe, 0x77, 0x9e, 0x7d, 0xfd, 0x13, 0x38, 0xa3, 0xf4, 0x2d, 0x70, 0x54, + 0xdf, 0x6a, 0x19, 0x26, 0x76, 0x3d, 0x7b, 0x66, 0x26, 0xe9, 0x29, 0xf6, 0xae, 0x64, 0xe5, 0x36, + 0xb8, 0xaa, 0x65, 0x14, 0x70, 0x9b, 0xf1, 0x9d, 0xa2, 0x3a, 0x45, 0x7a, 0xc4, 0xfe, 0x17, 0xe8, + 0x63, 0x51, 0x57, 0x9e, 0x5d, 0xa0, 0x0e, 0x4d, 0xf5, 0x2b, 0xf7, 0xc2, 0x64, 0x83, 0x79, 0x0d, + 0xd4, 0x75, 0xb7, 0x47, 0x04, 0x7e, 0xc7, 0x65, 0xf6, 0xc4, 0x29, 0xe5, 0x17, 0xa7, 0x45, 0x18, + 0x23, 0xc7, 0x54, 0x6c, 0x79, 0x4a, 0x77, 0x1d, 0x84, 0x26, 0xd3, 0x6d, 0xb7, 0x51, 0x3e, 0x96, + 0xcc, 0xe5, 0xd9, 0x27, 0xaa, 0xfb, 0x71, 0xb4, 0xf9, 0x4e, 0x38, 0x87, 0xe2, 0xef, 0x7a, 0x3f, + 0x9f, 0x82, 0xa3, 0x8b, 0xa6, 0xb1, 0xdb, 0xee, 0x78, 0x5d, 0xcf, 0x1f, 0x6e, 0xa1, 0x77, 0xd7, + 0xb3, 0x57, 0x30, 0x4c, 0x27, 0x9e, 0xc3, 0x4e, 0xb4, 0x17, 0x7f, 0x92, 0xbf, 0x73, 0x4a, 0x07, + 0xe9, 0x9c, 0x9e, 0x88, 0xa7, 0xfc, 0x22, 0x8e, 0x3e, 0x17, 0x75, 0xae, 0xda, 0xd5, 0xc8, 0x00, + 0x51, 0xcc, 0x43, 0x66, 0x8b, 0x64, 0x64, 0x92, 0x78, 0xab, 0x18, 0xd5, 0xa4, 0x70, 0x95, 0x7d, + 0xea, 0xf1, 0x4c, 0xf2, 0xf1, 0x2c, 0x9a, 0x58, 0x84, 0x53, 0x3b, 0x02, 0xd3, 0x46, 0x0a, 0x26, + 0xdd, 0xda, 0x4b, 0x8d, 0x0e, 0x32, 0xfa, 0x89, 0xc4, 0x3e, 0x43, 0x86, 0xab, 0xe7, 0x24, 0x9f, + 0x9e, 0xeb, 0xa1, 0x99, 0x26, 0x7a, 0x6a, 0x26, 0xf4, 0x98, 0x24, 0x1a, 0xea, 0x85, 0xef, 0x96, + 0x84, 0xdc, 0x17, 0xb2, 0xa2, 0x11, 0x0c, 0x38, 0xd3, 0xbf, 0x55, 0xf1, 0x4b, 0xc1, 0xfb, 0x93, + 0x70, 0x15, 0x55, 0x50, 0x6b, 0xad, 0x8e, 0xab, 0x1e, 0xf8, 0xf8, 0x00, 0xa4, 0x4d, 0x1d, 0x77, + 0x57, 0x94, 0x3c, 0xf1, 0x16, 0xe0, 0xd0, 0x23, 0x07, 0x9c, 0x1a, 0xf4, 0xd5, 0x12, 0xb0, 0x96, + 0x14, 0x3b, 0x54, 0x20, 0x58, 0xe8, 0x08, 0xb4, 0xab, 0x04, 0xe3, 0x55, 0x6c, 0x2d, 0x6b, 0x57, + 0x8c, 0x5d, 0x0b, 0x69, 0xa2, 0x66, 0xa9, 0xbb, 0x21, 0xd3, 0x24, 0x9f, 0x10, 0x0d, 0x32, 0x7d, + 0xe6, 0xfa, 0x9e, 0xc6, 0x53, 0xb2, 0xb9, 0x45, 0x8b, 0x56, 0x59, 0x7e, 0xfe, 0xac, 0x87, 0x88, + 0xe9, 0xdd, 0xa5, 0x6e, 0x28, 0x76, 0xc3, 0x48, 0x86, 0xf9, 0xa0, 0xaa, 0xe3, 0x87, 0xe5, 0xc7, + 0x25, 0x98, 0x22, 0xae, 0xfa, 0x0b, 0xda, 0x9e, 0x61, 0xea, 0x16, 0x8e, 0x66, 0x31, 0x74, 0x3f, + 0x63, 0xe7, 0x11, 0x7c, 0x29, 0xe8, 0x6d, 0xc9, 0x88, 0x5b, 0x72, 0x1c, 0x1d, 0x43, 0x01, 0x21, + 0xd2, 0x06, 0x5e, 0x58, 0xf5, 0x23, 0x04, 0x22, 0x67, 0xd6, 0xb7, 0xf5, 0x3d, 0xdc, 0x88, 0x08, + 0x84, 0xf3, 0x99, 0x07, 0x84, 0x5b, 0xd0, 0x60, 0x40, 0x38, 0x9f, 0x1f, 0x12, 0x10, 0x01, 0xd5, + 0xc7, 0x0f, 0xc4, 0x5b, 0x29, 0x10, 0x3e, 0xdf, 0x84, 0x15, 0x51, 0x20, 0x6e, 0x84, 0x29, 0xcf, + 0xaa, 0xb0, 0x66, 0x36, 0xd9, 0xac, 0x87, 0x4f, 0x44, 0x1f, 0x1e, 0x00, 0x8e, 0xbe, 0x6e, 0x06, + 0xd1, 0xe0, 0xf8, 0x50, 0x44, 0x38, 0x5e, 0xa8, 0x2e, 0x04, 0xcf, 0x4a, 0xf4, 0x44, 0x15, 0xe7, + 0xc9, 0xf1, 0xa8, 0x28, 0x5c, 0xfb, 0xbc, 0x46, 0xb2, 0x91, 0xbd, 0x46, 0x3e, 0x1a, 0xd5, 0x6b, + 0xa4, 0x9b, 0xda, 0xa1, 0xc0, 0x19, 0xc9, 0x29, 0xa4, 0x0f, 0x05, 0x87, 0x8c, 0xe8, 0x57, 0x25, + 0x00, 0x12, 0x67, 0x98, 0xfa, 0x3b, 0x2d, 0x41, 0x86, 0xfe, 0x75, 0x9c, 0x26, 0x13, 0x9e, 0xd3, + 0xe4, 0x6d, 0x90, 0xde, 0xd3, 0x9a, 0xbb, 0xd8, 0xe5, 0x51, 0xf7, 0x44, 0xf4, 0xbc, 0xfd, 0x56, + 0xa5, 0x99, 0xd0, 0xb6, 0xa8, 0x54, 0x3c, 0xe8, 0x77, 0xd8, 0xb1, 0xe5, 0xe1, 0xa6, 0x00, 0x2e, + 0x32, 0x1a, 0xe7, 0xe8, 0xaf, 0xe7, 0xa3, 0xf5, 0xe6, 0xa8, 0x0e, 0x14, 0xbe, 0xb2, 0x86, 0x21, + 0x0d, 0x91, 0x5c, 0x2a, 0x02, 0xeb, 0x8e, 0x5f, 0xd1, 0x7e, 0x34, 0x09, 0xe9, 0x9a, 0x51, 0xc5, + 0xdc, 0x79, 0xb3, 0x70, 0x6c, 0xbc, 0x25, 0x70, 0x92, 0x5b, 0x02, 0xff, 0x68, 0x54, 0x53, 0x24, + 0xa9, 0x37, 0x38, 0x98, 0x68, 0x07, 0x7b, 0x5b, 0xff, 0xf4, 0x21, 0x9a, 0xed, 0xb0, 0x57, 0xf1, + 0xf1, 0x33, 0xf4, 0x2c, 0x1c, 0x5d, 0x6b, 0x35, 0x0c, 0x15, 0x37, 0x0c, 0x66, 0x8b, 0xb1, 0x17, + 0x9e, 0xbb, 0xad, 0x86, 0x41, 0x68, 0x4d, 0xab, 0xe4, 0xbf, 0x9d, 0x66, 0xe2, 0x86, 0xc1, 0x0c, + 0xe5, 0xe4, 0x3f, 0x7a, 0x83, 0x04, 0x29, 0xfb, 0x5b, 0x71, 0xcf, 0x96, 0xaf, 0x45, 0x3d, 0x98, + 0x62, 0x17, 0x3f, 0x0c, 0xf9, 0x56, 0x1e, 0xf4, 0x59, 0xa7, 0xe8, 0xa6, 0xf0, 0x0d, 0x41, 0xf5, + 0xf9, 0x58, 0xe1, 0xb3, 0x4a, 0xbd, 0x33, 0xca, 0x61, 0x96, 0x1e, 0x64, 0x47, 0x43, 0xb2, 0x30, + 0x80, 0x8a, 0x94, 0x61, 0x32, 0x9f, 0x2b, 0x93, 0xc8, 0x2c, 0x2b, 0x95, 0xf3, 0x45, 0x59, 0x22, + 0x00, 0xd9, 0xad, 0x89, 0x11, 0x20, 0xbb, 0xf8, 0xef, 0x40, 0x80, 0x7a, 0x90, 0x7d, 0x18, 0x00, + 0x7d, 0x24, 0x09, 0x53, 0xcb, 0x7a, 0xc7, 0x0a, 0x72, 0x12, 0x0b, 0x39, 0x37, 0xff, 0x9a, 0xa8, + 0x13, 0x42, 0xae, 0x1e, 0xe1, 0x03, 0xf3, 0x91, 0xe6, 0xe0, 0x61, 0x55, 0x8c, 0xc6, 0x9b, 0x91, + 0x50, 0x40, 0xc3, 0x30, 0x0a, 0x73, 0x32, 0xf2, 0xd0, 0xeb, 0x55, 0x32, 0xfa, 0xa1, 0x37, 0xb0, + 0xee, 0xf8, 0xf9, 0xfb, 0xe5, 0x24, 0x5c, 0x65, 0x57, 0x1f, 0xb6, 0xe0, 0x0c, 0x66, 0x73, 0xdf, + 0x05, 0x67, 0x64, 0x9b, 0xd7, 0x3e, 0x5a, 0x86, 0x61, 0xf3, 0xea, 0x57, 0xe8, 0x88, 0xd9, 0x1c, + 0x60, 0x60, 0xe9, 0xc7, 0xe6, 0x10, 0x03, 0xcb, 0xe0, 0x6c, 0x0e, 0x37, 0xb2, 0x0c, 0xc8, 0xe6, + 0x43, 0x33, 0x9d, 0x7c, 0x36, 0x09, 0x53, 0xb9, 0x76, 0xbb, 0x79, 0xa5, 0xc6, 0x4e, 0x8e, 0x44, + 0x32, 0x9d, 0xf8, 0x0e, 0xa0, 0x24, 0xf7, 0x1d, 0xbf, 0x8c, 0xec, 0x56, 0xce, 0xd1, 0x31, 0x0c, + 0xb7, 0xf2, 0xb0, 0x02, 0xe3, 0x67, 0xed, 0xab, 0xd3, 0x54, 0x11, 0xb3, 0xc0, 0x10, 0x9f, 0x4e, + 0x84, 0x47, 0x86, 0x08, 0x0d, 0x83, 0xa3, 0xdc, 0x0f, 0x99, 0x4d, 0xc3, 0xdc, 0xd1, 0x1c, 0x5b, + 0xee, 0x4d, 0x41, 0xe2, 0xc4, 0x62, 0x2f, 0x2c, 0x90, 0xcc, 0x2a, 0xfb, 0xc8, 0x1e, 0xd1, 0x5e, + 0xa5, 0xb7, 0xd9, 0xd9, 0x69, 0xfb, 0x2f, 0x09, 0x8a, 0x42, 0x8f, 0x50, 0x97, 0x71, 0xc7, 0xc2, + 0x0d, 0xb2, 0x59, 0x39, 0xa6, 0xf2, 0x89, 0xca, 0x2c, 0x4c, 0xb2, 0x84, 0x05, 0xbd, 0x89, 0x3b, + 0x64, 0x0b, 0x7a, 0x4c, 0xe5, 0xd2, 0xd0, 0x27, 0x06, 0x19, 0x38, 0x22, 0x47, 0xac, 0x98, 0x81, + 0x6c, 0x67, 0xb7, 0x5e, 0xc7, 0xb8, 0xc1, 0xbc, 0x92, 0x9c, 0xc7, 0x88, 0x5e, 0x8e, 0x91, 0x87, + 0x99, 0xc3, 0x09, 0x66, 0x31, 0xbb, 0x0a, 0x19, 0x8a, 0xa1, 0x32, 0x09, 0x63, 0x8e, 0x9f, 0x25, + 0xf5, 0x23, 0x59, 0x65, 0x8b, 0x74, 0x39, 0x61, 0x97, 0xf8, 0x70, 0xb5, 0x52, 0xa6, 0xc1, 0x01, + 0x0b, 0x15, 0x16, 0x1c, 0xb0, 0x7a, 0x7e, 0x51, 0x4e, 0x29, 0xd3, 0x00, 0x8b, 0x6a, 0x6e, 0x75, + 0x69, 0x9d, 0xe4, 0x48, 0xa3, 0x2f, 0x8f, 0x41, 0x86, 0xba, 0x6d, 0xa2, 0x4f, 0x64, 0xfc, 0x97, + 0x33, 0x4d, 0xb6, 0x0c, 0x9b, 0xcc, 0x55, 0xcd, 0xd4, 0x76, 0x3a, 0x61, 0x7b, 0x63, 0xf4, 0x6b, + 0xf7, 0x62, 0xa6, 0xb2, 0xef, 0xb3, 0xa5, 0x23, 0x2a, 0x57, 0x8c, 0xf2, 0x2f, 0xe1, 0xe8, 0x06, + 0x3b, 0x70, 0xd0, 0x61, 0x25, 0x27, 0x83, 0xb7, 0x55, 0xbb, 0x4a, 0x9e, 0xe7, 0xbf, 0x5c, 0x3a, + 0xa2, 0x76, 0x17, 0xa6, 0x7c, 0x3f, 0x4c, 0xef, 0x30, 0xae, 0xb0, 0xe2, 0xa5, 0x7e, 0xfe, 0xb4, + 0x6e, 0xf1, 0x2b, 0xdc, 0x87, 0x4b, 0x47, 0xd4, 0xae, 0xa2, 0x94, 0x12, 0x8c, 0x77, 0x5a, 0x5a, + 0xbb, 0xb3, 0x6d, 0x58, 0xce, 0xb9, 0xb9, 0x5b, 0x05, 0xca, 0xad, 0xb2, 0x6f, 0x54, 0xef, 0x6b, + 0xe5, 0x65, 0xf0, 0xe2, 0x5d, 0x12, 0xaa, 0xb2, 0x78, 0x59, 0xef, 0x58, 0x7a, 0x6b, 0xcb, 0x89, + 0x63, 0x40, 0xfb, 0x5b, 0xef, 0x97, 0xca, 0xbd, 0xcc, 0xdd, 0x29, 0x43, 0x64, 0xf3, 0x66, 0x81, + 0xba, 0x7d, 0x2e, 0x4f, 0xf7, 0x42, 0x6a, 0xc7, 0x16, 0xec, 0xac, 0xf0, 0xc7, 0x2b, 0x44, 0x9a, + 0xed, 0x8f, 0xd0, 0x49, 0x98, 0xf4, 0xe3, 0xaa, 0x1c, 0x87, 0x8c, 0xd6, 0xd6, 0xcf, 0xb9, 0xe6, + 0x23, 0xf6, 0x84, 0x6e, 0x84, 0x69, 0x9e, 0x8d, 0xbd, 0x94, 0x1a, 0xba, 0x01, 0x8e, 0x76, 0x61, + 0xe9, 0x9c, 0x9a, 0x49, 0x78, 0xa7, 0x66, 0x7e, 0x00, 0xc6, 0x1c, 0xce, 0xed, 0x0b, 0x4d, 0x9d, + 0x83, 0x31, 0x87, 0x97, 0x4c, 0x7e, 0x6e, 0xea, 0x32, 0x31, 0x56, 0x77, 0x34, 0xd3, 0x22, 0x1b, + 0xea, 0x4e, 0x21, 0xf3, 0x5a, 0x07, 0xab, 0xee, 0x67, 0xb3, 0xb7, 0x43, 0xca, 0x6e, 0x9f, 0xa2, + 0xc0, 0x74, 0x6e, 0x79, 0x79, 0xbd, 0x42, 0xc2, 0xa2, 0x2f, 0x95, 0xca, 0x8b, 0xb4, 0x1f, 0x96, + 0x16, 0xcb, 0x15, 0xb5, 0x48, 0xbb, 0x61, 0x55, 0x4e, 0xcc, 0xce, 0x31, 0xd7, 0x2d, 0x80, 0x0c, + 0x65, 0x04, 0xed, 0x74, 0x6e, 0x17, 0x4c, 0xd8, 0x4f, 0xc5, 0xcb, 0xd4, 0x0a, 0x28, 0x27, 0xe7, + 0xc7, 0x20, 0xd3, 0x26, 0x2d, 0xe3, 0x2d, 0x29, 0x22, 0x9e, 0x8c, 0x2e, 0x0a, 0xbd, 0x46, 0xba, + 0x77, 0x47, 0x71, 0x4b, 0xec, 0x59, 0x52, 0x34, 0x25, 0xb5, 0xb0, 0x4f, 0x49, 0x29, 0x30, 0x5d, + 0x2a, 0xd7, 0x8a, 0x6a, 0x39, 0xb7, 0xec, 0x6a, 0xa9, 0x7d, 0x8a, 0x2b, 0xc9, 0x2b, 0x2e, 0x09, + 0x7d, 0x4d, 0x02, 0xa0, 0xe4, 0xd8, 0xda, 0xd3, 0x1f, 0x5f, 0xf2, 0xd3, 0x51, 0x07, 0x0a, 0xaf, + 0x98, 0x80, 0x81, 0xa2, 0x04, 0x63, 0x26, 0x7b, 0xc1, 0x0c, 0x8e, 0xfd, 0xca, 0xa1, 0x7f, 0x9d, + 0xd2, 0x54, 0xf7, 0x73, 0xf4, 0xde, 0x28, 0xe3, 0x42, 0x20, 0x61, 0x87, 0xc3, 0xf2, 0x57, 0x39, + 0x47, 0x17, 0x7c, 0xd3, 0x2d, 0xaa, 0x3f, 0xc4, 0xda, 0xc0, 0x7f, 0xec, 0x53, 0x25, 0xb3, 0xd7, + 0xf7, 0xeb, 0x0c, 0xe8, 0x83, 0x47, 0x61, 0x9a, 0x96, 0xe8, 0xc6, 0x14, 0xf8, 0x47, 0x16, 0xdc, + 0xf1, 0x9c, 0xe8, 0x4c, 0x72, 0x16, 0x26, 0x7d, 0x4e, 0x3f, 0x6e, 0x9c, 0x50, 0x7f, 0x1a, 0x7f, + 0xc9, 0x54, 0xe8, 0xed, 0x7d, 0x3c, 0x35, 0x21, 0x01, 0x20, 0xa3, 0xad, 0x4f, 0xa3, 0x38, 0xf5, + 0x87, 0x54, 0x1e, 0xff, 0xbc, 0xf3, 0x71, 0xef, 0x0e, 0x86, 0xa1, 0x22, 0x10, 0xf5, 0x44, 0x91, + 0xcb, 0x04, 0x31, 0x23, 0xc1, 0xd0, 0xcf, 0xa8, 0x84, 0xd7, 0x1f, 0x3f, 0x0e, 0xdf, 0x66, 0x56, + 0xad, 0xdc, 0x9e, 0xa6, 0x37, 0xb5, 0x8d, 0x66, 0x84, 0xa3, 0x8f, 0x1f, 0xf4, 0xb3, 0xba, 0xcc, + 0xb3, 0xfa, 0xee, 0xb0, 0xa6, 0x72, 0xf5, 0x05, 0x5e, 0x93, 0x31, 0xee, 0xe0, 0xea, 0x39, 0x30, + 0xf1, 0x63, 0xaa, 0x53, 0x9e, 0xea, 0xe5, 0x44, 0xbf, 0xed, 0xb2, 0xfe, 0x7b, 0x38, 0xd6, 0xdf, + 0x3f, 0x28, 0x3d, 0xf1, 0x23, 0xf0, 0xd3, 0x12, 0x4c, 0xe4, 0x1a, 0x8d, 0x05, 0xac, 0x59, 0xbb, + 0x26, 0x6e, 0xa0, 0xa2, 0x68, 0x77, 0xb8, 0xb6, 0x9b, 0x45, 0xe3, 0x7e, 0x4e, 0xbc, 0x47, 0x38, + 0x52, 0xe4, 0x7e, 0x6d, 0xe0, 0xd0, 0x32, 0x14, 0x95, 0x24, 0x16, 0x57, 0x52, 0x98, 0x88, 0xf8, + 0x01, 0x79, 0x9d, 0x04, 0xd3, 0x34, 0x80, 0xe8, 0xb0, 0x31, 0xf9, 0x03, 0x3f, 0x26, 0x15, 0x1e, + 0x93, 0xb3, 0x61, 0xec, 0xe0, 0xc9, 0x19, 0x0a, 0x2c, 0x9e, 0x09, 0x5e, 0xe5, 0x60, 0x79, 0x60, + 0x60, 0x3a, 0xe2, 0x47, 0xe6, 0xeb, 0x00, 0xe0, 0x73, 0xdb, 0xf8, 0x02, 0x78, 0xc7, 0x15, 0xd0, + 0x47, 0x25, 0x3a, 0x9e, 0x57, 0xb9, 0x53, 0xa9, 0xbc, 0xb7, 0x46, 0xa2, 0x87, 0xb7, 0x86, 0xd0, + 0xa8, 0xf2, 0xcd, 0x88, 0x5e, 0x00, 0xcc, 0x91, 0xa2, 0xef, 0xe0, 0x3e, 0xa0, 0x96, 0x7b, 0x2e, + 0x82, 0x3b, 0x40, 0x3f, 0x52, 0xe2, 0xbf, 0x15, 0x28, 0xcc, 0x1d, 0x40, 0x99, 0x81, 0x63, 0x6a, + 0x31, 0x57, 0xa8, 0x94, 0x97, 0x1f, 0xf1, 0xbf, 0x95, 0x53, 0xe8, 0x57, 0x24, 0xc8, 0xb0, 0x00, + 0xc5, 0xb1, 0x60, 0xfa, 0x1f, 0x23, 0x2a, 0x48, 0x9e, 0x91, 0x61, 0xb1, 0x8c, 0xd1, 0x7f, 0x8e, + 0xa0, 0xf2, 0x04, 0x8a, 0x7d, 0xc1, 0x42, 0xf4, 0x79, 0x09, 0x52, 0x64, 0xfd, 0xb4, 0x1b, 0x15, + 0xa0, 0x02, 0x5c, 0xa7, 0xb5, 0xdb, 0xb8, 0xd5, 0x70, 0x43, 0x23, 0x2e, 0x98, 0xc6, 0x4e, 0xc5, + 0xda, 0xc6, 0xa6, 0x9d, 0xa5, 0xc3, 0x8c, 0xe1, 0xe1, 0x99, 0xd0, 0xe7, 0x23, 0xda, 0xc7, 0x79, + 0x5e, 0x87, 0x2c, 0xd9, 0xce, 0xee, 0xef, 0x97, 0xd7, 0x04, 0xf4, 0xcb, 0x65, 0xbd, 0x75, 0xd1, + 0xdf, 0x37, 0xff, 0x34, 0x82, 0x69, 0xbd, 0x2f, 0x3d, 0x87, 0xec, 0xab, 0xf3, 0x58, 0xc6, 0xa7, + 0x60, 0x7f, 0x42, 0x02, 0xd9, 0x8b, 0xad, 0xcd, 0xe2, 0x7b, 0x55, 0xf8, 0xad, 0x0e, 0x92, 0xe8, + 0xdf, 0xea, 0x70, 0x12, 0x94, 0x93, 0x30, 0x5d, 0xdf, 0xc6, 0xf5, 0x8b, 0xa5, 0x96, 0x63, 0x5a, + 0xa2, 0x08, 0x77, 0xa5, 0xf2, 0x4e, 0xbd, 0xe7, 0x78, 0x48, 0x79, 0xf3, 0x39, 0xc7, 0x37, 0x3f, + 0x51, 0x01, 0x9d, 0xd2, 0x03, 0xa6, 0xcc, 0x01, 0x73, 0xcf, 0x40, 0xa5, 0x46, 0x43, 0xa6, 0x3c, + 0xd8, 0x1d, 0x2e, 0x95, 0x55, 0x72, 0xe9, 0xe1, 0x5a, 0xb5, 0x58, 0x58, 0x9f, 0x77, 0x3a, 0x5f, + 0x55, 0x96, 0xd0, 0x57, 0x93, 0x90, 0xa5, 0x64, 0x75, 0xba, 0x62, 0x5f, 0xfb, 0x8f, 0xaa, 0x24, + 0xf6, 0x1d, 0x55, 0x41, 0xef, 0x10, 0xf6, 0x99, 0x76, 0x19, 0xc1, 0xea, 0x09, 0xe8, 0x29, 0x77, + 0x43, 0x96, 0x82, 0xec, 0x58, 0x4e, 0x4f, 0x04, 0xf4, 0x13, 0x56, 0x8c, 0xea, 0x64, 0x17, 0xf4, + 0x9f, 0xee, 0x43, 0x46, 0xfc, 0x73, 0x8e, 0xb7, 0x4c, 0x40, 0x76, 0x49, 0xef, 0x58, 0x86, 0x79, + 0x05, 0xbd, 0x39, 0x01, 0xd9, 0xf3, 0xd8, 0xec, 0xe8, 0x46, 0x6b, 0x9f, 0x0d, 0xf0, 0x7a, 0x98, + 0x68, 0x9b, 0x78, 0x4f, 0x37, 0x76, 0x3b, 0xbe, 0x40, 0x07, 0xbe, 0x24, 0x05, 0xc1, 0x98, 0xb6, + 0x6b, 0x6d, 0x1b, 0xa6, 0x17, 0xf5, 0xc9, 0x79, 0x56, 0x4e, 0x00, 0xd0, 0xff, 0x65, 0x6d, 0x07, + 0xb3, 0x23, 0x14, 0xbe, 0x14, 0x45, 0x81, 0x94, 0xa5, 0xef, 0x60, 0x76, 0xe8, 0x8e, 0xfc, 0x57, + 0x66, 0x20, 0x4b, 0x0e, 0xe1, 0x94, 0x1a, 0xec, 0xd0, 0x9d, 0xf3, 0x88, 0x7e, 0x5d, 0x82, 0x89, + 0x45, 0x6c, 0x31, 0x52, 0x3b, 0x7e, 0x67, 0xfc, 0x3e, 0x21, 0xe8, 0x9b, 0x5a, 0xc7, 0xf9, 0xcc, + 0xdd, 0x2e, 0xe3, 0x13, 0xbd, 0x03, 0x80, 0x92, 0xef, 0x1c, 0x2e, 0x7a, 0x77, 0x52, 0xf4, 0x08, + 0x0b, 0x63, 0xe6, 0x9c, 0x8f, 0xc0, 0x40, 0xd9, 0x1a, 0xdb, 0x63, 0x39, 0x98, 0x12, 0xbe, 0xb6, + 0x67, 0x49, 0xac, 0x18, 0xd5, 0xcd, 0x2d, 0x78, 0xec, 0xa4, 0x3f, 0x25, 0xf1, 0x8b, 0xd7, 0xdf, + 0x4b, 0x30, 0x51, 0xdd, 0x36, 0x2e, 0x31, 0x02, 0xd0, 0x0f, 0x88, 0x41, 0x75, 0x2d, 0x8c, 0xef, + 0x75, 0xc1, 0xe4, 0x25, 0x04, 0x47, 0x2f, 0x46, 0x4f, 0x4a, 0x51, 0x61, 0xf2, 0x11, 0x37, 0xf4, + 0xa8, 0xc3, 0xca, 0x2b, 0x20, 0xcb, 0xa8, 0x66, 0x96, 0x95, 0x70, 0x80, 0x9d, 0xcc, 0xfe, 0x06, + 0xa6, 0xf8, 0x06, 0x46, 0x43, 0x3e, 0xb8, 0x71, 0x23, 0x88, 0xbe, 0x90, 0x24, 0x8e, 0xb0, 0x0e, + 0xf0, 0xf9, 0x21, 0x00, 0x8f, 0xbe, 0x95, 0x10, 0xb5, 0x3f, 0xba, 0x1c, 0x70, 0x29, 0x38, 0x50, + 0x98, 0x90, 0xbe, 0xc5, 0xc5, 0xcf, 0xcf, 0x1f, 0xb9, 0x0a, 0x52, 0x0b, 0x7a, 0x13, 0xdb, 0xeb, + 0xf7, 0x6c, 0x65, 0x73, 0x93, 0x84, 0xf9, 0x28, 0x06, 0xdf, 0x27, 0x7a, 0x0a, 0x64, 0x67, 0x1b, + 0xd9, 0xb0, 0x56, 0xf5, 0x56, 0xcb, 0xf5, 0x74, 0xd9, 0x97, 0xce, 0x9b, 0xba, 0x42, 0xdd, 0x4f, + 0x6d, 0x0a, 0xe6, 0x58, 0xed, 0x01, 0xfd, 0xe5, 0x24, 0x4c, 0x6f, 0x5c, 0xb1, 0x70, 0x87, 0xe5, + 0x62, 0xd5, 0xa6, 0xd4, 0xae, 0x54, 0xf4, 0xac, 0x90, 0x43, 0x6a, 0x48, 0x85, 0xd1, 0x78, 0xae, + 0x0d, 0x30, 0x47, 0x39, 0x06, 0x72, 0xb9, 0x52, 0x28, 0xd2, 0x8b, 0x37, 0x6b, 0x39, 0xb5, 0x56, + 0x2c, 0xc8, 0x5b, 0xe4, 0xb6, 0xc1, 0xd2, 0x32, 0x4d, 0x7d, 0xa4, 0x58, 0x5b, 0x5f, 0x2d, 0x95, + 0xcb, 0xc5, 0x82, 0xbc, 0x8d, 0xde, 0x27, 0xc1, 0x84, 0x3d, 0xaf, 0x72, 0xd0, 0xa9, 0x70, 0x97, + 0x35, 0x1a, 0xad, 0xe6, 0x15, 0x6f, 0xee, 0xe8, 0x3c, 0x46, 0xc2, 0xe9, 0x3f, 0x09, 0x4f, 0x6f, + 0x08, 0xdb, 0x7c, 0xb4, 0x04, 0x63, 0xb5, 0xa9, 0x37, 0xbb, 0xb1, 0x4a, 0xab, 0x5d, 0xa9, 0x3d, + 0x30, 0x95, 0x7a, 0x62, 0xfa, 0xfb, 0x42, 0x93, 0x9e, 0x3e, 0xc4, 0x45, 0xc3, 0x75, 0x69, 0x58, + 0xb8, 0xa2, 0x6f, 0x48, 0x90, 0x59, 0x6b, 0x13, 0xe4, 0x9e, 0xf3, 0xf9, 0x89, 0xec, 0xdb, 0x2b, + 0xb5, 0x95, 0x54, 0x93, 0xbf, 0x9d, 0x5e, 0xf5, 0x12, 0x94, 0x7b, 0xd8, 0xb6, 0x0f, 0xf5, 0x11, + 0x39, 0x19, 0x7a, 0xea, 0x98, 0x70, 0xc2, 0xb7, 0x6b, 0x7c, 0x1b, 0x5c, 0xd5, 0xd0, 0x3b, 0xda, + 0x46, 0x13, 0x17, 0x5b, 0x75, 0xf3, 0x0a, 0x6d, 0x34, 0x75, 0x18, 0xd9, 0xff, 0x42, 0xb9, 0x1f, + 0xd2, 0x1d, 0xeb, 0x4a, 0x93, 0x4e, 0x9b, 0xfc, 0x9b, 0xcc, 0x81, 0x55, 0x55, 0xed, 0xec, 0x2a, + 0xfd, 0x0a, 0x7d, 0x3b, 0x21, 0xea, 0x60, 0x4b, 0xbe, 0xa5, 0xac, 0x09, 0xf6, 0x16, 0xd9, 0xd6, + 0x3a, 0xae, 0xb7, 0x88, 0xfd, 0x1f, 0x3d, 0x2d, 0xe4, 0x05, 0x1b, 0x5c, 0x76, 0xfc, 0x3a, 0xf5, + 0x73, 0x49, 0x18, 0x2b, 0x18, 0x97, 0x5a, 0x04, 0xf3, 0x3b, 0x39, 0xd7, 0x20, 0xd2, 0x9a, 0x84, + 0xd7, 0x9a, 0x5e, 0xfe, 0x30, 0xe8, 0xdf, 0x09, 0x6f, 0x36, 0x93, 0x56, 0x3a, 0x55, 0x05, 0xdf, + 0xc1, 0x15, 0x2c, 0x56, 0x3e, 0xd3, 0x7f, 0xd8, 0x56, 0x74, 0x58, 0x3d, 0xd1, 0xf8, 0x99, 0x3b, + 0xf0, 0x1d, 0x06, 0xe8, 0x59, 0x09, 0x52, 0x05, 0xd3, 0x68, 0xa3, 0xdf, 0x4a, 0x44, 0xd8, 0x03, + 0x6b, 0x98, 0x46, 0xbb, 0x46, 0x82, 0xd0, 0xb8, 0x53, 0x00, 0x2e, 0x4d, 0x39, 0x0b, 0x63, 0x6d, + 0xa3, 0xa3, 0x5b, 0xce, 0xb4, 0x6a, 0x7a, 0xdf, 0x25, 0xe3, 0x54, 0xf2, 0x57, 0x59, 0x26, 0xd5, + 0xcd, 0x6e, 0xeb, 0x31, 0xc2, 0x51, 0x9b, 0x4d, 0x36, 0x57, 0x9d, 0x60, 0x39, 0x5d, 0xa9, 0xe8, + 0x17, 0xfc, 0xc0, 0xde, 0xcb, 0x03, 0x7b, 0x53, 0x0f, 0x86, 0x9b, 0x41, 0xb7, 0x16, 0x47, 0xb4, + 0x5a, 0xbf, 0xde, 0x05, 0xf9, 0x01, 0x0e, 0xe4, 0x53, 0x42, 0x75, 0xc6, 0xdf, 0x61, 0xbe, 0x96, + 0x05, 0x28, 0x6b, 0x7b, 0xfa, 0x16, 0xb5, 0x99, 0x7c, 0xc6, 0x19, 0xf0, 0x98, 0x75, 0xe3, 0xa7, + 0x7d, 0x38, 0x9f, 0x85, 0x2c, 0x83, 0x95, 0xb5, 0xe1, 0xa5, 0x5c, 0x1b, 0xbc, 0x52, 0xa8, 0x86, + 0xba, 0x6c, 0xa9, 0x4e, 0x7e, 0x2e, 0x2e, 0x56, 0xb2, 0x2b, 0x2e, 0x56, 0xcf, 0xe5, 0x59, 0x50, + 0xb4, 0x2c, 0xf4, 0x7b, 0xc2, 0xa1, 0x25, 0x7c, 0xf4, 0xf8, 0x5a, 0x14, 0x00, 0xea, 0x5d, 0x90, + 0x35, 0x5c, 0x33, 0x8f, 0x14, 0xb8, 0x1e, 0x28, 0xb5, 0x36, 0x0d, 0xd5, 0xc9, 0x29, 0x18, 0x34, + 0x42, 0x88, 0x8e, 0xf8, 0x81, 0xfe, 0x98, 0x04, 0xc7, 0x17, 0x9d, 0x73, 0x93, 0x76, 0x3b, 0x2e, + 0xe8, 0xd6, 0xf6, 0xb2, 0xde, 0xba, 0xd8, 0x41, 0xff, 0x4a, 0x6c, 0x26, 0xef, 0xc3, 0x3f, 0x19, + 0x0d, 0x7f, 0xde, 0x99, 0xb1, 0xca, 0xa3, 0x76, 0x7f, 0x50, 0x29, 0xbd, 0xa9, 0x0d, 0x00, 0xf0, + 0x1e, 0xc8, 0x50, 0x42, 0x59, 0xb7, 0x9c, 0x0d, 0xc4, 0xcf, 0x2d, 0x49, 0x65, 0x5f, 0xf8, 0x7c, + 0x82, 0xce, 0x73, 0x38, 0xce, 0x1f, 0x88, 0xb2, 0xf8, 0x9d, 0x19, 0xef, 0x84, 0x2c, 0xe3, 0xb4, + 0x32, 0xed, 0xef, 0xc5, 0xf2, 0x11, 0x05, 0x20, 0xb3, 0x62, 0xec, 0xe1, 0x9a, 0x21, 0x27, 0xec, + 0xff, 0x36, 0x7d, 0x35, 0x43, 0x4e, 0xa2, 0xff, 0x0a, 0x30, 0xe6, 0xfa, 0x24, 0x7f, 0x2a, 0xe9, + 0x84, 0x3d, 0x27, 0x66, 0x6a, 0xca, 0x0c, 0xe1, 0xdd, 0xf4, 0xd7, 0x09, 0x1b, 0x3e, 0x5d, 0x5f, + 0xe1, 0xee, 0xca, 0x04, 0x23, 0x0a, 0xbf, 0x5d, 0xc8, 0x10, 0x2a, 0x5a, 0x4b, 0xfc, 0x5d, 0xed, + 0x4b, 0x49, 0xe7, 0x72, 0x09, 0x8f, 0x08, 0xb2, 0xff, 0xc7, 0x5f, 0xb4, 0xef, 0x6d, 0x30, 0x30, + 0xe6, 0xfa, 0x52, 0xf8, 0xdb, 0x96, 0x43, 0x77, 0x5e, 0x03, 0xdb, 0x1d, 0x72, 0x36, 0xbb, 0x9b, + 0xc3, 0x62, 0x7b, 0xab, 0x51, 0x6a, 0x8a, 0x9f, 0xcb, 0xbf, 0x4b, 0xef, 0x1f, 0x6b, 0x45, 0x70, + 0x00, 0xe1, 0x62, 0x68, 0x3e, 0xc4, 0x33, 0xf5, 0x54, 0x40, 0x53, 0xed, 0x1a, 0x04, 0xb9, 0xf8, + 0x8c, 0xcb, 0xc5, 0x3c, 0xc7, 0xc5, 0xd3, 0xe2, 0x45, 0xc7, 0xcf, 0xb6, 0xaf, 0x26, 0x61, 0x9c, + 0x3a, 0x5f, 0xe7, 0x9a, 0xcd, 0xae, 0x5b, 0x97, 0xf7, 0x39, 0x9a, 0xfe, 0x07, 0x61, 0xf7, 0x30, + 0xb7, 0x55, 0x6e, 0xd9, 0xb1, 0xdd, 0x9b, 0x28, 0x66, 0xe0, 0xe9, 0x4b, 0xd0, 0x48, 0xe2, 0xc0, + 0x4e, 0xd8, 0x9a, 0x77, 0xd5, 0xc4, 0x7b, 0x3a, 0xbe, 0x84, 0xae, 0x09, 0x59, 0x82, 0xa2, 0xb7, + 0x0a, 0x1f, 0x8e, 0xf4, 0x15, 0x19, 0xc0, 0xe3, 0xfb, 0x60, 0xa2, 0xe9, 0x65, 0x62, 0x23, 0x22, + 0xea, 0x1a, 0x11, 0x7d, 0xc5, 0xa8, 0xfe, 0xec, 0x82, 0xab, 0xbc, 0x60, 0x2a, 0xe2, 0x67, 0xec, + 0x57, 0x32, 0x30, 0xb6, 0xd6, 0xea, 0xb4, 0x9b, 0xf6, 0xa2, 0xf4, 0x1f, 0x25, 0x37, 0x28, 0xec, + 0xcb, 0xb9, 0x38, 0x58, 0x3f, 0xb8, 0x8b, 0x4d, 0x67, 0x4f, 0x89, 0x3e, 0xf4, 0x0e, 0xc9, 0x89, + 0x7e, 0xdf, 0x6f, 0x63, 0xce, 0xf1, 0xac, 0xe7, 0x1d, 0xd4, 0x9d, 0x4a, 0xc3, 0xa3, 0xa5, 0x96, + 0x60, 0xac, 0xad, 0xd7, 0xad, 0x5d, 0xd3, 0x0d, 0x1e, 0x79, 0xbb, 0x58, 0x29, 0xab, 0xf4, 0x2b, + 0xd5, 0xfd, 0x1c, 0x69, 0x90, 0x65, 0x89, 0xfb, 0xcc, 0x81, 0xfb, 0xee, 0x49, 0x20, 0x4e, 0xe5, + 0xa6, 0xa5, 0x77, 0x9c, 0xd8, 0xb3, 0xec, 0xc9, 0x56, 0x8a, 0xf4, 0xdf, 0x9a, 0xd9, 0x64, 0xe6, + 0x67, 0x2f, 0x01, 0xbd, 0xcf, 0x85, 0xbb, 0xc0, 0xc1, 0x7d, 0x47, 0x84, 0x96, 0x47, 0x83, 0xfc, + 0xdc, 0x00, 0x0b, 0xd1, 0xab, 0xe1, 0x45, 0x6a, 0xae, 0x56, 0x5c, 0x5f, 0x2e, 0xad, 0x94, 0x6a, + 0xeb, 0xc5, 0xef, 0xcd, 0x17, 0x8b, 0x85, 0x62, 0x41, 0x6e, 0x90, 0x2b, 0x97, 0xdc, 0x15, 0x3f, + 0x3f, 0x12, 0x30, 0x2e, 0x7a, 0x23, 0x81, 0x9b, 0x80, 0x7e, 0x55, 0xd8, 0x69, 0xda, 0x6d, 0x78, + 0x9f, 0xb5, 0x7e, 0x2f, 0x7b, 0xc9, 0xfb, 0x85, 0xbc, 0x9f, 0xfb, 0xd5, 0x70, 0x88, 0xcc, 0x7d, + 0xd7, 0xf7, 0x41, 0x9a, 0x2c, 0xbd, 0xd1, 0xef, 0x90, 0x88, 0x9f, 0xed, 0xa6, 0x56, 0xc7, 0x68, + 0x27, 0xc2, 0x35, 0x09, 0x1b, 0xf6, 0xd7, 0xde, 0x35, 0x09, 0xec, 0x51, 0x39, 0x05, 0x69, 0xf2, + 0x97, 0x69, 0xfc, 0x63, 0xbd, 0x96, 0xfb, 0x2a, 0xcd, 0xc2, 0x3b, 0x06, 0x86, 0xda, 0x64, 0xa8, + 0x95, 0x80, 0x91, 0x19, 0x80, 0x53, 0x30, 0x4d, 0xd1, 0x46, 0x21, 0xb1, 0xf8, 0xc6, 0x61, 0x14, + 0xc5, 0xaf, 0x27, 0xff, 0x2a, 0x05, 0xe9, 0x6a, 0xbb, 0xa9, 0x5b, 0xe8, 0x97, 0x92, 0x43, 0xc1, + 0xcc, 0xd4, 0x5a, 0x5b, 0x38, 0x00, 0x33, 0xd5, 0x7e, 0xa7, 0xd2, 0x2c, 0x9e, 0x21, 0x33, 0x25, + 0x60, 0xc8, 0xac, 0xe1, 0xcb, 0x16, 0x67, 0xc8, 0x54, 0xce, 0xb2, 0xb3, 0x36, 0xe9, 0x1e, 0xa7, + 0xf2, 0xe8, 0xb7, 0xa4, 0x59, 0x3d, 0x4e, 0xda, 0xcc, 0xde, 0xc9, 0xce, 0xa5, 0x00, 0x64, 0xe6, + 0x2b, 0xb5, 0x5a, 0x65, 0x45, 0x3e, 0xa2, 0x64, 0x41, 0xaa, 0x55, 0x56, 0xe5, 0x84, 0x32, 0x0e, + 0xe9, 0x52, 0xb9, 0x5c, 0x54, 0xe5, 0xa4, 0xfd, 0xb7, 0x56, 0xaa, 0x2d, 0x17, 0x65, 0x09, 0xbd, + 0x4b, 0x78, 0xe8, 0xe5, 0xeb, 0x8e, 0x53, 0xbc, 0xc4, 0x06, 0xe1, 0x60, 0x7a, 0xe2, 0x17, 0xae, + 0x7f, 0x2b, 0x41, 0x7a, 0x05, 0x9b, 0x5b, 0x18, 0xfd, 0x60, 0x04, 0x5b, 0xe0, 0xa6, 0x6e, 0x76, + 0xe8, 0xb9, 0x22, 0xcf, 0x16, 0xe8, 0x4f, 0x53, 0x6e, 0x84, 0xa9, 0x0e, 0xae, 0x1b, 0xad, 0x86, + 0x93, 0x89, 0x45, 0xac, 0xe2, 0x12, 0xd1, 0x53, 0x11, 0x21, 0x23, 0x84, 0x0e, 0xc5, 0xa0, 0x17, + 0x05, 0x98, 0x5e, 0xb5, 0xc6, 0x0f, 0xcc, 0xff, 0x96, 0xec, 0x8f, 0xda, 0x57, 0xd0, 0x53, 0xc2, + 0x46, 0xda, 0xdb, 0x20, 0x43, 0xc4, 0xd4, 0x99, 0xaf, 0xf4, 0xd6, 0xc7, 0x2c, 0x8f, 0x32, 0x0f, + 0x57, 0x75, 0xc8, 0x8d, 0xf0, 0xb8, 0x61, 0x77, 0x5d, 0xb5, 0xaf, 0x52, 0xd8, 0x9f, 0x1d, 0xfd, + 0x85, 0x1f, 0xc0, 0xfb, 0x78, 0x00, 0x4f, 0xf6, 0x60, 0xa5, 0xdd, 0xa0, 0xe0, 0xbb, 0x71, 0xec, + 0x66, 0x54, 0x9b, 0x86, 0x6b, 0x5c, 0x74, 0x9e, 0xed, 0x77, 0xdb, 0xd6, 0x4e, 0x93, 0xbc, 0x63, + 0x2e, 0x2c, 0xce, 0xb3, 0x32, 0x07, 0x59, 0xad, 0x75, 0x85, 0xbc, 0x4a, 0x85, 0xb4, 0xda, 0xc9, + 0x84, 0xde, 0xe0, 0x22, 0xff, 0x20, 0x87, 0xfc, 0xad, 0x62, 0xe4, 0xc6, 0x0f, 0xfc, 0xdf, 0x65, + 0x20, 0xbd, 0xaa, 0x75, 0x2c, 0x8c, 0xbe, 0x20, 0x89, 0x22, 0x7f, 0x12, 0xa6, 0x37, 0x8d, 0xfa, + 0x6e, 0x07, 0x37, 0xf8, 0x4e, 0xd9, 0x95, 0x3a, 0x0c, 0xcc, 0x95, 0x53, 0x20, 0x3b, 0x89, 0xac, + 0x58, 0xc7, 0x5a, 0xbf, 0x2f, 0x9d, 0x1c, 0xa4, 0xee, 0xac, 0x6a, 0xa6, 0x55, 0xd9, 0x24, 0x69, + 0xee, 0x41, 0x6a, 0x7f, 0x22, 0x07, 0x7d, 0x26, 0x04, 0xfa, 0x6c, 0x30, 0xf4, 0x63, 0x02, 0xd0, + 0x2b, 0x39, 0x18, 0xdb, 0xd4, 0x9b, 0x98, 0x7c, 0x30, 0xde, 0x23, 0x04, 0x17, 0xdb, 0x9e, 0xb0, + 0x79, 0xef, 0x8e, 0x49, 0x0b, 0x7a, 0x13, 0xab, 0xee, 0x67, 0x68, 0x99, 0x6e, 0xf6, 0xbb, 0x61, + 0xf8, 0x13, 0xbe, 0x30, 0xfc, 0x0a, 0xa4, 0x1a, 0x9a, 0xa5, 0x11, 0xd6, 0x4f, 0xaa, 0xe4, 0x3f, + 0xbf, 0x77, 0x24, 0x75, 0xef, 0x1d, 0x3d, 0x21, 0x45, 0xd3, 0x7f, 0x0e, 0x69, 0x01, 0xfd, 0x67, + 0xc3, 0x81, 0x83, 0x7a, 0x81, 0xb9, 0xcf, 0x36, 0x0c, 0x75, 0xcd, 0xc4, 0xd6, 0xaa, 0x7f, 0x7b, + 0x26, 0xad, 0xf2, 0x89, 0x64, 0xc7, 0xbb, 0x53, 0xd5, 0x76, 0x30, 0xa9, 0x2c, 0x6f, 0xbf, 0x63, + 0x7b, 0x9c, 0xfb, 0xd2, 0x3d, 0x6d, 0x9b, 0x1e, 0xb6, 0xb6, 0xed, 0xd5, 0xc6, 0xf8, 0x3b, 0xdd, + 0x1b, 0x53, 0x20, 0xe5, 0x77, 0xad, 0x17, 0xb4, 0xb2, 0xfd, 0x27, 0xe1, 0xcd, 0x2f, 0xa6, 0xbd, + 0x76, 0xad, 0xc3, 0xd5, 0xb5, 0x11, 0xa5, 0x44, 0x6c, 0x93, 0x2d, 0xa8, 0x6d, 0x23, 0x39, 0xa0, + 0xe3, 0xf8, 0x21, 0x18, 0x07, 0x9f, 0x87, 0x23, 0xaa, 0x8c, 0x7c, 0x8a, 0xc1, 0x7d, 0x76, 0x8c, + 0x02, 0x29, 0xcf, 0xae, 0xf4, 0xcb, 0xc2, 0x9e, 0x40, 0x94, 0x3f, 0xa1, 0x4e, 0x01, 0xd1, 0xa6, + 0x4a, 0x62, 0x01, 0xea, 0x42, 0xaa, 0x8d, 0x1f, 0x99, 0x6f, 0xf8, 0xad, 0x07, 0xb9, 0x03, 0x63, + 0xc3, 0x9b, 0xed, 0x43, 0x2d, 0xcc, 0xb4, 0xd9, 0x7d, 0x8c, 0x0a, 0xd1, 0xf8, 0x2d, 0x66, 0x7f, + 0x0e, 0xad, 0x78, 0x04, 0x47, 0xa2, 0x24, 0xc8, 0xd0, 0xfd, 0x03, 0xf4, 0x1b, 0xc2, 0x2a, 0xd3, + 0x56, 0x3b, 0xbc, 0x03, 0x81, 0xfb, 0x1c, 0xc5, 0x94, 0xc0, 0x39, 0x1a, 0xa4, 0x22, 0x39, 0x1a, + 0xf0, 0xfe, 0xc2, 0x02, 0xfd, 0x88, 0xb6, 0x31, 0xe6, 0x55, 0x62, 0x94, 0x1e, 0xd6, 0x93, 0xa0, + 0xf8, 0xf1, 0x7e, 0x36, 0x05, 0x93, 0xb4, 0xea, 0x0b, 0x7a, 0x63, 0x0b, 0x5b, 0xe8, 0x1f, 0xbe, + 0x83, 0x50, 0x57, 0xca, 0x30, 0x79, 0x89, 0x90, 0x4d, 0x83, 0xa1, 0x33, 0x83, 0x44, 0xf8, 0x2d, + 0x34, 0xb4, 0x9d, 0x4e, 0xf0, 0x77, 0xee, 0x7b, 0xf4, 0x47, 0xc2, 0x1b, 0x2a, 0x7e, 0xd0, 0x58, + 0x89, 0xf1, 0xca, 0x92, 0xd8, 0xb6, 0x4a, 0x5f, 0xb2, 0x46, 0xe0, 0x81, 0xce, 0x87, 0xe2, 0xcb, + 0x47, 0x10, 0xa7, 0xa0, 0x79, 0x6e, 0x84, 0xd0, 0xfc, 0x94, 0x01, 0x43, 0x8e, 0xd2, 0x27, 0x76, + 0xb4, 0xa4, 0x4f, 0xd5, 0xf1, 0x73, 0xfe, 0x4d, 0xf4, 0xc6, 0x84, 0x05, 0x1d, 0x37, 0x1b, 0x1d, + 0x64, 0x1e, 0x7c, 0x2a, 0x73, 0x1a, 0x32, 0x9b, 0xa4, 0x30, 0x26, 0xa2, 0x81, 0x57, 0x77, 0xb0, + 0x6c, 0xe8, 0x8d, 0x49, 0xd1, 0xad, 0x1a, 0x66, 0x1a, 0x73, 0xa8, 0x1d, 0x0a, 0x4c, 0x6f, 0x12, + 0xda, 0x2a, 0x09, 0xaf, 0x39, 0x7e, 0x94, 0xde, 0x21, 0xc1, 0x24, 0x0b, 0x81, 0x97, 0x6b, 0xea, + 0x5b, 0x2d, 0xff, 0x61, 0xc7, 0x81, 0x7b, 0x88, 0x72, 0x07, 0xa4, 0x35, 0xbb, 0x34, 0xe6, 0xa0, + 0x87, 0x7a, 0xaa, 0x40, 0x52, 0x9f, 0x4a, 0x33, 0x46, 0x88, 0x2d, 0xe2, 0x09, 0xb6, 0x43, 0xf3, + 0x08, 0x63, 0x8b, 0xf4, 0xad, 0x3c, 0x7e, 0xc4, 0xbe, 0x28, 0xc1, 0x31, 0x46, 0xc0, 0x79, 0x6c, + 0x5a, 0x7a, 0x5d, 0x6b, 0x52, 0xe4, 0x5e, 0x9d, 0x18, 0x06, 0x74, 0x4b, 0x30, 0xb5, 0xe7, 0x2f, + 0x96, 0x41, 0x38, 0xdb, 0x13, 0x42, 0x8e, 0x00, 0x95, 0xff, 0x30, 0x42, 0x8c, 0x06, 0x8e, 0xab, + 0x5c, 0x99, 0x23, 0x8c, 0xd1, 0x20, 0x4c, 0x44, 0xfc, 0x10, 0xff, 0x42, 0x8a, 0x86, 0x2d, 0xf1, + 0xd4, 0xe7, 0x67, 0x84, 0xb1, 0x5d, 0x83, 0x09, 0x82, 0x25, 0xfd, 0x90, 0x59, 0x0d, 0x42, 0x84, + 0xd8, 0xd5, 0x3b, 0x2c, 0xec, 0x9b, 0xfb, 0xad, 0xea, 0x2f, 0x07, 0x5d, 0x00, 0xf0, 0x5e, 0xf9, + 0x95, 0x74, 0x22, 0x48, 0x49, 0x27, 0xc5, 0x94, 0xf4, 0x5b, 0x85, 0x8f, 0xd6, 0xf5, 0x26, 0xfb, + 0xe0, 0xe2, 0x21, 0x76, 0xa8, 0xaa, 0x7f, 0xed, 0xf1, 0xcb, 0xc5, 0x1b, 0x52, 0xdd, 0x41, 0x9a, + 0x3f, 0x38, 0x94, 0xf9, 0xb1, 0x5f, 0x1f, 0x48, 0x5d, 0xfa, 0xe0, 0x00, 0xf3, 0xe1, 0x5b, 0xe0, + 0x28, 0xad, 0x22, 0xef, 0x92, 0x45, 0xef, 0xfe, 0xec, 0x4e, 0x46, 0x1f, 0x1a, 0x40, 0x08, 0xfa, + 0x45, 0x90, 0x0e, 0x53, 0x72, 0xd1, 0x26, 0xbb, 0x51, 0x05, 0xe4, 0xf0, 0x02, 0x4f, 0x7f, 0x35, + 0x45, 0x67, 0xbb, 0x6b, 0x24, 0xa2, 0x21, 0xfa, 0xcb, 0xd4, 0x30, 0x46, 0x84, 0x87, 0x20, 0x65, + 0x39, 0x77, 0x14, 0xf7, 0x36, 0x4c, 0x78, 0x55, 0x7a, 0xb1, 0x10, 0xf1, 0x65, 0x6b, 0xe9, 0x88, + 0x4a, 0xbe, 0x54, 0x4e, 0xc1, 0xd1, 0x0d, 0xad, 0x7e, 0x71, 0xcb, 0x34, 0x76, 0x5b, 0x8d, 0xbc, + 0xd1, 0x34, 0x4c, 0x6a, 0x74, 0x22, 0x41, 0x25, 0xf9, 0x17, 0xca, 0x19, 0x67, 0xea, 0x90, 0xee, + 0x37, 0x75, 0x58, 0x3a, 0xc2, 0x26, 0x0f, 0xca, 0x9d, 0xae, 0xd2, 0xc9, 0x84, 0x2a, 0x9d, 0xa5, + 0x23, 0x8e, 0xda, 0x51, 0x0a, 0x30, 0xd6, 0xd0, 0xf7, 0xc8, 0x3e, 0x32, 0x0b, 0xd2, 0x18, 0x7e, + 0x54, 0xa7, 0xa0, 0xef, 0xd1, 0x5d, 0xe7, 0xa5, 0x23, 0xaa, 0xfb, 0xa5, 0xb2, 0x08, 0xe3, 0xc4, + 0x66, 0x4f, 0x8a, 0x19, 0x8b, 0x74, 0x0c, 0x67, 0xe9, 0x88, 0xea, 0x7d, 0x6b, 0xcf, 0x3e, 0x52, + 0xc4, 0xc1, 0xfd, 0x41, 0x67, 0x2f, 0x3c, 0x11, 0x69, 0x2f, 0xdc, 0xe6, 0x05, 0xdd, 0x0d, 0x3f, + 0x0e, 0xe9, 0x3a, 0xe1, 0x70, 0x92, 0x71, 0x98, 0x3e, 0x2a, 0xf7, 0x41, 0x6a, 0x47, 0x33, 0x9d, + 0x25, 0xf0, 0xc9, 0xfe, 0xe5, 0xae, 0x68, 0xe6, 0x45, 0x1b, 0x41, 0xfb, 0xab, 0xf9, 0x2c, 0xa4, + 0x09, 0xe3, 0xdc, 0x3f, 0xe8, 0x59, 0x36, 0x0d, 0xc9, 0x1b, 0x2d, 0x7b, 0xd8, 0xaf, 0x19, 0xce, + 0x29, 0x80, 0xfa, 0x30, 0x64, 0x8e, 0xf7, 0x78, 0x95, 0xf6, 0x79, 0xbc, 0xfe, 0xc5, 0x00, 0x73, + 0x8b, 0x6e, 0x4a, 0x83, 0x97, 0xc8, 0x4d, 0xee, 0x3e, 0x7f, 0xe7, 0x31, 0xa2, 0xd6, 0x88, 0x3a, + 0xeb, 0xe8, 0x43, 0x5e, 0xfc, 0xca, 0xe3, 0x6d, 0x29, 0x98, 0xb1, 0x09, 0xa1, 0xbe, 0xe0, 0x7c, + 0x38, 0x54, 0xf4, 0x67, 0x43, 0x99, 0x5c, 0xf6, 0x18, 0x11, 0xa4, 0x9e, 0x23, 0xc2, 0xbe, 0x93, + 0x40, 0xa9, 0x3e, 0x27, 0x81, 0xd2, 0xd1, 0x0c, 0x74, 0x7f, 0xe8, 0x97, 0x9f, 0x55, 0x5e, 0x7e, + 0xee, 0x09, 0x00, 0xa8, 0x17, 0x5f, 0x86, 0x32, 0x01, 0xf9, 0x1d, 0x57, 0x52, 0xaa, 0x9c, 0xa4, + 0x3c, 0x38, 0x38, 0x21, 0xf1, 0x4b, 0xcb, 0x1f, 0xa4, 0xe0, 0x45, 0x1e, 0x31, 0x65, 0x7c, 0x89, + 0x09, 0xca, 0xa7, 0x86, 0x22, 0x28, 0x77, 0x7a, 0xb7, 0x18, 0xf5, 0x59, 0xec, 0x3b, 0xf9, 0xe2, + 0x96, 0x98, 0x3f, 0x17, 0x3e, 0xc1, 0xd0, 0x0d, 0x94, 0xcb, 0x9b, 0x00, 0x61, 0x39, 0x0e, 0x19, + 0xaa, 0x61, 0x9c, 0x3b, 0xd8, 0xe9, 0x53, 0x44, 0x75, 0x23, 0x76, 0xee, 0x41, 0x94, 0xb6, 0x11, + 0xc8, 0x0f, 0x33, 0x3c, 0xd4, 0x76, 0xcd, 0x56, 0xa9, 0x65, 0x19, 0xe8, 0x47, 0x86, 0x22, 0x38, + 0xae, 0x2f, 0x99, 0x34, 0x88, 0x2f, 0xd9, 0x40, 0x66, 0x08, 0xa7, 0x05, 0x87, 0x62, 0x86, 0x08, + 0xa8, 0x3c, 0x7e, 0xfc, 0xde, 0x29, 0xc1, 0x71, 0xb6, 0x1a, 0x9a, 0xe7, 0xa7, 0x70, 0xe8, 0x91, + 0x61, 0x00, 0x79, 0xcc, 0x99, 0xc7, 0xb0, 0xab, 0x97, 0xc9, 0x03, 0x7f, 0xc6, 0x20, 0x34, 0x2a, + 0x27, 0xb7, 0x5e, 0xeb, 0xa2, 0x70, 0x28, 0x48, 0x89, 0x05, 0xe3, 0x8c, 0x40, 0x46, 0xfc, 0x98, + 0xfd, 0xac, 0x04, 0x19, 0x76, 0x15, 0xc2, 0x5a, 0x2c, 0x0e, 0x08, 0x7c, 0x04, 0x26, 0x81, 0x8d, + 0xaf, 0xc8, 0x77, 0x10, 0xc4, 0xb7, 0xe5, 0x75, 0x38, 0x97, 0x0c, 0xa0, 0xa7, 0x24, 0x66, 0x59, + 0x59, 0xd6, 0x2c, 0x7c, 0x19, 0xfd, 0xa4, 0x04, 0xd9, 0x2a, 0xb6, 0x6c, 0xcd, 0x24, 0x8e, 0x51, + 0xb0, 0xcd, 0x5c, 0xf1, 0xad, 0xdd, 0xc6, 0xe9, 0x6a, 0x2c, 0xaa, 0x8e, 0x23, 0x74, 0xcd, 0x31, + 0x9a, 0x46, 0xad, 0xe3, 0xc2, 0x2a, 0x1f, 0xc1, 0x79, 0xe7, 0x1b, 0x61, 0x9c, 0x90, 0x41, 0xe0, + 0xf8, 0xb0, 0x0f, 0x9a, 0x9f, 0x4f, 0xc4, 0x82, 0x8d, 0x3d, 0x7c, 0x91, 0x40, 0xfd, 0x64, 0xf6, + 0x32, 0x21, 0x32, 0x7c, 0xd9, 0xcb, 0xb4, 0x8e, 0x4a, 0xbf, 0x8a, 0x70, 0x81, 0x94, 0xdb, 0xac, + 0xa1, 0x22, 0x2b, 0x76, 0xb3, 0x47, 0xbf, 0xba, 0x47, 0x70, 0x2f, 0x8c, 0x04, 0x63, 0x55, 0x7b, + 0xb9, 0x61, 0x8f, 0x29, 0x17, 0x0e, 0x0e, 0x65, 0xef, 0xc1, 0x2a, 0x62, 0x47, 0x73, 0x38, 0x32, + 0xbc, 0x21, 0x2a, 0x42, 0x47, 0x0b, 0xab, 0x3c, 0x7e, 0x3c, 0xde, 0x45, 0xf1, 0x20, 0xb2, 0x8c, + 0xde, 0x22, 0x81, 0xb4, 0x88, 0xad, 0x21, 0x9d, 0x1c, 0x11, 0x3d, 0x85, 0xc0, 0x0f, 0x5d, 0xa1, + 0xc1, 0x02, 0x38, 0x86, 0x11, 0x9a, 0xe7, 0x16, 0xf1, 0x70, 0x3a, 0x90, 0x58, 0x94, 0x00, 0x21, + 0x02, 0xe2, 0x47, 0xed, 0x3d, 0x14, 0x35, 0x6a, 0xc1, 0xfa, 0xe1, 0x21, 0x68, 0xc4, 0xd1, 0x4e, + 0xde, 0x1d, 0x06, 0x92, 0x32, 0x0e, 0xab, 0xbf, 0xf5, 0xaa, 0x7c, 0x24, 0x3e, 0x86, 0x60, 0x77, + 0xf6, 0x6d, 0x5c, 0xbf, 0x88, 0x1b, 0xe8, 0xfb, 0x0f, 0x0e, 0xdd, 0x0c, 0x64, 0xeb, 0xb4, 0x34, + 0x02, 0xde, 0x98, 0xea, 0x3c, 0x46, 0xb8, 0xbe, 0x9d, 0x57, 0x44, 0xf4, 0xf3, 0x11, 0x5e, 0xdf, + 0x2e, 0x50, 0x7d, 0xfc, 0xc8, 0xfc, 0x36, 0x9d, 0x64, 0x94, 0xea, 0x46, 0x0b, 0xfd, 0xeb, 0x83, + 0xc3, 0x72, 0x2d, 0x8c, 0xeb, 0x75, 0xa3, 0x55, 0xda, 0xd1, 0xb6, 0x1c, 0x33, 0xaa, 0x97, 0xe0, + 0xbc, 0x2d, 0xee, 0x18, 0x8f, 0xea, 0x6c, 0x6b, 0xc6, 0x4b, 0x18, 0x74, 0x32, 0x61, 0x93, 0x7e, + 0x58, 0x93, 0x89, 0x1e, 0x75, 0xc7, 0x0f, 0xd9, 0x87, 0x3c, 0x17, 0x0a, 0xaa, 0x0a, 0x5f, 0x10, + 0x96, 0x8c, 0x41, 0x86, 0x33, 0x7f, 0x2b, 0x0e, 0x65, 0x38, 0x0b, 0x21, 0x20, 0x7e, 0x1c, 0x7f, + 0xd9, 0xc3, 0x31, 0x76, 0x3b, 0xc6, 0x01, 0xd0, 0x19, 0xde, 0xf4, 0x70, 0x40, 0x74, 0x0e, 0x67, + 0x8a, 0xf8, 0x7e, 0x16, 0x6c, 0x8a, 0xcd, 0x78, 0xd0, 0x0f, 0x0d, 0x03, 0x9c, 0x7b, 0x06, 0xd9, + 0x14, 0xa3, 0x5b, 0x62, 0x11, 0xee, 0xe2, 0xd9, 0xc7, 0x41, 0xbb, 0x94, 0xa1, 0x20, 0x28, 0x76, + 0x17, 0x8f, 0x48, 0xfd, 0xf1, 0x03, 0xf8, 0x53, 0x12, 0x4c, 0x93, 0x7d, 0xae, 0x26, 0xd6, 0x4c, + 0xaa, 0x28, 0x87, 0xe2, 0x8d, 0xf9, 0x2e, 0xe1, 0x30, 0xf9, 0x3c, 0x1f, 0x3c, 0x3a, 0x86, 0x02, + 0x85, 0xd8, 0xa5, 0xb3, 0x82, 0x24, 0x8c, 0xc4, 0x14, 0x28, 0xbb, 0x24, 0x30, 0x11, 0x1f, 0x0e, + 0x1e, 0x11, 0xdd, 0xbe, 0x78, 0x66, 0x38, 0x9d, 0x6d, 0xc4, 0x6e, 0x5f, 0x22, 0x44, 0x8c, 0x20, + 0x18, 0xfb, 0x1d, 0xcc, 0x14, 0x58, 0x23, 0x57, 0x55, 0x3d, 0x9d, 0x72, 0x0f, 0x3f, 0x7c, 0x7c, + 0x28, 0x6e, 0x3e, 0x07, 0x88, 0x9c, 0xa8, 0x40, 0xca, 0x34, 0x2e, 0x51, 0xb3, 0xd4, 0x94, 0x4a, + 0xfe, 0x93, 0x29, 0xbf, 0xd1, 0xdc, 0xdd, 0x69, 0xd1, 0x8b, 0x34, 0xa7, 0x54, 0xe7, 0x51, 0xb9, + 0x11, 0xa6, 0x2e, 0xe9, 0xd6, 0xf6, 0x12, 0xd6, 0x1a, 0xd8, 0x54, 0x8d, 0x4b, 0xec, 0xce, 0x5a, + 0x3e, 0x91, 0xdf, 0x83, 0x15, 0x98, 0x5f, 0x92, 0xfb, 0xab, 0x46, 0x72, 0x52, 0x22, 0xca, 0xcc, + 0x33, 0x98, 0xaa, 0xf8, 0x05, 0xe6, 0xbd, 0x12, 0x8c, 0xab, 0xc6, 0x25, 0x26, 0x24, 0xff, 0xe6, + 0x70, 0x65, 0x24, 0xf2, 0x42, 0x8f, 0xde, 0x47, 0xe6, 0x90, 0x3f, 0xf2, 0x85, 0x5e, 0x68, 0xf5, + 0x23, 0x71, 0x8f, 0x9f, 0x54, 0x8d, 0x4b, 0x55, 0x6c, 0xd1, 0x1e, 0x81, 0xd6, 0x87, 0xe4, 0xc9, + 0xa7, 0x77, 0x68, 0x81, 0x6c, 0x1d, 0xee, 0x3e, 0xa3, 0x77, 0x0a, 0x5f, 0xf3, 0xc4, 0x33, 0xc8, + 0x25, 0x71, 0x28, 0x10, 0xbd, 0x4d, 0xe8, 0x76, 0x27, 0x31, 0x0a, 0xe2, 0x47, 0xe9, 0xc7, 0x24, + 0x98, 0x50, 0x8d, 0x4b, 0xf6, 0xd0, 0xb0, 0xa0, 0x37, 0x9b, 0xc3, 0x19, 0x21, 0xa3, 0x4e, 0xfe, + 0x1d, 0x36, 0x38, 0x54, 0x8c, 0x7c, 0xf2, 0xdf, 0x87, 0x80, 0xf8, 0x61, 0x78, 0x82, 0x76, 0x16, + 0x67, 0x84, 0x6e, 0x0d, 0x07, 0x87, 0x41, 0x3b, 0x84, 0x4b, 0xc6, 0xa1, 0x75, 0x88, 0x20, 0x0a, + 0x46, 0xb2, 0x73, 0x32, 0x9d, 0x27, 0xc3, 0xfc, 0x70, 0xfb, 0xc4, 0xbb, 0xa3, 0xb9, 0xd7, 0xb0, + 0x61, 0x97, 0x23, 0x64, 0x28, 0x68, 0x44, 0x70, 0xa3, 0x11, 0xa0, 0x21, 0x7e, 0x3c, 0xfe, 0x58, + 0x82, 0x49, 0x4a, 0xc2, 0x0b, 0x64, 0x16, 0x30, 0x50, 0xa7, 0xf2, 0xb7, 0xe0, 0x70, 0x3a, 0x55, + 0x08, 0x05, 0xf1, 0x83, 0xf8, 0x7f, 0x93, 0x64, 0x1e, 0x37, 0xc0, 0x19, 0xc5, 0x20, 0x04, 0x07, + 0x9e, 0x8c, 0x0d, 0xf1, 0x9c, 0xe2, 0x20, 0x93, 0xb1, 0x43, 0x3a, 0xab, 0xf8, 0x84, 0xdb, 0x8b, + 0x86, 0x89, 0xc1, 0x01, 0xba, 0xc2, 0x10, 0x61, 0x18, 0xb0, 0x2b, 0x1c, 0x12, 0x12, 0x7f, 0x23, + 0x01, 0x50, 0x02, 0x56, 0x8c, 0x3d, 0x8c, 0x9e, 0x19, 0xca, 0xc2, 0xb7, 0xdb, 0x35, 0x54, 0xea, + 0xe3, 0x1a, 0x1a, 0xf1, 0xb4, 0x7f, 0x54, 0x4b, 0xa0, 0x8f, 0xcb, 0x2b, 0x81, 0xd7, 0x6c, 0xc6, + 0x68, 0x09, 0x0c, 0xaf, 0x3f, 0x7e, 0x8c, 0x3f, 0x4f, 0x67, 0x73, 0xde, 0x29, 0xa6, 0x5f, 0x1c, + 0x0a, 0xca, 0xbe, 0xd5, 0xbf, 0xc4, 0xaf, 0xfe, 0x0f, 0x80, 0xed, 0xa0, 0x73, 0xc4, 0x7e, 0xa7, + 0x93, 0xe2, 0x9f, 0x23, 0x1e, 0xde, 0x29, 0xa4, 0x1f, 0x4e, 0xc1, 0x51, 0xa6, 0x44, 0xbe, 0x13, + 0x20, 0x8e, 0x78, 0x96, 0x84, 0x53, 0x92, 0x7d, 0x50, 0x1e, 0x96, 0x41, 0x2a, 0x8a, 0x29, 0x53, + 0x80, 0xbc, 0x91, 0x58, 0x37, 0x32, 0xc5, 0xcb, 0x6d, 0xad, 0xd5, 0x10, 0x0f, 0xf8, 0xd8, 0x07, + 0x78, 0xc7, 0xd6, 0x28, 0xf1, 0xb6, 0xc6, 0x1e, 0x96, 0xc9, 0xc8, 0x3b, 0xd7, 0x84, 0x65, 0x94, + 0xdc, 0x91, 0xef, 0x5c, 0x07, 0xd7, 0x1d, 0x3f, 0x4a, 0xef, 0x96, 0x20, 0x55, 0x35, 0x4c, 0x0b, + 0x3d, 0x19, 0xa5, 0x77, 0x52, 0xce, 0x7b, 0x20, 0x39, 0xcf, 0x4a, 0x9e, 0xbb, 0xfa, 0xea, 0x74, + 0xf8, 0x79, 0x3a, 0xcd, 0xd2, 0x48, 0x38, 0x70, 0xbb, 0x7e, 0xdf, 0x1d, 0x58, 0x51, 0x83, 0x36, + 0x50, 0xfe, 0x55, 0x83, 0x9d, 0x88, 0x63, 0x0b, 0xda, 0x10, 0x58, 0xf3, 0x08, 0xec, 0xbe, 0x13, + 0xcc, 0x2f, 0x95, 0xdc, 0x08, 0xf8, 0x24, 0x75, 0x19, 0x29, 0x6b, 0x3b, 0x78, 0x48, 0x2e, 0xc3, + 0x24, 0xe6, 0xa0, 0xe4, 0xc5, 0x1c, 0x8c, 0xda, 0xa1, 0xe8, 0x29, 0x47, 0x4a, 0xd2, 0xa8, 0x3b, + 0x54, 0x48, 0xdd, 0xf1, 0x03, 0xf3, 0x59, 0x7b, 0xe4, 0x23, 0x6b, 0xc8, 0x5c, 0xab, 0xc1, 0x82, + 0xb8, 0xfd, 0xdd, 0x61, 0xef, 0xdd, 0xec, 0x0b, 0xf3, 0xc6, 0x87, 0x8b, 0x4c, 0x77, 0xdf, 0x60, + 0x37, 0x4f, 0x43, 0xc6, 0x91, 0x93, 0x97, 0x99, 0x48, 0xb7, 0xd8, 0xb9, 0xdf, 0xa1, 0x67, 0xa3, + 0x99, 0x73, 0x48, 0x11, 0x5d, 0x8c, 0x8b, 0x79, 0x48, 0x8d, 0x60, 0xe8, 0x11, 0xa0, 0xee, 0x9f, + 0x87, 0x97, 0xd1, 0xfe, 0x4b, 0x04, 0x23, 0x9a, 0xb2, 0xdd, 0xab, 0x1f, 0x0f, 0xcb, 0xcb, 0xa8, + 0x1f, 0x01, 0x23, 0x08, 0x71, 0x96, 0x66, 0x9b, 0xbc, 0xc4, 0x05, 0x0f, 0x7d, 0x2e, 0x19, 0xbb, + 0xf2, 0x16, 0xbf, 0x36, 0xd7, 0xa3, 0x2b, 0x5c, 0x7b, 0x47, 0x71, 0x74, 0x0d, 0x2b, 0x6e, 0x04, + 0xe6, 0x84, 0x24, 0x71, 0x51, 0xbe, 0xa0, 0x37, 0xac, 0xed, 0x21, 0x39, 0xfa, 0x5f, 0xb2, 0xcb, + 0x72, 0xee, 0x9f, 0x23, 0x0f, 0xe8, 0xf9, 0x44, 0xa4, 0xf0, 0x15, 0x2e, 0x4b, 0x08, 0x59, 0x01, + 0x2c, 0x8e, 0x10, 0x74, 0x22, 0xb4, 0xbc, 0x11, 0x4a, 0xf4, 0x79, 0xbd, 0x81, 0x8d, 0x17, 0xa0, + 0x44, 0x13, 0xba, 0x86, 0x27, 0xd1, 0x61, 0xc5, 0xfd, 0x33, 0x95, 0x68, 0x97, 0x25, 0x43, 0x92, + 0xe8, 0xd0, 0xf2, 0x46, 0x10, 0x1b, 0x1d, 0xd8, 0xfc, 0x7a, 0x59, 0x6f, 0x5d, 0x44, 0x1f, 0x49, + 0x3b, 0x37, 0xdf, 0x5d, 0xd0, 0xad, 0x6d, 0x76, 0xcc, 0xfd, 0x43, 0xc2, 0x77, 0x64, 0x0c, 0x70, + 0x94, 0xfd, 0x04, 0x80, 0xc5, 0x6e, 0xa4, 0x72, 0x63, 0xe6, 0xf8, 0x52, 0x94, 0x1c, 0x4c, 0xe9, + 0x2d, 0x0b, 0x9b, 0x2d, 0xad, 0xb9, 0xd0, 0xd4, 0xb6, 0x3a, 0x33, 0x59, 0x72, 0x34, 0xf3, 0x9a, + 0xae, 0xc1, 0xbb, 0xe4, 0xcb, 0xa3, 0xf2, 0x5f, 0x08, 0xcf, 0x35, 0x23, 0x86, 0xfc, 0x39, 0x2d, + 0x18, 0x89, 0xc5, 0x0d, 0xff, 0xf4, 0xf5, 0x68, 0xc6, 0x17, 0x1b, 0x90, 0xb9, 0x6e, 0x30, 0x22, + 0xcf, 0x14, 0xfd, 0x8d, 0x97, 0xba, 0x1a, 0xef, 0x4e, 0x3d, 0x52, 0x43, 0x36, 0xcc, 0x88, 0x90, + 0x3e, 0x82, 0x93, 0x1f, 0x69, 0xb8, 0xca, 0x09, 0x5f, 0xd7, 0x6e, 0x63, 0xcd, 0xd4, 0x5a, 0x75, + 0x1c, 0x41, 0x9a, 0xc3, 0xe6, 0x92, 0x0b, 0x30, 0xa6, 0xd7, 0x8d, 0x56, 0x55, 0x7f, 0x95, 0x73, + 0x95, 0x4b, 0x78, 0xec, 0x53, 0xc2, 0x91, 0x12, 0xfb, 0x42, 0x75, 0xbf, 0x55, 0x4a, 0x30, 0x5e, + 0xd7, 0xcc, 0x46, 0xd5, 0x77, 0xb9, 0xf5, 0xad, 0xfd, 0x0b, 0xca, 0x3b, 0x9f, 0xa8, 0xde, 0xd7, + 0x4a, 0x85, 0x67, 0x62, 0xa6, 0xeb, 0xf4, 0x6f, 0x60, 0x61, 0x05, 0xef, 0x23, 0x8e, 0xe7, 0x36, + 0x77, 0x4c, 0xdc, 0x24, 0x37, 0x67, 0xd2, 0x6e, 0x37, 0xae, 0x7a, 0x09, 0xe8, 0xbd, 0x7e, 0x69, + 0x5e, 0xe1, 0xa5, 0xf9, 0x95, 0x01, 0x22, 0xb1, 0x0f, 0x8d, 0xa1, 0xcc, 0x89, 0xdf, 0xe1, 0x0a, + 0xe6, 0x2a, 0x27, 0x98, 0xf7, 0x0d, 0x48, 0x45, 0xfc, 0x92, 0xf9, 0x3b, 0x19, 0x98, 0xa2, 0x87, + 0xc9, 0x19, 0x3b, 0xd1, 0x4f, 0x91, 0xcb, 0xda, 0xac, 0x73, 0xf8, 0x0a, 0xaa, 0x1e, 0x7c, 0xa0, + 0x93, 0x41, 0xba, 0x88, 0xaf, 0xb0, 0xfe, 0x6e, 0xff, 0x8d, 0xba, 0x47, 0xea, 0xd0, 0x35, 0x47, + 0x69, 0x1a, 0xf5, 0x1e, 0x69, 0x78, 0xf5, 0xf1, 0xe3, 0xf3, 0x5a, 0x09, 0xa4, 0x5c, 0xa3, 0x21, + 0x1e, 0xdf, 0x29, 0x18, 0x8a, 0xeb, 0x61, 0xc2, 0xe9, 0x33, 0xe7, 0x5c, 0x48, 0xfc, 0x49, 0x51, + 0x0d, 0x4e, 0x2e, 0x6f, 0x72, 0x8d, 0x91, 0x5b, 0x70, 0x43, 0xea, 0x8e, 0x1f, 0x94, 0x5f, 0xcc, + 0xb2, 0x4e, 0x33, 0x6f, 0x18, 0x17, 0xc9, 0xb1, 0x84, 0x27, 0x25, 0x48, 0x2f, 0x60, 0xab, 0xbe, + 0x3d, 0xa4, 0x3e, 0xb3, 0x6b, 0x36, 0x9d, 0x3e, 0xb3, 0xef, 0xe6, 0xc9, 0xfe, 0x13, 0x43, 0x87, + 0xac, 0x39, 0x42, 0xd2, 0xa8, 0xc3, 0x35, 0x86, 0xd6, 0x1e, 0x3f, 0x38, 0xcf, 0x4b, 0x30, 0xed, + 0x9a, 0x8d, 0x28, 0x26, 0x3f, 0xf3, 0x82, 0x33, 0x06, 0xa2, 0x4f, 0x45, 0x0b, 0xa9, 0xe2, 0xf2, + 0x94, 0x6f, 0x59, 0xcc, 0xd6, 0xba, 0x08, 0xc1, 0x56, 0xc4, 0x08, 0x1c, 0xc1, 0xb2, 0x58, 0x82, + 0x31, 0x42, 0x50, 0x41, 0xdf, 0x23, 0x6e, 0x5a, 0x9c, 0xf5, 0xee, 0xb1, 0xa1, 0x58, 0xef, 0xee, + 0xe3, 0xad, 0x77, 0x82, 0x21, 0x0c, 0x1d, 0xe3, 0x5d, 0x44, 0xbf, 0x05, 0xfb, 0xfb, 0xa1, 0xdb, + 0xee, 0x22, 0xf8, 0x2d, 0xf4, 0xa9, 0x7f, 0x04, 0x57, 0xf4, 0x9e, 0x62, 0xca, 0xd6, 0xd9, 0xbc, + 0x42, 0x8f, 0x29, 0x90, 0x3a, 0x6f, 0xff, 0xf9, 0x9c, 0x77, 0x51, 0xc5, 0x63, 0x43, 0x38, 0x08, + 0xff, 0x00, 0xa4, 0xc8, 0x65, 0xbc, 0xa9, 0xae, 0x90, 0x9b, 0xa1, 0x3b, 0x69, 0x36, 0x21, 0x2a, + 0xf9, 0x2e, 0x6a, 0xb0, 0x32, 0xae, 0x88, 0xb9, 0xe1, 0xb9, 0xe1, 0x29, 0xc7, 0x21, 0x63, 0x97, + 0xeb, 0x2e, 0xb3, 0xd8, 0x53, 0x14, 0xe3, 0xbb, 0x00, 0x6d, 0xf1, 0x23, 0xff, 0x39, 0x72, 0x27, + 0x0f, 0x89, 0xa9, 0xfa, 0xd4, 0x10, 0xe0, 0x0d, 0x60, 0xcb, 0x81, 0x61, 0x7f, 0xf7, 0x41, 0x60, + 0x77, 0x03, 0xb8, 0x8e, 0xd4, 0x89, 0x56, 0x80, 0x86, 0x91, 0x9c, 0xfc, 0xcd, 0x30, 0xc7, 0xbf, + 0x47, 0x86, 0x89, 0x6e, 0x8a, 0x13, 0xfa, 0x03, 0xa1, 0x33, 0x44, 0x87, 0xc0, 0x81, 0xd1, 0x39, + 0x24, 0x97, 0xc0, 0x3f, 0x91, 0x60, 0xa2, 0xea, 0x5d, 0x20, 0x27, 0x7e, 0x43, 0x41, 0x64, 0x88, + 0xec, 0xb1, 0x96, 0x8b, 0x0f, 0x39, 0x35, 0x78, 0xc8, 0x50, 0x9e, 0x75, 0x3e, 0xfa, 0x47, 0x1d, + 0x32, 0x54, 0x94, 0x90, 0xf8, 0x81, 0xfc, 0x04, 0xbd, 0x11, 0x24, 0x57, 0xb7, 0xf4, 0x3d, 0x8c, + 0x9e, 0x88, 0x51, 0x91, 0x1e, 0x87, 0x8c, 0xb1, 0xb9, 0xd9, 0x61, 0x37, 0x0b, 0x4e, 0xa9, 0xec, + 0xc9, 0xbb, 0xd2, 0x9d, 0x82, 0xcb, 0xae, 0x74, 0x8f, 0x18, 0x54, 0x70, 0x1f, 0x43, 0x69, 0x83, + 0x46, 0x1d, 0x54, 0x50, 0x8c, 0x8c, 0x11, 0x84, 0x0d, 0x06, 0x9b, 0x7b, 0xcc, 0x64, 0xf3, 0x16, + 0x66, 0x24, 0xc0, 0x07, 0xc7, 0x76, 0x16, 0x26, 0x7d, 0x16, 0x01, 0x27, 0x30, 0x3d, 0x97, 0x16, + 0xf5, 0xac, 0xb1, 0xcb, 0xb2, 0xa1, 0xdb, 0x0b, 0x22, 0xd8, 0x81, 0x45, 0x88, 0x18, 0xc9, 0xbd, + 0x2f, 0xce, 0x90, 0x37, 0x22, 0xac, 0xfe, 0xc0, 0x8f, 0x55, 0x85, 0xc7, 0xea, 0xac, 0x08, 0x9b, + 0xc4, 0x86, 0x40, 0xa1, 0xe5, 0xe4, 0x3b, 0x5d, 0xb8, 0x54, 0x0e, 0xae, 0x07, 0x06, 0xa6, 0x23, + 0x7e, 0xc4, 0x3e, 0x20, 0xd1, 0xcb, 0x1f, 0x72, 0x7b, 0x9a, 0xde, 0x24, 0x07, 0xc4, 0x87, 0x70, + 0x05, 0xe1, 0x7f, 0xf7, 0x83, 0x72, 0x9e, 0x07, 0xe5, 0x21, 0x11, 0x66, 0x70, 0x14, 0x05, 0x60, + 0xf3, 0x72, 0xbf, 0xcd, 0x9c, 0x46, 0x11, 0xbd, 0xba, 0x3b, 0x12, 0x1b, 0x7b, 0xef, 0x37, 0xa6, + 0x7f, 0xdc, 0x05, 0xe9, 0x11, 0x0e, 0xa4, 0xe2, 0x41, 0xe9, 0x8a, 0x86, 0xd5, 0x72, 0x74, 0xac, + 0x94, 0x19, 0x38, 0x56, 0xae, 0xd4, 0xd6, 0x73, 0xeb, 0x85, 0x5c, 0x2d, 0x77, 0xbe, 0x54, 0xbc, + 0xb0, 0x3e, 0xbf, 0x5c, 0xc9, 0x9f, 0x93, 0x25, 0xf4, 0x4b, 0x74, 0x0c, 0xac, 0x1a, 0xbb, 0x66, + 0x7d, 0x58, 0xb3, 0xcd, 0x0e, 0x29, 0x8c, 0x75, 0x3a, 0xf6, 0x14, 0xd5, 0x71, 0xdd, 0xf3, 0xc7, + 0x74, 0x88, 0xeb, 0xd7, 0xd1, 0x52, 0x43, 0x76, 0x5c, 0xef, 0x4b, 0x41, 0xfc, 0x5d, 0xec, 0x9b, + 0x12, 0xc0, 0xa2, 0x69, 0xec, 0xb6, 0x2b, 0x66, 0x03, 0x9b, 0xe8, 0x39, 0x6f, 0xd5, 0xf7, 0x73, + 0x43, 0x98, 0xac, 0xac, 0x02, 0x6c, 0xb9, 0x85, 0x33, 0x3d, 0x75, 0x87, 0xd8, 0x1a, 0xcf, 0x23, + 0x4a, 0xf5, 0x95, 0xc1, 0x5f, 0x10, 0xf8, 0x3d, 0x3c, 0xc6, 0x61, 0x23, 0x8f, 0x57, 0xdc, 0x30, + 0x57, 0x7d, 0xef, 0x72, 0xb1, 0xae, 0x71, 0x58, 0x3f, 0x74, 0x00, 0x4a, 0xe2, 0xc7, 0xfc, 0x5b, + 0x12, 0x4c, 0xd0, 0xbd, 0x58, 0xca, 0xd3, 0xbf, 0xf5, 0x40, 0xff, 0xc5, 0x21, 0x80, 0xbe, 0x06, + 0x93, 0x86, 0x57, 0x3a, 0x1d, 0x19, 0xfd, 0xd6, 0xb5, 0x50, 0xd8, 0x7d, 0x74, 0xa9, 0x5c, 0x31, + 0xe8, 0x03, 0x7e, 0xe4, 0x55, 0x1e, 0xf9, 0xfb, 0x42, 0xf8, 0xed, 0x2b, 0x71, 0x98, 0xd0, 0xff, + 0xae, 0x0b, 0xfd, 0x1a, 0x07, 0x7d, 0xee, 0x20, 0xa4, 0xc4, 0x8f, 0xfd, 0xe3, 0xae, 0x81, 0xde, + 0xdd, 0x3e, 0x89, 0x65, 0xd3, 0xe4, 0xf5, 0x03, 0x2e, 0x30, 0x78, 0xda, 0x02, 0x90, 0x9a, 0x86, + 0xa4, 0xee, 0xd0, 0x90, 0xd4, 0x1b, 0x03, 0x2d, 0x21, 0x42, 0x2b, 0x8a, 0x1f, 0x87, 0x5f, 0x7d, + 0x09, 0xa4, 0x0b, 0x78, 0x63, 0x77, 0x0b, 0xbd, 0x55, 0x82, 0x6c, 0xd3, 0xd8, 0x2a, 0xb5, 0x36, + 0x0d, 0xd6, 0xb0, 0x84, 0xd3, 0x30, 0x45, 0x81, 0xd4, 0x36, 0xd6, 0x9c, 0xa6, 0x92, 0xff, 0xca, + 0x49, 0x98, 0xb6, 0x7f, 0x9d, 0x0b, 0x8a, 0xdd, 0xe8, 0x93, 0x5d, 0xa9, 0xf6, 0x04, 0xd5, 0x32, + 0x2c, 0xad, 0xa9, 0xe2, 0xba, 0x61, 0x36, 0xe8, 0x69, 0x91, 0xb4, 0xca, 0xa5, 0xd9, 0x78, 0x93, + 0x67, 0xe2, 0xbf, 0x90, 0x26, 0x19, 0xbc, 0x04, 0xe5, 0x46, 0x98, 0xda, 0xd4, 0xcd, 0x8e, 0x45, + 0x73, 0xd7, 0xa8, 0x83, 0x4b, 0x5a, 0xe5, 0x13, 0x6d, 0x7a, 0x7c, 0x09, 0xe7, 0xb1, 0x49, 0x2e, + 0x17, 0x4a, 0xab, 0x5d, 0xa9, 0x36, 0x3d, 0x4d, 0xcd, 0x57, 0xd8, 0x18, 0xa5, 0xc7, 0x9f, 0x66, + 0xd7, 0xe8, 0x3d, 0xdb, 0x45, 0x8d, 0xd3, 0x1a, 0xb9, 0x44, 0xbb, 0x46, 0x3b, 0x61, 0x75, 0xb7, + 0xd9, 0xac, 0xe2, 0x7a, 0x6e, 0xcb, 0x98, 0x01, 0x5a, 0x23, 0x9f, 0xaa, 0x20, 0x18, 0xdb, 0x6d, + 0x57, 0x2d, 0xcd, 0xda, 0xed, 0xcc, 0x4c, 0xd0, 0xfd, 0x24, 0xe7, 0x59, 0x39, 0x01, 0xd0, 0x30, + 0x2e, 0xb5, 0xd8, 0xdb, 0x49, 0xea, 0x6f, 0xe4, 0xa5, 0xd8, 0xcb, 0x66, 0x2a, 0xb2, 0x53, 0x34, + 0x86, 0x1d, 0xf5, 0xe7, 0xfa, 0xa4, 0x04, 0x60, 0x6d, 0x9b, 0x58, 0x6b, 0xf4, 0x84, 0xeb, 0x15, + 0x70, 0xbc, 0x69, 0x6c, 0x75, 0x2e, 0xe8, 0xd6, 0xb6, 0x07, 0xc4, 0x92, 0x03, 0x60, 0x5a, 0x0d, + 0x78, 0xab, 0x3c, 0x04, 0xd7, 0x38, 0x6f, 0x2e, 0x6c, 0x1b, 0x4d, 0x5c, 0x33, 0x31, 0xee, 0xc2, + 0x37, 0xad, 0x86, 0x65, 0x51, 0xe6, 0x20, 0x65, 0xbf, 0x66, 0x97, 0xc7, 0x23, 0x4e, 0xee, 0x89, + 0x98, 0xcd, 0x31, 0x11, 0x53, 0x49, 0x3e, 0xe5, 0x6e, 0xb8, 0xda, 0xb8, 0xd4, 0x5a, 0x36, 0xb6, + 0x96, 0xb4, 0x4e, 0x5e, 0xdb, 0xc4, 0x2a, 0xa6, 0xc7, 0xa6, 0x0c, 0x93, 0x88, 0xc1, 0x98, 0x1a, + 0xf4, 0x5a, 0x99, 0x03, 0xa5, 0xae, 0x6d, 0xe2, 0x65, 0x1e, 0x00, 0x2a, 0x19, 0x3d, 0xde, 0xd8, + 0xb0, 0xdb, 0xa9, 0x6b, 0x0e, 0x10, 0x59, 0x7a, 0x10, 0xd5, 0x9f, 0x66, 0x03, 0x6a, 0x3f, 0x17, + 0x3c, 0x40, 0xc6, 0x48, 0xae, 0xae, 0xd4, 0x7d, 0x22, 0x3d, 0xde, 0x4f, 0xa4, 0xa1, 0x5b, 0xa4, + 0x5d, 0x58, 0x27, 0xfc, 0xb0, 0x7e, 0x26, 0x0d, 0xa9, 0xea, 0x95, 0x56, 0x1d, 0xbd, 0xc9, 0x37, + 0xfc, 0x9d, 0x81, 0x63, 0x26, 0x2d, 0xb3, 0x66, 0x6a, 0x7b, 0xd8, 0xec, 0xe0, 0x65, 0x62, 0x47, + 0x49, 0x90, 0x32, 0x7b, 0xbe, 0xb3, 0xe5, 0xb7, 0x73, 0x51, 0x6f, 0x17, 0x77, 0xda, 0xd6, 0x95, + 0x65, 0x1b, 0x8f, 0x24, 0x8d, 0x02, 0xc5, 0x25, 0x2a, 0x0f, 0x00, 0xb2, 0xcc, 0x2b, 0x35, 0xc3, + 0xc1, 0x4f, 0xc5, 0x3b, 0x86, 0x85, 0x9d, 0x46, 0xd1, 0xde, 0x1c, 0x92, 0x03, 0xfd, 0x7a, 0xca, + 0xa7, 0x5b, 0xef, 0xe3, 0x75, 0xeb, 0xc9, 0x1e, 0xd0, 0xdb, 0x4d, 0x0b, 0xd0, 0xa4, 0xaf, 0x84, + 0x2c, 0x95, 0x67, 0x67, 0x95, 0x72, 0x5d, 0x8f, 0xef, 0x3d, 0x89, 0x57, 0x9d, 0xdc, 0x76, 0xdf, + 0x6a, 0xe0, 0x3d, 0xbd, 0x8e, 0x3d, 0x7f, 0x32, 0xe7, 0xd9, 0x85, 0xa9, 0xc6, 0x4a, 0xf6, 0x6b, + 0x1e, 0x96, 0x46, 0x78, 0x40, 0xff, 0xda, 0x22, 0x6d, 0xec, 0x5a, 0xb6, 0x88, 0x95, 0x5a, 0x15, + 0x22, 0x75, 0x4c, 0x15, 0x85, 0xe4, 0x50, 0xe6, 0xe1, 0x5a, 0xfe, 0xed, 0x12, 0xaf, 0x13, 0xa9, + 0x40, 0x86, 0xe6, 0xd9, 0x27, 0x4e, 0xd9, 0x7e, 0xe2, 0x34, 0xd6, 0x25, 0x4e, 0xe8, 0x0d, 0xee, + 0xc0, 0xf3, 0x20, 0x37, 0xf0, 0xdc, 0x2a, 0x86, 0xc2, 0x48, 0xc2, 0x65, 0x65, 0x28, 0xcb, 0xd1, + 0x4f, 0xf9, 0x64, 0x1b, 0xc1, 0x18, 0x03, 0xd5, 0x51, 0x5f, 0xee, 0xf3, 0x88, 0x64, 0xf8, 0x57, + 0x84, 0x6f, 0xcd, 0xa0, 0xdc, 0xa3, 0x8d, 0x08, 0x90, 0xe2, 0x3b, 0x21, 0xa5, 0xb7, 0x36, 0x0d, + 0x36, 0x71, 0xeb, 0x23, 0xc2, 0x24, 0xab, 0xe0, 0x35, 0x19, 0x21, 0x75, 0xc7, 0x8f, 0xdd, 0x6b, + 0x24, 0x48, 0xd9, 0x6a, 0xde, 0x1f, 0xf7, 0x13, 0xc1, 0x18, 0x9d, 0x14, 0x7b, 0xc0, 0x39, 0xcf, + 0x3d, 0xef, 0x0e, 0x99, 0x85, 0xc9, 0xdd, 0x96, 0xd6, 0x32, 0x5a, 0x57, 0x76, 0xf4, 0x57, 0xb9, + 0x53, 0x05, 0x2e, 0xcd, 0xa6, 0x7e, 0x0b, 0xb7, 0xb0, 0xa9, 0x59, 0xb8, 0xba, 0xb7, 0x45, 0x7a, + 0xeb, 0x98, 0xea, 0x4f, 0x42, 0x8f, 0x27, 0xa3, 0x29, 0x1c, 0x9b, 0xea, 0xe0, 0x2b, 0x2a, 0x37, + 0xf5, 0x26, 0x26, 0xfe, 0xed, 0xcc, 0xc7, 0xc3, 0x79, 0x8e, 0xd4, 0x9b, 0x7a, 0x54, 0x31, 0x12, + 0x44, 0x64, 0x7a, 0x67, 0xca, 0xb2, 0x51, 0xd7, 0x9a, 0x1d, 0xcb, 0x30, 0x31, 0x7a, 0xb9, 0x87, + 0x8e, 0x83, 0x40, 0xc2, 0x87, 0xc0, 0x71, 0xc8, 0x34, 0x8c, 0xba, 0xe7, 0xc9, 0xc0, 0x9e, 0xf8, + 0xe5, 0x4c, 0xe8, 0x31, 0x22, 0xda, 0xe0, 0xee, 0x7a, 0x63, 0xbb, 0x40, 0x46, 0xec, 0x68, 0x91, + 0x10, 0x51, 0x23, 0x88, 0xab, 0x90, 0x84, 0xd4, 0xaa, 0xde, 0xda, 0xf2, 0x2f, 0x62, 0x8e, 0x41, + 0x5a, 0x6f, 0x35, 0xf0, 0x65, 0x36, 0x52, 0xd3, 0x07, 0x7b, 0x38, 0x6f, 0xed, 0xee, 0x6c, 0x60, + 0xb3, 0xb2, 0x49, 0x9a, 0xdb, 0xa9, 0x19, 0x55, 0xdc, 0x72, 0x66, 0x66, 0x3d, 0xdf, 0xa1, 0x6f, + 0x27, 0xa2, 0xc9, 0xbd, 0x4d, 0x49, 0x00, 0x2e, 0x2e, 0x51, 0x49, 0x1f, 0x51, 0x91, 0x24, 0xbe, + 0x47, 0xe1, 0xf1, 0xf3, 0xf7, 0x23, 0x49, 0xc8, 0xae, 0x60, 0xcb, 0xd4, 0xeb, 0x1d, 0xf4, 0xfe, + 0x24, 0x4c, 0x55, 0xb1, 0xb5, 0xaa, 0x99, 0xda, 0x0e, 0xb6, 0xec, 0x25, 0xf9, 0xad, 0x9c, 0x62, + 0x6a, 0x37, 0x35, 0x6b, 0xd3, 0x30, 0x77, 0x1c, 0xc5, 0xe4, 0x3c, 0xdf, 0x93, 0x7a, 0xf2, 0x2b, + 0x52, 0x82, 0x67, 0x66, 0xa8, 0xeb, 0x0d, 0xab, 0x70, 0x8e, 0xab, 0x2c, 0xe0, 0x84, 0x85, 0x98, + 0x33, 0x8d, 0x48, 0x89, 0xf1, 0x33, 0xf3, 0x0f, 0x25, 0x90, 0x96, 0x8d, 0x2d, 0xf4, 0x1e, 0x09, + 0x52, 0x44, 0xbe, 0x7e, 0xc3, 0x37, 0x24, 0xcf, 0x40, 0x76, 0x07, 0x77, 0x3a, 0xda, 0x16, 0x76, + 0xee, 0x97, 0x66, 0x8f, 0xca, 0x59, 0x48, 0x37, 0xf1, 0x1e, 0x6e, 0x12, 0x32, 0xa6, 0xcf, 0xdc, + 0xc0, 0xb5, 0x6c, 0xd9, 0xd8, 0x9a, 0xb3, 0xcb, 0x72, 0x6f, 0xa1, 0x5d, 0xb6, 0xb3, 0xaa, 0xf4, + 0x8b, 0xd9, 0x87, 0x21, 0x4d, 0x9e, 0x95, 0x71, 0x48, 0x17, 0x8a, 0xf3, 0x6b, 0x8b, 0xf2, 0x11, + 0xfb, 0xaf, 0x43, 0xdf, 0x38, 0xa4, 0x17, 0x72, 0xb5, 0xdc, 0xb2, 0x9c, 0xb4, 0xdb, 0x51, 0x2a, + 0x2f, 0x54, 0x64, 0xc9, 0x4e, 0x5c, 0xcd, 0x95, 0x4b, 0x79, 0x39, 0xa5, 0x4c, 0x40, 0xf6, 0x42, + 0x4e, 0x2d, 0x97, 0xca, 0x8b, 0x72, 0x1a, 0x3d, 0xe6, 0x57, 0x58, 0xf7, 0xf0, 0xf8, 0xdd, 0x18, + 0x44, 0x53, 0x2f, 0xc8, 0xfe, 0xbd, 0x0b, 0xd9, 0xfd, 0x1c, 0x64, 0xdf, 0x2d, 0x52, 0x48, 0x34, + 0x94, 0xca, 0x03, 0x18, 0xb2, 0xa7, 0x60, 0xbc, 0x5c, 0xa9, 0xad, 0x2f, 0x54, 0xd6, 0xca, 0x05, + 0x19, 0xdb, 0x3c, 0xa8, 0x95, 0x56, 0x8a, 0x95, 0xb5, 0x9a, 0xbc, 0x89, 0xde, 0x94, 0x84, 0xec, + 0xaa, 0x69, 0xd4, 0x71, 0xa7, 0x83, 0x5e, 0x97, 0x84, 0x4c, 0x5e, 0x6b, 0xd5, 0x71, 0x13, 0xbd, + 0xc4, 0x83, 0xb1, 0x6b, 0x49, 0x88, 0xbe, 0xe9, 0x97, 0xfa, 0x87, 0x78, 0xae, 0xf1, 0xf7, 0x0a, + 0xb3, 0x72, 0xe7, 0x68, 0x99, 0x01, 0xbc, 0x7b, 0xc6, 0xe5, 0x5d, 0x9e, 0xe3, 0xdd, 0x69, 0xf1, + 0xa2, 0xe2, 0x97, 0xf3, 0xbf, 0x4f, 0xc0, 0xb1, 0x45, 0x7b, 0xfa, 0xa0, 0xd7, 0x29, 0xf1, 0x4e, + 0xfb, 0xef, 0xe7, 0xdb, 0x7f, 0x33, 0x47, 0x74, 0xaf, 0x2f, 0xf8, 0xc6, 0x3f, 0xed, 0x36, 0xfe, + 0x21, 0xae, 0xf1, 0xb7, 0x09, 0x96, 0x13, 0x7b, 0xcb, 0x67, 0xb3, 0x90, 0x26, 0x53, 0xe4, 0xd9, + 0x9b, 0x60, 0xaa, 0x6a, 0x99, 0x58, 0xdb, 0xf1, 0x0d, 0x4a, 0x96, 0x71, 0x11, 0xb7, 0x98, 0x68, + 0xd0, 0x87, 0x7b, 0xce, 0x42, 0xb6, 0x65, 0xac, 0x6b, 0xbb, 0xd6, 0xb6, 0xf2, 0xd2, 0x7d, 0xc7, + 0x86, 0x56, 0x68, 0xff, 0xaf, 0xb4, 0xe9, 0x2e, 0xd2, 0xdf, 0xdc, 0x47, 0x26, 0x66, 0x99, 0x96, + 0x91, 0xdb, 0xb5, 0xb6, 0xe7, 0xaf, 0xfd, 0xf0, 0x73, 0x27, 0x12, 0x1f, 0x7b, 0xee, 0x44, 0xe2, + 0x8b, 0xcf, 0x9d, 0x48, 0xfc, 0xcc, 0x97, 0x4e, 0x1c, 0xf9, 0xd8, 0x97, 0x4e, 0x1c, 0xf9, 0xec, + 0x97, 0x4e, 0x1c, 0xf9, 0xbe, 0x64, 0x7b, 0x63, 0x23, 0x43, 0x4a, 0xb9, 0xeb, 0xff, 0x05, 0x00, + 0x00, 0xff, 0xff, 0xd3, 0x4c, 0x7e, 0x8a, 0x73, 0x39, 0x01, 0x00, } func (m *Rpc) Marshal() (dAtA []byte, err error) { From c5f954c3259ba87e3644a1155a65e3b5df5abbbf Mon Sep 17 00:00:00 2001 From: kirillston Date: Thu, 22 Dec 2022 11:17:10 +0100 Subject: [PATCH 37/68] GO-677 Add validation in all methods --- core/block/editor/bookmark/bookmark.go | 2 +- core/block/editor/file/uploader.go | 2 +- core/block/service.go | 4 +- core/block/simple/text/text.go | 2 +- core/converter/md/md.go | 4 +- core/linkpreview.go | 3 +- util/linkpreview/linkpreview.go | 4 +- util/unsplash/unsplash.go | 2 +- util/uri/uri.go | 62 +++++++++++++------------- util/uri/uri_test.go | 27 +++++++---- 10 files changed, 60 insertions(+), 52 deletions(-) diff --git a/core/block/editor/bookmark/bookmark.go b/core/block/editor/bookmark/bookmark.go index 0e12ab3a3..bec5ef181 100644 --- a/core/block/editor/bookmark/bookmark.go +++ b/core/block/editor/bookmark/bookmark.go @@ -61,7 +61,7 @@ func (b *sbookmark) fetch(s *state.State, id, url string, isSync bool) (err erro if b == nil { return smartblock.ErrSimpleBlockNotFound } - url, err = uri.ValidateAndNormalizeURI(url) + url, err = uri.NormalizeURI(url) if err != nil { // Do nothing } diff --git a/core/block/editor/file/uploader.go b/core/block/editor/file/uploader.go index b0de714b4..14d32114d 100644 --- a/core/block/editor/file/uploader.go +++ b/core/block/editor/file/uploader.go @@ -175,7 +175,7 @@ func (u *uploader) AddOptions(options ...files.AddOption) Uploader { } func (u *uploader) SetUrl(url string) Uploader { - url = uri.NormalizeURI(url) + url, _ = uri.NormalizeURI(url) u.name = strings.Split(filepath.Base(url), "?")[0] u.getReader = func(ctx context.Context) (*fileReader, error) { req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) diff --git a/core/block/service.go b/core/block/service.go index 2080ba951..b952891f5 100644 --- a/core/block/service.go +++ b/core/block/service.go @@ -1593,7 +1593,7 @@ func (s *Service) fetchBookmarkContent(url string) bookmarksvc.ContentFuture { func (s *Service) ObjectCreateBookmark( req pb.RpcObjectCreateBookmarkRequest, ) (objectId string, newDetails *types.Struct, err error) { - u, err := uri.ValidateAndNormalizeURI(pbtypes.GetString(req.Details, bundle.RelationKeySource.String())) + u, err := uri.NormalizeURI(pbtypes.GetString(req.Details, bundle.RelationKeySource.String())) if err != nil { return "", nil, fmt.Errorf("process uri: %w", err) } @@ -1602,7 +1602,7 @@ func (s *Service) ObjectCreateBookmark( } func (s *Service) ObjectBookmarkFetch(req pb.RpcObjectBookmarkFetchRequest) (err error) { - url, err := uri.ValidateAndNormalizeURI(req.Url) + url, err := uri.NormalizeURI(req.Url) if err != nil { return fmt.Errorf("process uri: %w", err) } diff --git a/core/block/simple/text/text.go b/core/block/simple/text/text.go index 17c5abf6c..7e6068f47 100644 --- a/core/block/simple/text/text.go +++ b/core/block/simple/text/text.go @@ -234,7 +234,7 @@ func (t *Text) SetText(text string, marks *model.BlockContentTextMarks) (err err } else { for mI, _ := range marks.Marks { if marks.Marks[mI].Type == model.BlockContentTextMark_Link { - m, err := uri.ValidateAndNormalizeURI(marks.Marks[mI].Param) + m, err := uri.NormalizeURI(marks.Marks[mI].Param) if err == nil { marks.Marks[mI].Param = m } diff --git a/core/converter/md/md.go b/core/converter/md/md.go index ec5593cac..68063a7f1 100644 --- a/core/converter/md/md.go +++ b/core/converter/md/md.go @@ -217,7 +217,7 @@ func (h *MD) renderBookmark(buf writer, in *renderState, b *model.Block) { bm := b.GetBookmark() if bm != nil && bm.Url != "" { buf.WriteString(in.indent) - url, e := uri.ValidateAndParseURI(bm.Url) + url, e := uri.ParseURI(bm.Url) if e == nil { fmt.Fprintf(buf, "[%s](%s) \n", escape.MarkdownCharacters(html.EscapeString(bm.Title)), url.String()) } @@ -411,7 +411,7 @@ func (mw *marksWriter) writeMarks(buf writer, pos int) { if start { buf.WriteString("[") } else { - urlP, e := uri.ValidateAndParseURI(m.Param) + urlP, e := uri.ParseURI(m.Param) urlS := m.Param if e == nil { urlS = urlP.String() diff --git a/core/linkpreview.go b/core/linkpreview.go index 85a98bb1e..7dd416e15 100644 --- a/core/linkpreview.go +++ b/core/linkpreview.go @@ -15,7 +15,7 @@ func (mw *Middleware) LinkPreview(cctx context.Context, req *pb.RpcLinkPreviewRe ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() - urlStr, err := uri.ValidateAndNormalizeURI(req.Url) + u, err := uri.NormalizeAndParseURI(req.Url) if err != nil { return &pb.RpcLinkPreviewResponse{ Error: &pb.RpcLinkPreviewResponseError{ @@ -24,7 +24,6 @@ func (mw *Middleware) LinkPreview(cctx context.Context, req *pb.RpcLinkPreviewRe }, } } - u := uri.ParseURI(urlStr) mw.m.RLock() defer mw.m.RUnlock() diff --git a/util/linkpreview/linkpreview.go b/util/linkpreview/linkpreview.go index 3b3436b4c..3678c104f 100644 --- a/util/linkpreview/linkpreview.go +++ b/util/linkpreview/linkpreview.go @@ -86,7 +86,7 @@ func (l *linkPreview) convertOGToInfo(fetchUrl string, og *opengraph.OpenGraph) } if len(og.Image) != 0 { - url, err := uri.ValidateAndNormalizeURI(og.Image[0].URL) + url, err := uri.NormalizeURI(og.Image[0].URL) if err == nil { i.ImageUrl = url } @@ -126,7 +126,7 @@ func (l *linkPreview) makeNonHtml(fetchUrl string, resp *http.Response) (i model } else { i.Type = model.LinkPreview_Unknown } - pURL, e := uri.ValidateAndParseURI(fetchUrl) + pURL, e := uri.ParseURI(fetchUrl) if e == nil { pURL.Path = "favicon.ico" pURL.RawQuery = "" diff --git a/util/unsplash/unsplash.go b/util/unsplash/unsplash.go index 2209ef409..47603bfd1 100644 --- a/util/unsplash/unsplash.go +++ b/util/unsplash/unsplash.go @@ -111,7 +111,7 @@ func newFromPhoto(v unsplash.Photo) (Result, error) { fUrl := v.Urls.Regular.String() // hack to have full hd instead of 1080w, // in case unsplash will change the URL format it will not break things - u := uri.ParseURI(fUrl) + u, _ := uri.ParseURI(fUrl) if u != nil { if q := u.Query(); q.Get("w") != "" { q.Set("w", "1920") diff --git a/util/uri/uri.go b/util/uri/uri.go index 424390890..49d500ba5 100644 --- a/util/uri/uri.go +++ b/util/uri/uri.go @@ -22,9 +22,7 @@ var ( errFilepathNotSupported = fmt.Errorf("filepath not supported") ) -func ValidateURI(uri string) error { - uri = strings.TrimSpace(uri) - +func excludePathAndEmptyURIs(uri string) error { switch { case len(uri) == 0: return errURLEmpty @@ -36,19 +34,10 @@ func ValidateURI(uri string) error { return errFilepathNotSupported } - _, err := url.Parse(uri) - return err + return nil } -func ParseURI(uri string) *url.URL { - u, err := url.Parse(uri) - if err != nil { - // do nothing as validation is implemented in ValidateAndParseURI - } - return u -} - -func NormalizeURI(uri string) string { +func normalizeURI(uri string) string { switch { case noPrefixEmailRegexp.MatchString(uri): return "mailto:" + uri @@ -57,31 +46,42 @@ func NormalizeURI(uri string) string { case noPrefixHttpRegex.MatchString(uri): return "http://" + uri } + return uri } -func ValidateAndParseURI(uri string) (*url.URL, error) { +func ValidateURI(uri string) error { uri = strings.TrimSpace(uri) - - switch { - case len(uri) == 0: - return nil, errURLEmpty - case winFilepathPrefixRegex.MatchString(uri): - return nil, errFilepathNotSupported - case strings.HasPrefix(uri, string(os.PathSeparator)): - return nil, errFilepathNotSupported - case strings.HasPrefix(uri, "."): - return nil, errFilepathNotSupported + if err := excludePathAndEmptyURIs(uri); err != nil { + return err } - u, err := url.Parse(uri) - return u, err + _, err := url.Parse(uri) + return err } -func ValidateAndNormalizeURI(uri string) (string, error) { - err := ValidateURI(uri) - if err != nil { +func ParseURI(uri string) (*url.URL, error) { + uri = strings.TrimSpace(uri) + if err := excludePathAndEmptyURIs(uri); err != nil { + return nil, err + } + + return url.Parse(uri) +} + +func NormalizeURI(uri string) (string, error) { + if err := ValidateURI(uri); err != nil { return "", err } - return NormalizeURI(uri), nil + + return normalizeURI(uri), nil +} + +func NormalizeAndParseURI(uri string) (*url.URL, error) { + uri = strings.TrimSpace(uri) + if err := excludePathAndEmptyURIs(uri); err != nil { + return nil, err + } + + return url.Parse(normalizeURI(uri)) } diff --git a/util/uri/uri_test.go b/util/uri/uri_test.go index 613b7a211..3a1e4befb 100644 --- a/util/uri/uri_test.go +++ b/util/uri/uri_test.go @@ -9,55 +9,64 @@ import ( func TestURI_NormalizeURI(t *testing.T) { t.Run("should process mailto uri", func(t *testing.T) { uri := "john@doe.com" - processedURI := NormalizeURI(uri) + processedURI, err := NormalizeURI(uri) + assert.NoError(t, err) assert.Equal(t, "mailto:"+uri, processedURI) }) t.Run("should process tel uri", func(t *testing.T) { uri := "+491234567" - processedURI := NormalizeURI(uri) + processedURI, err := NormalizeURI(uri) + assert.NoError(t, err) assert.Equal(t, "tel:"+uri, processedURI) }) t.Run("should process url", func(t *testing.T) { uri := "website.com" - processedURI := NormalizeURI(uri) + processedURI, err := NormalizeURI(uri) + assert.NoError(t, err) assert.Equal(t, "http://"+uri, processedURI) }) t.Run("should process url with additional content 1", func(t *testing.T) { uri := "website.com/123/456" - processedURI := NormalizeURI(uri) + processedURI, err := NormalizeURI(uri) + assert.NoError(t, err) assert.Equal(t, "http://"+uri, processedURI) }) t.Run("should process url with additional content 2", func(t *testing.T) { uri := "website.com?content=11" - processedURI := NormalizeURI(uri) + processedURI, err := NormalizeURI(uri) + assert.NoError(t, err) assert.Equal(t, "http://"+uri, processedURI) }) t.Run("should process url with additional content and numbers", func(t *testing.T) { uri := "webs1te.com/123/456" - processedURI := NormalizeURI(uri) + processedURI, err := NormalizeURI(uri) + assert.NoError(t, err) assert.Equal(t, "http://"+uri, processedURI) }) t.Run("should not modify url with http://", func(t *testing.T) { uri := "http://website.com" - processedURI := NormalizeURI(uri) + processedURI, err := NormalizeURI(uri) + assert.NoError(t, err) assert.Equal(t, uri, processedURI) }) t.Run("should not modify url with https://", func(t *testing.T) { uri := "https://website.com" - processedURI := NormalizeURI(uri) + processedURI, err := NormalizeURI(uri) + assert.NoError(t, err) assert.Equal(t, uri, processedURI) }) t.Run("should not modify non url/tel/mailto uri", func(t *testing.T) { uri := "type:content" - processedURI := NormalizeURI(uri) + processedURI, err := NormalizeURI(uri) + assert.NoError(t, err) assert.Equal(t, uri, processedURI) }) } From 4ba75b058710efc48f9aa93faef080067332535d Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Thu, 22 Dec 2022 13:21:56 +0300 Subject: [PATCH 38/68] GO-564: fix lint Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/relationcreator.go | 5 ++++- pkg/lib/core/core.go | 11 +++++++++++ pkg/lib/core/images.go | 2 ++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/core/block/import/relationcreator.go b/core/block/import/relationcreator.go index 91f25c6d8..3a247e83a 100644 --- a/core/block/import/relationcreator.go +++ b/core/block/import/relationcreator.go @@ -33,7 +33,10 @@ type RelationService struct { } // NewRelationCreator constructor for RelationService -func NewRelationCreator(service *block.Service, objCreator objectCreator, store filestore.FileStore, core core.Service) RelationCreator { +func NewRelationCreator(service *block.Service, + objCreator objectCreator, + store filestore.FileStore, + core core.Service) RelationCreator { return &RelationService{ service: service, objCreator: objCreator, diff --git a/pkg/lib/core/core.go b/pkg/lib/core/core.go index a16f1d826..fef58a233 100644 --- a/pkg/lib/core/core.go +++ b/pkg/lib/core/core.go @@ -3,6 +3,17 @@ package core import ( "context" "fmt" + "io" + "os" + "path/filepath" + "strings" + "sync" + + "github.com/libp2p/go-libp2p/core/peer" + pstore "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/p2p/discovery/mdns" + "github.com/textileio/go-threads/core/net" + "github.com/anytypeio/go-anytype-middleware/app" "github.com/anytypeio/go-anytype-middleware/core/anytype/config" "github.com/anytypeio/go-anytype-middleware/core/configfetcher" diff --git a/pkg/lib/core/images.go b/pkg/lib/core/images.go index aaa43a1d1..c3954414f 100644 --- a/pkg/lib/core/images.go +++ b/pkg/lib/core/images.go @@ -3,6 +3,8 @@ package core import ( "context" "fmt" + "io" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/files" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/storage" ) From 80402dd6d76dabdd8f152479e52da7a4f7045257 Mon Sep 17 00:00:00 2001 From: kirillston Date: Thu, 22 Dec 2022 12:07:49 +0100 Subject: [PATCH 39/68] GO-677 fix lint 3 --- core/block/editor/file/uploader.go | 5 ++++- core/block/object/creator.go | 2 +- util/unsplash/unsplash.go | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/core/block/editor/file/uploader.go b/core/block/editor/file/uploader.go index 14d32114d..dc1d6f38b 100644 --- a/core/block/editor/file/uploader.go +++ b/core/block/editor/file/uploader.go @@ -175,7 +175,10 @@ func (u *uploader) AddOptions(options ...files.AddOption) Uploader { } func (u *uploader) SetUrl(url string) Uploader { - url, _ = uri.NormalizeURI(url) + url, err := uri.NormalizeURI(url) + if err != nil { + // do nothing + } u.name = strings.Split(filepath.Base(url), "?")[0] u.getReader = func(ctx context.Context) (*fileReader, error) { req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) diff --git a/core/block/object/creator.go b/core/block/object/creator.go index 26bc65a05..46852b01a 100644 --- a/core/block/object/creator.go +++ b/core/block/object/creator.go @@ -280,7 +280,7 @@ func (c *Creator) CreateSubObjectsInWorkspace(details []*types.Struct) (ids []st // ObjectCreateBookmark creates a new Bookmark object for provided URL or returns id of existing one func (c *Creator) ObjectCreateBookmark(req *pb.RpcObjectCreateBookmarkRequest) (objectID string, newDetails *types.Struct, err error) { - u, err := uri.ProcessURI(pbtypes.GetString(req.Details, bundle.RelationKeySource.String())) + u, err := uri.NormalizeURI(pbtypes.GetString(req.Details, bundle.RelationKeySource.String())) if err != nil { return "", nil, fmt.Errorf("process uri: %w", err) } diff --git a/util/unsplash/unsplash.go b/util/unsplash/unsplash.go index 47603bfd1..0362c8cd6 100644 --- a/util/unsplash/unsplash.go +++ b/util/unsplash/unsplash.go @@ -111,8 +111,8 @@ func newFromPhoto(v unsplash.Photo) (Result, error) { fUrl := v.Urls.Regular.String() // hack to have full hd instead of 1080w, // in case unsplash will change the URL format it will not break things - u, _ := uri.ParseURI(fUrl) - if u != nil { + u, err := uri.ParseURI(fUrl) + if err == nil { if q := u.Query(); q.Get("w") != "" { q.Set("w", "1920") u.RawQuery = q.Encode() From 4ed07c57724042f93a42357633df6ce53bb7cff2 Mon Sep 17 00:00:00 2001 From: Roman Khafizianov Date: Thu, 22 Dec 2022 20:30:21 +0100 Subject: [PATCH 40/68] ci: add linux/arm64 build --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 82dc1fbfa..b887628f7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -72,7 +72,7 @@ jobs: run: | echo $FLAGS mkdir -p .release - gox -ldflags="$FLAGS" -osarch="darwin/amd64 darwin/arm64 linux/amd64" --tags="nographviz nowatchdog nosigar nomutexdeadlockdetector" -output="{{.OS}}-{{.Arch}}" github.com/anytypeio/go-anytype-middleware/cmd/grpcserver + gox -ldflags="$FLAGS" -osarch="darwin/amd64 darwin/arm64 linux/amd64 linux/arm64" --tags="nographviz nowatchdog nosigar nomutexdeadlockdetector" -output="{{.OS}}-{{.Arch}}" github.com/anytypeio/go-anytype-middleware/cmd/grpcserver make protos-server CC="x86_64-w64-mingw32-gcc" CXX="x86_64-w64-mingw32-g++" gox -ldflags="$FLAGS" -osarch="windows/amd64" --tags="nographviz nowatchdog nosigar nomutexdeadlockdetector" -output="{{.OS}}-{{.Arch}}" github.com/anytypeio/go-anytype-middleware/cmd/grpcserver ls -lha . From aa68eaf436645a96ca77d312a515c7baa92ed206 Mon Sep 17 00:00:00 2001 From: Sergey Date: Fri, 23 Dec 2022 12:35:33 +0500 Subject: [PATCH 41/68] Use normal mutex by default --- util/mutex/locker.go | 2 +- util/mutex/locker_prod.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/util/mutex/locker.go b/util/mutex/locker.go index d0dcc05cc..d3f153f56 100644 --- a/util/mutex/locker.go +++ b/util/mutex/locker.go @@ -1,4 +1,4 @@ -//go:build !nomutexdeadlockdetector +//go:build mutexdeadlockdetector package mutex diff --git a/util/mutex/locker_prod.go b/util/mutex/locker_prod.go index 82d3fdbad..0bdf50771 100644 --- a/util/mutex/locker_prod.go +++ b/util/mutex/locker_prod.go @@ -1,4 +1,4 @@ -//go:build nomutexdeadlockdetector +//go:build !mutexdeadlockdetector package mutex From 58f16b0a1704a447429d28f662cf5e0d88b9d7ef Mon Sep 17 00:00:00 2001 From: kirillston Date: Fri, 23 Dec 2022 09:55:37 +0100 Subject: [PATCH 42/68] GO-230 Add webp resize --- go.mod | 3 ++- go.sum | 5 ++++- pkg/lib/mill/image_resize.go | 26 +++++++++++++++++++++++++- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0070d6962..6a52ad10d 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/anytypeio/go-slip21 v0.0.0-20200218204727-e2e51e20ab51 github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de github.com/blevesearch/bleve/v2 v2.3.6 + github.com/chai2010/webp v1.1.1 github.com/cheggaaa/mb v1.0.3 github.com/dave/jennifer v1.4.1 github.com/davecgh/go-spew v1.1.1 @@ -87,6 +88,7 @@ require ( github.com/yuin/goldmark v1.4.13 go.uber.org/zap v1.24.0 golang.org/x/exp v0.0.0-20221205204356-47842c84f3db + golang.org/x/image v0.0.0-20211028202545-6944b10bf410 golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b golang.org/x/text v0.5.0 google.golang.org/grpc v1.47.0 @@ -275,7 +277,6 @@ require ( go.uber.org/fx v1.18.2 // indirect go.uber.org/multierr v1.8.0 // indirect golang.org/x/crypto v0.3.0 // indirect - golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect golang.org/x/mod v0.7.0 // indirect golang.org/x/net v0.3.0 // indirect golang.org/x/sync v0.1.0 // indirect diff --git a/go.sum b/go.sum index defad0df9..a6346e40b 100644 --- a/go.sum +++ b/go.sum @@ -185,6 +185,8 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chai2010/webp v1.1.1 h1:jTRmEccAJ4MGrhFOrPMpNGIJ/eybIgwKpcACsrTEapk= +github.com/chai2010/webp v1.1.1/go.mod h1:0XVwvZWdjjdxpUEIf7b9g9VkHFnInUSYujwqTLEuldU= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/cheggaaa/mb v1.0.3 h1:03ksWum+6kHclB+kjwKMaBtgl5gtNYUwNpxsHQciKe8= github.com/cheggaaa/mb v1.0.3/go.mod h1:NUl0GBtFLlfg2o6iZwxzcG7Lslc2wV/ADTFbLXtVPE4= @@ -1567,8 +1569,9 @@ golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86h golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20200119044424-58c23975cae1 h1:5h3ngYt7+vXCDZCup/HkCQgW5XwmSvR/nA2JmJ0RErg= golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ= +golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= diff --git a/pkg/lib/mill/image_resize.go b/pkg/lib/mill/image_resize.go index d374d9b37..2d6c5fef8 100644 --- a/pkg/lib/mill/image_resize.go +++ b/pkg/lib/mill/image_resize.go @@ -3,9 +3,11 @@ package mill import ( "bytes" "fmt" + "github.com/chai2010/webp" "github.com/disintegration/imaging" "github.com/dsoprea/go-exif/v3" jpegstructure "github.com/dsoprea/go-jpeg-image-structure/v2" + _ "golang.org/x/image/webp" "image" "image/color/palette" "image/draw" @@ -30,6 +32,7 @@ const ( PNG Format = "png" GIF Format = "gif" ICO Format = "ico" + WEBP Format = "webp" ) type ImageSize struct { @@ -150,7 +153,7 @@ func (m *ImageResize) Mill(r io.ReadSeeker, name string) (*Result, error) { r2 = r } // here is an optimisation - // lets return the original picture in case it has not been resized or normilised + // lets return the original picture in case it has not been resized or normalized return &Result{ File: r2, Meta: map[string]interface{}{ @@ -222,6 +225,27 @@ func (m *ImageResize) Mill(r io.ReadSeeker, name string) (*Result, error) { "height": gifImg.Config.Height, }, }, nil + } else if format == WEBP { + webpImg, err := webp.Decode(r) + if err != nil { + return nil, err + } + + resized := imaging.Resize(webpImg, width, 0, imaging.Lanczos) + width, height = resized.Rect.Max.X, resized.Rect.Max.Y + + buff := &bytes.Buffer{} + if err = webp.Encode(buff, resized, &webp.Options{Quality: float32(quality)}); err != nil { + return nil, err + } + + return &Result{ + File: buff, + Meta: map[string]interface{}{ + "width": width, + "height": height, + }, + }, nil } return nil, fmt.Errorf("unknown format") From 4523945702ccf05e9fe9fbeba331f338ddddcd08 Mon Sep 17 00:00:00 2001 From: Sergey Date: Fri, 23 Dec 2022 14:16:31 +0500 Subject: [PATCH 43/68] Revert deadlock detector by default --- util/mutex/locker.go | 2 +- util/mutex/locker_prod.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/util/mutex/locker.go b/util/mutex/locker.go index d3f153f56..d0dcc05cc 100644 --- a/util/mutex/locker.go +++ b/util/mutex/locker.go @@ -1,4 +1,4 @@ -//go:build mutexdeadlockdetector +//go:build !nomutexdeadlockdetector package mutex diff --git a/util/mutex/locker_prod.go b/util/mutex/locker_prod.go index 0bdf50771..82d3fdbad 100644 --- a/util/mutex/locker_prod.go +++ b/util/mutex/locker_prod.go @@ -1,4 +1,4 @@ -//go:build !mutexdeadlockdetector +//go:build nomutexdeadlockdetector package mutex From 432872a93b8954e14dbf90acb689f63068c00970 Mon Sep 17 00:00:00 2001 From: kirillston Date: Fri, 23 Dec 2022 17:50:53 +0100 Subject: [PATCH 44/68] GO-230 Add webp sample to testdata --- pkg/lib/mill/image_resize.go | 32 ++++++++++--------------------- pkg/lib/mill/testdata/image.webp | Bin 0 -> 10474 bytes pkg/lib/mill/testdata/images.go | 7 +++++++ 3 files changed, 17 insertions(+), 22 deletions(-) create mode 100644 pkg/lib/mill/testdata/image.webp diff --git a/pkg/lib/mill/image_resize.go b/pkg/lib/mill/image_resize.go index 2d6c5fef8..08a269fae 100644 --- a/pkg/lib/mill/image_resize.go +++ b/pkg/lib/mill/image_resize.go @@ -163,13 +163,18 @@ func (m *ImageResize) Mill(r io.ReadSeeker, name string) (*Result, error) { }, nil } - if format == JPEG || format == PNG || format == ICO { + if format == JPEG || format == PNG || format == ICO || format == WEBP { if format == JPEG && img == nil { // we already have img decoded if we have orientation <= 1 img, err = jpeg.Decode(r) if err != nil { return nil, err } + } else if format == WEBP { + img, err = webp.Decode(r) + if err != nil { + return nil, err + } } else if format != JPEG { img, err = png.Decode(r) if err != nil { @@ -185,6 +190,10 @@ func (m *ImageResize) Mill(r io.ReadSeeker, name string) (*Result, error) { if err = jpeg.Encode(buff, resized, &jpeg.Options{Quality: quality}); err != nil { return nil, err } + } else if format == WEBP { + if err = webp.Encode(buff, resized, &webp.Options{Quality: float32(quality)}); err != nil { + return nil, err + } } else { if err = png.Encode(buff, resized); err != nil { return nil, err @@ -225,27 +234,6 @@ func (m *ImageResize) Mill(r io.ReadSeeker, name string) (*Result, error) { "height": gifImg.Config.Height, }, }, nil - } else if format == WEBP { - webpImg, err := webp.Decode(r) - if err != nil { - return nil, err - } - - resized := imaging.Resize(webpImg, width, 0, imaging.Lanczos) - width, height = resized.Rect.Max.X, resized.Rect.Max.Y - - buff := &bytes.Buffer{} - if err = webp.Encode(buff, resized, &webp.Options{Quality: float32(quality)}); err != nil { - return nil, err - } - - return &Result{ - File: buff, - Meta: map[string]interface{}{ - "width": width, - "height": height, - }, - }, nil } return nil, fmt.Errorf("unknown format") diff --git a/pkg/lib/mill/testdata/image.webp b/pkg/lib/mill/testdata/image.webp new file mode 100644 index 0000000000000000000000000000000000000000..0da983e2ce5335eb13a7b793a1403588617dde3c GIT binary patch literal 10474 zcmV7UINk&HEC;$LgMM6+kP&gpgC;$MGvjCj|DnJ3&06vjAl}Dr^3{6ivAOwO~ z+eST}*jM{(wJ+6cBmBd+9~^!R8h;bM$G=+!KA*Y2dco(n^PJzG-Hf&KYnPvWv&*9T z|1aRL_HNr>qAtMwG5( zaZc)n6Q5~UfSUzhs=x-_&u0so=_GdYM6n|qccd(=ZwQQU!0e3BA~NZ!H?=L2^!-A+ zPx)e6k{A*}Jb?mhq_bkOtrQHeS#muC&9^f@pCHDBxXT&D{)tC=MTk?&kbCl!_N z?XBxLkCIBGj7S^s5LL!&r4+AWN7N`YVzoQ_>!P`v&OQ!%j5ws?tGxx>S%^7;s1q*v zo)KRN@%RF(3*nxarCBhB^2xDkNFdwcl`Tw|els65!A|we&!A^e@86_URtQB02>imS zDBIGYs5;TM$&j!u&sKtR;Y{hUn7;x=`H}x0UnUSjp}4&)nDtGOb<2I_(9(u*9`3G{ zYt_iS)AL<@k{{%+eBUgwyl6Ha?|o zS~(-2e8dTG@YCyIeDuq@0qYa&qAND8$dZ1^KhhXb&$VSG=*JmLEwpSWj_<6Lt9dM%HgB+=Y|)Lj}m=nNd`5=>z5!pUbi zHp!_;FYex}3aR9VDGneH6t2mVPg7X?nb)>r>2|xh=AJa&fc=SZ6ts)UJi4f|arcsN zgeHG9>gK@G>Lp(v)Hvu`S*C@5+07Va^}{{hbu?Ga?`^&=Aa@lI>PmmBSMOGx7CV{$ z8IL+?q~ztet9xWa`_l&-9MZIhj%h}O=b9G5Q{$0(+JNUId`4GE%Gj{}kLPWm<4~7Z zBJM~#chEMQxFmxSVaaXc_J#-998g8#o`T71Iaq_REQhFBdguy%*(=Clj$#7*iwduu zD~S2yv|40)H=F#DY=co{3+7{;PkrY{jd-Rp4pw?Z!LbjzRhlcK_kiMh`D7{z>JHtn zLC5C-vN^|iTU>Zz;0wYl%o#dN*2Del$13gSNC|d8Dut^*%wGmHlx(Jz(-$kkE?A8p z#>YuV4Um37R|?W$!*c080~j4WEM@z5`BCrK#3cJ_x@CC zDfL=79hA!?ei>-BNflmPAVg%*TdRwYX$8d0|)x_ujXI@$RKwa86l;O@`#*_#rz?Ylk5pNw&<<@c*3jG}9Xb^wP<>)mv7c{Gizf zueq|o%#|61X27G5XW_)&1k&T9KT9Uh}&S=t^a4#($5t&C8lva{cy@fZeSS_gO>-^WKlXlECuQH8*Ri zfTEEmfPPq~g!T(;4M0p_Fzw~8Z^nV43?*@3h1GR#Q)rGK_okxz8ab$k5D1)`_ZQ+^ zV?&d%G>0G0HRTwRK)v2VXM!!XV)r@HYH59UHLs1if7So>%=~(?#u#f^3qQEW1vYC) z?8?@(LR>RjZ_A=!^}m1ZfJnLVCv#^0!vgPm6HUejm;aX5_eGv;wSV%Rj@LStJECi9-$E3;p@2im(1dP5;yVZ1T zqVecO;<9$5;g4$1`R@EIYRi2tkq%vK6hrNZH%G&0N6LvC@dR|wd{==Mx;!3gbZl4Y zm35z`7}s>*hoG`a(HRH!~&peEnbGUK2T;p$W0zQ)E z>#I=MTR~r5Jd^UY8iU7$zj{SDiC~YLGsr>OX>!P}Otvk@gE^L}GO~7OZO-yN ztoy*b>k&bBypdf*zb$JxgF{1K#5Bu-@@$#M7^c$+qKSeiNl!F(tf7ne98C*XnS%eu zK!K3aePN}njsfLQ*!IEXWhGd7l>JU%9d$MW#;OVk3D9tnGVvit^$0>A7U_t(Zz@tk zn@QUpl9xeMV5Svd6pwoAnQ1T^vF_ z{*}B5$3oxxYXlYg8k`Dksg#a`4${E&q;uwgQ)qj1=l`!!c7P+Bo*S1STcdI>RnvM> zkX%KC{sS_@%}bXZfYxm$$p=rwg2BTJB{CypPgpk|lw}GHX3MZ|rn`o^%I zYORGGlM$oS1+#K@VB2;0#^A<4#r6$XGTC0B3VMLi63V^D^kbFY-sn zYF4Ifl5vW3Yt}zCh1{`z{0G?({%7})08pu~6W9kOz?sl8{ToYKEZ3v6R@_+2xn+&6 zd`8(rkASd;YPZCpXzr6QBR(L!bGq#xXA(99=QX(WOGxp$fAvVZk?PkgX zl3}tqj{S`n=y=R9y8oNjO!ewCh9xvH8!_G!HdiZ@*Ea$Z`y)8}54PQz>%f%yV}=D- z)i^|2KrziT46__ly5(fM=xyLxlHqG|Wr4zZQ$pv^LVi=~pWI(yjLQq(j9QXVjJ-by_ zTeYozIwlTMz{D$A-=8J8*T2}yb0c&*%D~^PG{GT!9Knl=#%^ldG2mY@PpoK zGd(QUSqSWX{3vyg(Vq^C3Ms493D0x9GX*)93}l{|I_TyKxU`+h0=?Ux$B=QQZCgT| z9HEq!Xbj2 zZ^U8@e#f?3V3aZX1mEDUZf0S)r!}^#f8F zT#QNMGt0{v7;~J+G&ItwWaHk(px$_+hQSwenF<40Eo#*_NI)`f`b=1eR?_omge@B^ zw?JH;Pe&5yUf?F{Zy*AFoob?vV)uAwWnz6l^R5%jn|u8P9vqPH;Xv`i^snXcO=MgG zrrV*Yfn5H{(66I8YoTtWD_Mn0`b+?o$1nTHe|h5@qfq7zI?Y8y^saXaLsPs3;c4FQ z0hb=Q*WILtwFXH)K6d7S=}6QI(R_al1yMZF=qbgqrX#HW?6qEamMDgd)&x7ZeWI_PD~()-&~vr7F6l|CDYny6I~jS>?T|lEBiuo8|C%aIEN6jKc{b!XVHqw>7G&pwDG2V6qb zI2QUdtVj5rki}K7<}c?25-fQvEHl?BIT0iY2Gp3Ub?ADqvkDK9PjoZ__Ya+gzgCDE zqZgFezxJ6T{8oSL6c&;ICN7u9hgn!-YZm!9hAw)pE3xG3LIugx)kyT;GdQTFWJ#jk z_?wDpMy}85Sc^6emdayOHMzTaUzs%d2wFWu2c9uA3ih$G#thYBca*)cK~nFjgDNxm zK-MNBwlWj$;8su|Omw7DcVH&jtndy$>;6IJc>E4M`UPy$iQ6o$k(N4!i65lp6*T)% zR_8&%%c)QZKv0z0-1nDtQzdW$;T=|n&&av}_9(ZuLRFt*gx#XUPK8cGjH2)~|AY29 zs~>?|DepKdfGxbo8+#W* zd8+CpZ@HRYsoq!Z`&x-!wm>BWblFNiqK*DZ%O&$! zwnZ4<-~T+)r&e#5w;XuRU*ILWto_<)7D1eSu&`$`BHQ`Pe3@oH(kyB-)?_yb11O-a zuk1(UIs}4H+62U8y%S>T_^6=rV?+xW8fa%w2fHkiQ4?Pn-!dKns6ql2b_39;K)-loY4G%-+NGlMs zQ+sVFGh{zcbJ(o`Q8}rJ>rW@W*z)FwXECRp?0)%Xr`nq}wnVdMN@Igw-A2(v!BgIB z=vk=^sInH4-OHhAwwYNjy_>kwWwFrGTTd|d5+SK-ki=Wz0(3bi>i$3ol@U$Tt9T?k zPv`(NJjo>y$g}m2q}74zAccw~2Pe`zoi1lKc4X=ZDm28Ph1rEW+}h;z7~PG+j6;aq z8urvS^Qbd%m+eCy2hkNbvb>NbnWS^}oL0VFM=cE4p0dc7 zUY!*e zgfg`IT%uq;f@p%QVnNfQ6RMW`3w>GAx02WdoP&wWAd*U`m>*neBaYzB2Wvl_-K`jJ zu`C*7mO`|^)qL5E^l&!Z?dtXWwBxv9&cAf@T?aXsUnCeS>@tmS7T! zu@ZJHUx>g07w2z(tVA=^XSTYKAHJRX#n32I$dbn0S)m5`T$LWij`tM35q1BAUbdcz zbn2nk_i)sjaTRGV_D&%}r4;EM55*!29k$Zs20_rHJR`}KJs#=+kbBP3mdD{&<5bm& z!ivdk2DV)Nj=tadP;820aLK00z0EUPl&-e4NifKkEMo&+Uw@D7mkCK>Yg{Pw1Dg|Y zu2nz=5)fmpIoga@?vP6p6FiZZAUcU$a9G!hYZ=J3qK@yCZ*U@ce6n?S2Ch1T4Qc2- zT*1{2;$$fZjsz8O?sZ>WoZ*lA5W8>v3&QiJ67Zrg+_0+n)d_+<<&U|H z4_g;RA(3h|_{T;#t>5vRh z0vIpi!22VEJbpj;ic3hou_&a8BVm6Bsk+Ob-%()BwwwR$B#@k(r>No9Vc4pTy-c|^6llM24@EHAjJCEv|@>Hd=e|wIbYvZ8xJ4Q^t!0tF_`+h8$ z+Sj_gH*=I5JLMo$0T~+1K~?f%^?-m@;;XQ?)Ui>Hi&o z@@CRlXGu)@cCCpnovLdZ$hxe-9Uqy7i zh)dSrpJ=5-_;mo-Jxj5VmDV~vq!(f!pU49G-S}b@E;g9hh(R|Q#kMfz195a`nC(-Q zQ9J#BG1PiYiE37zY^aOBq0RcxjXNn&Eph`|w-dxWYu`0WhWVTT>0sffb-qaa4Z4w} z(Az(l@zm*v50t{pf6dsRD&#y3(w3nwL+)sacT9xd`VA&xEc?jYOj5bg)A**ZVRc>= zax-_f_KQ5_*qF-rfv-^-Bx&;NK9UoVf|Mq6?i$ZKl4@R}O;9~P=ZRS1;jDXEc|?vh zteFu!M`M{D^H#s8>sS2lV3n$3g3|GMp$_y{S(=A!ohGp7cSZVW5T7}9aj zE7HfXrKJ{5JD&;h1FJHY%7iAq5AAWE|1;2Fq{mzx^tK0_-c8o<%C&(-++H>P30El! zw82JhOGHO;8-awuyt#dZUiskrYJ-=4bbtN1&mQu|-%ct=d44#hx-$D^Gqb$g)^ZnM zx+f-ROt4F43SY3;c3l-{7|BPxxkswsX*|bMxh5k$Rpl zYjNJ}-C!-95!@UmOYNqfPUE2IyJN*OoAkzJg@fo%2C&7`UEW2fu#207^u4C|vy*gu zC!F=>kL}7*_CUO6`6(jA6#pYeid45YdRJ^}D{bqsUczKtzAK!^HoZ=M02ODdqyafc zPm4?1r_wWmtx6O{1ji&@Swos97Q3XOa^bhZMd1PfD0hmc2=Qes@MNg`dB}a6SIC@&k-l$DZr>)63#|a{6 z7dQS9FaN3tkyQ4|m)3QNP@bgoQ!c9opa3Ar6%~e08s_jbY`3Bd%BAk$e6=Qwb1|%4 z$~ug=y~w4HGdkI86Q4ccR?pEj+=@I_iKzlt&5Xc-fbT^fa}E$dFLw?b?(T%r@U(A6v9)I!F#eCK{G z0!x$le!&$yUp2(5EUM*^C>lHV`X(i^L_05$N)Jg}vqn0qs({_+C;WKSO2&*v`T}v! zMhB(U6Zr%{$rdZdXjEf zS+_N7%XG1N`|`+NvRzh3+12IJ-G{mrmxP7KR3QJRm~Aky5PrS$N8mgoIEMMQg3PAa z7H@rDRC;nWKKd{7n3gYti$|0cAOg~$Lap)G^d>Bb(-B`>|GvC*JNo=11|qD7W73Bx zX7aSWG}2l?Ld@ITK97^fDQ*`W9f4{i5l=#1G`+Bytq5rU7vC7s!0+_=Up_*Rh;`&B zety<0xwVGCJPwDS<$P8CaL!GLHmq_ga33@6dS)tr>zjQg3Ea-I!DU&(bPYS&7*Mkp zQUe)nj9Uptl^a;y3}o6Kj_=2H+pn7)Q;M^_vVup65T`z>R$|TRYJ9#$)BSd0_T0ec1_xS>hZ1{Z<}Pm&u@n=g_-M@D)f7Js5okk5>RN=K@tlY+EdE<2u< z?+L-OI1@#34@I&Yn(~GhB+^NYPjN$*X5|NF2MXUV+Vu!iaza4_IB?@fHVt7*wX^Z_+;%`rQmJ?fTv^Q*9-2)e@mc34e@UA}KIa zDpZN8u*-*3PC>e+zgs&z|AY7XI?NfO174TN2D~$A_*E019jL$alLnGwP#`Z-#Cq4+ zSlRWgDLj24<+;S==qqgZUTT2=2miUGp(bB8JmFrXqfguLt`MEerxQ-#t`=^P#+slL z5a;8JmASWds6xQGhRag3E>Gas4YT7pM(5m?^&t|7joEI+H>6&Jm@&J(| zRt~>N$eLAu}rOeT+7qU|+~jKph&MyfB)y8Vit?p* z%PTS()VVw3m?7>>m>a!%M#kVPX{Hfs`6Eq%3Lw2}FUatycfBI6lGfzm7X=5Xq7CxH z>*U{SKDPvy!fHTrl2|v z6?X!o{}+Q@4YI4l01CJ+tLc{#j-0xpUXftR2#A7j?)e}zRlXFV zx@YxUr&Y&VTJiC5wkpn>2(KMq8d8zi!ZEf=WPW_qW-EPspq~Pev6${Tn;Ntd3}j*Jgp>7qyW?d(8bkWPhV0uT87xZo1~`YGBjbJycYO z%g#2MG?yOjJnv0}J2N&ohvLCc>R^&jQO?YbIAl*LB_o2_Qs|b{PtO>@0}UWNIA_mU zgT^qmSD2)xOEavy_7MAlFCT&QA*jWjx_rqRc=F|_WAkQlSMhAfgM@j#hM3S`MW6#- zVwK%~oF-Yq>{pT;X(^P6_#YXg3B&)dvbJ3B?ljX+7N<<_XD;P{(soH*_z3i+I(cN> zBZ2t-)cOgm`o6!zk?FUOfg_k2+%sJTDv7ih=5`@Q#c|d$$SI+*ohmN;DJz|xBR6%_ zCc_y2Pu1bg5ePxbrr>`Ref+V~7SG=KX1TJbiLfv=!9ljzxbH8zDnoD;-&vo_`~mKu zXqP?62Ovv8@$&cfeA6>5l9N{5LDSac9D}u+O0|-A9kYKapl8aca|bIA0wxba8xode zq(1D1$h|qSr{%TxGj01kY@@$sWNcwYILOKy9ngPkY8&M1tgKHt$q|3~MwAwXXci8- z_a*C-wp91e+$C<@Msc1R8$uj5+Tp!n-bX!3*-m28d;N_xiq}JlxN{9Id0sp3Zg@6D zey$f(urx*0M>C$1ed<`zQ=p*2g2);R)Qt7Sia~q+oyZhWeVo3I-?9#zHv4&b*lQDm zcUpek8818z-Z>Xto!-y=I^onqM22$v0L;A15cX&@X>Y))Oq_KG_D6gjinYSo5Y|0;tK&CZSwp87e9TdZ|0aS{Rg%!lBdng_s7d8bZ2&l5#svC1%@kKlFYOPp#S#H10_j z%ey`%p?T+9;QvkoxATrLzsa332&0w(79!#!%;28-t&&dDWx1-!LvCo?*=cVaYkx+I6RwvPl2Mz%}-19R-r;QV*7vTe)icM*j+ z6)wC7%IuJxq}@$w6$O)E~Nu{ZgWu!{ZT70Cp-Mygf)QE$4 z2s#8My$x*0M65$-D+s7@F$+m}HhGX?l6~Ak|7vDjz!PsmK+}__So%<7l`DD>fDCIH z8e)Jw%?FK=TF=d%3HBN^pW>X{d!aRlE*Udsrpe@ET`n(whFBV8!$ef@mcigoT4z9y zt11ECtv~>BgSqx(j*U(rQ4~%G_W=b}&QTu)FYB+($7<|2q#K6b5@j9&&IH3bgQqPc zcA&@Bvhb6>AIA@Q9rQ6Oq0Y)){p1P2buD03NTPTkRc2=Er%gMwXjA-)`d1hkXUJtU z#)x-Wqfe?Mt)|=JK`=*gpe)qL4o=7nEj*QE*u^mFm8mL!b1~EOnW&3;6l@|+m~~0= zup)L|Of0hPaR1|A%Mc9gW%%|Eh{De9eRl=ipY)+W@>YJ={VY{)Q1YH&imyM$aSPkq zyj$6~Mk^%jyk7)twe;h}!r`_^@RJyk#z4<<_C4>x&N0GM=i&f}CHlup)OI72k(!{^ zS8N6zXD-*u69hWbdeYMIbhU}zBG3rE6~?sx11Y}m*rE6|IYjSm)Ki+3W@QmWU-iyc zp@9cdjPqpTqdDdeIl`|gCCihrVz@Py#&B zBK}U!7gQ@*2`@i(Oz8OGq7KWqZ{44op61iePp#U}eOE?{lRAa9k&KLOG4I_>dyIpx z7w06lGb;I^MHL^?=e~PN)Ghuv?oVh=0YCdy;Z;DjC#zwzA4&YNd^hkYrV;>!iyE*` zMa!Tr#2T!TQEbQG5hb+3h_*@9fZLb`AKAD0kx55i^X3YAn&IQRmdTw0;{2&42=mtb zJc<$g(zof(+zhKS>5X;LIgkMLVS?XVL)t!>=>udxKwFp>0a8KI%svdZS-_5+)q@_~W(jqayX60m8u#WWb#nb&7$WPTD^erA!~zWdr5 zhXE(}F)7Xn>O{xbPNAZvRN3m2a!Y@hNW0NnhkrX2i|)?uWKz&wd;kO(e9U$xlPg2P zB0EQvx`G}Fo8|zF+BCZ)E<<1Sxz6MQEJ<_E``ej;1|C4ez)$s_=!vlsPhAY}e(Qx@ zFbiU93uI@B*#@%&e{{6mUo!|>Eh?%2x;J4^99f~ZuC51upqj{MTE{JvlX%!a6P{Z9 z#GdDAwinewV{u?Z+SQA6-$W)Yw15J~aHn8o*V(_M$&~z>+fp{s3Nh|t`|XM--S)B3%RGx>tHf<6 z)g5$Tpw`QWEVK1wOBjU}^kTcpwPWpG_+9y7MWhcUUz6_dGi!xcK<5HUVNuEljI}{i zB#f>=pgq^r#RO(A|J58j>aa+U^ZPwQJCpaZ+F*tZ!a_-pfN zY5i#mJ;k>E_XQtjK*o#xDOVHU<-F^?Vw%~|l5gep6 z5&iCqY?Q*QlSHh_Y99UqD(G9-o9}r58W3CR&vG_ktuK!W3ue-!KeS%!6@}KWJC48y giLlbD?3du$IMk23MD+EeZ|&DCACFU1$3TDp02cv?f&c&j literal 0 HcmV?d00001 diff --git a/pkg/lib/mill/testdata/images.go b/pkg/lib/mill/testdata/images.go index cbfa7f972..3a7d23ca7 100644 --- a/pkg/lib/mill/testdata/images.go +++ b/pkg/lib/mill/testdata/images.go @@ -44,4 +44,11 @@ var Images = []TestImage{ Width: 300, Height: 187, }, + { + Path: "testdata/image.webp", + Format: "webp", + HasExif: true, + Width: 320, + Height: 214, + }, } From 66d41bf5e218d315bd143adbe99109faa21b0867 Mon Sep 17 00:00:00 2001 From: kirillston Date: Fri, 23 Dec 2022 18:31:16 +0100 Subject: [PATCH 45/68] GO-230 Fix lint 1 --- pkg/lib/mill/image_resize.go | 24 ++++++++++-------------- pkg/lib/mill/image_resize_test.go | 9 ++++----- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/pkg/lib/mill/image_resize.go b/pkg/lib/mill/image_resize.go index 08a269fae..0bc092029 100644 --- a/pkg/lib/mill/image_resize.go +++ b/pkg/lib/mill/image_resize.go @@ -3,11 +3,6 @@ package mill import ( "bytes" "fmt" - "github.com/chai2010/webp" - "github.com/disintegration/imaging" - "github.com/dsoprea/go-exif/v3" - jpegstructure "github.com/dsoprea/go-jpeg-image-structure/v2" - _ "golang.org/x/image/webp" "image" "image/color/palette" "image/draw" @@ -18,6 +13,12 @@ import ( "strconv" "github.com/anytypeio/go-anytype-middleware/pkg/lib/mill/ico" + "github.com/chai2010/webp" + "github.com/disintegration/imaging" + "github.com/dsoprea/go-exif/v3" + jpegstructure "github.com/dsoprea/go-jpeg-image-structure/v2" + // Import for image.DecodeConfig to support .webp format + _ "golang.org/x/image/webp" ) // Format enumerates the type of images currently supported @@ -167,19 +168,14 @@ func (m *ImageResize) Mill(r io.ReadSeeker, name string) (*Result, error) { if format == JPEG && img == nil { // we already have img decoded if we have orientation <= 1 img, err = jpeg.Decode(r) - if err != nil { - return nil, err - } } else if format == WEBP { img, err = webp.Decode(r) - if err != nil { - return nil, err - } } else if format != JPEG { img, err = png.Decode(r) - if err != nil { - return nil, err - } + } + + if err != nil { + return nil, err } resized := imaging.Resize(img, width, 0, imaging.Lanczos) diff --git a/pkg/lib/mill/image_resize_test.go b/pkg/lib/mill/image_resize_test.go index 516d68853..444281015 100644 --- a/pkg/lib/mill/image_resize_test.go +++ b/pkg/lib/mill/image_resize_test.go @@ -3,9 +3,6 @@ package mill import ( "bytes" "fmt" - "github.com/davecgh/go-spew/spew" - exif2 "github.com/dsoprea/go-exif/v3" - "github.com/stretchr/testify/require" "image" "image/jpeg" "io" @@ -13,9 +10,11 @@ import ( "os" "testing" - "github.com/rwcarlsen/goexif/exif" - "github.com/anytypeio/go-anytype-middleware/pkg/lib/mill/testdata" + "github.com/davecgh/go-spew/spew" + exif2 "github.com/dsoprea/go-exif/v3" + "github.com/rwcarlsen/goexif/exif" + "github.com/stretchr/testify/require" ) var errFailedToFindExifMarker = fmt.Errorf("exif: failed to find exif intro marker") From 1f53e25eeff9c8142a3345fdfd7318b68cb85f02 Mon Sep 17 00:00:00 2001 From: kirillston Date: Fri, 23 Dec 2022 19:05:32 +0100 Subject: [PATCH 46/68] GO-230 Fix lint 2 --- pkg/lib/mill/image_resize.go | 20 ++++++++++---------- pkg/lib/mill/image_resize_test.go | 3 ++- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/pkg/lib/mill/image_resize.go b/pkg/lib/mill/image_resize.go index 0bc092029..ab4b851fc 100644 --- a/pkg/lib/mill/image_resize.go +++ b/pkg/lib/mill/image_resize.go @@ -12,11 +12,13 @@ import ( "io" "strconv" - "github.com/anytypeio/go-anytype-middleware/pkg/lib/mill/ico" "github.com/chai2010/webp" "github.com/disintegration/imaging" "github.com/dsoprea/go-exif/v3" jpegstructure "github.com/dsoprea/go-jpeg-image-structure/v2" + + "github.com/anytypeio/go-anytype-middleware/pkg/lib/mill/ico" + // Import for image.DecodeConfig to support .webp format _ "golang.org/x/image/webp" ) @@ -183,17 +185,15 @@ func (m *ImageResize) Mill(r io.ReadSeeker, name string) (*Result, error) { buff := &bytes.Buffer{} if format == JPEG { - if err = jpeg.Encode(buff, resized, &jpeg.Options{Quality: quality}); err != nil { - return nil, err - } + err = jpeg.Encode(buff, resized, &jpeg.Options{Quality: quality}) } else if format == WEBP { - if err = webp.Encode(buff, resized, &webp.Options{Quality: float32(quality)}); err != nil { - return nil, err - } + err = webp.Encode(buff, resized, &webp.Options{Quality: float32(quality)}) } else { - if err = png.Encode(buff, resized); err != nil { - return nil, err - } + err = png.Encode(buff, resized) + } + + if err != nil { + return nil, err } return &Result{ diff --git a/pkg/lib/mill/image_resize_test.go b/pkg/lib/mill/image_resize_test.go index 444281015..c56faeaae 100644 --- a/pkg/lib/mill/image_resize_test.go +++ b/pkg/lib/mill/image_resize_test.go @@ -10,11 +10,12 @@ import ( "os" "testing" - "github.com/anytypeio/go-anytype-middleware/pkg/lib/mill/testdata" "github.com/davecgh/go-spew/spew" exif2 "github.com/dsoprea/go-exif/v3" "github.com/rwcarlsen/goexif/exif" "github.com/stretchr/testify/require" + + "github.com/anytypeio/go-anytype-middleware/pkg/lib/mill/testdata" ) var errFailedToFindExifMarker = fmt.Errorf("exif: failed to find exif intro marker") From 08e27f01a6a7ef6ac869f5e9c250dfb2e017f8c2 Mon Sep 17 00:00:00 2001 From: kirillston Date: Fri, 23 Dec 2022 19:32:38 +0100 Subject: [PATCH 47/68] GO-230 Fix lint 3 --- pkg/lib/mill/image_resize.go | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/pkg/lib/mill/image_resize.go b/pkg/lib/mill/image_resize.go index ab4b851fc..934d7ba57 100644 --- a/pkg/lib/mill/image_resize.go +++ b/pkg/lib/mill/image_resize.go @@ -3,6 +3,7 @@ package mill import ( "bytes" "fmt" + "golang.org/x/exp/slices" "image" "image/color/palette" "image/draw" @@ -166,13 +167,14 @@ func (m *ImageResize) Mill(r io.ReadSeeker, name string) (*Result, error) { }, nil } - if format == JPEG || format == PNG || format == ICO || format == WEBP { - if format == JPEG && img == nil { + if slices.Contains([]Format{JPEG, PNG, ICO, WEBP}, format) { + switch { + case format == JPEG && img == nil: // we already have img decoded if we have orientation <= 1 img, err = jpeg.Decode(r) - } else if format == WEBP { + case format == WEBP: img, err = webp.Decode(r) - } else if format != JPEG { + case format != JPEG: img, err = png.Decode(r) } @@ -184,11 +186,12 @@ func (m *ImageResize) Mill(r io.ReadSeeker, name string) (*Result, error) { width, height = resized.Rect.Max.X, resized.Rect.Max.Y buff := &bytes.Buffer{} - if format == JPEG { + switch format { + case JPEG: err = jpeg.Encode(buff, resized, &jpeg.Options{Quality: quality}) - } else if format == WEBP { + case WEBP: err = webp.Encode(buff, resized, &webp.Options{Quality: float32(quality)}) - } else { + default: err = png.Encode(buff, resized) } From b75ceee3b406906ecdffe1ac9cca322db7561b4b Mon Sep 17 00:00:00 2001 From: kirillston Date: Fri, 23 Dec 2022 19:42:39 +0100 Subject: [PATCH 48/68] GO-230 Fix lint 4 --- pkg/lib/mill/image_resize.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/lib/mill/image_resize.go b/pkg/lib/mill/image_resize.go index 934d7ba57..fb3457ac1 100644 --- a/pkg/lib/mill/image_resize.go +++ b/pkg/lib/mill/image_resize.go @@ -206,7 +206,9 @@ func (m *ImageResize) Mill(r io.ReadSeeker, name string) (*Result, error) { "height": height, }, }, nil - } else if format == GIF { + } + + if format == GIF { gifImg, err := gif.DecodeAll(r) if err != nil { return nil, err From 9d73e2add0dd4b352b9b9d8b4f423ceef289b57b Mon Sep 17 00:00:00 2001 From: kirillston Date: Fri, 23 Dec 2022 19:47:06 +0100 Subject: [PATCH 49/68] GO-230 Fix lint 5 gci returns... --- pkg/lib/mill/image_resize.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/lib/mill/image_resize.go b/pkg/lib/mill/image_resize.go index fb3457ac1..40f7b95d8 100644 --- a/pkg/lib/mill/image_resize.go +++ b/pkg/lib/mill/image_resize.go @@ -3,7 +3,6 @@ package mill import ( "bytes" "fmt" - "golang.org/x/exp/slices" "image" "image/color/palette" "image/draw" @@ -17,6 +16,7 @@ import ( "github.com/disintegration/imaging" "github.com/dsoprea/go-exif/v3" jpegstructure "github.com/dsoprea/go-jpeg-image-structure/v2" + "golang.org/x/exp/slices" "github.com/anytypeio/go-anytype-middleware/pkg/lib/mill/ico" From e5b48b4f80c77536326a0ec07a68d999af912882 Mon Sep 17 00:00:00 2001 From: Sergey Date: Wed, 28 Dec 2022 18:44:19 +0500 Subject: [PATCH 50/68] Add missing source to ObjectCreateSet --- core/relations.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/relations.go b/core/relations.go index f52015956..69b3985d4 100644 --- a/core/relations.go +++ b/core/relations.go @@ -178,6 +178,13 @@ func (mw *Middleware) ObjectCreateSet(cctx context.Context, req *pb.RpcObjectCre ) err := mw.doBlockService(func(bs *block.Service) error { var err error + if req.Details == nil { + req.Details = &types.Struct{} + } + if req.Details.Fields == nil { + req.Details.Fields = map[string]*types.Value{} + } + req.Details.Fields[bundle.RelationKeySetOf.String()] = pbtypes.StringList(req.Source) id, newDetails, err = bs.CreateObject(req, bundle.TypeKeySet) return err }) From 9e88b38f63ed84728d15e40016871c27433c84a8 Mon Sep 17 00:00:00 2001 From: Sergey Date: Wed, 28 Dec 2022 19:40:11 +0500 Subject: [PATCH 51/68] GO-707 Fix CreateSet --- core/block/object/creator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/block/object/creator.go b/core/block/object/creator.go index 26bc65a05..f08094147 100644 --- a/core/block/object/creator.go +++ b/core/block/object/creator.go @@ -251,7 +251,7 @@ func (c *Creator) CreateSet(req *pb.RpcObjectCreateSetRequest) (setID string, ne } // TODO: here can be a deadlock if this is somehow created from workspace (as set) - return c.CreateSmartBlockFromState(context.TODO(), coresb.SmartBlockTypeSet, req.Details, nil, newState) + return c.CreateSmartBlockFromState(context.TODO(), coresb.SmartBlockTypeSet, nil, nil, newState) } // TODO: it must be in another component From 62f18d45179ee72781ba1071547d07b8125f095a Mon Sep 17 00:00:00 2001 From: Roman Khafizianov Date: Tue, 3 Jan 2023 14:29:32 +0100 Subject: [PATCH 52/68] optimize ObjectGraph do not query each relation separately --- core/object.go | 14 ++++++++---- core/relation/service.go | 41 ++++++++++++++++++++++++++++++++++++ pkg/lib/database/database.go | 1 - 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/core/object.go b/core/object.go index fcd415545..09d4b33ce 100644 --- a/core/object.go +++ b/core/object.go @@ -15,6 +15,7 @@ import ( "github.com/anytypeio/go-anytype-middleware/core/block" importer "github.com/anytypeio/go-anytype-middleware/core/block/import" "github.com/anytypeio/go-anytype-middleware/core/indexer" + "github.com/anytypeio/go-anytype-middleware/core/relation" "github.com/anytypeio/go-anytype-middleware/core/subscription" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle" @@ -397,12 +398,19 @@ func (mw *Middleware) ObjectGraph(cctx context.Context, req *pb.RpcObjectGraphRe } at := mw.app.MustComponent(core.CName).(core.Service) + rs := mw.app.MustComponent(relation.CName).(relation.Service) records, _, err := at.ObjectStore().Query(nil, database.Query{ Filters: req.Filters, Limit: int(req.Limit), ObjectTypeFilter: req.ObjectTypeFilter, }) + + if err != nil { + return response(pb.RpcObjectGraphResponseError_UNKNOWN_ERROR, nil, nil, err) + } + + relations, err := rs.ListAll(relation.WithWorkspaceId(at.PredefinedBlocks().Account)) if err != nil { return response(pb.RpcObjectGraphResponseError_UNKNOWN_ERROR, nil, nil, err) } @@ -440,10 +448,8 @@ func (mw *Middleware) ObjectGraph(cctx context.Context, req *pb.RpcObjectGraphRe if list := pbtypes.GetStringListValue(v); len(list) == 0 { continue } else { - - rel, err := at.ObjectStore().GetRelationByKey(k) - if err != nil { - log.Errorf("ObjectGraph failed to get relation %s: %s", k, err.Error()) + rel := relations.GetByKey(k) + if rel == nil { continue } diff --git a/core/relation/service.go b/core/relation/service.go index b63da082e..361aab8d8 100644 --- a/core/relation/service.go +++ b/core/relation/service.go @@ -39,6 +39,8 @@ func New() Service { type Service interface { FetchKeys(keys ...string) (relations relationutils.Relations, err error) FetchKey(key string, opts ...FetchOption) (relation *relationutils.Relation, err error) + ListAll(opts ...FetchOption) (relations relationutils.Relations, err error) + FetchLinks(links pbtypes.RelationLinks) (relations relationutils.Relations, err error) CreateBulkMigration() BulkMigration MigrateRelations(relations []*model.Relation) error @@ -212,6 +214,45 @@ func (s *service) fetchKeys(keys ...string) (relations []*relationutils.Relation return } +func (s *service) ListAll(opts ...FetchOption) (relations relationutils.Relations, err error) { + s.mu.RLock() + defer s.mu.RUnlock() + return s.listAll(opts...) +} + +func (s *service) listAll(opts ...FetchOption) (relations relationutils.Relations, err error) { + filters := []*model.BlockContentDataviewFilter{ + { + RelationKey: bundle.RelationKeyType.String(), + Condition: model.BlockContentDataviewFilter_Equal, + Value: pbtypes.String(bundle.TypeKeyRelation.URL()), + }, + } + o := &fetchOptions{} + for _, apply := range opts { + apply(o) + } + if o.workspaceId != nil { + filters = append(filters, &model.BlockContentDataviewFilter{ + RelationKey: bundle.RelationKeyWorkspaceId.String(), + Condition: model.BlockContentDataviewFilter_Equal, + Value: pbtypes.String(*o.workspaceId), + }) + } + + relations2, _, err := s.objectStore.Query(nil, database.Query{ + Filters: filters, + }) + if err != nil { + return + } + + for _, rec := range relations2 { + relations = append(relations, relationutils.RelationFromStruct(rec.Details)) + } + return +} + type fetchOptions struct { workspaceId *string } diff --git a/pkg/lib/database/database.go b/pkg/lib/database/database.go index 6fbb54cff..9ce31457e 100644 --- a/pkg/lib/database/database.go +++ b/pkg/lib/database/database.go @@ -80,7 +80,6 @@ type Query struct { WithSystemObjects bool ObjectTypeFilter []string WorkspaceId string - SearchInWorkspace bool } func (q Query) DSQuery(sch schema.Schema) (qq query.Query, err error) { From b52765c47565ade0d953e44b14c2c9a1a9f713ed Mon Sep 17 00:00:00 2001 From: Roman Khafizianov Date: Tue, 3 Jan 2023 16:18:32 +0100 Subject: [PATCH 53/68] add an optimisation to updateHeads do not iterate over the whole tree if we add 1 change to the top and it points to the current head --- change/tree.go | 49 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/change/tree.go b/change/tree.go index 1dbcb7641..40e656b59 100644 --- a/change/tree.go +++ b/change/tree.go @@ -6,6 +6,7 @@ import ( "crypto/md5" "fmt" "sort" + "time" "github.com/anytypeio/go-anytype-middleware/util/slice" ) @@ -64,7 +65,7 @@ func (t *Tree) AddFast(changes ...*Change) { } t.add(c) } - t.updateHeads() + t.updateHeads(changes) } func (t *Tree) Add(changes ...*Change) (mode Mode) { @@ -85,7 +86,7 @@ func (t *Tree) Add(changes ...*Change) (mode Mode) { if !attached { return Nothing } - t.updateHeads() + t.updateHeads(changes) if empty { return Rebuild } @@ -184,20 +185,40 @@ func (t *Tree) after(id1, id2 string) (found bool) { return } -func (t *Tree) updateHeads() { +func (t *Tree) updateHeads(chs []*Change) { var newHeadIds, newMetaHeadIds []string - t.iterate(t.root, func(c *Change) (isContinue bool) { - if len(c.Next) == 0 { - newHeadIds = append(newHeadIds, c.Id) - } - if c.HasMeta() { - for _, prevDetId := range c.PreviousMetaIds { - newMetaHeadIds = slice.Remove(newMetaHeadIds, prevDetId) + if len(chs) == 1 && slice.UnsortedEquals(chs[0].PreviousIds, t.headIds) { + // shortcut when adding to the top of the tree + // only cover edge case when adding one change, otherwise it's not worth it + newHeadIds = []string{chs[0].Id} + } + if len(chs) == 1 && chs[0].HasMeta() && slice.UnsortedEquals(chs[0].PreviousMetaIds, t.metaHeadIds) { + // shortcut when adding to the top of the tree + // only cover edge case when adding one change, otherwise it's not worth it + newMetaHeadIds = []string{chs[0].Id} + } + + total := 0 + start := time.Now() + if len(newHeadIds) == 0 { + // otherwise do the full iterate to make sure we have the correct changes order + t.iterate(t.root, func(c *Change) (isContinue bool) { + total++ + if len(c.Next) == 0 { + newHeadIds = append(newHeadIds, c.Id) } - newMetaHeadIds = append(newMetaHeadIds, c.Id) - } - return true - }) + if c.HasMeta() { + for _, prevDetId := range c.PreviousMetaIds { + newMetaHeadIds = slice.Remove(newMetaHeadIds, prevDetId) + } + newMetaHeadIds = append(newMetaHeadIds, c.Id) + } + return true + }) + } + if time.Since(start) > time.Millisecond*100 { + log.Errorf("updateHeads took %s for %d changes", time.Since(start), total) + } t.headIds = newHeadIds t.metaHeadIds = newMetaHeadIds sort.Strings(t.headIds) From e464132bd5690747f2550421c9292390b9bb4f14 Mon Sep 17 00:00:00 2001 From: Roman Khafizianov Date: Tue, 3 Jan 2023 18:22:31 +0100 Subject: [PATCH 54/68] updateHeads: extract recalculateHeads --- change/tree.go | 56 +++++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/change/tree.go b/change/tree.go index 40e656b59..2f2a75355 100644 --- a/change/tree.go +++ b/change/tree.go @@ -185,6 +185,29 @@ func (t *Tree) after(id1, id2 string) (found bool) { return } +func (t *Tree) recalculateHeads() (heads []string, metaHeads []string) { + start := time.Now() + total := 0 + t.iterate(t.root, func(c *Change) (isContinue bool) { + total++ + if len(c.Next) == 0 { + heads = append(heads, c.Id) + } + if c.HasMeta() { + for _, prevDetId := range c.PreviousMetaIds { + metaHeads = slice.Remove(metaHeads, prevDetId) + } + metaHeads = append(metaHeads, c.Id) + } + return true + }) + if time.Since(start) > time.Millisecond*100 { + log.Errorf("recalculateHeads took %s for %d changes", time.Since(start), total) + } + + return +} + func (t *Tree) updateHeads(chs []*Change) { var newHeadIds, newMetaHeadIds []string if len(chs) == 1 && slice.UnsortedEquals(chs[0].PreviousIds, t.headIds) { @@ -198,31 +221,18 @@ func (t *Tree) updateHeads(chs []*Change) { newMetaHeadIds = []string{chs[0].Id} } - total := 0 - start := time.Now() - if len(newHeadIds) == 0 { - // otherwise do the full iterate to make sure we have the correct changes order - t.iterate(t.root, func(c *Change) (isContinue bool) { - total++ - if len(c.Next) == 0 { - newHeadIds = append(newHeadIds, c.Id) - } - if c.HasMeta() { - for _, prevDetId := range c.PreviousMetaIds { - newMetaHeadIds = slice.Remove(newMetaHeadIds, prevDetId) - } - newMetaHeadIds = append(newMetaHeadIds, c.Id) - } - return true - }) + if newHeadIds == nil { + newHeadIds, newMetaHeadIds = t.recalculateHeads() } - if time.Since(start) > time.Millisecond*100 { - log.Errorf("updateHeads took %s for %d changes", time.Since(start), total) + if newHeadIds != nil { + t.headIds = newHeadIds + sort.Strings(t.headIds) + } + + if newMetaHeadIds != nil { + t.metaHeadIds = newMetaHeadIds + sort.Strings(t.metaHeadIds) } - t.headIds = newHeadIds - t.metaHeadIds = newMetaHeadIds - sort.Strings(t.headIds) - sort.Strings(t.metaHeadIds) } func (t *Tree) iterate(start *Change, f func(c *Change) (isContinue bool)) { From cae76743b8f71446f8bb20695a2a4ed983392718 Mon Sep 17 00:00:00 2001 From: Roman Khafizianov Date: Wed, 4 Jan 2023 16:45:24 +0100 Subject: [PATCH 55/68] improve needSnapshot probability to depend on the number of changes after the last snapshot --- change/change_test.go | 4 ++-- change/state.go | 11 +++++---- change/state_test.go | 4 ++-- core/block/source/source.go | 36 ++++++++++++++++++++++++++---- core/block/source/source_test.go | 37 +++++++++++++++++++++++++++++++ core/debug/debugtree/debugtree.go | 2 +- core/history/history.go | 2 +- 7 files changed, 80 insertions(+), 16 deletions(-) create mode 100644 core/block/source/source_test.go diff --git a/change/change_test.go b/change/change_test.go index 1f28b3fa5..3101b9dc9 100644 --- a/change/change_test.go +++ b/change/change_test.go @@ -88,7 +88,7 @@ func Test_Issue605Tree(t *testing.T) { } doc := state.NewDocFromSnapshot("bafyba6akblqzapgdmlu3swkrsb62mgrvgdv2g72eqvtufuis4vxhgcgl", root.GetSnapshot()).(*state.State) doc.SetChangeId(root.Id) - st, err := BuildStateSimpleCRDT(doc, tree) + st, _, err := BuildStateSimpleCRDT(doc, tree) if err != nil { return } @@ -132,7 +132,7 @@ func Test_Home_ecz5pu(t *testing.T) { doc := state.NewDocFromSnapshot("", root.GetSnapshot()).(*state.State) doc.SetChangeId(root.Id) doc.RootId() - st, err := BuildStateSimpleCRDT(doc, tree) + st, _, err := BuildStateSimpleCRDT(doc, tree) if err != nil { return } diff --git a/change/state.go b/change/state.go index 7e2810d6b..28151b6ed 100644 --- a/change/state.go +++ b/change/state.go @@ -42,13 +42,12 @@ func (sc *stateCache) Get(id string) *state.State { } // Simple implementation hopes for CRDT and ignores errors. No merge -func BuildStateSimpleCRDT(root *state.State, t *Tree) (s *state.State, err error) { +func BuildStateSimpleCRDT(root *state.State, t *Tree) (s *state.State, changesApplied int, err error) { var ( startId string applyRoot bool st = time.Now() lastChange *Change - count int ) if startId = root.ChangeId(); startId == "" { startId = t.RootId() @@ -56,7 +55,7 @@ func BuildStateSimpleCRDT(root *state.State, t *Tree) (s *state.State, err error } t.Iterate(startId, func(c *Change) (isContinue bool) { - count++ + changesApplied++ lastChange = c if startId == c.Id { s = root.NewState() @@ -78,14 +77,14 @@ func BuildStateSimpleCRDT(root *state.State, t *Tree) (s *state.State, err error return true }) if err != nil { - return nil, err + return nil, changesApplied, err } if lastChange != nil { s.SetLastModified(lastChange.Timestamp, lastChange.Account) } - log.Infof("build state (crdt): changes: %d; dur: %v;", count, time.Since(st)) - return s, err + log.Infof("build state (crdt): changes: %d; dur: %v;", changesApplied, time.Since(st)) + return s, changesApplied, err } // Full version found parallel branches and proposes to resolve conflicts diff --git a/change/state_test.go b/change/state_test.go index fe94c2de6..547e43e9a 100644 --- a/change/state_test.go +++ b/change/state_test.go @@ -43,7 +43,7 @@ func BenchmarkOpenDoc(b *testing.B) { root := tree.Root() doc := state.NewDocFromSnapshot("bafybapt3aap3tmkbs7mkj5jao3vhjblijkiwqq37wxlylx5nn7cqokgk", root.GetSnapshot()).(*state.State) doc.SetChangeId(root.Id) - _, err = BuildStateSimpleCRDT(doc, tree) + _, _, err = BuildStateSimpleCRDT(doc, tree) require.NoError(b, err) b.Log("build state:", time.Since(st)) @@ -57,7 +57,7 @@ func BenchmarkOpenDoc(b *testing.B) { for i := 0; i < b.N; i++ { doc := state.NewDocFromSnapshot("bafybapt3aap3tmkbs7mkj5jao3vhjblijkiwqq37wxlylx5nn7cqokgk", root.GetSnapshot()).(*state.State) doc.SetChangeId(root.Id) - _, err := BuildStateSimpleCRDT(doc, tree) + _, _, err := BuildStateSimpleCRDT(doc, tree) require.NoError(b, err) } }) diff --git a/core/block/source/source.go b/core/block/source/source.go index a2329b982..9bd7e487b 100644 --- a/core/block/source/source.go +++ b/core/block/source/source.go @@ -136,6 +136,7 @@ type source struct { sb core.SmartBlock tree *change.Tree lastSnapshotId string + changesSinceSnapshot int logHeads map[string]*change.Change receiver ChangeReceiver unsubscribe func() @@ -314,10 +315,11 @@ func (s *source) buildState() (doc state.Doc, err error) { s.lastSnapshotId = root.Id doc = state.NewDocFromSnapshot(s.id, root.GetSnapshot()).(*state.State) doc.(*state.State).SetChangeId(root.Id) - st, err := change.BuildStateSimpleCRDT(doc.(*state.State), s.tree) + st, changesApplied, err := change.BuildStateSimpleCRDT(doc.(*state.State), s.tree) if err != nil { return } + s.changesSinceSnapshot = changesApplied if s.sb.Type() != smartblock.SmartBlockTypeArchive && !s.Virtual() { if verr := st.Validate(); verr != nil { @@ -418,8 +420,10 @@ func (s *source) PushChange(params PushChangeParams) (id string, err error) { s.logHeads[s.logId] = ch if c.Snapshot != nil { s.lastSnapshotId = id + s.changesSinceSnapshot = 0 log.Infof("%s: pushed snapshot", s.id) } else { + s.changesSinceSnapshot++ log.Debugf("%s: pushed %d changes", s.id, len(ch.Content)) } return @@ -444,13 +448,31 @@ func (v *source) ListIds() ([]string, error) { return ids, nil } +func snapshotChance(changesSinceSnapshot int) bool { + v := 2000 + if changesSinceSnapshot <= 100 { + return false + } + + d := changesSinceSnapshot/50 + 1 + + min := (v / 2) - d + max := (v / 2) + d + + r := rand.Intn(v) + if r >= min && r <= max { + return true + } + + return false +} + func (s *source) needSnapshot() bool { if s.tree.Len() == 0 { // starting tree with snapshot return true } - // TODO: think about a more smart way - return rand.Intn(500) == 42 + return snapshotChance(s.changesSinceSnapshot) } func (s *source) changeListener(batch *mb.MB) { @@ -515,11 +537,17 @@ func (s *source) applyRecords(records []core.SmartblockRecordEnvelope) error { case change.Append: changesContent := make([]*pb.ChangeContent, 0, len(changes)) for _, ch := range changes { + if ch.Snapshot != nil { + s.changesSinceSnapshot = 0 + } else { + s.changesSinceSnapshot++ + } changesContent = append(changesContent, ch.Content...) } s.lastSnapshotId = s.tree.LastSnapshotId(context.TODO()) return s.receiver.StateAppend(func(d state.Doc) (*state.State, error) { - return change.BuildStateSimpleCRDT(d.(*state.State), s.tree) + st, _, err := change.BuildStateSimpleCRDT(d.(*state.State), s.tree) + return st, err }, changesContent) case change.Rebuild: s.lastSnapshotId = s.tree.LastSnapshotId(context.TODO()) diff --git a/core/block/source/source_test.go b/core/block/source/source_test.go new file mode 100644 index 000000000..f3224db4f --- /dev/null +++ b/core/block/source/source_test.go @@ -0,0 +1,37 @@ +package source + +import ( + "fmt" + "testing" +) + +func Test_snapshotChance(t *testing.T) { + return + for i := 0; i <= 500; i++ { + for s := 0; s <= 10000; s++ { + if snapshotChance(s) { + fmt.Println(s) + break + } + } + } + fmt.Println() + // here is an example of distribution histogram + // https://docs.google.com/spreadsheets/d/1xgH7fUxno5Rm-0VEaSD4LsTHeGeUXQFmHsOm29M6paI +} + +func Test_snapshotChance2(t *testing.T) { + return + for s := 0; s <= 10000; s++ { + total := 0 + for i := 0; i <= 50000; i++ { + if snapshotChance(s) { + total++ + } + } + fmt.Printf("%d\t%.5f\n", s, float64(total)/50000) + } + + // here is an example of distribution histogram + // https://docs.google.com/spreadsheets/d/1xgH7fUxno5Rm-0VEaSD4LsTHeGeUXQFmHsOm29M6paI +} diff --git a/core/debug/debugtree/debugtree.go b/core/debug/debugtree/debugtree.go index c0d68f42f..8ba0671b2 100644 --- a/core/debug/debugtree/debugtree.go +++ b/core/debug/debugtree/debugtree.go @@ -213,7 +213,7 @@ func (r *debugTree) BuildStateByTree(t *change.Tree) (*state.State, error) { } s := state.NewDocFromSnapshot("", root.GetSnapshot()).(*state.State) s.SetChangeId(root.Id) - st, err := change.BuildStateSimpleCRDT(s, t) + st, _, err := change.BuildStateSimpleCRDT(s, t) if err != nil { return nil, err } diff --git a/core/history/history.go b/core/history/history.go index f351842db..07d975021 100644 --- a/core/history/history.go +++ b/core/history/history.go @@ -221,7 +221,7 @@ func (h *history) buildState(pageId, versionId string) (s *state.State, ver *pb. } s = state.NewDocFromSnapshot(pageId, root.GetSnapshot()).(*state.State) s.SetChangeId(root.Id) - st, err := change.BuildStateSimpleCRDT(s, tree) + st, _, err := change.BuildStateSimpleCRDT(s, tree) if err != nil { return } From 5f54767fcffc6980e20f5c9bdc9430de61f51e53 Mon Sep 17 00:00:00 2001 From: Roman Khafizianov Date: Wed, 4 Jan 2023 17:05:02 +0100 Subject: [PATCH 56/68] fix linter --- core/block/source/source_test.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/core/block/source/source_test.go b/core/block/source/source_test.go index f3224db4f..716e32fe8 100644 --- a/core/block/source/source_test.go +++ b/core/block/source/source_test.go @@ -2,11 +2,15 @@ package source import ( "fmt" + "os" "testing" ) func Test_snapshotChance(t *testing.T) { - return + if os.Getenv("ANYTYPE_TEST_SNAPSHOT_CHANCE") == "" { + t.Skip() + return + } for i := 0; i <= 500; i++ { for s := 0; s <= 10000; s++ { if snapshotChance(s) { @@ -21,7 +25,10 @@ func Test_snapshotChance(t *testing.T) { } func Test_snapshotChance2(t *testing.T) { - return + if os.Getenv("ANYTYPE_TEST_SNAPSHOT_CHANCE") == "" { + t.Skip() + return + } for s := 0; s <= 10000; s++ { total := 0 for i := 0; i <= 50000; i++ { From 1613c5501d35c7f615a6e85b284f8b31fbde23ac Mon Sep 17 00:00:00 2001 From: Roman Khafizianov Date: Thu, 5 Jan 2023 18:06:41 +0100 Subject: [PATCH 57/68] threadDb listenToChanges: check if chan closed --- core/block/source/threaddb.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/block/source/threaddb.go b/core/block/source/threaddb.go index 588ab259d..84df3e2b6 100644 --- a/core/block/source/threaddb.go +++ b/core/block/source/threaddb.go @@ -192,7 +192,11 @@ func (v *threadDB) listenToChanges() (err error) { // we don't have new messages for at least deadline and we have something to flush processBuffer() - case c := <-listenerCh: + case c, ok := <-listenerCh: + if !ok { + processBuffer() + return + } log.With("thread id", c.ID.String()). Debugf("received new thread through channel") // as per docs the timer should be stopped or expired with drained channel From 5e2ad9a2bdde90341d5690ff31a62a6fd0081d40 Mon Sep 17 00:00:00 2001 From: Roman Khafizianov Date: Fri, 6 Jan 2023 14:08:59 +0100 Subject: [PATCH 58/68] fix deadlock in Subscription --- pkg/lib/database/subscription.go | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/pkg/lib/database/subscription.go b/pkg/lib/database/subscription.go index 2a0cf5067..39ae47f84 100644 --- a/pkg/lib/database/subscription.go +++ b/pkg/lib/database/subscription.go @@ -9,10 +9,11 @@ import ( ) type subscription struct { - ids []string - quit chan struct{} - closed bool - ch chan *types.Struct + ids []string + quit chan struct{} + closed bool + closedOnce sync.Once + ch chan *types.Struct sync.RWMutex } @@ -29,21 +30,21 @@ func (sub *subscription) RecordChan() chan *types.Struct { } func (sub *subscription) Close() { - sub.Lock() - defer sub.Unlock() - if sub.closed { - return - } - - close(sub.quit) - close(sub.ch) - - sub.closed = true + sub.closedOnce.Do(func() { + close(sub.quit) + close(sub.ch) + sub.Lock() + sub.closed = true + sub.Unlock() + }) } func (sub *subscription) Subscribe(ids []string) (added []string) { sub.Lock() defer sub.Unlock() + if sub.closed { + return nil + } loop: for _, id := range ids { for _, idEx := range sub.ids { From ac9ed5197cb8324cf0b6bee8490e27a214cb28b6 Mon Sep 17 00:00:00 2001 From: Roman Khafizianov Date: Fri, 6 Jan 2023 17:08:43 +0100 Subject: [PATCH 59/68] GC installed relations alongside type removal --- core/block/editor/workspaces.go | 143 +++++++++++++++++++++++++++++++- core/block/service.go | 4 +- core/workspace.go | 3 +- 3 files changed, 146 insertions(+), 4 deletions(-) diff --git a/core/block/editor/workspaces.go b/core/block/editor/workspaces.go index f34190654..c1bd2dca0 100644 --- a/core/block/editor/workspaces.go +++ b/core/block/editor/workspaces.go @@ -841,14 +841,155 @@ func (w *Workspaces) CreateSubObjects(details []*types.Struct) (ids []string, ob return } -func (w *Workspaces) RemoveSubObjects(objectIds []string) (err error) { +// objectTypeRelationsForGC returns the list of relation IDs that are safe to remove alongside with the provided object type +// - they were installed from the marketplace(not custom by the user) +// - they are not used as recommended in other installed/custom object types +// - they are not used directly in some object +func (w *Workspaces) objectTypeRelationsForGC(objectTypeID string) (ids []string, err error) { + obj, err := w.objectStore.GetDetails(objectTypeID) + if err != nil { + return nil, err + } + + source := pbtypes.GetString(obj.Details, bundle.RelationKeySourceObject.String()) + if source == "" { + // type was not installed from marketplace + return nil, nil + } + + var skipIDs = map[string]struct{}{} + for _, rel := range bundle.SystemRelations { + skipIDs[addr.RelationKeyToIdPrefix+rel.String()] = struct{}{} + } + + relIds := pbtypes.GetStringList(obj.Details, bundle.RelationKeyRecommendedRelations.String()) + + // find relations that are custom(was not installed from somewhere) + records, _, err := w.objectStore.Query(nil, database2.Query{ + Filters: []*model.BlockContentDataviewFilter{ + { + RelationKey: bundle.RelationKeyId.String(), + Condition: model.BlockContentDataviewFilter_In, + Value: pbtypes.StringList(relIds), + }, + { + RelationKey: bundle.RelationKeySourceObject.String(), + Condition: model.BlockContentDataviewFilter_Empty, + }, + }, + }) + if err != nil { + return nil, err + } + + for _, rec := range records { + skipIDs[pbtypes.GetString(rec.Details, bundle.RelationKeyId.String())] = struct{}{} + } + + // check if this relation is used in some other installed object types + records, _, err = w.objectStore.Query(nil, database2.Query{ + Filters: []*model.BlockContentDataviewFilter{ + { + RelationKey: bundle.RelationKeyType.String(), + Condition: model.BlockContentDataviewFilter_Equal, + Value: pbtypes.String(bundle.TypeKeyObjectType.URL()), + }, + { + RelationKey: bundle.RelationKeyRecommendedRelations.String(), + Condition: model.BlockContentDataviewFilter_In, + Value: pbtypes.StringList(relIds), + }, + }, + }) + if err != nil { + return nil, err + } + + for _, rec := range records { + recId := pbtypes.GetString(rec.Details, bundle.RelationKeyId.String()) + if recId == objectTypeID { + continue + } + rels := pbtypes.GetStringList(rec.Details, bundle.RelationKeyRecommendedRelations.String()) + for _, rel := range rels { + if slice.FindPos(relIds, rel) > -1 { + skipIDs[rel] = struct{}{} + } + } + } + + for _, relId := range relIds { + if _, exists := skipIDs[relId]; exists { + continue + } + relKey, err := pbtypes.RelationIdToKey(relId) + if err != nil { + log.Errorf("failed to get relation key from id %s: %s", relId, err.Error()) + continue + } + records, _, err := w.objectStore.Query(nil, database2.Query{ + Limit: 1, + Filters: []*model.BlockContentDataviewFilter{ + { + // exclude installed templates that we don't remove yet and they may depend on the relation + RelationKey: bundle.RelationKeyTargetObjectType.String(), + Condition: model.BlockContentDataviewFilter_NotEqual, + Value: pbtypes.String(objectTypeID), + }, + { + RelationKey: bundle.RelationKeyWorkspaceId.String(), + Condition: model.BlockContentDataviewFilter_Equal, + Value: pbtypes.String(w.Id()), + }, + { + RelationKey: relKey, + Condition: model.BlockContentDataviewFilter_NotEmpty, + }, + }, + }) + if len(records) > 0 { + skipIDs[relId] = struct{}{} + } + } + return slice.Filter(relIds, func(s string) bool { + _, exists := skipIDs[s] + return !exists + }), nil +} + +// RemoveSubObjects removes sub objects from the workspace collection +// if allowGC is true, then relations that are not used by any object in the workspace will be removed as well +func (w *Workspaces) RemoveSubObjects(objectIds []string, allowDependentsGC bool) (err error) { st := w.NewState() + var idsToRemove []string for _, id := range objectIds { + // special case for object types + idsToRemove = nil + if strings.HasPrefix(id, addr.ObjectTypeKeyToIdPrefix) && allowDependentsGC { + idsToRemove, err = w.objectTypeRelationsForGC(id) + if err != nil { + log.Errorf("objectTypeRelationsForGC failed: %s", err.Error()) + continue + } + if len(idsToRemove) > 0 { + log.Debugf("objectTypeRelationsForGC, relations to remove: %v", idsToRemove) + } + } + err = w.removeObject(st, id) if err != nil { log.Errorf("failed to remove sub object: %s", err.Error()) continue } + if allowDependentsGC && len(idsToRemove) > 0 { + for _, relId := range idsToRemove { + err = w.removeObject(st, relId) + if err != nil { + log.Errorf("failed to remove dependent sub object: %s", err.Error()) + continue + } + } + } } // reset error in case we have at least 1 object created diff --git a/core/block/service.go b/core/block/service.go index c5d0f91d8..e9c31fc04 100644 --- a/core/block/service.go +++ b/core/block/service.go @@ -436,13 +436,13 @@ func (s *Service) AddSubObjectsToWorkspace( return } -func (s *Service) RemoveSubObjectsInWorkspace(objectIds []string, workspaceId string) (err error) { +func (s *Service) RemoveSubObjectsInWorkspace(objectIds []string, workspaceId string, allowDependentsGC bool) (err error) { err = s.Do(workspaceId, func(b smartblock.SmartBlock) error { ws, ok := b.(*editor.Workspaces) if !ok { return fmt.Errorf("incorrect workspace id") } - err = ws.RemoveSubObjects(objectIds) + err = ws.RemoveSubObjects(objectIds, allowDependentsGC) return err }) diff --git a/core/workspace.go b/core/workspace.go index fa4794a6e..943611ca5 100644 --- a/core/workspace.go +++ b/core/workspace.go @@ -184,7 +184,8 @@ func (mw *Middleware) WorkspaceObjectListRemove(cctx context.Context, req *pb.Rp ) err := mw.doBlockService(func(bs *block.Service) (err error) { - err = bs.RemoveSubObjectsInWorkspace(req.ObjectIds, mw.GetAnytype().PredefinedBlocks().Account) + allowDependentGC := true // may be added as a parameter later + err = bs.RemoveSubObjectsInWorkspace(req.ObjectIds, mw.GetAnytype().PredefinedBlocks().Account, allowDependentGC) return }) From 63a89dfbdbae0dd2841985dcf1d98ed72e09085a Mon Sep 17 00:00:00 2001 From: Roman Khafizianov Date: Mon, 9 Jan 2023 10:25:00 +0100 Subject: [PATCH 60/68] add log --- core/block/source/source.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/block/source/source.go b/core/block/source/source.go index 9bd7e487b..52f8239c4 100644 --- a/core/block/source/source.go +++ b/core/block/source/source.go @@ -408,6 +408,9 @@ func (s *source) PushChange(params PushChangeParams) (id string, err error) { }, FileKeys: s.getFileHashesForSnapshot(params.FileChangedHashes), } + if s.tree.Len() > 0 { + log.With("thread", s.id).With("len", s.tree.Len(), "lenSnap", s.changesSinceSnapshot, "changes", len(params.Changes), "doSnap", params.DoSnapshot).Warnf("do the snapshot") + } } c.Content = params.Changes c.FileKeys = s.getFileKeysByHashes(params.FileChangedHashes) From e85e467ccea076a5b36e32c0b87b22a40deae752 Mon Sep 17 00:00:00 2001 From: Roman Khafizianov Date: Mon, 9 Jan 2023 10:05:08 +0100 Subject: [PATCH 61/68] rename methods --- core/block/editor/subobjectcollection.go | 3 +-- core/block/editor/workspaces.go | 8 ++++---- core/block/service.go | 4 ++-- core/workspace.go | 3 +-- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/core/block/editor/subobjectcollection.go b/core/block/editor/subobjectcollection.go index ab6d65861..6c3bd6927 100644 --- a/core/block/editor/subobjectcollection.go +++ b/core/block/editor/subobjectcollection.go @@ -150,8 +150,7 @@ func (c *SubObjectCollection) removeObject(st *state.State, objectId string) (er return err } if len(links) > 0 { - // todo: return the error to user? - log.Errorf("workspace removeObject: found inbound links: %v", links) + log.With("id", objectId).With("total", len(links)).Debugf("workspace removeObject: found inbound links: %v", links) } st.RemoveFromStore([]string{collection, key}) if v, exists := c.collections[collection]; exists { diff --git a/core/block/editor/workspaces.go b/core/block/editor/workspaces.go index c1bd2dca0..57d7fc182 100644 --- a/core/block/editor/workspaces.go +++ b/core/block/editor/workspaces.go @@ -958,14 +958,14 @@ func (w *Workspaces) objectTypeRelationsForGC(objectTypeID string) (ids []string } // RemoveSubObjects removes sub objects from the workspace collection -// if allowGC is true, then relations that are not used by any object in the workspace will be removed as well -func (w *Workspaces) RemoveSubObjects(objectIds []string, allowDependentsGC bool) (err error) { +// if orphansGC is true, then relations that are not used by any object in the workspace will be removed as well +func (w *Workspaces) RemoveSubObjects(objectIds []string, orphansGC bool) (err error) { st := w.NewState() var idsToRemove []string for _, id := range objectIds { // special case for object types idsToRemove = nil - if strings.HasPrefix(id, addr.ObjectTypeKeyToIdPrefix) && allowDependentsGC { + if strings.HasPrefix(id, addr.ObjectTypeKeyToIdPrefix) && orphansGC { idsToRemove, err = w.objectTypeRelationsForGC(id) if err != nil { log.Errorf("objectTypeRelationsForGC failed: %s", err.Error()) @@ -981,7 +981,7 @@ func (w *Workspaces) RemoveSubObjects(objectIds []string, allowDependentsGC bool log.Errorf("failed to remove sub object: %s", err.Error()) continue } - if allowDependentsGC && len(idsToRemove) > 0 { + if orphansGC && len(idsToRemove) > 0 { for _, relId := range idsToRemove { err = w.removeObject(st, relId) if err != nil { diff --git a/core/block/service.go b/core/block/service.go index e9c31fc04..49b15070b 100644 --- a/core/block/service.go +++ b/core/block/service.go @@ -436,13 +436,13 @@ func (s *Service) AddSubObjectsToWorkspace( return } -func (s *Service) RemoveSubObjectsInWorkspace(objectIds []string, workspaceId string, allowDependentsGC bool) (err error) { +func (s *Service) RemoveSubObjectsInWorkspace(objectIds []string, workspaceId string, orphansGC bool) (err error) { err = s.Do(workspaceId, func(b smartblock.SmartBlock) error { ws, ok := b.(*editor.Workspaces) if !ok { return fmt.Errorf("incorrect workspace id") } - err = ws.RemoveSubObjects(objectIds, allowDependentsGC) + err = ws.RemoveSubObjects(objectIds, orphansGC) return err }) diff --git a/core/workspace.go b/core/workspace.go index 943611ca5..bc2762323 100644 --- a/core/workspace.go +++ b/core/workspace.go @@ -184,8 +184,7 @@ func (mw *Middleware) WorkspaceObjectListRemove(cctx context.Context, req *pb.Rp ) err := mw.doBlockService(func(bs *block.Service) (err error) { - allowDependentGC := true // may be added as a parameter later - err = bs.RemoveSubObjectsInWorkspace(req.ObjectIds, mw.GetAnytype().PredefinedBlocks().Account, allowDependentGC) + err = bs.RemoveSubObjectsInWorkspace(req.ObjectIds, mw.GetAnytype().PredefinedBlocks().Account, true) return }) From 82b2566f63137f56679bae914e430ad95a68c520 Mon Sep 17 00:00:00 2001 From: Roman Khafizianov Date: Mon, 9 Jan 2023 10:47:37 +0100 Subject: [PATCH 62/68] do not migrate relations for breadcrumbs --- core/indexer/indexer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/indexer/indexer.go b/core/indexer/indexer.go index fc32659d1..7b6f704de 100644 --- a/core/indexer/indexer.go +++ b/core/indexer/indexer.go @@ -801,7 +801,7 @@ func (i *indexer) index(ctx context.Context, info doc.DocInfo) error { } indexDetails, indexLinks := sbType.Indexable() - if sbType != smartblock.SmartBlockTypeSubObject && sbType != smartblock.SmartBlockTypeWorkspace { + if sbType != smartblock.SmartBlockTypeSubObject && sbType != smartblock.SmartBlockTypeWorkspace && sbType != smartblock.SmartBlockTypeBreadcrumbs { // avoid recursions if pbtypes.GetString(info.State.CombinedDetails(), bundle.RelationKeyCreator.String()) != addr.AnytypeProfileId { From 1b7f8d9b0c5a50d50848614210b12c5443098018 Mon Sep 17 00:00:00 2001 From: Roman Khafizianov Date: Mon, 9 Jan 2023 11:54:30 +0100 Subject: [PATCH 63/68] remove unused lock --- core/relation/service.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/core/relation/service.go b/core/relation/service.go index 361aab8d8..9c3e8dc9b 100644 --- a/core/relation/service.go +++ b/core/relation/service.go @@ -150,8 +150,6 @@ func (b *bulkMigration) Commit() error { type service struct { objectStore objectstore.ObjectStore relationCreator subObjectCreator - - mu sync.RWMutex } func (s *service) MigrateRelations(relations []*model.Relation) error { @@ -190,8 +188,6 @@ func (s *service) FetchLinks(links pbtypes.RelationLinks) (relations relationuti } func (s *service) FetchKeys(keys ...string) (relations relationutils.Relations, err error) { - s.mu.RLock() - defer s.mu.RUnlock() return s.fetchKeys(keys...) } @@ -215,8 +211,6 @@ func (s *service) fetchKeys(keys ...string) (relations []*relationutils.Relation } func (s *service) ListAll(opts ...FetchOption) (relations relationutils.Relations, err error) { - s.mu.RLock() - defer s.mu.RUnlock() return s.listAll(opts...) } @@ -266,8 +260,6 @@ func WithWorkspaceId(id string) FetchOption { } func (s *service) FetchKey(key string, opts ...FetchOption) (relation *relationutils.Relation, err error) { - s.mu.RLock() - defer s.mu.RUnlock() return s.fetchKey(key, opts...) } From 636ca1069bc3180b0f697ef768b1c74102d7f290 Mon Sep 17 00:00:00 2001 From: Roman Khafizianov Date: Mon, 9 Jan 2023 13:42:49 +0100 Subject: [PATCH 64/68] small fixes --- core/block/editor/workspaces.go | 8 +- docs/proto.md | 7084 +++++++++++++------------- pkg/lib/pb/model/protos/models.proto | 4 +- 3 files changed, 3550 insertions(+), 3546 deletions(-) diff --git a/core/block/editor/workspaces.go b/core/block/editor/workspaces.go index 57d7fc182..2e5856081 100644 --- a/core/block/editor/workspaces.go +++ b/core/block/editor/workspaces.go @@ -899,6 +899,11 @@ func (w *Workspaces) objectTypeRelationsForGC(objectTypeID string) (ids []string Condition: model.BlockContentDataviewFilter_In, Value: pbtypes.StringList(relIds), }, + { + RelationKey: bundle.RelationKeyWorkspaceId.String(), + Condition: model.BlockContentDataviewFilter_Equal, + Value: pbtypes.String(w.Id()), + }, }, }) if err != nil { @@ -961,10 +966,9 @@ func (w *Workspaces) objectTypeRelationsForGC(objectTypeID string) (ids []string // if orphansGC is true, then relations that are not used by any object in the workspace will be removed as well func (w *Workspaces) RemoveSubObjects(objectIds []string, orphansGC bool) (err error) { st := w.NewState() - var idsToRemove []string for _, id := range objectIds { // special case for object types - idsToRemove = nil + var idsToRemove []string if strings.HasPrefix(id, addr.ObjectTypeKeyToIdPrefix) && orphansGC { idsToRemove, err = w.objectTypeRelationsForGC(id) if err != nil { diff --git a/docs/proto.md b/docs/proto.md index 6bc19acf1..c5b685603 100644 --- a/docs/proto.md +++ b/docs/proto.md @@ -3,1248 +3,1248 @@ ## Table of Contents -- [pb/protos/service/service.proto](#pb_protos_service_service-proto) - - [ClientCommands](#anytype-ClientCommands) +- [pb/protos/service/service.proto](#pb/protos/service/service.proto) + - [ClientCommands](#anytype.ClientCommands) -- [pb/protos/changes.proto](#pb_protos_changes-proto) - - [Change](#anytype-Change) - - [Change.BlockCreate](#anytype-Change-BlockCreate) - - [Change.BlockDuplicate](#anytype-Change-BlockDuplicate) - - [Change.BlockMove](#anytype-Change-BlockMove) - - [Change.BlockRemove](#anytype-Change-BlockRemove) - - [Change.BlockUpdate](#anytype-Change-BlockUpdate) - - [Change.Content](#anytype-Change-Content) - - [Change.DetailsSet](#anytype-Change-DetailsSet) - - [Change.DetailsUnset](#anytype-Change-DetailsUnset) - - [Change.FileKeys](#anytype-Change-FileKeys) - - [Change.FileKeys.KeysEntry](#anytype-Change-FileKeys-KeysEntry) - - [Change.ObjectTypeAdd](#anytype-Change-ObjectTypeAdd) - - [Change.ObjectTypeRemove](#anytype-Change-ObjectTypeRemove) - - [Change.RelationAdd](#anytype-Change-RelationAdd) - - [Change.RelationRemove](#anytype-Change-RelationRemove) - - [Change.Snapshot](#anytype-Change-Snapshot) - - [Change.Snapshot.LogHeadsEntry](#anytype-Change-Snapshot-LogHeadsEntry) - - [Change.StoreKeySet](#anytype-Change-StoreKeySet) - - [Change.StoreKeyUnset](#anytype-Change-StoreKeyUnset) - - [Change._RelationAdd](#anytype-Change-_RelationAdd) - - [Change._RelationRemove](#anytype-Change-_RelationRemove) - - [Change._RelationUpdate](#anytype-Change-_RelationUpdate) - - [Change._RelationUpdate.Dict](#anytype-Change-_RelationUpdate-Dict) - - [Change._RelationUpdate.ObjectTypes](#anytype-Change-_RelationUpdate-ObjectTypes) +- [pb/protos/changes.proto](#pb/protos/changes.proto) + - [Change](#anytype.Change) + - [Change.BlockCreate](#anytype.Change.BlockCreate) + - [Change.BlockDuplicate](#anytype.Change.BlockDuplicate) + - [Change.BlockMove](#anytype.Change.BlockMove) + - [Change.BlockRemove](#anytype.Change.BlockRemove) + - [Change.BlockUpdate](#anytype.Change.BlockUpdate) + - [Change.Content](#anytype.Change.Content) + - [Change.DetailsSet](#anytype.Change.DetailsSet) + - [Change.DetailsUnset](#anytype.Change.DetailsUnset) + - [Change.FileKeys](#anytype.Change.FileKeys) + - [Change.FileKeys.KeysEntry](#anytype.Change.FileKeys.KeysEntry) + - [Change.ObjectTypeAdd](#anytype.Change.ObjectTypeAdd) + - [Change.ObjectTypeRemove](#anytype.Change.ObjectTypeRemove) + - [Change.RelationAdd](#anytype.Change.RelationAdd) + - [Change.RelationRemove](#anytype.Change.RelationRemove) + - [Change.Snapshot](#anytype.Change.Snapshot) + - [Change.Snapshot.LogHeadsEntry](#anytype.Change.Snapshot.LogHeadsEntry) + - [Change.StoreKeySet](#anytype.Change.StoreKeySet) + - [Change.StoreKeyUnset](#anytype.Change.StoreKeyUnset) + - [Change._RelationAdd](#anytype.Change._RelationAdd) + - [Change._RelationRemove](#anytype.Change._RelationRemove) + - [Change._RelationUpdate](#anytype.Change._RelationUpdate) + - [Change._RelationUpdate.Dict](#anytype.Change._RelationUpdate.Dict) + - [Change._RelationUpdate.ObjectTypes](#anytype.Change._RelationUpdate.ObjectTypes) -- [pb/protos/commands.proto](#pb_protos_commands-proto) - - [Empty](#anytype-Empty) - - [Rpc](#anytype-Rpc) - - [Rpc.Account](#anytype-Rpc-Account) - - [Rpc.Account.Config](#anytype-Rpc-Account-Config) - - [Rpc.Account.ConfigUpdate](#anytype-Rpc-Account-ConfigUpdate) - - [Rpc.Account.ConfigUpdate.Request](#anytype-Rpc-Account-ConfigUpdate-Request) - - [Rpc.Account.ConfigUpdate.Response](#anytype-Rpc-Account-ConfigUpdate-Response) - - [Rpc.Account.ConfigUpdate.Response.Error](#anytype-Rpc-Account-ConfigUpdate-Response-Error) - - [Rpc.Account.Create](#anytype-Rpc-Account-Create) - - [Rpc.Account.Create.Request](#anytype-Rpc-Account-Create-Request) - - [Rpc.Account.Create.Response](#anytype-Rpc-Account-Create-Response) - - [Rpc.Account.Create.Response.Error](#anytype-Rpc-Account-Create-Response-Error) - - [Rpc.Account.Delete](#anytype-Rpc-Account-Delete) - - [Rpc.Account.Delete.Request](#anytype-Rpc-Account-Delete-Request) - - [Rpc.Account.Delete.Response](#anytype-Rpc-Account-Delete-Response) - - [Rpc.Account.Delete.Response.Error](#anytype-Rpc-Account-Delete-Response-Error) - - [Rpc.Account.GetConfig](#anytype-Rpc-Account-GetConfig) - - [Rpc.Account.GetConfig.Get](#anytype-Rpc-Account-GetConfig-Get) - - [Rpc.Account.GetConfig.Get.Request](#anytype-Rpc-Account-GetConfig-Get-Request) - - [Rpc.Account.Move](#anytype-Rpc-Account-Move) - - [Rpc.Account.Move.Request](#anytype-Rpc-Account-Move-Request) - - [Rpc.Account.Move.Response](#anytype-Rpc-Account-Move-Response) - - [Rpc.Account.Move.Response.Error](#anytype-Rpc-Account-Move-Response-Error) - - [Rpc.Account.Recover](#anytype-Rpc-Account-Recover) - - [Rpc.Account.Recover.Request](#anytype-Rpc-Account-Recover-Request) - - [Rpc.Account.Recover.Response](#anytype-Rpc-Account-Recover-Response) - - [Rpc.Account.Recover.Response.Error](#anytype-Rpc-Account-Recover-Response-Error) - - [Rpc.Account.Select](#anytype-Rpc-Account-Select) - - [Rpc.Account.Select.Request](#anytype-Rpc-Account-Select-Request) - - [Rpc.Account.Select.Response](#anytype-Rpc-Account-Select-Response) - - [Rpc.Account.Select.Response.Error](#anytype-Rpc-Account-Select-Response-Error) - - [Rpc.Account.Stop](#anytype-Rpc-Account-Stop) - - [Rpc.Account.Stop.Request](#anytype-Rpc-Account-Stop-Request) - - [Rpc.Account.Stop.Response](#anytype-Rpc-Account-Stop-Response) - - [Rpc.Account.Stop.Response.Error](#anytype-Rpc-Account-Stop-Response-Error) - - [Rpc.App](#anytype-Rpc-App) - - [Rpc.App.GetVersion](#anytype-Rpc-App-GetVersion) - - [Rpc.App.GetVersion.Request](#anytype-Rpc-App-GetVersion-Request) - - [Rpc.App.GetVersion.Response](#anytype-Rpc-App-GetVersion-Response) - - [Rpc.App.GetVersion.Response.Error](#anytype-Rpc-App-GetVersion-Response-Error) - - [Rpc.App.SetDeviceState](#anytype-Rpc-App-SetDeviceState) - - [Rpc.App.SetDeviceState.Request](#anytype-Rpc-App-SetDeviceState-Request) - - [Rpc.App.SetDeviceState.Response](#anytype-Rpc-App-SetDeviceState-Response) - - [Rpc.App.SetDeviceState.Response.Error](#anytype-Rpc-App-SetDeviceState-Response-Error) - - [Rpc.App.Shutdown](#anytype-Rpc-App-Shutdown) - - [Rpc.App.Shutdown.Request](#anytype-Rpc-App-Shutdown-Request) - - [Rpc.App.Shutdown.Response](#anytype-Rpc-App-Shutdown-Response) - - [Rpc.App.Shutdown.Response.Error](#anytype-Rpc-App-Shutdown-Response-Error) - - [Rpc.Block](#anytype-Rpc-Block) - - [Rpc.Block.Copy](#anytype-Rpc-Block-Copy) - - [Rpc.Block.Copy.Request](#anytype-Rpc-Block-Copy-Request) - - [Rpc.Block.Copy.Response](#anytype-Rpc-Block-Copy-Response) - - [Rpc.Block.Copy.Response.Error](#anytype-Rpc-Block-Copy-Response-Error) - - [Rpc.Block.Create](#anytype-Rpc-Block-Create) - - [Rpc.Block.Create.Request](#anytype-Rpc-Block-Create-Request) - - [Rpc.Block.Create.Response](#anytype-Rpc-Block-Create-Response) - - [Rpc.Block.Create.Response.Error](#anytype-Rpc-Block-Create-Response-Error) - - [Rpc.Block.CreateWidget](#anytype-Rpc-Block-CreateWidget) - - [Rpc.Block.CreateWidget.Request](#anytype-Rpc-Block-CreateWidget-Request) - - [Rpc.Block.CreateWidget.Response](#anytype-Rpc-Block-CreateWidget-Response) - - [Rpc.Block.CreateWidget.Response.Error](#anytype-Rpc-Block-CreateWidget-Response-Error) - - [Rpc.Block.Cut](#anytype-Rpc-Block-Cut) - - [Rpc.Block.Cut.Request](#anytype-Rpc-Block-Cut-Request) - - [Rpc.Block.Cut.Response](#anytype-Rpc-Block-Cut-Response) - - [Rpc.Block.Cut.Response.Error](#anytype-Rpc-Block-Cut-Response-Error) - - [Rpc.Block.Download](#anytype-Rpc-Block-Download) - - [Rpc.Block.Download.Request](#anytype-Rpc-Block-Download-Request) - - [Rpc.Block.Download.Response](#anytype-Rpc-Block-Download-Response) - - [Rpc.Block.Download.Response.Error](#anytype-Rpc-Block-Download-Response-Error) - - [Rpc.Block.Export](#anytype-Rpc-Block-Export) - - [Rpc.Block.Export.Request](#anytype-Rpc-Block-Export-Request) - - [Rpc.Block.Export.Response](#anytype-Rpc-Block-Export-Response) - - [Rpc.Block.Export.Response.Error](#anytype-Rpc-Block-Export-Response-Error) - - [Rpc.Block.ListConvertToObjects](#anytype-Rpc-Block-ListConvertToObjects) - - [Rpc.Block.ListConvertToObjects.Request](#anytype-Rpc-Block-ListConvertToObjects-Request) - - [Rpc.Block.ListConvertToObjects.Response](#anytype-Rpc-Block-ListConvertToObjects-Response) - - [Rpc.Block.ListConvertToObjects.Response.Error](#anytype-Rpc-Block-ListConvertToObjects-Response-Error) - - [Rpc.Block.ListDelete](#anytype-Rpc-Block-ListDelete) - - [Rpc.Block.ListDelete.Request](#anytype-Rpc-Block-ListDelete-Request) - - [Rpc.Block.ListDelete.Response](#anytype-Rpc-Block-ListDelete-Response) - - [Rpc.Block.ListDelete.Response.Error](#anytype-Rpc-Block-ListDelete-Response-Error) - - [Rpc.Block.ListDuplicate](#anytype-Rpc-Block-ListDuplicate) - - [Rpc.Block.ListDuplicate.Request](#anytype-Rpc-Block-ListDuplicate-Request) - - [Rpc.Block.ListDuplicate.Response](#anytype-Rpc-Block-ListDuplicate-Response) - - [Rpc.Block.ListDuplicate.Response.Error](#anytype-Rpc-Block-ListDuplicate-Response-Error) - - [Rpc.Block.ListMoveToExistingObject](#anytype-Rpc-Block-ListMoveToExistingObject) - - [Rpc.Block.ListMoveToExistingObject.Request](#anytype-Rpc-Block-ListMoveToExistingObject-Request) - - [Rpc.Block.ListMoveToExistingObject.Response](#anytype-Rpc-Block-ListMoveToExistingObject-Response) - - [Rpc.Block.ListMoveToExistingObject.Response.Error](#anytype-Rpc-Block-ListMoveToExistingObject-Response-Error) - - [Rpc.Block.ListMoveToNewObject](#anytype-Rpc-Block-ListMoveToNewObject) - - [Rpc.Block.ListMoveToNewObject.Request](#anytype-Rpc-Block-ListMoveToNewObject-Request) - - [Rpc.Block.ListMoveToNewObject.Response](#anytype-Rpc-Block-ListMoveToNewObject-Response) - - [Rpc.Block.ListMoveToNewObject.Response.Error](#anytype-Rpc-Block-ListMoveToNewObject-Response-Error) - - [Rpc.Block.ListSetAlign](#anytype-Rpc-Block-ListSetAlign) - - [Rpc.Block.ListSetAlign.Request](#anytype-Rpc-Block-ListSetAlign-Request) - - [Rpc.Block.ListSetAlign.Response](#anytype-Rpc-Block-ListSetAlign-Response) - - [Rpc.Block.ListSetAlign.Response.Error](#anytype-Rpc-Block-ListSetAlign-Response-Error) - - [Rpc.Block.ListSetBackgroundColor](#anytype-Rpc-Block-ListSetBackgroundColor) - - [Rpc.Block.ListSetBackgroundColor.Request](#anytype-Rpc-Block-ListSetBackgroundColor-Request) - - [Rpc.Block.ListSetBackgroundColor.Response](#anytype-Rpc-Block-ListSetBackgroundColor-Response) - - [Rpc.Block.ListSetBackgroundColor.Response.Error](#anytype-Rpc-Block-ListSetBackgroundColor-Response-Error) - - [Rpc.Block.ListSetFields](#anytype-Rpc-Block-ListSetFields) - - [Rpc.Block.ListSetFields.Request](#anytype-Rpc-Block-ListSetFields-Request) - - [Rpc.Block.ListSetFields.Request.BlockField](#anytype-Rpc-Block-ListSetFields-Request-BlockField) - - [Rpc.Block.ListSetFields.Response](#anytype-Rpc-Block-ListSetFields-Response) - - [Rpc.Block.ListSetFields.Response.Error](#anytype-Rpc-Block-ListSetFields-Response-Error) - - [Rpc.Block.ListSetVerticalAlign](#anytype-Rpc-Block-ListSetVerticalAlign) - - [Rpc.Block.ListSetVerticalAlign.Request](#anytype-Rpc-Block-ListSetVerticalAlign-Request) - - [Rpc.Block.ListSetVerticalAlign.Response](#anytype-Rpc-Block-ListSetVerticalAlign-Response) - - [Rpc.Block.ListSetVerticalAlign.Response.Error](#anytype-Rpc-Block-ListSetVerticalAlign-Response-Error) - - [Rpc.Block.ListTurnInto](#anytype-Rpc-Block-ListTurnInto) - - [Rpc.Block.ListTurnInto.Request](#anytype-Rpc-Block-ListTurnInto-Request) - - [Rpc.Block.ListTurnInto.Response](#anytype-Rpc-Block-ListTurnInto-Response) - - [Rpc.Block.ListTurnInto.Response.Error](#anytype-Rpc-Block-ListTurnInto-Response-Error) - - [Rpc.Block.ListUpdate](#anytype-Rpc-Block-ListUpdate) - - [Rpc.Block.ListUpdate.Request](#anytype-Rpc-Block-ListUpdate-Request) - - [Rpc.Block.ListUpdate.Request.Text](#anytype-Rpc-Block-ListUpdate-Request-Text) - - [Rpc.Block.Merge](#anytype-Rpc-Block-Merge) - - [Rpc.Block.Merge.Request](#anytype-Rpc-Block-Merge-Request) - - [Rpc.Block.Merge.Response](#anytype-Rpc-Block-Merge-Response) - - [Rpc.Block.Merge.Response.Error](#anytype-Rpc-Block-Merge-Response-Error) - - [Rpc.Block.Paste](#anytype-Rpc-Block-Paste) - - [Rpc.Block.Paste.Request](#anytype-Rpc-Block-Paste-Request) - - [Rpc.Block.Paste.Request.File](#anytype-Rpc-Block-Paste-Request-File) - - [Rpc.Block.Paste.Response](#anytype-Rpc-Block-Paste-Response) - - [Rpc.Block.Paste.Response.Error](#anytype-Rpc-Block-Paste-Response-Error) - - [Rpc.Block.Replace](#anytype-Rpc-Block-Replace) - - [Rpc.Block.Replace.Request](#anytype-Rpc-Block-Replace-Request) - - [Rpc.Block.Replace.Response](#anytype-Rpc-Block-Replace-Response) - - [Rpc.Block.Replace.Response.Error](#anytype-Rpc-Block-Replace-Response-Error) - - [Rpc.Block.SetFields](#anytype-Rpc-Block-SetFields) - - [Rpc.Block.SetFields.Request](#anytype-Rpc-Block-SetFields-Request) - - [Rpc.Block.SetFields.Response](#anytype-Rpc-Block-SetFields-Response) - - [Rpc.Block.SetFields.Response.Error](#anytype-Rpc-Block-SetFields-Response-Error) - - [Rpc.Block.Split](#anytype-Rpc-Block-Split) - - [Rpc.Block.Split.Request](#anytype-Rpc-Block-Split-Request) - - [Rpc.Block.Split.Response](#anytype-Rpc-Block-Split-Response) - - [Rpc.Block.Split.Response.Error](#anytype-Rpc-Block-Split-Response-Error) - - [Rpc.Block.Upload](#anytype-Rpc-Block-Upload) - - [Rpc.Block.Upload.Request](#anytype-Rpc-Block-Upload-Request) - - [Rpc.Block.Upload.Response](#anytype-Rpc-Block-Upload-Response) - - [Rpc.Block.Upload.Response.Error](#anytype-Rpc-Block-Upload-Response-Error) - - [Rpc.BlockBookmark](#anytype-Rpc-BlockBookmark) - - [Rpc.BlockBookmark.CreateAndFetch](#anytype-Rpc-BlockBookmark-CreateAndFetch) - - [Rpc.BlockBookmark.CreateAndFetch.Request](#anytype-Rpc-BlockBookmark-CreateAndFetch-Request) - - [Rpc.BlockBookmark.CreateAndFetch.Response](#anytype-Rpc-BlockBookmark-CreateAndFetch-Response) - - [Rpc.BlockBookmark.CreateAndFetch.Response.Error](#anytype-Rpc-BlockBookmark-CreateAndFetch-Response-Error) - - [Rpc.BlockBookmark.Fetch](#anytype-Rpc-BlockBookmark-Fetch) - - [Rpc.BlockBookmark.Fetch.Request](#anytype-Rpc-BlockBookmark-Fetch-Request) - - [Rpc.BlockBookmark.Fetch.Response](#anytype-Rpc-BlockBookmark-Fetch-Response) - - [Rpc.BlockBookmark.Fetch.Response.Error](#anytype-Rpc-BlockBookmark-Fetch-Response-Error) - - [Rpc.BlockDataview](#anytype-Rpc-BlockDataview) - - [Rpc.BlockDataview.CreateBookmark](#anytype-Rpc-BlockDataview-CreateBookmark) - - [Rpc.BlockDataview.CreateBookmark.Request](#anytype-Rpc-BlockDataview-CreateBookmark-Request) - - [Rpc.BlockDataview.CreateBookmark.Response](#anytype-Rpc-BlockDataview-CreateBookmark-Response) - - [Rpc.BlockDataview.CreateBookmark.Response.Error](#anytype-Rpc-BlockDataview-CreateBookmark-Response-Error) - - [Rpc.BlockDataview.GroupOrder](#anytype-Rpc-BlockDataview-GroupOrder) - - [Rpc.BlockDataview.GroupOrder.Update](#anytype-Rpc-BlockDataview-GroupOrder-Update) - - [Rpc.BlockDataview.GroupOrder.Update.Request](#anytype-Rpc-BlockDataview-GroupOrder-Update-Request) - - [Rpc.BlockDataview.GroupOrder.Update.Response](#anytype-Rpc-BlockDataview-GroupOrder-Update-Response) - - [Rpc.BlockDataview.GroupOrder.Update.Response.Error](#anytype-Rpc-BlockDataview-GroupOrder-Update-Response-Error) - - [Rpc.BlockDataview.ObjectOrder](#anytype-Rpc-BlockDataview-ObjectOrder) - - [Rpc.BlockDataview.ObjectOrder.Update](#anytype-Rpc-BlockDataview-ObjectOrder-Update) - - [Rpc.BlockDataview.ObjectOrder.Update.Request](#anytype-Rpc-BlockDataview-ObjectOrder-Update-Request) - - [Rpc.BlockDataview.ObjectOrder.Update.Response](#anytype-Rpc-BlockDataview-ObjectOrder-Update-Response) - - [Rpc.BlockDataview.ObjectOrder.Update.Response.Error](#anytype-Rpc-BlockDataview-ObjectOrder-Update-Response-Error) - - [Rpc.BlockDataview.Relation](#anytype-Rpc-BlockDataview-Relation) - - [Rpc.BlockDataview.Relation.Add](#anytype-Rpc-BlockDataview-Relation-Add) - - [Rpc.BlockDataview.Relation.Add.Request](#anytype-Rpc-BlockDataview-Relation-Add-Request) - - [Rpc.BlockDataview.Relation.Add.Response](#anytype-Rpc-BlockDataview-Relation-Add-Response) - - [Rpc.BlockDataview.Relation.Add.Response.Error](#anytype-Rpc-BlockDataview-Relation-Add-Response-Error) - - [Rpc.BlockDataview.Relation.Delete](#anytype-Rpc-BlockDataview-Relation-Delete) - - [Rpc.BlockDataview.Relation.Delete.Request](#anytype-Rpc-BlockDataview-Relation-Delete-Request) - - [Rpc.BlockDataview.Relation.Delete.Response](#anytype-Rpc-BlockDataview-Relation-Delete-Response) - - [Rpc.BlockDataview.Relation.Delete.Response.Error](#anytype-Rpc-BlockDataview-Relation-Delete-Response-Error) - - [Rpc.BlockDataview.Relation.ListAvailable](#anytype-Rpc-BlockDataview-Relation-ListAvailable) - - [Rpc.BlockDataview.Relation.ListAvailable.Request](#anytype-Rpc-BlockDataview-Relation-ListAvailable-Request) - - [Rpc.BlockDataview.Relation.ListAvailable.Response](#anytype-Rpc-BlockDataview-Relation-ListAvailable-Response) - - [Rpc.BlockDataview.Relation.ListAvailable.Response.Error](#anytype-Rpc-BlockDataview-Relation-ListAvailable-Response-Error) - - [Rpc.BlockDataview.SetSource](#anytype-Rpc-BlockDataview-SetSource) - - [Rpc.BlockDataview.SetSource.Request](#anytype-Rpc-BlockDataview-SetSource-Request) - - [Rpc.BlockDataview.SetSource.Response](#anytype-Rpc-BlockDataview-SetSource-Response) - - [Rpc.BlockDataview.SetSource.Response.Error](#anytype-Rpc-BlockDataview-SetSource-Response-Error) - - [Rpc.BlockDataview.View](#anytype-Rpc-BlockDataview-View) - - [Rpc.BlockDataview.View.Create](#anytype-Rpc-BlockDataview-View-Create) - - [Rpc.BlockDataview.View.Create.Request](#anytype-Rpc-BlockDataview-View-Create-Request) - - [Rpc.BlockDataview.View.Create.Response](#anytype-Rpc-BlockDataview-View-Create-Response) - - [Rpc.BlockDataview.View.Create.Response.Error](#anytype-Rpc-BlockDataview-View-Create-Response-Error) - - [Rpc.BlockDataview.View.Delete](#anytype-Rpc-BlockDataview-View-Delete) - - [Rpc.BlockDataview.View.Delete.Request](#anytype-Rpc-BlockDataview-View-Delete-Request) - - [Rpc.BlockDataview.View.Delete.Response](#anytype-Rpc-BlockDataview-View-Delete-Response) - - [Rpc.BlockDataview.View.Delete.Response.Error](#anytype-Rpc-BlockDataview-View-Delete-Response-Error) - - [Rpc.BlockDataview.View.SetActive](#anytype-Rpc-BlockDataview-View-SetActive) - - [Rpc.BlockDataview.View.SetActive.Request](#anytype-Rpc-BlockDataview-View-SetActive-Request) - - [Rpc.BlockDataview.View.SetActive.Response](#anytype-Rpc-BlockDataview-View-SetActive-Response) - - [Rpc.BlockDataview.View.SetActive.Response.Error](#anytype-Rpc-BlockDataview-View-SetActive-Response-Error) - - [Rpc.BlockDataview.View.SetPosition](#anytype-Rpc-BlockDataview-View-SetPosition) - - [Rpc.BlockDataview.View.SetPosition.Request](#anytype-Rpc-BlockDataview-View-SetPosition-Request) - - [Rpc.BlockDataview.View.SetPosition.Response](#anytype-Rpc-BlockDataview-View-SetPosition-Response) - - [Rpc.BlockDataview.View.SetPosition.Response.Error](#anytype-Rpc-BlockDataview-View-SetPosition-Response-Error) - - [Rpc.BlockDataview.View.Update](#anytype-Rpc-BlockDataview-View-Update) - - [Rpc.BlockDataview.View.Update.Request](#anytype-Rpc-BlockDataview-View-Update-Request) - - [Rpc.BlockDataview.View.Update.Response](#anytype-Rpc-BlockDataview-View-Update-Response) - - [Rpc.BlockDataview.View.Update.Response.Error](#anytype-Rpc-BlockDataview-View-Update-Response-Error) - - [Rpc.BlockDiv](#anytype-Rpc-BlockDiv) - - [Rpc.BlockDiv.ListSetStyle](#anytype-Rpc-BlockDiv-ListSetStyle) - - [Rpc.BlockDiv.ListSetStyle.Request](#anytype-Rpc-BlockDiv-ListSetStyle-Request) - - [Rpc.BlockDiv.ListSetStyle.Response](#anytype-Rpc-BlockDiv-ListSetStyle-Response) - - [Rpc.BlockDiv.ListSetStyle.Response.Error](#anytype-Rpc-BlockDiv-ListSetStyle-Response-Error) - - [Rpc.BlockFile](#anytype-Rpc-BlockFile) - - [Rpc.BlockFile.CreateAndUpload](#anytype-Rpc-BlockFile-CreateAndUpload) - - [Rpc.BlockFile.CreateAndUpload.Request](#anytype-Rpc-BlockFile-CreateAndUpload-Request) - - [Rpc.BlockFile.CreateAndUpload.Response](#anytype-Rpc-BlockFile-CreateAndUpload-Response) - - [Rpc.BlockFile.CreateAndUpload.Response.Error](#anytype-Rpc-BlockFile-CreateAndUpload-Response-Error) - - [Rpc.BlockFile.ListSetStyle](#anytype-Rpc-BlockFile-ListSetStyle) - - [Rpc.BlockFile.ListSetStyle.Request](#anytype-Rpc-BlockFile-ListSetStyle-Request) - - [Rpc.BlockFile.ListSetStyle.Response](#anytype-Rpc-BlockFile-ListSetStyle-Response) - - [Rpc.BlockFile.ListSetStyle.Response.Error](#anytype-Rpc-BlockFile-ListSetStyle-Response-Error) - - [Rpc.BlockFile.SetName](#anytype-Rpc-BlockFile-SetName) - - [Rpc.BlockFile.SetName.Request](#anytype-Rpc-BlockFile-SetName-Request) - - [Rpc.BlockFile.SetName.Response](#anytype-Rpc-BlockFile-SetName-Response) - - [Rpc.BlockFile.SetName.Response.Error](#anytype-Rpc-BlockFile-SetName-Response-Error) - - [Rpc.BlockImage](#anytype-Rpc-BlockImage) - - [Rpc.BlockImage.SetName](#anytype-Rpc-BlockImage-SetName) - - [Rpc.BlockImage.SetName.Request](#anytype-Rpc-BlockImage-SetName-Request) - - [Rpc.BlockImage.SetName.Response](#anytype-Rpc-BlockImage-SetName-Response) - - [Rpc.BlockImage.SetName.Response.Error](#anytype-Rpc-BlockImage-SetName-Response-Error) - - [Rpc.BlockImage.SetWidth](#anytype-Rpc-BlockImage-SetWidth) - - [Rpc.BlockImage.SetWidth.Request](#anytype-Rpc-BlockImage-SetWidth-Request) - - [Rpc.BlockImage.SetWidth.Response](#anytype-Rpc-BlockImage-SetWidth-Response) - - [Rpc.BlockImage.SetWidth.Response.Error](#anytype-Rpc-BlockImage-SetWidth-Response-Error) - - [Rpc.BlockLatex](#anytype-Rpc-BlockLatex) - - [Rpc.BlockLatex.SetText](#anytype-Rpc-BlockLatex-SetText) - - [Rpc.BlockLatex.SetText.Request](#anytype-Rpc-BlockLatex-SetText-Request) - - [Rpc.BlockLatex.SetText.Response](#anytype-Rpc-BlockLatex-SetText-Response) - - [Rpc.BlockLatex.SetText.Response.Error](#anytype-Rpc-BlockLatex-SetText-Response-Error) - - [Rpc.BlockLink](#anytype-Rpc-BlockLink) - - [Rpc.BlockLink.CreateWithObject](#anytype-Rpc-BlockLink-CreateWithObject) - - [Rpc.BlockLink.CreateWithObject.Request](#anytype-Rpc-BlockLink-CreateWithObject-Request) - - [Rpc.BlockLink.CreateWithObject.Response](#anytype-Rpc-BlockLink-CreateWithObject-Response) - - [Rpc.BlockLink.CreateWithObject.Response.Error](#anytype-Rpc-BlockLink-CreateWithObject-Response-Error) - - [Rpc.BlockLink.ListSetAppearance](#anytype-Rpc-BlockLink-ListSetAppearance) - - [Rpc.BlockLink.ListSetAppearance.Request](#anytype-Rpc-BlockLink-ListSetAppearance-Request) - - [Rpc.BlockLink.ListSetAppearance.Response](#anytype-Rpc-BlockLink-ListSetAppearance-Response) - - [Rpc.BlockLink.ListSetAppearance.Response.Error](#anytype-Rpc-BlockLink-ListSetAppearance-Response-Error) - - [Rpc.BlockRelation](#anytype-Rpc-BlockRelation) - - [Rpc.BlockRelation.Add](#anytype-Rpc-BlockRelation-Add) - - [Rpc.BlockRelation.Add.Request](#anytype-Rpc-BlockRelation-Add-Request) - - [Rpc.BlockRelation.Add.Response](#anytype-Rpc-BlockRelation-Add-Response) - - [Rpc.BlockRelation.Add.Response.Error](#anytype-Rpc-BlockRelation-Add-Response-Error) - - [Rpc.BlockRelation.SetKey](#anytype-Rpc-BlockRelation-SetKey) - - [Rpc.BlockRelation.SetKey.Request](#anytype-Rpc-BlockRelation-SetKey-Request) - - [Rpc.BlockRelation.SetKey.Response](#anytype-Rpc-BlockRelation-SetKey-Response) - - [Rpc.BlockRelation.SetKey.Response.Error](#anytype-Rpc-BlockRelation-SetKey-Response-Error) - - [Rpc.BlockTable](#anytype-Rpc-BlockTable) - - [Rpc.BlockTable.ColumnCreate](#anytype-Rpc-BlockTable-ColumnCreate) - - [Rpc.BlockTable.ColumnCreate.Request](#anytype-Rpc-BlockTable-ColumnCreate-Request) - - [Rpc.BlockTable.ColumnCreate.Response](#anytype-Rpc-BlockTable-ColumnCreate-Response) - - [Rpc.BlockTable.ColumnCreate.Response.Error](#anytype-Rpc-BlockTable-ColumnCreate-Response-Error) - - [Rpc.BlockTable.ColumnDelete](#anytype-Rpc-BlockTable-ColumnDelete) - - [Rpc.BlockTable.ColumnDelete.Request](#anytype-Rpc-BlockTable-ColumnDelete-Request) - - [Rpc.BlockTable.ColumnDelete.Response](#anytype-Rpc-BlockTable-ColumnDelete-Response) - - [Rpc.BlockTable.ColumnDelete.Response.Error](#anytype-Rpc-BlockTable-ColumnDelete-Response-Error) - - [Rpc.BlockTable.ColumnDuplicate](#anytype-Rpc-BlockTable-ColumnDuplicate) - - [Rpc.BlockTable.ColumnDuplicate.Request](#anytype-Rpc-BlockTable-ColumnDuplicate-Request) - - [Rpc.BlockTable.ColumnDuplicate.Response](#anytype-Rpc-BlockTable-ColumnDuplicate-Response) - - [Rpc.BlockTable.ColumnDuplicate.Response.Error](#anytype-Rpc-BlockTable-ColumnDuplicate-Response-Error) - - [Rpc.BlockTable.ColumnListFill](#anytype-Rpc-BlockTable-ColumnListFill) - - [Rpc.BlockTable.ColumnListFill.Request](#anytype-Rpc-BlockTable-ColumnListFill-Request) - - [Rpc.BlockTable.ColumnListFill.Response](#anytype-Rpc-BlockTable-ColumnListFill-Response) - - [Rpc.BlockTable.ColumnListFill.Response.Error](#anytype-Rpc-BlockTable-ColumnListFill-Response-Error) - - [Rpc.BlockTable.ColumnMove](#anytype-Rpc-BlockTable-ColumnMove) - - [Rpc.BlockTable.ColumnMove.Request](#anytype-Rpc-BlockTable-ColumnMove-Request) - - [Rpc.BlockTable.ColumnMove.Response](#anytype-Rpc-BlockTable-ColumnMove-Response) - - [Rpc.BlockTable.ColumnMove.Response.Error](#anytype-Rpc-BlockTable-ColumnMove-Response-Error) - - [Rpc.BlockTable.Create](#anytype-Rpc-BlockTable-Create) - - [Rpc.BlockTable.Create.Request](#anytype-Rpc-BlockTable-Create-Request) - - [Rpc.BlockTable.Create.Response](#anytype-Rpc-BlockTable-Create-Response) - - [Rpc.BlockTable.Create.Response.Error](#anytype-Rpc-BlockTable-Create-Response-Error) - - [Rpc.BlockTable.Expand](#anytype-Rpc-BlockTable-Expand) - - [Rpc.BlockTable.Expand.Request](#anytype-Rpc-BlockTable-Expand-Request) - - [Rpc.BlockTable.Expand.Response](#anytype-Rpc-BlockTable-Expand-Response) - - [Rpc.BlockTable.Expand.Response.Error](#anytype-Rpc-BlockTable-Expand-Response-Error) - - [Rpc.BlockTable.RowCreate](#anytype-Rpc-BlockTable-RowCreate) - - [Rpc.BlockTable.RowCreate.Request](#anytype-Rpc-BlockTable-RowCreate-Request) - - [Rpc.BlockTable.RowCreate.Response](#anytype-Rpc-BlockTable-RowCreate-Response) - - [Rpc.BlockTable.RowCreate.Response.Error](#anytype-Rpc-BlockTable-RowCreate-Response-Error) - - [Rpc.BlockTable.RowDelete](#anytype-Rpc-BlockTable-RowDelete) - - [Rpc.BlockTable.RowDelete.Request](#anytype-Rpc-BlockTable-RowDelete-Request) - - [Rpc.BlockTable.RowDelete.Response](#anytype-Rpc-BlockTable-RowDelete-Response) - - [Rpc.BlockTable.RowDelete.Response.Error](#anytype-Rpc-BlockTable-RowDelete-Response-Error) - - [Rpc.BlockTable.RowDuplicate](#anytype-Rpc-BlockTable-RowDuplicate) - - [Rpc.BlockTable.RowDuplicate.Request](#anytype-Rpc-BlockTable-RowDuplicate-Request) - - [Rpc.BlockTable.RowDuplicate.Response](#anytype-Rpc-BlockTable-RowDuplicate-Response) - - [Rpc.BlockTable.RowDuplicate.Response.Error](#anytype-Rpc-BlockTable-RowDuplicate-Response-Error) - - [Rpc.BlockTable.RowListClean](#anytype-Rpc-BlockTable-RowListClean) - - [Rpc.BlockTable.RowListClean.Request](#anytype-Rpc-BlockTable-RowListClean-Request) - - [Rpc.BlockTable.RowListClean.Response](#anytype-Rpc-BlockTable-RowListClean-Response) - - [Rpc.BlockTable.RowListClean.Response.Error](#anytype-Rpc-BlockTable-RowListClean-Response-Error) - - [Rpc.BlockTable.RowListFill](#anytype-Rpc-BlockTable-RowListFill) - - [Rpc.BlockTable.RowListFill.Request](#anytype-Rpc-BlockTable-RowListFill-Request) - - [Rpc.BlockTable.RowListFill.Response](#anytype-Rpc-BlockTable-RowListFill-Response) - - [Rpc.BlockTable.RowListFill.Response.Error](#anytype-Rpc-BlockTable-RowListFill-Response-Error) - - [Rpc.BlockTable.RowSetHeader](#anytype-Rpc-BlockTable-RowSetHeader) - - [Rpc.BlockTable.RowSetHeader.Request](#anytype-Rpc-BlockTable-RowSetHeader-Request) - - [Rpc.BlockTable.RowSetHeader.Response](#anytype-Rpc-BlockTable-RowSetHeader-Response) - - [Rpc.BlockTable.RowSetHeader.Response.Error](#anytype-Rpc-BlockTable-RowSetHeader-Response-Error) - - [Rpc.BlockTable.Sort](#anytype-Rpc-BlockTable-Sort) - - [Rpc.BlockTable.Sort.Request](#anytype-Rpc-BlockTable-Sort-Request) - - [Rpc.BlockTable.Sort.Response](#anytype-Rpc-BlockTable-Sort-Response) - - [Rpc.BlockTable.Sort.Response.Error](#anytype-Rpc-BlockTable-Sort-Response-Error) - - [Rpc.BlockText](#anytype-Rpc-BlockText) - - [Rpc.BlockText.ListClearContent](#anytype-Rpc-BlockText-ListClearContent) - - [Rpc.BlockText.ListClearContent.Request](#anytype-Rpc-BlockText-ListClearContent-Request) - - [Rpc.BlockText.ListClearContent.Response](#anytype-Rpc-BlockText-ListClearContent-Response) - - [Rpc.BlockText.ListClearContent.Response.Error](#anytype-Rpc-BlockText-ListClearContent-Response-Error) - - [Rpc.BlockText.ListClearStyle](#anytype-Rpc-BlockText-ListClearStyle) - - [Rpc.BlockText.ListClearStyle.Request](#anytype-Rpc-BlockText-ListClearStyle-Request) - - [Rpc.BlockText.ListClearStyle.Response](#anytype-Rpc-BlockText-ListClearStyle-Response) - - [Rpc.BlockText.ListClearStyle.Response.Error](#anytype-Rpc-BlockText-ListClearStyle-Response-Error) - - [Rpc.BlockText.ListSetColor](#anytype-Rpc-BlockText-ListSetColor) - - [Rpc.BlockText.ListSetColor.Request](#anytype-Rpc-BlockText-ListSetColor-Request) - - [Rpc.BlockText.ListSetColor.Response](#anytype-Rpc-BlockText-ListSetColor-Response) - - [Rpc.BlockText.ListSetColor.Response.Error](#anytype-Rpc-BlockText-ListSetColor-Response-Error) - - [Rpc.BlockText.ListSetMark](#anytype-Rpc-BlockText-ListSetMark) - - [Rpc.BlockText.ListSetMark.Request](#anytype-Rpc-BlockText-ListSetMark-Request) - - [Rpc.BlockText.ListSetMark.Response](#anytype-Rpc-BlockText-ListSetMark-Response) - - [Rpc.BlockText.ListSetMark.Response.Error](#anytype-Rpc-BlockText-ListSetMark-Response-Error) - - [Rpc.BlockText.ListSetStyle](#anytype-Rpc-BlockText-ListSetStyle) - - [Rpc.BlockText.ListSetStyle.Request](#anytype-Rpc-BlockText-ListSetStyle-Request) - - [Rpc.BlockText.ListSetStyle.Response](#anytype-Rpc-BlockText-ListSetStyle-Response) - - [Rpc.BlockText.ListSetStyle.Response.Error](#anytype-Rpc-BlockText-ListSetStyle-Response-Error) - - [Rpc.BlockText.SetChecked](#anytype-Rpc-BlockText-SetChecked) - - [Rpc.BlockText.SetChecked.Request](#anytype-Rpc-BlockText-SetChecked-Request) - - [Rpc.BlockText.SetChecked.Response](#anytype-Rpc-BlockText-SetChecked-Response) - - [Rpc.BlockText.SetChecked.Response.Error](#anytype-Rpc-BlockText-SetChecked-Response-Error) - - [Rpc.BlockText.SetColor](#anytype-Rpc-BlockText-SetColor) - - [Rpc.BlockText.SetColor.Request](#anytype-Rpc-BlockText-SetColor-Request) - - [Rpc.BlockText.SetColor.Response](#anytype-Rpc-BlockText-SetColor-Response) - - [Rpc.BlockText.SetColor.Response.Error](#anytype-Rpc-BlockText-SetColor-Response-Error) - - [Rpc.BlockText.SetIcon](#anytype-Rpc-BlockText-SetIcon) - - [Rpc.BlockText.SetIcon.Request](#anytype-Rpc-BlockText-SetIcon-Request) - - [Rpc.BlockText.SetIcon.Response](#anytype-Rpc-BlockText-SetIcon-Response) - - [Rpc.BlockText.SetIcon.Response.Error](#anytype-Rpc-BlockText-SetIcon-Response-Error) - - [Rpc.BlockText.SetMarks](#anytype-Rpc-BlockText-SetMarks) - - [Rpc.BlockText.SetMarks.Get](#anytype-Rpc-BlockText-SetMarks-Get) - - [Rpc.BlockText.SetMarks.Get.Request](#anytype-Rpc-BlockText-SetMarks-Get-Request) - - [Rpc.BlockText.SetMarks.Get.Response](#anytype-Rpc-BlockText-SetMarks-Get-Response) - - [Rpc.BlockText.SetMarks.Get.Response.Error](#anytype-Rpc-BlockText-SetMarks-Get-Response-Error) - - [Rpc.BlockText.SetStyle](#anytype-Rpc-BlockText-SetStyle) - - [Rpc.BlockText.SetStyle.Request](#anytype-Rpc-BlockText-SetStyle-Request) - - [Rpc.BlockText.SetStyle.Response](#anytype-Rpc-BlockText-SetStyle-Response) - - [Rpc.BlockText.SetStyle.Response.Error](#anytype-Rpc-BlockText-SetStyle-Response-Error) - - [Rpc.BlockText.SetText](#anytype-Rpc-BlockText-SetText) - - [Rpc.BlockText.SetText.Request](#anytype-Rpc-BlockText-SetText-Request) - - [Rpc.BlockText.SetText.Response](#anytype-Rpc-BlockText-SetText-Response) - - [Rpc.BlockText.SetText.Response.Error](#anytype-Rpc-BlockText-SetText-Response-Error) - - [Rpc.BlockVideo](#anytype-Rpc-BlockVideo) - - [Rpc.BlockVideo.SetName](#anytype-Rpc-BlockVideo-SetName) - - [Rpc.BlockVideo.SetName.Request](#anytype-Rpc-BlockVideo-SetName-Request) - - [Rpc.BlockVideo.SetName.Response](#anytype-Rpc-BlockVideo-SetName-Response) - - [Rpc.BlockVideo.SetName.Response.Error](#anytype-Rpc-BlockVideo-SetName-Response-Error) - - [Rpc.BlockVideo.SetWidth](#anytype-Rpc-BlockVideo-SetWidth) - - [Rpc.BlockVideo.SetWidth.Request](#anytype-Rpc-BlockVideo-SetWidth-Request) - - [Rpc.BlockVideo.SetWidth.Response](#anytype-Rpc-BlockVideo-SetWidth-Response) - - [Rpc.BlockVideo.SetWidth.Response.Error](#anytype-Rpc-BlockVideo-SetWidth-Response-Error) - - [Rpc.Debug](#anytype-Rpc-Debug) - - [Rpc.Debug.ExportLocalstore](#anytype-Rpc-Debug-ExportLocalstore) - - [Rpc.Debug.ExportLocalstore.Request](#anytype-Rpc-Debug-ExportLocalstore-Request) - - [Rpc.Debug.ExportLocalstore.Response](#anytype-Rpc-Debug-ExportLocalstore-Response) - - [Rpc.Debug.ExportLocalstore.Response.Error](#anytype-Rpc-Debug-ExportLocalstore-Response-Error) - - [Rpc.Debug.Ping](#anytype-Rpc-Debug-Ping) - - [Rpc.Debug.Ping.Request](#anytype-Rpc-Debug-Ping-Request) - - [Rpc.Debug.Ping.Response](#anytype-Rpc-Debug-Ping-Response) - - [Rpc.Debug.Ping.Response.Error](#anytype-Rpc-Debug-Ping-Response-Error) - - [Rpc.Debug.Sync](#anytype-Rpc-Debug-Sync) - - [Rpc.Debug.Sync.Request](#anytype-Rpc-Debug-Sync-Request) - - [Rpc.Debug.Sync.Response](#anytype-Rpc-Debug-Sync-Response) - - [Rpc.Debug.Sync.Response.Error](#anytype-Rpc-Debug-Sync-Response-Error) - - [Rpc.Debug.Thread](#anytype-Rpc-Debug-Thread) - - [Rpc.Debug.Thread.Request](#anytype-Rpc-Debug-Thread-Request) - - [Rpc.Debug.Thread.Response](#anytype-Rpc-Debug-Thread-Response) - - [Rpc.Debug.Thread.Response.Error](#anytype-Rpc-Debug-Thread-Response-Error) - - [Rpc.Debug.Tree](#anytype-Rpc-Debug-Tree) - - [Rpc.Debug.Tree.Request](#anytype-Rpc-Debug-Tree-Request) - - [Rpc.Debug.Tree.Response](#anytype-Rpc-Debug-Tree-Response) - - [Rpc.Debug.Tree.Response.Error](#anytype-Rpc-Debug-Tree-Response-Error) - - [Rpc.Debug.logInfo](#anytype-Rpc-Debug-logInfo) - - [Rpc.Debug.threadInfo](#anytype-Rpc-Debug-threadInfo) - - [Rpc.File](#anytype-Rpc-File) - - [Rpc.File.Download](#anytype-Rpc-File-Download) - - [Rpc.File.Download.Request](#anytype-Rpc-File-Download-Request) - - [Rpc.File.Download.Response](#anytype-Rpc-File-Download-Response) - - [Rpc.File.Download.Response.Error](#anytype-Rpc-File-Download-Response-Error) - - [Rpc.File.Drop](#anytype-Rpc-File-Drop) - - [Rpc.File.Drop.Request](#anytype-Rpc-File-Drop-Request) - - [Rpc.File.Drop.Response](#anytype-Rpc-File-Drop-Response) - - [Rpc.File.Drop.Response.Error](#anytype-Rpc-File-Drop-Response-Error) - - [Rpc.File.ListOffload](#anytype-Rpc-File-ListOffload) - - [Rpc.File.ListOffload.Request](#anytype-Rpc-File-ListOffload-Request) - - [Rpc.File.ListOffload.Response](#anytype-Rpc-File-ListOffload-Response) - - [Rpc.File.ListOffload.Response.Error](#anytype-Rpc-File-ListOffload-Response-Error) - - [Rpc.File.Offload](#anytype-Rpc-File-Offload) - - [Rpc.File.Offload.Request](#anytype-Rpc-File-Offload-Request) - - [Rpc.File.Offload.Response](#anytype-Rpc-File-Offload-Response) - - [Rpc.File.Offload.Response.Error](#anytype-Rpc-File-Offload-Response-Error) - - [Rpc.File.Upload](#anytype-Rpc-File-Upload) - - [Rpc.File.Upload.Request](#anytype-Rpc-File-Upload-Request) - - [Rpc.File.Upload.Response](#anytype-Rpc-File-Upload-Response) - - [Rpc.File.Upload.Response.Error](#anytype-Rpc-File-Upload-Response-Error) - - [Rpc.GenericErrorResponse](#anytype-Rpc-GenericErrorResponse) - - [Rpc.GenericErrorResponse.Error](#anytype-Rpc-GenericErrorResponse-Error) - - [Rpc.History](#anytype-Rpc-History) - - [Rpc.History.GetVersions](#anytype-Rpc-History-GetVersions) - - [Rpc.History.GetVersions.Request](#anytype-Rpc-History-GetVersions-Request) - - [Rpc.History.GetVersions.Response](#anytype-Rpc-History-GetVersions-Response) - - [Rpc.History.GetVersions.Response.Error](#anytype-Rpc-History-GetVersions-Response-Error) - - [Rpc.History.SetVersion](#anytype-Rpc-History-SetVersion) - - [Rpc.History.SetVersion.Request](#anytype-Rpc-History-SetVersion-Request) - - [Rpc.History.SetVersion.Response](#anytype-Rpc-History-SetVersion-Response) - - [Rpc.History.SetVersion.Response.Error](#anytype-Rpc-History-SetVersion-Response-Error) - - [Rpc.History.ShowVersion](#anytype-Rpc-History-ShowVersion) - - [Rpc.History.ShowVersion.Request](#anytype-Rpc-History-ShowVersion-Request) - - [Rpc.History.ShowVersion.Response](#anytype-Rpc-History-ShowVersion-Response) - - [Rpc.History.ShowVersion.Response.Error](#anytype-Rpc-History-ShowVersion-Response-Error) - - [Rpc.History.Version](#anytype-Rpc-History-Version) - - [Rpc.LinkPreview](#anytype-Rpc-LinkPreview) - - [Rpc.LinkPreview.Request](#anytype-Rpc-LinkPreview-Request) - - [Rpc.LinkPreview.Response](#anytype-Rpc-LinkPreview-Response) - - [Rpc.LinkPreview.Response.Error](#anytype-Rpc-LinkPreview-Response-Error) - - [Rpc.Log](#anytype-Rpc-Log) - - [Rpc.Log.Send](#anytype-Rpc-Log-Send) - - [Rpc.Log.Send.Request](#anytype-Rpc-Log-Send-Request) - - [Rpc.Log.Send.Response](#anytype-Rpc-Log-Send-Response) - - [Rpc.Log.Send.Response.Error](#anytype-Rpc-Log-Send-Response-Error) - - [Rpc.Metrics](#anytype-Rpc-Metrics) - - [Rpc.Metrics.SetParameters](#anytype-Rpc-Metrics-SetParameters) - - [Rpc.Metrics.SetParameters.Request](#anytype-Rpc-Metrics-SetParameters-Request) - - [Rpc.Metrics.SetParameters.Response](#anytype-Rpc-Metrics-SetParameters-Response) - - [Rpc.Metrics.SetParameters.Response.Error](#anytype-Rpc-Metrics-SetParameters-Response-Error) - - [Rpc.Navigation](#anytype-Rpc-Navigation) - - [Rpc.Navigation.GetObjectInfoWithLinks](#anytype-Rpc-Navigation-GetObjectInfoWithLinks) - - [Rpc.Navigation.GetObjectInfoWithLinks.Request](#anytype-Rpc-Navigation-GetObjectInfoWithLinks-Request) - - [Rpc.Navigation.GetObjectInfoWithLinks.Response](#anytype-Rpc-Navigation-GetObjectInfoWithLinks-Response) - - [Rpc.Navigation.GetObjectInfoWithLinks.Response.Error](#anytype-Rpc-Navigation-GetObjectInfoWithLinks-Response-Error) - - [Rpc.Navigation.ListObjects](#anytype-Rpc-Navigation-ListObjects) - - [Rpc.Navigation.ListObjects.Request](#anytype-Rpc-Navigation-ListObjects-Request) - - [Rpc.Navigation.ListObjects.Response](#anytype-Rpc-Navigation-ListObjects-Response) - - [Rpc.Navigation.ListObjects.Response.Error](#anytype-Rpc-Navigation-ListObjects-Response-Error) - - [Rpc.Object](#anytype-Rpc-Object) - - [Rpc.Object.AddWithObjectId](#anytype-Rpc-Object-AddWithObjectId) - - [Rpc.Object.AddWithObjectId.Request](#anytype-Rpc-Object-AddWithObjectId-Request) - - [Rpc.Object.AddWithObjectId.Response](#anytype-Rpc-Object-AddWithObjectId-Response) - - [Rpc.Object.AddWithObjectId.Response.Error](#anytype-Rpc-Object-AddWithObjectId-Response-Error) - - [Rpc.Object.ApplyTemplate](#anytype-Rpc-Object-ApplyTemplate) - - [Rpc.Object.ApplyTemplate.Request](#anytype-Rpc-Object-ApplyTemplate-Request) - - [Rpc.Object.ApplyTemplate.Response](#anytype-Rpc-Object-ApplyTemplate-Response) - - [Rpc.Object.ApplyTemplate.Response.Error](#anytype-Rpc-Object-ApplyTemplate-Response-Error) - - [Rpc.Object.BookmarkFetch](#anytype-Rpc-Object-BookmarkFetch) - - [Rpc.Object.BookmarkFetch.Request](#anytype-Rpc-Object-BookmarkFetch-Request) - - [Rpc.Object.BookmarkFetch.Response](#anytype-Rpc-Object-BookmarkFetch-Response) - - [Rpc.Object.BookmarkFetch.Response.Error](#anytype-Rpc-Object-BookmarkFetch-Response-Error) - - [Rpc.Object.Close](#anytype-Rpc-Object-Close) - - [Rpc.Object.Close.Request](#anytype-Rpc-Object-Close-Request) - - [Rpc.Object.Close.Response](#anytype-Rpc-Object-Close-Response) - - [Rpc.Object.Close.Response.Error](#anytype-Rpc-Object-Close-Response-Error) - - [Rpc.Object.Create](#anytype-Rpc-Object-Create) - - [Rpc.Object.Create.Request](#anytype-Rpc-Object-Create-Request) - - [Rpc.Object.Create.Response](#anytype-Rpc-Object-Create-Response) - - [Rpc.Object.Create.Response.Error](#anytype-Rpc-Object-Create-Response-Error) - - [Rpc.Object.CreateBookmark](#anytype-Rpc-Object-CreateBookmark) - - [Rpc.Object.CreateBookmark.Request](#anytype-Rpc-Object-CreateBookmark-Request) - - [Rpc.Object.CreateBookmark.Response](#anytype-Rpc-Object-CreateBookmark-Response) - - [Rpc.Object.CreateBookmark.Response.Error](#anytype-Rpc-Object-CreateBookmark-Response-Error) - - [Rpc.Object.CreateObjectType](#anytype-Rpc-Object-CreateObjectType) - - [Rpc.Object.CreateObjectType.Request](#anytype-Rpc-Object-CreateObjectType-Request) - - [Rpc.Object.CreateObjectType.Response](#anytype-Rpc-Object-CreateObjectType-Response) - - [Rpc.Object.CreateObjectType.Response.Error](#anytype-Rpc-Object-CreateObjectType-Response-Error) - - [Rpc.Object.CreateRelation](#anytype-Rpc-Object-CreateRelation) - - [Rpc.Object.CreateRelation.Request](#anytype-Rpc-Object-CreateRelation-Request) - - [Rpc.Object.CreateRelation.Response](#anytype-Rpc-Object-CreateRelation-Response) - - [Rpc.Object.CreateRelation.Response.Error](#anytype-Rpc-Object-CreateRelation-Response-Error) - - [Rpc.Object.CreateRelationOption](#anytype-Rpc-Object-CreateRelationOption) - - [Rpc.Object.CreateRelationOption.Request](#anytype-Rpc-Object-CreateRelationOption-Request) - - [Rpc.Object.CreateRelationOption.Response](#anytype-Rpc-Object-CreateRelationOption-Response) - - [Rpc.Object.CreateRelationOption.Response.Error](#anytype-Rpc-Object-CreateRelationOption-Response-Error) - - [Rpc.Object.CreateSet](#anytype-Rpc-Object-CreateSet) - - [Rpc.Object.CreateSet.Request](#anytype-Rpc-Object-CreateSet-Request) - - [Rpc.Object.CreateSet.Response](#anytype-Rpc-Object-CreateSet-Response) - - [Rpc.Object.CreateSet.Response.Error](#anytype-Rpc-Object-CreateSet-Response-Error) - - [Rpc.Object.Duplicate](#anytype-Rpc-Object-Duplicate) - - [Rpc.Object.Duplicate.Request](#anytype-Rpc-Object-Duplicate-Request) - - [Rpc.Object.Duplicate.Response](#anytype-Rpc-Object-Duplicate-Response) - - [Rpc.Object.Duplicate.Response.Error](#anytype-Rpc-Object-Duplicate-Response-Error) - - [Rpc.Object.Graph](#anytype-Rpc-Object-Graph) - - [Rpc.Object.Graph.Edge](#anytype-Rpc-Object-Graph-Edge) - - [Rpc.Object.Graph.Request](#anytype-Rpc-Object-Graph-Request) - - [Rpc.Object.Graph.Response](#anytype-Rpc-Object-Graph-Response) - - [Rpc.Object.Graph.Response.Error](#anytype-Rpc-Object-Graph-Response-Error) - - [Rpc.Object.GroupsSubscribe](#anytype-Rpc-Object-GroupsSubscribe) - - [Rpc.Object.GroupsSubscribe.Request](#anytype-Rpc-Object-GroupsSubscribe-Request) - - [Rpc.Object.GroupsSubscribe.Response](#anytype-Rpc-Object-GroupsSubscribe-Response) - - [Rpc.Object.GroupsSubscribe.Response.Error](#anytype-Rpc-Object-GroupsSubscribe-Response-Error) - - [Rpc.Object.Import](#anytype-Rpc-Object-Import) - - [Rpc.Object.Import.Request](#anytype-Rpc-Object-Import-Request) - - [Rpc.Object.Import.Request.BookmarksParams](#anytype-Rpc-Object-Import-Request-BookmarksParams) - - [Rpc.Object.Import.Request.NotionParams](#anytype-Rpc-Object-Import-Request-NotionParams) - - [Rpc.Object.Import.Request.Snapshot](#anytype-Rpc-Object-Import-Request-Snapshot) - - [Rpc.Object.Import.Response](#anytype-Rpc-Object-Import-Response) - - [Rpc.Object.Import.Response.Error](#anytype-Rpc-Object-Import-Response-Error) - - [Rpc.Object.ImportList](#anytype-Rpc-Object-ImportList) - - [Rpc.Object.ImportList.ImportResponse](#anytype-Rpc-Object-ImportList-ImportResponse) - - [Rpc.Object.ImportList.Request](#anytype-Rpc-Object-ImportList-Request) - - [Rpc.Object.ImportList.Response](#anytype-Rpc-Object-ImportList-Response) - - [Rpc.Object.ImportList.Response.Error](#anytype-Rpc-Object-ImportList-Response-Error) - - [Rpc.Object.ImportMarkdown](#anytype-Rpc-Object-ImportMarkdown) - - [Rpc.Object.ImportMarkdown.Request](#anytype-Rpc-Object-ImportMarkdown-Request) - - [Rpc.Object.ImportMarkdown.Response](#anytype-Rpc-Object-ImportMarkdown-Response) - - [Rpc.Object.ImportMarkdown.Response.Error](#anytype-Rpc-Object-ImportMarkdown-Response-Error) - - [Rpc.Object.ListDelete](#anytype-Rpc-Object-ListDelete) - - [Rpc.Object.ListDelete.Request](#anytype-Rpc-Object-ListDelete-Request) - - [Rpc.Object.ListDelete.Response](#anytype-Rpc-Object-ListDelete-Response) - - [Rpc.Object.ListDelete.Response.Error](#anytype-Rpc-Object-ListDelete-Response-Error) - - [Rpc.Object.ListDuplicate](#anytype-Rpc-Object-ListDuplicate) - - [Rpc.Object.ListDuplicate.Request](#anytype-Rpc-Object-ListDuplicate-Request) - - [Rpc.Object.ListDuplicate.Response](#anytype-Rpc-Object-ListDuplicate-Response) - - [Rpc.Object.ListDuplicate.Response.Error](#anytype-Rpc-Object-ListDuplicate-Response-Error) - - [Rpc.Object.ListExport](#anytype-Rpc-Object-ListExport) - - [Rpc.Object.ListExport.Request](#anytype-Rpc-Object-ListExport-Request) - - [Rpc.Object.ListExport.Response](#anytype-Rpc-Object-ListExport-Response) - - [Rpc.Object.ListExport.Response.Error](#anytype-Rpc-Object-ListExport-Response-Error) - - [Rpc.Object.ListSetIsArchived](#anytype-Rpc-Object-ListSetIsArchived) - - [Rpc.Object.ListSetIsArchived.Request](#anytype-Rpc-Object-ListSetIsArchived-Request) - - [Rpc.Object.ListSetIsArchived.Response](#anytype-Rpc-Object-ListSetIsArchived-Response) - - [Rpc.Object.ListSetIsArchived.Response.Error](#anytype-Rpc-Object-ListSetIsArchived-Response-Error) - - [Rpc.Object.ListSetIsFavorite](#anytype-Rpc-Object-ListSetIsFavorite) - - [Rpc.Object.ListSetIsFavorite.Request](#anytype-Rpc-Object-ListSetIsFavorite-Request) - - [Rpc.Object.ListSetIsFavorite.Response](#anytype-Rpc-Object-ListSetIsFavorite-Response) - - [Rpc.Object.ListSetIsFavorite.Response.Error](#anytype-Rpc-Object-ListSetIsFavorite-Response-Error) - - [Rpc.Object.Open](#anytype-Rpc-Object-Open) - - [Rpc.Object.Open.Request](#anytype-Rpc-Object-Open-Request) - - [Rpc.Object.Open.Response](#anytype-Rpc-Object-Open-Response) - - [Rpc.Object.Open.Response.Error](#anytype-Rpc-Object-Open-Response-Error) - - [Rpc.Object.OpenBreadcrumbs](#anytype-Rpc-Object-OpenBreadcrumbs) - - [Rpc.Object.OpenBreadcrumbs.Request](#anytype-Rpc-Object-OpenBreadcrumbs-Request) - - [Rpc.Object.OpenBreadcrumbs.Response](#anytype-Rpc-Object-OpenBreadcrumbs-Response) - - [Rpc.Object.OpenBreadcrumbs.Response.Error](#anytype-Rpc-Object-OpenBreadcrumbs-Response-Error) - - [Rpc.Object.Redo](#anytype-Rpc-Object-Redo) - - [Rpc.Object.Redo.Request](#anytype-Rpc-Object-Redo-Request) - - [Rpc.Object.Redo.Response](#anytype-Rpc-Object-Redo-Response) - - [Rpc.Object.Redo.Response.Error](#anytype-Rpc-Object-Redo-Response-Error) - - [Rpc.Object.Search](#anytype-Rpc-Object-Search) - - [Rpc.Object.Search.Request](#anytype-Rpc-Object-Search-Request) - - [Rpc.Object.Search.Response](#anytype-Rpc-Object-Search-Response) - - [Rpc.Object.Search.Response.Error](#anytype-Rpc-Object-Search-Response-Error) - - [Rpc.Object.SearchSubscribe](#anytype-Rpc-Object-SearchSubscribe) - - [Rpc.Object.SearchSubscribe.Request](#anytype-Rpc-Object-SearchSubscribe-Request) - - [Rpc.Object.SearchSubscribe.Response](#anytype-Rpc-Object-SearchSubscribe-Response) - - [Rpc.Object.SearchSubscribe.Response.Error](#anytype-Rpc-Object-SearchSubscribe-Response-Error) - - [Rpc.Object.SearchUnsubscribe](#anytype-Rpc-Object-SearchUnsubscribe) - - [Rpc.Object.SearchUnsubscribe.Request](#anytype-Rpc-Object-SearchUnsubscribe-Request) - - [Rpc.Object.SearchUnsubscribe.Response](#anytype-Rpc-Object-SearchUnsubscribe-Response) - - [Rpc.Object.SearchUnsubscribe.Response.Error](#anytype-Rpc-Object-SearchUnsubscribe-Response-Error) - - [Rpc.Object.SetBreadcrumbs](#anytype-Rpc-Object-SetBreadcrumbs) - - [Rpc.Object.SetBreadcrumbs.Request](#anytype-Rpc-Object-SetBreadcrumbs-Request) - - [Rpc.Object.SetBreadcrumbs.Response](#anytype-Rpc-Object-SetBreadcrumbs-Response) - - [Rpc.Object.SetBreadcrumbs.Response.Error](#anytype-Rpc-Object-SetBreadcrumbs-Response-Error) - - [Rpc.Object.SetDetails](#anytype-Rpc-Object-SetDetails) - - [Rpc.Object.SetDetails.Detail](#anytype-Rpc-Object-SetDetails-Detail) - - [Rpc.Object.SetDetails.Request](#anytype-Rpc-Object-SetDetails-Request) - - [Rpc.Object.SetDetails.Response](#anytype-Rpc-Object-SetDetails-Response) - - [Rpc.Object.SetDetails.Response.Error](#anytype-Rpc-Object-SetDetails-Response-Error) - - [Rpc.Object.SetInternalFlags](#anytype-Rpc-Object-SetInternalFlags) - - [Rpc.Object.SetInternalFlags.Request](#anytype-Rpc-Object-SetInternalFlags-Request) - - [Rpc.Object.SetInternalFlags.Response](#anytype-Rpc-Object-SetInternalFlags-Response) - - [Rpc.Object.SetInternalFlags.Response.Error](#anytype-Rpc-Object-SetInternalFlags-Response-Error) - - [Rpc.Object.SetIsArchived](#anytype-Rpc-Object-SetIsArchived) - - [Rpc.Object.SetIsArchived.Request](#anytype-Rpc-Object-SetIsArchived-Request) - - [Rpc.Object.SetIsArchived.Response](#anytype-Rpc-Object-SetIsArchived-Response) - - [Rpc.Object.SetIsArchived.Response.Error](#anytype-Rpc-Object-SetIsArchived-Response-Error) - - [Rpc.Object.SetIsFavorite](#anytype-Rpc-Object-SetIsFavorite) - - [Rpc.Object.SetIsFavorite.Request](#anytype-Rpc-Object-SetIsFavorite-Request) - - [Rpc.Object.SetIsFavorite.Response](#anytype-Rpc-Object-SetIsFavorite-Response) - - [Rpc.Object.SetIsFavorite.Response.Error](#anytype-Rpc-Object-SetIsFavorite-Response-Error) - - [Rpc.Object.SetLayout](#anytype-Rpc-Object-SetLayout) - - [Rpc.Object.SetLayout.Request](#anytype-Rpc-Object-SetLayout-Request) - - [Rpc.Object.SetLayout.Response](#anytype-Rpc-Object-SetLayout-Response) - - [Rpc.Object.SetLayout.Response.Error](#anytype-Rpc-Object-SetLayout-Response-Error) - - [Rpc.Object.SetObjectType](#anytype-Rpc-Object-SetObjectType) - - [Rpc.Object.SetObjectType.Request](#anytype-Rpc-Object-SetObjectType-Request) - - [Rpc.Object.SetObjectType.Response](#anytype-Rpc-Object-SetObjectType-Response) - - [Rpc.Object.SetObjectType.Response.Error](#anytype-Rpc-Object-SetObjectType-Response-Error) - - [Rpc.Object.ShareByLink](#anytype-Rpc-Object-ShareByLink) - - [Rpc.Object.ShareByLink.Request](#anytype-Rpc-Object-ShareByLink-Request) - - [Rpc.Object.ShareByLink.Response](#anytype-Rpc-Object-ShareByLink-Response) - - [Rpc.Object.ShareByLink.Response.Error](#anytype-Rpc-Object-ShareByLink-Response-Error) - - [Rpc.Object.Show](#anytype-Rpc-Object-Show) - - [Rpc.Object.Show.Request](#anytype-Rpc-Object-Show-Request) - - [Rpc.Object.Show.Response](#anytype-Rpc-Object-Show-Response) - - [Rpc.Object.Show.Response.Error](#anytype-Rpc-Object-Show-Response-Error) - - [Rpc.Object.SubscribeIds](#anytype-Rpc-Object-SubscribeIds) - - [Rpc.Object.SubscribeIds.Request](#anytype-Rpc-Object-SubscribeIds-Request) - - [Rpc.Object.SubscribeIds.Response](#anytype-Rpc-Object-SubscribeIds-Response) - - [Rpc.Object.SubscribeIds.Response.Error](#anytype-Rpc-Object-SubscribeIds-Response-Error) - - [Rpc.Object.ToBookmark](#anytype-Rpc-Object-ToBookmark) - - [Rpc.Object.ToBookmark.Request](#anytype-Rpc-Object-ToBookmark-Request) - - [Rpc.Object.ToBookmark.Response](#anytype-Rpc-Object-ToBookmark-Response) - - [Rpc.Object.ToBookmark.Response.Error](#anytype-Rpc-Object-ToBookmark-Response-Error) - - [Rpc.Object.ToSet](#anytype-Rpc-Object-ToSet) - - [Rpc.Object.ToSet.Request](#anytype-Rpc-Object-ToSet-Request) - - [Rpc.Object.ToSet.Response](#anytype-Rpc-Object-ToSet-Response) - - [Rpc.Object.ToSet.Response.Error](#anytype-Rpc-Object-ToSet-Response-Error) - - [Rpc.Object.Undo](#anytype-Rpc-Object-Undo) - - [Rpc.Object.Undo.Request](#anytype-Rpc-Object-Undo-Request) - - [Rpc.Object.Undo.Response](#anytype-Rpc-Object-Undo-Response) - - [Rpc.Object.Undo.Response.Error](#anytype-Rpc-Object-Undo-Response-Error) - - [Rpc.Object.UndoRedoCounter](#anytype-Rpc-Object-UndoRedoCounter) - - [Rpc.ObjectRelation](#anytype-Rpc-ObjectRelation) - - [Rpc.ObjectRelation.Add](#anytype-Rpc-ObjectRelation-Add) - - [Rpc.ObjectRelation.Add.Request](#anytype-Rpc-ObjectRelation-Add-Request) - - [Rpc.ObjectRelation.Add.Response](#anytype-Rpc-ObjectRelation-Add-Response) - - [Rpc.ObjectRelation.Add.Response.Error](#anytype-Rpc-ObjectRelation-Add-Response-Error) - - [Rpc.ObjectRelation.AddFeatured](#anytype-Rpc-ObjectRelation-AddFeatured) - - [Rpc.ObjectRelation.AddFeatured.Request](#anytype-Rpc-ObjectRelation-AddFeatured-Request) - - [Rpc.ObjectRelation.AddFeatured.Response](#anytype-Rpc-ObjectRelation-AddFeatured-Response) - - [Rpc.ObjectRelation.AddFeatured.Response.Error](#anytype-Rpc-ObjectRelation-AddFeatured-Response-Error) - - [Rpc.ObjectRelation.Delete](#anytype-Rpc-ObjectRelation-Delete) - - [Rpc.ObjectRelation.Delete.Request](#anytype-Rpc-ObjectRelation-Delete-Request) - - [Rpc.ObjectRelation.Delete.Response](#anytype-Rpc-ObjectRelation-Delete-Response) - - [Rpc.ObjectRelation.Delete.Response.Error](#anytype-Rpc-ObjectRelation-Delete-Response-Error) - - [Rpc.ObjectRelation.ListAvailable](#anytype-Rpc-ObjectRelation-ListAvailable) - - [Rpc.ObjectRelation.ListAvailable.Request](#anytype-Rpc-ObjectRelation-ListAvailable-Request) - - [Rpc.ObjectRelation.ListAvailable.Response](#anytype-Rpc-ObjectRelation-ListAvailable-Response) - - [Rpc.ObjectRelation.ListAvailable.Response.Error](#anytype-Rpc-ObjectRelation-ListAvailable-Response-Error) - - [Rpc.ObjectRelation.RemoveFeatured](#anytype-Rpc-ObjectRelation-RemoveFeatured) - - [Rpc.ObjectRelation.RemoveFeatured.Request](#anytype-Rpc-ObjectRelation-RemoveFeatured-Request) - - [Rpc.ObjectRelation.RemoveFeatured.Response](#anytype-Rpc-ObjectRelation-RemoveFeatured-Response) - - [Rpc.ObjectRelation.RemoveFeatured.Response.Error](#anytype-Rpc-ObjectRelation-RemoveFeatured-Response-Error) - - [Rpc.ObjectType](#anytype-Rpc-ObjectType) - - [Rpc.ObjectType.Relation](#anytype-Rpc-ObjectType-Relation) - - [Rpc.ObjectType.Relation.Add](#anytype-Rpc-ObjectType-Relation-Add) - - [Rpc.ObjectType.Relation.Add.Request](#anytype-Rpc-ObjectType-Relation-Add-Request) - - [Rpc.ObjectType.Relation.Add.Response](#anytype-Rpc-ObjectType-Relation-Add-Response) - - [Rpc.ObjectType.Relation.Add.Response.Error](#anytype-Rpc-ObjectType-Relation-Add-Response-Error) - - [Rpc.ObjectType.Relation.List](#anytype-Rpc-ObjectType-Relation-List) - - [Rpc.ObjectType.Relation.List.Request](#anytype-Rpc-ObjectType-Relation-List-Request) - - [Rpc.ObjectType.Relation.List.Response](#anytype-Rpc-ObjectType-Relation-List-Response) - - [Rpc.ObjectType.Relation.List.Response.Error](#anytype-Rpc-ObjectType-Relation-List-Response-Error) - - [Rpc.ObjectType.Relation.Remove](#anytype-Rpc-ObjectType-Relation-Remove) - - [Rpc.ObjectType.Relation.Remove.Request](#anytype-Rpc-ObjectType-Relation-Remove-Request) - - [Rpc.ObjectType.Relation.Remove.Response](#anytype-Rpc-ObjectType-Relation-Remove-Response) - - [Rpc.ObjectType.Relation.Remove.Response.Error](#anytype-Rpc-ObjectType-Relation-Remove-Response-Error) - - [Rpc.Process](#anytype-Rpc-Process) - - [Rpc.Process.Cancel](#anytype-Rpc-Process-Cancel) - - [Rpc.Process.Cancel.Request](#anytype-Rpc-Process-Cancel-Request) - - [Rpc.Process.Cancel.Response](#anytype-Rpc-Process-Cancel-Response) - - [Rpc.Process.Cancel.Response.Error](#anytype-Rpc-Process-Cancel-Response-Error) - - [Rpc.Relation](#anytype-Rpc-Relation) - - [Rpc.Relation.ListRemoveOption](#anytype-Rpc-Relation-ListRemoveOption) - - [Rpc.Relation.ListRemoveOption.Request](#anytype-Rpc-Relation-ListRemoveOption-Request) - - [Rpc.Relation.ListRemoveOption.Response](#anytype-Rpc-Relation-ListRemoveOption-Response) - - [Rpc.Relation.ListRemoveOption.Response.Error](#anytype-Rpc-Relation-ListRemoveOption-Response-Error) - - [Rpc.Relation.Options](#anytype-Rpc-Relation-Options) - - [Rpc.Relation.Options.Request](#anytype-Rpc-Relation-Options-Request) - - [Rpc.Relation.Options.Response](#anytype-Rpc-Relation-Options-Response) - - [Rpc.Relation.Options.Response.Error](#anytype-Rpc-Relation-Options-Response-Error) - - [Rpc.Template](#anytype-Rpc-Template) - - [Rpc.Template.Clone](#anytype-Rpc-Template-Clone) - - [Rpc.Template.Clone.Request](#anytype-Rpc-Template-Clone-Request) - - [Rpc.Template.Clone.Response](#anytype-Rpc-Template-Clone-Response) - - [Rpc.Template.Clone.Response.Error](#anytype-Rpc-Template-Clone-Response-Error) - - [Rpc.Template.CreateFromObject](#anytype-Rpc-Template-CreateFromObject) - - [Rpc.Template.CreateFromObject.Request](#anytype-Rpc-Template-CreateFromObject-Request) - - [Rpc.Template.CreateFromObject.Response](#anytype-Rpc-Template-CreateFromObject-Response) - - [Rpc.Template.CreateFromObject.Response.Error](#anytype-Rpc-Template-CreateFromObject-Response-Error) - - [Rpc.Template.CreateFromObjectType](#anytype-Rpc-Template-CreateFromObjectType) - - [Rpc.Template.CreateFromObjectType.Request](#anytype-Rpc-Template-CreateFromObjectType-Request) - - [Rpc.Template.CreateFromObjectType.Response](#anytype-Rpc-Template-CreateFromObjectType-Response) - - [Rpc.Template.CreateFromObjectType.Response.Error](#anytype-Rpc-Template-CreateFromObjectType-Response-Error) - - [Rpc.Template.ExportAll](#anytype-Rpc-Template-ExportAll) - - [Rpc.Template.ExportAll.Request](#anytype-Rpc-Template-ExportAll-Request) - - [Rpc.Template.ExportAll.Response](#anytype-Rpc-Template-ExportAll-Response) - - [Rpc.Template.ExportAll.Response.Error](#anytype-Rpc-Template-ExportAll-Response-Error) - - [Rpc.Unsplash](#anytype-Rpc-Unsplash) - - [Rpc.Unsplash.Download](#anytype-Rpc-Unsplash-Download) - - [Rpc.Unsplash.Download.Request](#anytype-Rpc-Unsplash-Download-Request) - - [Rpc.Unsplash.Download.Response](#anytype-Rpc-Unsplash-Download-Response) - - [Rpc.Unsplash.Download.Response.Error](#anytype-Rpc-Unsplash-Download-Response-Error) - - [Rpc.Unsplash.Search](#anytype-Rpc-Unsplash-Search) - - [Rpc.Unsplash.Search.Request](#anytype-Rpc-Unsplash-Search-Request) - - [Rpc.Unsplash.Search.Response](#anytype-Rpc-Unsplash-Search-Response) - - [Rpc.Unsplash.Search.Response.Error](#anytype-Rpc-Unsplash-Search-Response-Error) - - [Rpc.Unsplash.Search.Response.Picture](#anytype-Rpc-Unsplash-Search-Response-Picture) - - [Rpc.Wallet](#anytype-Rpc-Wallet) - - [Rpc.Wallet.CloseSession](#anytype-Rpc-Wallet-CloseSession) - - [Rpc.Wallet.CloseSession.Request](#anytype-Rpc-Wallet-CloseSession-Request) - - [Rpc.Wallet.CloseSession.Response](#anytype-Rpc-Wallet-CloseSession-Response) - - [Rpc.Wallet.CloseSession.Response.Error](#anytype-Rpc-Wallet-CloseSession-Response-Error) - - [Rpc.Wallet.Convert](#anytype-Rpc-Wallet-Convert) - - [Rpc.Wallet.Convert.Request](#anytype-Rpc-Wallet-Convert-Request) - - [Rpc.Wallet.Convert.Response](#anytype-Rpc-Wallet-Convert-Response) - - [Rpc.Wallet.Convert.Response.Error](#anytype-Rpc-Wallet-Convert-Response-Error) - - [Rpc.Wallet.Create](#anytype-Rpc-Wallet-Create) - - [Rpc.Wallet.Create.Request](#anytype-Rpc-Wallet-Create-Request) - - [Rpc.Wallet.Create.Response](#anytype-Rpc-Wallet-Create-Response) - - [Rpc.Wallet.Create.Response.Error](#anytype-Rpc-Wallet-Create-Response-Error) - - [Rpc.Wallet.CreateSession](#anytype-Rpc-Wallet-CreateSession) - - [Rpc.Wallet.CreateSession.Request](#anytype-Rpc-Wallet-CreateSession-Request) - - [Rpc.Wallet.CreateSession.Response](#anytype-Rpc-Wallet-CreateSession-Response) - - [Rpc.Wallet.CreateSession.Response.Error](#anytype-Rpc-Wallet-CreateSession-Response-Error) - - [Rpc.Wallet.Recover](#anytype-Rpc-Wallet-Recover) - - [Rpc.Wallet.Recover.Request](#anytype-Rpc-Wallet-Recover-Request) - - [Rpc.Wallet.Recover.Response](#anytype-Rpc-Wallet-Recover-Response) - - [Rpc.Wallet.Recover.Response.Error](#anytype-Rpc-Wallet-Recover-Response-Error) - - [Rpc.Workspace](#anytype-Rpc-Workspace) - - [Rpc.Workspace.Create](#anytype-Rpc-Workspace-Create) - - [Rpc.Workspace.Create.Request](#anytype-Rpc-Workspace-Create-Request) - - [Rpc.Workspace.Create.Response](#anytype-Rpc-Workspace-Create-Response) - - [Rpc.Workspace.Create.Response.Error](#anytype-Rpc-Workspace-Create-Response-Error) - - [Rpc.Workspace.Export](#anytype-Rpc-Workspace-Export) - - [Rpc.Workspace.Export.Request](#anytype-Rpc-Workspace-Export-Request) - - [Rpc.Workspace.Export.Response](#anytype-Rpc-Workspace-Export-Response) - - [Rpc.Workspace.Export.Response.Error](#anytype-Rpc-Workspace-Export-Response-Error) - - [Rpc.Workspace.GetAll](#anytype-Rpc-Workspace-GetAll) - - [Rpc.Workspace.GetAll.Request](#anytype-Rpc-Workspace-GetAll-Request) - - [Rpc.Workspace.GetAll.Response](#anytype-Rpc-Workspace-GetAll-Response) - - [Rpc.Workspace.GetAll.Response.Error](#anytype-Rpc-Workspace-GetAll-Response-Error) - - [Rpc.Workspace.GetCurrent](#anytype-Rpc-Workspace-GetCurrent) - - [Rpc.Workspace.GetCurrent.Request](#anytype-Rpc-Workspace-GetCurrent-Request) - - [Rpc.Workspace.GetCurrent.Response](#anytype-Rpc-Workspace-GetCurrent-Response) - - [Rpc.Workspace.GetCurrent.Response.Error](#anytype-Rpc-Workspace-GetCurrent-Response-Error) - - [Rpc.Workspace.Object](#anytype-Rpc-Workspace-Object) - - [Rpc.Workspace.Object.Add](#anytype-Rpc-Workspace-Object-Add) - - [Rpc.Workspace.Object.Add.Request](#anytype-Rpc-Workspace-Object-Add-Request) - - [Rpc.Workspace.Object.Add.Response](#anytype-Rpc-Workspace-Object-Add-Response) - - [Rpc.Workspace.Object.Add.Response.Error](#anytype-Rpc-Workspace-Object-Add-Response-Error) - - [Rpc.Workspace.Object.ListAdd](#anytype-Rpc-Workspace-Object-ListAdd) - - [Rpc.Workspace.Object.ListAdd.Request](#anytype-Rpc-Workspace-Object-ListAdd-Request) - - [Rpc.Workspace.Object.ListAdd.Response](#anytype-Rpc-Workspace-Object-ListAdd-Response) - - [Rpc.Workspace.Object.ListAdd.Response.Error](#anytype-Rpc-Workspace-Object-ListAdd-Response-Error) - - [Rpc.Workspace.Object.ListRemove](#anytype-Rpc-Workspace-Object-ListRemove) - - [Rpc.Workspace.Object.ListRemove.Request](#anytype-Rpc-Workspace-Object-ListRemove-Request) - - [Rpc.Workspace.Object.ListRemove.Response](#anytype-Rpc-Workspace-Object-ListRemove-Response) - - [Rpc.Workspace.Object.ListRemove.Response.Error](#anytype-Rpc-Workspace-Object-ListRemove-Response-Error) - - [Rpc.Workspace.Select](#anytype-Rpc-Workspace-Select) - - [Rpc.Workspace.Select.Request](#anytype-Rpc-Workspace-Select-Request) - - [Rpc.Workspace.Select.Response](#anytype-Rpc-Workspace-Select-Response) - - [Rpc.Workspace.Select.Response.Error](#anytype-Rpc-Workspace-Select-Response-Error) - - [Rpc.Workspace.SetIsHighlighted](#anytype-Rpc-Workspace-SetIsHighlighted) - - [Rpc.Workspace.SetIsHighlighted.Request](#anytype-Rpc-Workspace-SetIsHighlighted-Request) - - [Rpc.Workspace.SetIsHighlighted.Response](#anytype-Rpc-Workspace-SetIsHighlighted-Response) - - [Rpc.Workspace.SetIsHighlighted.Response.Error](#anytype-Rpc-Workspace-SetIsHighlighted-Response-Error) - - [StreamRequest](#anytype-StreamRequest) +- [pb/protos/commands.proto](#pb/protos/commands.proto) + - [Empty](#anytype.Empty) + - [Rpc](#anytype.Rpc) + - [Rpc.Account](#anytype.Rpc.Account) + - [Rpc.Account.Config](#anytype.Rpc.Account.Config) + - [Rpc.Account.ConfigUpdate](#anytype.Rpc.Account.ConfigUpdate) + - [Rpc.Account.ConfigUpdate.Request](#anytype.Rpc.Account.ConfigUpdate.Request) + - [Rpc.Account.ConfigUpdate.Response](#anytype.Rpc.Account.ConfigUpdate.Response) + - [Rpc.Account.ConfigUpdate.Response.Error](#anytype.Rpc.Account.ConfigUpdate.Response.Error) + - [Rpc.Account.Create](#anytype.Rpc.Account.Create) + - [Rpc.Account.Create.Request](#anytype.Rpc.Account.Create.Request) + - [Rpc.Account.Create.Response](#anytype.Rpc.Account.Create.Response) + - [Rpc.Account.Create.Response.Error](#anytype.Rpc.Account.Create.Response.Error) + - [Rpc.Account.Delete](#anytype.Rpc.Account.Delete) + - [Rpc.Account.Delete.Request](#anytype.Rpc.Account.Delete.Request) + - [Rpc.Account.Delete.Response](#anytype.Rpc.Account.Delete.Response) + - [Rpc.Account.Delete.Response.Error](#anytype.Rpc.Account.Delete.Response.Error) + - [Rpc.Account.GetConfig](#anytype.Rpc.Account.GetConfig) + - [Rpc.Account.GetConfig.Get](#anytype.Rpc.Account.GetConfig.Get) + - [Rpc.Account.GetConfig.Get.Request](#anytype.Rpc.Account.GetConfig.Get.Request) + - [Rpc.Account.Move](#anytype.Rpc.Account.Move) + - [Rpc.Account.Move.Request](#anytype.Rpc.Account.Move.Request) + - [Rpc.Account.Move.Response](#anytype.Rpc.Account.Move.Response) + - [Rpc.Account.Move.Response.Error](#anytype.Rpc.Account.Move.Response.Error) + - [Rpc.Account.Recover](#anytype.Rpc.Account.Recover) + - [Rpc.Account.Recover.Request](#anytype.Rpc.Account.Recover.Request) + - [Rpc.Account.Recover.Response](#anytype.Rpc.Account.Recover.Response) + - [Rpc.Account.Recover.Response.Error](#anytype.Rpc.Account.Recover.Response.Error) + - [Rpc.Account.Select](#anytype.Rpc.Account.Select) + - [Rpc.Account.Select.Request](#anytype.Rpc.Account.Select.Request) + - [Rpc.Account.Select.Response](#anytype.Rpc.Account.Select.Response) + - [Rpc.Account.Select.Response.Error](#anytype.Rpc.Account.Select.Response.Error) + - [Rpc.Account.Stop](#anytype.Rpc.Account.Stop) + - [Rpc.Account.Stop.Request](#anytype.Rpc.Account.Stop.Request) + - [Rpc.Account.Stop.Response](#anytype.Rpc.Account.Stop.Response) + - [Rpc.Account.Stop.Response.Error](#anytype.Rpc.Account.Stop.Response.Error) + - [Rpc.App](#anytype.Rpc.App) + - [Rpc.App.GetVersion](#anytype.Rpc.App.GetVersion) + - [Rpc.App.GetVersion.Request](#anytype.Rpc.App.GetVersion.Request) + - [Rpc.App.GetVersion.Response](#anytype.Rpc.App.GetVersion.Response) + - [Rpc.App.GetVersion.Response.Error](#anytype.Rpc.App.GetVersion.Response.Error) + - [Rpc.App.SetDeviceState](#anytype.Rpc.App.SetDeviceState) + - [Rpc.App.SetDeviceState.Request](#anytype.Rpc.App.SetDeviceState.Request) + - [Rpc.App.SetDeviceState.Response](#anytype.Rpc.App.SetDeviceState.Response) + - [Rpc.App.SetDeviceState.Response.Error](#anytype.Rpc.App.SetDeviceState.Response.Error) + - [Rpc.App.Shutdown](#anytype.Rpc.App.Shutdown) + - [Rpc.App.Shutdown.Request](#anytype.Rpc.App.Shutdown.Request) + - [Rpc.App.Shutdown.Response](#anytype.Rpc.App.Shutdown.Response) + - [Rpc.App.Shutdown.Response.Error](#anytype.Rpc.App.Shutdown.Response.Error) + - [Rpc.Block](#anytype.Rpc.Block) + - [Rpc.Block.Copy](#anytype.Rpc.Block.Copy) + - [Rpc.Block.Copy.Request](#anytype.Rpc.Block.Copy.Request) + - [Rpc.Block.Copy.Response](#anytype.Rpc.Block.Copy.Response) + - [Rpc.Block.Copy.Response.Error](#anytype.Rpc.Block.Copy.Response.Error) + - [Rpc.Block.Create](#anytype.Rpc.Block.Create) + - [Rpc.Block.Create.Request](#anytype.Rpc.Block.Create.Request) + - [Rpc.Block.Create.Response](#anytype.Rpc.Block.Create.Response) + - [Rpc.Block.Create.Response.Error](#anytype.Rpc.Block.Create.Response.Error) + - [Rpc.Block.CreateWidget](#anytype.Rpc.Block.CreateWidget) + - [Rpc.Block.CreateWidget.Request](#anytype.Rpc.Block.CreateWidget.Request) + - [Rpc.Block.CreateWidget.Response](#anytype.Rpc.Block.CreateWidget.Response) + - [Rpc.Block.CreateWidget.Response.Error](#anytype.Rpc.Block.CreateWidget.Response.Error) + - [Rpc.Block.Cut](#anytype.Rpc.Block.Cut) + - [Rpc.Block.Cut.Request](#anytype.Rpc.Block.Cut.Request) + - [Rpc.Block.Cut.Response](#anytype.Rpc.Block.Cut.Response) + - [Rpc.Block.Cut.Response.Error](#anytype.Rpc.Block.Cut.Response.Error) + - [Rpc.Block.Download](#anytype.Rpc.Block.Download) + - [Rpc.Block.Download.Request](#anytype.Rpc.Block.Download.Request) + - [Rpc.Block.Download.Response](#anytype.Rpc.Block.Download.Response) + - [Rpc.Block.Download.Response.Error](#anytype.Rpc.Block.Download.Response.Error) + - [Rpc.Block.Export](#anytype.Rpc.Block.Export) + - [Rpc.Block.Export.Request](#anytype.Rpc.Block.Export.Request) + - [Rpc.Block.Export.Response](#anytype.Rpc.Block.Export.Response) + - [Rpc.Block.Export.Response.Error](#anytype.Rpc.Block.Export.Response.Error) + - [Rpc.Block.ListConvertToObjects](#anytype.Rpc.Block.ListConvertToObjects) + - [Rpc.Block.ListConvertToObjects.Request](#anytype.Rpc.Block.ListConvertToObjects.Request) + - [Rpc.Block.ListConvertToObjects.Response](#anytype.Rpc.Block.ListConvertToObjects.Response) + - [Rpc.Block.ListConvertToObjects.Response.Error](#anytype.Rpc.Block.ListConvertToObjects.Response.Error) + - [Rpc.Block.ListDelete](#anytype.Rpc.Block.ListDelete) + - [Rpc.Block.ListDelete.Request](#anytype.Rpc.Block.ListDelete.Request) + - [Rpc.Block.ListDelete.Response](#anytype.Rpc.Block.ListDelete.Response) + - [Rpc.Block.ListDelete.Response.Error](#anytype.Rpc.Block.ListDelete.Response.Error) + - [Rpc.Block.ListDuplicate](#anytype.Rpc.Block.ListDuplicate) + - [Rpc.Block.ListDuplicate.Request](#anytype.Rpc.Block.ListDuplicate.Request) + - [Rpc.Block.ListDuplicate.Response](#anytype.Rpc.Block.ListDuplicate.Response) + - [Rpc.Block.ListDuplicate.Response.Error](#anytype.Rpc.Block.ListDuplicate.Response.Error) + - [Rpc.Block.ListMoveToExistingObject](#anytype.Rpc.Block.ListMoveToExistingObject) + - [Rpc.Block.ListMoveToExistingObject.Request](#anytype.Rpc.Block.ListMoveToExistingObject.Request) + - [Rpc.Block.ListMoveToExistingObject.Response](#anytype.Rpc.Block.ListMoveToExistingObject.Response) + - [Rpc.Block.ListMoveToExistingObject.Response.Error](#anytype.Rpc.Block.ListMoveToExistingObject.Response.Error) + - [Rpc.Block.ListMoveToNewObject](#anytype.Rpc.Block.ListMoveToNewObject) + - [Rpc.Block.ListMoveToNewObject.Request](#anytype.Rpc.Block.ListMoveToNewObject.Request) + - [Rpc.Block.ListMoveToNewObject.Response](#anytype.Rpc.Block.ListMoveToNewObject.Response) + - [Rpc.Block.ListMoveToNewObject.Response.Error](#anytype.Rpc.Block.ListMoveToNewObject.Response.Error) + - [Rpc.Block.ListSetAlign](#anytype.Rpc.Block.ListSetAlign) + - [Rpc.Block.ListSetAlign.Request](#anytype.Rpc.Block.ListSetAlign.Request) + - [Rpc.Block.ListSetAlign.Response](#anytype.Rpc.Block.ListSetAlign.Response) + - [Rpc.Block.ListSetAlign.Response.Error](#anytype.Rpc.Block.ListSetAlign.Response.Error) + - [Rpc.Block.ListSetBackgroundColor](#anytype.Rpc.Block.ListSetBackgroundColor) + - [Rpc.Block.ListSetBackgroundColor.Request](#anytype.Rpc.Block.ListSetBackgroundColor.Request) + - [Rpc.Block.ListSetBackgroundColor.Response](#anytype.Rpc.Block.ListSetBackgroundColor.Response) + - [Rpc.Block.ListSetBackgroundColor.Response.Error](#anytype.Rpc.Block.ListSetBackgroundColor.Response.Error) + - [Rpc.Block.ListSetFields](#anytype.Rpc.Block.ListSetFields) + - [Rpc.Block.ListSetFields.Request](#anytype.Rpc.Block.ListSetFields.Request) + - [Rpc.Block.ListSetFields.Request.BlockField](#anytype.Rpc.Block.ListSetFields.Request.BlockField) + - [Rpc.Block.ListSetFields.Response](#anytype.Rpc.Block.ListSetFields.Response) + - [Rpc.Block.ListSetFields.Response.Error](#anytype.Rpc.Block.ListSetFields.Response.Error) + - [Rpc.Block.ListSetVerticalAlign](#anytype.Rpc.Block.ListSetVerticalAlign) + - [Rpc.Block.ListSetVerticalAlign.Request](#anytype.Rpc.Block.ListSetVerticalAlign.Request) + - [Rpc.Block.ListSetVerticalAlign.Response](#anytype.Rpc.Block.ListSetVerticalAlign.Response) + - [Rpc.Block.ListSetVerticalAlign.Response.Error](#anytype.Rpc.Block.ListSetVerticalAlign.Response.Error) + - [Rpc.Block.ListTurnInto](#anytype.Rpc.Block.ListTurnInto) + - [Rpc.Block.ListTurnInto.Request](#anytype.Rpc.Block.ListTurnInto.Request) + - [Rpc.Block.ListTurnInto.Response](#anytype.Rpc.Block.ListTurnInto.Response) + - [Rpc.Block.ListTurnInto.Response.Error](#anytype.Rpc.Block.ListTurnInto.Response.Error) + - [Rpc.Block.ListUpdate](#anytype.Rpc.Block.ListUpdate) + - [Rpc.Block.ListUpdate.Request](#anytype.Rpc.Block.ListUpdate.Request) + - [Rpc.Block.ListUpdate.Request.Text](#anytype.Rpc.Block.ListUpdate.Request.Text) + - [Rpc.Block.Merge](#anytype.Rpc.Block.Merge) + - [Rpc.Block.Merge.Request](#anytype.Rpc.Block.Merge.Request) + - [Rpc.Block.Merge.Response](#anytype.Rpc.Block.Merge.Response) + - [Rpc.Block.Merge.Response.Error](#anytype.Rpc.Block.Merge.Response.Error) + - [Rpc.Block.Paste](#anytype.Rpc.Block.Paste) + - [Rpc.Block.Paste.Request](#anytype.Rpc.Block.Paste.Request) + - [Rpc.Block.Paste.Request.File](#anytype.Rpc.Block.Paste.Request.File) + - [Rpc.Block.Paste.Response](#anytype.Rpc.Block.Paste.Response) + - [Rpc.Block.Paste.Response.Error](#anytype.Rpc.Block.Paste.Response.Error) + - [Rpc.Block.Replace](#anytype.Rpc.Block.Replace) + - [Rpc.Block.Replace.Request](#anytype.Rpc.Block.Replace.Request) + - [Rpc.Block.Replace.Response](#anytype.Rpc.Block.Replace.Response) + - [Rpc.Block.Replace.Response.Error](#anytype.Rpc.Block.Replace.Response.Error) + - [Rpc.Block.SetFields](#anytype.Rpc.Block.SetFields) + - [Rpc.Block.SetFields.Request](#anytype.Rpc.Block.SetFields.Request) + - [Rpc.Block.SetFields.Response](#anytype.Rpc.Block.SetFields.Response) + - [Rpc.Block.SetFields.Response.Error](#anytype.Rpc.Block.SetFields.Response.Error) + - [Rpc.Block.Split](#anytype.Rpc.Block.Split) + - [Rpc.Block.Split.Request](#anytype.Rpc.Block.Split.Request) + - [Rpc.Block.Split.Response](#anytype.Rpc.Block.Split.Response) + - [Rpc.Block.Split.Response.Error](#anytype.Rpc.Block.Split.Response.Error) + - [Rpc.Block.Upload](#anytype.Rpc.Block.Upload) + - [Rpc.Block.Upload.Request](#anytype.Rpc.Block.Upload.Request) + - [Rpc.Block.Upload.Response](#anytype.Rpc.Block.Upload.Response) + - [Rpc.Block.Upload.Response.Error](#anytype.Rpc.Block.Upload.Response.Error) + - [Rpc.BlockBookmark](#anytype.Rpc.BlockBookmark) + - [Rpc.BlockBookmark.CreateAndFetch](#anytype.Rpc.BlockBookmark.CreateAndFetch) + - [Rpc.BlockBookmark.CreateAndFetch.Request](#anytype.Rpc.BlockBookmark.CreateAndFetch.Request) + - [Rpc.BlockBookmark.CreateAndFetch.Response](#anytype.Rpc.BlockBookmark.CreateAndFetch.Response) + - [Rpc.BlockBookmark.CreateAndFetch.Response.Error](#anytype.Rpc.BlockBookmark.CreateAndFetch.Response.Error) + - [Rpc.BlockBookmark.Fetch](#anytype.Rpc.BlockBookmark.Fetch) + - [Rpc.BlockBookmark.Fetch.Request](#anytype.Rpc.BlockBookmark.Fetch.Request) + - [Rpc.BlockBookmark.Fetch.Response](#anytype.Rpc.BlockBookmark.Fetch.Response) + - [Rpc.BlockBookmark.Fetch.Response.Error](#anytype.Rpc.BlockBookmark.Fetch.Response.Error) + - [Rpc.BlockDataview](#anytype.Rpc.BlockDataview) + - [Rpc.BlockDataview.CreateBookmark](#anytype.Rpc.BlockDataview.CreateBookmark) + - [Rpc.BlockDataview.CreateBookmark.Request](#anytype.Rpc.BlockDataview.CreateBookmark.Request) + - [Rpc.BlockDataview.CreateBookmark.Response](#anytype.Rpc.BlockDataview.CreateBookmark.Response) + - [Rpc.BlockDataview.CreateBookmark.Response.Error](#anytype.Rpc.BlockDataview.CreateBookmark.Response.Error) + - [Rpc.BlockDataview.GroupOrder](#anytype.Rpc.BlockDataview.GroupOrder) + - [Rpc.BlockDataview.GroupOrder.Update](#anytype.Rpc.BlockDataview.GroupOrder.Update) + - [Rpc.BlockDataview.GroupOrder.Update.Request](#anytype.Rpc.BlockDataview.GroupOrder.Update.Request) + - [Rpc.BlockDataview.GroupOrder.Update.Response](#anytype.Rpc.BlockDataview.GroupOrder.Update.Response) + - [Rpc.BlockDataview.GroupOrder.Update.Response.Error](#anytype.Rpc.BlockDataview.GroupOrder.Update.Response.Error) + - [Rpc.BlockDataview.ObjectOrder](#anytype.Rpc.BlockDataview.ObjectOrder) + - [Rpc.BlockDataview.ObjectOrder.Update](#anytype.Rpc.BlockDataview.ObjectOrder.Update) + - [Rpc.BlockDataview.ObjectOrder.Update.Request](#anytype.Rpc.BlockDataview.ObjectOrder.Update.Request) + - [Rpc.BlockDataview.ObjectOrder.Update.Response](#anytype.Rpc.BlockDataview.ObjectOrder.Update.Response) + - [Rpc.BlockDataview.ObjectOrder.Update.Response.Error](#anytype.Rpc.BlockDataview.ObjectOrder.Update.Response.Error) + - [Rpc.BlockDataview.Relation](#anytype.Rpc.BlockDataview.Relation) + - [Rpc.BlockDataview.Relation.Add](#anytype.Rpc.BlockDataview.Relation.Add) + - [Rpc.BlockDataview.Relation.Add.Request](#anytype.Rpc.BlockDataview.Relation.Add.Request) + - [Rpc.BlockDataview.Relation.Add.Response](#anytype.Rpc.BlockDataview.Relation.Add.Response) + - [Rpc.BlockDataview.Relation.Add.Response.Error](#anytype.Rpc.BlockDataview.Relation.Add.Response.Error) + - [Rpc.BlockDataview.Relation.Delete](#anytype.Rpc.BlockDataview.Relation.Delete) + - [Rpc.BlockDataview.Relation.Delete.Request](#anytype.Rpc.BlockDataview.Relation.Delete.Request) + - [Rpc.BlockDataview.Relation.Delete.Response](#anytype.Rpc.BlockDataview.Relation.Delete.Response) + - [Rpc.BlockDataview.Relation.Delete.Response.Error](#anytype.Rpc.BlockDataview.Relation.Delete.Response.Error) + - [Rpc.BlockDataview.Relation.ListAvailable](#anytype.Rpc.BlockDataview.Relation.ListAvailable) + - [Rpc.BlockDataview.Relation.ListAvailable.Request](#anytype.Rpc.BlockDataview.Relation.ListAvailable.Request) + - [Rpc.BlockDataview.Relation.ListAvailable.Response](#anytype.Rpc.BlockDataview.Relation.ListAvailable.Response) + - [Rpc.BlockDataview.Relation.ListAvailable.Response.Error](#anytype.Rpc.BlockDataview.Relation.ListAvailable.Response.Error) + - [Rpc.BlockDataview.SetSource](#anytype.Rpc.BlockDataview.SetSource) + - [Rpc.BlockDataview.SetSource.Request](#anytype.Rpc.BlockDataview.SetSource.Request) + - [Rpc.BlockDataview.SetSource.Response](#anytype.Rpc.BlockDataview.SetSource.Response) + - [Rpc.BlockDataview.SetSource.Response.Error](#anytype.Rpc.BlockDataview.SetSource.Response.Error) + - [Rpc.BlockDataview.View](#anytype.Rpc.BlockDataview.View) + - [Rpc.BlockDataview.View.Create](#anytype.Rpc.BlockDataview.View.Create) + - [Rpc.BlockDataview.View.Create.Request](#anytype.Rpc.BlockDataview.View.Create.Request) + - [Rpc.BlockDataview.View.Create.Response](#anytype.Rpc.BlockDataview.View.Create.Response) + - [Rpc.BlockDataview.View.Create.Response.Error](#anytype.Rpc.BlockDataview.View.Create.Response.Error) + - [Rpc.BlockDataview.View.Delete](#anytype.Rpc.BlockDataview.View.Delete) + - [Rpc.BlockDataview.View.Delete.Request](#anytype.Rpc.BlockDataview.View.Delete.Request) + - [Rpc.BlockDataview.View.Delete.Response](#anytype.Rpc.BlockDataview.View.Delete.Response) + - [Rpc.BlockDataview.View.Delete.Response.Error](#anytype.Rpc.BlockDataview.View.Delete.Response.Error) + - [Rpc.BlockDataview.View.SetActive](#anytype.Rpc.BlockDataview.View.SetActive) + - [Rpc.BlockDataview.View.SetActive.Request](#anytype.Rpc.BlockDataview.View.SetActive.Request) + - [Rpc.BlockDataview.View.SetActive.Response](#anytype.Rpc.BlockDataview.View.SetActive.Response) + - [Rpc.BlockDataview.View.SetActive.Response.Error](#anytype.Rpc.BlockDataview.View.SetActive.Response.Error) + - [Rpc.BlockDataview.View.SetPosition](#anytype.Rpc.BlockDataview.View.SetPosition) + - [Rpc.BlockDataview.View.SetPosition.Request](#anytype.Rpc.BlockDataview.View.SetPosition.Request) + - [Rpc.BlockDataview.View.SetPosition.Response](#anytype.Rpc.BlockDataview.View.SetPosition.Response) + - [Rpc.BlockDataview.View.SetPosition.Response.Error](#anytype.Rpc.BlockDataview.View.SetPosition.Response.Error) + - [Rpc.BlockDataview.View.Update](#anytype.Rpc.BlockDataview.View.Update) + - [Rpc.BlockDataview.View.Update.Request](#anytype.Rpc.BlockDataview.View.Update.Request) + - [Rpc.BlockDataview.View.Update.Response](#anytype.Rpc.BlockDataview.View.Update.Response) + - [Rpc.BlockDataview.View.Update.Response.Error](#anytype.Rpc.BlockDataview.View.Update.Response.Error) + - [Rpc.BlockDiv](#anytype.Rpc.BlockDiv) + - [Rpc.BlockDiv.ListSetStyle](#anytype.Rpc.BlockDiv.ListSetStyle) + - [Rpc.BlockDiv.ListSetStyle.Request](#anytype.Rpc.BlockDiv.ListSetStyle.Request) + - [Rpc.BlockDiv.ListSetStyle.Response](#anytype.Rpc.BlockDiv.ListSetStyle.Response) + - [Rpc.BlockDiv.ListSetStyle.Response.Error](#anytype.Rpc.BlockDiv.ListSetStyle.Response.Error) + - [Rpc.BlockFile](#anytype.Rpc.BlockFile) + - [Rpc.BlockFile.CreateAndUpload](#anytype.Rpc.BlockFile.CreateAndUpload) + - [Rpc.BlockFile.CreateAndUpload.Request](#anytype.Rpc.BlockFile.CreateAndUpload.Request) + - [Rpc.BlockFile.CreateAndUpload.Response](#anytype.Rpc.BlockFile.CreateAndUpload.Response) + - [Rpc.BlockFile.CreateAndUpload.Response.Error](#anytype.Rpc.BlockFile.CreateAndUpload.Response.Error) + - [Rpc.BlockFile.ListSetStyle](#anytype.Rpc.BlockFile.ListSetStyle) + - [Rpc.BlockFile.ListSetStyle.Request](#anytype.Rpc.BlockFile.ListSetStyle.Request) + - [Rpc.BlockFile.ListSetStyle.Response](#anytype.Rpc.BlockFile.ListSetStyle.Response) + - [Rpc.BlockFile.ListSetStyle.Response.Error](#anytype.Rpc.BlockFile.ListSetStyle.Response.Error) + - [Rpc.BlockFile.SetName](#anytype.Rpc.BlockFile.SetName) + - [Rpc.BlockFile.SetName.Request](#anytype.Rpc.BlockFile.SetName.Request) + - [Rpc.BlockFile.SetName.Response](#anytype.Rpc.BlockFile.SetName.Response) + - [Rpc.BlockFile.SetName.Response.Error](#anytype.Rpc.BlockFile.SetName.Response.Error) + - [Rpc.BlockImage](#anytype.Rpc.BlockImage) + - [Rpc.BlockImage.SetName](#anytype.Rpc.BlockImage.SetName) + - [Rpc.BlockImage.SetName.Request](#anytype.Rpc.BlockImage.SetName.Request) + - [Rpc.BlockImage.SetName.Response](#anytype.Rpc.BlockImage.SetName.Response) + - [Rpc.BlockImage.SetName.Response.Error](#anytype.Rpc.BlockImage.SetName.Response.Error) + - [Rpc.BlockImage.SetWidth](#anytype.Rpc.BlockImage.SetWidth) + - [Rpc.BlockImage.SetWidth.Request](#anytype.Rpc.BlockImage.SetWidth.Request) + - [Rpc.BlockImage.SetWidth.Response](#anytype.Rpc.BlockImage.SetWidth.Response) + - [Rpc.BlockImage.SetWidth.Response.Error](#anytype.Rpc.BlockImage.SetWidth.Response.Error) + - [Rpc.BlockLatex](#anytype.Rpc.BlockLatex) + - [Rpc.BlockLatex.SetText](#anytype.Rpc.BlockLatex.SetText) + - [Rpc.BlockLatex.SetText.Request](#anytype.Rpc.BlockLatex.SetText.Request) + - [Rpc.BlockLatex.SetText.Response](#anytype.Rpc.BlockLatex.SetText.Response) + - [Rpc.BlockLatex.SetText.Response.Error](#anytype.Rpc.BlockLatex.SetText.Response.Error) + - [Rpc.BlockLink](#anytype.Rpc.BlockLink) + - [Rpc.BlockLink.CreateWithObject](#anytype.Rpc.BlockLink.CreateWithObject) + - [Rpc.BlockLink.CreateWithObject.Request](#anytype.Rpc.BlockLink.CreateWithObject.Request) + - [Rpc.BlockLink.CreateWithObject.Response](#anytype.Rpc.BlockLink.CreateWithObject.Response) + - [Rpc.BlockLink.CreateWithObject.Response.Error](#anytype.Rpc.BlockLink.CreateWithObject.Response.Error) + - [Rpc.BlockLink.ListSetAppearance](#anytype.Rpc.BlockLink.ListSetAppearance) + - [Rpc.BlockLink.ListSetAppearance.Request](#anytype.Rpc.BlockLink.ListSetAppearance.Request) + - [Rpc.BlockLink.ListSetAppearance.Response](#anytype.Rpc.BlockLink.ListSetAppearance.Response) + - [Rpc.BlockLink.ListSetAppearance.Response.Error](#anytype.Rpc.BlockLink.ListSetAppearance.Response.Error) + - [Rpc.BlockRelation](#anytype.Rpc.BlockRelation) + - [Rpc.BlockRelation.Add](#anytype.Rpc.BlockRelation.Add) + - [Rpc.BlockRelation.Add.Request](#anytype.Rpc.BlockRelation.Add.Request) + - [Rpc.BlockRelation.Add.Response](#anytype.Rpc.BlockRelation.Add.Response) + - [Rpc.BlockRelation.Add.Response.Error](#anytype.Rpc.BlockRelation.Add.Response.Error) + - [Rpc.BlockRelation.SetKey](#anytype.Rpc.BlockRelation.SetKey) + - [Rpc.BlockRelation.SetKey.Request](#anytype.Rpc.BlockRelation.SetKey.Request) + - [Rpc.BlockRelation.SetKey.Response](#anytype.Rpc.BlockRelation.SetKey.Response) + - [Rpc.BlockRelation.SetKey.Response.Error](#anytype.Rpc.BlockRelation.SetKey.Response.Error) + - [Rpc.BlockTable](#anytype.Rpc.BlockTable) + - [Rpc.BlockTable.ColumnCreate](#anytype.Rpc.BlockTable.ColumnCreate) + - [Rpc.BlockTable.ColumnCreate.Request](#anytype.Rpc.BlockTable.ColumnCreate.Request) + - [Rpc.BlockTable.ColumnCreate.Response](#anytype.Rpc.BlockTable.ColumnCreate.Response) + - [Rpc.BlockTable.ColumnCreate.Response.Error](#anytype.Rpc.BlockTable.ColumnCreate.Response.Error) + - [Rpc.BlockTable.ColumnDelete](#anytype.Rpc.BlockTable.ColumnDelete) + - [Rpc.BlockTable.ColumnDelete.Request](#anytype.Rpc.BlockTable.ColumnDelete.Request) + - [Rpc.BlockTable.ColumnDelete.Response](#anytype.Rpc.BlockTable.ColumnDelete.Response) + - [Rpc.BlockTable.ColumnDelete.Response.Error](#anytype.Rpc.BlockTable.ColumnDelete.Response.Error) + - [Rpc.BlockTable.ColumnDuplicate](#anytype.Rpc.BlockTable.ColumnDuplicate) + - [Rpc.BlockTable.ColumnDuplicate.Request](#anytype.Rpc.BlockTable.ColumnDuplicate.Request) + - [Rpc.BlockTable.ColumnDuplicate.Response](#anytype.Rpc.BlockTable.ColumnDuplicate.Response) + - [Rpc.BlockTable.ColumnDuplicate.Response.Error](#anytype.Rpc.BlockTable.ColumnDuplicate.Response.Error) + - [Rpc.BlockTable.ColumnListFill](#anytype.Rpc.BlockTable.ColumnListFill) + - [Rpc.BlockTable.ColumnListFill.Request](#anytype.Rpc.BlockTable.ColumnListFill.Request) + - [Rpc.BlockTable.ColumnListFill.Response](#anytype.Rpc.BlockTable.ColumnListFill.Response) + - [Rpc.BlockTable.ColumnListFill.Response.Error](#anytype.Rpc.BlockTable.ColumnListFill.Response.Error) + - [Rpc.BlockTable.ColumnMove](#anytype.Rpc.BlockTable.ColumnMove) + - [Rpc.BlockTable.ColumnMove.Request](#anytype.Rpc.BlockTable.ColumnMove.Request) + - [Rpc.BlockTable.ColumnMove.Response](#anytype.Rpc.BlockTable.ColumnMove.Response) + - [Rpc.BlockTable.ColumnMove.Response.Error](#anytype.Rpc.BlockTable.ColumnMove.Response.Error) + - [Rpc.BlockTable.Create](#anytype.Rpc.BlockTable.Create) + - [Rpc.BlockTable.Create.Request](#anytype.Rpc.BlockTable.Create.Request) + - [Rpc.BlockTable.Create.Response](#anytype.Rpc.BlockTable.Create.Response) + - [Rpc.BlockTable.Create.Response.Error](#anytype.Rpc.BlockTable.Create.Response.Error) + - [Rpc.BlockTable.Expand](#anytype.Rpc.BlockTable.Expand) + - [Rpc.BlockTable.Expand.Request](#anytype.Rpc.BlockTable.Expand.Request) + - [Rpc.BlockTable.Expand.Response](#anytype.Rpc.BlockTable.Expand.Response) + - [Rpc.BlockTable.Expand.Response.Error](#anytype.Rpc.BlockTable.Expand.Response.Error) + - [Rpc.BlockTable.RowCreate](#anytype.Rpc.BlockTable.RowCreate) + - [Rpc.BlockTable.RowCreate.Request](#anytype.Rpc.BlockTable.RowCreate.Request) + - [Rpc.BlockTable.RowCreate.Response](#anytype.Rpc.BlockTable.RowCreate.Response) + - [Rpc.BlockTable.RowCreate.Response.Error](#anytype.Rpc.BlockTable.RowCreate.Response.Error) + - [Rpc.BlockTable.RowDelete](#anytype.Rpc.BlockTable.RowDelete) + - [Rpc.BlockTable.RowDelete.Request](#anytype.Rpc.BlockTable.RowDelete.Request) + - [Rpc.BlockTable.RowDelete.Response](#anytype.Rpc.BlockTable.RowDelete.Response) + - [Rpc.BlockTable.RowDelete.Response.Error](#anytype.Rpc.BlockTable.RowDelete.Response.Error) + - [Rpc.BlockTable.RowDuplicate](#anytype.Rpc.BlockTable.RowDuplicate) + - [Rpc.BlockTable.RowDuplicate.Request](#anytype.Rpc.BlockTable.RowDuplicate.Request) + - [Rpc.BlockTable.RowDuplicate.Response](#anytype.Rpc.BlockTable.RowDuplicate.Response) + - [Rpc.BlockTable.RowDuplicate.Response.Error](#anytype.Rpc.BlockTable.RowDuplicate.Response.Error) + - [Rpc.BlockTable.RowListClean](#anytype.Rpc.BlockTable.RowListClean) + - [Rpc.BlockTable.RowListClean.Request](#anytype.Rpc.BlockTable.RowListClean.Request) + - [Rpc.BlockTable.RowListClean.Response](#anytype.Rpc.BlockTable.RowListClean.Response) + - [Rpc.BlockTable.RowListClean.Response.Error](#anytype.Rpc.BlockTable.RowListClean.Response.Error) + - [Rpc.BlockTable.RowListFill](#anytype.Rpc.BlockTable.RowListFill) + - [Rpc.BlockTable.RowListFill.Request](#anytype.Rpc.BlockTable.RowListFill.Request) + - [Rpc.BlockTable.RowListFill.Response](#anytype.Rpc.BlockTable.RowListFill.Response) + - [Rpc.BlockTable.RowListFill.Response.Error](#anytype.Rpc.BlockTable.RowListFill.Response.Error) + - [Rpc.BlockTable.RowSetHeader](#anytype.Rpc.BlockTable.RowSetHeader) + - [Rpc.BlockTable.RowSetHeader.Request](#anytype.Rpc.BlockTable.RowSetHeader.Request) + - [Rpc.BlockTable.RowSetHeader.Response](#anytype.Rpc.BlockTable.RowSetHeader.Response) + - [Rpc.BlockTable.RowSetHeader.Response.Error](#anytype.Rpc.BlockTable.RowSetHeader.Response.Error) + - [Rpc.BlockTable.Sort](#anytype.Rpc.BlockTable.Sort) + - [Rpc.BlockTable.Sort.Request](#anytype.Rpc.BlockTable.Sort.Request) + - [Rpc.BlockTable.Sort.Response](#anytype.Rpc.BlockTable.Sort.Response) + - [Rpc.BlockTable.Sort.Response.Error](#anytype.Rpc.BlockTable.Sort.Response.Error) + - [Rpc.BlockText](#anytype.Rpc.BlockText) + - [Rpc.BlockText.ListClearContent](#anytype.Rpc.BlockText.ListClearContent) + - [Rpc.BlockText.ListClearContent.Request](#anytype.Rpc.BlockText.ListClearContent.Request) + - [Rpc.BlockText.ListClearContent.Response](#anytype.Rpc.BlockText.ListClearContent.Response) + - [Rpc.BlockText.ListClearContent.Response.Error](#anytype.Rpc.BlockText.ListClearContent.Response.Error) + - [Rpc.BlockText.ListClearStyle](#anytype.Rpc.BlockText.ListClearStyle) + - [Rpc.BlockText.ListClearStyle.Request](#anytype.Rpc.BlockText.ListClearStyle.Request) + - [Rpc.BlockText.ListClearStyle.Response](#anytype.Rpc.BlockText.ListClearStyle.Response) + - [Rpc.BlockText.ListClearStyle.Response.Error](#anytype.Rpc.BlockText.ListClearStyle.Response.Error) + - [Rpc.BlockText.ListSetColor](#anytype.Rpc.BlockText.ListSetColor) + - [Rpc.BlockText.ListSetColor.Request](#anytype.Rpc.BlockText.ListSetColor.Request) + - [Rpc.BlockText.ListSetColor.Response](#anytype.Rpc.BlockText.ListSetColor.Response) + - [Rpc.BlockText.ListSetColor.Response.Error](#anytype.Rpc.BlockText.ListSetColor.Response.Error) + - [Rpc.BlockText.ListSetMark](#anytype.Rpc.BlockText.ListSetMark) + - [Rpc.BlockText.ListSetMark.Request](#anytype.Rpc.BlockText.ListSetMark.Request) + - [Rpc.BlockText.ListSetMark.Response](#anytype.Rpc.BlockText.ListSetMark.Response) + - [Rpc.BlockText.ListSetMark.Response.Error](#anytype.Rpc.BlockText.ListSetMark.Response.Error) + - [Rpc.BlockText.ListSetStyle](#anytype.Rpc.BlockText.ListSetStyle) + - [Rpc.BlockText.ListSetStyle.Request](#anytype.Rpc.BlockText.ListSetStyle.Request) + - [Rpc.BlockText.ListSetStyle.Response](#anytype.Rpc.BlockText.ListSetStyle.Response) + - [Rpc.BlockText.ListSetStyle.Response.Error](#anytype.Rpc.BlockText.ListSetStyle.Response.Error) + - [Rpc.BlockText.SetChecked](#anytype.Rpc.BlockText.SetChecked) + - [Rpc.BlockText.SetChecked.Request](#anytype.Rpc.BlockText.SetChecked.Request) + - [Rpc.BlockText.SetChecked.Response](#anytype.Rpc.BlockText.SetChecked.Response) + - [Rpc.BlockText.SetChecked.Response.Error](#anytype.Rpc.BlockText.SetChecked.Response.Error) + - [Rpc.BlockText.SetColor](#anytype.Rpc.BlockText.SetColor) + - [Rpc.BlockText.SetColor.Request](#anytype.Rpc.BlockText.SetColor.Request) + - [Rpc.BlockText.SetColor.Response](#anytype.Rpc.BlockText.SetColor.Response) + - [Rpc.BlockText.SetColor.Response.Error](#anytype.Rpc.BlockText.SetColor.Response.Error) + - [Rpc.BlockText.SetIcon](#anytype.Rpc.BlockText.SetIcon) + - [Rpc.BlockText.SetIcon.Request](#anytype.Rpc.BlockText.SetIcon.Request) + - [Rpc.BlockText.SetIcon.Response](#anytype.Rpc.BlockText.SetIcon.Response) + - [Rpc.BlockText.SetIcon.Response.Error](#anytype.Rpc.BlockText.SetIcon.Response.Error) + - [Rpc.BlockText.SetMarks](#anytype.Rpc.BlockText.SetMarks) + - [Rpc.BlockText.SetMarks.Get](#anytype.Rpc.BlockText.SetMarks.Get) + - [Rpc.BlockText.SetMarks.Get.Request](#anytype.Rpc.BlockText.SetMarks.Get.Request) + - [Rpc.BlockText.SetMarks.Get.Response](#anytype.Rpc.BlockText.SetMarks.Get.Response) + - [Rpc.BlockText.SetMarks.Get.Response.Error](#anytype.Rpc.BlockText.SetMarks.Get.Response.Error) + - [Rpc.BlockText.SetStyle](#anytype.Rpc.BlockText.SetStyle) + - [Rpc.BlockText.SetStyle.Request](#anytype.Rpc.BlockText.SetStyle.Request) + - [Rpc.BlockText.SetStyle.Response](#anytype.Rpc.BlockText.SetStyle.Response) + - [Rpc.BlockText.SetStyle.Response.Error](#anytype.Rpc.BlockText.SetStyle.Response.Error) + - [Rpc.BlockText.SetText](#anytype.Rpc.BlockText.SetText) + - [Rpc.BlockText.SetText.Request](#anytype.Rpc.BlockText.SetText.Request) + - [Rpc.BlockText.SetText.Response](#anytype.Rpc.BlockText.SetText.Response) + - [Rpc.BlockText.SetText.Response.Error](#anytype.Rpc.BlockText.SetText.Response.Error) + - [Rpc.BlockVideo](#anytype.Rpc.BlockVideo) + - [Rpc.BlockVideo.SetName](#anytype.Rpc.BlockVideo.SetName) + - [Rpc.BlockVideo.SetName.Request](#anytype.Rpc.BlockVideo.SetName.Request) + - [Rpc.BlockVideo.SetName.Response](#anytype.Rpc.BlockVideo.SetName.Response) + - [Rpc.BlockVideo.SetName.Response.Error](#anytype.Rpc.BlockVideo.SetName.Response.Error) + - [Rpc.BlockVideo.SetWidth](#anytype.Rpc.BlockVideo.SetWidth) + - [Rpc.BlockVideo.SetWidth.Request](#anytype.Rpc.BlockVideo.SetWidth.Request) + - [Rpc.BlockVideo.SetWidth.Response](#anytype.Rpc.BlockVideo.SetWidth.Response) + - [Rpc.BlockVideo.SetWidth.Response.Error](#anytype.Rpc.BlockVideo.SetWidth.Response.Error) + - [Rpc.Debug](#anytype.Rpc.Debug) + - [Rpc.Debug.ExportLocalstore](#anytype.Rpc.Debug.ExportLocalstore) + - [Rpc.Debug.ExportLocalstore.Request](#anytype.Rpc.Debug.ExportLocalstore.Request) + - [Rpc.Debug.ExportLocalstore.Response](#anytype.Rpc.Debug.ExportLocalstore.Response) + - [Rpc.Debug.ExportLocalstore.Response.Error](#anytype.Rpc.Debug.ExportLocalstore.Response.Error) + - [Rpc.Debug.Ping](#anytype.Rpc.Debug.Ping) + - [Rpc.Debug.Ping.Request](#anytype.Rpc.Debug.Ping.Request) + - [Rpc.Debug.Ping.Response](#anytype.Rpc.Debug.Ping.Response) + - [Rpc.Debug.Ping.Response.Error](#anytype.Rpc.Debug.Ping.Response.Error) + - [Rpc.Debug.Sync](#anytype.Rpc.Debug.Sync) + - [Rpc.Debug.Sync.Request](#anytype.Rpc.Debug.Sync.Request) + - [Rpc.Debug.Sync.Response](#anytype.Rpc.Debug.Sync.Response) + - [Rpc.Debug.Sync.Response.Error](#anytype.Rpc.Debug.Sync.Response.Error) + - [Rpc.Debug.Thread](#anytype.Rpc.Debug.Thread) + - [Rpc.Debug.Thread.Request](#anytype.Rpc.Debug.Thread.Request) + - [Rpc.Debug.Thread.Response](#anytype.Rpc.Debug.Thread.Response) + - [Rpc.Debug.Thread.Response.Error](#anytype.Rpc.Debug.Thread.Response.Error) + - [Rpc.Debug.Tree](#anytype.Rpc.Debug.Tree) + - [Rpc.Debug.Tree.Request](#anytype.Rpc.Debug.Tree.Request) + - [Rpc.Debug.Tree.Response](#anytype.Rpc.Debug.Tree.Response) + - [Rpc.Debug.Tree.Response.Error](#anytype.Rpc.Debug.Tree.Response.Error) + - [Rpc.Debug.logInfo](#anytype.Rpc.Debug.logInfo) + - [Rpc.Debug.threadInfo](#anytype.Rpc.Debug.threadInfo) + - [Rpc.File](#anytype.Rpc.File) + - [Rpc.File.Download](#anytype.Rpc.File.Download) + - [Rpc.File.Download.Request](#anytype.Rpc.File.Download.Request) + - [Rpc.File.Download.Response](#anytype.Rpc.File.Download.Response) + - [Rpc.File.Download.Response.Error](#anytype.Rpc.File.Download.Response.Error) + - [Rpc.File.Drop](#anytype.Rpc.File.Drop) + - [Rpc.File.Drop.Request](#anytype.Rpc.File.Drop.Request) + - [Rpc.File.Drop.Response](#anytype.Rpc.File.Drop.Response) + - [Rpc.File.Drop.Response.Error](#anytype.Rpc.File.Drop.Response.Error) + - [Rpc.File.ListOffload](#anytype.Rpc.File.ListOffload) + - [Rpc.File.ListOffload.Request](#anytype.Rpc.File.ListOffload.Request) + - [Rpc.File.ListOffload.Response](#anytype.Rpc.File.ListOffload.Response) + - [Rpc.File.ListOffload.Response.Error](#anytype.Rpc.File.ListOffload.Response.Error) + - [Rpc.File.Offload](#anytype.Rpc.File.Offload) + - [Rpc.File.Offload.Request](#anytype.Rpc.File.Offload.Request) + - [Rpc.File.Offload.Response](#anytype.Rpc.File.Offload.Response) + - [Rpc.File.Offload.Response.Error](#anytype.Rpc.File.Offload.Response.Error) + - [Rpc.File.Upload](#anytype.Rpc.File.Upload) + - [Rpc.File.Upload.Request](#anytype.Rpc.File.Upload.Request) + - [Rpc.File.Upload.Response](#anytype.Rpc.File.Upload.Response) + - [Rpc.File.Upload.Response.Error](#anytype.Rpc.File.Upload.Response.Error) + - [Rpc.GenericErrorResponse](#anytype.Rpc.GenericErrorResponse) + - [Rpc.GenericErrorResponse.Error](#anytype.Rpc.GenericErrorResponse.Error) + - [Rpc.History](#anytype.Rpc.History) + - [Rpc.History.GetVersions](#anytype.Rpc.History.GetVersions) + - [Rpc.History.GetVersions.Request](#anytype.Rpc.History.GetVersions.Request) + - [Rpc.History.GetVersions.Response](#anytype.Rpc.History.GetVersions.Response) + - [Rpc.History.GetVersions.Response.Error](#anytype.Rpc.History.GetVersions.Response.Error) + - [Rpc.History.SetVersion](#anytype.Rpc.History.SetVersion) + - [Rpc.History.SetVersion.Request](#anytype.Rpc.History.SetVersion.Request) + - [Rpc.History.SetVersion.Response](#anytype.Rpc.History.SetVersion.Response) + - [Rpc.History.SetVersion.Response.Error](#anytype.Rpc.History.SetVersion.Response.Error) + - [Rpc.History.ShowVersion](#anytype.Rpc.History.ShowVersion) + - [Rpc.History.ShowVersion.Request](#anytype.Rpc.History.ShowVersion.Request) + - [Rpc.History.ShowVersion.Response](#anytype.Rpc.History.ShowVersion.Response) + - [Rpc.History.ShowVersion.Response.Error](#anytype.Rpc.History.ShowVersion.Response.Error) + - [Rpc.History.Version](#anytype.Rpc.History.Version) + - [Rpc.LinkPreview](#anytype.Rpc.LinkPreview) + - [Rpc.LinkPreview.Request](#anytype.Rpc.LinkPreview.Request) + - [Rpc.LinkPreview.Response](#anytype.Rpc.LinkPreview.Response) + - [Rpc.LinkPreview.Response.Error](#anytype.Rpc.LinkPreview.Response.Error) + - [Rpc.Log](#anytype.Rpc.Log) + - [Rpc.Log.Send](#anytype.Rpc.Log.Send) + - [Rpc.Log.Send.Request](#anytype.Rpc.Log.Send.Request) + - [Rpc.Log.Send.Response](#anytype.Rpc.Log.Send.Response) + - [Rpc.Log.Send.Response.Error](#anytype.Rpc.Log.Send.Response.Error) + - [Rpc.Metrics](#anytype.Rpc.Metrics) + - [Rpc.Metrics.SetParameters](#anytype.Rpc.Metrics.SetParameters) + - [Rpc.Metrics.SetParameters.Request](#anytype.Rpc.Metrics.SetParameters.Request) + - [Rpc.Metrics.SetParameters.Response](#anytype.Rpc.Metrics.SetParameters.Response) + - [Rpc.Metrics.SetParameters.Response.Error](#anytype.Rpc.Metrics.SetParameters.Response.Error) + - [Rpc.Navigation](#anytype.Rpc.Navigation) + - [Rpc.Navigation.GetObjectInfoWithLinks](#anytype.Rpc.Navigation.GetObjectInfoWithLinks) + - [Rpc.Navigation.GetObjectInfoWithLinks.Request](#anytype.Rpc.Navigation.GetObjectInfoWithLinks.Request) + - [Rpc.Navigation.GetObjectInfoWithLinks.Response](#anytype.Rpc.Navigation.GetObjectInfoWithLinks.Response) + - [Rpc.Navigation.GetObjectInfoWithLinks.Response.Error](#anytype.Rpc.Navigation.GetObjectInfoWithLinks.Response.Error) + - [Rpc.Navigation.ListObjects](#anytype.Rpc.Navigation.ListObjects) + - [Rpc.Navigation.ListObjects.Request](#anytype.Rpc.Navigation.ListObjects.Request) + - [Rpc.Navigation.ListObjects.Response](#anytype.Rpc.Navigation.ListObjects.Response) + - [Rpc.Navigation.ListObjects.Response.Error](#anytype.Rpc.Navigation.ListObjects.Response.Error) + - [Rpc.Object](#anytype.Rpc.Object) + - [Rpc.Object.AddWithObjectId](#anytype.Rpc.Object.AddWithObjectId) + - [Rpc.Object.AddWithObjectId.Request](#anytype.Rpc.Object.AddWithObjectId.Request) + - [Rpc.Object.AddWithObjectId.Response](#anytype.Rpc.Object.AddWithObjectId.Response) + - [Rpc.Object.AddWithObjectId.Response.Error](#anytype.Rpc.Object.AddWithObjectId.Response.Error) + - [Rpc.Object.ApplyTemplate](#anytype.Rpc.Object.ApplyTemplate) + - [Rpc.Object.ApplyTemplate.Request](#anytype.Rpc.Object.ApplyTemplate.Request) + - [Rpc.Object.ApplyTemplate.Response](#anytype.Rpc.Object.ApplyTemplate.Response) + - [Rpc.Object.ApplyTemplate.Response.Error](#anytype.Rpc.Object.ApplyTemplate.Response.Error) + - [Rpc.Object.BookmarkFetch](#anytype.Rpc.Object.BookmarkFetch) + - [Rpc.Object.BookmarkFetch.Request](#anytype.Rpc.Object.BookmarkFetch.Request) + - [Rpc.Object.BookmarkFetch.Response](#anytype.Rpc.Object.BookmarkFetch.Response) + - [Rpc.Object.BookmarkFetch.Response.Error](#anytype.Rpc.Object.BookmarkFetch.Response.Error) + - [Rpc.Object.Close](#anytype.Rpc.Object.Close) + - [Rpc.Object.Close.Request](#anytype.Rpc.Object.Close.Request) + - [Rpc.Object.Close.Response](#anytype.Rpc.Object.Close.Response) + - [Rpc.Object.Close.Response.Error](#anytype.Rpc.Object.Close.Response.Error) + - [Rpc.Object.Create](#anytype.Rpc.Object.Create) + - [Rpc.Object.Create.Request](#anytype.Rpc.Object.Create.Request) + - [Rpc.Object.Create.Response](#anytype.Rpc.Object.Create.Response) + - [Rpc.Object.Create.Response.Error](#anytype.Rpc.Object.Create.Response.Error) + - [Rpc.Object.CreateBookmark](#anytype.Rpc.Object.CreateBookmark) + - [Rpc.Object.CreateBookmark.Request](#anytype.Rpc.Object.CreateBookmark.Request) + - [Rpc.Object.CreateBookmark.Response](#anytype.Rpc.Object.CreateBookmark.Response) + - [Rpc.Object.CreateBookmark.Response.Error](#anytype.Rpc.Object.CreateBookmark.Response.Error) + - [Rpc.Object.CreateObjectType](#anytype.Rpc.Object.CreateObjectType) + - [Rpc.Object.CreateObjectType.Request](#anytype.Rpc.Object.CreateObjectType.Request) + - [Rpc.Object.CreateObjectType.Response](#anytype.Rpc.Object.CreateObjectType.Response) + - [Rpc.Object.CreateObjectType.Response.Error](#anytype.Rpc.Object.CreateObjectType.Response.Error) + - [Rpc.Object.CreateRelation](#anytype.Rpc.Object.CreateRelation) + - [Rpc.Object.CreateRelation.Request](#anytype.Rpc.Object.CreateRelation.Request) + - [Rpc.Object.CreateRelation.Response](#anytype.Rpc.Object.CreateRelation.Response) + - [Rpc.Object.CreateRelation.Response.Error](#anytype.Rpc.Object.CreateRelation.Response.Error) + - [Rpc.Object.CreateRelationOption](#anytype.Rpc.Object.CreateRelationOption) + - [Rpc.Object.CreateRelationOption.Request](#anytype.Rpc.Object.CreateRelationOption.Request) + - [Rpc.Object.CreateRelationOption.Response](#anytype.Rpc.Object.CreateRelationOption.Response) + - [Rpc.Object.CreateRelationOption.Response.Error](#anytype.Rpc.Object.CreateRelationOption.Response.Error) + - [Rpc.Object.CreateSet](#anytype.Rpc.Object.CreateSet) + - [Rpc.Object.CreateSet.Request](#anytype.Rpc.Object.CreateSet.Request) + - [Rpc.Object.CreateSet.Response](#anytype.Rpc.Object.CreateSet.Response) + - [Rpc.Object.CreateSet.Response.Error](#anytype.Rpc.Object.CreateSet.Response.Error) + - [Rpc.Object.Duplicate](#anytype.Rpc.Object.Duplicate) + - [Rpc.Object.Duplicate.Request](#anytype.Rpc.Object.Duplicate.Request) + - [Rpc.Object.Duplicate.Response](#anytype.Rpc.Object.Duplicate.Response) + - [Rpc.Object.Duplicate.Response.Error](#anytype.Rpc.Object.Duplicate.Response.Error) + - [Rpc.Object.Graph](#anytype.Rpc.Object.Graph) + - [Rpc.Object.Graph.Edge](#anytype.Rpc.Object.Graph.Edge) + - [Rpc.Object.Graph.Request](#anytype.Rpc.Object.Graph.Request) + - [Rpc.Object.Graph.Response](#anytype.Rpc.Object.Graph.Response) + - [Rpc.Object.Graph.Response.Error](#anytype.Rpc.Object.Graph.Response.Error) + - [Rpc.Object.GroupsSubscribe](#anytype.Rpc.Object.GroupsSubscribe) + - [Rpc.Object.GroupsSubscribe.Request](#anytype.Rpc.Object.GroupsSubscribe.Request) + - [Rpc.Object.GroupsSubscribe.Response](#anytype.Rpc.Object.GroupsSubscribe.Response) + - [Rpc.Object.GroupsSubscribe.Response.Error](#anytype.Rpc.Object.GroupsSubscribe.Response.Error) + - [Rpc.Object.Import](#anytype.Rpc.Object.Import) + - [Rpc.Object.Import.Request](#anytype.Rpc.Object.Import.Request) + - [Rpc.Object.Import.Request.BookmarksParams](#anytype.Rpc.Object.Import.Request.BookmarksParams) + - [Rpc.Object.Import.Request.NotionParams](#anytype.Rpc.Object.Import.Request.NotionParams) + - [Rpc.Object.Import.Request.Snapshot](#anytype.Rpc.Object.Import.Request.Snapshot) + - [Rpc.Object.Import.Response](#anytype.Rpc.Object.Import.Response) + - [Rpc.Object.Import.Response.Error](#anytype.Rpc.Object.Import.Response.Error) + - [Rpc.Object.ImportList](#anytype.Rpc.Object.ImportList) + - [Rpc.Object.ImportList.ImportResponse](#anytype.Rpc.Object.ImportList.ImportResponse) + - [Rpc.Object.ImportList.Request](#anytype.Rpc.Object.ImportList.Request) + - [Rpc.Object.ImportList.Response](#anytype.Rpc.Object.ImportList.Response) + - [Rpc.Object.ImportList.Response.Error](#anytype.Rpc.Object.ImportList.Response.Error) + - [Rpc.Object.ImportMarkdown](#anytype.Rpc.Object.ImportMarkdown) + - [Rpc.Object.ImportMarkdown.Request](#anytype.Rpc.Object.ImportMarkdown.Request) + - [Rpc.Object.ImportMarkdown.Response](#anytype.Rpc.Object.ImportMarkdown.Response) + - [Rpc.Object.ImportMarkdown.Response.Error](#anytype.Rpc.Object.ImportMarkdown.Response.Error) + - [Rpc.Object.ListDelete](#anytype.Rpc.Object.ListDelete) + - [Rpc.Object.ListDelete.Request](#anytype.Rpc.Object.ListDelete.Request) + - [Rpc.Object.ListDelete.Response](#anytype.Rpc.Object.ListDelete.Response) + - [Rpc.Object.ListDelete.Response.Error](#anytype.Rpc.Object.ListDelete.Response.Error) + - [Rpc.Object.ListDuplicate](#anytype.Rpc.Object.ListDuplicate) + - [Rpc.Object.ListDuplicate.Request](#anytype.Rpc.Object.ListDuplicate.Request) + - [Rpc.Object.ListDuplicate.Response](#anytype.Rpc.Object.ListDuplicate.Response) + - [Rpc.Object.ListDuplicate.Response.Error](#anytype.Rpc.Object.ListDuplicate.Response.Error) + - [Rpc.Object.ListExport](#anytype.Rpc.Object.ListExport) + - [Rpc.Object.ListExport.Request](#anytype.Rpc.Object.ListExport.Request) + - [Rpc.Object.ListExport.Response](#anytype.Rpc.Object.ListExport.Response) + - [Rpc.Object.ListExport.Response.Error](#anytype.Rpc.Object.ListExport.Response.Error) + - [Rpc.Object.ListSetIsArchived](#anytype.Rpc.Object.ListSetIsArchived) + - [Rpc.Object.ListSetIsArchived.Request](#anytype.Rpc.Object.ListSetIsArchived.Request) + - [Rpc.Object.ListSetIsArchived.Response](#anytype.Rpc.Object.ListSetIsArchived.Response) + - [Rpc.Object.ListSetIsArchived.Response.Error](#anytype.Rpc.Object.ListSetIsArchived.Response.Error) + - [Rpc.Object.ListSetIsFavorite](#anytype.Rpc.Object.ListSetIsFavorite) + - [Rpc.Object.ListSetIsFavorite.Request](#anytype.Rpc.Object.ListSetIsFavorite.Request) + - [Rpc.Object.ListSetIsFavorite.Response](#anytype.Rpc.Object.ListSetIsFavorite.Response) + - [Rpc.Object.ListSetIsFavorite.Response.Error](#anytype.Rpc.Object.ListSetIsFavorite.Response.Error) + - [Rpc.Object.Open](#anytype.Rpc.Object.Open) + - [Rpc.Object.Open.Request](#anytype.Rpc.Object.Open.Request) + - [Rpc.Object.Open.Response](#anytype.Rpc.Object.Open.Response) + - [Rpc.Object.Open.Response.Error](#anytype.Rpc.Object.Open.Response.Error) + - [Rpc.Object.OpenBreadcrumbs](#anytype.Rpc.Object.OpenBreadcrumbs) + - [Rpc.Object.OpenBreadcrumbs.Request](#anytype.Rpc.Object.OpenBreadcrumbs.Request) + - [Rpc.Object.OpenBreadcrumbs.Response](#anytype.Rpc.Object.OpenBreadcrumbs.Response) + - [Rpc.Object.OpenBreadcrumbs.Response.Error](#anytype.Rpc.Object.OpenBreadcrumbs.Response.Error) + - [Rpc.Object.Redo](#anytype.Rpc.Object.Redo) + - [Rpc.Object.Redo.Request](#anytype.Rpc.Object.Redo.Request) + - [Rpc.Object.Redo.Response](#anytype.Rpc.Object.Redo.Response) + - [Rpc.Object.Redo.Response.Error](#anytype.Rpc.Object.Redo.Response.Error) + - [Rpc.Object.Search](#anytype.Rpc.Object.Search) + - [Rpc.Object.Search.Request](#anytype.Rpc.Object.Search.Request) + - [Rpc.Object.Search.Response](#anytype.Rpc.Object.Search.Response) + - [Rpc.Object.Search.Response.Error](#anytype.Rpc.Object.Search.Response.Error) + - [Rpc.Object.SearchSubscribe](#anytype.Rpc.Object.SearchSubscribe) + - [Rpc.Object.SearchSubscribe.Request](#anytype.Rpc.Object.SearchSubscribe.Request) + - [Rpc.Object.SearchSubscribe.Response](#anytype.Rpc.Object.SearchSubscribe.Response) + - [Rpc.Object.SearchSubscribe.Response.Error](#anytype.Rpc.Object.SearchSubscribe.Response.Error) + - [Rpc.Object.SearchUnsubscribe](#anytype.Rpc.Object.SearchUnsubscribe) + - [Rpc.Object.SearchUnsubscribe.Request](#anytype.Rpc.Object.SearchUnsubscribe.Request) + - [Rpc.Object.SearchUnsubscribe.Response](#anytype.Rpc.Object.SearchUnsubscribe.Response) + - [Rpc.Object.SearchUnsubscribe.Response.Error](#anytype.Rpc.Object.SearchUnsubscribe.Response.Error) + - [Rpc.Object.SetBreadcrumbs](#anytype.Rpc.Object.SetBreadcrumbs) + - [Rpc.Object.SetBreadcrumbs.Request](#anytype.Rpc.Object.SetBreadcrumbs.Request) + - [Rpc.Object.SetBreadcrumbs.Response](#anytype.Rpc.Object.SetBreadcrumbs.Response) + - [Rpc.Object.SetBreadcrumbs.Response.Error](#anytype.Rpc.Object.SetBreadcrumbs.Response.Error) + - [Rpc.Object.SetDetails](#anytype.Rpc.Object.SetDetails) + - [Rpc.Object.SetDetails.Detail](#anytype.Rpc.Object.SetDetails.Detail) + - [Rpc.Object.SetDetails.Request](#anytype.Rpc.Object.SetDetails.Request) + - [Rpc.Object.SetDetails.Response](#anytype.Rpc.Object.SetDetails.Response) + - [Rpc.Object.SetDetails.Response.Error](#anytype.Rpc.Object.SetDetails.Response.Error) + - [Rpc.Object.SetInternalFlags](#anytype.Rpc.Object.SetInternalFlags) + - [Rpc.Object.SetInternalFlags.Request](#anytype.Rpc.Object.SetInternalFlags.Request) + - [Rpc.Object.SetInternalFlags.Response](#anytype.Rpc.Object.SetInternalFlags.Response) + - [Rpc.Object.SetInternalFlags.Response.Error](#anytype.Rpc.Object.SetInternalFlags.Response.Error) + - [Rpc.Object.SetIsArchived](#anytype.Rpc.Object.SetIsArchived) + - [Rpc.Object.SetIsArchived.Request](#anytype.Rpc.Object.SetIsArchived.Request) + - [Rpc.Object.SetIsArchived.Response](#anytype.Rpc.Object.SetIsArchived.Response) + - [Rpc.Object.SetIsArchived.Response.Error](#anytype.Rpc.Object.SetIsArchived.Response.Error) + - [Rpc.Object.SetIsFavorite](#anytype.Rpc.Object.SetIsFavorite) + - [Rpc.Object.SetIsFavorite.Request](#anytype.Rpc.Object.SetIsFavorite.Request) + - [Rpc.Object.SetIsFavorite.Response](#anytype.Rpc.Object.SetIsFavorite.Response) + - [Rpc.Object.SetIsFavorite.Response.Error](#anytype.Rpc.Object.SetIsFavorite.Response.Error) + - [Rpc.Object.SetLayout](#anytype.Rpc.Object.SetLayout) + - [Rpc.Object.SetLayout.Request](#anytype.Rpc.Object.SetLayout.Request) + - [Rpc.Object.SetLayout.Response](#anytype.Rpc.Object.SetLayout.Response) + - [Rpc.Object.SetLayout.Response.Error](#anytype.Rpc.Object.SetLayout.Response.Error) + - [Rpc.Object.SetObjectType](#anytype.Rpc.Object.SetObjectType) + - [Rpc.Object.SetObjectType.Request](#anytype.Rpc.Object.SetObjectType.Request) + - [Rpc.Object.SetObjectType.Response](#anytype.Rpc.Object.SetObjectType.Response) + - [Rpc.Object.SetObjectType.Response.Error](#anytype.Rpc.Object.SetObjectType.Response.Error) + - [Rpc.Object.ShareByLink](#anytype.Rpc.Object.ShareByLink) + - [Rpc.Object.ShareByLink.Request](#anytype.Rpc.Object.ShareByLink.Request) + - [Rpc.Object.ShareByLink.Response](#anytype.Rpc.Object.ShareByLink.Response) + - [Rpc.Object.ShareByLink.Response.Error](#anytype.Rpc.Object.ShareByLink.Response.Error) + - [Rpc.Object.Show](#anytype.Rpc.Object.Show) + - [Rpc.Object.Show.Request](#anytype.Rpc.Object.Show.Request) + - [Rpc.Object.Show.Response](#anytype.Rpc.Object.Show.Response) + - [Rpc.Object.Show.Response.Error](#anytype.Rpc.Object.Show.Response.Error) + - [Rpc.Object.SubscribeIds](#anytype.Rpc.Object.SubscribeIds) + - [Rpc.Object.SubscribeIds.Request](#anytype.Rpc.Object.SubscribeIds.Request) + - [Rpc.Object.SubscribeIds.Response](#anytype.Rpc.Object.SubscribeIds.Response) + - [Rpc.Object.SubscribeIds.Response.Error](#anytype.Rpc.Object.SubscribeIds.Response.Error) + - [Rpc.Object.ToBookmark](#anytype.Rpc.Object.ToBookmark) + - [Rpc.Object.ToBookmark.Request](#anytype.Rpc.Object.ToBookmark.Request) + - [Rpc.Object.ToBookmark.Response](#anytype.Rpc.Object.ToBookmark.Response) + - [Rpc.Object.ToBookmark.Response.Error](#anytype.Rpc.Object.ToBookmark.Response.Error) + - [Rpc.Object.ToSet](#anytype.Rpc.Object.ToSet) + - [Rpc.Object.ToSet.Request](#anytype.Rpc.Object.ToSet.Request) + - [Rpc.Object.ToSet.Response](#anytype.Rpc.Object.ToSet.Response) + - [Rpc.Object.ToSet.Response.Error](#anytype.Rpc.Object.ToSet.Response.Error) + - [Rpc.Object.Undo](#anytype.Rpc.Object.Undo) + - [Rpc.Object.Undo.Request](#anytype.Rpc.Object.Undo.Request) + - [Rpc.Object.Undo.Response](#anytype.Rpc.Object.Undo.Response) + - [Rpc.Object.Undo.Response.Error](#anytype.Rpc.Object.Undo.Response.Error) + - [Rpc.Object.UndoRedoCounter](#anytype.Rpc.Object.UndoRedoCounter) + - [Rpc.ObjectRelation](#anytype.Rpc.ObjectRelation) + - [Rpc.ObjectRelation.Add](#anytype.Rpc.ObjectRelation.Add) + - [Rpc.ObjectRelation.Add.Request](#anytype.Rpc.ObjectRelation.Add.Request) + - [Rpc.ObjectRelation.Add.Response](#anytype.Rpc.ObjectRelation.Add.Response) + - [Rpc.ObjectRelation.Add.Response.Error](#anytype.Rpc.ObjectRelation.Add.Response.Error) + - [Rpc.ObjectRelation.AddFeatured](#anytype.Rpc.ObjectRelation.AddFeatured) + - [Rpc.ObjectRelation.AddFeatured.Request](#anytype.Rpc.ObjectRelation.AddFeatured.Request) + - [Rpc.ObjectRelation.AddFeatured.Response](#anytype.Rpc.ObjectRelation.AddFeatured.Response) + - [Rpc.ObjectRelation.AddFeatured.Response.Error](#anytype.Rpc.ObjectRelation.AddFeatured.Response.Error) + - [Rpc.ObjectRelation.Delete](#anytype.Rpc.ObjectRelation.Delete) + - [Rpc.ObjectRelation.Delete.Request](#anytype.Rpc.ObjectRelation.Delete.Request) + - [Rpc.ObjectRelation.Delete.Response](#anytype.Rpc.ObjectRelation.Delete.Response) + - [Rpc.ObjectRelation.Delete.Response.Error](#anytype.Rpc.ObjectRelation.Delete.Response.Error) + - [Rpc.ObjectRelation.ListAvailable](#anytype.Rpc.ObjectRelation.ListAvailable) + - [Rpc.ObjectRelation.ListAvailable.Request](#anytype.Rpc.ObjectRelation.ListAvailable.Request) + - [Rpc.ObjectRelation.ListAvailable.Response](#anytype.Rpc.ObjectRelation.ListAvailable.Response) + - [Rpc.ObjectRelation.ListAvailable.Response.Error](#anytype.Rpc.ObjectRelation.ListAvailable.Response.Error) + - [Rpc.ObjectRelation.RemoveFeatured](#anytype.Rpc.ObjectRelation.RemoveFeatured) + - [Rpc.ObjectRelation.RemoveFeatured.Request](#anytype.Rpc.ObjectRelation.RemoveFeatured.Request) + - [Rpc.ObjectRelation.RemoveFeatured.Response](#anytype.Rpc.ObjectRelation.RemoveFeatured.Response) + - [Rpc.ObjectRelation.RemoveFeatured.Response.Error](#anytype.Rpc.ObjectRelation.RemoveFeatured.Response.Error) + - [Rpc.ObjectType](#anytype.Rpc.ObjectType) + - [Rpc.ObjectType.Relation](#anytype.Rpc.ObjectType.Relation) + - [Rpc.ObjectType.Relation.Add](#anytype.Rpc.ObjectType.Relation.Add) + - [Rpc.ObjectType.Relation.Add.Request](#anytype.Rpc.ObjectType.Relation.Add.Request) + - [Rpc.ObjectType.Relation.Add.Response](#anytype.Rpc.ObjectType.Relation.Add.Response) + - [Rpc.ObjectType.Relation.Add.Response.Error](#anytype.Rpc.ObjectType.Relation.Add.Response.Error) + - [Rpc.ObjectType.Relation.List](#anytype.Rpc.ObjectType.Relation.List) + - [Rpc.ObjectType.Relation.List.Request](#anytype.Rpc.ObjectType.Relation.List.Request) + - [Rpc.ObjectType.Relation.List.Response](#anytype.Rpc.ObjectType.Relation.List.Response) + - [Rpc.ObjectType.Relation.List.Response.Error](#anytype.Rpc.ObjectType.Relation.List.Response.Error) + - [Rpc.ObjectType.Relation.Remove](#anytype.Rpc.ObjectType.Relation.Remove) + - [Rpc.ObjectType.Relation.Remove.Request](#anytype.Rpc.ObjectType.Relation.Remove.Request) + - [Rpc.ObjectType.Relation.Remove.Response](#anytype.Rpc.ObjectType.Relation.Remove.Response) + - [Rpc.ObjectType.Relation.Remove.Response.Error](#anytype.Rpc.ObjectType.Relation.Remove.Response.Error) + - [Rpc.Process](#anytype.Rpc.Process) + - [Rpc.Process.Cancel](#anytype.Rpc.Process.Cancel) + - [Rpc.Process.Cancel.Request](#anytype.Rpc.Process.Cancel.Request) + - [Rpc.Process.Cancel.Response](#anytype.Rpc.Process.Cancel.Response) + - [Rpc.Process.Cancel.Response.Error](#anytype.Rpc.Process.Cancel.Response.Error) + - [Rpc.Relation](#anytype.Rpc.Relation) + - [Rpc.Relation.ListRemoveOption](#anytype.Rpc.Relation.ListRemoveOption) + - [Rpc.Relation.ListRemoveOption.Request](#anytype.Rpc.Relation.ListRemoveOption.Request) + - [Rpc.Relation.ListRemoveOption.Response](#anytype.Rpc.Relation.ListRemoveOption.Response) + - [Rpc.Relation.ListRemoveOption.Response.Error](#anytype.Rpc.Relation.ListRemoveOption.Response.Error) + - [Rpc.Relation.Options](#anytype.Rpc.Relation.Options) + - [Rpc.Relation.Options.Request](#anytype.Rpc.Relation.Options.Request) + - [Rpc.Relation.Options.Response](#anytype.Rpc.Relation.Options.Response) + - [Rpc.Relation.Options.Response.Error](#anytype.Rpc.Relation.Options.Response.Error) + - [Rpc.Template](#anytype.Rpc.Template) + - [Rpc.Template.Clone](#anytype.Rpc.Template.Clone) + - [Rpc.Template.Clone.Request](#anytype.Rpc.Template.Clone.Request) + - [Rpc.Template.Clone.Response](#anytype.Rpc.Template.Clone.Response) + - [Rpc.Template.Clone.Response.Error](#anytype.Rpc.Template.Clone.Response.Error) + - [Rpc.Template.CreateFromObject](#anytype.Rpc.Template.CreateFromObject) + - [Rpc.Template.CreateFromObject.Request](#anytype.Rpc.Template.CreateFromObject.Request) + - [Rpc.Template.CreateFromObject.Response](#anytype.Rpc.Template.CreateFromObject.Response) + - [Rpc.Template.CreateFromObject.Response.Error](#anytype.Rpc.Template.CreateFromObject.Response.Error) + - [Rpc.Template.CreateFromObjectType](#anytype.Rpc.Template.CreateFromObjectType) + - [Rpc.Template.CreateFromObjectType.Request](#anytype.Rpc.Template.CreateFromObjectType.Request) + - [Rpc.Template.CreateFromObjectType.Response](#anytype.Rpc.Template.CreateFromObjectType.Response) + - [Rpc.Template.CreateFromObjectType.Response.Error](#anytype.Rpc.Template.CreateFromObjectType.Response.Error) + - [Rpc.Template.ExportAll](#anytype.Rpc.Template.ExportAll) + - [Rpc.Template.ExportAll.Request](#anytype.Rpc.Template.ExportAll.Request) + - [Rpc.Template.ExportAll.Response](#anytype.Rpc.Template.ExportAll.Response) + - [Rpc.Template.ExportAll.Response.Error](#anytype.Rpc.Template.ExportAll.Response.Error) + - [Rpc.Unsplash](#anytype.Rpc.Unsplash) + - [Rpc.Unsplash.Download](#anytype.Rpc.Unsplash.Download) + - [Rpc.Unsplash.Download.Request](#anytype.Rpc.Unsplash.Download.Request) + - [Rpc.Unsplash.Download.Response](#anytype.Rpc.Unsplash.Download.Response) + - [Rpc.Unsplash.Download.Response.Error](#anytype.Rpc.Unsplash.Download.Response.Error) + - [Rpc.Unsplash.Search](#anytype.Rpc.Unsplash.Search) + - [Rpc.Unsplash.Search.Request](#anytype.Rpc.Unsplash.Search.Request) + - [Rpc.Unsplash.Search.Response](#anytype.Rpc.Unsplash.Search.Response) + - [Rpc.Unsplash.Search.Response.Error](#anytype.Rpc.Unsplash.Search.Response.Error) + - [Rpc.Unsplash.Search.Response.Picture](#anytype.Rpc.Unsplash.Search.Response.Picture) + - [Rpc.Wallet](#anytype.Rpc.Wallet) + - [Rpc.Wallet.CloseSession](#anytype.Rpc.Wallet.CloseSession) + - [Rpc.Wallet.CloseSession.Request](#anytype.Rpc.Wallet.CloseSession.Request) + - [Rpc.Wallet.CloseSession.Response](#anytype.Rpc.Wallet.CloseSession.Response) + - [Rpc.Wallet.CloseSession.Response.Error](#anytype.Rpc.Wallet.CloseSession.Response.Error) + - [Rpc.Wallet.Convert](#anytype.Rpc.Wallet.Convert) + - [Rpc.Wallet.Convert.Request](#anytype.Rpc.Wallet.Convert.Request) + - [Rpc.Wallet.Convert.Response](#anytype.Rpc.Wallet.Convert.Response) + - [Rpc.Wallet.Convert.Response.Error](#anytype.Rpc.Wallet.Convert.Response.Error) + - [Rpc.Wallet.Create](#anytype.Rpc.Wallet.Create) + - [Rpc.Wallet.Create.Request](#anytype.Rpc.Wallet.Create.Request) + - [Rpc.Wallet.Create.Response](#anytype.Rpc.Wallet.Create.Response) + - [Rpc.Wallet.Create.Response.Error](#anytype.Rpc.Wallet.Create.Response.Error) + - [Rpc.Wallet.CreateSession](#anytype.Rpc.Wallet.CreateSession) + - [Rpc.Wallet.CreateSession.Request](#anytype.Rpc.Wallet.CreateSession.Request) + - [Rpc.Wallet.CreateSession.Response](#anytype.Rpc.Wallet.CreateSession.Response) + - [Rpc.Wallet.CreateSession.Response.Error](#anytype.Rpc.Wallet.CreateSession.Response.Error) + - [Rpc.Wallet.Recover](#anytype.Rpc.Wallet.Recover) + - [Rpc.Wallet.Recover.Request](#anytype.Rpc.Wallet.Recover.Request) + - [Rpc.Wallet.Recover.Response](#anytype.Rpc.Wallet.Recover.Response) + - [Rpc.Wallet.Recover.Response.Error](#anytype.Rpc.Wallet.Recover.Response.Error) + - [Rpc.Workspace](#anytype.Rpc.Workspace) + - [Rpc.Workspace.Create](#anytype.Rpc.Workspace.Create) + - [Rpc.Workspace.Create.Request](#anytype.Rpc.Workspace.Create.Request) + - [Rpc.Workspace.Create.Response](#anytype.Rpc.Workspace.Create.Response) + - [Rpc.Workspace.Create.Response.Error](#anytype.Rpc.Workspace.Create.Response.Error) + - [Rpc.Workspace.Export](#anytype.Rpc.Workspace.Export) + - [Rpc.Workspace.Export.Request](#anytype.Rpc.Workspace.Export.Request) + - [Rpc.Workspace.Export.Response](#anytype.Rpc.Workspace.Export.Response) + - [Rpc.Workspace.Export.Response.Error](#anytype.Rpc.Workspace.Export.Response.Error) + - [Rpc.Workspace.GetAll](#anytype.Rpc.Workspace.GetAll) + - [Rpc.Workspace.GetAll.Request](#anytype.Rpc.Workspace.GetAll.Request) + - [Rpc.Workspace.GetAll.Response](#anytype.Rpc.Workspace.GetAll.Response) + - [Rpc.Workspace.GetAll.Response.Error](#anytype.Rpc.Workspace.GetAll.Response.Error) + - [Rpc.Workspace.GetCurrent](#anytype.Rpc.Workspace.GetCurrent) + - [Rpc.Workspace.GetCurrent.Request](#anytype.Rpc.Workspace.GetCurrent.Request) + - [Rpc.Workspace.GetCurrent.Response](#anytype.Rpc.Workspace.GetCurrent.Response) + - [Rpc.Workspace.GetCurrent.Response.Error](#anytype.Rpc.Workspace.GetCurrent.Response.Error) + - [Rpc.Workspace.Object](#anytype.Rpc.Workspace.Object) + - [Rpc.Workspace.Object.Add](#anytype.Rpc.Workspace.Object.Add) + - [Rpc.Workspace.Object.Add.Request](#anytype.Rpc.Workspace.Object.Add.Request) + - [Rpc.Workspace.Object.Add.Response](#anytype.Rpc.Workspace.Object.Add.Response) + - [Rpc.Workspace.Object.Add.Response.Error](#anytype.Rpc.Workspace.Object.Add.Response.Error) + - [Rpc.Workspace.Object.ListAdd](#anytype.Rpc.Workspace.Object.ListAdd) + - [Rpc.Workspace.Object.ListAdd.Request](#anytype.Rpc.Workspace.Object.ListAdd.Request) + - [Rpc.Workspace.Object.ListAdd.Response](#anytype.Rpc.Workspace.Object.ListAdd.Response) + - [Rpc.Workspace.Object.ListAdd.Response.Error](#anytype.Rpc.Workspace.Object.ListAdd.Response.Error) + - [Rpc.Workspace.Object.ListRemove](#anytype.Rpc.Workspace.Object.ListRemove) + - [Rpc.Workspace.Object.ListRemove.Request](#anytype.Rpc.Workspace.Object.ListRemove.Request) + - [Rpc.Workspace.Object.ListRemove.Response](#anytype.Rpc.Workspace.Object.ListRemove.Response) + - [Rpc.Workspace.Object.ListRemove.Response.Error](#anytype.Rpc.Workspace.Object.ListRemove.Response.Error) + - [Rpc.Workspace.Select](#anytype.Rpc.Workspace.Select) + - [Rpc.Workspace.Select.Request](#anytype.Rpc.Workspace.Select.Request) + - [Rpc.Workspace.Select.Response](#anytype.Rpc.Workspace.Select.Response) + - [Rpc.Workspace.Select.Response.Error](#anytype.Rpc.Workspace.Select.Response.Error) + - [Rpc.Workspace.SetIsHighlighted](#anytype.Rpc.Workspace.SetIsHighlighted) + - [Rpc.Workspace.SetIsHighlighted.Request](#anytype.Rpc.Workspace.SetIsHighlighted.Request) + - [Rpc.Workspace.SetIsHighlighted.Response](#anytype.Rpc.Workspace.SetIsHighlighted.Response) + - [Rpc.Workspace.SetIsHighlighted.Response.Error](#anytype.Rpc.Workspace.SetIsHighlighted.Response.Error) + - [StreamRequest](#anytype.StreamRequest) - - [Rpc.Account.ConfigUpdate.Response.Error.Code](#anytype-Rpc-Account-ConfigUpdate-Response-Error-Code) - - [Rpc.Account.ConfigUpdate.Timezones](#anytype-Rpc-Account-ConfigUpdate-Timezones) - - [Rpc.Account.Create.Response.Error.Code](#anytype-Rpc-Account-Create-Response-Error-Code) - - [Rpc.Account.Delete.Response.Error.Code](#anytype-Rpc-Account-Delete-Response-Error-Code) - - [Rpc.Account.Move.Response.Error.Code](#anytype-Rpc-Account-Move-Response-Error-Code) - - [Rpc.Account.Recover.Response.Error.Code](#anytype-Rpc-Account-Recover-Response-Error-Code) - - [Rpc.Account.Select.Response.Error.Code](#anytype-Rpc-Account-Select-Response-Error-Code) - - [Rpc.Account.Stop.Response.Error.Code](#anytype-Rpc-Account-Stop-Response-Error-Code) - - [Rpc.App.GetVersion.Response.Error.Code](#anytype-Rpc-App-GetVersion-Response-Error-Code) - - [Rpc.App.SetDeviceState.Request.DeviceState](#anytype-Rpc-App-SetDeviceState-Request-DeviceState) - - [Rpc.App.SetDeviceState.Response.Error.Code](#anytype-Rpc-App-SetDeviceState-Response-Error-Code) - - [Rpc.App.Shutdown.Response.Error.Code](#anytype-Rpc-App-Shutdown-Response-Error-Code) - - [Rpc.Block.Copy.Response.Error.Code](#anytype-Rpc-Block-Copy-Response-Error-Code) - - [Rpc.Block.Create.Response.Error.Code](#anytype-Rpc-Block-Create-Response-Error-Code) - - [Rpc.Block.CreateWidget.Response.Error.Code](#anytype-Rpc-Block-CreateWidget-Response-Error-Code) - - [Rpc.Block.Cut.Response.Error.Code](#anytype-Rpc-Block-Cut-Response-Error-Code) - - [Rpc.Block.Download.Response.Error.Code](#anytype-Rpc-Block-Download-Response-Error-Code) - - [Rpc.Block.Export.Response.Error.Code](#anytype-Rpc-Block-Export-Response-Error-Code) - - [Rpc.Block.ListConvertToObjects.Response.Error.Code](#anytype-Rpc-Block-ListConvertToObjects-Response-Error-Code) - - [Rpc.Block.ListDelete.Response.Error.Code](#anytype-Rpc-Block-ListDelete-Response-Error-Code) - - [Rpc.Block.ListDuplicate.Response.Error.Code](#anytype-Rpc-Block-ListDuplicate-Response-Error-Code) - - [Rpc.Block.ListMoveToExistingObject.Response.Error.Code](#anytype-Rpc-Block-ListMoveToExistingObject-Response-Error-Code) - - [Rpc.Block.ListMoveToNewObject.Response.Error.Code](#anytype-Rpc-Block-ListMoveToNewObject-Response-Error-Code) - - [Rpc.Block.ListSetAlign.Response.Error.Code](#anytype-Rpc-Block-ListSetAlign-Response-Error-Code) - - [Rpc.Block.ListSetBackgroundColor.Response.Error.Code](#anytype-Rpc-Block-ListSetBackgroundColor-Response-Error-Code) - - [Rpc.Block.ListSetFields.Response.Error.Code](#anytype-Rpc-Block-ListSetFields-Response-Error-Code) - - [Rpc.Block.ListSetVerticalAlign.Response.Error.Code](#anytype-Rpc-Block-ListSetVerticalAlign-Response-Error-Code) - - [Rpc.Block.ListTurnInto.Response.Error.Code](#anytype-Rpc-Block-ListTurnInto-Response-Error-Code) - - [Rpc.Block.Merge.Response.Error.Code](#anytype-Rpc-Block-Merge-Response-Error-Code) - - [Rpc.Block.Paste.Response.Error.Code](#anytype-Rpc-Block-Paste-Response-Error-Code) - - [Rpc.Block.Replace.Response.Error.Code](#anytype-Rpc-Block-Replace-Response-Error-Code) - - [Rpc.Block.SetFields.Response.Error.Code](#anytype-Rpc-Block-SetFields-Response-Error-Code) - - [Rpc.Block.Split.Request.Mode](#anytype-Rpc-Block-Split-Request-Mode) - - [Rpc.Block.Split.Response.Error.Code](#anytype-Rpc-Block-Split-Response-Error-Code) - - [Rpc.Block.Upload.Response.Error.Code](#anytype-Rpc-Block-Upload-Response-Error-Code) - - [Rpc.BlockBookmark.CreateAndFetch.Response.Error.Code](#anytype-Rpc-BlockBookmark-CreateAndFetch-Response-Error-Code) - - [Rpc.BlockBookmark.Fetch.Response.Error.Code](#anytype-Rpc-BlockBookmark-Fetch-Response-Error-Code) - - [Rpc.BlockDataview.CreateBookmark.Response.Error.Code](#anytype-Rpc-BlockDataview-CreateBookmark-Response-Error-Code) - - [Rpc.BlockDataview.GroupOrder.Update.Response.Error.Code](#anytype-Rpc-BlockDataview-GroupOrder-Update-Response-Error-Code) - - [Rpc.BlockDataview.ObjectOrder.Update.Response.Error.Code](#anytype-Rpc-BlockDataview-ObjectOrder-Update-Response-Error-Code) - - [Rpc.BlockDataview.Relation.Add.Response.Error.Code](#anytype-Rpc-BlockDataview-Relation-Add-Response-Error-Code) - - [Rpc.BlockDataview.Relation.Delete.Response.Error.Code](#anytype-Rpc-BlockDataview-Relation-Delete-Response-Error-Code) - - [Rpc.BlockDataview.Relation.ListAvailable.Response.Error.Code](#anytype-Rpc-BlockDataview-Relation-ListAvailable-Response-Error-Code) - - [Rpc.BlockDataview.SetSource.Response.Error.Code](#anytype-Rpc-BlockDataview-SetSource-Response-Error-Code) - - [Rpc.BlockDataview.View.Create.Response.Error.Code](#anytype-Rpc-BlockDataview-View-Create-Response-Error-Code) - - [Rpc.BlockDataview.View.Delete.Response.Error.Code](#anytype-Rpc-BlockDataview-View-Delete-Response-Error-Code) - - [Rpc.BlockDataview.View.SetActive.Response.Error.Code](#anytype-Rpc-BlockDataview-View-SetActive-Response-Error-Code) - - [Rpc.BlockDataview.View.SetPosition.Response.Error.Code](#anytype-Rpc-BlockDataview-View-SetPosition-Response-Error-Code) - - [Rpc.BlockDataview.View.Update.Response.Error.Code](#anytype-Rpc-BlockDataview-View-Update-Response-Error-Code) - - [Rpc.BlockDiv.ListSetStyle.Response.Error.Code](#anytype-Rpc-BlockDiv-ListSetStyle-Response-Error-Code) - - [Rpc.BlockFile.CreateAndUpload.Response.Error.Code](#anytype-Rpc-BlockFile-CreateAndUpload-Response-Error-Code) - - [Rpc.BlockFile.ListSetStyle.Response.Error.Code](#anytype-Rpc-BlockFile-ListSetStyle-Response-Error-Code) - - [Rpc.BlockFile.SetName.Response.Error.Code](#anytype-Rpc-BlockFile-SetName-Response-Error-Code) - - [Rpc.BlockImage.SetName.Response.Error.Code](#anytype-Rpc-BlockImage-SetName-Response-Error-Code) - - [Rpc.BlockImage.SetWidth.Response.Error.Code](#anytype-Rpc-BlockImage-SetWidth-Response-Error-Code) - - [Rpc.BlockLatex.SetText.Response.Error.Code](#anytype-Rpc-BlockLatex-SetText-Response-Error-Code) - - [Rpc.BlockLink.CreateWithObject.Response.Error.Code](#anytype-Rpc-BlockLink-CreateWithObject-Response-Error-Code) - - [Rpc.BlockLink.ListSetAppearance.Response.Error.Code](#anytype-Rpc-BlockLink-ListSetAppearance-Response-Error-Code) - - [Rpc.BlockRelation.Add.Response.Error.Code](#anytype-Rpc-BlockRelation-Add-Response-Error-Code) - - [Rpc.BlockRelation.SetKey.Response.Error.Code](#anytype-Rpc-BlockRelation-SetKey-Response-Error-Code) - - [Rpc.BlockTable.ColumnCreate.Response.Error.Code](#anytype-Rpc-BlockTable-ColumnCreate-Response-Error-Code) - - [Rpc.BlockTable.ColumnDelete.Response.Error.Code](#anytype-Rpc-BlockTable-ColumnDelete-Response-Error-Code) - - [Rpc.BlockTable.ColumnDuplicate.Response.Error.Code](#anytype-Rpc-BlockTable-ColumnDuplicate-Response-Error-Code) - - [Rpc.BlockTable.ColumnListFill.Response.Error.Code](#anytype-Rpc-BlockTable-ColumnListFill-Response-Error-Code) - - [Rpc.BlockTable.ColumnMove.Response.Error.Code](#anytype-Rpc-BlockTable-ColumnMove-Response-Error-Code) - - [Rpc.BlockTable.Create.Response.Error.Code](#anytype-Rpc-BlockTable-Create-Response-Error-Code) - - [Rpc.BlockTable.Expand.Response.Error.Code](#anytype-Rpc-BlockTable-Expand-Response-Error-Code) - - [Rpc.BlockTable.RowCreate.Response.Error.Code](#anytype-Rpc-BlockTable-RowCreate-Response-Error-Code) - - [Rpc.BlockTable.RowDelete.Response.Error.Code](#anytype-Rpc-BlockTable-RowDelete-Response-Error-Code) - - [Rpc.BlockTable.RowDuplicate.Response.Error.Code](#anytype-Rpc-BlockTable-RowDuplicate-Response-Error-Code) - - [Rpc.BlockTable.RowListClean.Response.Error.Code](#anytype-Rpc-BlockTable-RowListClean-Response-Error-Code) - - [Rpc.BlockTable.RowListFill.Response.Error.Code](#anytype-Rpc-BlockTable-RowListFill-Response-Error-Code) - - [Rpc.BlockTable.RowSetHeader.Response.Error.Code](#anytype-Rpc-BlockTable-RowSetHeader-Response-Error-Code) - - [Rpc.BlockTable.Sort.Response.Error.Code](#anytype-Rpc-BlockTable-Sort-Response-Error-Code) - - [Rpc.BlockText.ListClearContent.Response.Error.Code](#anytype-Rpc-BlockText-ListClearContent-Response-Error-Code) - - [Rpc.BlockText.ListClearStyle.Response.Error.Code](#anytype-Rpc-BlockText-ListClearStyle-Response-Error-Code) - - [Rpc.BlockText.ListSetColor.Response.Error.Code](#anytype-Rpc-BlockText-ListSetColor-Response-Error-Code) - - [Rpc.BlockText.ListSetMark.Response.Error.Code](#anytype-Rpc-BlockText-ListSetMark-Response-Error-Code) - - [Rpc.BlockText.ListSetStyle.Response.Error.Code](#anytype-Rpc-BlockText-ListSetStyle-Response-Error-Code) - - [Rpc.BlockText.SetChecked.Response.Error.Code](#anytype-Rpc-BlockText-SetChecked-Response-Error-Code) - - [Rpc.BlockText.SetColor.Response.Error.Code](#anytype-Rpc-BlockText-SetColor-Response-Error-Code) - - [Rpc.BlockText.SetIcon.Response.Error.Code](#anytype-Rpc-BlockText-SetIcon-Response-Error-Code) - - [Rpc.BlockText.SetMarks.Get.Response.Error.Code](#anytype-Rpc-BlockText-SetMarks-Get-Response-Error-Code) - - [Rpc.BlockText.SetStyle.Response.Error.Code](#anytype-Rpc-BlockText-SetStyle-Response-Error-Code) - - [Rpc.BlockText.SetText.Response.Error.Code](#anytype-Rpc-BlockText-SetText-Response-Error-Code) - - [Rpc.BlockVideo.SetName.Response.Error.Code](#anytype-Rpc-BlockVideo-SetName-Response-Error-Code) - - [Rpc.BlockVideo.SetWidth.Response.Error.Code](#anytype-Rpc-BlockVideo-SetWidth-Response-Error-Code) - - [Rpc.Debug.ExportLocalstore.Response.Error.Code](#anytype-Rpc-Debug-ExportLocalstore-Response-Error-Code) - - [Rpc.Debug.Ping.Response.Error.Code](#anytype-Rpc-Debug-Ping-Response-Error-Code) - - [Rpc.Debug.Sync.Response.Error.Code](#anytype-Rpc-Debug-Sync-Response-Error-Code) - - [Rpc.Debug.Thread.Response.Error.Code](#anytype-Rpc-Debug-Thread-Response-Error-Code) - - [Rpc.Debug.Tree.Response.Error.Code](#anytype-Rpc-Debug-Tree-Response-Error-Code) - - [Rpc.File.Download.Response.Error.Code](#anytype-Rpc-File-Download-Response-Error-Code) - - [Rpc.File.Drop.Response.Error.Code](#anytype-Rpc-File-Drop-Response-Error-Code) - - [Rpc.File.ListOffload.Response.Error.Code](#anytype-Rpc-File-ListOffload-Response-Error-Code) - - [Rpc.File.Offload.Response.Error.Code](#anytype-Rpc-File-Offload-Response-Error-Code) - - [Rpc.File.Upload.Response.Error.Code](#anytype-Rpc-File-Upload-Response-Error-Code) - - [Rpc.GenericErrorResponse.Error.Code](#anytype-Rpc-GenericErrorResponse-Error-Code) - - [Rpc.History.GetVersions.Response.Error.Code](#anytype-Rpc-History-GetVersions-Response-Error-Code) - - [Rpc.History.SetVersion.Response.Error.Code](#anytype-Rpc-History-SetVersion-Response-Error-Code) - - [Rpc.History.ShowVersion.Response.Error.Code](#anytype-Rpc-History-ShowVersion-Response-Error-Code) - - [Rpc.LinkPreview.Response.Error.Code](#anytype-Rpc-LinkPreview-Response-Error-Code) - - [Rpc.Log.Send.Request.Level](#anytype-Rpc-Log-Send-Request-Level) - - [Rpc.Log.Send.Response.Error.Code](#anytype-Rpc-Log-Send-Response-Error-Code) - - [Rpc.Metrics.SetParameters.Response.Error.Code](#anytype-Rpc-Metrics-SetParameters-Response-Error-Code) - - [Rpc.Navigation.Context](#anytype-Rpc-Navigation-Context) - - [Rpc.Navigation.GetObjectInfoWithLinks.Response.Error.Code](#anytype-Rpc-Navigation-GetObjectInfoWithLinks-Response-Error-Code) - - [Rpc.Navigation.ListObjects.Response.Error.Code](#anytype-Rpc-Navigation-ListObjects-Response-Error-Code) - - [Rpc.Object.AddWithObjectId.Response.Error.Code](#anytype-Rpc-Object-AddWithObjectId-Response-Error-Code) - - [Rpc.Object.ApplyTemplate.Response.Error.Code](#anytype-Rpc-Object-ApplyTemplate-Response-Error-Code) - - [Rpc.Object.BookmarkFetch.Response.Error.Code](#anytype-Rpc-Object-BookmarkFetch-Response-Error-Code) - - [Rpc.Object.Close.Response.Error.Code](#anytype-Rpc-Object-Close-Response-Error-Code) - - [Rpc.Object.Create.Response.Error.Code](#anytype-Rpc-Object-Create-Response-Error-Code) - - [Rpc.Object.CreateBookmark.Response.Error.Code](#anytype-Rpc-Object-CreateBookmark-Response-Error-Code) - - [Rpc.Object.CreateObjectType.Response.Error.Code](#anytype-Rpc-Object-CreateObjectType-Response-Error-Code) - - [Rpc.Object.CreateRelation.Response.Error.Code](#anytype-Rpc-Object-CreateRelation-Response-Error-Code) - - [Rpc.Object.CreateRelationOption.Response.Error.Code](#anytype-Rpc-Object-CreateRelationOption-Response-Error-Code) - - [Rpc.Object.CreateSet.Response.Error.Code](#anytype-Rpc-Object-CreateSet-Response-Error-Code) - - [Rpc.Object.Duplicate.Response.Error.Code](#anytype-Rpc-Object-Duplicate-Response-Error-Code) - - [Rpc.Object.Graph.Edge.Type](#anytype-Rpc-Object-Graph-Edge-Type) - - [Rpc.Object.Graph.Response.Error.Code](#anytype-Rpc-Object-Graph-Response-Error-Code) - - [Rpc.Object.GroupsSubscribe.Response.Error.Code](#anytype-Rpc-Object-GroupsSubscribe-Response-Error-Code) - - [Rpc.Object.Import.Request.Mode](#anytype-Rpc-Object-Import-Request-Mode) - - [Rpc.Object.Import.Request.Type](#anytype-Rpc-Object-Import-Request-Type) - - [Rpc.Object.Import.Response.Error.Code](#anytype-Rpc-Object-Import-Response-Error-Code) - - [Rpc.Object.ImportList.ImportResponse.Type](#anytype-Rpc-Object-ImportList-ImportResponse-Type) - - [Rpc.Object.ImportList.Response.Error.Code](#anytype-Rpc-Object-ImportList-Response-Error-Code) - - [Rpc.Object.ImportMarkdown.Response.Error.Code](#anytype-Rpc-Object-ImportMarkdown-Response-Error-Code) - - [Rpc.Object.ListDelete.Response.Error.Code](#anytype-Rpc-Object-ListDelete-Response-Error-Code) - - [Rpc.Object.ListDuplicate.Response.Error.Code](#anytype-Rpc-Object-ListDuplicate-Response-Error-Code) - - [Rpc.Object.ListExport.Format](#anytype-Rpc-Object-ListExport-Format) - - [Rpc.Object.ListExport.Response.Error.Code](#anytype-Rpc-Object-ListExport-Response-Error-Code) - - [Rpc.Object.ListSetIsArchived.Response.Error.Code](#anytype-Rpc-Object-ListSetIsArchived-Response-Error-Code) - - [Rpc.Object.ListSetIsFavorite.Response.Error.Code](#anytype-Rpc-Object-ListSetIsFavorite-Response-Error-Code) - - [Rpc.Object.Open.Response.Error.Code](#anytype-Rpc-Object-Open-Response-Error-Code) - - [Rpc.Object.OpenBreadcrumbs.Response.Error.Code](#anytype-Rpc-Object-OpenBreadcrumbs-Response-Error-Code) - - [Rpc.Object.Redo.Response.Error.Code](#anytype-Rpc-Object-Redo-Response-Error-Code) - - [Rpc.Object.Search.Response.Error.Code](#anytype-Rpc-Object-Search-Response-Error-Code) - - [Rpc.Object.SearchSubscribe.Response.Error.Code](#anytype-Rpc-Object-SearchSubscribe-Response-Error-Code) - - [Rpc.Object.SearchUnsubscribe.Response.Error.Code](#anytype-Rpc-Object-SearchUnsubscribe-Response-Error-Code) - - [Rpc.Object.SetBreadcrumbs.Response.Error.Code](#anytype-Rpc-Object-SetBreadcrumbs-Response-Error-Code) - - [Rpc.Object.SetDetails.Response.Error.Code](#anytype-Rpc-Object-SetDetails-Response-Error-Code) - - [Rpc.Object.SetInternalFlags.Response.Error.Code](#anytype-Rpc-Object-SetInternalFlags-Response-Error-Code) - - [Rpc.Object.SetIsArchived.Response.Error.Code](#anytype-Rpc-Object-SetIsArchived-Response-Error-Code) - - [Rpc.Object.SetIsFavorite.Response.Error.Code](#anytype-Rpc-Object-SetIsFavorite-Response-Error-Code) - - [Rpc.Object.SetLayout.Response.Error.Code](#anytype-Rpc-Object-SetLayout-Response-Error-Code) - - [Rpc.Object.SetObjectType.Response.Error.Code](#anytype-Rpc-Object-SetObjectType-Response-Error-Code) - - [Rpc.Object.ShareByLink.Response.Error.Code](#anytype-Rpc-Object-ShareByLink-Response-Error-Code) - - [Rpc.Object.Show.Response.Error.Code](#anytype-Rpc-Object-Show-Response-Error-Code) - - [Rpc.Object.SubscribeIds.Response.Error.Code](#anytype-Rpc-Object-SubscribeIds-Response-Error-Code) - - [Rpc.Object.ToBookmark.Response.Error.Code](#anytype-Rpc-Object-ToBookmark-Response-Error-Code) - - [Rpc.Object.ToSet.Response.Error.Code](#anytype-Rpc-Object-ToSet-Response-Error-Code) - - [Rpc.Object.Undo.Response.Error.Code](#anytype-Rpc-Object-Undo-Response-Error-Code) - - [Rpc.ObjectRelation.Add.Response.Error.Code](#anytype-Rpc-ObjectRelation-Add-Response-Error-Code) - - [Rpc.ObjectRelation.AddFeatured.Response.Error.Code](#anytype-Rpc-ObjectRelation-AddFeatured-Response-Error-Code) - - [Rpc.ObjectRelation.Delete.Response.Error.Code](#anytype-Rpc-ObjectRelation-Delete-Response-Error-Code) - - [Rpc.ObjectRelation.ListAvailable.Response.Error.Code](#anytype-Rpc-ObjectRelation-ListAvailable-Response-Error-Code) - - [Rpc.ObjectRelation.RemoveFeatured.Response.Error.Code](#anytype-Rpc-ObjectRelation-RemoveFeatured-Response-Error-Code) - - [Rpc.ObjectType.Relation.Add.Response.Error.Code](#anytype-Rpc-ObjectType-Relation-Add-Response-Error-Code) - - [Rpc.ObjectType.Relation.List.Response.Error.Code](#anytype-Rpc-ObjectType-Relation-List-Response-Error-Code) - - [Rpc.ObjectType.Relation.Remove.Response.Error.Code](#anytype-Rpc-ObjectType-Relation-Remove-Response-Error-Code) - - [Rpc.Process.Cancel.Response.Error.Code](#anytype-Rpc-Process-Cancel-Response-Error-Code) - - [Rpc.Relation.ListRemoveOption.Response.Error.Code](#anytype-Rpc-Relation-ListRemoveOption-Response-Error-Code) - - [Rpc.Relation.Options.Response.Error.Code](#anytype-Rpc-Relation-Options-Response-Error-Code) - - [Rpc.Template.Clone.Response.Error.Code](#anytype-Rpc-Template-Clone-Response-Error-Code) - - [Rpc.Template.CreateFromObject.Response.Error.Code](#anytype-Rpc-Template-CreateFromObject-Response-Error-Code) - - [Rpc.Template.CreateFromObjectType.Response.Error.Code](#anytype-Rpc-Template-CreateFromObjectType-Response-Error-Code) - - [Rpc.Template.ExportAll.Response.Error.Code](#anytype-Rpc-Template-ExportAll-Response-Error-Code) - - [Rpc.Unsplash.Download.Response.Error.Code](#anytype-Rpc-Unsplash-Download-Response-Error-Code) - - [Rpc.Unsplash.Search.Response.Error.Code](#anytype-Rpc-Unsplash-Search-Response-Error-Code) - - [Rpc.Wallet.CloseSession.Response.Error.Code](#anytype-Rpc-Wallet-CloseSession-Response-Error-Code) - - [Rpc.Wallet.Convert.Response.Error.Code](#anytype-Rpc-Wallet-Convert-Response-Error-Code) - - [Rpc.Wallet.Create.Response.Error.Code](#anytype-Rpc-Wallet-Create-Response-Error-Code) - - [Rpc.Wallet.CreateSession.Response.Error.Code](#anytype-Rpc-Wallet-CreateSession-Response-Error-Code) - - [Rpc.Wallet.Recover.Response.Error.Code](#anytype-Rpc-Wallet-Recover-Response-Error-Code) - - [Rpc.Workspace.Create.Response.Error.Code](#anytype-Rpc-Workspace-Create-Response-Error-Code) - - [Rpc.Workspace.Export.Response.Error.Code](#anytype-Rpc-Workspace-Export-Response-Error-Code) - - [Rpc.Workspace.GetAll.Response.Error.Code](#anytype-Rpc-Workspace-GetAll-Response-Error-Code) - - [Rpc.Workspace.GetCurrent.Response.Error.Code](#anytype-Rpc-Workspace-GetCurrent-Response-Error-Code) - - [Rpc.Workspace.Object.Add.Response.Error.Code](#anytype-Rpc-Workspace-Object-Add-Response-Error-Code) - - [Rpc.Workspace.Object.ListAdd.Response.Error.Code](#anytype-Rpc-Workspace-Object-ListAdd-Response-Error-Code) - - [Rpc.Workspace.Object.ListRemove.Response.Error.Code](#anytype-Rpc-Workspace-Object-ListRemove-Response-Error-Code) - - [Rpc.Workspace.Select.Response.Error.Code](#anytype-Rpc-Workspace-Select-Response-Error-Code) - - [Rpc.Workspace.SetIsHighlighted.Response.Error.Code](#anytype-Rpc-Workspace-SetIsHighlighted-Response-Error-Code) + - [Rpc.Account.ConfigUpdate.Response.Error.Code](#anytype.Rpc.Account.ConfigUpdate.Response.Error.Code) + - [Rpc.Account.ConfigUpdate.Timezones](#anytype.Rpc.Account.ConfigUpdate.Timezones) + - [Rpc.Account.Create.Response.Error.Code](#anytype.Rpc.Account.Create.Response.Error.Code) + - [Rpc.Account.Delete.Response.Error.Code](#anytype.Rpc.Account.Delete.Response.Error.Code) + - [Rpc.Account.Move.Response.Error.Code](#anytype.Rpc.Account.Move.Response.Error.Code) + - [Rpc.Account.Recover.Response.Error.Code](#anytype.Rpc.Account.Recover.Response.Error.Code) + - [Rpc.Account.Select.Response.Error.Code](#anytype.Rpc.Account.Select.Response.Error.Code) + - [Rpc.Account.Stop.Response.Error.Code](#anytype.Rpc.Account.Stop.Response.Error.Code) + - [Rpc.App.GetVersion.Response.Error.Code](#anytype.Rpc.App.GetVersion.Response.Error.Code) + - [Rpc.App.SetDeviceState.Request.DeviceState](#anytype.Rpc.App.SetDeviceState.Request.DeviceState) + - [Rpc.App.SetDeviceState.Response.Error.Code](#anytype.Rpc.App.SetDeviceState.Response.Error.Code) + - [Rpc.App.Shutdown.Response.Error.Code](#anytype.Rpc.App.Shutdown.Response.Error.Code) + - [Rpc.Block.Copy.Response.Error.Code](#anytype.Rpc.Block.Copy.Response.Error.Code) + - [Rpc.Block.Create.Response.Error.Code](#anytype.Rpc.Block.Create.Response.Error.Code) + - [Rpc.Block.CreateWidget.Response.Error.Code](#anytype.Rpc.Block.CreateWidget.Response.Error.Code) + - [Rpc.Block.Cut.Response.Error.Code](#anytype.Rpc.Block.Cut.Response.Error.Code) + - [Rpc.Block.Download.Response.Error.Code](#anytype.Rpc.Block.Download.Response.Error.Code) + - [Rpc.Block.Export.Response.Error.Code](#anytype.Rpc.Block.Export.Response.Error.Code) + - [Rpc.Block.ListConvertToObjects.Response.Error.Code](#anytype.Rpc.Block.ListConvertToObjects.Response.Error.Code) + - [Rpc.Block.ListDelete.Response.Error.Code](#anytype.Rpc.Block.ListDelete.Response.Error.Code) + - [Rpc.Block.ListDuplicate.Response.Error.Code](#anytype.Rpc.Block.ListDuplicate.Response.Error.Code) + - [Rpc.Block.ListMoveToExistingObject.Response.Error.Code](#anytype.Rpc.Block.ListMoveToExistingObject.Response.Error.Code) + - [Rpc.Block.ListMoveToNewObject.Response.Error.Code](#anytype.Rpc.Block.ListMoveToNewObject.Response.Error.Code) + - [Rpc.Block.ListSetAlign.Response.Error.Code](#anytype.Rpc.Block.ListSetAlign.Response.Error.Code) + - [Rpc.Block.ListSetBackgroundColor.Response.Error.Code](#anytype.Rpc.Block.ListSetBackgroundColor.Response.Error.Code) + - [Rpc.Block.ListSetFields.Response.Error.Code](#anytype.Rpc.Block.ListSetFields.Response.Error.Code) + - [Rpc.Block.ListSetVerticalAlign.Response.Error.Code](#anytype.Rpc.Block.ListSetVerticalAlign.Response.Error.Code) + - [Rpc.Block.ListTurnInto.Response.Error.Code](#anytype.Rpc.Block.ListTurnInto.Response.Error.Code) + - [Rpc.Block.Merge.Response.Error.Code](#anytype.Rpc.Block.Merge.Response.Error.Code) + - [Rpc.Block.Paste.Response.Error.Code](#anytype.Rpc.Block.Paste.Response.Error.Code) + - [Rpc.Block.Replace.Response.Error.Code](#anytype.Rpc.Block.Replace.Response.Error.Code) + - [Rpc.Block.SetFields.Response.Error.Code](#anytype.Rpc.Block.SetFields.Response.Error.Code) + - [Rpc.Block.Split.Request.Mode](#anytype.Rpc.Block.Split.Request.Mode) + - [Rpc.Block.Split.Response.Error.Code](#anytype.Rpc.Block.Split.Response.Error.Code) + - [Rpc.Block.Upload.Response.Error.Code](#anytype.Rpc.Block.Upload.Response.Error.Code) + - [Rpc.BlockBookmark.CreateAndFetch.Response.Error.Code](#anytype.Rpc.BlockBookmark.CreateAndFetch.Response.Error.Code) + - [Rpc.BlockBookmark.Fetch.Response.Error.Code](#anytype.Rpc.BlockBookmark.Fetch.Response.Error.Code) + - [Rpc.BlockDataview.CreateBookmark.Response.Error.Code](#anytype.Rpc.BlockDataview.CreateBookmark.Response.Error.Code) + - [Rpc.BlockDataview.GroupOrder.Update.Response.Error.Code](#anytype.Rpc.BlockDataview.GroupOrder.Update.Response.Error.Code) + - [Rpc.BlockDataview.ObjectOrder.Update.Response.Error.Code](#anytype.Rpc.BlockDataview.ObjectOrder.Update.Response.Error.Code) + - [Rpc.BlockDataview.Relation.Add.Response.Error.Code](#anytype.Rpc.BlockDataview.Relation.Add.Response.Error.Code) + - [Rpc.BlockDataview.Relation.Delete.Response.Error.Code](#anytype.Rpc.BlockDataview.Relation.Delete.Response.Error.Code) + - [Rpc.BlockDataview.Relation.ListAvailable.Response.Error.Code](#anytype.Rpc.BlockDataview.Relation.ListAvailable.Response.Error.Code) + - [Rpc.BlockDataview.SetSource.Response.Error.Code](#anytype.Rpc.BlockDataview.SetSource.Response.Error.Code) + - [Rpc.BlockDataview.View.Create.Response.Error.Code](#anytype.Rpc.BlockDataview.View.Create.Response.Error.Code) + - [Rpc.BlockDataview.View.Delete.Response.Error.Code](#anytype.Rpc.BlockDataview.View.Delete.Response.Error.Code) + - [Rpc.BlockDataview.View.SetActive.Response.Error.Code](#anytype.Rpc.BlockDataview.View.SetActive.Response.Error.Code) + - [Rpc.BlockDataview.View.SetPosition.Response.Error.Code](#anytype.Rpc.BlockDataview.View.SetPosition.Response.Error.Code) + - [Rpc.BlockDataview.View.Update.Response.Error.Code](#anytype.Rpc.BlockDataview.View.Update.Response.Error.Code) + - [Rpc.BlockDiv.ListSetStyle.Response.Error.Code](#anytype.Rpc.BlockDiv.ListSetStyle.Response.Error.Code) + - [Rpc.BlockFile.CreateAndUpload.Response.Error.Code](#anytype.Rpc.BlockFile.CreateAndUpload.Response.Error.Code) + - [Rpc.BlockFile.ListSetStyle.Response.Error.Code](#anytype.Rpc.BlockFile.ListSetStyle.Response.Error.Code) + - [Rpc.BlockFile.SetName.Response.Error.Code](#anytype.Rpc.BlockFile.SetName.Response.Error.Code) + - [Rpc.BlockImage.SetName.Response.Error.Code](#anytype.Rpc.BlockImage.SetName.Response.Error.Code) + - [Rpc.BlockImage.SetWidth.Response.Error.Code](#anytype.Rpc.BlockImage.SetWidth.Response.Error.Code) + - [Rpc.BlockLatex.SetText.Response.Error.Code](#anytype.Rpc.BlockLatex.SetText.Response.Error.Code) + - [Rpc.BlockLink.CreateWithObject.Response.Error.Code](#anytype.Rpc.BlockLink.CreateWithObject.Response.Error.Code) + - [Rpc.BlockLink.ListSetAppearance.Response.Error.Code](#anytype.Rpc.BlockLink.ListSetAppearance.Response.Error.Code) + - [Rpc.BlockRelation.Add.Response.Error.Code](#anytype.Rpc.BlockRelation.Add.Response.Error.Code) + - [Rpc.BlockRelation.SetKey.Response.Error.Code](#anytype.Rpc.BlockRelation.SetKey.Response.Error.Code) + - [Rpc.BlockTable.ColumnCreate.Response.Error.Code](#anytype.Rpc.BlockTable.ColumnCreate.Response.Error.Code) + - [Rpc.BlockTable.ColumnDelete.Response.Error.Code](#anytype.Rpc.BlockTable.ColumnDelete.Response.Error.Code) + - [Rpc.BlockTable.ColumnDuplicate.Response.Error.Code](#anytype.Rpc.BlockTable.ColumnDuplicate.Response.Error.Code) + - [Rpc.BlockTable.ColumnListFill.Response.Error.Code](#anytype.Rpc.BlockTable.ColumnListFill.Response.Error.Code) + - [Rpc.BlockTable.ColumnMove.Response.Error.Code](#anytype.Rpc.BlockTable.ColumnMove.Response.Error.Code) + - [Rpc.BlockTable.Create.Response.Error.Code](#anytype.Rpc.BlockTable.Create.Response.Error.Code) + - [Rpc.BlockTable.Expand.Response.Error.Code](#anytype.Rpc.BlockTable.Expand.Response.Error.Code) + - [Rpc.BlockTable.RowCreate.Response.Error.Code](#anytype.Rpc.BlockTable.RowCreate.Response.Error.Code) + - [Rpc.BlockTable.RowDelete.Response.Error.Code](#anytype.Rpc.BlockTable.RowDelete.Response.Error.Code) + - [Rpc.BlockTable.RowDuplicate.Response.Error.Code](#anytype.Rpc.BlockTable.RowDuplicate.Response.Error.Code) + - [Rpc.BlockTable.RowListClean.Response.Error.Code](#anytype.Rpc.BlockTable.RowListClean.Response.Error.Code) + - [Rpc.BlockTable.RowListFill.Response.Error.Code](#anytype.Rpc.BlockTable.RowListFill.Response.Error.Code) + - [Rpc.BlockTable.RowSetHeader.Response.Error.Code](#anytype.Rpc.BlockTable.RowSetHeader.Response.Error.Code) + - [Rpc.BlockTable.Sort.Response.Error.Code](#anytype.Rpc.BlockTable.Sort.Response.Error.Code) + - [Rpc.BlockText.ListClearContent.Response.Error.Code](#anytype.Rpc.BlockText.ListClearContent.Response.Error.Code) + - [Rpc.BlockText.ListClearStyle.Response.Error.Code](#anytype.Rpc.BlockText.ListClearStyle.Response.Error.Code) + - [Rpc.BlockText.ListSetColor.Response.Error.Code](#anytype.Rpc.BlockText.ListSetColor.Response.Error.Code) + - [Rpc.BlockText.ListSetMark.Response.Error.Code](#anytype.Rpc.BlockText.ListSetMark.Response.Error.Code) + - [Rpc.BlockText.ListSetStyle.Response.Error.Code](#anytype.Rpc.BlockText.ListSetStyle.Response.Error.Code) + - [Rpc.BlockText.SetChecked.Response.Error.Code](#anytype.Rpc.BlockText.SetChecked.Response.Error.Code) + - [Rpc.BlockText.SetColor.Response.Error.Code](#anytype.Rpc.BlockText.SetColor.Response.Error.Code) + - [Rpc.BlockText.SetIcon.Response.Error.Code](#anytype.Rpc.BlockText.SetIcon.Response.Error.Code) + - [Rpc.BlockText.SetMarks.Get.Response.Error.Code](#anytype.Rpc.BlockText.SetMarks.Get.Response.Error.Code) + - [Rpc.BlockText.SetStyle.Response.Error.Code](#anytype.Rpc.BlockText.SetStyle.Response.Error.Code) + - [Rpc.BlockText.SetText.Response.Error.Code](#anytype.Rpc.BlockText.SetText.Response.Error.Code) + - [Rpc.BlockVideo.SetName.Response.Error.Code](#anytype.Rpc.BlockVideo.SetName.Response.Error.Code) + - [Rpc.BlockVideo.SetWidth.Response.Error.Code](#anytype.Rpc.BlockVideo.SetWidth.Response.Error.Code) + - [Rpc.Debug.ExportLocalstore.Response.Error.Code](#anytype.Rpc.Debug.ExportLocalstore.Response.Error.Code) + - [Rpc.Debug.Ping.Response.Error.Code](#anytype.Rpc.Debug.Ping.Response.Error.Code) + - [Rpc.Debug.Sync.Response.Error.Code](#anytype.Rpc.Debug.Sync.Response.Error.Code) + - [Rpc.Debug.Thread.Response.Error.Code](#anytype.Rpc.Debug.Thread.Response.Error.Code) + - [Rpc.Debug.Tree.Response.Error.Code](#anytype.Rpc.Debug.Tree.Response.Error.Code) + - [Rpc.File.Download.Response.Error.Code](#anytype.Rpc.File.Download.Response.Error.Code) + - [Rpc.File.Drop.Response.Error.Code](#anytype.Rpc.File.Drop.Response.Error.Code) + - [Rpc.File.ListOffload.Response.Error.Code](#anytype.Rpc.File.ListOffload.Response.Error.Code) + - [Rpc.File.Offload.Response.Error.Code](#anytype.Rpc.File.Offload.Response.Error.Code) + - [Rpc.File.Upload.Response.Error.Code](#anytype.Rpc.File.Upload.Response.Error.Code) + - [Rpc.GenericErrorResponse.Error.Code](#anytype.Rpc.GenericErrorResponse.Error.Code) + - [Rpc.History.GetVersions.Response.Error.Code](#anytype.Rpc.History.GetVersions.Response.Error.Code) + - [Rpc.History.SetVersion.Response.Error.Code](#anytype.Rpc.History.SetVersion.Response.Error.Code) + - [Rpc.History.ShowVersion.Response.Error.Code](#anytype.Rpc.History.ShowVersion.Response.Error.Code) + - [Rpc.LinkPreview.Response.Error.Code](#anytype.Rpc.LinkPreview.Response.Error.Code) + - [Rpc.Log.Send.Request.Level](#anytype.Rpc.Log.Send.Request.Level) + - [Rpc.Log.Send.Response.Error.Code](#anytype.Rpc.Log.Send.Response.Error.Code) + - [Rpc.Metrics.SetParameters.Response.Error.Code](#anytype.Rpc.Metrics.SetParameters.Response.Error.Code) + - [Rpc.Navigation.Context](#anytype.Rpc.Navigation.Context) + - [Rpc.Navigation.GetObjectInfoWithLinks.Response.Error.Code](#anytype.Rpc.Navigation.GetObjectInfoWithLinks.Response.Error.Code) + - [Rpc.Navigation.ListObjects.Response.Error.Code](#anytype.Rpc.Navigation.ListObjects.Response.Error.Code) + - [Rpc.Object.AddWithObjectId.Response.Error.Code](#anytype.Rpc.Object.AddWithObjectId.Response.Error.Code) + - [Rpc.Object.ApplyTemplate.Response.Error.Code](#anytype.Rpc.Object.ApplyTemplate.Response.Error.Code) + - [Rpc.Object.BookmarkFetch.Response.Error.Code](#anytype.Rpc.Object.BookmarkFetch.Response.Error.Code) + - [Rpc.Object.Close.Response.Error.Code](#anytype.Rpc.Object.Close.Response.Error.Code) + - [Rpc.Object.Create.Response.Error.Code](#anytype.Rpc.Object.Create.Response.Error.Code) + - [Rpc.Object.CreateBookmark.Response.Error.Code](#anytype.Rpc.Object.CreateBookmark.Response.Error.Code) + - [Rpc.Object.CreateObjectType.Response.Error.Code](#anytype.Rpc.Object.CreateObjectType.Response.Error.Code) + - [Rpc.Object.CreateRelation.Response.Error.Code](#anytype.Rpc.Object.CreateRelation.Response.Error.Code) + - [Rpc.Object.CreateRelationOption.Response.Error.Code](#anytype.Rpc.Object.CreateRelationOption.Response.Error.Code) + - [Rpc.Object.CreateSet.Response.Error.Code](#anytype.Rpc.Object.CreateSet.Response.Error.Code) + - [Rpc.Object.Duplicate.Response.Error.Code](#anytype.Rpc.Object.Duplicate.Response.Error.Code) + - [Rpc.Object.Graph.Edge.Type](#anytype.Rpc.Object.Graph.Edge.Type) + - [Rpc.Object.Graph.Response.Error.Code](#anytype.Rpc.Object.Graph.Response.Error.Code) + - [Rpc.Object.GroupsSubscribe.Response.Error.Code](#anytype.Rpc.Object.GroupsSubscribe.Response.Error.Code) + - [Rpc.Object.Import.Request.Mode](#anytype.Rpc.Object.Import.Request.Mode) + - [Rpc.Object.Import.Request.Type](#anytype.Rpc.Object.Import.Request.Type) + - [Rpc.Object.Import.Response.Error.Code](#anytype.Rpc.Object.Import.Response.Error.Code) + - [Rpc.Object.ImportList.ImportResponse.Type](#anytype.Rpc.Object.ImportList.ImportResponse.Type) + - [Rpc.Object.ImportList.Response.Error.Code](#anytype.Rpc.Object.ImportList.Response.Error.Code) + - [Rpc.Object.ImportMarkdown.Response.Error.Code](#anytype.Rpc.Object.ImportMarkdown.Response.Error.Code) + - [Rpc.Object.ListDelete.Response.Error.Code](#anytype.Rpc.Object.ListDelete.Response.Error.Code) + - [Rpc.Object.ListDuplicate.Response.Error.Code](#anytype.Rpc.Object.ListDuplicate.Response.Error.Code) + - [Rpc.Object.ListExport.Format](#anytype.Rpc.Object.ListExport.Format) + - [Rpc.Object.ListExport.Response.Error.Code](#anytype.Rpc.Object.ListExport.Response.Error.Code) + - [Rpc.Object.ListSetIsArchived.Response.Error.Code](#anytype.Rpc.Object.ListSetIsArchived.Response.Error.Code) + - [Rpc.Object.ListSetIsFavorite.Response.Error.Code](#anytype.Rpc.Object.ListSetIsFavorite.Response.Error.Code) + - [Rpc.Object.Open.Response.Error.Code](#anytype.Rpc.Object.Open.Response.Error.Code) + - [Rpc.Object.OpenBreadcrumbs.Response.Error.Code](#anytype.Rpc.Object.OpenBreadcrumbs.Response.Error.Code) + - [Rpc.Object.Redo.Response.Error.Code](#anytype.Rpc.Object.Redo.Response.Error.Code) + - [Rpc.Object.Search.Response.Error.Code](#anytype.Rpc.Object.Search.Response.Error.Code) + - [Rpc.Object.SearchSubscribe.Response.Error.Code](#anytype.Rpc.Object.SearchSubscribe.Response.Error.Code) + - [Rpc.Object.SearchUnsubscribe.Response.Error.Code](#anytype.Rpc.Object.SearchUnsubscribe.Response.Error.Code) + - [Rpc.Object.SetBreadcrumbs.Response.Error.Code](#anytype.Rpc.Object.SetBreadcrumbs.Response.Error.Code) + - [Rpc.Object.SetDetails.Response.Error.Code](#anytype.Rpc.Object.SetDetails.Response.Error.Code) + - [Rpc.Object.SetInternalFlags.Response.Error.Code](#anytype.Rpc.Object.SetInternalFlags.Response.Error.Code) + - [Rpc.Object.SetIsArchived.Response.Error.Code](#anytype.Rpc.Object.SetIsArchived.Response.Error.Code) + - [Rpc.Object.SetIsFavorite.Response.Error.Code](#anytype.Rpc.Object.SetIsFavorite.Response.Error.Code) + - [Rpc.Object.SetLayout.Response.Error.Code](#anytype.Rpc.Object.SetLayout.Response.Error.Code) + - [Rpc.Object.SetObjectType.Response.Error.Code](#anytype.Rpc.Object.SetObjectType.Response.Error.Code) + - [Rpc.Object.ShareByLink.Response.Error.Code](#anytype.Rpc.Object.ShareByLink.Response.Error.Code) + - [Rpc.Object.Show.Response.Error.Code](#anytype.Rpc.Object.Show.Response.Error.Code) + - [Rpc.Object.SubscribeIds.Response.Error.Code](#anytype.Rpc.Object.SubscribeIds.Response.Error.Code) + - [Rpc.Object.ToBookmark.Response.Error.Code](#anytype.Rpc.Object.ToBookmark.Response.Error.Code) + - [Rpc.Object.ToSet.Response.Error.Code](#anytype.Rpc.Object.ToSet.Response.Error.Code) + - [Rpc.Object.Undo.Response.Error.Code](#anytype.Rpc.Object.Undo.Response.Error.Code) + - [Rpc.ObjectRelation.Add.Response.Error.Code](#anytype.Rpc.ObjectRelation.Add.Response.Error.Code) + - [Rpc.ObjectRelation.AddFeatured.Response.Error.Code](#anytype.Rpc.ObjectRelation.AddFeatured.Response.Error.Code) + - [Rpc.ObjectRelation.Delete.Response.Error.Code](#anytype.Rpc.ObjectRelation.Delete.Response.Error.Code) + - [Rpc.ObjectRelation.ListAvailable.Response.Error.Code](#anytype.Rpc.ObjectRelation.ListAvailable.Response.Error.Code) + - [Rpc.ObjectRelation.RemoveFeatured.Response.Error.Code](#anytype.Rpc.ObjectRelation.RemoveFeatured.Response.Error.Code) + - [Rpc.ObjectType.Relation.Add.Response.Error.Code](#anytype.Rpc.ObjectType.Relation.Add.Response.Error.Code) + - [Rpc.ObjectType.Relation.List.Response.Error.Code](#anytype.Rpc.ObjectType.Relation.List.Response.Error.Code) + - [Rpc.ObjectType.Relation.Remove.Response.Error.Code](#anytype.Rpc.ObjectType.Relation.Remove.Response.Error.Code) + - [Rpc.Process.Cancel.Response.Error.Code](#anytype.Rpc.Process.Cancel.Response.Error.Code) + - [Rpc.Relation.ListRemoveOption.Response.Error.Code](#anytype.Rpc.Relation.ListRemoveOption.Response.Error.Code) + - [Rpc.Relation.Options.Response.Error.Code](#anytype.Rpc.Relation.Options.Response.Error.Code) + - [Rpc.Template.Clone.Response.Error.Code](#anytype.Rpc.Template.Clone.Response.Error.Code) + - [Rpc.Template.CreateFromObject.Response.Error.Code](#anytype.Rpc.Template.CreateFromObject.Response.Error.Code) + - [Rpc.Template.CreateFromObjectType.Response.Error.Code](#anytype.Rpc.Template.CreateFromObjectType.Response.Error.Code) + - [Rpc.Template.ExportAll.Response.Error.Code](#anytype.Rpc.Template.ExportAll.Response.Error.Code) + - [Rpc.Unsplash.Download.Response.Error.Code](#anytype.Rpc.Unsplash.Download.Response.Error.Code) + - [Rpc.Unsplash.Search.Response.Error.Code](#anytype.Rpc.Unsplash.Search.Response.Error.Code) + - [Rpc.Wallet.CloseSession.Response.Error.Code](#anytype.Rpc.Wallet.CloseSession.Response.Error.Code) + - [Rpc.Wallet.Convert.Response.Error.Code](#anytype.Rpc.Wallet.Convert.Response.Error.Code) + - [Rpc.Wallet.Create.Response.Error.Code](#anytype.Rpc.Wallet.Create.Response.Error.Code) + - [Rpc.Wallet.CreateSession.Response.Error.Code](#anytype.Rpc.Wallet.CreateSession.Response.Error.Code) + - [Rpc.Wallet.Recover.Response.Error.Code](#anytype.Rpc.Wallet.Recover.Response.Error.Code) + - [Rpc.Workspace.Create.Response.Error.Code](#anytype.Rpc.Workspace.Create.Response.Error.Code) + - [Rpc.Workspace.Export.Response.Error.Code](#anytype.Rpc.Workspace.Export.Response.Error.Code) + - [Rpc.Workspace.GetAll.Response.Error.Code](#anytype.Rpc.Workspace.GetAll.Response.Error.Code) + - [Rpc.Workspace.GetCurrent.Response.Error.Code](#anytype.Rpc.Workspace.GetCurrent.Response.Error.Code) + - [Rpc.Workspace.Object.Add.Response.Error.Code](#anytype.Rpc.Workspace.Object.Add.Response.Error.Code) + - [Rpc.Workspace.Object.ListAdd.Response.Error.Code](#anytype.Rpc.Workspace.Object.ListAdd.Response.Error.Code) + - [Rpc.Workspace.Object.ListRemove.Response.Error.Code](#anytype.Rpc.Workspace.Object.ListRemove.Response.Error.Code) + - [Rpc.Workspace.Select.Response.Error.Code](#anytype.Rpc.Workspace.Select.Response.Error.Code) + - [Rpc.Workspace.SetIsHighlighted.Response.Error.Code](#anytype.Rpc.Workspace.SetIsHighlighted.Response.Error.Code) - - [File-level Extensions](#pb_protos_commands-proto-extensions) + - [File-level Extensions](#pb/protos/commands.proto-extensions) -- [pb/protos/events.proto](#pb_protos_events-proto) - - [Event](#anytype-Event) - - [Event.Account](#anytype-Event-Account) - - [Event.Account.Config](#anytype-Event-Account-Config) - - [Event.Account.Config.Update](#anytype-Event-Account-Config-Update) - - [Event.Account.Details](#anytype-Event-Account-Details) - - [Event.Account.Show](#anytype-Event-Account-Show) - - [Event.Account.Update](#anytype-Event-Account-Update) - - [Event.Block](#anytype-Event-Block) - - [Event.Block.Add](#anytype-Event-Block-Add) - - [Event.Block.Dataview](#anytype-Event-Block-Dataview) - - [Event.Block.Dataview.GroupOrderUpdate](#anytype-Event-Block-Dataview-GroupOrderUpdate) - - [Event.Block.Dataview.ObjectOrderUpdate](#anytype-Event-Block-Dataview-ObjectOrderUpdate) - - [Event.Block.Dataview.OldRelationDelete](#anytype-Event-Block-Dataview-OldRelationDelete) - - [Event.Block.Dataview.OldRelationSet](#anytype-Event-Block-Dataview-OldRelationSet) - - [Event.Block.Dataview.RelationDelete](#anytype-Event-Block-Dataview-RelationDelete) - - [Event.Block.Dataview.RelationSet](#anytype-Event-Block-Dataview-RelationSet) - - [Event.Block.Dataview.SliceChange](#anytype-Event-Block-Dataview-SliceChange) - - [Event.Block.Dataview.SourceSet](#anytype-Event-Block-Dataview-SourceSet) - - [Event.Block.Dataview.ViewDelete](#anytype-Event-Block-Dataview-ViewDelete) - - [Event.Block.Dataview.ViewOrder](#anytype-Event-Block-Dataview-ViewOrder) - - [Event.Block.Dataview.ViewSet](#anytype-Event-Block-Dataview-ViewSet) - - [Event.Block.Delete](#anytype-Event-Block-Delete) - - [Event.Block.FilesUpload](#anytype-Event-Block-FilesUpload) - - [Event.Block.Fill](#anytype-Event-Block-Fill) - - [Event.Block.Fill.Align](#anytype-Event-Block-Fill-Align) - - [Event.Block.Fill.BackgroundColor](#anytype-Event-Block-Fill-BackgroundColor) - - [Event.Block.Fill.Bookmark](#anytype-Event-Block-Fill-Bookmark) - - [Event.Block.Fill.Bookmark.Description](#anytype-Event-Block-Fill-Bookmark-Description) - - [Event.Block.Fill.Bookmark.FaviconHash](#anytype-Event-Block-Fill-Bookmark-FaviconHash) - - [Event.Block.Fill.Bookmark.ImageHash](#anytype-Event-Block-Fill-Bookmark-ImageHash) - - [Event.Block.Fill.Bookmark.TargetObjectId](#anytype-Event-Block-Fill-Bookmark-TargetObjectId) - - [Event.Block.Fill.Bookmark.Title](#anytype-Event-Block-Fill-Bookmark-Title) - - [Event.Block.Fill.Bookmark.Type](#anytype-Event-Block-Fill-Bookmark-Type) - - [Event.Block.Fill.Bookmark.Url](#anytype-Event-Block-Fill-Bookmark-Url) - - [Event.Block.Fill.ChildrenIds](#anytype-Event-Block-Fill-ChildrenIds) - - [Event.Block.Fill.DatabaseRecords](#anytype-Event-Block-Fill-DatabaseRecords) - - [Event.Block.Fill.Details](#anytype-Event-Block-Fill-Details) - - [Event.Block.Fill.Div](#anytype-Event-Block-Fill-Div) - - [Event.Block.Fill.Div.Style](#anytype-Event-Block-Fill-Div-Style) - - [Event.Block.Fill.Fields](#anytype-Event-Block-Fill-Fields) - - [Event.Block.Fill.File](#anytype-Event-Block-Fill-File) - - [Event.Block.Fill.File.Hash](#anytype-Event-Block-Fill-File-Hash) - - [Event.Block.Fill.File.Mime](#anytype-Event-Block-Fill-File-Mime) - - [Event.Block.Fill.File.Name](#anytype-Event-Block-Fill-File-Name) - - [Event.Block.Fill.File.Size](#anytype-Event-Block-Fill-File-Size) - - [Event.Block.Fill.File.State](#anytype-Event-Block-Fill-File-State) - - [Event.Block.Fill.File.Style](#anytype-Event-Block-Fill-File-Style) - - [Event.Block.Fill.File.Type](#anytype-Event-Block-Fill-File-Type) - - [Event.Block.Fill.File.Width](#anytype-Event-Block-Fill-File-Width) - - [Event.Block.Fill.Link](#anytype-Event-Block-Fill-Link) - - [Event.Block.Fill.Link.Fields](#anytype-Event-Block-Fill-Link-Fields) - - [Event.Block.Fill.Link.Style](#anytype-Event-Block-Fill-Link-Style) - - [Event.Block.Fill.Link.TargetBlockId](#anytype-Event-Block-Fill-Link-TargetBlockId) - - [Event.Block.Fill.Restrictions](#anytype-Event-Block-Fill-Restrictions) - - [Event.Block.Fill.Text](#anytype-Event-Block-Fill-Text) - - [Event.Block.Fill.Text.Checked](#anytype-Event-Block-Fill-Text-Checked) - - [Event.Block.Fill.Text.Color](#anytype-Event-Block-Fill-Text-Color) - - [Event.Block.Fill.Text.Marks](#anytype-Event-Block-Fill-Text-Marks) - - [Event.Block.Fill.Text.Style](#anytype-Event-Block-Fill-Text-Style) - - [Event.Block.Fill.Text.Text](#anytype-Event-Block-Fill-Text-Text) - - [Event.Block.MarksInfo](#anytype-Event-Block-MarksInfo) - - [Event.Block.Set](#anytype-Event-Block-Set) - - [Event.Block.Set.Align](#anytype-Event-Block-Set-Align) - - [Event.Block.Set.BackgroundColor](#anytype-Event-Block-Set-BackgroundColor) - - [Event.Block.Set.Bookmark](#anytype-Event-Block-Set-Bookmark) - - [Event.Block.Set.Bookmark.Description](#anytype-Event-Block-Set-Bookmark-Description) - - [Event.Block.Set.Bookmark.FaviconHash](#anytype-Event-Block-Set-Bookmark-FaviconHash) - - [Event.Block.Set.Bookmark.ImageHash](#anytype-Event-Block-Set-Bookmark-ImageHash) - - [Event.Block.Set.Bookmark.State](#anytype-Event-Block-Set-Bookmark-State) - - [Event.Block.Set.Bookmark.TargetObjectId](#anytype-Event-Block-Set-Bookmark-TargetObjectId) - - [Event.Block.Set.Bookmark.Title](#anytype-Event-Block-Set-Bookmark-Title) - - [Event.Block.Set.Bookmark.Type](#anytype-Event-Block-Set-Bookmark-Type) - - [Event.Block.Set.Bookmark.Url](#anytype-Event-Block-Set-Bookmark-Url) - - [Event.Block.Set.ChildrenIds](#anytype-Event-Block-Set-ChildrenIds) - - [Event.Block.Set.Div](#anytype-Event-Block-Set-Div) - - [Event.Block.Set.Div.Style](#anytype-Event-Block-Set-Div-Style) - - [Event.Block.Set.Fields](#anytype-Event-Block-Set-Fields) - - [Event.Block.Set.File](#anytype-Event-Block-Set-File) - - [Event.Block.Set.File.Hash](#anytype-Event-Block-Set-File-Hash) - - [Event.Block.Set.File.Mime](#anytype-Event-Block-Set-File-Mime) - - [Event.Block.Set.File.Name](#anytype-Event-Block-Set-File-Name) - - [Event.Block.Set.File.Size](#anytype-Event-Block-Set-File-Size) - - [Event.Block.Set.File.State](#anytype-Event-Block-Set-File-State) - - [Event.Block.Set.File.Style](#anytype-Event-Block-Set-File-Style) - - [Event.Block.Set.File.Type](#anytype-Event-Block-Set-File-Type) - - [Event.Block.Set.File.Width](#anytype-Event-Block-Set-File-Width) - - [Event.Block.Set.Latex](#anytype-Event-Block-Set-Latex) - - [Event.Block.Set.Latex.Text](#anytype-Event-Block-Set-Latex-Text) - - [Event.Block.Set.Link](#anytype-Event-Block-Set-Link) - - [Event.Block.Set.Link.CardStyle](#anytype-Event-Block-Set-Link-CardStyle) - - [Event.Block.Set.Link.Description](#anytype-Event-Block-Set-Link-Description) - - [Event.Block.Set.Link.Fields](#anytype-Event-Block-Set-Link-Fields) - - [Event.Block.Set.Link.IconSize](#anytype-Event-Block-Set-Link-IconSize) - - [Event.Block.Set.Link.Relations](#anytype-Event-Block-Set-Link-Relations) - - [Event.Block.Set.Link.Style](#anytype-Event-Block-Set-Link-Style) - - [Event.Block.Set.Link.TargetBlockId](#anytype-Event-Block-Set-Link-TargetBlockId) - - [Event.Block.Set.Relation](#anytype-Event-Block-Set-Relation) - - [Event.Block.Set.Relation.Key](#anytype-Event-Block-Set-Relation-Key) - - [Event.Block.Set.Restrictions](#anytype-Event-Block-Set-Restrictions) - - [Event.Block.Set.TableRow](#anytype-Event-Block-Set-TableRow) - - [Event.Block.Set.TableRow.IsHeader](#anytype-Event-Block-Set-TableRow-IsHeader) - - [Event.Block.Set.Text](#anytype-Event-Block-Set-Text) - - [Event.Block.Set.Text.Checked](#anytype-Event-Block-Set-Text-Checked) - - [Event.Block.Set.Text.Color](#anytype-Event-Block-Set-Text-Color) - - [Event.Block.Set.Text.IconEmoji](#anytype-Event-Block-Set-Text-IconEmoji) - - [Event.Block.Set.Text.IconImage](#anytype-Event-Block-Set-Text-IconImage) - - [Event.Block.Set.Text.Marks](#anytype-Event-Block-Set-Text-Marks) - - [Event.Block.Set.Text.Style](#anytype-Event-Block-Set-Text-Style) - - [Event.Block.Set.Text.Text](#anytype-Event-Block-Set-Text-Text) - - [Event.Block.Set.VerticalAlign](#anytype-Event-Block-Set-VerticalAlign) - - [Event.Block.Set.Widget](#anytype-Event-Block-Set-Widget) - - [Event.Block.Set.Widget.Layout](#anytype-Event-Block-Set-Widget-Layout) - - [Event.Message](#anytype-Event-Message) - - [Event.Object](#anytype-Event-Object) - - [Event.Object.Details](#anytype-Event-Object-Details) - - [Event.Object.Details.Amend](#anytype-Event-Object-Details-Amend) - - [Event.Object.Details.Amend.KeyValue](#anytype-Event-Object-Details-Amend-KeyValue) - - [Event.Object.Details.Set](#anytype-Event-Object-Details-Set) - - [Event.Object.Details.Unset](#anytype-Event-Object-Details-Unset) - - [Event.Object.Relations](#anytype-Event-Object-Relations) - - [Event.Object.Relations.Amend](#anytype-Event-Object-Relations-Amend) - - [Event.Object.Relations.Remove](#anytype-Event-Object-Relations-Remove) - - [Event.Object.Remove](#anytype-Event-Object-Remove) - - [Event.Object.Restriction](#anytype-Event-Object-Restriction) - - [Event.Object.Subscription](#anytype-Event-Object-Subscription) - - [Event.Object.Subscription.Add](#anytype-Event-Object-Subscription-Add) - - [Event.Object.Subscription.Counters](#anytype-Event-Object-Subscription-Counters) - - [Event.Object.Subscription.Groups](#anytype-Event-Object-Subscription-Groups) - - [Event.Object.Subscription.Position](#anytype-Event-Object-Subscription-Position) - - [Event.Object.Subscription.Remove](#anytype-Event-Object-Subscription-Remove) - - [Event.Ping](#anytype-Event-Ping) - - [Event.Process](#anytype-Event-Process) - - [Event.Process.Done](#anytype-Event-Process-Done) - - [Event.Process.New](#anytype-Event-Process-New) - - [Event.Process.Update](#anytype-Event-Process-Update) - - [Event.Status](#anytype-Event-Status) - - [Event.Status.Thread](#anytype-Event-Status-Thread) - - [Event.Status.Thread.Account](#anytype-Event-Status-Thread-Account) - - [Event.Status.Thread.Cafe](#anytype-Event-Status-Thread-Cafe) - - [Event.Status.Thread.Cafe.PinStatus](#anytype-Event-Status-Thread-Cafe-PinStatus) - - [Event.Status.Thread.Device](#anytype-Event-Status-Thread-Device) - - [Event.Status.Thread.Summary](#anytype-Event-Status-Thread-Summary) - - [Event.User](#anytype-Event-User) - - [Event.User.Block](#anytype-Event-User-Block) - - [Event.User.Block.Join](#anytype-Event-User-Block-Join) - - [Event.User.Block.Left](#anytype-Event-User-Block-Left) - - [Event.User.Block.SelectRange](#anytype-Event-User-Block-SelectRange) - - [Event.User.Block.TextRange](#anytype-Event-User-Block-TextRange) - - [Model](#anytype-Model) - - [Model.Process](#anytype-Model-Process) - - [Model.Process.Progress](#anytype-Model-Process-Progress) - - [ResponseEvent](#anytype-ResponseEvent) +- [pb/protos/events.proto](#pb/protos/events.proto) + - [Event](#anytype.Event) + - [Event.Account](#anytype.Event.Account) + - [Event.Account.Config](#anytype.Event.Account.Config) + - [Event.Account.Config.Update](#anytype.Event.Account.Config.Update) + - [Event.Account.Details](#anytype.Event.Account.Details) + - [Event.Account.Show](#anytype.Event.Account.Show) + - [Event.Account.Update](#anytype.Event.Account.Update) + - [Event.Block](#anytype.Event.Block) + - [Event.Block.Add](#anytype.Event.Block.Add) + - [Event.Block.Dataview](#anytype.Event.Block.Dataview) + - [Event.Block.Dataview.GroupOrderUpdate](#anytype.Event.Block.Dataview.GroupOrderUpdate) + - [Event.Block.Dataview.ObjectOrderUpdate](#anytype.Event.Block.Dataview.ObjectOrderUpdate) + - [Event.Block.Dataview.OldRelationDelete](#anytype.Event.Block.Dataview.OldRelationDelete) + - [Event.Block.Dataview.OldRelationSet](#anytype.Event.Block.Dataview.OldRelationSet) + - [Event.Block.Dataview.RelationDelete](#anytype.Event.Block.Dataview.RelationDelete) + - [Event.Block.Dataview.RelationSet](#anytype.Event.Block.Dataview.RelationSet) + - [Event.Block.Dataview.SliceChange](#anytype.Event.Block.Dataview.SliceChange) + - [Event.Block.Dataview.SourceSet](#anytype.Event.Block.Dataview.SourceSet) + - [Event.Block.Dataview.ViewDelete](#anytype.Event.Block.Dataview.ViewDelete) + - [Event.Block.Dataview.ViewOrder](#anytype.Event.Block.Dataview.ViewOrder) + - [Event.Block.Dataview.ViewSet](#anytype.Event.Block.Dataview.ViewSet) + - [Event.Block.Delete](#anytype.Event.Block.Delete) + - [Event.Block.FilesUpload](#anytype.Event.Block.FilesUpload) + - [Event.Block.Fill](#anytype.Event.Block.Fill) + - [Event.Block.Fill.Align](#anytype.Event.Block.Fill.Align) + - [Event.Block.Fill.BackgroundColor](#anytype.Event.Block.Fill.BackgroundColor) + - [Event.Block.Fill.Bookmark](#anytype.Event.Block.Fill.Bookmark) + - [Event.Block.Fill.Bookmark.Description](#anytype.Event.Block.Fill.Bookmark.Description) + - [Event.Block.Fill.Bookmark.FaviconHash](#anytype.Event.Block.Fill.Bookmark.FaviconHash) + - [Event.Block.Fill.Bookmark.ImageHash](#anytype.Event.Block.Fill.Bookmark.ImageHash) + - [Event.Block.Fill.Bookmark.TargetObjectId](#anytype.Event.Block.Fill.Bookmark.TargetObjectId) + - [Event.Block.Fill.Bookmark.Title](#anytype.Event.Block.Fill.Bookmark.Title) + - [Event.Block.Fill.Bookmark.Type](#anytype.Event.Block.Fill.Bookmark.Type) + - [Event.Block.Fill.Bookmark.Url](#anytype.Event.Block.Fill.Bookmark.Url) + - [Event.Block.Fill.ChildrenIds](#anytype.Event.Block.Fill.ChildrenIds) + - [Event.Block.Fill.DatabaseRecords](#anytype.Event.Block.Fill.DatabaseRecords) + - [Event.Block.Fill.Details](#anytype.Event.Block.Fill.Details) + - [Event.Block.Fill.Div](#anytype.Event.Block.Fill.Div) + - [Event.Block.Fill.Div.Style](#anytype.Event.Block.Fill.Div.Style) + - [Event.Block.Fill.Fields](#anytype.Event.Block.Fill.Fields) + - [Event.Block.Fill.File](#anytype.Event.Block.Fill.File) + - [Event.Block.Fill.File.Hash](#anytype.Event.Block.Fill.File.Hash) + - [Event.Block.Fill.File.Mime](#anytype.Event.Block.Fill.File.Mime) + - [Event.Block.Fill.File.Name](#anytype.Event.Block.Fill.File.Name) + - [Event.Block.Fill.File.Size](#anytype.Event.Block.Fill.File.Size) + - [Event.Block.Fill.File.State](#anytype.Event.Block.Fill.File.State) + - [Event.Block.Fill.File.Style](#anytype.Event.Block.Fill.File.Style) + - [Event.Block.Fill.File.Type](#anytype.Event.Block.Fill.File.Type) + - [Event.Block.Fill.File.Width](#anytype.Event.Block.Fill.File.Width) + - [Event.Block.Fill.Link](#anytype.Event.Block.Fill.Link) + - [Event.Block.Fill.Link.Fields](#anytype.Event.Block.Fill.Link.Fields) + - [Event.Block.Fill.Link.Style](#anytype.Event.Block.Fill.Link.Style) + - [Event.Block.Fill.Link.TargetBlockId](#anytype.Event.Block.Fill.Link.TargetBlockId) + - [Event.Block.Fill.Restrictions](#anytype.Event.Block.Fill.Restrictions) + - [Event.Block.Fill.Text](#anytype.Event.Block.Fill.Text) + - [Event.Block.Fill.Text.Checked](#anytype.Event.Block.Fill.Text.Checked) + - [Event.Block.Fill.Text.Color](#anytype.Event.Block.Fill.Text.Color) + - [Event.Block.Fill.Text.Marks](#anytype.Event.Block.Fill.Text.Marks) + - [Event.Block.Fill.Text.Style](#anytype.Event.Block.Fill.Text.Style) + - [Event.Block.Fill.Text.Text](#anytype.Event.Block.Fill.Text.Text) + - [Event.Block.MarksInfo](#anytype.Event.Block.MarksInfo) + - [Event.Block.Set](#anytype.Event.Block.Set) + - [Event.Block.Set.Align](#anytype.Event.Block.Set.Align) + - [Event.Block.Set.BackgroundColor](#anytype.Event.Block.Set.BackgroundColor) + - [Event.Block.Set.Bookmark](#anytype.Event.Block.Set.Bookmark) + - [Event.Block.Set.Bookmark.Description](#anytype.Event.Block.Set.Bookmark.Description) + - [Event.Block.Set.Bookmark.FaviconHash](#anytype.Event.Block.Set.Bookmark.FaviconHash) + - [Event.Block.Set.Bookmark.ImageHash](#anytype.Event.Block.Set.Bookmark.ImageHash) + - [Event.Block.Set.Bookmark.State](#anytype.Event.Block.Set.Bookmark.State) + - [Event.Block.Set.Bookmark.TargetObjectId](#anytype.Event.Block.Set.Bookmark.TargetObjectId) + - [Event.Block.Set.Bookmark.Title](#anytype.Event.Block.Set.Bookmark.Title) + - [Event.Block.Set.Bookmark.Type](#anytype.Event.Block.Set.Bookmark.Type) + - [Event.Block.Set.Bookmark.Url](#anytype.Event.Block.Set.Bookmark.Url) + - [Event.Block.Set.ChildrenIds](#anytype.Event.Block.Set.ChildrenIds) + - [Event.Block.Set.Div](#anytype.Event.Block.Set.Div) + - [Event.Block.Set.Div.Style](#anytype.Event.Block.Set.Div.Style) + - [Event.Block.Set.Fields](#anytype.Event.Block.Set.Fields) + - [Event.Block.Set.File](#anytype.Event.Block.Set.File) + - [Event.Block.Set.File.Hash](#anytype.Event.Block.Set.File.Hash) + - [Event.Block.Set.File.Mime](#anytype.Event.Block.Set.File.Mime) + - [Event.Block.Set.File.Name](#anytype.Event.Block.Set.File.Name) + - [Event.Block.Set.File.Size](#anytype.Event.Block.Set.File.Size) + - [Event.Block.Set.File.State](#anytype.Event.Block.Set.File.State) + - [Event.Block.Set.File.Style](#anytype.Event.Block.Set.File.Style) + - [Event.Block.Set.File.Type](#anytype.Event.Block.Set.File.Type) + - [Event.Block.Set.File.Width](#anytype.Event.Block.Set.File.Width) + - [Event.Block.Set.Latex](#anytype.Event.Block.Set.Latex) + - [Event.Block.Set.Latex.Text](#anytype.Event.Block.Set.Latex.Text) + - [Event.Block.Set.Link](#anytype.Event.Block.Set.Link) + - [Event.Block.Set.Link.CardStyle](#anytype.Event.Block.Set.Link.CardStyle) + - [Event.Block.Set.Link.Description](#anytype.Event.Block.Set.Link.Description) + - [Event.Block.Set.Link.Fields](#anytype.Event.Block.Set.Link.Fields) + - [Event.Block.Set.Link.IconSize](#anytype.Event.Block.Set.Link.IconSize) + - [Event.Block.Set.Link.Relations](#anytype.Event.Block.Set.Link.Relations) + - [Event.Block.Set.Link.Style](#anytype.Event.Block.Set.Link.Style) + - [Event.Block.Set.Link.TargetBlockId](#anytype.Event.Block.Set.Link.TargetBlockId) + - [Event.Block.Set.Relation](#anytype.Event.Block.Set.Relation) + - [Event.Block.Set.Relation.Key](#anytype.Event.Block.Set.Relation.Key) + - [Event.Block.Set.Restrictions](#anytype.Event.Block.Set.Restrictions) + - [Event.Block.Set.TableRow](#anytype.Event.Block.Set.TableRow) + - [Event.Block.Set.TableRow.IsHeader](#anytype.Event.Block.Set.TableRow.IsHeader) + - [Event.Block.Set.Text](#anytype.Event.Block.Set.Text) + - [Event.Block.Set.Text.Checked](#anytype.Event.Block.Set.Text.Checked) + - [Event.Block.Set.Text.Color](#anytype.Event.Block.Set.Text.Color) + - [Event.Block.Set.Text.IconEmoji](#anytype.Event.Block.Set.Text.IconEmoji) + - [Event.Block.Set.Text.IconImage](#anytype.Event.Block.Set.Text.IconImage) + - [Event.Block.Set.Text.Marks](#anytype.Event.Block.Set.Text.Marks) + - [Event.Block.Set.Text.Style](#anytype.Event.Block.Set.Text.Style) + - [Event.Block.Set.Text.Text](#anytype.Event.Block.Set.Text.Text) + - [Event.Block.Set.VerticalAlign](#anytype.Event.Block.Set.VerticalAlign) + - [Event.Block.Set.Widget](#anytype.Event.Block.Set.Widget) + - [Event.Block.Set.Widget.Layout](#anytype.Event.Block.Set.Widget.Layout) + - [Event.Message](#anytype.Event.Message) + - [Event.Object](#anytype.Event.Object) + - [Event.Object.Details](#anytype.Event.Object.Details) + - [Event.Object.Details.Amend](#anytype.Event.Object.Details.Amend) + - [Event.Object.Details.Amend.KeyValue](#anytype.Event.Object.Details.Amend.KeyValue) + - [Event.Object.Details.Set](#anytype.Event.Object.Details.Set) + - [Event.Object.Details.Unset](#anytype.Event.Object.Details.Unset) + - [Event.Object.Relations](#anytype.Event.Object.Relations) + - [Event.Object.Relations.Amend](#anytype.Event.Object.Relations.Amend) + - [Event.Object.Relations.Remove](#anytype.Event.Object.Relations.Remove) + - [Event.Object.Remove](#anytype.Event.Object.Remove) + - [Event.Object.Restriction](#anytype.Event.Object.Restriction) + - [Event.Object.Subscription](#anytype.Event.Object.Subscription) + - [Event.Object.Subscription.Add](#anytype.Event.Object.Subscription.Add) + - [Event.Object.Subscription.Counters](#anytype.Event.Object.Subscription.Counters) + - [Event.Object.Subscription.Groups](#anytype.Event.Object.Subscription.Groups) + - [Event.Object.Subscription.Position](#anytype.Event.Object.Subscription.Position) + - [Event.Object.Subscription.Remove](#anytype.Event.Object.Subscription.Remove) + - [Event.Ping](#anytype.Event.Ping) + - [Event.Process](#anytype.Event.Process) + - [Event.Process.Done](#anytype.Event.Process.Done) + - [Event.Process.New](#anytype.Event.Process.New) + - [Event.Process.Update](#anytype.Event.Process.Update) + - [Event.Status](#anytype.Event.Status) + - [Event.Status.Thread](#anytype.Event.Status.Thread) + - [Event.Status.Thread.Account](#anytype.Event.Status.Thread.Account) + - [Event.Status.Thread.Cafe](#anytype.Event.Status.Thread.Cafe) + - [Event.Status.Thread.Cafe.PinStatus](#anytype.Event.Status.Thread.Cafe.PinStatus) + - [Event.Status.Thread.Device](#anytype.Event.Status.Thread.Device) + - [Event.Status.Thread.Summary](#anytype.Event.Status.Thread.Summary) + - [Event.User](#anytype.Event.User) + - [Event.User.Block](#anytype.Event.User.Block) + - [Event.User.Block.Join](#anytype.Event.User.Block.Join) + - [Event.User.Block.Left](#anytype.Event.User.Block.Left) + - [Event.User.Block.SelectRange](#anytype.Event.User.Block.SelectRange) + - [Event.User.Block.TextRange](#anytype.Event.User.Block.TextRange) + - [Model](#anytype.Model) + - [Model.Process](#anytype.Model.Process) + - [Model.Process.Progress](#anytype.Model.Process.Progress) + - [ResponseEvent](#anytype.ResponseEvent) - - [Event.Block.Dataview.SliceOperation](#anytype-Event-Block-Dataview-SliceOperation) - - [Event.Status.Thread.SyncStatus](#anytype-Event-Status-Thread-SyncStatus) - - [Model.Process.State](#anytype-Model-Process-State) - - [Model.Process.Type](#anytype-Model-Process-Type) + - [Event.Block.Dataview.SliceOperation](#anytype.Event.Block.Dataview.SliceOperation) + - [Event.Status.Thread.SyncStatus](#anytype.Event.Status.Thread.SyncStatus) + - [Model.Process.State](#anytype.Model.Process.State) + - [Model.Process.Type](#anytype.Model.Process.Type) -- [pkg/lib/pb/model/protos/localstore.proto](#pkg_lib_pb_model_protos_localstore-proto) - - [ObjectDetails](#anytype-model-ObjectDetails) - - [ObjectInfo](#anytype-model-ObjectInfo) - - [ObjectInfoWithLinks](#anytype-model-ObjectInfoWithLinks) - - [ObjectInfoWithOutboundLinks](#anytype-model-ObjectInfoWithOutboundLinks) - - [ObjectInfoWithOutboundLinksIDs](#anytype-model-ObjectInfoWithOutboundLinksIDs) - - [ObjectLinks](#anytype-model-ObjectLinks) - - [ObjectLinksInfo](#anytype-model-ObjectLinksInfo) - - [ObjectStoreChecksums](#anytype-model-ObjectStoreChecksums) +- [pkg/lib/pb/model/protos/localstore.proto](#pkg/lib/pb/model/protos/localstore.proto) + - [ObjectDetails](#anytype.model.ObjectDetails) + - [ObjectInfo](#anytype.model.ObjectInfo) + - [ObjectInfoWithLinks](#anytype.model.ObjectInfoWithLinks) + - [ObjectInfoWithOutboundLinks](#anytype.model.ObjectInfoWithOutboundLinks) + - [ObjectInfoWithOutboundLinksIDs](#anytype.model.ObjectInfoWithOutboundLinksIDs) + - [ObjectLinks](#anytype.model.ObjectLinks) + - [ObjectLinksInfo](#anytype.model.ObjectLinksInfo) + - [ObjectStoreChecksums](#anytype.model.ObjectStoreChecksums) -- [pkg/lib/pb/model/protos/models.proto](#pkg_lib_pb_model_protos_models-proto) - - [Account](#anytype-model-Account) - - [Account.Avatar](#anytype-model-Account-Avatar) - - [Account.Config](#anytype-model-Account-Config) - - [Account.Info](#anytype-model-Account-Info) - - [Account.Status](#anytype-model-Account-Status) - - [Block](#anytype-model-Block) - - [Block.Content](#anytype-model-Block-Content) - - [Block.Content.Bookmark](#anytype-model-Block-Content-Bookmark) - - [Block.Content.Dataview](#anytype-model-Block-Content-Dataview) - - [Block.Content.Dataview.Checkbox](#anytype-model-Block-Content-Dataview-Checkbox) - - [Block.Content.Dataview.Date](#anytype-model-Block-Content-Dataview-Date) - - [Block.Content.Dataview.Filter](#anytype-model-Block-Content-Dataview-Filter) - - [Block.Content.Dataview.Group](#anytype-model-Block-Content-Dataview-Group) - - [Block.Content.Dataview.GroupOrder](#anytype-model-Block-Content-Dataview-GroupOrder) - - [Block.Content.Dataview.ObjectOrder](#anytype-model-Block-Content-Dataview-ObjectOrder) - - [Block.Content.Dataview.Relation](#anytype-model-Block-Content-Dataview-Relation) - - [Block.Content.Dataview.Sort](#anytype-model-Block-Content-Dataview-Sort) - - [Block.Content.Dataview.Status](#anytype-model-Block-Content-Dataview-Status) - - [Block.Content.Dataview.Tag](#anytype-model-Block-Content-Dataview-Tag) - - [Block.Content.Dataview.View](#anytype-model-Block-Content-Dataview-View) - - [Block.Content.Dataview.ViewGroup](#anytype-model-Block-Content-Dataview-ViewGroup) - - [Block.Content.Div](#anytype-model-Block-Content-Div) - - [Block.Content.FeaturedRelations](#anytype-model-Block-Content-FeaturedRelations) - - [Block.Content.File](#anytype-model-Block-Content-File) - - [Block.Content.Icon](#anytype-model-Block-Content-Icon) - - [Block.Content.Latex](#anytype-model-Block-Content-Latex) - - [Block.Content.Layout](#anytype-model-Block-Content-Layout) - - [Block.Content.Link](#anytype-model-Block-Content-Link) - - [Block.Content.Relation](#anytype-model-Block-Content-Relation) - - [Block.Content.Smartblock](#anytype-model-Block-Content-Smartblock) - - [Block.Content.Table](#anytype-model-Block-Content-Table) - - [Block.Content.TableColumn](#anytype-model-Block-Content-TableColumn) - - [Block.Content.TableOfContents](#anytype-model-Block-Content-TableOfContents) - - [Block.Content.TableRow](#anytype-model-Block-Content-TableRow) - - [Block.Content.Text](#anytype-model-Block-Content-Text) - - [Block.Content.Text.Mark](#anytype-model-Block-Content-Text-Mark) - - [Block.Content.Text.Marks](#anytype-model-Block-Content-Text-Marks) - - [Block.Content.Widget](#anytype-model-Block-Content-Widget) - - [Block.Restrictions](#anytype-model-Block-Restrictions) - - [BlockMetaOnly](#anytype-model-BlockMetaOnly) - - [InternalFlag](#anytype-model-InternalFlag) - - [Layout](#anytype-model-Layout) - - [LinkPreview](#anytype-model-LinkPreview) - - [ObjectType](#anytype-model-ObjectType) - - [ObjectView](#anytype-model-ObjectView) - - [ObjectView.DetailsSet](#anytype-model-ObjectView-DetailsSet) - - [ObjectView.HistorySize](#anytype-model-ObjectView-HistorySize) - - [ObjectView.RelationWithValuePerObject](#anytype-model-ObjectView-RelationWithValuePerObject) - - [Range](#anytype-model-Range) - - [Relation](#anytype-model-Relation) - - [Relation.Option](#anytype-model-Relation-Option) - - [RelationLink](#anytype-model-RelationLink) - - [RelationOptions](#anytype-model-RelationOptions) - - [RelationWithValue](#anytype-model-RelationWithValue) - - [Relations](#anytype-model-Relations) - - [Restrictions](#anytype-model-Restrictions) - - [Restrictions.DataviewRestrictions](#anytype-model-Restrictions-DataviewRestrictions) - - [SmartBlockSnapshotBase](#anytype-model-SmartBlockSnapshotBase) - - [ThreadCreateQueueEntry](#anytype-model-ThreadCreateQueueEntry) - - [ThreadDeeplinkPayload](#anytype-model-ThreadDeeplinkPayload) +- [pkg/lib/pb/model/protos/models.proto](#pkg/lib/pb/model/protos/models.proto) + - [Account](#anytype.model.Account) + - [Account.Avatar](#anytype.model.Account.Avatar) + - [Account.Config](#anytype.model.Account.Config) + - [Account.Info](#anytype.model.Account.Info) + - [Account.Status](#anytype.model.Account.Status) + - [Block](#anytype.model.Block) + - [Block.Content](#anytype.model.Block.Content) + - [Block.Content.Bookmark](#anytype.model.Block.Content.Bookmark) + - [Block.Content.Dataview](#anytype.model.Block.Content.Dataview) + - [Block.Content.Dataview.Checkbox](#anytype.model.Block.Content.Dataview.Checkbox) + - [Block.Content.Dataview.Date](#anytype.model.Block.Content.Dataview.Date) + - [Block.Content.Dataview.Filter](#anytype.model.Block.Content.Dataview.Filter) + - [Block.Content.Dataview.Group](#anytype.model.Block.Content.Dataview.Group) + - [Block.Content.Dataview.GroupOrder](#anytype.model.Block.Content.Dataview.GroupOrder) + - [Block.Content.Dataview.ObjectOrder](#anytype.model.Block.Content.Dataview.ObjectOrder) + - [Block.Content.Dataview.Relation](#anytype.model.Block.Content.Dataview.Relation) + - [Block.Content.Dataview.Sort](#anytype.model.Block.Content.Dataview.Sort) + - [Block.Content.Dataview.Status](#anytype.model.Block.Content.Dataview.Status) + - [Block.Content.Dataview.Tag](#anytype.model.Block.Content.Dataview.Tag) + - [Block.Content.Dataview.View](#anytype.model.Block.Content.Dataview.View) + - [Block.Content.Dataview.ViewGroup](#anytype.model.Block.Content.Dataview.ViewGroup) + - [Block.Content.Div](#anytype.model.Block.Content.Div) + - [Block.Content.FeaturedRelations](#anytype.model.Block.Content.FeaturedRelations) + - [Block.Content.File](#anytype.model.Block.Content.File) + - [Block.Content.Icon](#anytype.model.Block.Content.Icon) + - [Block.Content.Latex](#anytype.model.Block.Content.Latex) + - [Block.Content.Layout](#anytype.model.Block.Content.Layout) + - [Block.Content.Link](#anytype.model.Block.Content.Link) + - [Block.Content.Relation](#anytype.model.Block.Content.Relation) + - [Block.Content.Smartblock](#anytype.model.Block.Content.Smartblock) + - [Block.Content.Table](#anytype.model.Block.Content.Table) + - [Block.Content.TableColumn](#anytype.model.Block.Content.TableColumn) + - [Block.Content.TableOfContents](#anytype.model.Block.Content.TableOfContents) + - [Block.Content.TableRow](#anytype.model.Block.Content.TableRow) + - [Block.Content.Text](#anytype.model.Block.Content.Text) + - [Block.Content.Text.Mark](#anytype.model.Block.Content.Text.Mark) + - [Block.Content.Text.Marks](#anytype.model.Block.Content.Text.Marks) + - [Block.Content.Widget](#anytype.model.Block.Content.Widget) + - [Block.Restrictions](#anytype.model.Block.Restrictions) + - [BlockMetaOnly](#anytype.model.BlockMetaOnly) + - [InternalFlag](#anytype.model.InternalFlag) + - [Layout](#anytype.model.Layout) + - [LinkPreview](#anytype.model.LinkPreview) + - [ObjectType](#anytype.model.ObjectType) + - [ObjectView](#anytype.model.ObjectView) + - [ObjectView.DetailsSet](#anytype.model.ObjectView.DetailsSet) + - [ObjectView.HistorySize](#anytype.model.ObjectView.HistorySize) + - [ObjectView.RelationWithValuePerObject](#anytype.model.ObjectView.RelationWithValuePerObject) + - [Range](#anytype.model.Range) + - [Relation](#anytype.model.Relation) + - [Relation.Option](#anytype.model.Relation.Option) + - [RelationLink](#anytype.model.RelationLink) + - [RelationOptions](#anytype.model.RelationOptions) + - [RelationWithValue](#anytype.model.RelationWithValue) + - [Relations](#anytype.model.Relations) + - [Restrictions](#anytype.model.Restrictions) + - [Restrictions.DataviewRestrictions](#anytype.model.Restrictions.DataviewRestrictions) + - [SmartBlockSnapshotBase](#anytype.model.SmartBlockSnapshotBase) + - [ThreadCreateQueueEntry](#anytype.model.ThreadCreateQueueEntry) + - [ThreadDeeplinkPayload](#anytype.model.ThreadDeeplinkPayload) - - [Account.StatusType](#anytype-model-Account-StatusType) - - [Block.Align](#anytype-model-Block-Align) - - [Block.Content.Bookmark.State](#anytype-model-Block-Content-Bookmark-State) - - [Block.Content.Dataview.Filter.Condition](#anytype-model-Block-Content-Dataview-Filter-Condition) - - [Block.Content.Dataview.Filter.Operator](#anytype-model-Block-Content-Dataview-Filter-Operator) - - [Block.Content.Dataview.Filter.QuickOption](#anytype-model-Block-Content-Dataview-Filter-QuickOption) - - [Block.Content.Dataview.Relation.DateFormat](#anytype-model-Block-Content-Dataview-Relation-DateFormat) - - [Block.Content.Dataview.Relation.TimeFormat](#anytype-model-Block-Content-Dataview-Relation-TimeFormat) - - [Block.Content.Dataview.Sort.Type](#anytype-model-Block-Content-Dataview-Sort-Type) - - [Block.Content.Dataview.View.Size](#anytype-model-Block-Content-Dataview-View-Size) - - [Block.Content.Dataview.View.Type](#anytype-model-Block-Content-Dataview-View-Type) - - [Block.Content.Div.Style](#anytype-model-Block-Content-Div-Style) - - [Block.Content.File.State](#anytype-model-Block-Content-File-State) - - [Block.Content.File.Style](#anytype-model-Block-Content-File-Style) - - [Block.Content.File.Type](#anytype-model-Block-Content-File-Type) - - [Block.Content.Layout.Style](#anytype-model-Block-Content-Layout-Style) - - [Block.Content.Link.CardStyle](#anytype-model-Block-Content-Link-CardStyle) - - [Block.Content.Link.Description](#anytype-model-Block-Content-Link-Description) - - [Block.Content.Link.IconSize](#anytype-model-Block-Content-Link-IconSize) - - [Block.Content.Link.Style](#anytype-model-Block-Content-Link-Style) - - [Block.Content.Text.Mark.Type](#anytype-model-Block-Content-Text-Mark-Type) - - [Block.Content.Text.Style](#anytype-model-Block-Content-Text-Style) - - [Block.Content.Widget.Layout](#anytype-model-Block-Content-Widget-Layout) - - [Block.Position](#anytype-model-Block-Position) - - [Block.VerticalAlign](#anytype-model-Block-VerticalAlign) - - [InternalFlag.Value](#anytype-model-InternalFlag-Value) - - [LinkPreview.Type](#anytype-model-LinkPreview-Type) - - [ObjectType.Layout](#anytype-model-ObjectType-Layout) - - [Relation.DataSource](#anytype-model-Relation-DataSource) - - [Relation.Scope](#anytype-model-Relation-Scope) - - [RelationFormat](#anytype-model-RelationFormat) - - [Restrictions.DataviewRestriction](#anytype-model-Restrictions-DataviewRestriction) - - [Restrictions.ObjectRestriction](#anytype-model-Restrictions-ObjectRestriction) - - [SmartBlockType](#anytype-model-SmartBlockType) + - [Account.StatusType](#anytype.model.Account.StatusType) + - [Block.Align](#anytype.model.Block.Align) + - [Block.Content.Bookmark.State](#anytype.model.Block.Content.Bookmark.State) + - [Block.Content.Dataview.Filter.Condition](#anytype.model.Block.Content.Dataview.Filter.Condition) + - [Block.Content.Dataview.Filter.Operator](#anytype.model.Block.Content.Dataview.Filter.Operator) + - [Block.Content.Dataview.Filter.QuickOption](#anytype.model.Block.Content.Dataview.Filter.QuickOption) + - [Block.Content.Dataview.Relation.DateFormat](#anytype.model.Block.Content.Dataview.Relation.DateFormat) + - [Block.Content.Dataview.Relation.TimeFormat](#anytype.model.Block.Content.Dataview.Relation.TimeFormat) + - [Block.Content.Dataview.Sort.Type](#anytype.model.Block.Content.Dataview.Sort.Type) + - [Block.Content.Dataview.View.Size](#anytype.model.Block.Content.Dataview.View.Size) + - [Block.Content.Dataview.View.Type](#anytype.model.Block.Content.Dataview.View.Type) + - [Block.Content.Div.Style](#anytype.model.Block.Content.Div.Style) + - [Block.Content.File.State](#anytype.model.Block.Content.File.State) + - [Block.Content.File.Style](#anytype.model.Block.Content.File.Style) + - [Block.Content.File.Type](#anytype.model.Block.Content.File.Type) + - [Block.Content.Layout.Style](#anytype.model.Block.Content.Layout.Style) + - [Block.Content.Link.CardStyle](#anytype.model.Block.Content.Link.CardStyle) + - [Block.Content.Link.Description](#anytype.model.Block.Content.Link.Description) + - [Block.Content.Link.IconSize](#anytype.model.Block.Content.Link.IconSize) + - [Block.Content.Link.Style](#anytype.model.Block.Content.Link.Style) + - [Block.Content.Text.Mark.Type](#anytype.model.Block.Content.Text.Mark.Type) + - [Block.Content.Text.Style](#anytype.model.Block.Content.Text.Style) + - [Block.Content.Widget.Layout](#anytype.model.Block.Content.Widget.Layout) + - [Block.Position](#anytype.model.Block.Position) + - [Block.VerticalAlign](#anytype.model.Block.VerticalAlign) + - [InternalFlag.Value](#anytype.model.InternalFlag.Value) + - [LinkPreview.Type](#anytype.model.LinkPreview.Type) + - [ObjectType.Layout](#anytype.model.ObjectType.Layout) + - [Relation.DataSource](#anytype.model.Relation.DataSource) + - [Relation.Scope](#anytype.model.Relation.Scope) + - [RelationFormat](#anytype.model.RelationFormat) + - [Restrictions.DataviewRestriction](#anytype.model.Restrictions.DataviewRestriction) + - [Restrictions.ObjectRestriction](#anytype.model.Restrictions.ObjectRestriction) + - [SmartBlockType](#anytype.model.SmartBlockType) - [Scalar Value Types](#scalar-value-types) - +

Top

## pb/protos/service/service.proto @@ -1257,195 +1257,195 @@ - + ### ClientCommands | Method Name | Request Type | Response Type | Description | | ----------- | ------------ | ------------- | ------------| -| AppGetVersion | [Rpc.App.GetVersion.Request](#anytype-Rpc-App-GetVersion-Request) | [Rpc.App.GetVersion.Response](#anytype-Rpc-App-GetVersion-Response) | | -| AppSetDeviceState | [Rpc.App.SetDeviceState.Request](#anytype-Rpc-App-SetDeviceState-Request) | [Rpc.App.SetDeviceState.Response](#anytype-Rpc-App-SetDeviceState-Response) | | -| AppShutdown | [Rpc.App.Shutdown.Request](#anytype-Rpc-App-Shutdown-Request) | [Rpc.App.Shutdown.Response](#anytype-Rpc-App-Shutdown-Response) | | -| WalletCreate | [Rpc.Wallet.Create.Request](#anytype-Rpc-Wallet-Create-Request) | [Rpc.Wallet.Create.Response](#anytype-Rpc-Wallet-Create-Response) | Wallet *** | -| WalletRecover | [Rpc.Wallet.Recover.Request](#anytype-Rpc-Wallet-Recover-Request) | [Rpc.Wallet.Recover.Response](#anytype-Rpc-Wallet-Recover-Response) | | -| WalletConvert | [Rpc.Wallet.Convert.Request](#anytype-Rpc-Wallet-Convert-Request) | [Rpc.Wallet.Convert.Response](#anytype-Rpc-Wallet-Convert-Response) | | -| WalletCreateSession | [Rpc.Wallet.CreateSession.Request](#anytype-Rpc-Wallet-CreateSession-Request) | [Rpc.Wallet.CreateSession.Response](#anytype-Rpc-Wallet-CreateSession-Response) | | -| WalletCloseSession | [Rpc.Wallet.CloseSession.Request](#anytype-Rpc-Wallet-CloseSession-Request) | [Rpc.Wallet.CloseSession.Response](#anytype-Rpc-Wallet-CloseSession-Response) | | -| WorkspaceCreate | [Rpc.Workspace.Create.Request](#anytype-Rpc-Workspace-Create-Request) | [Rpc.Workspace.Create.Response](#anytype-Rpc-Workspace-Create-Response) | Workspace *** | -| WorkspaceObjectAdd | [Rpc.Workspace.Object.Add.Request](#anytype-Rpc-Workspace-Object-Add-Request) | [Rpc.Workspace.Object.Add.Response](#anytype-Rpc-Workspace-Object-Add-Response) | | -| WorkspaceObjectListAdd | [Rpc.Workspace.Object.ListAdd.Request](#anytype-Rpc-Workspace-Object-ListAdd-Request) | [Rpc.Workspace.Object.ListAdd.Response](#anytype-Rpc-Workspace-Object-ListAdd-Response) | | -| WorkspaceObjectListRemove | [Rpc.Workspace.Object.ListRemove.Request](#anytype-Rpc-Workspace-Object-ListRemove-Request) | [Rpc.Workspace.Object.ListRemove.Response](#anytype-Rpc-Workspace-Object-ListRemove-Response) | | -| WorkspaceSelect | [Rpc.Workspace.Select.Request](#anytype-Rpc-Workspace-Select-Request) | [Rpc.Workspace.Select.Response](#anytype-Rpc-Workspace-Select-Response) | | -| WorkspaceGetCurrent | [Rpc.Workspace.GetCurrent.Request](#anytype-Rpc-Workspace-GetCurrent-Request) | [Rpc.Workspace.GetCurrent.Response](#anytype-Rpc-Workspace-GetCurrent-Response) | | -| WorkspaceGetAll | [Rpc.Workspace.GetAll.Request](#anytype-Rpc-Workspace-GetAll-Request) | [Rpc.Workspace.GetAll.Response](#anytype-Rpc-Workspace-GetAll-Response) | | -| WorkspaceSetIsHighlighted | [Rpc.Workspace.SetIsHighlighted.Request](#anytype-Rpc-Workspace-SetIsHighlighted-Request) | [Rpc.Workspace.SetIsHighlighted.Response](#anytype-Rpc-Workspace-SetIsHighlighted-Response) | | -| WorkspaceExport | [Rpc.Workspace.Export.Request](#anytype-Rpc-Workspace-Export-Request) | [Rpc.Workspace.Export.Response](#anytype-Rpc-Workspace-Export-Response) | | -| AccountRecover | [Rpc.Account.Recover.Request](#anytype-Rpc-Account-Recover-Request) | [Rpc.Account.Recover.Response](#anytype-Rpc-Account-Recover-Response) | Account *** | -| AccountCreate | [Rpc.Account.Create.Request](#anytype-Rpc-Account-Create-Request) | [Rpc.Account.Create.Response](#anytype-Rpc-Account-Create-Response) | | -| AccountDelete | [Rpc.Account.Delete.Request](#anytype-Rpc-Account-Delete-Request) | [Rpc.Account.Delete.Response](#anytype-Rpc-Account-Delete-Response) | | -| AccountSelect | [Rpc.Account.Select.Request](#anytype-Rpc-Account-Select-Request) | [Rpc.Account.Select.Response](#anytype-Rpc-Account-Select-Response) | | -| AccountStop | [Rpc.Account.Stop.Request](#anytype-Rpc-Account-Stop-Request) | [Rpc.Account.Stop.Response](#anytype-Rpc-Account-Stop-Response) | | -| AccountMove | [Rpc.Account.Move.Request](#anytype-Rpc-Account-Move-Request) | [Rpc.Account.Move.Response](#anytype-Rpc-Account-Move-Response) | | -| AccountConfigUpdate | [Rpc.Account.ConfigUpdate.Request](#anytype-Rpc-Account-ConfigUpdate-Request) | [Rpc.Account.ConfigUpdate.Response](#anytype-Rpc-Account-ConfigUpdate-Response) | | -| ObjectOpen | [Rpc.Object.Open.Request](#anytype-Rpc-Object-Open-Request) | [Rpc.Object.Open.Response](#anytype-Rpc-Object-Open-Response) | Object *** | -| ObjectClose | [Rpc.Object.Close.Request](#anytype-Rpc-Object-Close-Request) | [Rpc.Object.Close.Response](#anytype-Rpc-Object-Close-Response) | | -| ObjectShow | [Rpc.Object.Show.Request](#anytype-Rpc-Object-Show-Request) | [Rpc.Object.Show.Response](#anytype-Rpc-Object-Show-Response) | | -| ObjectCreate | [Rpc.Object.Create.Request](#anytype-Rpc-Object-Create-Request) | [Rpc.Object.Create.Response](#anytype-Rpc-Object-Create-Response) | ObjectCreate just creates the new page, without adding the link to it from some other page | -| ObjectCreateBookmark | [Rpc.Object.CreateBookmark.Request](#anytype-Rpc-Object-CreateBookmark-Request) | [Rpc.Object.CreateBookmark.Response](#anytype-Rpc-Object-CreateBookmark-Response) | | -| ObjectCreateSet | [Rpc.Object.CreateSet.Request](#anytype-Rpc-Object-CreateSet-Request) | [Rpc.Object.CreateSet.Response](#anytype-Rpc-Object-CreateSet-Response) | ObjectCreateSet just creates the new set, without adding the link to it from some other page | -| ObjectGraph | [Rpc.Object.Graph.Request](#anytype-Rpc-Object-Graph-Request) | [Rpc.Object.Graph.Response](#anytype-Rpc-Object-Graph-Response) | | -| ObjectSearch | [Rpc.Object.Search.Request](#anytype-Rpc-Object-Search-Request) | [Rpc.Object.Search.Response](#anytype-Rpc-Object-Search-Response) | | -| ObjectSearchSubscribe | [Rpc.Object.SearchSubscribe.Request](#anytype-Rpc-Object-SearchSubscribe-Request) | [Rpc.Object.SearchSubscribe.Response](#anytype-Rpc-Object-SearchSubscribe-Response) | | -| ObjectSubscribeIds | [Rpc.Object.SubscribeIds.Request](#anytype-Rpc-Object-SubscribeIds-Request) | [Rpc.Object.SubscribeIds.Response](#anytype-Rpc-Object-SubscribeIds-Response) | | -| ObjectGroupsSubscribe | [Rpc.Object.GroupsSubscribe.Request](#anytype-Rpc-Object-GroupsSubscribe-Request) | [Rpc.Object.GroupsSubscribe.Response](#anytype-Rpc-Object-GroupsSubscribe-Response) | | -| ObjectSearchUnsubscribe | [Rpc.Object.SearchUnsubscribe.Request](#anytype-Rpc-Object-SearchUnsubscribe-Request) | [Rpc.Object.SearchUnsubscribe.Response](#anytype-Rpc-Object-SearchUnsubscribe-Response) | | -| ObjectSetDetails | [Rpc.Object.SetDetails.Request](#anytype-Rpc-Object-SetDetails-Request) | [Rpc.Object.SetDetails.Response](#anytype-Rpc-Object-SetDetails-Response) | | -| ObjectDuplicate | [Rpc.Object.Duplicate.Request](#anytype-Rpc-Object-Duplicate-Request) | [Rpc.Object.Duplicate.Response](#anytype-Rpc-Object-Duplicate-Response) | | -| ObjectSetObjectType | [Rpc.Object.SetObjectType.Request](#anytype-Rpc-Object-SetObjectType-Request) | [Rpc.Object.SetObjectType.Response](#anytype-Rpc-Object-SetObjectType-Response) | ObjectSetObjectType sets an existing object type to the object so it will appear in sets and suggests relations from this type | -| ObjectSetLayout | [Rpc.Object.SetLayout.Request](#anytype-Rpc-Object-SetLayout-Request) | [Rpc.Object.SetLayout.Response](#anytype-Rpc-Object-SetLayout-Response) | | -| ObjectSetInternalFlags | [Rpc.Object.SetInternalFlags.Request](#anytype-Rpc-Object-SetInternalFlags-Request) | [Rpc.Object.SetInternalFlags.Response](#anytype-Rpc-Object-SetInternalFlags-Response) | | -| ObjectSetIsFavorite | [Rpc.Object.SetIsFavorite.Request](#anytype-Rpc-Object-SetIsFavorite-Request) | [Rpc.Object.SetIsFavorite.Response](#anytype-Rpc-Object-SetIsFavorite-Response) | | -| ObjectSetIsArchived | [Rpc.Object.SetIsArchived.Request](#anytype-Rpc-Object-SetIsArchived-Request) | [Rpc.Object.SetIsArchived.Response](#anytype-Rpc-Object-SetIsArchived-Response) | | -| ObjectListDuplicate | [Rpc.Object.ListDuplicate.Request](#anytype-Rpc-Object-ListDuplicate-Request) | [Rpc.Object.ListDuplicate.Response](#anytype-Rpc-Object-ListDuplicate-Response) | | -| ObjectListDelete | [Rpc.Object.ListDelete.Request](#anytype-Rpc-Object-ListDelete-Request) | [Rpc.Object.ListDelete.Response](#anytype-Rpc-Object-ListDelete-Response) | | -| ObjectListSetIsArchived | [Rpc.Object.ListSetIsArchived.Request](#anytype-Rpc-Object-ListSetIsArchived-Request) | [Rpc.Object.ListSetIsArchived.Response](#anytype-Rpc-Object-ListSetIsArchived-Response) | | -| ObjectListSetIsFavorite | [Rpc.Object.ListSetIsFavorite.Request](#anytype-Rpc-Object-ListSetIsFavorite-Request) | [Rpc.Object.ListSetIsFavorite.Response](#anytype-Rpc-Object-ListSetIsFavorite-Response) | | -| ObjectApplyTemplate | [Rpc.Object.ApplyTemplate.Request](#anytype-Rpc-Object-ApplyTemplate-Request) | [Rpc.Object.ApplyTemplate.Response](#anytype-Rpc-Object-ApplyTemplate-Response) | | -| ObjectToSet | [Rpc.Object.ToSet.Request](#anytype-Rpc-Object-ToSet-Request) | [Rpc.Object.ToSet.Response](#anytype-Rpc-Object-ToSet-Response) | ObjectToSet creates new set from given object and removes object | -| ObjectAddWithObjectId | [Rpc.Object.AddWithObjectId.Request](#anytype-Rpc-Object-AddWithObjectId-Request) | [Rpc.Object.AddWithObjectId.Response](#anytype-Rpc-Object-AddWithObjectId-Response) | | -| ObjectShareByLink | [Rpc.Object.ShareByLink.Request](#anytype-Rpc-Object-ShareByLink-Request) | [Rpc.Object.ShareByLink.Response](#anytype-Rpc-Object-ShareByLink-Response) | | -| ObjectOpenBreadcrumbs | [Rpc.Object.OpenBreadcrumbs.Request](#anytype-Rpc-Object-OpenBreadcrumbs-Request) | [Rpc.Object.OpenBreadcrumbs.Response](#anytype-Rpc-Object-OpenBreadcrumbs-Response) | | -| ObjectSetBreadcrumbs | [Rpc.Object.SetBreadcrumbs.Request](#anytype-Rpc-Object-SetBreadcrumbs-Request) | [Rpc.Object.SetBreadcrumbs.Response](#anytype-Rpc-Object-SetBreadcrumbs-Response) | | -| ObjectUndo | [Rpc.Object.Undo.Request](#anytype-Rpc-Object-Undo-Request) | [Rpc.Object.Undo.Response](#anytype-Rpc-Object-Undo-Response) | | -| ObjectRedo | [Rpc.Object.Redo.Request](#anytype-Rpc-Object-Redo-Request) | [Rpc.Object.Redo.Response](#anytype-Rpc-Object-Redo-Response) | | -| ObjectImportMarkdown | [Rpc.Object.ImportMarkdown.Request](#anytype-Rpc-Object-ImportMarkdown-Request) | [Rpc.Object.ImportMarkdown.Response](#anytype-Rpc-Object-ImportMarkdown-Response) | | -| ObjectListExport | [Rpc.Object.ListExport.Request](#anytype-Rpc-Object-ListExport-Request) | [Rpc.Object.ListExport.Response](#anytype-Rpc-Object-ListExport-Response) | | -| ObjectBookmarkFetch | [Rpc.Object.BookmarkFetch.Request](#anytype-Rpc-Object-BookmarkFetch-Request) | [Rpc.Object.BookmarkFetch.Response](#anytype-Rpc-Object-BookmarkFetch-Response) | | -| ObjectToBookmark | [Rpc.Object.ToBookmark.Request](#anytype-Rpc-Object-ToBookmark-Request) | [Rpc.Object.ToBookmark.Response](#anytype-Rpc-Object-ToBookmark-Response) | | -| ObjectImport | [Rpc.Object.Import.Request](#anytype-Rpc-Object-Import-Request) | [Rpc.Object.Import.Response](#anytype-Rpc-Object-Import-Response) | | -| ObjectImportList | [Rpc.Object.ImportList.Request](#anytype-Rpc-Object-ImportList-Request) | [Rpc.Object.ImportList.Response](#anytype-Rpc-Object-ImportList-Response) | | -| ObjectCreateRelation | [Rpc.Object.CreateRelation.Request](#anytype-Rpc-Object-CreateRelation-Request) | [Rpc.Object.CreateRelation.Response](#anytype-Rpc-Object-CreateRelation-Response) | Relations *** | -| ObjectCreateRelationOption | [Rpc.Object.CreateRelationOption.Request](#anytype-Rpc-Object-CreateRelationOption-Request) | [Rpc.Object.CreateRelationOption.Response](#anytype-Rpc-Object-CreateRelationOption-Response) | | -| RelationListRemoveOption | [Rpc.Relation.ListRemoveOption.Request](#anytype-Rpc-Relation-ListRemoveOption-Request) | [Rpc.Relation.ListRemoveOption.Response](#anytype-Rpc-Relation-ListRemoveOption-Response) | | -| RelationOptions | [Rpc.Relation.Options.Request](#anytype-Rpc-Relation-Options-Request) | [Rpc.Relation.Options.Response](#anytype-Rpc-Relation-Options-Response) | | -| ObjectRelationAdd | [Rpc.ObjectRelation.Add.Request](#anytype-Rpc-ObjectRelation-Add-Request) | [Rpc.ObjectRelation.Add.Response](#anytype-Rpc-ObjectRelation-Add-Response) | Object Relations *** | -| ObjectRelationDelete | [Rpc.ObjectRelation.Delete.Request](#anytype-Rpc-ObjectRelation-Delete-Request) | [Rpc.ObjectRelation.Delete.Response](#anytype-Rpc-ObjectRelation-Delete-Response) | | -| ObjectRelationAddFeatured | [Rpc.ObjectRelation.AddFeatured.Request](#anytype-Rpc-ObjectRelation-AddFeatured-Request) | [Rpc.ObjectRelation.AddFeatured.Response](#anytype-Rpc-ObjectRelation-AddFeatured-Response) | | -| ObjectRelationRemoveFeatured | [Rpc.ObjectRelation.RemoveFeatured.Request](#anytype-Rpc-ObjectRelation-RemoveFeatured-Request) | [Rpc.ObjectRelation.RemoveFeatured.Response](#anytype-Rpc-ObjectRelation-RemoveFeatured-Response) | | -| ObjectRelationListAvailable | [Rpc.ObjectRelation.ListAvailable.Request](#anytype-Rpc-ObjectRelation-ListAvailable-Request) | [Rpc.ObjectRelation.ListAvailable.Response](#anytype-Rpc-ObjectRelation-ListAvailable-Response) | | -| ObjectCreateObjectType | [Rpc.Object.CreateObjectType.Request](#anytype-Rpc-Object-CreateObjectType-Request) | [Rpc.Object.CreateObjectType.Response](#anytype-Rpc-Object-CreateObjectType-Response) | ObjectType commands *** | -| ObjectTypeRelationList | [Rpc.ObjectType.Relation.List.Request](#anytype-Rpc-ObjectType-Relation-List-Request) | [Rpc.ObjectType.Relation.List.Response](#anytype-Rpc-ObjectType-Relation-List-Response) | | -| ObjectTypeRelationAdd | [Rpc.ObjectType.Relation.Add.Request](#anytype-Rpc-ObjectType-Relation-Add-Request) | [Rpc.ObjectType.Relation.Add.Response](#anytype-Rpc-ObjectType-Relation-Add-Response) | | -| ObjectTypeRelationRemove | [Rpc.ObjectType.Relation.Remove.Request](#anytype-Rpc-ObjectType-Relation-Remove-Request) | [Rpc.ObjectType.Relation.Remove.Response](#anytype-Rpc-ObjectType-Relation-Remove-Response) | | -| HistoryShowVersion | [Rpc.History.ShowVersion.Request](#anytype-Rpc-History-ShowVersion-Request) | [Rpc.History.ShowVersion.Response](#anytype-Rpc-History-ShowVersion-Response) | | -| HistoryGetVersions | [Rpc.History.GetVersions.Request](#anytype-Rpc-History-GetVersions-Request) | [Rpc.History.GetVersions.Response](#anytype-Rpc-History-GetVersions-Response) | | -| HistorySetVersion | [Rpc.History.SetVersion.Request](#anytype-Rpc-History-SetVersion-Request) | [Rpc.History.SetVersion.Response](#anytype-Rpc-History-SetVersion-Response) | | -| FileOffload | [Rpc.File.Offload.Request](#anytype-Rpc-File-Offload-Request) | [Rpc.File.Offload.Response](#anytype-Rpc-File-Offload-Response) | Files *** | -| FileListOffload | [Rpc.File.ListOffload.Request](#anytype-Rpc-File-ListOffload-Request) | [Rpc.File.ListOffload.Response](#anytype-Rpc-File-ListOffload-Response) | | -| FileUpload | [Rpc.File.Upload.Request](#anytype-Rpc-File-Upload-Request) | [Rpc.File.Upload.Response](#anytype-Rpc-File-Upload-Response) | | -| FileDownload | [Rpc.File.Download.Request](#anytype-Rpc-File-Download-Request) | [Rpc.File.Download.Response](#anytype-Rpc-File-Download-Response) | | -| FileDrop | [Rpc.File.Drop.Request](#anytype-Rpc-File-Drop-Request) | [Rpc.File.Drop.Response](#anytype-Rpc-File-Drop-Response) | | -| NavigationListObjects | [Rpc.Navigation.ListObjects.Request](#anytype-Rpc-Navigation-ListObjects-Request) | [Rpc.Navigation.ListObjects.Response](#anytype-Rpc-Navigation-ListObjects-Response) | | -| NavigationGetObjectInfoWithLinks | [Rpc.Navigation.GetObjectInfoWithLinks.Request](#anytype-Rpc-Navigation-GetObjectInfoWithLinks-Request) | [Rpc.Navigation.GetObjectInfoWithLinks.Response](#anytype-Rpc-Navigation-GetObjectInfoWithLinks-Response) | | -| TemplateCreateFromObject | [Rpc.Template.CreateFromObject.Request](#anytype-Rpc-Template-CreateFromObject-Request) | [Rpc.Template.CreateFromObject.Response](#anytype-Rpc-Template-CreateFromObject-Response) | | -| TemplateCreateFromObjectType | [Rpc.Template.CreateFromObjectType.Request](#anytype-Rpc-Template-CreateFromObjectType-Request) | [Rpc.Template.CreateFromObjectType.Response](#anytype-Rpc-Template-CreateFromObjectType-Response) | to be renamed to ObjectCreateTemplate | -| TemplateClone | [Rpc.Template.Clone.Request](#anytype-Rpc-Template-Clone-Request) | [Rpc.Template.Clone.Response](#anytype-Rpc-Template-Clone-Response) | | -| TemplateExportAll | [Rpc.Template.ExportAll.Request](#anytype-Rpc-Template-ExportAll-Request) | [Rpc.Template.ExportAll.Response](#anytype-Rpc-Template-ExportAll-Response) | | -| LinkPreview | [Rpc.LinkPreview.Request](#anytype-Rpc-LinkPreview-Request) | [Rpc.LinkPreview.Response](#anytype-Rpc-LinkPreview-Response) | | -| UnsplashSearch | [Rpc.Unsplash.Search.Request](#anytype-Rpc-Unsplash-Search-Request) | [Rpc.Unsplash.Search.Response](#anytype-Rpc-Unsplash-Search-Response) | | -| UnsplashDownload | [Rpc.Unsplash.Download.Request](#anytype-Rpc-Unsplash-Download-Request) | [Rpc.Unsplash.Download.Response](#anytype-Rpc-Unsplash-Download-Response) | UnsplashDownload downloads picture from unsplash by ID, put it to the IPFS and returns the hash. The artist info is available in the object details | -| BlockUpload | [Rpc.Block.Upload.Request](#anytype-Rpc-Block-Upload-Request) | [Rpc.Block.Upload.Response](#anytype-Rpc-Block-Upload-Response) | General Block commands *** | -| BlockReplace | [Rpc.Block.Replace.Request](#anytype-Rpc-Block-Replace-Request) | [Rpc.Block.Replace.Response](#anytype-Rpc-Block-Replace-Response) | | -| BlockCreate | [Rpc.Block.Create.Request](#anytype-Rpc-Block-Create-Request) | [Rpc.Block.Create.Response](#anytype-Rpc-Block-Create-Response) | | -| BlockSplit | [Rpc.Block.Split.Request](#anytype-Rpc-Block-Split-Request) | [Rpc.Block.Split.Response](#anytype-Rpc-Block-Split-Response) | | -| BlockMerge | [Rpc.Block.Merge.Request](#anytype-Rpc-Block-Merge-Request) | [Rpc.Block.Merge.Response](#anytype-Rpc-Block-Merge-Response) | | -| BlockCopy | [Rpc.Block.Copy.Request](#anytype-Rpc-Block-Copy-Request) | [Rpc.Block.Copy.Response](#anytype-Rpc-Block-Copy-Response) | | -| BlockPaste | [Rpc.Block.Paste.Request](#anytype-Rpc-Block-Paste-Request) | [Rpc.Block.Paste.Response](#anytype-Rpc-Block-Paste-Response) | | -| BlockCut | [Rpc.Block.Cut.Request](#anytype-Rpc-Block-Cut-Request) | [Rpc.Block.Cut.Response](#anytype-Rpc-Block-Cut-Response) | | -| BlockSetFields | [Rpc.Block.SetFields.Request](#anytype-Rpc-Block-SetFields-Request) | [Rpc.Block.SetFields.Response](#anytype-Rpc-Block-SetFields-Response) | | -| BlockExport | [Rpc.Block.Export.Request](#anytype-Rpc-Block-Export-Request) | [Rpc.Block.Export.Response](#anytype-Rpc-Block-Export-Response) | | -| BlockListDelete | [Rpc.Block.ListDelete.Request](#anytype-Rpc-Block-ListDelete-Request) | [Rpc.Block.ListDelete.Response](#anytype-Rpc-Block-ListDelete-Response) | | -| BlockListMoveToExistingObject | [Rpc.Block.ListMoveToExistingObject.Request](#anytype-Rpc-Block-ListMoveToExistingObject-Request) | [Rpc.Block.ListMoveToExistingObject.Response](#anytype-Rpc-Block-ListMoveToExistingObject-Response) | | -| BlockListMoveToNewObject | [Rpc.Block.ListMoveToNewObject.Request](#anytype-Rpc-Block-ListMoveToNewObject-Request) | [Rpc.Block.ListMoveToNewObject.Response](#anytype-Rpc-Block-ListMoveToNewObject-Response) | | -| BlockListConvertToObjects | [Rpc.Block.ListConvertToObjects.Request](#anytype-Rpc-Block-ListConvertToObjects-Request) | [Rpc.Block.ListConvertToObjects.Response](#anytype-Rpc-Block-ListConvertToObjects-Response) | | -| BlockListSetFields | [Rpc.Block.ListSetFields.Request](#anytype-Rpc-Block-ListSetFields-Request) | [Rpc.Block.ListSetFields.Response](#anytype-Rpc-Block-ListSetFields-Response) | | -| BlockListDuplicate | [Rpc.Block.ListDuplicate.Request](#anytype-Rpc-Block-ListDuplicate-Request) | [Rpc.Block.ListDuplicate.Response](#anytype-Rpc-Block-ListDuplicate-Response) | | -| BlockListSetBackgroundColor | [Rpc.Block.ListSetBackgroundColor.Request](#anytype-Rpc-Block-ListSetBackgroundColor-Request) | [Rpc.Block.ListSetBackgroundColor.Response](#anytype-Rpc-Block-ListSetBackgroundColor-Response) | | -| BlockListSetAlign | [Rpc.Block.ListSetAlign.Request](#anytype-Rpc-Block-ListSetAlign-Request) | [Rpc.Block.ListSetAlign.Response](#anytype-Rpc-Block-ListSetAlign-Response) | | -| BlockListSetVerticalAlign | [Rpc.Block.ListSetVerticalAlign.Request](#anytype-Rpc-Block-ListSetVerticalAlign-Request) | [Rpc.Block.ListSetVerticalAlign.Response](#anytype-Rpc-Block-ListSetVerticalAlign-Response) | | -| BlockListTurnInto | [Rpc.Block.ListTurnInto.Request](#anytype-Rpc-Block-ListTurnInto-Request) | [Rpc.Block.ListTurnInto.Response](#anytype-Rpc-Block-ListTurnInto-Response) | | -| BlockTextSetText | [Rpc.BlockText.SetText.Request](#anytype-Rpc-BlockText-SetText-Request) | [Rpc.BlockText.SetText.Response](#anytype-Rpc-BlockText-SetText-Response) | Text Block commands *** | -| BlockTextSetColor | [Rpc.BlockText.SetColor.Request](#anytype-Rpc-BlockText-SetColor-Request) | [Rpc.BlockText.SetColor.Response](#anytype-Rpc-BlockText-SetColor-Response) | | -| BlockTextSetStyle | [Rpc.BlockText.SetStyle.Request](#anytype-Rpc-BlockText-SetStyle-Request) | [Rpc.BlockText.SetStyle.Response](#anytype-Rpc-BlockText-SetStyle-Response) | | -| BlockTextSetChecked | [Rpc.BlockText.SetChecked.Request](#anytype-Rpc-BlockText-SetChecked-Request) | [Rpc.BlockText.SetChecked.Response](#anytype-Rpc-BlockText-SetChecked-Response) | | -| BlockTextSetIcon | [Rpc.BlockText.SetIcon.Request](#anytype-Rpc-BlockText-SetIcon-Request) | [Rpc.BlockText.SetIcon.Response](#anytype-Rpc-BlockText-SetIcon-Response) | | -| BlockTextListSetColor | [Rpc.BlockText.ListSetColor.Request](#anytype-Rpc-BlockText-ListSetColor-Request) | [Rpc.BlockText.ListSetColor.Response](#anytype-Rpc-BlockText-ListSetColor-Response) | | -| BlockTextListSetMark | [Rpc.BlockText.ListSetMark.Request](#anytype-Rpc-BlockText-ListSetMark-Request) | [Rpc.BlockText.ListSetMark.Response](#anytype-Rpc-BlockText-ListSetMark-Response) | | -| BlockTextListSetStyle | [Rpc.BlockText.ListSetStyle.Request](#anytype-Rpc-BlockText-ListSetStyle-Request) | [Rpc.BlockText.ListSetStyle.Response](#anytype-Rpc-BlockText-ListSetStyle-Response) | | -| BlockTextListClearStyle | [Rpc.BlockText.ListClearStyle.Request](#anytype-Rpc-BlockText-ListClearStyle-Request) | [Rpc.BlockText.ListClearStyle.Response](#anytype-Rpc-BlockText-ListClearStyle-Response) | | -| BlockTextListClearContent | [Rpc.BlockText.ListClearContent.Request](#anytype-Rpc-BlockText-ListClearContent-Request) | [Rpc.BlockText.ListClearContent.Response](#anytype-Rpc-BlockText-ListClearContent-Response) | | -| BlockFileSetName | [Rpc.BlockFile.SetName.Request](#anytype-Rpc-BlockFile-SetName-Request) | [Rpc.BlockFile.SetName.Response](#anytype-Rpc-BlockFile-SetName-Response) | File block commands *** | -| BlockImageSetName | [Rpc.BlockImage.SetName.Request](#anytype-Rpc-BlockImage-SetName-Request) | [Rpc.BlockImage.SetName.Response](#anytype-Rpc-BlockImage-SetName-Response) | | -| BlockVideoSetName | [Rpc.BlockVideo.SetName.Request](#anytype-Rpc-BlockVideo-SetName-Request) | [Rpc.BlockVideo.SetName.Response](#anytype-Rpc-BlockVideo-SetName-Response) | | -| BlockFileCreateAndUpload | [Rpc.BlockFile.CreateAndUpload.Request](#anytype-Rpc-BlockFile-CreateAndUpload-Request) | [Rpc.BlockFile.CreateAndUpload.Response](#anytype-Rpc-BlockFile-CreateAndUpload-Response) | | -| BlockFileListSetStyle | [Rpc.BlockFile.ListSetStyle.Request](#anytype-Rpc-BlockFile-ListSetStyle-Request) | [Rpc.BlockFile.ListSetStyle.Response](#anytype-Rpc-BlockFile-ListSetStyle-Response) | | -| BlockDataviewViewCreate | [Rpc.BlockDataview.View.Create.Request](#anytype-Rpc-BlockDataview-View-Create-Request) | [Rpc.BlockDataview.View.Create.Response](#anytype-Rpc-BlockDataview-View-Create-Response) | Dataview block commands *** | -| BlockDataviewViewDelete | [Rpc.BlockDataview.View.Delete.Request](#anytype-Rpc-BlockDataview-View-Delete-Request) | [Rpc.BlockDataview.View.Delete.Response](#anytype-Rpc-BlockDataview-View-Delete-Response) | | -| BlockDataviewViewUpdate | [Rpc.BlockDataview.View.Update.Request](#anytype-Rpc-BlockDataview-View-Update-Request) | [Rpc.BlockDataview.View.Update.Response](#anytype-Rpc-BlockDataview-View-Update-Response) | | -| BlockDataviewViewSetActive | [Rpc.BlockDataview.View.SetActive.Request](#anytype-Rpc-BlockDataview-View-SetActive-Request) | [Rpc.BlockDataview.View.SetActive.Response](#anytype-Rpc-BlockDataview-View-SetActive-Response) | | -| BlockDataviewViewSetPosition | [Rpc.BlockDataview.View.SetPosition.Request](#anytype-Rpc-BlockDataview-View-SetPosition-Request) | [Rpc.BlockDataview.View.SetPosition.Response](#anytype-Rpc-BlockDataview-View-SetPosition-Response) | | -| BlockDataviewSetSource | [Rpc.BlockDataview.SetSource.Request](#anytype-Rpc-BlockDataview-SetSource-Request) | [Rpc.BlockDataview.SetSource.Response](#anytype-Rpc-BlockDataview-SetSource-Response) | | -| BlockDataviewRelationAdd | [Rpc.BlockDataview.Relation.Add.Request](#anytype-Rpc-BlockDataview-Relation-Add-Request) | [Rpc.BlockDataview.Relation.Add.Response](#anytype-Rpc-BlockDataview-Relation-Add-Response) | | -| BlockDataviewRelationDelete | [Rpc.BlockDataview.Relation.Delete.Request](#anytype-Rpc-BlockDataview-Relation-Delete-Request) | [Rpc.BlockDataview.Relation.Delete.Response](#anytype-Rpc-BlockDataview-Relation-Delete-Response) | | -| BlockDataviewRelationListAvailable | [Rpc.BlockDataview.Relation.ListAvailable.Request](#anytype-Rpc-BlockDataview-Relation-ListAvailable-Request) | [Rpc.BlockDataview.Relation.ListAvailable.Response](#anytype-Rpc-BlockDataview-Relation-ListAvailable-Response) | | -| BlockDataviewGroupOrderUpdate | [Rpc.BlockDataview.GroupOrder.Update.Request](#anytype-Rpc-BlockDataview-GroupOrder-Update-Request) | [Rpc.BlockDataview.GroupOrder.Update.Response](#anytype-Rpc-BlockDataview-GroupOrder-Update-Response) | | -| BlockDataviewObjectOrderUpdate | [Rpc.BlockDataview.ObjectOrder.Update.Request](#anytype-Rpc-BlockDataview-ObjectOrder-Update-Request) | [Rpc.BlockDataview.ObjectOrder.Update.Response](#anytype-Rpc-BlockDataview-ObjectOrder-Update-Response) | | -| BlockTableCreate | [Rpc.BlockTable.Create.Request](#anytype-Rpc-BlockTable-Create-Request) | [Rpc.BlockTable.Create.Response](#anytype-Rpc-BlockTable-Create-Response) | Simple table block commands *** | -| BlockTableExpand | [Rpc.BlockTable.Expand.Request](#anytype-Rpc-BlockTable-Expand-Request) | [Rpc.BlockTable.Expand.Response](#anytype-Rpc-BlockTable-Expand-Response) | | -| BlockTableRowCreate | [Rpc.BlockTable.RowCreate.Request](#anytype-Rpc-BlockTable-RowCreate-Request) | [Rpc.BlockTable.RowCreate.Response](#anytype-Rpc-BlockTable-RowCreate-Response) | | -| BlockTableRowDelete | [Rpc.BlockTable.RowDelete.Request](#anytype-Rpc-BlockTable-RowDelete-Request) | [Rpc.BlockTable.RowDelete.Response](#anytype-Rpc-BlockTable-RowDelete-Response) | | -| BlockTableRowDuplicate | [Rpc.BlockTable.RowDuplicate.Request](#anytype-Rpc-BlockTable-RowDuplicate-Request) | [Rpc.BlockTable.RowDuplicate.Response](#anytype-Rpc-BlockTable-RowDuplicate-Response) | | -| BlockTableRowSetHeader | [Rpc.BlockTable.RowSetHeader.Request](#anytype-Rpc-BlockTable-RowSetHeader-Request) | [Rpc.BlockTable.RowSetHeader.Response](#anytype-Rpc-BlockTable-RowSetHeader-Response) | | -| BlockTableColumnCreate | [Rpc.BlockTable.ColumnCreate.Request](#anytype-Rpc-BlockTable-ColumnCreate-Request) | [Rpc.BlockTable.ColumnCreate.Response](#anytype-Rpc-BlockTable-ColumnCreate-Response) | | -| BlockTableColumnMove | [Rpc.BlockTable.ColumnMove.Request](#anytype-Rpc-BlockTable-ColumnMove-Request) | [Rpc.BlockTable.ColumnMove.Response](#anytype-Rpc-BlockTable-ColumnMove-Response) | | -| BlockTableColumnDelete | [Rpc.BlockTable.ColumnDelete.Request](#anytype-Rpc-BlockTable-ColumnDelete-Request) | [Rpc.BlockTable.ColumnDelete.Response](#anytype-Rpc-BlockTable-ColumnDelete-Response) | | -| BlockTableColumnDuplicate | [Rpc.BlockTable.ColumnDuplicate.Request](#anytype-Rpc-BlockTable-ColumnDuplicate-Request) | [Rpc.BlockTable.ColumnDuplicate.Response](#anytype-Rpc-BlockTable-ColumnDuplicate-Response) | | -| BlockTableRowListFill | [Rpc.BlockTable.RowListFill.Request](#anytype-Rpc-BlockTable-RowListFill-Request) | [Rpc.BlockTable.RowListFill.Response](#anytype-Rpc-BlockTable-RowListFill-Response) | | -| BlockTableRowListClean | [Rpc.BlockTable.RowListClean.Request](#anytype-Rpc-BlockTable-RowListClean-Request) | [Rpc.BlockTable.RowListClean.Response](#anytype-Rpc-BlockTable-RowListClean-Response) | | -| BlockTableColumnListFill | [Rpc.BlockTable.ColumnListFill.Request](#anytype-Rpc-BlockTable-ColumnListFill-Request) | [Rpc.BlockTable.ColumnListFill.Response](#anytype-Rpc-BlockTable-ColumnListFill-Response) | | -| BlockTableSort | [Rpc.BlockTable.Sort.Request](#anytype-Rpc-BlockTable-Sort-Request) | [Rpc.BlockTable.Sort.Response](#anytype-Rpc-BlockTable-Sort-Response) | | -| BlockLinkCreateWithObject | [Rpc.BlockLink.CreateWithObject.Request](#anytype-Rpc-BlockLink-CreateWithObject-Request) | [Rpc.BlockLink.CreateWithObject.Response](#anytype-Rpc-BlockLink-CreateWithObject-Response) | Other specific block commands *** | -| BlockLinkListSetAppearance | [Rpc.BlockLink.ListSetAppearance.Request](#anytype-Rpc-BlockLink-ListSetAppearance-Request) | [Rpc.BlockLink.ListSetAppearance.Response](#anytype-Rpc-BlockLink-ListSetAppearance-Response) | | -| BlockBookmarkFetch | [Rpc.BlockBookmark.Fetch.Request](#anytype-Rpc-BlockBookmark-Fetch-Request) | [Rpc.BlockBookmark.Fetch.Response](#anytype-Rpc-BlockBookmark-Fetch-Response) | | -| BlockBookmarkCreateAndFetch | [Rpc.BlockBookmark.CreateAndFetch.Request](#anytype-Rpc-BlockBookmark-CreateAndFetch-Request) | [Rpc.BlockBookmark.CreateAndFetch.Response](#anytype-Rpc-BlockBookmark-CreateAndFetch-Response) | | -| BlockRelationSetKey | [Rpc.BlockRelation.SetKey.Request](#anytype-Rpc-BlockRelation-SetKey-Request) | [Rpc.BlockRelation.SetKey.Response](#anytype-Rpc-BlockRelation-SetKey-Response) | | -| BlockRelationAdd | [Rpc.BlockRelation.Add.Request](#anytype-Rpc-BlockRelation-Add-Request) | [Rpc.BlockRelation.Add.Response](#anytype-Rpc-BlockRelation-Add-Response) | | -| BlockDivListSetStyle | [Rpc.BlockDiv.ListSetStyle.Request](#anytype-Rpc-BlockDiv-ListSetStyle-Request) | [Rpc.BlockDiv.ListSetStyle.Response](#anytype-Rpc-BlockDiv-ListSetStyle-Response) | | -| BlockLatexSetText | [Rpc.BlockLatex.SetText.Request](#anytype-Rpc-BlockLatex-SetText-Request) | [Rpc.BlockLatex.SetText.Response](#anytype-Rpc-BlockLatex-SetText-Response) | | -| BlockCreateWidget | [Rpc.Block.CreateWidget.Request](#anytype-Rpc-Block-CreateWidget-Request) | [Rpc.Block.CreateWidget.Response](#anytype-Rpc-Block-CreateWidget-Response) | | -| ProcessCancel | [Rpc.Process.Cancel.Request](#anytype-Rpc-Process-Cancel-Request) | [Rpc.Process.Cancel.Response](#anytype-Rpc-Process-Cancel-Response) | | -| LogSend | [Rpc.Log.Send.Request](#anytype-Rpc-Log-Send-Request) | [Rpc.Log.Send.Response](#anytype-Rpc-Log-Send-Response) | | -| DebugSync | [Rpc.Debug.Sync.Request](#anytype-Rpc-Debug-Sync-Request) | [Rpc.Debug.Sync.Response](#anytype-Rpc-Debug-Sync-Response) | | -| DebugThread | [Rpc.Debug.Thread.Request](#anytype-Rpc-Debug-Thread-Request) | [Rpc.Debug.Thread.Response](#anytype-Rpc-Debug-Thread-Response) | | -| DebugTree | [Rpc.Debug.Tree.Request](#anytype-Rpc-Debug-Tree-Request) | [Rpc.Debug.Tree.Response](#anytype-Rpc-Debug-Tree-Response) | | -| DebugExportLocalstore | [Rpc.Debug.ExportLocalstore.Request](#anytype-Rpc-Debug-ExportLocalstore-Request) | [Rpc.Debug.ExportLocalstore.Response](#anytype-Rpc-Debug-ExportLocalstore-Response) | | -| DebugPing | [Rpc.Debug.Ping.Request](#anytype-Rpc-Debug-Ping-Request) | [Rpc.Debug.Ping.Response](#anytype-Rpc-Debug-Ping-Response) | | -| MetricsSetParameters | [Rpc.Metrics.SetParameters.Request](#anytype-Rpc-Metrics-SetParameters-Request) | [Rpc.Metrics.SetParameters.Response](#anytype-Rpc-Metrics-SetParameters-Response) | | -| ListenSessionEvents | [StreamRequest](#anytype-StreamRequest) | [Event](#anytype-Event) stream | used only for lib-server via grpc | +| AppGetVersion | [Rpc.App.GetVersion.Request](#anytype.Rpc.App.GetVersion.Request) | [Rpc.App.GetVersion.Response](#anytype.Rpc.App.GetVersion.Response) | | +| AppSetDeviceState | [Rpc.App.SetDeviceState.Request](#anytype.Rpc.App.SetDeviceState.Request) | [Rpc.App.SetDeviceState.Response](#anytype.Rpc.App.SetDeviceState.Response) | | +| AppShutdown | [Rpc.App.Shutdown.Request](#anytype.Rpc.App.Shutdown.Request) | [Rpc.App.Shutdown.Response](#anytype.Rpc.App.Shutdown.Response) | | +| WalletCreate | [Rpc.Wallet.Create.Request](#anytype.Rpc.Wallet.Create.Request) | [Rpc.Wallet.Create.Response](#anytype.Rpc.Wallet.Create.Response) | Wallet *** | +| WalletRecover | [Rpc.Wallet.Recover.Request](#anytype.Rpc.Wallet.Recover.Request) | [Rpc.Wallet.Recover.Response](#anytype.Rpc.Wallet.Recover.Response) | | +| WalletConvert | [Rpc.Wallet.Convert.Request](#anytype.Rpc.Wallet.Convert.Request) | [Rpc.Wallet.Convert.Response](#anytype.Rpc.Wallet.Convert.Response) | | +| WalletCreateSession | [Rpc.Wallet.CreateSession.Request](#anytype.Rpc.Wallet.CreateSession.Request) | [Rpc.Wallet.CreateSession.Response](#anytype.Rpc.Wallet.CreateSession.Response) | | +| WalletCloseSession | [Rpc.Wallet.CloseSession.Request](#anytype.Rpc.Wallet.CloseSession.Request) | [Rpc.Wallet.CloseSession.Response](#anytype.Rpc.Wallet.CloseSession.Response) | | +| WorkspaceCreate | [Rpc.Workspace.Create.Request](#anytype.Rpc.Workspace.Create.Request) | [Rpc.Workspace.Create.Response](#anytype.Rpc.Workspace.Create.Response) | Workspace *** | +| WorkspaceObjectAdd | [Rpc.Workspace.Object.Add.Request](#anytype.Rpc.Workspace.Object.Add.Request) | [Rpc.Workspace.Object.Add.Response](#anytype.Rpc.Workspace.Object.Add.Response) | | +| WorkspaceObjectListAdd | [Rpc.Workspace.Object.ListAdd.Request](#anytype.Rpc.Workspace.Object.ListAdd.Request) | [Rpc.Workspace.Object.ListAdd.Response](#anytype.Rpc.Workspace.Object.ListAdd.Response) | | +| WorkspaceObjectListRemove | [Rpc.Workspace.Object.ListRemove.Request](#anytype.Rpc.Workspace.Object.ListRemove.Request) | [Rpc.Workspace.Object.ListRemove.Response](#anytype.Rpc.Workspace.Object.ListRemove.Response) | | +| WorkspaceSelect | [Rpc.Workspace.Select.Request](#anytype.Rpc.Workspace.Select.Request) | [Rpc.Workspace.Select.Response](#anytype.Rpc.Workspace.Select.Response) | | +| WorkspaceGetCurrent | [Rpc.Workspace.GetCurrent.Request](#anytype.Rpc.Workspace.GetCurrent.Request) | [Rpc.Workspace.GetCurrent.Response](#anytype.Rpc.Workspace.GetCurrent.Response) | | +| WorkspaceGetAll | [Rpc.Workspace.GetAll.Request](#anytype.Rpc.Workspace.GetAll.Request) | [Rpc.Workspace.GetAll.Response](#anytype.Rpc.Workspace.GetAll.Response) | | +| WorkspaceSetIsHighlighted | [Rpc.Workspace.SetIsHighlighted.Request](#anytype.Rpc.Workspace.SetIsHighlighted.Request) | [Rpc.Workspace.SetIsHighlighted.Response](#anytype.Rpc.Workspace.SetIsHighlighted.Response) | | +| WorkspaceExport | [Rpc.Workspace.Export.Request](#anytype.Rpc.Workspace.Export.Request) | [Rpc.Workspace.Export.Response](#anytype.Rpc.Workspace.Export.Response) | | +| AccountRecover | [Rpc.Account.Recover.Request](#anytype.Rpc.Account.Recover.Request) | [Rpc.Account.Recover.Response](#anytype.Rpc.Account.Recover.Response) | Account *** | +| AccountCreate | [Rpc.Account.Create.Request](#anytype.Rpc.Account.Create.Request) | [Rpc.Account.Create.Response](#anytype.Rpc.Account.Create.Response) | | +| AccountDelete | [Rpc.Account.Delete.Request](#anytype.Rpc.Account.Delete.Request) | [Rpc.Account.Delete.Response](#anytype.Rpc.Account.Delete.Response) | | +| AccountSelect | [Rpc.Account.Select.Request](#anytype.Rpc.Account.Select.Request) | [Rpc.Account.Select.Response](#anytype.Rpc.Account.Select.Response) | | +| AccountStop | [Rpc.Account.Stop.Request](#anytype.Rpc.Account.Stop.Request) | [Rpc.Account.Stop.Response](#anytype.Rpc.Account.Stop.Response) | | +| AccountMove | [Rpc.Account.Move.Request](#anytype.Rpc.Account.Move.Request) | [Rpc.Account.Move.Response](#anytype.Rpc.Account.Move.Response) | | +| AccountConfigUpdate | [Rpc.Account.ConfigUpdate.Request](#anytype.Rpc.Account.ConfigUpdate.Request) | [Rpc.Account.ConfigUpdate.Response](#anytype.Rpc.Account.ConfigUpdate.Response) | | +| ObjectOpen | [Rpc.Object.Open.Request](#anytype.Rpc.Object.Open.Request) | [Rpc.Object.Open.Response](#anytype.Rpc.Object.Open.Response) | Object *** | +| ObjectClose | [Rpc.Object.Close.Request](#anytype.Rpc.Object.Close.Request) | [Rpc.Object.Close.Response](#anytype.Rpc.Object.Close.Response) | | +| ObjectShow | [Rpc.Object.Show.Request](#anytype.Rpc.Object.Show.Request) | [Rpc.Object.Show.Response](#anytype.Rpc.Object.Show.Response) | | +| ObjectCreate | [Rpc.Object.Create.Request](#anytype.Rpc.Object.Create.Request) | [Rpc.Object.Create.Response](#anytype.Rpc.Object.Create.Response) | ObjectCreate just creates the new page, without adding the link to it from some other page | +| ObjectCreateBookmark | [Rpc.Object.CreateBookmark.Request](#anytype.Rpc.Object.CreateBookmark.Request) | [Rpc.Object.CreateBookmark.Response](#anytype.Rpc.Object.CreateBookmark.Response) | | +| ObjectCreateSet | [Rpc.Object.CreateSet.Request](#anytype.Rpc.Object.CreateSet.Request) | [Rpc.Object.CreateSet.Response](#anytype.Rpc.Object.CreateSet.Response) | ObjectCreateSet just creates the new set, without adding the link to it from some other page | +| ObjectGraph | [Rpc.Object.Graph.Request](#anytype.Rpc.Object.Graph.Request) | [Rpc.Object.Graph.Response](#anytype.Rpc.Object.Graph.Response) | | +| ObjectSearch | [Rpc.Object.Search.Request](#anytype.Rpc.Object.Search.Request) | [Rpc.Object.Search.Response](#anytype.Rpc.Object.Search.Response) | | +| ObjectSearchSubscribe | [Rpc.Object.SearchSubscribe.Request](#anytype.Rpc.Object.SearchSubscribe.Request) | [Rpc.Object.SearchSubscribe.Response](#anytype.Rpc.Object.SearchSubscribe.Response) | | +| ObjectSubscribeIds | [Rpc.Object.SubscribeIds.Request](#anytype.Rpc.Object.SubscribeIds.Request) | [Rpc.Object.SubscribeIds.Response](#anytype.Rpc.Object.SubscribeIds.Response) | | +| ObjectGroupsSubscribe | [Rpc.Object.GroupsSubscribe.Request](#anytype.Rpc.Object.GroupsSubscribe.Request) | [Rpc.Object.GroupsSubscribe.Response](#anytype.Rpc.Object.GroupsSubscribe.Response) | | +| ObjectSearchUnsubscribe | [Rpc.Object.SearchUnsubscribe.Request](#anytype.Rpc.Object.SearchUnsubscribe.Request) | [Rpc.Object.SearchUnsubscribe.Response](#anytype.Rpc.Object.SearchUnsubscribe.Response) | | +| ObjectSetDetails | [Rpc.Object.SetDetails.Request](#anytype.Rpc.Object.SetDetails.Request) | [Rpc.Object.SetDetails.Response](#anytype.Rpc.Object.SetDetails.Response) | | +| ObjectDuplicate | [Rpc.Object.Duplicate.Request](#anytype.Rpc.Object.Duplicate.Request) | [Rpc.Object.Duplicate.Response](#anytype.Rpc.Object.Duplicate.Response) | | +| ObjectSetObjectType | [Rpc.Object.SetObjectType.Request](#anytype.Rpc.Object.SetObjectType.Request) | [Rpc.Object.SetObjectType.Response](#anytype.Rpc.Object.SetObjectType.Response) | ObjectSetObjectType sets an existing object type to the object so it will appear in sets and suggests relations from this type | +| ObjectSetLayout | [Rpc.Object.SetLayout.Request](#anytype.Rpc.Object.SetLayout.Request) | [Rpc.Object.SetLayout.Response](#anytype.Rpc.Object.SetLayout.Response) | | +| ObjectSetInternalFlags | [Rpc.Object.SetInternalFlags.Request](#anytype.Rpc.Object.SetInternalFlags.Request) | [Rpc.Object.SetInternalFlags.Response](#anytype.Rpc.Object.SetInternalFlags.Response) | | +| ObjectSetIsFavorite | [Rpc.Object.SetIsFavorite.Request](#anytype.Rpc.Object.SetIsFavorite.Request) | [Rpc.Object.SetIsFavorite.Response](#anytype.Rpc.Object.SetIsFavorite.Response) | | +| ObjectSetIsArchived | [Rpc.Object.SetIsArchived.Request](#anytype.Rpc.Object.SetIsArchived.Request) | [Rpc.Object.SetIsArchived.Response](#anytype.Rpc.Object.SetIsArchived.Response) | | +| ObjectListDuplicate | [Rpc.Object.ListDuplicate.Request](#anytype.Rpc.Object.ListDuplicate.Request) | [Rpc.Object.ListDuplicate.Response](#anytype.Rpc.Object.ListDuplicate.Response) | | +| ObjectListDelete | [Rpc.Object.ListDelete.Request](#anytype.Rpc.Object.ListDelete.Request) | [Rpc.Object.ListDelete.Response](#anytype.Rpc.Object.ListDelete.Response) | | +| ObjectListSetIsArchived | [Rpc.Object.ListSetIsArchived.Request](#anytype.Rpc.Object.ListSetIsArchived.Request) | [Rpc.Object.ListSetIsArchived.Response](#anytype.Rpc.Object.ListSetIsArchived.Response) | | +| ObjectListSetIsFavorite | [Rpc.Object.ListSetIsFavorite.Request](#anytype.Rpc.Object.ListSetIsFavorite.Request) | [Rpc.Object.ListSetIsFavorite.Response](#anytype.Rpc.Object.ListSetIsFavorite.Response) | | +| ObjectApplyTemplate | [Rpc.Object.ApplyTemplate.Request](#anytype.Rpc.Object.ApplyTemplate.Request) | [Rpc.Object.ApplyTemplate.Response](#anytype.Rpc.Object.ApplyTemplate.Response) | | +| ObjectToSet | [Rpc.Object.ToSet.Request](#anytype.Rpc.Object.ToSet.Request) | [Rpc.Object.ToSet.Response](#anytype.Rpc.Object.ToSet.Response) | ObjectToSet creates new set from given object and removes object | +| ObjectAddWithObjectId | [Rpc.Object.AddWithObjectId.Request](#anytype.Rpc.Object.AddWithObjectId.Request) | [Rpc.Object.AddWithObjectId.Response](#anytype.Rpc.Object.AddWithObjectId.Response) | | +| ObjectShareByLink | [Rpc.Object.ShareByLink.Request](#anytype.Rpc.Object.ShareByLink.Request) | [Rpc.Object.ShareByLink.Response](#anytype.Rpc.Object.ShareByLink.Response) | | +| ObjectOpenBreadcrumbs | [Rpc.Object.OpenBreadcrumbs.Request](#anytype.Rpc.Object.OpenBreadcrumbs.Request) | [Rpc.Object.OpenBreadcrumbs.Response](#anytype.Rpc.Object.OpenBreadcrumbs.Response) | | +| ObjectSetBreadcrumbs | [Rpc.Object.SetBreadcrumbs.Request](#anytype.Rpc.Object.SetBreadcrumbs.Request) | [Rpc.Object.SetBreadcrumbs.Response](#anytype.Rpc.Object.SetBreadcrumbs.Response) | | +| ObjectUndo | [Rpc.Object.Undo.Request](#anytype.Rpc.Object.Undo.Request) | [Rpc.Object.Undo.Response](#anytype.Rpc.Object.Undo.Response) | | +| ObjectRedo | [Rpc.Object.Redo.Request](#anytype.Rpc.Object.Redo.Request) | [Rpc.Object.Redo.Response](#anytype.Rpc.Object.Redo.Response) | | +| ObjectImportMarkdown | [Rpc.Object.ImportMarkdown.Request](#anytype.Rpc.Object.ImportMarkdown.Request) | [Rpc.Object.ImportMarkdown.Response](#anytype.Rpc.Object.ImportMarkdown.Response) | | +| ObjectListExport | [Rpc.Object.ListExport.Request](#anytype.Rpc.Object.ListExport.Request) | [Rpc.Object.ListExport.Response](#anytype.Rpc.Object.ListExport.Response) | | +| ObjectBookmarkFetch | [Rpc.Object.BookmarkFetch.Request](#anytype.Rpc.Object.BookmarkFetch.Request) | [Rpc.Object.BookmarkFetch.Response](#anytype.Rpc.Object.BookmarkFetch.Response) | | +| ObjectToBookmark | [Rpc.Object.ToBookmark.Request](#anytype.Rpc.Object.ToBookmark.Request) | [Rpc.Object.ToBookmark.Response](#anytype.Rpc.Object.ToBookmark.Response) | | +| ObjectImport | [Rpc.Object.Import.Request](#anytype.Rpc.Object.Import.Request) | [Rpc.Object.Import.Response](#anytype.Rpc.Object.Import.Response) | | +| ObjectImportList | [Rpc.Object.ImportList.Request](#anytype.Rpc.Object.ImportList.Request) | [Rpc.Object.ImportList.Response](#anytype.Rpc.Object.ImportList.Response) | | +| ObjectCreateRelation | [Rpc.Object.CreateRelation.Request](#anytype.Rpc.Object.CreateRelation.Request) | [Rpc.Object.CreateRelation.Response](#anytype.Rpc.Object.CreateRelation.Response) | Relations *** | +| ObjectCreateRelationOption | [Rpc.Object.CreateRelationOption.Request](#anytype.Rpc.Object.CreateRelationOption.Request) | [Rpc.Object.CreateRelationOption.Response](#anytype.Rpc.Object.CreateRelationOption.Response) | | +| RelationListRemoveOption | [Rpc.Relation.ListRemoveOption.Request](#anytype.Rpc.Relation.ListRemoveOption.Request) | [Rpc.Relation.ListRemoveOption.Response](#anytype.Rpc.Relation.ListRemoveOption.Response) | | +| RelationOptions | [Rpc.Relation.Options.Request](#anytype.Rpc.Relation.Options.Request) | [Rpc.Relation.Options.Response](#anytype.Rpc.Relation.Options.Response) | | +| ObjectRelationAdd | [Rpc.ObjectRelation.Add.Request](#anytype.Rpc.ObjectRelation.Add.Request) | [Rpc.ObjectRelation.Add.Response](#anytype.Rpc.ObjectRelation.Add.Response) | Object Relations *** | +| ObjectRelationDelete | [Rpc.ObjectRelation.Delete.Request](#anytype.Rpc.ObjectRelation.Delete.Request) | [Rpc.ObjectRelation.Delete.Response](#anytype.Rpc.ObjectRelation.Delete.Response) | | +| ObjectRelationAddFeatured | [Rpc.ObjectRelation.AddFeatured.Request](#anytype.Rpc.ObjectRelation.AddFeatured.Request) | [Rpc.ObjectRelation.AddFeatured.Response](#anytype.Rpc.ObjectRelation.AddFeatured.Response) | | +| ObjectRelationRemoveFeatured | [Rpc.ObjectRelation.RemoveFeatured.Request](#anytype.Rpc.ObjectRelation.RemoveFeatured.Request) | [Rpc.ObjectRelation.RemoveFeatured.Response](#anytype.Rpc.ObjectRelation.RemoveFeatured.Response) | | +| ObjectRelationListAvailable | [Rpc.ObjectRelation.ListAvailable.Request](#anytype.Rpc.ObjectRelation.ListAvailable.Request) | [Rpc.ObjectRelation.ListAvailable.Response](#anytype.Rpc.ObjectRelation.ListAvailable.Response) | | +| ObjectCreateObjectType | [Rpc.Object.CreateObjectType.Request](#anytype.Rpc.Object.CreateObjectType.Request) | [Rpc.Object.CreateObjectType.Response](#anytype.Rpc.Object.CreateObjectType.Response) | ObjectType commands *** | +| ObjectTypeRelationList | [Rpc.ObjectType.Relation.List.Request](#anytype.Rpc.ObjectType.Relation.List.Request) | [Rpc.ObjectType.Relation.List.Response](#anytype.Rpc.ObjectType.Relation.List.Response) | | +| ObjectTypeRelationAdd | [Rpc.ObjectType.Relation.Add.Request](#anytype.Rpc.ObjectType.Relation.Add.Request) | [Rpc.ObjectType.Relation.Add.Response](#anytype.Rpc.ObjectType.Relation.Add.Response) | | +| ObjectTypeRelationRemove | [Rpc.ObjectType.Relation.Remove.Request](#anytype.Rpc.ObjectType.Relation.Remove.Request) | [Rpc.ObjectType.Relation.Remove.Response](#anytype.Rpc.ObjectType.Relation.Remove.Response) | | +| HistoryShowVersion | [Rpc.History.ShowVersion.Request](#anytype.Rpc.History.ShowVersion.Request) | [Rpc.History.ShowVersion.Response](#anytype.Rpc.History.ShowVersion.Response) | | +| HistoryGetVersions | [Rpc.History.GetVersions.Request](#anytype.Rpc.History.GetVersions.Request) | [Rpc.History.GetVersions.Response](#anytype.Rpc.History.GetVersions.Response) | | +| HistorySetVersion | [Rpc.History.SetVersion.Request](#anytype.Rpc.History.SetVersion.Request) | [Rpc.History.SetVersion.Response](#anytype.Rpc.History.SetVersion.Response) | | +| FileOffload | [Rpc.File.Offload.Request](#anytype.Rpc.File.Offload.Request) | [Rpc.File.Offload.Response](#anytype.Rpc.File.Offload.Response) | Files *** | +| FileListOffload | [Rpc.File.ListOffload.Request](#anytype.Rpc.File.ListOffload.Request) | [Rpc.File.ListOffload.Response](#anytype.Rpc.File.ListOffload.Response) | | +| FileUpload | [Rpc.File.Upload.Request](#anytype.Rpc.File.Upload.Request) | [Rpc.File.Upload.Response](#anytype.Rpc.File.Upload.Response) | | +| FileDownload | [Rpc.File.Download.Request](#anytype.Rpc.File.Download.Request) | [Rpc.File.Download.Response](#anytype.Rpc.File.Download.Response) | | +| FileDrop | [Rpc.File.Drop.Request](#anytype.Rpc.File.Drop.Request) | [Rpc.File.Drop.Response](#anytype.Rpc.File.Drop.Response) | | +| NavigationListObjects | [Rpc.Navigation.ListObjects.Request](#anytype.Rpc.Navigation.ListObjects.Request) | [Rpc.Navigation.ListObjects.Response](#anytype.Rpc.Navigation.ListObjects.Response) | | +| NavigationGetObjectInfoWithLinks | [Rpc.Navigation.GetObjectInfoWithLinks.Request](#anytype.Rpc.Navigation.GetObjectInfoWithLinks.Request) | [Rpc.Navigation.GetObjectInfoWithLinks.Response](#anytype.Rpc.Navigation.GetObjectInfoWithLinks.Response) | | +| TemplateCreateFromObject | [Rpc.Template.CreateFromObject.Request](#anytype.Rpc.Template.CreateFromObject.Request) | [Rpc.Template.CreateFromObject.Response](#anytype.Rpc.Template.CreateFromObject.Response) | | +| TemplateCreateFromObjectType | [Rpc.Template.CreateFromObjectType.Request](#anytype.Rpc.Template.CreateFromObjectType.Request) | [Rpc.Template.CreateFromObjectType.Response](#anytype.Rpc.Template.CreateFromObjectType.Response) | to be renamed to ObjectCreateTemplate | +| TemplateClone | [Rpc.Template.Clone.Request](#anytype.Rpc.Template.Clone.Request) | [Rpc.Template.Clone.Response](#anytype.Rpc.Template.Clone.Response) | | +| TemplateExportAll | [Rpc.Template.ExportAll.Request](#anytype.Rpc.Template.ExportAll.Request) | [Rpc.Template.ExportAll.Response](#anytype.Rpc.Template.ExportAll.Response) | | +| LinkPreview | [Rpc.LinkPreview.Request](#anytype.Rpc.LinkPreview.Request) | [Rpc.LinkPreview.Response](#anytype.Rpc.LinkPreview.Response) | | +| UnsplashSearch | [Rpc.Unsplash.Search.Request](#anytype.Rpc.Unsplash.Search.Request) | [Rpc.Unsplash.Search.Response](#anytype.Rpc.Unsplash.Search.Response) | | +| UnsplashDownload | [Rpc.Unsplash.Download.Request](#anytype.Rpc.Unsplash.Download.Request) | [Rpc.Unsplash.Download.Response](#anytype.Rpc.Unsplash.Download.Response) | UnsplashDownload downloads picture from unsplash by ID, put it to the IPFS and returns the hash. The artist info is available in the object details | +| BlockUpload | [Rpc.Block.Upload.Request](#anytype.Rpc.Block.Upload.Request) | [Rpc.Block.Upload.Response](#anytype.Rpc.Block.Upload.Response) | General Block commands *** | +| BlockReplace | [Rpc.Block.Replace.Request](#anytype.Rpc.Block.Replace.Request) | [Rpc.Block.Replace.Response](#anytype.Rpc.Block.Replace.Response) | | +| BlockCreate | [Rpc.Block.Create.Request](#anytype.Rpc.Block.Create.Request) | [Rpc.Block.Create.Response](#anytype.Rpc.Block.Create.Response) | | +| BlockSplit | [Rpc.Block.Split.Request](#anytype.Rpc.Block.Split.Request) | [Rpc.Block.Split.Response](#anytype.Rpc.Block.Split.Response) | | +| BlockMerge | [Rpc.Block.Merge.Request](#anytype.Rpc.Block.Merge.Request) | [Rpc.Block.Merge.Response](#anytype.Rpc.Block.Merge.Response) | | +| BlockCopy | [Rpc.Block.Copy.Request](#anytype.Rpc.Block.Copy.Request) | [Rpc.Block.Copy.Response](#anytype.Rpc.Block.Copy.Response) | | +| BlockPaste | [Rpc.Block.Paste.Request](#anytype.Rpc.Block.Paste.Request) | [Rpc.Block.Paste.Response](#anytype.Rpc.Block.Paste.Response) | | +| BlockCut | [Rpc.Block.Cut.Request](#anytype.Rpc.Block.Cut.Request) | [Rpc.Block.Cut.Response](#anytype.Rpc.Block.Cut.Response) | | +| BlockSetFields | [Rpc.Block.SetFields.Request](#anytype.Rpc.Block.SetFields.Request) | [Rpc.Block.SetFields.Response](#anytype.Rpc.Block.SetFields.Response) | | +| BlockExport | [Rpc.Block.Export.Request](#anytype.Rpc.Block.Export.Request) | [Rpc.Block.Export.Response](#anytype.Rpc.Block.Export.Response) | | +| BlockListDelete | [Rpc.Block.ListDelete.Request](#anytype.Rpc.Block.ListDelete.Request) | [Rpc.Block.ListDelete.Response](#anytype.Rpc.Block.ListDelete.Response) | | +| BlockListMoveToExistingObject | [Rpc.Block.ListMoveToExistingObject.Request](#anytype.Rpc.Block.ListMoveToExistingObject.Request) | [Rpc.Block.ListMoveToExistingObject.Response](#anytype.Rpc.Block.ListMoveToExistingObject.Response) | | +| BlockListMoveToNewObject | [Rpc.Block.ListMoveToNewObject.Request](#anytype.Rpc.Block.ListMoveToNewObject.Request) | [Rpc.Block.ListMoveToNewObject.Response](#anytype.Rpc.Block.ListMoveToNewObject.Response) | | +| BlockListConvertToObjects | [Rpc.Block.ListConvertToObjects.Request](#anytype.Rpc.Block.ListConvertToObjects.Request) | [Rpc.Block.ListConvertToObjects.Response](#anytype.Rpc.Block.ListConvertToObjects.Response) | | +| BlockListSetFields | [Rpc.Block.ListSetFields.Request](#anytype.Rpc.Block.ListSetFields.Request) | [Rpc.Block.ListSetFields.Response](#anytype.Rpc.Block.ListSetFields.Response) | | +| BlockListDuplicate | [Rpc.Block.ListDuplicate.Request](#anytype.Rpc.Block.ListDuplicate.Request) | [Rpc.Block.ListDuplicate.Response](#anytype.Rpc.Block.ListDuplicate.Response) | | +| BlockListSetBackgroundColor | [Rpc.Block.ListSetBackgroundColor.Request](#anytype.Rpc.Block.ListSetBackgroundColor.Request) | [Rpc.Block.ListSetBackgroundColor.Response](#anytype.Rpc.Block.ListSetBackgroundColor.Response) | | +| BlockListSetAlign | [Rpc.Block.ListSetAlign.Request](#anytype.Rpc.Block.ListSetAlign.Request) | [Rpc.Block.ListSetAlign.Response](#anytype.Rpc.Block.ListSetAlign.Response) | | +| BlockListSetVerticalAlign | [Rpc.Block.ListSetVerticalAlign.Request](#anytype.Rpc.Block.ListSetVerticalAlign.Request) | [Rpc.Block.ListSetVerticalAlign.Response](#anytype.Rpc.Block.ListSetVerticalAlign.Response) | | +| BlockListTurnInto | [Rpc.Block.ListTurnInto.Request](#anytype.Rpc.Block.ListTurnInto.Request) | [Rpc.Block.ListTurnInto.Response](#anytype.Rpc.Block.ListTurnInto.Response) | | +| BlockTextSetText | [Rpc.BlockText.SetText.Request](#anytype.Rpc.BlockText.SetText.Request) | [Rpc.BlockText.SetText.Response](#anytype.Rpc.BlockText.SetText.Response) | Text Block commands *** | +| BlockTextSetColor | [Rpc.BlockText.SetColor.Request](#anytype.Rpc.BlockText.SetColor.Request) | [Rpc.BlockText.SetColor.Response](#anytype.Rpc.BlockText.SetColor.Response) | | +| BlockTextSetStyle | [Rpc.BlockText.SetStyle.Request](#anytype.Rpc.BlockText.SetStyle.Request) | [Rpc.BlockText.SetStyle.Response](#anytype.Rpc.BlockText.SetStyle.Response) | | +| BlockTextSetChecked | [Rpc.BlockText.SetChecked.Request](#anytype.Rpc.BlockText.SetChecked.Request) | [Rpc.BlockText.SetChecked.Response](#anytype.Rpc.BlockText.SetChecked.Response) | | +| BlockTextSetIcon | [Rpc.BlockText.SetIcon.Request](#anytype.Rpc.BlockText.SetIcon.Request) | [Rpc.BlockText.SetIcon.Response](#anytype.Rpc.BlockText.SetIcon.Response) | | +| BlockTextListSetColor | [Rpc.BlockText.ListSetColor.Request](#anytype.Rpc.BlockText.ListSetColor.Request) | [Rpc.BlockText.ListSetColor.Response](#anytype.Rpc.BlockText.ListSetColor.Response) | | +| BlockTextListSetMark | [Rpc.BlockText.ListSetMark.Request](#anytype.Rpc.BlockText.ListSetMark.Request) | [Rpc.BlockText.ListSetMark.Response](#anytype.Rpc.BlockText.ListSetMark.Response) | | +| BlockTextListSetStyle | [Rpc.BlockText.ListSetStyle.Request](#anytype.Rpc.BlockText.ListSetStyle.Request) | [Rpc.BlockText.ListSetStyle.Response](#anytype.Rpc.BlockText.ListSetStyle.Response) | | +| BlockTextListClearStyle | [Rpc.BlockText.ListClearStyle.Request](#anytype.Rpc.BlockText.ListClearStyle.Request) | [Rpc.BlockText.ListClearStyle.Response](#anytype.Rpc.BlockText.ListClearStyle.Response) | | +| BlockTextListClearContent | [Rpc.BlockText.ListClearContent.Request](#anytype.Rpc.BlockText.ListClearContent.Request) | [Rpc.BlockText.ListClearContent.Response](#anytype.Rpc.BlockText.ListClearContent.Response) | | +| BlockFileSetName | [Rpc.BlockFile.SetName.Request](#anytype.Rpc.BlockFile.SetName.Request) | [Rpc.BlockFile.SetName.Response](#anytype.Rpc.BlockFile.SetName.Response) | File block commands *** | +| BlockImageSetName | [Rpc.BlockImage.SetName.Request](#anytype.Rpc.BlockImage.SetName.Request) | [Rpc.BlockImage.SetName.Response](#anytype.Rpc.BlockImage.SetName.Response) | | +| BlockVideoSetName | [Rpc.BlockVideo.SetName.Request](#anytype.Rpc.BlockVideo.SetName.Request) | [Rpc.BlockVideo.SetName.Response](#anytype.Rpc.BlockVideo.SetName.Response) | | +| BlockFileCreateAndUpload | [Rpc.BlockFile.CreateAndUpload.Request](#anytype.Rpc.BlockFile.CreateAndUpload.Request) | [Rpc.BlockFile.CreateAndUpload.Response](#anytype.Rpc.BlockFile.CreateAndUpload.Response) | | +| BlockFileListSetStyle | [Rpc.BlockFile.ListSetStyle.Request](#anytype.Rpc.BlockFile.ListSetStyle.Request) | [Rpc.BlockFile.ListSetStyle.Response](#anytype.Rpc.BlockFile.ListSetStyle.Response) | | +| BlockDataviewViewCreate | [Rpc.BlockDataview.View.Create.Request](#anytype.Rpc.BlockDataview.View.Create.Request) | [Rpc.BlockDataview.View.Create.Response](#anytype.Rpc.BlockDataview.View.Create.Response) | Dataview block commands *** | +| BlockDataviewViewDelete | [Rpc.BlockDataview.View.Delete.Request](#anytype.Rpc.BlockDataview.View.Delete.Request) | [Rpc.BlockDataview.View.Delete.Response](#anytype.Rpc.BlockDataview.View.Delete.Response) | | +| BlockDataviewViewUpdate | [Rpc.BlockDataview.View.Update.Request](#anytype.Rpc.BlockDataview.View.Update.Request) | [Rpc.BlockDataview.View.Update.Response](#anytype.Rpc.BlockDataview.View.Update.Response) | | +| BlockDataviewViewSetActive | [Rpc.BlockDataview.View.SetActive.Request](#anytype.Rpc.BlockDataview.View.SetActive.Request) | [Rpc.BlockDataview.View.SetActive.Response](#anytype.Rpc.BlockDataview.View.SetActive.Response) | | +| BlockDataviewViewSetPosition | [Rpc.BlockDataview.View.SetPosition.Request](#anytype.Rpc.BlockDataview.View.SetPosition.Request) | [Rpc.BlockDataview.View.SetPosition.Response](#anytype.Rpc.BlockDataview.View.SetPosition.Response) | | +| BlockDataviewSetSource | [Rpc.BlockDataview.SetSource.Request](#anytype.Rpc.BlockDataview.SetSource.Request) | [Rpc.BlockDataview.SetSource.Response](#anytype.Rpc.BlockDataview.SetSource.Response) | | +| BlockDataviewRelationAdd | [Rpc.BlockDataview.Relation.Add.Request](#anytype.Rpc.BlockDataview.Relation.Add.Request) | [Rpc.BlockDataview.Relation.Add.Response](#anytype.Rpc.BlockDataview.Relation.Add.Response) | | +| BlockDataviewRelationDelete | [Rpc.BlockDataview.Relation.Delete.Request](#anytype.Rpc.BlockDataview.Relation.Delete.Request) | [Rpc.BlockDataview.Relation.Delete.Response](#anytype.Rpc.BlockDataview.Relation.Delete.Response) | | +| BlockDataviewRelationListAvailable | [Rpc.BlockDataview.Relation.ListAvailable.Request](#anytype.Rpc.BlockDataview.Relation.ListAvailable.Request) | [Rpc.BlockDataview.Relation.ListAvailable.Response](#anytype.Rpc.BlockDataview.Relation.ListAvailable.Response) | | +| BlockDataviewGroupOrderUpdate | [Rpc.BlockDataview.GroupOrder.Update.Request](#anytype.Rpc.BlockDataview.GroupOrder.Update.Request) | [Rpc.BlockDataview.GroupOrder.Update.Response](#anytype.Rpc.BlockDataview.GroupOrder.Update.Response) | | +| BlockDataviewObjectOrderUpdate | [Rpc.BlockDataview.ObjectOrder.Update.Request](#anytype.Rpc.BlockDataview.ObjectOrder.Update.Request) | [Rpc.BlockDataview.ObjectOrder.Update.Response](#anytype.Rpc.BlockDataview.ObjectOrder.Update.Response) | | +| BlockTableCreate | [Rpc.BlockTable.Create.Request](#anytype.Rpc.BlockTable.Create.Request) | [Rpc.BlockTable.Create.Response](#anytype.Rpc.BlockTable.Create.Response) | Simple table block commands *** | +| BlockTableExpand | [Rpc.BlockTable.Expand.Request](#anytype.Rpc.BlockTable.Expand.Request) | [Rpc.BlockTable.Expand.Response](#anytype.Rpc.BlockTable.Expand.Response) | | +| BlockTableRowCreate | [Rpc.BlockTable.RowCreate.Request](#anytype.Rpc.BlockTable.RowCreate.Request) | [Rpc.BlockTable.RowCreate.Response](#anytype.Rpc.BlockTable.RowCreate.Response) | | +| BlockTableRowDelete | [Rpc.BlockTable.RowDelete.Request](#anytype.Rpc.BlockTable.RowDelete.Request) | [Rpc.BlockTable.RowDelete.Response](#anytype.Rpc.BlockTable.RowDelete.Response) | | +| BlockTableRowDuplicate | [Rpc.BlockTable.RowDuplicate.Request](#anytype.Rpc.BlockTable.RowDuplicate.Request) | [Rpc.BlockTable.RowDuplicate.Response](#anytype.Rpc.BlockTable.RowDuplicate.Response) | | +| BlockTableRowSetHeader | [Rpc.BlockTable.RowSetHeader.Request](#anytype.Rpc.BlockTable.RowSetHeader.Request) | [Rpc.BlockTable.RowSetHeader.Response](#anytype.Rpc.BlockTable.RowSetHeader.Response) | | +| BlockTableColumnCreate | [Rpc.BlockTable.ColumnCreate.Request](#anytype.Rpc.BlockTable.ColumnCreate.Request) | [Rpc.BlockTable.ColumnCreate.Response](#anytype.Rpc.BlockTable.ColumnCreate.Response) | | +| BlockTableColumnMove | [Rpc.BlockTable.ColumnMove.Request](#anytype.Rpc.BlockTable.ColumnMove.Request) | [Rpc.BlockTable.ColumnMove.Response](#anytype.Rpc.BlockTable.ColumnMove.Response) | | +| BlockTableColumnDelete | [Rpc.BlockTable.ColumnDelete.Request](#anytype.Rpc.BlockTable.ColumnDelete.Request) | [Rpc.BlockTable.ColumnDelete.Response](#anytype.Rpc.BlockTable.ColumnDelete.Response) | | +| BlockTableColumnDuplicate | [Rpc.BlockTable.ColumnDuplicate.Request](#anytype.Rpc.BlockTable.ColumnDuplicate.Request) | [Rpc.BlockTable.ColumnDuplicate.Response](#anytype.Rpc.BlockTable.ColumnDuplicate.Response) | | +| BlockTableRowListFill | [Rpc.BlockTable.RowListFill.Request](#anytype.Rpc.BlockTable.RowListFill.Request) | [Rpc.BlockTable.RowListFill.Response](#anytype.Rpc.BlockTable.RowListFill.Response) | | +| BlockTableRowListClean | [Rpc.BlockTable.RowListClean.Request](#anytype.Rpc.BlockTable.RowListClean.Request) | [Rpc.BlockTable.RowListClean.Response](#anytype.Rpc.BlockTable.RowListClean.Response) | | +| BlockTableColumnListFill | [Rpc.BlockTable.ColumnListFill.Request](#anytype.Rpc.BlockTable.ColumnListFill.Request) | [Rpc.BlockTable.ColumnListFill.Response](#anytype.Rpc.BlockTable.ColumnListFill.Response) | | +| BlockTableSort | [Rpc.BlockTable.Sort.Request](#anytype.Rpc.BlockTable.Sort.Request) | [Rpc.BlockTable.Sort.Response](#anytype.Rpc.BlockTable.Sort.Response) | | +| BlockLinkCreateWithObject | [Rpc.BlockLink.CreateWithObject.Request](#anytype.Rpc.BlockLink.CreateWithObject.Request) | [Rpc.BlockLink.CreateWithObject.Response](#anytype.Rpc.BlockLink.CreateWithObject.Response) | Other specific block commands *** | +| BlockLinkListSetAppearance | [Rpc.BlockLink.ListSetAppearance.Request](#anytype.Rpc.BlockLink.ListSetAppearance.Request) | [Rpc.BlockLink.ListSetAppearance.Response](#anytype.Rpc.BlockLink.ListSetAppearance.Response) | | +| BlockBookmarkFetch | [Rpc.BlockBookmark.Fetch.Request](#anytype.Rpc.BlockBookmark.Fetch.Request) | [Rpc.BlockBookmark.Fetch.Response](#anytype.Rpc.BlockBookmark.Fetch.Response) | | +| BlockBookmarkCreateAndFetch | [Rpc.BlockBookmark.CreateAndFetch.Request](#anytype.Rpc.BlockBookmark.CreateAndFetch.Request) | [Rpc.BlockBookmark.CreateAndFetch.Response](#anytype.Rpc.BlockBookmark.CreateAndFetch.Response) | | +| BlockRelationSetKey | [Rpc.BlockRelation.SetKey.Request](#anytype.Rpc.BlockRelation.SetKey.Request) | [Rpc.BlockRelation.SetKey.Response](#anytype.Rpc.BlockRelation.SetKey.Response) | | +| BlockRelationAdd | [Rpc.BlockRelation.Add.Request](#anytype.Rpc.BlockRelation.Add.Request) | [Rpc.BlockRelation.Add.Response](#anytype.Rpc.BlockRelation.Add.Response) | | +| BlockDivListSetStyle | [Rpc.BlockDiv.ListSetStyle.Request](#anytype.Rpc.BlockDiv.ListSetStyle.Request) | [Rpc.BlockDiv.ListSetStyle.Response](#anytype.Rpc.BlockDiv.ListSetStyle.Response) | | +| BlockLatexSetText | [Rpc.BlockLatex.SetText.Request](#anytype.Rpc.BlockLatex.SetText.Request) | [Rpc.BlockLatex.SetText.Response](#anytype.Rpc.BlockLatex.SetText.Response) | | +| BlockCreateWidget | [Rpc.Block.CreateWidget.Request](#anytype.Rpc.Block.CreateWidget.Request) | [Rpc.Block.CreateWidget.Response](#anytype.Rpc.Block.CreateWidget.Response) | | +| ProcessCancel | [Rpc.Process.Cancel.Request](#anytype.Rpc.Process.Cancel.Request) | [Rpc.Process.Cancel.Response](#anytype.Rpc.Process.Cancel.Response) | | +| LogSend | [Rpc.Log.Send.Request](#anytype.Rpc.Log.Send.Request) | [Rpc.Log.Send.Response](#anytype.Rpc.Log.Send.Response) | | +| DebugSync | [Rpc.Debug.Sync.Request](#anytype.Rpc.Debug.Sync.Request) | [Rpc.Debug.Sync.Response](#anytype.Rpc.Debug.Sync.Response) | | +| DebugThread | [Rpc.Debug.Thread.Request](#anytype.Rpc.Debug.Thread.Request) | [Rpc.Debug.Thread.Response](#anytype.Rpc.Debug.Thread.Response) | | +| DebugTree | [Rpc.Debug.Tree.Request](#anytype.Rpc.Debug.Tree.Request) | [Rpc.Debug.Tree.Response](#anytype.Rpc.Debug.Tree.Response) | | +| DebugExportLocalstore | [Rpc.Debug.ExportLocalstore.Request](#anytype.Rpc.Debug.ExportLocalstore.Request) | [Rpc.Debug.ExportLocalstore.Response](#anytype.Rpc.Debug.ExportLocalstore.Response) | | +| DebugPing | [Rpc.Debug.Ping.Request](#anytype.Rpc.Debug.Ping.Request) | [Rpc.Debug.Ping.Response](#anytype.Rpc.Debug.Ping.Response) | | +| MetricsSetParameters | [Rpc.Metrics.SetParameters.Request](#anytype.Rpc.Metrics.SetParameters.Request) | [Rpc.Metrics.SetParameters.Response](#anytype.Rpc.Metrics.SetParameters.Response) | | +| ListenSessionEvents | [StreamRequest](#anytype.StreamRequest) | [Event](#anytype.Event) stream | used only for lib-server via grpc | - +

Top

## pb/protos/changes.proto - + ### Change the element of change tree used to store and internal apply smartBlock history @@ -1456,9 +1456,9 @@ the element of change tree used to store and internal apply smartBlock history | previous_ids | [string](#string) | repeated | ids of previous changes | | last_snapshot_id | [string](#string) | | id of the last snapshot | | previous_meta_ids | [string](#string) | repeated | ids of the last changes with details/relations content | -| content | [Change.Content](#anytype-Change-Content) | repeated | set of actions to apply | -| snapshot | [Change.Snapshot](#anytype-Change-Snapshot) | | snapshot - when not null, the Content will be ignored | -| fileKeys | [Change.FileKeys](#anytype-Change-FileKeys) | repeated | file keys related to changes content | +| content | [Change.Content](#anytype.Change.Content) | repeated | set of actions to apply | +| snapshot | [Change.Snapshot](#anytype.Change.Snapshot) | | snapshot - when not null, the Content will be ignored | +| fileKeys | [Change.FileKeys](#anytype.Change.FileKeys) | repeated | file keys related to changes content | | timestamp | [int64](#int64) | | creation timestamp | @@ -1466,7 +1466,7 @@ the element of change tree used to store and internal apply smartBlock history - + ### Change.BlockCreate @@ -1475,15 +1475,15 @@ the element of change tree used to store and internal apply smartBlock history | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | targetId | [string](#string) | | | -| position | [model.Block.Position](#anytype-model-Block-Position) | | | -| blocks | [model.Block](#anytype-model-Block) | repeated | | +| position | [model.Block.Position](#anytype.model.Block.Position) | | | +| blocks | [model.Block](#anytype.model.Block) | repeated | | - + ### Change.BlockDuplicate @@ -1492,7 +1492,7 @@ the element of change tree used to store and internal apply smartBlock history | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | targetId | [string](#string) | | | -| position | [model.Block.Position](#anytype-model-Block-Position) | | | +| position | [model.Block.Position](#anytype.model.Block.Position) | | | | ids | [string](#string) | repeated | | @@ -1500,7 +1500,7 @@ the element of change tree used to store and internal apply smartBlock history - + ### Change.BlockMove @@ -1509,7 +1509,7 @@ the element of change tree used to store and internal apply smartBlock history | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | targetId | [string](#string) | | | -| position | [model.Block.Position](#anytype-model-Block-Position) | | | +| position | [model.Block.Position](#anytype.model.Block.Position) | | | | ids | [string](#string) | repeated | | @@ -1517,7 +1517,7 @@ the element of change tree used to store and internal apply smartBlock history - + ### Change.BlockRemove @@ -1532,7 +1532,7 @@ the element of change tree used to store and internal apply smartBlock history - + ### Change.BlockUpdate @@ -1540,14 +1540,14 @@ the element of change tree used to store and internal apply smartBlock history | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| events | [Event.Message](#anytype-Event-Message) | repeated | | +| events | [Event.Message](#anytype.Event.Message) | repeated | | - + ### Change.Content @@ -1555,29 +1555,29 @@ the element of change tree used to store and internal apply smartBlock history | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| blockCreate | [Change.BlockCreate](#anytype-Change-BlockCreate) | | | -| blockUpdate | [Change.BlockUpdate](#anytype-Change-BlockUpdate) | | | -| blockRemove | [Change.BlockRemove](#anytype-Change-BlockRemove) | | | -| blockMove | [Change.BlockMove](#anytype-Change-BlockMove) | | | -| blockDuplicate | [Change.BlockDuplicate](#anytype-Change-BlockDuplicate) | | | -| relationAdd | [Change.RelationAdd](#anytype-Change-RelationAdd) | | | -| relationRemove | [Change.RelationRemove](#anytype-Change-RelationRemove) | | | -| detailsSet | [Change.DetailsSet](#anytype-Change-DetailsSet) | | | -| detailsUnset | [Change.DetailsUnset](#anytype-Change-DetailsUnset) | | | -| old_relationAdd | [Change._RelationAdd](#anytype-Change-_RelationAdd) | | deprecated | -| old_relationRemove | [Change._RelationRemove](#anytype-Change-_RelationRemove) | | | -| old_relationUpdate | [Change._RelationUpdate](#anytype-Change-_RelationUpdate) | | | -| objectTypeAdd | [Change.ObjectTypeAdd](#anytype-Change-ObjectTypeAdd) | | | -| objectTypeRemove | [Change.ObjectTypeRemove](#anytype-Change-ObjectTypeRemove) | | | -| storeKeySet | [Change.StoreKeySet](#anytype-Change-StoreKeySet) | | | -| storeKeyUnset | [Change.StoreKeyUnset](#anytype-Change-StoreKeyUnset) | | | +| blockCreate | [Change.BlockCreate](#anytype.Change.BlockCreate) | | | +| blockUpdate | [Change.BlockUpdate](#anytype.Change.BlockUpdate) | | | +| blockRemove | [Change.BlockRemove](#anytype.Change.BlockRemove) | | | +| blockMove | [Change.BlockMove](#anytype.Change.BlockMove) | | | +| blockDuplicate | [Change.BlockDuplicate](#anytype.Change.BlockDuplicate) | | | +| relationAdd | [Change.RelationAdd](#anytype.Change.RelationAdd) | | | +| relationRemove | [Change.RelationRemove](#anytype.Change.RelationRemove) | | | +| detailsSet | [Change.DetailsSet](#anytype.Change.DetailsSet) | | | +| detailsUnset | [Change.DetailsUnset](#anytype.Change.DetailsUnset) | | | +| old_relationAdd | [Change._RelationAdd](#anytype.Change._RelationAdd) | | deprecated | +| old_relationRemove | [Change._RelationRemove](#anytype.Change._RelationRemove) | | | +| old_relationUpdate | [Change._RelationUpdate](#anytype.Change._RelationUpdate) | | | +| objectTypeAdd | [Change.ObjectTypeAdd](#anytype.Change.ObjectTypeAdd) | | | +| objectTypeRemove | [Change.ObjectTypeRemove](#anytype.Change.ObjectTypeRemove) | | | +| storeKeySet | [Change.StoreKeySet](#anytype.Change.StoreKeySet) | | | +| storeKeyUnset | [Change.StoreKeyUnset](#anytype.Change.StoreKeyUnset) | | | - + ### Change.DetailsSet @@ -1586,14 +1586,14 @@ the element of change tree used to store and internal apply smartBlock history | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | key | [string](#string) | | | -| value | [google.protobuf.Value](#google-protobuf-Value) | | | +| value | [google.protobuf.Value](#google.protobuf.Value) | | | - + ### Change.DetailsUnset @@ -1608,7 +1608,7 @@ the element of change tree used to store and internal apply smartBlock history - + ### Change.FileKeys @@ -1617,14 +1617,14 @@ the element of change tree used to store and internal apply smartBlock history | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | hash | [string](#string) | | | -| keys | [Change.FileKeys.KeysEntry](#anytype-Change-FileKeys-KeysEntry) | repeated | | +| keys | [Change.FileKeys.KeysEntry](#anytype.Change.FileKeys.KeysEntry) | repeated | | - + ### Change.FileKeys.KeysEntry @@ -1640,7 +1640,7 @@ the element of change tree used to store and internal apply smartBlock history - + ### Change.ObjectTypeAdd @@ -1655,7 +1655,7 @@ the element of change tree used to store and internal apply smartBlock history - + ### Change.ObjectTypeRemove @@ -1670,7 +1670,7 @@ the element of change tree used to store and internal apply smartBlock history - + ### Change.RelationAdd @@ -1678,14 +1678,14 @@ the element of change tree used to store and internal apply smartBlock history | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| relationLinks | [model.RelationLink](#anytype-model-RelationLink) | repeated | | +| relationLinks | [model.RelationLink](#anytype.model.RelationLink) | repeated | | - + ### Change.RelationRemove @@ -1700,7 +1700,7 @@ the element of change tree used to store and internal apply smartBlock history - + ### Change.Snapshot @@ -1708,16 +1708,16 @@ the element of change tree used to store and internal apply smartBlock history | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| logHeads | [Change.Snapshot.LogHeadsEntry](#anytype-Change-Snapshot-LogHeadsEntry) | repeated | logId -> lastChangeId | -| data | [model.SmartBlockSnapshotBase](#anytype-model-SmartBlockSnapshotBase) | | snapshot data | -| fileKeys | [Change.FileKeys](#anytype-Change-FileKeys) | repeated | all file keys related to doc | +| logHeads | [Change.Snapshot.LogHeadsEntry](#anytype.Change.Snapshot.LogHeadsEntry) | repeated | logId -> lastChangeId | +| data | [model.SmartBlockSnapshotBase](#anytype.model.SmartBlockSnapshotBase) | | snapshot data | +| fileKeys | [Change.FileKeys](#anytype.Change.FileKeys) | repeated | all file keys related to doc | - + ### Change.Snapshot.LogHeadsEntry @@ -1733,7 +1733,7 @@ the element of change tree used to store and internal apply smartBlock history - + ### Change.StoreKeySet @@ -1742,14 +1742,14 @@ the element of change tree used to store and internal apply smartBlock history | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | path | [string](#string) | repeated | | -| value | [google.protobuf.Value](#google-protobuf-Value) | | | +| value | [google.protobuf.Value](#google.protobuf.Value) | | | - + ### Change.StoreKeyUnset @@ -1764,7 +1764,7 @@ the element of change tree used to store and internal apply smartBlock history - + ### Change._RelationAdd @@ -1772,14 +1772,14 @@ the element of change tree used to store and internal apply smartBlock history | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| relation | [model.Relation](#anytype-model-Relation) | | | +| relation | [model.Relation](#anytype.model.Relation) | | | - + ### Change._RelationRemove @@ -1794,7 +1794,7 @@ the element of change tree used to store and internal apply smartBlock history - + ### Change._RelationUpdate @@ -1803,19 +1803,19 @@ the element of change tree used to store and internal apply smartBlock history | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | key | [string](#string) | | | -| format | [model.RelationFormat](#anytype-model-RelationFormat) | | | +| format | [model.RelationFormat](#anytype.model.RelationFormat) | | | | name | [string](#string) | | | -| defaultValue | [google.protobuf.Value](#google-protobuf-Value) | | | -| objectTypes | [Change._RelationUpdate.ObjectTypes](#anytype-Change-_RelationUpdate-ObjectTypes) | | | +| defaultValue | [google.protobuf.Value](#google.protobuf.Value) | | | +| objectTypes | [Change._RelationUpdate.ObjectTypes](#anytype.Change._RelationUpdate.ObjectTypes) | | | | multi | [bool](#bool) | | | -| selectDict | [Change._RelationUpdate.Dict](#anytype-Change-_RelationUpdate-Dict) | | | +| selectDict | [Change._RelationUpdate.Dict](#anytype.Change._RelationUpdate.Dict) | | | - + ### Change._RelationUpdate.Dict @@ -1823,14 +1823,14 @@ the element of change tree used to store and internal apply smartBlock history | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| dict | [model.Relation.Option](#anytype-model-Relation-Option) | repeated | | +| dict | [model.Relation.Option](#anytype.model.Relation.Option) | repeated | | - + ### Change._RelationUpdate.ObjectTypes @@ -1854,14 +1854,14 @@ the element of change tree used to store and internal apply smartBlock history - +

Top

## pb/protos/commands.proto - + ### Empty @@ -1871,7 +1871,7 @@ the element of change tree used to store and internal apply smartBlock history - + ### Rpc Rpc is a namespace, that agregates all of the service commands between client and middleware. @@ -1884,7 +1884,7 @@ Response – message from a middleware. - + ### Rpc.Account @@ -1894,7 +1894,7 @@ Response – message from a middleware. - + ### Rpc.Account.Config @@ -1906,14 +1906,14 @@ Response – message from a middleware. | enableDebug | [bool](#bool) | | | | enablePrereleaseChannel | [bool](#bool) | | | | enableSpaces | [bool](#bool) | | | -| extra | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| extra | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### Rpc.Account.ConfigUpdate @@ -1923,7 +1923,7 @@ Response – message from a middleware. - + ### Rpc.Account.ConfigUpdate.Request @@ -1939,7 +1939,7 @@ Response – message from a middleware. - + ### Rpc.Account.ConfigUpdate.Response @@ -1947,14 +1947,14 @@ Response – message from a middleware. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Account.ConfigUpdate.Response.Error](#anytype-Rpc-Account-ConfigUpdate-Response-Error) | | | +| error | [Rpc.Account.ConfigUpdate.Response.Error](#anytype.Rpc.Account.ConfigUpdate.Response.Error) | | | - + ### Rpc.Account.ConfigUpdate.Response.Error @@ -1962,7 +1962,7 @@ Response – message from a middleware. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Account.ConfigUpdate.Response.Error.Code](#anytype-Rpc-Account-ConfigUpdate-Response-Error-Code) | | | +| code | [Rpc.Account.ConfigUpdate.Response.Error.Code](#anytype.Rpc.Account.ConfigUpdate.Response.Error.Code) | | | | description | [string](#string) | | | @@ -1970,7 +1970,7 @@ Response – message from a middleware. - + ### Rpc.Account.Create @@ -1980,7 +1980,7 @@ Response – message from a middleware. - + ### Rpc.Account.Create.Request Front end to middleware request-to-create-an account @@ -1998,7 +1998,7 @@ Front end to middleware request-to-create-an account - + ### Rpc.Account.Create.Response Middleware-to-front-end response for an account creation request, that can contain a NULL error and created account or a non-NULL error and an empty account @@ -2006,16 +2006,16 @@ Middleware-to-front-end response for an account creation request, that can conta | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Account.Create.Response.Error](#anytype-Rpc-Account-Create-Response-Error) | | Error while trying to create an account | -| account | [model.Account](#anytype-model-Account) | | A newly created account; In case of a failure, i.e. error is non-NULL, the account model should contain empty/default-value fields | -| config | [Rpc.Account.Config](#anytype-Rpc-Account-Config) | | deprecated, use account | +| error | [Rpc.Account.Create.Response.Error](#anytype.Rpc.Account.Create.Response.Error) | | Error while trying to create an account | +| account | [model.Account](#anytype.model.Account) | | A newly created account; In case of a failure, i.e. error is non-NULL, the account model should contain empty/default-value fields | +| config | [Rpc.Account.Config](#anytype.Rpc.Account.Config) | | deprecated, use account | - + ### Rpc.Account.Create.Response.Error @@ -2023,7 +2023,7 @@ Middleware-to-front-end response for an account creation request, that can conta | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Account.Create.Response.Error.Code](#anytype-Rpc-Account-Create-Response-Error-Code) | | | +| code | [Rpc.Account.Create.Response.Error.Code](#anytype.Rpc.Account.Create.Response.Error.Code) | | | | description | [string](#string) | | | @@ -2031,7 +2031,7 @@ Middleware-to-front-end response for an account creation request, that can conta - + ### Rpc.Account.Delete @@ -2041,7 +2041,7 @@ Middleware-to-front-end response for an account creation request, that can conta - + ### Rpc.Account.Delete.Request @@ -2056,7 +2056,7 @@ Middleware-to-front-end response for an account creation request, that can conta - + ### Rpc.Account.Delete.Response @@ -2064,15 +2064,15 @@ Middleware-to-front-end response for an account creation request, that can conta | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Account.Delete.Response.Error](#anytype-Rpc-Account-Delete-Response-Error) | | Error while trying to recover an account | -| status | [model.Account.Status](#anytype-model-Account-Status) | | | +| error | [Rpc.Account.Delete.Response.Error](#anytype.Rpc.Account.Delete.Response.Error) | | Error while trying to recover an account | +| status | [model.Account.Status](#anytype.model.Account.Status) | | | - + ### Rpc.Account.Delete.Response.Error @@ -2080,7 +2080,7 @@ Middleware-to-front-end response for an account creation request, that can conta | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Account.Delete.Response.Error.Code](#anytype-Rpc-Account-Delete-Response-Error-Code) | | | +| code | [Rpc.Account.Delete.Response.Error.Code](#anytype.Rpc.Account.Delete.Response.Error.Code) | | | | description | [string](#string) | | | @@ -2088,7 +2088,7 @@ Middleware-to-front-end response for an account creation request, that can conta - + ### Rpc.Account.GetConfig @@ -2098,7 +2098,7 @@ Middleware-to-front-end response for an account creation request, that can conta - + ### Rpc.Account.GetConfig.Get @@ -2108,7 +2108,7 @@ Middleware-to-front-end response for an account creation request, that can conta - + ### Rpc.Account.GetConfig.Get.Request @@ -2118,7 +2118,7 @@ Middleware-to-front-end response for an account creation request, that can conta - + ### Rpc.Account.Move @@ -2128,7 +2128,7 @@ Middleware-to-front-end response for an account creation request, that can conta - + ### Rpc.Account.Move.Request Front-end-to-middleware request to move a account to a new disk location @@ -2143,7 +2143,7 @@ Front-end-to-middleware request to move a account to a new disk location - + ### Rpc.Account.Move.Response @@ -2151,14 +2151,14 @@ Front-end-to-middleware request to move a account to a new disk location | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Account.Move.Response.Error](#anytype-Rpc-Account-Move-Response-Error) | | | +| error | [Rpc.Account.Move.Response.Error](#anytype.Rpc.Account.Move.Response.Error) | | | - + ### Rpc.Account.Move.Response.Error @@ -2166,7 +2166,7 @@ Front-end-to-middleware request to move a account to a new disk location | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Account.Move.Response.Error.Code](#anytype-Rpc-Account-Move-Response-Error-Code) | | | +| code | [Rpc.Account.Move.Response.Error.Code](#anytype.Rpc.Account.Move.Response.Error.Code) | | | | description | [string](#string) | | | @@ -2174,7 +2174,7 @@ Front-end-to-middleware request to move a account to a new disk location - + ### Rpc.Account.Recover @@ -2184,7 +2184,7 @@ Front-end-to-middleware request to move a account to a new disk location - + ### Rpc.Account.Recover.Request Front end to middleware request-to-start-search of an accounts for a recovered mnemonic. @@ -2195,7 +2195,7 @@ Each of an account that would be found will come with an AccountAdd event - + ### Rpc.Account.Recover.Response Middleware-to-front-end response to an account recover request, that can contain a NULL error and created account or a non-NULL error and an empty account @@ -2203,14 +2203,14 @@ Middleware-to-front-end response to an account recover request, that can contain | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Account.Recover.Response.Error](#anytype-Rpc-Account-Recover-Response-Error) | | Error while trying to recover an account | +| error | [Rpc.Account.Recover.Response.Error](#anytype.Rpc.Account.Recover.Response.Error) | | Error while trying to recover an account | - + ### Rpc.Account.Recover.Response.Error @@ -2218,7 +2218,7 @@ Middleware-to-front-end response to an account recover request, that can contain | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Account.Recover.Response.Error.Code](#anytype-Rpc-Account-Recover-Response-Error-Code) | | | +| code | [Rpc.Account.Recover.Response.Error.Code](#anytype.Rpc.Account.Recover.Response.Error.Code) | | | | description | [string](#string) | | | @@ -2226,7 +2226,7 @@ Middleware-to-front-end response to an account recover request, that can contain - + ### Rpc.Account.Select @@ -2236,7 +2236,7 @@ Middleware-to-front-end response to an account recover request, that can contain - + ### Rpc.Account.Select.Request Front end to middleware request-to-launch-a specific account using account id and a root path @@ -2253,7 +2253,7 @@ User can select an account from those, that came with an AccountAdd events - + ### Rpc.Account.Select.Response Middleware-to-front-end response for an account select request, that can contain a NULL error and selected account or a non-NULL error and an empty account @@ -2261,16 +2261,16 @@ Middleware-to-front-end response for an account select request, that can contain | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Account.Select.Response.Error](#anytype-Rpc-Account-Select-Response-Error) | | Error while trying to launch/select an account | -| account | [model.Account](#anytype-model-Account) | | Selected account | -| config | [Rpc.Account.Config](#anytype-Rpc-Account-Config) | | deprecated, use account | +| error | [Rpc.Account.Select.Response.Error](#anytype.Rpc.Account.Select.Response.Error) | | Error while trying to launch/select an account | +| account | [model.Account](#anytype.model.Account) | | Selected account | +| config | [Rpc.Account.Config](#anytype.Rpc.Account.Config) | | deprecated, use account | - + ### Rpc.Account.Select.Response.Error @@ -2278,7 +2278,7 @@ Middleware-to-front-end response for an account select request, that can contain | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Account.Select.Response.Error.Code](#anytype-Rpc-Account-Select-Response-Error-Code) | | | +| code | [Rpc.Account.Select.Response.Error.Code](#anytype.Rpc.Account.Select.Response.Error.Code) | | | | description | [string](#string) | | | @@ -2286,7 +2286,7 @@ Middleware-to-front-end response for an account select request, that can contain - + ### Rpc.Account.Stop @@ -2296,7 +2296,7 @@ Middleware-to-front-end response for an account select request, that can contain - + ### Rpc.Account.Stop.Request Front end to middleware request to stop currently running account node and optionally remove the locally stored data @@ -2311,7 +2311,7 @@ Front end to middleware request to stop currently running account node and optio - + ### Rpc.Account.Stop.Response Middleware-to-front-end response for an account stop request @@ -2319,14 +2319,14 @@ Middleware-to-front-end response for an account stop request | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Account.Stop.Response.Error](#anytype-Rpc-Account-Stop-Response-Error) | | Error while trying to launch/select an account | +| error | [Rpc.Account.Stop.Response.Error](#anytype.Rpc.Account.Stop.Response.Error) | | Error while trying to launch/select an account | - + ### Rpc.Account.Stop.Response.Error @@ -2334,7 +2334,7 @@ Middleware-to-front-end response for an account stop request | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Account.Stop.Response.Error.Code](#anytype-Rpc-Account-Stop-Response-Error-Code) | | | +| code | [Rpc.Account.Stop.Response.Error.Code](#anytype.Rpc.Account.Stop.Response.Error.Code) | | | | description | [string](#string) | | | @@ -2342,7 +2342,7 @@ Middleware-to-front-end response for an account stop request - + ### Rpc.App @@ -2352,7 +2352,7 @@ Middleware-to-front-end response for an account stop request - + ### Rpc.App.GetVersion @@ -2362,7 +2362,7 @@ Middleware-to-front-end response for an account stop request - + ### Rpc.App.GetVersion.Request @@ -2372,7 +2372,7 @@ Middleware-to-front-end response for an account stop request - + ### Rpc.App.GetVersion.Response @@ -2380,7 +2380,7 @@ Middleware-to-front-end response for an account stop request | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.App.GetVersion.Response.Error](#anytype-Rpc-App-GetVersion-Response-Error) | | | +| error | [Rpc.App.GetVersion.Response.Error](#anytype.Rpc.App.GetVersion.Response.Error) | | | | version | [string](#string) | | | | details | [string](#string) | | build date, branch and commit | @@ -2389,7 +2389,7 @@ Middleware-to-front-end response for an account stop request - + ### Rpc.App.GetVersion.Response.Error @@ -2397,7 +2397,7 @@ Middleware-to-front-end response for an account stop request | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.App.GetVersion.Response.Error.Code](#anytype-Rpc-App-GetVersion-Response-Error-Code) | | | +| code | [Rpc.App.GetVersion.Response.Error.Code](#anytype.Rpc.App.GetVersion.Response.Error.Code) | | | | description | [string](#string) | | | @@ -2405,7 +2405,7 @@ Middleware-to-front-end response for an account stop request - + ### Rpc.App.SetDeviceState @@ -2415,7 +2415,7 @@ Middleware-to-front-end response for an account stop request - + ### Rpc.App.SetDeviceState.Request @@ -2423,14 +2423,14 @@ Middleware-to-front-end response for an account stop request | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| deviceState | [Rpc.App.SetDeviceState.Request.DeviceState](#anytype-Rpc-App-SetDeviceState-Request-DeviceState) | | | +| deviceState | [Rpc.App.SetDeviceState.Request.DeviceState](#anytype.Rpc.App.SetDeviceState.Request.DeviceState) | | | - + ### Rpc.App.SetDeviceState.Response @@ -2438,14 +2438,14 @@ Middleware-to-front-end response for an account stop request | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.App.SetDeviceState.Response.Error](#anytype-Rpc-App-SetDeviceState-Response-Error) | | | +| error | [Rpc.App.SetDeviceState.Response.Error](#anytype.Rpc.App.SetDeviceState.Response.Error) | | | - + ### Rpc.App.SetDeviceState.Response.Error @@ -2453,7 +2453,7 @@ Middleware-to-front-end response for an account stop request | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.App.SetDeviceState.Response.Error.Code](#anytype-Rpc-App-SetDeviceState-Response-Error-Code) | | | +| code | [Rpc.App.SetDeviceState.Response.Error.Code](#anytype.Rpc.App.SetDeviceState.Response.Error.Code) | | | | description | [string](#string) | | | @@ -2461,7 +2461,7 @@ Middleware-to-front-end response for an account stop request - + ### Rpc.App.Shutdown @@ -2471,7 +2471,7 @@ Middleware-to-front-end response for an account stop request - + ### Rpc.App.Shutdown.Request @@ -2481,7 +2481,7 @@ Middleware-to-front-end response for an account stop request - + ### Rpc.App.Shutdown.Response @@ -2489,14 +2489,14 @@ Middleware-to-front-end response for an account stop request | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.App.Shutdown.Response.Error](#anytype-Rpc-App-Shutdown-Response-Error) | | | +| error | [Rpc.App.Shutdown.Response.Error](#anytype.Rpc.App.Shutdown.Response.Error) | | | - + ### Rpc.App.Shutdown.Response.Error @@ -2504,7 +2504,7 @@ Middleware-to-front-end response for an account stop request | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.App.Shutdown.Response.Error.Code](#anytype-Rpc-App-Shutdown-Response-Error-Code) | | | +| code | [Rpc.App.Shutdown.Response.Error.Code](#anytype.Rpc.App.Shutdown.Response.Error.Code) | | | | description | [string](#string) | | | @@ -2512,7 +2512,7 @@ Middleware-to-front-end response for an account stop request - + ### Rpc.Block Block commands @@ -2522,7 +2522,7 @@ Block commands - + ### Rpc.Block.Copy @@ -2532,7 +2532,7 @@ Block commands - + ### Rpc.Block.Copy.Request @@ -2541,15 +2541,15 @@ Block commands | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | -| blocks | [model.Block](#anytype-model-Block) | repeated | | -| selectedTextRange | [model.Range](#anytype-model-Range) | | | +| blocks | [model.Block](#anytype.model.Block) | repeated | | +| selectedTextRange | [model.Range](#anytype.model.Range) | | | - + ### Rpc.Block.Copy.Response @@ -2557,17 +2557,17 @@ Block commands | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.Copy.Response.Error](#anytype-Rpc-Block-Copy-Response-Error) | | | +| error | [Rpc.Block.Copy.Response.Error](#anytype.Rpc.Block.Copy.Response.Error) | | | | textSlot | [string](#string) | | | | htmlSlot | [string](#string) | | | -| anySlot | [model.Block](#anytype-model-Block) | repeated | | +| anySlot | [model.Block](#anytype.model.Block) | repeated | | - + ### Rpc.Block.Copy.Response.Error @@ -2575,7 +2575,7 @@ Block commands | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.Copy.Response.Error.Code](#anytype-Rpc-Block-Copy-Response-Error-Code) | | | +| code | [Rpc.Block.Copy.Response.Error.Code](#anytype.Rpc.Block.Copy.Response.Error.Code) | | | | description | [string](#string) | | | @@ -2583,7 +2583,7 @@ Block commands - + ### Rpc.Block.Create Create a Smart/Internal block. Request can contain a block with a content, or it can be an empty block with a specific block.content. @@ -2605,7 +2605,7 @@ Create a Smart/Internal block. Request can contain a block with a content, or it - + ### Rpc.Block.Create.Request common simple block command @@ -2615,15 +2615,15 @@ common simple block command | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | id of the context object | | targetId | [string](#string) | | id of the closest block | -| block | [model.Block](#anytype-model-Block) | | | -| position | [model.Block.Position](#anytype-model-Block-Position) | | | +| block | [model.Block](#anytype.model.Block) | | | +| position | [model.Block.Position](#anytype.model.Block.Position) | | | - + ### Rpc.Block.Create.Response @@ -2631,16 +2631,16 @@ common simple block command | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.Create.Response.Error](#anytype-Rpc-Block-Create-Response-Error) | | | +| error | [Rpc.Block.Create.Response.Error](#anytype.Rpc.Block.Create.Response.Error) | | | | blockId | [string](#string) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.Create.Response.Error @@ -2648,7 +2648,7 @@ common simple block command | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.Create.Response.Error.Code](#anytype-Rpc-Block-Create-Response-Error-Code) | | | +| code | [Rpc.Block.Create.Response.Error.Code](#anytype.Rpc.Block.Create.Response.Error.Code) | | | | description | [string](#string) | | | @@ -2656,7 +2656,7 @@ common simple block command - + ### Rpc.Block.CreateWidget @@ -2666,7 +2666,7 @@ common simple block command - + ### Rpc.Block.CreateWidget.Request @@ -2676,16 +2676,16 @@ common simple block command | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | id of the context object | | targetId | [string](#string) | | id of the closest block | -| block | [model.Block](#anytype-model-Block) | | | -| position | [model.Block.Position](#anytype-model-Block-Position) | | | -| widgetLayout | [model.Block.Content.Widget.Layout](#anytype-model-Block-Content-Widget-Layout) | | | +| block | [model.Block](#anytype.model.Block) | | | +| position | [model.Block.Position](#anytype.model.Block.Position) | | | +| widgetLayout | [model.Block.Content.Widget.Layout](#anytype.model.Block.Content.Widget.Layout) | | | - + ### Rpc.Block.CreateWidget.Response @@ -2693,16 +2693,16 @@ common simple block command | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.CreateWidget.Response.Error](#anytype-Rpc-Block-CreateWidget-Response-Error) | | | +| error | [Rpc.Block.CreateWidget.Response.Error](#anytype.Rpc.Block.CreateWidget.Response.Error) | | | | blockId | [string](#string) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.CreateWidget.Response.Error @@ -2710,7 +2710,7 @@ common simple block command | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.CreateWidget.Response.Error.Code](#anytype-Rpc-Block-CreateWidget-Response-Error-Code) | | | +| code | [Rpc.Block.CreateWidget.Response.Error.Code](#anytype.Rpc.Block.CreateWidget.Response.Error.Code) | | | | description | [string](#string) | | | @@ -2718,7 +2718,7 @@ common simple block command - + ### Rpc.Block.Cut @@ -2728,7 +2728,7 @@ common simple block command - + ### Rpc.Block.Cut.Request @@ -2737,15 +2737,15 @@ common simple block command | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | -| blocks | [model.Block](#anytype-model-Block) | repeated | | -| selectedTextRange | [model.Range](#anytype-model-Range) | | | +| blocks | [model.Block](#anytype.model.Block) | repeated | | +| selectedTextRange | [model.Range](#anytype.model.Range) | | | - + ### Rpc.Block.Cut.Response @@ -2753,18 +2753,18 @@ common simple block command | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.Cut.Response.Error](#anytype-Rpc-Block-Cut-Response-Error) | | | +| error | [Rpc.Block.Cut.Response.Error](#anytype.Rpc.Block.Cut.Response.Error) | | | | textSlot | [string](#string) | | | | htmlSlot | [string](#string) | | | -| anySlot | [model.Block](#anytype-model-Block) | repeated | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| anySlot | [model.Block](#anytype.model.Block) | repeated | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.Cut.Response.Error @@ -2772,7 +2772,7 @@ common simple block command | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.Cut.Response.Error.Code](#anytype-Rpc-Block-Cut-Response-Error-Code) | | | +| code | [Rpc.Block.Cut.Response.Error.Code](#anytype.Rpc.Block.Cut.Response.Error.Code) | | | | description | [string](#string) | | | @@ -2780,7 +2780,7 @@ common simple block command - + ### Rpc.Block.Download @@ -2790,7 +2790,7 @@ common simple block command - + ### Rpc.Block.Download.Request @@ -2806,7 +2806,7 @@ common simple block command - + ### Rpc.Block.Download.Response @@ -2814,15 +2814,15 @@ common simple block command | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.Download.Response.Error](#anytype-Rpc-Block-Download-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.Block.Download.Response.Error](#anytype.Rpc.Block.Download.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.Download.Response.Error @@ -2830,7 +2830,7 @@ common simple block command | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.Download.Response.Error.Code](#anytype-Rpc-Block-Download-Response-Error-Code) | | | +| code | [Rpc.Block.Download.Response.Error.Code](#anytype.Rpc.Block.Download.Response.Error.Code) | | | | description | [string](#string) | | | @@ -2838,7 +2838,7 @@ common simple block command - + ### Rpc.Block.Export @@ -2848,7 +2848,7 @@ common simple block command - + ### Rpc.Block.Export.Request @@ -2857,14 +2857,14 @@ common simple block command | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | -| blocks | [model.Block](#anytype-model-Block) | repeated | | +| blocks | [model.Block](#anytype.model.Block) | repeated | | - + ### Rpc.Block.Export.Response @@ -2872,16 +2872,16 @@ common simple block command | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.Export.Response.Error](#anytype-Rpc-Block-Export-Response-Error) | | | +| error | [Rpc.Block.Export.Response.Error](#anytype.Rpc.Block.Export.Response.Error) | | | | path | [string](#string) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.Export.Response.Error @@ -2889,7 +2889,7 @@ common simple block command | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.Export.Response.Error.Code](#anytype-Rpc-Block-Export-Response-Error-Code) | | | +| code | [Rpc.Block.Export.Response.Error.Code](#anytype.Rpc.Block.Export.Response.Error.Code) | | | | description | [string](#string) | | | @@ -2897,7 +2897,7 @@ common simple block command - + ### Rpc.Block.ListConvertToObjects @@ -2907,7 +2907,7 @@ common simple block command - + ### Rpc.Block.ListConvertToObjects.Request @@ -2924,7 +2924,7 @@ common simple block command - + ### Rpc.Block.ListConvertToObjects.Response @@ -2932,16 +2932,16 @@ common simple block command | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.ListConvertToObjects.Response.Error](#anytype-Rpc-Block-ListConvertToObjects-Response-Error) | | | +| error | [Rpc.Block.ListConvertToObjects.Response.Error](#anytype.Rpc.Block.ListConvertToObjects.Response.Error) | | | | linkIds | [string](#string) | repeated | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.ListConvertToObjects.Response.Error @@ -2949,7 +2949,7 @@ common simple block command | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.ListConvertToObjects.Response.Error.Code](#anytype-Rpc-Block-ListConvertToObjects-Response-Error-Code) | | | +| code | [Rpc.Block.ListConvertToObjects.Response.Error.Code](#anytype.Rpc.Block.ListConvertToObjects.Response.Error.Code) | | | | description | [string](#string) | | | @@ -2957,7 +2957,7 @@ common simple block command - + ### Rpc.Block.ListDelete Remove blocks from the childrenIds of its parents @@ -2967,7 +2967,7 @@ Remove blocks from the childrenIds of its parents - + ### Rpc.Block.ListDelete.Request @@ -2983,7 +2983,7 @@ Remove blocks from the childrenIds of its parents - + ### Rpc.Block.ListDelete.Response @@ -2991,15 +2991,15 @@ Remove blocks from the childrenIds of its parents | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.ListDelete.Response.Error](#anytype-Rpc-Block-ListDelete-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.Block.ListDelete.Response.Error](#anytype.Rpc.Block.ListDelete.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.ListDelete.Response.Error @@ -3007,7 +3007,7 @@ Remove blocks from the childrenIds of its parents | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.ListDelete.Response.Error.Code](#anytype-Rpc-Block-ListDelete-Response-Error-Code) | | | +| code | [Rpc.Block.ListDelete.Response.Error.Code](#anytype.Rpc.Block.ListDelete.Response.Error.Code) | | | | description | [string](#string) | | | @@ -3015,7 +3015,7 @@ Remove blocks from the childrenIds of its parents - + ### Rpc.Block.ListDuplicate Makes blocks copy by given ids and paste it to shown place @@ -3025,7 +3025,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.ListDuplicate.Request @@ -3036,7 +3036,7 @@ Makes blocks copy by given ids and paste it to shown place | contextId | [string](#string) | | id of the context object | | targetId | [string](#string) | | id of the closest block | | blockIds | [string](#string) | repeated | id of block for duplicate | -| position | [model.Block.Position](#anytype-model-Block-Position) | | | +| position | [model.Block.Position](#anytype.model.Block.Position) | | | | targetContextId | [string](#string) | | | @@ -3044,7 +3044,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.ListDuplicate.Response @@ -3052,16 +3052,16 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.ListDuplicate.Response.Error](#anytype-Rpc-Block-ListDuplicate-Response-Error) | | | +| error | [Rpc.Block.ListDuplicate.Response.Error](#anytype.Rpc.Block.ListDuplicate.Response.Error) | | | | blockIds | [string](#string) | repeated | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.ListDuplicate.Response.Error @@ -3069,7 +3069,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.ListDuplicate.Response.Error.Code](#anytype-Rpc-Block-ListDuplicate-Response-Error-Code) | | | +| code | [Rpc.Block.ListDuplicate.Response.Error.Code](#anytype.Rpc.Block.ListDuplicate.Response.Error.Code) | | | | description | [string](#string) | | | @@ -3077,7 +3077,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.ListMoveToExistingObject @@ -3087,7 +3087,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.ListMoveToExistingObject.Request @@ -3099,14 +3099,14 @@ Makes blocks copy by given ids and paste it to shown place | blockIds | [string](#string) | repeated | | | targetContextId | [string](#string) | | | | dropTargetId | [string](#string) | | id of the simple block to insert considering position | -| position | [model.Block.Position](#anytype-model-Block-Position) | | position relatively to the dropTargetId simple block | +| position | [model.Block.Position](#anytype.model.Block.Position) | | position relatively to the dropTargetId simple block | - + ### Rpc.Block.ListMoveToExistingObject.Response @@ -3114,15 +3114,15 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.ListMoveToExistingObject.Response.Error](#anytype-Rpc-Block-ListMoveToExistingObject-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.Block.ListMoveToExistingObject.Response.Error](#anytype.Rpc.Block.ListMoveToExistingObject.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.ListMoveToExistingObject.Response.Error @@ -3130,7 +3130,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.ListMoveToExistingObject.Response.Error.Code](#anytype-Rpc-Block-ListMoveToExistingObject-Response-Error-Code) | | | +| code | [Rpc.Block.ListMoveToExistingObject.Response.Error.Code](#anytype.Rpc.Block.ListMoveToExistingObject.Response.Error.Code) | | | | description | [string](#string) | | | @@ -3138,7 +3138,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.ListMoveToNewObject @@ -3148,7 +3148,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.ListMoveToNewObject.Request @@ -3158,16 +3158,16 @@ Makes blocks copy by given ids and paste it to shown place | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | blockIds | [string](#string) | repeated | | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | new object details | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | new object details | | dropTargetId | [string](#string) | | id of the simple block to insert considering position | -| position | [model.Block.Position](#anytype-model-Block-Position) | | position relatively to the dropTargetId simple block | +| position | [model.Block.Position](#anytype.model.Block.Position) | | position relatively to the dropTargetId simple block | - + ### Rpc.Block.ListMoveToNewObject.Response @@ -3175,16 +3175,16 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.ListMoveToNewObject.Response.Error](#anytype-Rpc-Block-ListMoveToNewObject-Response-Error) | | | +| error | [Rpc.Block.ListMoveToNewObject.Response.Error](#anytype.Rpc.Block.ListMoveToNewObject.Response.Error) | | | | linkId | [string](#string) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.ListMoveToNewObject.Response.Error @@ -3192,7 +3192,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.ListMoveToNewObject.Response.Error.Code](#anytype-Rpc-Block-ListMoveToNewObject-Response-Error-Code) | | | +| code | [Rpc.Block.ListMoveToNewObject.Response.Error.Code](#anytype.Rpc.Block.ListMoveToNewObject.Response.Error.Code) | | | | description | [string](#string) | | | @@ -3200,7 +3200,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.ListSetAlign @@ -3210,7 +3210,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.ListSetAlign.Request @@ -3220,14 +3220,14 @@ Makes blocks copy by given ids and paste it to shown place | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | blockIds | [string](#string) | repeated | when empty - align will be applied as layoutAlign | -| align | [model.Block.Align](#anytype-model-Block-Align) | | | +| align | [model.Block.Align](#anytype.model.Block.Align) | | | - + ### Rpc.Block.ListSetAlign.Response @@ -3235,15 +3235,15 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.ListSetAlign.Response.Error](#anytype-Rpc-Block-ListSetAlign-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.Block.ListSetAlign.Response.Error](#anytype.Rpc.Block.ListSetAlign.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.ListSetAlign.Response.Error @@ -3251,7 +3251,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.ListSetAlign.Response.Error.Code](#anytype-Rpc-Block-ListSetAlign-Response-Error-Code) | | | +| code | [Rpc.Block.ListSetAlign.Response.Error.Code](#anytype.Rpc.Block.ListSetAlign.Response.Error.Code) | | | | description | [string](#string) | | | @@ -3259,7 +3259,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.ListSetBackgroundColor @@ -3269,7 +3269,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.ListSetBackgroundColor.Request @@ -3286,7 +3286,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.ListSetBackgroundColor.Response @@ -3294,15 +3294,15 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.ListSetBackgroundColor.Response.Error](#anytype-Rpc-Block-ListSetBackgroundColor-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.Block.ListSetBackgroundColor.Response.Error](#anytype.Rpc.Block.ListSetBackgroundColor.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.ListSetBackgroundColor.Response.Error @@ -3310,7 +3310,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.ListSetBackgroundColor.Response.Error.Code](#anytype-Rpc-Block-ListSetBackgroundColor-Response-Error-Code) | | | +| code | [Rpc.Block.ListSetBackgroundColor.Response.Error.Code](#anytype.Rpc.Block.ListSetBackgroundColor.Response.Error.Code) | | | | description | [string](#string) | | | @@ -3318,7 +3318,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.ListSetFields @@ -3328,7 +3328,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.ListSetFields.Request @@ -3337,14 +3337,14 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | -| blockFields | [Rpc.Block.ListSetFields.Request.BlockField](#anytype-Rpc-Block-ListSetFields-Request-BlockField) | repeated | | +| blockFields | [Rpc.Block.ListSetFields.Request.BlockField](#anytype.Rpc.Block.ListSetFields.Request.BlockField) | repeated | | - + ### Rpc.Block.ListSetFields.Request.BlockField @@ -3353,14 +3353,14 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | blockId | [string](#string) | | | -| fields | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| fields | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### Rpc.Block.ListSetFields.Response @@ -3368,15 +3368,15 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.ListSetFields.Response.Error](#anytype-Rpc-Block-ListSetFields-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.Block.ListSetFields.Response.Error](#anytype.Rpc.Block.ListSetFields.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.ListSetFields.Response.Error @@ -3384,7 +3384,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.ListSetFields.Response.Error.Code](#anytype-Rpc-Block-ListSetFields-Response-Error-Code) | | | +| code | [Rpc.Block.ListSetFields.Response.Error.Code](#anytype.Rpc.Block.ListSetFields.Response.Error.Code) | | | | description | [string](#string) | | | @@ -3392,7 +3392,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.ListSetVerticalAlign @@ -3402,7 +3402,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.ListSetVerticalAlign.Request @@ -3412,14 +3412,14 @@ Makes blocks copy by given ids and paste it to shown place | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | id of the context object | | blockIds | [string](#string) | repeated | | -| verticalAlign | [model.Block.VerticalAlign](#anytype-model-Block-VerticalAlign) | | | +| verticalAlign | [model.Block.VerticalAlign](#anytype.model.Block.VerticalAlign) | | | - + ### Rpc.Block.ListSetVerticalAlign.Response @@ -3427,15 +3427,15 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.ListSetVerticalAlign.Response.Error](#anytype-Rpc-Block-ListSetVerticalAlign-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.Block.ListSetVerticalAlign.Response.Error](#anytype.Rpc.Block.ListSetVerticalAlign.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.ListSetVerticalAlign.Response.Error @@ -3443,7 +3443,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.ListSetVerticalAlign.Response.Error.Code](#anytype-Rpc-Block-ListSetVerticalAlign-Response-Error-Code) | | | +| code | [Rpc.Block.ListSetVerticalAlign.Response.Error.Code](#anytype.Rpc.Block.ListSetVerticalAlign.Response.Error.Code) | | | | description | [string](#string) | | | @@ -3451,7 +3451,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.ListTurnInto @@ -3461,7 +3461,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.ListTurnInto.Request @@ -3471,14 +3471,14 @@ Makes blocks copy by given ids and paste it to shown place | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | blockIds | [string](#string) | repeated | | -| style | [model.Block.Content.Text.Style](#anytype-model-Block-Content-Text-Style) | | | +| style | [model.Block.Content.Text.Style](#anytype.model.Block.Content.Text.Style) | | | - + ### Rpc.Block.ListTurnInto.Response @@ -3486,15 +3486,15 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.ListTurnInto.Response.Error](#anytype-Rpc-Block-ListTurnInto-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.Block.ListTurnInto.Response.Error](#anytype.Rpc.Block.ListTurnInto.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.ListTurnInto.Response.Error @@ -3502,7 +3502,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.ListTurnInto.Response.Error.Code](#anytype-Rpc-Block-ListTurnInto-Response-Error-Code) | | | +| code | [Rpc.Block.ListTurnInto.Response.Error.Code](#anytype.Rpc.Block.ListTurnInto.Response.Error.Code) | | | | description | [string](#string) | | | @@ -3510,7 +3510,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.ListUpdate @@ -3520,7 +3520,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.ListUpdate.Request @@ -3530,19 +3530,19 @@ Makes blocks copy by given ids and paste it to shown place | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | blockIds | [string](#string) | repeated | | -| text | [Rpc.Block.ListUpdate.Request.Text](#anytype-Rpc-Block-ListUpdate-Request-Text) | | | +| text | [Rpc.Block.ListUpdate.Request.Text](#anytype.Rpc.Block.ListUpdate.Request.Text) | | | | backgroundColor | [string](#string) | | | -| align | [model.Block.Align](#anytype-model-Block-Align) | | | -| fields | [google.protobuf.Struct](#google-protobuf-Struct) | | | -| divStyle | [model.Block.Content.Div.Style](#anytype-model-Block-Content-Div-Style) | | | -| fileStyle | [model.Block.Content.File.Style](#anytype-model-Block-Content-File-Style) | | | +| align | [model.Block.Align](#anytype.model.Block.Align) | | | +| fields | [google.protobuf.Struct](#google.protobuf.Struct) | | | +| divStyle | [model.Block.Content.Div.Style](#anytype.model.Block.Content.Div.Style) | | | +| fileStyle | [model.Block.Content.File.Style](#anytype.model.Block.Content.File.Style) | | | - + ### Rpc.Block.ListUpdate.Request.Text @@ -3550,16 +3550,16 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| style | [model.Block.Content.Text.Style](#anytype-model-Block-Content-Text-Style) | | | +| style | [model.Block.Content.Text.Style](#anytype.model.Block.Content.Text.Style) | | | | color | [string](#string) | | | -| mark | [model.Block.Content.Text.Mark](#anytype-model-Block-Content-Text-Mark) | | | +| mark | [model.Block.Content.Text.Mark](#anytype.model.Block.Content.Text.Mark) | | | - + ### Rpc.Block.Merge @@ -3569,7 +3569,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.Merge.Request @@ -3586,7 +3586,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.Merge.Response @@ -3594,15 +3594,15 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.Merge.Response.Error](#anytype-Rpc-Block-Merge-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.Block.Merge.Response.Error](#anytype.Rpc.Block.Merge.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.Merge.Response.Error @@ -3610,7 +3610,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.Merge.Response.Error.Code](#anytype-Rpc-Block-Merge-Response-Error-Code) | | | +| code | [Rpc.Block.Merge.Response.Error.Code](#anytype.Rpc.Block.Merge.Response.Error.Code) | | | | description | [string](#string) | | | @@ -3618,7 +3618,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.Paste @@ -3628,7 +3628,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.Paste.Request @@ -3638,20 +3638,20 @@ Makes blocks copy by given ids and paste it to shown place | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | focusedBlockId | [string](#string) | | | -| selectedTextRange | [model.Range](#anytype-model-Range) | | | +| selectedTextRange | [model.Range](#anytype.model.Range) | | | | selectedBlockIds | [string](#string) | repeated | | | isPartOfBlock | [bool](#bool) | | | | textSlot | [string](#string) | | | | htmlSlot | [string](#string) | | | -| anySlot | [model.Block](#anytype-model-Block) | repeated | | -| fileSlot | [Rpc.Block.Paste.Request.File](#anytype-Rpc-Block-Paste-Request-File) | repeated | | +| anySlot | [model.Block](#anytype.model.Block) | repeated | | +| fileSlot | [Rpc.Block.Paste.Request.File](#anytype.Rpc.Block.Paste.Request.File) | repeated | | - + ### Rpc.Block.Paste.Request.File @@ -3668,7 +3668,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.Paste.Response @@ -3676,18 +3676,18 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.Paste.Response.Error](#anytype-Rpc-Block-Paste-Response-Error) | | | +| error | [Rpc.Block.Paste.Response.Error](#anytype.Rpc.Block.Paste.Response.Error) | | | | blockIds | [string](#string) | repeated | | | caretPosition | [int32](#int32) | | | | isSameBlockCaret | [bool](#bool) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.Paste.Response.Error @@ -3695,7 +3695,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.Paste.Response.Error.Code](#anytype-Rpc-Block-Paste-Response-Error-Code) | | | +| code | [Rpc.Block.Paste.Response.Error.Code](#anytype.Rpc.Block.Paste.Response.Error.Code) | | | | description | [string](#string) | | | @@ -3703,7 +3703,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.Replace @@ -3713,7 +3713,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.Replace.Request @@ -3723,14 +3723,14 @@ Makes blocks copy by given ids and paste it to shown place | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | blockId | [string](#string) | | | -| block | [model.Block](#anytype-model-Block) | | | +| block | [model.Block](#anytype.model.Block) | | | - + ### Rpc.Block.Replace.Response @@ -3738,16 +3738,16 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.Replace.Response.Error](#anytype-Rpc-Block-Replace-Response-Error) | | | +| error | [Rpc.Block.Replace.Response.Error](#anytype.Rpc.Block.Replace.Response.Error) | | | | blockId | [string](#string) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.Replace.Response.Error @@ -3755,7 +3755,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.Replace.Response.Error.Code](#anytype-Rpc-Block-Replace-Response-Error-Code) | | | +| code | [Rpc.Block.Replace.Response.Error.Code](#anytype.Rpc.Block.Replace.Response.Error.Code) | | | | description | [string](#string) | | | @@ -3763,7 +3763,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.SetFields @@ -3773,7 +3773,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.SetFields.Request @@ -3783,14 +3783,14 @@ Makes blocks copy by given ids and paste it to shown place | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | blockId | [string](#string) | | | -| fields | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| fields | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### Rpc.Block.SetFields.Response @@ -3798,15 +3798,15 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.SetFields.Response.Error](#anytype-Rpc-Block-SetFields-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.Block.SetFields.Response.Error](#anytype.Rpc.Block.SetFields.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.SetFields.Response.Error @@ -3814,7 +3814,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.SetFields.Response.Error.Code](#anytype-Rpc-Block-SetFields-Response-Error-Code) | | | +| code | [Rpc.Block.SetFields.Response.Error.Code](#anytype.Rpc.Block.SetFields.Response.Error.Code) | | | | description | [string](#string) | | | @@ -3822,7 +3822,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.Split @@ -3832,7 +3832,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.Split.Request @@ -3842,16 +3842,16 @@ Makes blocks copy by given ids and paste it to shown place | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | blockId | [string](#string) | | | -| range | [model.Range](#anytype-model-Range) | | | -| style | [model.Block.Content.Text.Style](#anytype-model-Block-Content-Text-Style) | | | -| mode | [Rpc.Block.Split.Request.Mode](#anytype-Rpc-Block-Split-Request-Mode) | | | +| range | [model.Range](#anytype.model.Range) | | | +| style | [model.Block.Content.Text.Style](#anytype.model.Block.Content.Text.Style) | | | +| mode | [Rpc.Block.Split.Request.Mode](#anytype.Rpc.Block.Split.Request.Mode) | | | - + ### Rpc.Block.Split.Response @@ -3859,16 +3859,16 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.Split.Response.Error](#anytype-Rpc-Block-Split-Response-Error) | | | +| error | [Rpc.Block.Split.Response.Error](#anytype.Rpc.Block.Split.Response.Error) | | | | blockId | [string](#string) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.Split.Response.Error @@ -3876,7 +3876,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.Split.Response.Error.Code](#anytype-Rpc-Block-Split-Response-Error-Code) | | | +| code | [Rpc.Block.Split.Response.Error.Code](#anytype.Rpc.Block.Split.Response.Error.Code) | | | | description | [string](#string) | | | @@ -3884,7 +3884,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.Upload @@ -3894,7 +3894,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.Upload.Request @@ -3912,7 +3912,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.Block.Upload.Response @@ -3920,15 +3920,15 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Block.Upload.Response.Error](#anytype-Rpc-Block-Upload-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.Block.Upload.Response.Error](#anytype.Rpc.Block.Upload.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Block.Upload.Response.Error @@ -3936,7 +3936,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Block.Upload.Response.Error.Code](#anytype-Rpc-Block-Upload-Response-Error-Code) | | | +| code | [Rpc.Block.Upload.Response.Error.Code](#anytype.Rpc.Block.Upload.Response.Error.Code) | | | | description | [string](#string) | | | @@ -3944,7 +3944,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockBookmark @@ -3954,7 +3954,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockBookmark.CreateAndFetch @@ -3964,7 +3964,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockBookmark.CreateAndFetch.Request @@ -3974,7 +3974,7 @@ Makes blocks copy by given ids and paste it to shown place | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | targetId | [string](#string) | | | -| position | [model.Block.Position](#anytype-model-Block-Position) | | | +| position | [model.Block.Position](#anytype.model.Block.Position) | | | | url | [string](#string) | | | @@ -3982,7 +3982,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockBookmark.CreateAndFetch.Response @@ -3990,16 +3990,16 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockBookmark.CreateAndFetch.Response.Error](#anytype-Rpc-BlockBookmark-CreateAndFetch-Response-Error) | | | +| error | [Rpc.BlockBookmark.CreateAndFetch.Response.Error](#anytype.Rpc.BlockBookmark.CreateAndFetch.Response.Error) | | | | blockId | [string](#string) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockBookmark.CreateAndFetch.Response.Error @@ -4007,7 +4007,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockBookmark.CreateAndFetch.Response.Error.Code](#anytype-Rpc-BlockBookmark-CreateAndFetch-Response-Error-Code) | | | +| code | [Rpc.BlockBookmark.CreateAndFetch.Response.Error.Code](#anytype.Rpc.BlockBookmark.CreateAndFetch.Response.Error.Code) | | | | description | [string](#string) | | | @@ -4015,7 +4015,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockBookmark.Fetch @@ -4025,7 +4025,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockBookmark.Fetch.Request @@ -4042,7 +4042,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockBookmark.Fetch.Response @@ -4050,15 +4050,15 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockBookmark.Fetch.Response.Error](#anytype-Rpc-BlockBookmark-Fetch-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockBookmark.Fetch.Response.Error](#anytype.Rpc.BlockBookmark.Fetch.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockBookmark.Fetch.Response.Error @@ -4066,7 +4066,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockBookmark.Fetch.Response.Error.Code](#anytype-Rpc-BlockBookmark-Fetch-Response-Error-Code) | | | +| code | [Rpc.BlockBookmark.Fetch.Response.Error.Code](#anytype.Rpc.BlockBookmark.Fetch.Response.Error.Code) | | | | description | [string](#string) | | | @@ -4074,7 +4074,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview @@ -4084,7 +4084,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.CreateBookmark @@ -4094,7 +4094,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.CreateBookmark.Request @@ -4111,7 +4111,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.CreateBookmark.Response @@ -4119,7 +4119,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockDataview.CreateBookmark.Response.Error](#anytype-Rpc-BlockDataview-CreateBookmark-Response-Error) | | | +| error | [Rpc.BlockDataview.CreateBookmark.Response.Error](#anytype.Rpc.BlockDataview.CreateBookmark.Response.Error) | | | | id | [string](#string) | | | @@ -4127,7 +4127,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.CreateBookmark.Response.Error @@ -4135,7 +4135,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockDataview.CreateBookmark.Response.Error.Code](#anytype-Rpc-BlockDataview-CreateBookmark-Response-Error-Code) | | | +| code | [Rpc.BlockDataview.CreateBookmark.Response.Error.Code](#anytype.Rpc.BlockDataview.CreateBookmark.Response.Error.Code) | | | | description | [string](#string) | | | @@ -4143,7 +4143,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.GroupOrder @@ -4153,7 +4153,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.GroupOrder.Update @@ -4163,7 +4163,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.GroupOrder.Update.Request @@ -4173,14 +4173,14 @@ Makes blocks copy by given ids and paste it to shown place | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | blockId | [string](#string) | | | -| groupOrder | [model.Block.Content.Dataview.GroupOrder](#anytype-model-Block-Content-Dataview-GroupOrder) | | | +| groupOrder | [model.Block.Content.Dataview.GroupOrder](#anytype.model.Block.Content.Dataview.GroupOrder) | | | - + ### Rpc.BlockDataview.GroupOrder.Update.Response @@ -4188,15 +4188,15 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockDataview.GroupOrder.Update.Response.Error](#anytype-Rpc-BlockDataview-GroupOrder-Update-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockDataview.GroupOrder.Update.Response.Error](#anytype.Rpc.BlockDataview.GroupOrder.Update.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockDataview.GroupOrder.Update.Response.Error @@ -4204,7 +4204,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockDataview.GroupOrder.Update.Response.Error.Code](#anytype-Rpc-BlockDataview-GroupOrder-Update-Response-Error-Code) | | | +| code | [Rpc.BlockDataview.GroupOrder.Update.Response.Error.Code](#anytype.Rpc.BlockDataview.GroupOrder.Update.Response.Error.Code) | | | | description | [string](#string) | | | @@ -4212,7 +4212,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.ObjectOrder @@ -4222,7 +4222,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.ObjectOrder.Update @@ -4232,7 +4232,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.ObjectOrder.Update.Request @@ -4242,14 +4242,14 @@ Makes blocks copy by given ids and paste it to shown place | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | blockId | [string](#string) | | | -| objectOrders | [model.Block.Content.Dataview.ObjectOrder](#anytype-model-Block-Content-Dataview-ObjectOrder) | repeated | | +| objectOrders | [model.Block.Content.Dataview.ObjectOrder](#anytype.model.Block.Content.Dataview.ObjectOrder) | repeated | | - + ### Rpc.BlockDataview.ObjectOrder.Update.Response @@ -4257,15 +4257,15 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockDataview.ObjectOrder.Update.Response.Error](#anytype-Rpc-BlockDataview-ObjectOrder-Update-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockDataview.ObjectOrder.Update.Response.Error](#anytype.Rpc.BlockDataview.ObjectOrder.Update.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockDataview.ObjectOrder.Update.Response.Error @@ -4273,7 +4273,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockDataview.ObjectOrder.Update.Response.Error.Code](#anytype-Rpc-BlockDataview-ObjectOrder-Update-Response-Error-Code) | | | +| code | [Rpc.BlockDataview.ObjectOrder.Update.Response.Error.Code](#anytype.Rpc.BlockDataview.ObjectOrder.Update.Response.Error.Code) | | | | description | [string](#string) | | | @@ -4281,7 +4281,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.Relation @@ -4291,7 +4291,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.Relation.Add @@ -4301,7 +4301,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.Relation.Add.Request @@ -4318,7 +4318,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.Relation.Add.Response @@ -4326,15 +4326,15 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockDataview.Relation.Add.Response.Error](#anytype-Rpc-BlockDataview-Relation-Add-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockDataview.Relation.Add.Response.Error](#anytype.Rpc.BlockDataview.Relation.Add.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockDataview.Relation.Add.Response.Error @@ -4342,7 +4342,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockDataview.Relation.Add.Response.Error.Code](#anytype-Rpc-BlockDataview-Relation-Add-Response-Error-Code) | | | +| code | [Rpc.BlockDataview.Relation.Add.Response.Error.Code](#anytype.Rpc.BlockDataview.Relation.Add.Response.Error.Code) | | | | description | [string](#string) | | | @@ -4350,7 +4350,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.Relation.Delete @@ -4360,7 +4360,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.Relation.Delete.Request @@ -4377,7 +4377,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.Relation.Delete.Response @@ -4385,15 +4385,15 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockDataview.Relation.Delete.Response.Error](#anytype-Rpc-BlockDataview-Relation-Delete-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockDataview.Relation.Delete.Response.Error](#anytype.Rpc.BlockDataview.Relation.Delete.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockDataview.Relation.Delete.Response.Error @@ -4401,7 +4401,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockDataview.Relation.Delete.Response.Error.Code](#anytype-Rpc-BlockDataview-Relation-Delete-Response-Error-Code) | | | +| code | [Rpc.BlockDataview.Relation.Delete.Response.Error.Code](#anytype.Rpc.BlockDataview.Relation.Delete.Response.Error.Code) | | | | description | [string](#string) | | | @@ -4409,7 +4409,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.Relation.ListAvailable @@ -4419,7 +4419,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.Relation.ListAvailable.Request @@ -4435,7 +4435,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.Relation.ListAvailable.Response @@ -4443,15 +4443,15 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockDataview.Relation.ListAvailable.Response.Error](#anytype-Rpc-BlockDataview-Relation-ListAvailable-Response-Error) | | | -| relations | [model.Relation](#anytype-model-Relation) | repeated | | +| error | [Rpc.BlockDataview.Relation.ListAvailable.Response.Error](#anytype.Rpc.BlockDataview.Relation.ListAvailable.Response.Error) | | | +| relations | [model.Relation](#anytype.model.Relation) | repeated | | - + ### Rpc.BlockDataview.Relation.ListAvailable.Response.Error @@ -4459,7 +4459,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockDataview.Relation.ListAvailable.Response.Error.Code](#anytype-Rpc-BlockDataview-Relation-ListAvailable-Response-Error-Code) | | | +| code | [Rpc.BlockDataview.Relation.ListAvailable.Response.Error.Code](#anytype.Rpc.BlockDataview.Relation.ListAvailable.Response.Error.Code) | | | | description | [string](#string) | | | @@ -4467,7 +4467,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.SetSource @@ -4477,7 +4477,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.SetSource.Request @@ -4494,7 +4494,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.SetSource.Response @@ -4502,15 +4502,15 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockDataview.SetSource.Response.Error](#anytype-Rpc-BlockDataview-SetSource-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockDataview.SetSource.Response.Error](#anytype.Rpc.BlockDataview.SetSource.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockDataview.SetSource.Response.Error @@ -4518,7 +4518,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockDataview.SetSource.Response.Error.Code](#anytype-Rpc-BlockDataview-SetSource-Response-Error-Code) | | | +| code | [Rpc.BlockDataview.SetSource.Response.Error.Code](#anytype.Rpc.BlockDataview.SetSource.Response.Error.Code) | | | | description | [string](#string) | | | @@ -4526,7 +4526,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.View @@ -4536,7 +4536,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.View.Create @@ -4546,7 +4546,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.View.Create.Request @@ -4556,14 +4556,14 @@ Makes blocks copy by given ids and paste it to shown place | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | blockId | [string](#string) | | id of dataview block to insert the new block | -| view | [model.Block.Content.Dataview.View](#anytype-model-Block-Content-Dataview-View) | | | +| view | [model.Block.Content.Dataview.View](#anytype.model.Block.Content.Dataview.View) | | | - + ### Rpc.BlockDataview.View.Create.Response @@ -4571,8 +4571,8 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockDataview.View.Create.Response.Error](#anytype-Rpc-BlockDataview-View-Create-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockDataview.View.Create.Response.Error](#anytype.Rpc.BlockDataview.View.Create.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | | viewId | [string](#string) | | | @@ -4580,7 +4580,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.View.Create.Response.Error @@ -4588,7 +4588,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockDataview.View.Create.Response.Error.Code](#anytype-Rpc-BlockDataview-View-Create-Response-Error-Code) | | | +| code | [Rpc.BlockDataview.View.Create.Response.Error.Code](#anytype.Rpc.BlockDataview.View.Create.Response.Error.Code) | | | | description | [string](#string) | | | @@ -4596,7 +4596,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.View.Delete @@ -4606,7 +4606,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.View.Delete.Request @@ -4623,7 +4623,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.View.Delete.Response @@ -4631,15 +4631,15 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockDataview.View.Delete.Response.Error](#anytype-Rpc-BlockDataview-View-Delete-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockDataview.View.Delete.Response.Error](#anytype.Rpc.BlockDataview.View.Delete.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockDataview.View.Delete.Response.Error @@ -4647,7 +4647,7 @@ Makes blocks copy by given ids and paste it to shown place | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockDataview.View.Delete.Response.Error.Code](#anytype-Rpc-BlockDataview-View-Delete-Response-Error-Code) | | | +| code | [Rpc.BlockDataview.View.Delete.Response.Error.Code](#anytype.Rpc.BlockDataview.View.Delete.Response.Error.Code) | | | | description | [string](#string) | | | @@ -4655,7 +4655,7 @@ Makes blocks copy by given ids and paste it to shown place - + ### Rpc.BlockDataview.View.SetActive set the current active view (persisted only within a session) @@ -4665,7 +4665,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockDataview.View.SetActive.Request @@ -4684,7 +4684,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockDataview.View.SetActive.Response @@ -4692,15 +4692,15 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockDataview.View.SetActive.Response.Error](#anytype-Rpc-BlockDataview-View-SetActive-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockDataview.View.SetActive.Response.Error](#anytype.Rpc.BlockDataview.View.SetActive.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockDataview.View.SetActive.Response.Error @@ -4708,7 +4708,7 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockDataview.View.SetActive.Response.Error.Code](#anytype-Rpc-BlockDataview-View-SetActive-Response-Error-Code) | | | +| code | [Rpc.BlockDataview.View.SetActive.Response.Error.Code](#anytype.Rpc.BlockDataview.View.SetActive.Response.Error.Code) | | | | description | [string](#string) | | | @@ -4716,7 +4716,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockDataview.View.SetPosition @@ -4726,7 +4726,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockDataview.View.SetPosition.Request @@ -4744,7 +4744,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockDataview.View.SetPosition.Response @@ -4752,15 +4752,15 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockDataview.View.SetPosition.Response.Error](#anytype-Rpc-BlockDataview-View-SetPosition-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockDataview.View.SetPosition.Response.Error](#anytype.Rpc.BlockDataview.View.SetPosition.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockDataview.View.SetPosition.Response.Error @@ -4768,7 +4768,7 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockDataview.View.SetPosition.Response.Error.Code](#anytype-Rpc-BlockDataview-View-SetPosition-Response-Error-Code) | | | +| code | [Rpc.BlockDataview.View.SetPosition.Response.Error.Code](#anytype.Rpc.BlockDataview.View.SetPosition.Response.Error.Code) | | | | description | [string](#string) | | | @@ -4776,7 +4776,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockDataview.View.Update @@ -4786,7 +4786,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockDataview.View.Update.Request @@ -4797,14 +4797,14 @@ set the current active view (persisted only within a session) | contextId | [string](#string) | | | | blockId | [string](#string) | | id of dataview block to update | | viewId | [string](#string) | | id of view to update | -| view | [model.Block.Content.Dataview.View](#anytype-model-Block-Content-Dataview-View) | | | +| view | [model.Block.Content.Dataview.View](#anytype.model.Block.Content.Dataview.View) | | | - + ### Rpc.BlockDataview.View.Update.Response @@ -4812,15 +4812,15 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockDataview.View.Update.Response.Error](#anytype-Rpc-BlockDataview-View-Update-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockDataview.View.Update.Response.Error](#anytype.Rpc.BlockDataview.View.Update.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockDataview.View.Update.Response.Error @@ -4828,7 +4828,7 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockDataview.View.Update.Response.Error.Code](#anytype-Rpc-BlockDataview-View-Update-Response-Error-Code) | | | +| code | [Rpc.BlockDataview.View.Update.Response.Error.Code](#anytype.Rpc.BlockDataview.View.Update.Response.Error.Code) | | | | description | [string](#string) | | | @@ -4836,7 +4836,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockDiv @@ -4846,7 +4846,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockDiv.ListSetStyle @@ -4856,7 +4856,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockDiv.ListSetStyle.Request @@ -4866,14 +4866,14 @@ set the current active view (persisted only within a session) | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | blockIds | [string](#string) | repeated | | -| style | [model.Block.Content.Div.Style](#anytype-model-Block-Content-Div-Style) | | | +| style | [model.Block.Content.Div.Style](#anytype.model.Block.Content.Div.Style) | | | - + ### Rpc.BlockDiv.ListSetStyle.Response @@ -4881,15 +4881,15 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockDiv.ListSetStyle.Response.Error](#anytype-Rpc-BlockDiv-ListSetStyle-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockDiv.ListSetStyle.Response.Error](#anytype.Rpc.BlockDiv.ListSetStyle.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockDiv.ListSetStyle.Response.Error @@ -4897,7 +4897,7 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockDiv.ListSetStyle.Response.Error.Code](#anytype-Rpc-BlockDiv-ListSetStyle-Response-Error-Code) | | | +| code | [Rpc.BlockDiv.ListSetStyle.Response.Error.Code](#anytype.Rpc.BlockDiv.ListSetStyle.Response.Error.Code) | | | | description | [string](#string) | | | @@ -4905,7 +4905,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockFile @@ -4915,7 +4915,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockFile.CreateAndUpload @@ -4925,7 +4925,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockFile.CreateAndUpload.Request @@ -4935,17 +4935,17 @@ set the current active view (persisted only within a session) | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | targetId | [string](#string) | | | -| position | [model.Block.Position](#anytype-model-Block-Position) | | | +| position | [model.Block.Position](#anytype.model.Block.Position) | | | | url | [string](#string) | | | | localPath | [string](#string) | | | -| fileType | [model.Block.Content.File.Type](#anytype-model-Block-Content-File-Type) | | | +| fileType | [model.Block.Content.File.Type](#anytype.model.Block.Content.File.Type) | | | - + ### Rpc.BlockFile.CreateAndUpload.Response @@ -4953,16 +4953,16 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockFile.CreateAndUpload.Response.Error](#anytype-Rpc-BlockFile-CreateAndUpload-Response-Error) | | | +| error | [Rpc.BlockFile.CreateAndUpload.Response.Error](#anytype.Rpc.BlockFile.CreateAndUpload.Response.Error) | | | | blockId | [string](#string) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockFile.CreateAndUpload.Response.Error @@ -4970,7 +4970,7 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockFile.CreateAndUpload.Response.Error.Code](#anytype-Rpc-BlockFile-CreateAndUpload-Response-Error-Code) | | | +| code | [Rpc.BlockFile.CreateAndUpload.Response.Error.Code](#anytype.Rpc.BlockFile.CreateAndUpload.Response.Error.Code) | | | | description | [string](#string) | | | @@ -4978,7 +4978,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockFile.ListSetStyle @@ -4988,7 +4988,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockFile.ListSetStyle.Request @@ -4998,14 +4998,14 @@ set the current active view (persisted only within a session) | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | blockIds | [string](#string) | repeated | | -| style | [model.Block.Content.File.Style](#anytype-model-Block-Content-File-Style) | | | +| style | [model.Block.Content.File.Style](#anytype.model.Block.Content.File.Style) | | | - + ### Rpc.BlockFile.ListSetStyle.Response @@ -5013,15 +5013,15 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockFile.ListSetStyle.Response.Error](#anytype-Rpc-BlockFile-ListSetStyle-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockFile.ListSetStyle.Response.Error](#anytype.Rpc.BlockFile.ListSetStyle.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockFile.ListSetStyle.Response.Error @@ -5029,7 +5029,7 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockFile.ListSetStyle.Response.Error.Code](#anytype-Rpc-BlockFile-ListSetStyle-Response-Error-Code) | | | +| code | [Rpc.BlockFile.ListSetStyle.Response.Error.Code](#anytype.Rpc.BlockFile.ListSetStyle.Response.Error.Code) | | | | description | [string](#string) | | | @@ -5037,7 +5037,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockFile.SetName @@ -5047,7 +5047,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockFile.SetName.Request @@ -5064,7 +5064,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockFile.SetName.Response @@ -5072,15 +5072,15 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockFile.SetName.Response.Error](#anytype-Rpc-BlockFile-SetName-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockFile.SetName.Response.Error](#anytype.Rpc.BlockFile.SetName.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockFile.SetName.Response.Error @@ -5088,7 +5088,7 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockFile.SetName.Response.Error.Code](#anytype-Rpc-BlockFile-SetName-Response-Error-Code) | | | +| code | [Rpc.BlockFile.SetName.Response.Error.Code](#anytype.Rpc.BlockFile.SetName.Response.Error.Code) | | | | description | [string](#string) | | | @@ -5096,7 +5096,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockImage @@ -5106,7 +5106,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockImage.SetName @@ -5116,7 +5116,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockImage.SetName.Request @@ -5133,7 +5133,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockImage.SetName.Response @@ -5141,14 +5141,14 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockImage.SetName.Response.Error](#anytype-Rpc-BlockImage-SetName-Response-Error) | | | +| error | [Rpc.BlockImage.SetName.Response.Error](#anytype.Rpc.BlockImage.SetName.Response.Error) | | | - + ### Rpc.BlockImage.SetName.Response.Error @@ -5156,7 +5156,7 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockImage.SetName.Response.Error.Code](#anytype-Rpc-BlockImage-SetName-Response-Error-Code) | | | +| code | [Rpc.BlockImage.SetName.Response.Error.Code](#anytype.Rpc.BlockImage.SetName.Response.Error.Code) | | | | description | [string](#string) | | | @@ -5164,7 +5164,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockImage.SetWidth @@ -5174,7 +5174,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockImage.SetWidth.Request @@ -5191,7 +5191,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockImage.SetWidth.Response @@ -5199,14 +5199,14 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockImage.SetWidth.Response.Error](#anytype-Rpc-BlockImage-SetWidth-Response-Error) | | | +| error | [Rpc.BlockImage.SetWidth.Response.Error](#anytype.Rpc.BlockImage.SetWidth.Response.Error) | | | - + ### Rpc.BlockImage.SetWidth.Response.Error @@ -5214,7 +5214,7 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockImage.SetWidth.Response.Error.Code](#anytype-Rpc-BlockImage-SetWidth-Response-Error-Code) | | | +| code | [Rpc.BlockImage.SetWidth.Response.Error.Code](#anytype.Rpc.BlockImage.SetWidth.Response.Error.Code) | | | | description | [string](#string) | | | @@ -5222,7 +5222,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockLatex @@ -5232,7 +5232,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockLatex.SetText @@ -5242,7 +5242,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockLatex.SetText.Request @@ -5259,7 +5259,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockLatex.SetText.Response @@ -5267,15 +5267,15 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockLatex.SetText.Response.Error](#anytype-Rpc-BlockLatex-SetText-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockLatex.SetText.Response.Error](#anytype.Rpc.BlockLatex.SetText.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockLatex.SetText.Response.Error @@ -5283,7 +5283,7 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockLatex.SetText.Response.Error.Code](#anytype-Rpc-BlockLatex-SetText-Response-Error-Code) | | | +| code | [Rpc.BlockLatex.SetText.Response.Error.Code](#anytype.Rpc.BlockLatex.SetText.Response.Error.Code) | | | | description | [string](#string) | | | @@ -5291,7 +5291,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockLink @@ -5301,7 +5301,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockLink.CreateWithObject @@ -5311,7 +5311,7 @@ set the current active view (persisted only within a session) - + ### Rpc.BlockLink.CreateWithObject.Request @@ -5320,21 +5320,21 @@ set the current active view (persisted only within a session) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | id of the context object | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | new object details | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | new object details | | templateId | [string](#string) | | optional template id for creating from template | -| internalFlags | [model.InternalFlag](#anytype-model-InternalFlag) | repeated | | +| internalFlags | [model.InternalFlag](#anytype.model.InternalFlag) | repeated | | | targetId | [string](#string) | | link block params id of the closest simple block | -| position | [model.Block.Position](#anytype-model-Block-Position) | | | -| fields | [google.protobuf.Struct](#google-protobuf-Struct) | | link block fields | +| position | [model.Block.Position](#anytype.model.Block.Position) | | | +| fields | [google.protobuf.Struct](#google.protobuf.Struct) | | link block fields | - + ### Rpc.BlockLink.CreateWithObject.Response @@ -5342,17 +5342,17 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockLink.CreateWithObject.Response.Error](#anytype-Rpc-BlockLink-CreateWithObject-Response-Error) | | | +| error | [Rpc.BlockLink.CreateWithObject.Response.Error](#anytype.Rpc.BlockLink.CreateWithObject.Response.Error) | | | | blockId | [string](#string) | | | | targetId | [string](#string) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockLink.CreateWithObject.Response.Error @@ -5360,7 +5360,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockLink.CreateWithObject.Response.Error.Code](#anytype-Rpc-BlockLink-CreateWithObject-Response-Error-Code) | | | +| code | [Rpc.BlockLink.CreateWithObject.Response.Error.Code](#anytype.Rpc.BlockLink.CreateWithObject.Response.Error.Code) | | | | description | [string](#string) | | | @@ -5368,7 +5368,7 @@ id of the closest simple block | - + ### Rpc.BlockLink.ListSetAppearance @@ -5378,7 +5378,7 @@ id of the closest simple block | - + ### Rpc.BlockLink.ListSetAppearance.Request @@ -5388,9 +5388,9 @@ id of the closest simple block | | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | blockIds | [string](#string) | repeated | | -| iconSize | [model.Block.Content.Link.IconSize](#anytype-model-Block-Content-Link-IconSize) | | | -| cardStyle | [model.Block.Content.Link.CardStyle](#anytype-model-Block-Content-Link-CardStyle) | | | -| description | [model.Block.Content.Link.Description](#anytype-model-Block-Content-Link-Description) | | | +| iconSize | [model.Block.Content.Link.IconSize](#anytype.model.Block.Content.Link.IconSize) | | | +| cardStyle | [model.Block.Content.Link.CardStyle](#anytype.model.Block.Content.Link.CardStyle) | | | +| description | [model.Block.Content.Link.Description](#anytype.model.Block.Content.Link.Description) | | | | relations | [string](#string) | repeated | | @@ -5398,7 +5398,7 @@ id of the closest simple block | - + ### Rpc.BlockLink.ListSetAppearance.Response @@ -5406,15 +5406,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockLink.ListSetAppearance.Response.Error](#anytype-Rpc-BlockLink-ListSetAppearance-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockLink.ListSetAppearance.Response.Error](#anytype.Rpc.BlockLink.ListSetAppearance.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockLink.ListSetAppearance.Response.Error @@ -5422,7 +5422,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockLink.ListSetAppearance.Response.Error.Code](#anytype-Rpc-BlockLink-ListSetAppearance-Response-Error-Code) | | | +| code | [Rpc.BlockLink.ListSetAppearance.Response.Error.Code](#anytype.Rpc.BlockLink.ListSetAppearance.Response.Error.Code) | | | | description | [string](#string) | | | @@ -5430,7 +5430,7 @@ id of the closest simple block | - + ### Rpc.BlockRelation @@ -5440,7 +5440,7 @@ id of the closest simple block | - + ### Rpc.BlockRelation.Add @@ -5450,7 +5450,7 @@ id of the closest simple block | - + ### Rpc.BlockRelation.Add.Request @@ -5467,7 +5467,7 @@ id of the closest simple block | - + ### Rpc.BlockRelation.Add.Response @@ -5475,15 +5475,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockRelation.Add.Response.Error](#anytype-Rpc-BlockRelation-Add-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockRelation.Add.Response.Error](#anytype.Rpc.BlockRelation.Add.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockRelation.Add.Response.Error @@ -5491,7 +5491,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockRelation.Add.Response.Error.Code](#anytype-Rpc-BlockRelation-Add-Response-Error-Code) | | | +| code | [Rpc.BlockRelation.Add.Response.Error.Code](#anytype.Rpc.BlockRelation.Add.Response.Error.Code) | | | | description | [string](#string) | | | @@ -5499,7 +5499,7 @@ id of the closest simple block | - + ### Rpc.BlockRelation.SetKey @@ -5509,7 +5509,7 @@ id of the closest simple block | - + ### Rpc.BlockRelation.SetKey.Request @@ -5526,7 +5526,7 @@ id of the closest simple block | - + ### Rpc.BlockRelation.SetKey.Response @@ -5534,15 +5534,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockRelation.SetKey.Response.Error](#anytype-Rpc-BlockRelation-SetKey-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockRelation.SetKey.Response.Error](#anytype.Rpc.BlockRelation.SetKey.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockRelation.SetKey.Response.Error @@ -5550,7 +5550,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockRelation.SetKey.Response.Error.Code](#anytype-Rpc-BlockRelation-SetKey-Response-Error-Code) | | | +| code | [Rpc.BlockRelation.SetKey.Response.Error.Code](#anytype.Rpc.BlockRelation.SetKey.Response.Error.Code) | | | | description | [string](#string) | | | @@ -5558,7 +5558,7 @@ id of the closest simple block | - + ### Rpc.BlockTable @@ -5568,7 +5568,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.ColumnCreate @@ -5578,7 +5578,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.ColumnCreate.Request @@ -5588,14 +5588,14 @@ id of the closest simple block | | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | id of the context object | | targetId | [string](#string) | | id of the closest column | -| position | [model.Block.Position](#anytype-model-Block-Position) | | | +| position | [model.Block.Position](#anytype.model.Block.Position) | | | - + ### Rpc.BlockTable.ColumnCreate.Response @@ -5603,15 +5603,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockTable.ColumnCreate.Response.Error](#anytype-Rpc-BlockTable-ColumnCreate-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockTable.ColumnCreate.Response.Error](#anytype.Rpc.BlockTable.ColumnCreate.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockTable.ColumnCreate.Response.Error @@ -5619,7 +5619,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockTable.ColumnCreate.Response.Error.Code](#anytype-Rpc-BlockTable-ColumnCreate-Response-Error-Code) | | | +| code | [Rpc.BlockTable.ColumnCreate.Response.Error.Code](#anytype.Rpc.BlockTable.ColumnCreate.Response.Error.Code) | | | | description | [string](#string) | | | @@ -5627,7 +5627,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.ColumnDelete @@ -5637,7 +5637,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.ColumnDelete.Request @@ -5653,7 +5653,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.ColumnDelete.Response @@ -5661,15 +5661,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockTable.ColumnDelete.Response.Error](#anytype-Rpc-BlockTable-ColumnDelete-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockTable.ColumnDelete.Response.Error](#anytype.Rpc.BlockTable.ColumnDelete.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockTable.ColumnDelete.Response.Error @@ -5677,7 +5677,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockTable.ColumnDelete.Response.Error.Code](#anytype-Rpc-BlockTable-ColumnDelete-Response-Error-Code) | | | +| code | [Rpc.BlockTable.ColumnDelete.Response.Error.Code](#anytype.Rpc.BlockTable.ColumnDelete.Response.Error.Code) | | | | description | [string](#string) | | | @@ -5685,7 +5685,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.ColumnDuplicate @@ -5695,7 +5695,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.ColumnDuplicate.Request @@ -5706,14 +5706,14 @@ id of the closest simple block | | contextId | [string](#string) | | id of the context object | | targetId | [string](#string) | | | | blockId | [string](#string) | | block to duplicate | -| position | [model.Block.Position](#anytype-model-Block-Position) | | | +| position | [model.Block.Position](#anytype.model.Block.Position) | | | - + ### Rpc.BlockTable.ColumnDuplicate.Response @@ -5721,16 +5721,16 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockTable.ColumnDuplicate.Response.Error](#anytype-Rpc-BlockTable-ColumnDuplicate-Response-Error) | | | +| error | [Rpc.BlockTable.ColumnDuplicate.Response.Error](#anytype.Rpc.BlockTable.ColumnDuplicate.Response.Error) | | | | blockId | [string](#string) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockTable.ColumnDuplicate.Response.Error @@ -5738,7 +5738,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockTable.ColumnDuplicate.Response.Error.Code](#anytype-Rpc-BlockTable-ColumnDuplicate-Response-Error-Code) | | | +| code | [Rpc.BlockTable.ColumnDuplicate.Response.Error.Code](#anytype.Rpc.BlockTable.ColumnDuplicate.Response.Error.Code) | | | | description | [string](#string) | | | @@ -5746,7 +5746,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.ColumnListFill @@ -5756,7 +5756,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.ColumnListFill.Request @@ -5772,7 +5772,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.ColumnListFill.Response @@ -5780,15 +5780,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockTable.ColumnListFill.Response.Error](#anytype-Rpc-BlockTable-ColumnListFill-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockTable.ColumnListFill.Response.Error](#anytype.Rpc.BlockTable.ColumnListFill.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockTable.ColumnListFill.Response.Error @@ -5796,7 +5796,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockTable.ColumnListFill.Response.Error.Code](#anytype-Rpc-BlockTable-ColumnListFill-Response-Error-Code) | | | +| code | [Rpc.BlockTable.ColumnListFill.Response.Error.Code](#anytype.Rpc.BlockTable.ColumnListFill.Response.Error.Code) | | | | description | [string](#string) | | | @@ -5804,7 +5804,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.ColumnMove @@ -5814,7 +5814,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.ColumnMove.Request @@ -5825,14 +5825,14 @@ id of the closest simple block | | contextId | [string](#string) | | | | targetId | [string](#string) | | | | dropTargetId | [string](#string) | | | -| position | [model.Block.Position](#anytype-model-Block-Position) | | | +| position | [model.Block.Position](#anytype.model.Block.Position) | | | - + ### Rpc.BlockTable.ColumnMove.Response @@ -5840,15 +5840,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockTable.ColumnMove.Response.Error](#anytype-Rpc-BlockTable-ColumnMove-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockTable.ColumnMove.Response.Error](#anytype.Rpc.BlockTable.ColumnMove.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockTable.ColumnMove.Response.Error @@ -5856,7 +5856,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockTable.ColumnMove.Response.Error.Code](#anytype-Rpc-BlockTable-ColumnMove-Response-Error-Code) | | | +| code | [Rpc.BlockTable.ColumnMove.Response.Error.Code](#anytype.Rpc.BlockTable.ColumnMove.Response.Error.Code) | | | | description | [string](#string) | | | @@ -5864,7 +5864,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.Create @@ -5874,7 +5874,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.Create.Request @@ -5884,7 +5884,7 @@ id of the closest simple block | | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | id of the context object | | targetId | [string](#string) | | id of the closest block | -| position | [model.Block.Position](#anytype-model-Block-Position) | | | +| position | [model.Block.Position](#anytype.model.Block.Position) | | | | rows | [uint32](#uint32) | | | | columns | [uint32](#uint32) | | | | withHeaderRow | [bool](#bool) | | | @@ -5894,7 +5894,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.Create.Response @@ -5902,16 +5902,16 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockTable.Create.Response.Error](#anytype-Rpc-BlockTable-Create-Response-Error) | | | +| error | [Rpc.BlockTable.Create.Response.Error](#anytype.Rpc.BlockTable.Create.Response.Error) | | | | blockId | [string](#string) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockTable.Create.Response.Error @@ -5919,7 +5919,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockTable.Create.Response.Error.Code](#anytype-Rpc-BlockTable-Create-Response-Error-Code) | | | +| code | [Rpc.BlockTable.Create.Response.Error.Code](#anytype.Rpc.BlockTable.Create.Response.Error.Code) | | | | description | [string](#string) | | | @@ -5927,7 +5927,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.Expand @@ -5937,7 +5937,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.Expand.Request @@ -5955,7 +5955,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.Expand.Response @@ -5963,15 +5963,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockTable.Expand.Response.Error](#anytype-Rpc-BlockTable-Expand-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockTable.Expand.Response.Error](#anytype.Rpc.BlockTable.Expand.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockTable.Expand.Response.Error @@ -5979,7 +5979,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockTable.Expand.Response.Error.Code](#anytype-Rpc-BlockTable-Expand-Response-Error-Code) | | | +| code | [Rpc.BlockTable.Expand.Response.Error.Code](#anytype.Rpc.BlockTable.Expand.Response.Error.Code) | | | | description | [string](#string) | | | @@ -5987,7 +5987,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.RowCreate @@ -5997,7 +5997,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.RowCreate.Request @@ -6007,14 +6007,14 @@ id of the closest simple block | | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | id of the context object | | targetId | [string](#string) | | id of the closest row | -| position | [model.Block.Position](#anytype-model-Block-Position) | | | +| position | [model.Block.Position](#anytype.model.Block.Position) | | | - + ### Rpc.BlockTable.RowCreate.Response @@ -6022,15 +6022,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockTable.RowCreate.Response.Error](#anytype-Rpc-BlockTable-RowCreate-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockTable.RowCreate.Response.Error](#anytype.Rpc.BlockTable.RowCreate.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockTable.RowCreate.Response.Error @@ -6038,7 +6038,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockTable.RowCreate.Response.Error.Code](#anytype-Rpc-BlockTable-RowCreate-Response-Error-Code) | | | +| code | [Rpc.BlockTable.RowCreate.Response.Error.Code](#anytype.Rpc.BlockTable.RowCreate.Response.Error.Code) | | | | description | [string](#string) | | | @@ -6046,7 +6046,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.RowDelete @@ -6056,7 +6056,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.RowDelete.Request @@ -6072,7 +6072,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.RowDelete.Response @@ -6080,15 +6080,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockTable.RowDelete.Response.Error](#anytype-Rpc-BlockTable-RowDelete-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockTable.RowDelete.Response.Error](#anytype.Rpc.BlockTable.RowDelete.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockTable.RowDelete.Response.Error @@ -6096,7 +6096,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockTable.RowDelete.Response.Error.Code](#anytype-Rpc-BlockTable-RowDelete-Response-Error-Code) | | | +| code | [Rpc.BlockTable.RowDelete.Response.Error.Code](#anytype.Rpc.BlockTable.RowDelete.Response.Error.Code) | | | | description | [string](#string) | | | @@ -6104,7 +6104,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.RowDuplicate @@ -6114,7 +6114,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.RowDuplicate.Request @@ -6125,14 +6125,14 @@ id of the closest simple block | | contextId | [string](#string) | | id of the context object | | targetId | [string](#string) | | | | blockId | [string](#string) | | block to duplicate | -| position | [model.Block.Position](#anytype-model-Block-Position) | | | +| position | [model.Block.Position](#anytype.model.Block.Position) | | | - + ### Rpc.BlockTable.RowDuplicate.Response @@ -6140,15 +6140,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockTable.RowDuplicate.Response.Error](#anytype-Rpc-BlockTable-RowDuplicate-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockTable.RowDuplicate.Response.Error](#anytype.Rpc.BlockTable.RowDuplicate.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockTable.RowDuplicate.Response.Error @@ -6156,7 +6156,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockTable.RowDuplicate.Response.Error.Code](#anytype-Rpc-BlockTable-RowDuplicate-Response-Error-Code) | | | +| code | [Rpc.BlockTable.RowDuplicate.Response.Error.Code](#anytype.Rpc.BlockTable.RowDuplicate.Response.Error.Code) | | | | description | [string](#string) | | | @@ -6164,7 +6164,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.RowListClean @@ -6174,7 +6174,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.RowListClean.Request @@ -6190,7 +6190,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.RowListClean.Response @@ -6198,15 +6198,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockTable.RowListClean.Response.Error](#anytype-Rpc-BlockTable-RowListClean-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockTable.RowListClean.Response.Error](#anytype.Rpc.BlockTable.RowListClean.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockTable.RowListClean.Response.Error @@ -6214,7 +6214,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockTable.RowListClean.Response.Error.Code](#anytype-Rpc-BlockTable-RowListClean-Response-Error-Code) | | | +| code | [Rpc.BlockTable.RowListClean.Response.Error.Code](#anytype.Rpc.BlockTable.RowListClean.Response.Error.Code) | | | | description | [string](#string) | | | @@ -6222,7 +6222,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.RowListFill @@ -6232,7 +6232,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.RowListFill.Request @@ -6248,7 +6248,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.RowListFill.Response @@ -6256,15 +6256,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockTable.RowListFill.Response.Error](#anytype-Rpc-BlockTable-RowListFill-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockTable.RowListFill.Response.Error](#anytype.Rpc.BlockTable.RowListFill.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockTable.RowListFill.Response.Error @@ -6272,7 +6272,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockTable.RowListFill.Response.Error.Code](#anytype-Rpc-BlockTable-RowListFill-Response-Error-Code) | | | +| code | [Rpc.BlockTable.RowListFill.Response.Error.Code](#anytype.Rpc.BlockTable.RowListFill.Response.Error.Code) | | | | description | [string](#string) | | | @@ -6280,7 +6280,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.RowSetHeader @@ -6290,7 +6290,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.RowSetHeader.Request @@ -6307,7 +6307,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.RowSetHeader.Response @@ -6315,15 +6315,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockTable.RowSetHeader.Response.Error](#anytype-Rpc-BlockTable-RowSetHeader-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockTable.RowSetHeader.Response.Error](#anytype.Rpc.BlockTable.RowSetHeader.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockTable.RowSetHeader.Response.Error @@ -6331,7 +6331,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockTable.RowSetHeader.Response.Error.Code](#anytype-Rpc-BlockTable-RowSetHeader-Response-Error-Code) | | | +| code | [Rpc.BlockTable.RowSetHeader.Response.Error.Code](#anytype.Rpc.BlockTable.RowSetHeader.Response.Error.Code) | | | | description | [string](#string) | | | @@ -6339,7 +6339,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.Sort @@ -6349,7 +6349,7 @@ id of the closest simple block | - + ### Rpc.BlockTable.Sort.Request @@ -6359,14 +6359,14 @@ id of the closest simple block | | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | id of the context object | | columnId | [string](#string) | | | -| type | [model.Block.Content.Dataview.Sort.Type](#anytype-model-Block-Content-Dataview-Sort-Type) | | | +| type | [model.Block.Content.Dataview.Sort.Type](#anytype.model.Block.Content.Dataview.Sort.Type) | | | - + ### Rpc.BlockTable.Sort.Response @@ -6374,15 +6374,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockTable.Sort.Response.Error](#anytype-Rpc-BlockTable-Sort-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockTable.Sort.Response.Error](#anytype.Rpc.BlockTable.Sort.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockTable.Sort.Response.Error @@ -6390,7 +6390,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockTable.Sort.Response.Error.Code](#anytype-Rpc-BlockTable-Sort-Response-Error-Code) | | | +| code | [Rpc.BlockTable.Sort.Response.Error.Code](#anytype.Rpc.BlockTable.Sort.Response.Error.Code) | | | | description | [string](#string) | | | @@ -6398,7 +6398,7 @@ id of the closest simple block | - + ### Rpc.BlockText @@ -6408,7 +6408,7 @@ id of the closest simple block | - + ### Rpc.BlockText.ListClearContent @@ -6418,7 +6418,7 @@ id of the closest simple block | - + ### Rpc.BlockText.ListClearContent.Request @@ -6434,7 +6434,7 @@ id of the closest simple block | - + ### Rpc.BlockText.ListClearContent.Response @@ -6442,15 +6442,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockText.ListClearContent.Response.Error](#anytype-Rpc-BlockText-ListClearContent-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockText.ListClearContent.Response.Error](#anytype.Rpc.BlockText.ListClearContent.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockText.ListClearContent.Response.Error @@ -6458,7 +6458,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockText.ListClearContent.Response.Error.Code](#anytype-Rpc-BlockText-ListClearContent-Response-Error-Code) | | | +| code | [Rpc.BlockText.ListClearContent.Response.Error.Code](#anytype.Rpc.BlockText.ListClearContent.Response.Error.Code) | | | | description | [string](#string) | | | @@ -6466,7 +6466,7 @@ id of the closest simple block | - + ### Rpc.BlockText.ListClearStyle @@ -6476,7 +6476,7 @@ id of the closest simple block | - + ### Rpc.BlockText.ListClearStyle.Request @@ -6492,7 +6492,7 @@ id of the closest simple block | - + ### Rpc.BlockText.ListClearStyle.Response @@ -6500,15 +6500,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockText.ListClearStyle.Response.Error](#anytype-Rpc-BlockText-ListClearStyle-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockText.ListClearStyle.Response.Error](#anytype.Rpc.BlockText.ListClearStyle.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockText.ListClearStyle.Response.Error @@ -6516,7 +6516,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockText.ListClearStyle.Response.Error.Code](#anytype-Rpc-BlockText-ListClearStyle-Response-Error-Code) | | | +| code | [Rpc.BlockText.ListClearStyle.Response.Error.Code](#anytype.Rpc.BlockText.ListClearStyle.Response.Error.Code) | | | | description | [string](#string) | | | @@ -6524,7 +6524,7 @@ id of the closest simple block | - + ### Rpc.BlockText.ListSetColor @@ -6534,7 +6534,7 @@ id of the closest simple block | - + ### Rpc.BlockText.ListSetColor.Request @@ -6551,7 +6551,7 @@ id of the closest simple block | - + ### Rpc.BlockText.ListSetColor.Response @@ -6559,15 +6559,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockText.ListSetColor.Response.Error](#anytype-Rpc-BlockText-ListSetColor-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockText.ListSetColor.Response.Error](#anytype.Rpc.BlockText.ListSetColor.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockText.ListSetColor.Response.Error @@ -6575,7 +6575,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockText.ListSetColor.Response.Error.Code](#anytype-Rpc-BlockText-ListSetColor-Response-Error-Code) | | | +| code | [Rpc.BlockText.ListSetColor.Response.Error.Code](#anytype.Rpc.BlockText.ListSetColor.Response.Error.Code) | | | | description | [string](#string) | | | @@ -6583,7 +6583,7 @@ id of the closest simple block | - + ### Rpc.BlockText.ListSetMark @@ -6593,7 +6593,7 @@ id of the closest simple block | - + ### Rpc.BlockText.ListSetMark.Request @@ -6603,14 +6603,14 @@ id of the closest simple block | | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | blockIds | [string](#string) | repeated | | -| mark | [model.Block.Content.Text.Mark](#anytype-model-Block-Content-Text-Mark) | | | +| mark | [model.Block.Content.Text.Mark](#anytype.model.Block.Content.Text.Mark) | | | - + ### Rpc.BlockText.ListSetMark.Response @@ -6618,15 +6618,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockText.ListSetMark.Response.Error](#anytype-Rpc-BlockText-ListSetMark-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockText.ListSetMark.Response.Error](#anytype.Rpc.BlockText.ListSetMark.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockText.ListSetMark.Response.Error @@ -6634,7 +6634,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockText.ListSetMark.Response.Error.Code](#anytype-Rpc-BlockText-ListSetMark-Response-Error-Code) | | | +| code | [Rpc.BlockText.ListSetMark.Response.Error.Code](#anytype.Rpc.BlockText.ListSetMark.Response.Error.Code) | | | | description | [string](#string) | | | @@ -6642,7 +6642,7 @@ id of the closest simple block | - + ### Rpc.BlockText.ListSetStyle @@ -6652,7 +6652,7 @@ id of the closest simple block | - + ### Rpc.BlockText.ListSetStyle.Request @@ -6662,14 +6662,14 @@ id of the closest simple block | | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | blockIds | [string](#string) | repeated | | -| style | [model.Block.Content.Text.Style](#anytype-model-Block-Content-Text-Style) | | | +| style | [model.Block.Content.Text.Style](#anytype.model.Block.Content.Text.Style) | | | - + ### Rpc.BlockText.ListSetStyle.Response @@ -6677,15 +6677,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockText.ListSetStyle.Response.Error](#anytype-Rpc-BlockText-ListSetStyle-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockText.ListSetStyle.Response.Error](#anytype.Rpc.BlockText.ListSetStyle.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockText.ListSetStyle.Response.Error @@ -6693,7 +6693,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockText.ListSetStyle.Response.Error.Code](#anytype-Rpc-BlockText-ListSetStyle-Response-Error-Code) | | | +| code | [Rpc.BlockText.ListSetStyle.Response.Error.Code](#anytype.Rpc.BlockText.ListSetStyle.Response.Error.Code) | | | | description | [string](#string) | | | @@ -6701,7 +6701,7 @@ id of the closest simple block | - + ### Rpc.BlockText.SetChecked @@ -6711,7 +6711,7 @@ id of the closest simple block | - + ### Rpc.BlockText.SetChecked.Request @@ -6728,7 +6728,7 @@ id of the closest simple block | - + ### Rpc.BlockText.SetChecked.Response @@ -6736,15 +6736,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockText.SetChecked.Response.Error](#anytype-Rpc-BlockText-SetChecked-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockText.SetChecked.Response.Error](#anytype.Rpc.BlockText.SetChecked.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockText.SetChecked.Response.Error @@ -6752,7 +6752,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockText.SetChecked.Response.Error.Code](#anytype-Rpc-BlockText-SetChecked-Response-Error-Code) | | | +| code | [Rpc.BlockText.SetChecked.Response.Error.Code](#anytype.Rpc.BlockText.SetChecked.Response.Error.Code) | | | | description | [string](#string) | | | @@ -6760,7 +6760,7 @@ id of the closest simple block | - + ### Rpc.BlockText.SetColor @@ -6770,7 +6770,7 @@ id of the closest simple block | - + ### Rpc.BlockText.SetColor.Request @@ -6787,7 +6787,7 @@ id of the closest simple block | - + ### Rpc.BlockText.SetColor.Response @@ -6795,15 +6795,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockText.SetColor.Response.Error](#anytype-Rpc-BlockText-SetColor-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockText.SetColor.Response.Error](#anytype.Rpc.BlockText.SetColor.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockText.SetColor.Response.Error @@ -6811,7 +6811,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockText.SetColor.Response.Error.Code](#anytype-Rpc-BlockText-SetColor-Response-Error-Code) | | | +| code | [Rpc.BlockText.SetColor.Response.Error.Code](#anytype.Rpc.BlockText.SetColor.Response.Error.Code) | | | | description | [string](#string) | | | @@ -6819,7 +6819,7 @@ id of the closest simple block | - + ### Rpc.BlockText.SetIcon @@ -6829,7 +6829,7 @@ id of the closest simple block | - + ### Rpc.BlockText.SetIcon.Request @@ -6847,7 +6847,7 @@ id of the closest simple block | - + ### Rpc.BlockText.SetIcon.Response @@ -6855,15 +6855,15 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockText.SetIcon.Response.Error](#anytype-Rpc-BlockText-SetIcon-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockText.SetIcon.Response.Error](#anytype.Rpc.BlockText.SetIcon.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockText.SetIcon.Response.Error @@ -6871,7 +6871,7 @@ id of the closest simple block | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockText.SetIcon.Response.Error.Code](#anytype-Rpc-BlockText-SetIcon-Response-Error-Code) | | | +| code | [Rpc.BlockText.SetIcon.Response.Error.Code](#anytype.Rpc.BlockText.SetIcon.Response.Error.Code) | | | | description | [string](#string) | | | @@ -6879,7 +6879,7 @@ id of the closest simple block | - + ### Rpc.BlockText.SetMarks @@ -6889,7 +6889,7 @@ id of the closest simple block | - + ### Rpc.BlockText.SetMarks.Get Get marks list in the selected range in text block. @@ -6899,7 +6899,7 @@ Get marks list in the selected range in text block. - + ### Rpc.BlockText.SetMarks.Get.Request @@ -6909,14 +6909,14 @@ Get marks list in the selected range in text block. | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | blockId | [string](#string) | | | -| range | [model.Range](#anytype-model-Range) | | | +| range | [model.Range](#anytype.model.Range) | | | - + ### Rpc.BlockText.SetMarks.Get.Response @@ -6924,15 +6924,15 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockText.SetMarks.Get.Response.Error](#anytype-Rpc-BlockText-SetMarks-Get-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockText.SetMarks.Get.Response.Error](#anytype.Rpc.BlockText.SetMarks.Get.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockText.SetMarks.Get.Response.Error @@ -6940,7 +6940,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockText.SetMarks.Get.Response.Error.Code](#anytype-Rpc-BlockText-SetMarks-Get-Response-Error-Code) | | | +| code | [Rpc.BlockText.SetMarks.Get.Response.Error.Code](#anytype.Rpc.BlockText.SetMarks.Get.Response.Error.Code) | | | | description | [string](#string) | | | @@ -6948,7 +6948,7 @@ Get marks list in the selected range in text block. - + ### Rpc.BlockText.SetStyle @@ -6958,7 +6958,7 @@ Get marks list in the selected range in text block. - + ### Rpc.BlockText.SetStyle.Request @@ -6968,14 +6968,14 @@ Get marks list in the selected range in text block. | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | blockId | [string](#string) | | | -| style | [model.Block.Content.Text.Style](#anytype-model-Block-Content-Text-Style) | | | +| style | [model.Block.Content.Text.Style](#anytype.model.Block.Content.Text.Style) | | | - + ### Rpc.BlockText.SetStyle.Response @@ -6983,15 +6983,15 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockText.SetStyle.Response.Error](#anytype-Rpc-BlockText-SetStyle-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockText.SetStyle.Response.Error](#anytype.Rpc.BlockText.SetStyle.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockText.SetStyle.Response.Error @@ -6999,7 +6999,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockText.SetStyle.Response.Error.Code](#anytype-Rpc-BlockText-SetStyle-Response-Error-Code) | | | +| code | [Rpc.BlockText.SetStyle.Response.Error.Code](#anytype.Rpc.BlockText.SetStyle.Response.Error.Code) | | | | description | [string](#string) | | | @@ -7007,7 +7007,7 @@ Get marks list in the selected range in text block. - + ### Rpc.BlockText.SetText @@ -7017,7 +7017,7 @@ Get marks list in the selected range in text block. - + ### Rpc.BlockText.SetText.Request @@ -7028,14 +7028,14 @@ Get marks list in the selected range in text block. | contextId | [string](#string) | | | | blockId | [string](#string) | | | | text | [string](#string) | | | -| marks | [model.Block.Content.Text.Marks](#anytype-model-Block-Content-Text-Marks) | | | +| marks | [model.Block.Content.Text.Marks](#anytype.model.Block.Content.Text.Marks) | | | - + ### Rpc.BlockText.SetText.Response @@ -7043,15 +7043,15 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockText.SetText.Response.Error](#anytype-Rpc-BlockText-SetText-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.BlockText.SetText.Response.Error](#anytype.Rpc.BlockText.SetText.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.BlockText.SetText.Response.Error @@ -7059,7 +7059,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockText.SetText.Response.Error.Code](#anytype-Rpc-BlockText-SetText-Response-Error-Code) | | | +| code | [Rpc.BlockText.SetText.Response.Error.Code](#anytype.Rpc.BlockText.SetText.Response.Error.Code) | | | | description | [string](#string) | | | @@ -7067,7 +7067,7 @@ Get marks list in the selected range in text block. - + ### Rpc.BlockVideo @@ -7077,7 +7077,7 @@ Get marks list in the selected range in text block. - + ### Rpc.BlockVideo.SetName @@ -7087,7 +7087,7 @@ Get marks list in the selected range in text block. - + ### Rpc.BlockVideo.SetName.Request @@ -7104,7 +7104,7 @@ Get marks list in the selected range in text block. - + ### Rpc.BlockVideo.SetName.Response @@ -7112,14 +7112,14 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockVideo.SetName.Response.Error](#anytype-Rpc-BlockVideo-SetName-Response-Error) | | | +| error | [Rpc.BlockVideo.SetName.Response.Error](#anytype.Rpc.BlockVideo.SetName.Response.Error) | | | - + ### Rpc.BlockVideo.SetName.Response.Error @@ -7127,7 +7127,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockVideo.SetName.Response.Error.Code](#anytype-Rpc-BlockVideo-SetName-Response-Error-Code) | | | +| code | [Rpc.BlockVideo.SetName.Response.Error.Code](#anytype.Rpc.BlockVideo.SetName.Response.Error.Code) | | | | description | [string](#string) | | | @@ -7135,7 +7135,7 @@ Get marks list in the selected range in text block. - + ### Rpc.BlockVideo.SetWidth @@ -7145,7 +7145,7 @@ Get marks list in the selected range in text block. - + ### Rpc.BlockVideo.SetWidth.Request @@ -7162,7 +7162,7 @@ Get marks list in the selected range in text block. - + ### Rpc.BlockVideo.SetWidth.Response @@ -7170,14 +7170,14 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.BlockVideo.SetWidth.Response.Error](#anytype-Rpc-BlockVideo-SetWidth-Response-Error) | | | +| error | [Rpc.BlockVideo.SetWidth.Response.Error](#anytype.Rpc.BlockVideo.SetWidth.Response.Error) | | | - + ### Rpc.BlockVideo.SetWidth.Response.Error @@ -7185,7 +7185,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.BlockVideo.SetWidth.Response.Error.Code](#anytype-Rpc-BlockVideo-SetWidth-Response-Error-Code) | | | +| code | [Rpc.BlockVideo.SetWidth.Response.Error.Code](#anytype.Rpc.BlockVideo.SetWidth.Response.Error.Code) | | | | description | [string](#string) | | | @@ -7193,7 +7193,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug @@ -7203,7 +7203,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug.ExportLocalstore @@ -7213,7 +7213,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug.ExportLocalstore.Request @@ -7229,7 +7229,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug.ExportLocalstore.Response @@ -7237,16 +7237,16 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Debug.ExportLocalstore.Response.Error](#anytype-Rpc-Debug-ExportLocalstore-Response-Error) | | | +| error | [Rpc.Debug.ExportLocalstore.Response.Error](#anytype.Rpc.Debug.ExportLocalstore.Response.Error) | | | | path | [string](#string) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Debug.ExportLocalstore.Response.Error @@ -7254,7 +7254,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Debug.ExportLocalstore.Response.Error.Code](#anytype-Rpc-Debug-ExportLocalstore-Response-Error-Code) | | | +| code | [Rpc.Debug.ExportLocalstore.Response.Error.Code](#anytype.Rpc.Debug.ExportLocalstore.Response.Error.Code) | | | | description | [string](#string) | | | @@ -7262,7 +7262,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug.Ping @@ -7272,7 +7272,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug.Ping.Request @@ -7288,7 +7288,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug.Ping.Response @@ -7296,7 +7296,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Debug.Ping.Response.Error](#anytype-Rpc-Debug-Ping-Response-Error) | | | +| error | [Rpc.Debug.Ping.Response.Error](#anytype.Rpc.Debug.Ping.Response.Error) | | | | index | [int32](#int32) | | | @@ -7304,7 +7304,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug.Ping.Response.Error @@ -7312,7 +7312,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Debug.Ping.Response.Error.Code](#anytype-Rpc-Debug-Ping-Response-Error-Code) | | | +| code | [Rpc.Debug.Ping.Response.Error.Code](#anytype.Rpc.Debug.Ping.Response.Error.Code) | | | | description | [string](#string) | | | @@ -7320,7 +7320,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug.Sync @@ -7330,7 +7330,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug.Sync.Request @@ -7347,7 +7347,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug.Sync.Response @@ -7355,8 +7355,8 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Debug.Sync.Response.Error](#anytype-Rpc-Debug-Sync-Response-Error) | | | -| threads | [Rpc.Debug.threadInfo](#anytype-Rpc-Debug-threadInfo) | repeated | | +| error | [Rpc.Debug.Sync.Response.Error](#anytype.Rpc.Debug.Sync.Response.Error) | | | +| threads | [Rpc.Debug.threadInfo](#anytype.Rpc.Debug.threadInfo) | repeated | | | deviceId | [string](#string) | | | | totalThreads | [int32](#int32) | | | | threadsWithoutReplInOwnLog | [int32](#int32) | | | @@ -7369,7 +7369,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug.Sync.Response.Error @@ -7377,7 +7377,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Debug.Sync.Response.Error.Code](#anytype-Rpc-Debug-Sync-Response-Error-Code) | | | +| code | [Rpc.Debug.Sync.Response.Error.Code](#anytype.Rpc.Debug.Sync.Response.Error.Code) | | | | description | [string](#string) | | | @@ -7385,7 +7385,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug.Thread @@ -7395,7 +7395,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug.Thread.Request @@ -7412,7 +7412,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug.Thread.Response @@ -7420,15 +7420,15 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Debug.Thread.Response.Error](#anytype-Rpc-Debug-Thread-Response-Error) | | | -| info | [Rpc.Debug.threadInfo](#anytype-Rpc-Debug-threadInfo) | | | +| error | [Rpc.Debug.Thread.Response.Error](#anytype.Rpc.Debug.Thread.Response.Error) | | | +| info | [Rpc.Debug.threadInfo](#anytype.Rpc.Debug.threadInfo) | | | - + ### Rpc.Debug.Thread.Response.Error @@ -7436,7 +7436,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Debug.Thread.Response.Error.Code](#anytype-Rpc-Debug-Thread-Response-Error-Code) | | | +| code | [Rpc.Debug.Thread.Response.Error.Code](#anytype.Rpc.Debug.Thread.Response.Error.Code) | | | | description | [string](#string) | | | @@ -7444,7 +7444,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug.Tree @@ -7454,7 +7454,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug.Tree.Request @@ -7472,7 +7472,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug.Tree.Response @@ -7480,7 +7480,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Debug.Tree.Response.Error](#anytype-Rpc-Debug-Tree-Response-Error) | | | +| error | [Rpc.Debug.Tree.Response.Error](#anytype.Rpc.Debug.Tree.Response.Error) | | | | filename | [string](#string) | | | @@ -7488,7 +7488,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug.Tree.Response.Error @@ -7496,7 +7496,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Debug.Tree.Response.Error.Code](#anytype-Rpc-Debug-Tree-Response-Error-Code) | | | +| code | [Rpc.Debug.Tree.Response.Error.Code](#anytype.Rpc.Debug.Tree.Response.Error.Code) | | | | description | [string](#string) | | | @@ -7504,7 +7504,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug.logInfo @@ -7531,7 +7531,7 @@ Get marks list in the selected range in text block. - + ### Rpc.Debug.threadInfo @@ -7542,7 +7542,7 @@ Get marks list in the selected range in text block. | id | [string](#string) | | | | logsWithDownloadedHead | [int32](#int32) | | | | logsWithWholeTreeDownloaded | [int32](#int32) | | | -| logs | [Rpc.Debug.logInfo](#anytype-Rpc-Debug-logInfo) | repeated | | +| logs | [Rpc.Debug.logInfo](#anytype.Rpc.Debug.logInfo) | repeated | | | ownLogHasCafeReplicator | [bool](#bool) | | | | cafeLastPullSecAgo | [int32](#int32) | | | | cafeUpStatus | [string](#string) | | | @@ -7556,7 +7556,7 @@ Get marks list in the selected range in text block. - + ### Rpc.File @@ -7566,7 +7566,7 @@ Get marks list in the selected range in text block. - + ### Rpc.File.Download @@ -7576,7 +7576,7 @@ Get marks list in the selected range in text block. - + ### Rpc.File.Download.Request @@ -7592,7 +7592,7 @@ Get marks list in the selected range in text block. - + ### Rpc.File.Download.Response @@ -7600,7 +7600,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.File.Download.Response.Error](#anytype-Rpc-File-Download-Response-Error) | | | +| error | [Rpc.File.Download.Response.Error](#anytype.Rpc.File.Download.Response.Error) | | | | localPath | [string](#string) | | | @@ -7608,7 +7608,7 @@ Get marks list in the selected range in text block. - + ### Rpc.File.Download.Response.Error @@ -7616,7 +7616,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.File.Download.Response.Error.Code](#anytype-Rpc-File-Download-Response-Error-Code) | | | +| code | [Rpc.File.Download.Response.Error.Code](#anytype.Rpc.File.Download.Response.Error.Code) | | | | description | [string](#string) | | | @@ -7624,7 +7624,7 @@ Get marks list in the selected range in text block. - + ### Rpc.File.Drop @@ -7634,7 +7634,7 @@ Get marks list in the selected range in text block. - + ### Rpc.File.Drop.Request @@ -7644,7 +7644,7 @@ Get marks list in the selected range in text block. | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | | dropTargetId | [string](#string) | | id of the simple block to insert considering position | -| position | [model.Block.Position](#anytype-model-Block-Position) | | position relatively to the dropTargetId simple block | +| position | [model.Block.Position](#anytype.model.Block.Position) | | position relatively to the dropTargetId simple block | | localFilePaths | [string](#string) | repeated | | @@ -7652,7 +7652,7 @@ Get marks list in the selected range in text block. - + ### Rpc.File.Drop.Response @@ -7660,15 +7660,15 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.File.Drop.Response.Error](#anytype-Rpc-File-Drop-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.File.Drop.Response.Error](#anytype.Rpc.File.Drop.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.File.Drop.Response.Error @@ -7676,7 +7676,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.File.Drop.Response.Error.Code](#anytype-Rpc-File-Drop-Response-Error-Code) | | | +| code | [Rpc.File.Drop.Response.Error.Code](#anytype.Rpc.File.Drop.Response.Error.Code) | | | | description | [string](#string) | | | @@ -7684,7 +7684,7 @@ Get marks list in the selected range in text block. - + ### Rpc.File.ListOffload @@ -7694,7 +7694,7 @@ Get marks list in the selected range in text block. - + ### Rpc.File.ListOffload.Request @@ -7710,7 +7710,7 @@ Get marks list in the selected range in text block. - + ### Rpc.File.ListOffload.Response @@ -7718,7 +7718,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.File.ListOffload.Response.Error](#anytype-Rpc-File-ListOffload-Response-Error) | | | +| error | [Rpc.File.ListOffload.Response.Error](#anytype.Rpc.File.ListOffload.Response.Error) | | | | filesOffloaded | [int32](#int32) | | | | bytesOffloaded | [uint64](#uint64) | | | @@ -7727,7 +7727,7 @@ Get marks list in the selected range in text block. - + ### Rpc.File.ListOffload.Response.Error @@ -7735,7 +7735,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.File.ListOffload.Response.Error.Code](#anytype-Rpc-File-ListOffload-Response-Error-Code) | | | +| code | [Rpc.File.ListOffload.Response.Error.Code](#anytype.Rpc.File.ListOffload.Response.Error.Code) | | | | description | [string](#string) | | | @@ -7743,7 +7743,7 @@ Get marks list in the selected range in text block. - + ### Rpc.File.Offload @@ -7753,7 +7753,7 @@ Get marks list in the selected range in text block. - + ### Rpc.File.Offload.Request @@ -7769,7 +7769,7 @@ Get marks list in the selected range in text block. - + ### Rpc.File.Offload.Response @@ -7777,7 +7777,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.File.Offload.Response.Error](#anytype-Rpc-File-Offload-Response-Error) | | | +| error | [Rpc.File.Offload.Response.Error](#anytype.Rpc.File.Offload.Response.Error) | | | | bytesOffloaded | [uint64](#uint64) | | | @@ -7785,7 +7785,7 @@ Get marks list in the selected range in text block. - + ### Rpc.File.Offload.Response.Error @@ -7793,7 +7793,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.File.Offload.Response.Error.Code](#anytype-Rpc-File-Offload-Response-Error-Code) | | | +| code | [Rpc.File.Offload.Response.Error.Code](#anytype.Rpc.File.Offload.Response.Error.Code) | | | | description | [string](#string) | | | @@ -7801,7 +7801,7 @@ Get marks list in the selected range in text block. - + ### Rpc.File.Upload @@ -7811,7 +7811,7 @@ Get marks list in the selected range in text block. - + ### Rpc.File.Upload.Request @@ -7821,16 +7821,16 @@ Get marks list in the selected range in text block. | ----- | ---- | ----- | ----------- | | url | [string](#string) | | | | localPath | [string](#string) | | | -| type | [model.Block.Content.File.Type](#anytype-model-Block-Content-File-Type) | | | +| type | [model.Block.Content.File.Type](#anytype.model.Block.Content.File.Type) | | | | disableEncryption | [bool](#bool) | | deprecated, has no affect | -| style | [model.Block.Content.File.Style](#anytype-model-Block-Content-File-Style) | | | +| style | [model.Block.Content.File.Style](#anytype.model.Block.Content.File.Style) | | | - + ### Rpc.File.Upload.Response @@ -7838,7 +7838,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.File.Upload.Response.Error](#anytype-Rpc-File-Upload-Response-Error) | | | +| error | [Rpc.File.Upload.Response.Error](#anytype.Rpc.File.Upload.Response.Error) | | | | hash | [string](#string) | | | @@ -7846,7 +7846,7 @@ Get marks list in the selected range in text block. - + ### Rpc.File.Upload.Response.Error @@ -7854,7 +7854,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.File.Upload.Response.Error.Code](#anytype-Rpc-File-Upload-Response-Error-Code) | | | +| code | [Rpc.File.Upload.Response.Error.Code](#anytype.Rpc.File.Upload.Response.Error.Code) | | | | description | [string](#string) | | | @@ -7862,7 +7862,7 @@ Get marks list in the selected range in text block. - + ### Rpc.GenericErrorResponse @@ -7870,14 +7870,14 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.GenericErrorResponse.Error](#anytype-Rpc-GenericErrorResponse-Error) | | | +| error | [Rpc.GenericErrorResponse.Error](#anytype.Rpc.GenericErrorResponse.Error) | | | - + ### Rpc.GenericErrorResponse.Error @@ -7885,7 +7885,7 @@ Get marks list in the selected range in text block. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.GenericErrorResponse.Error.Code](#anytype-Rpc-GenericErrorResponse-Error-Code) | | | +| code | [Rpc.GenericErrorResponse.Error.Code](#anytype.Rpc.GenericErrorResponse.Error.Code) | | | | description | [string](#string) | | | @@ -7893,7 +7893,7 @@ Get marks list in the selected range in text block. - + ### Rpc.History @@ -7903,7 +7903,7 @@ Get marks list in the selected range in text block. - + ### Rpc.History.GetVersions returns list of versions (changes) @@ -7913,7 +7913,7 @@ returns list of versions (changes) - + ### Rpc.History.GetVersions.Request @@ -7930,7 +7930,7 @@ returns list of versions (changes) - + ### Rpc.History.GetVersions.Response @@ -7938,15 +7938,15 @@ returns list of versions (changes) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.History.GetVersions.Response.Error](#anytype-Rpc-History-GetVersions-Response-Error) | | | -| versions | [Rpc.History.Version](#anytype-Rpc-History-Version) | repeated | | +| error | [Rpc.History.GetVersions.Response.Error](#anytype.Rpc.History.GetVersions.Response.Error) | | | +| versions | [Rpc.History.Version](#anytype.Rpc.History.Version) | repeated | | - + ### Rpc.History.GetVersions.Response.Error @@ -7954,7 +7954,7 @@ returns list of versions (changes) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.History.GetVersions.Response.Error.Code](#anytype-Rpc-History-GetVersions-Response-Error-Code) | | | +| code | [Rpc.History.GetVersions.Response.Error.Code](#anytype.Rpc.History.GetVersions.Response.Error.Code) | | | | description | [string](#string) | | | @@ -7962,7 +7962,7 @@ returns list of versions (changes) - + ### Rpc.History.SetVersion @@ -7972,7 +7972,7 @@ returns list of versions (changes) - + ### Rpc.History.SetVersion.Request @@ -7988,7 +7988,7 @@ returns list of versions (changes) - + ### Rpc.History.SetVersion.Response @@ -7996,14 +7996,14 @@ returns list of versions (changes) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.History.SetVersion.Response.Error](#anytype-Rpc-History-SetVersion-Response-Error) | | | +| error | [Rpc.History.SetVersion.Response.Error](#anytype.Rpc.History.SetVersion.Response.Error) | | | - + ### Rpc.History.SetVersion.Response.Error @@ -8011,7 +8011,7 @@ returns list of versions (changes) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.History.SetVersion.Response.Error.Code](#anytype-Rpc-History-SetVersion-Response-Error-Code) | | | +| code | [Rpc.History.SetVersion.Response.Error.Code](#anytype.Rpc.History.SetVersion.Response.Error.Code) | | | | description | [string](#string) | | | @@ -8019,7 +8019,7 @@ returns list of versions (changes) - + ### Rpc.History.ShowVersion returns blockShow event for given version @@ -8029,7 +8029,7 @@ returns blockShow event for given version - + ### Rpc.History.ShowVersion.Request @@ -8046,7 +8046,7 @@ returns blockShow event for given version - + ### Rpc.History.ShowVersion.Response @@ -8054,9 +8054,9 @@ returns blockShow event for given version | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.History.ShowVersion.Response.Error](#anytype-Rpc-History-ShowVersion-Response-Error) | | | -| objectView | [model.ObjectView](#anytype-model-ObjectView) | | | -| version | [Rpc.History.Version](#anytype-Rpc-History-Version) | | | +| error | [Rpc.History.ShowVersion.Response.Error](#anytype.Rpc.History.ShowVersion.Response.Error) | | | +| objectView | [model.ObjectView](#anytype.model.ObjectView) | | | +| version | [Rpc.History.Version](#anytype.Rpc.History.Version) | | | | traceId | [string](#string) | | | @@ -8064,7 +8064,7 @@ returns blockShow event for given version - + ### Rpc.History.ShowVersion.Response.Error @@ -8072,7 +8072,7 @@ returns blockShow event for given version | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.History.ShowVersion.Response.Error.Code](#anytype-Rpc-History-ShowVersion-Response-Error-Code) | | | +| code | [Rpc.History.ShowVersion.Response.Error.Code](#anytype.Rpc.History.ShowVersion.Response.Error.Code) | | | | description | [string](#string) | | | @@ -8080,7 +8080,7 @@ returns blockShow event for given version - + ### Rpc.History.Version @@ -8100,7 +8100,7 @@ returns blockShow event for given version - + ### Rpc.LinkPreview @@ -8110,7 +8110,7 @@ returns blockShow event for given version - + ### Rpc.LinkPreview.Request @@ -8125,7 +8125,7 @@ returns blockShow event for given version - + ### Rpc.LinkPreview.Response @@ -8133,15 +8133,15 @@ returns blockShow event for given version | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.LinkPreview.Response.Error](#anytype-Rpc-LinkPreview-Response-Error) | | | -| linkPreview | [model.LinkPreview](#anytype-model-LinkPreview) | | | +| error | [Rpc.LinkPreview.Response.Error](#anytype.Rpc.LinkPreview.Response.Error) | | | +| linkPreview | [model.LinkPreview](#anytype.model.LinkPreview) | | | - + ### Rpc.LinkPreview.Response.Error @@ -8149,7 +8149,7 @@ returns blockShow event for given version | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.LinkPreview.Response.Error.Code](#anytype-Rpc-LinkPreview-Response-Error-Code) | | | +| code | [Rpc.LinkPreview.Response.Error.Code](#anytype.Rpc.LinkPreview.Response.Error.Code) | | | | description | [string](#string) | | | @@ -8157,7 +8157,7 @@ returns blockShow event for given version - + ### Rpc.Log @@ -8167,7 +8167,7 @@ returns blockShow event for given version - + ### Rpc.Log.Send @@ -8177,7 +8177,7 @@ returns blockShow event for given version - + ### Rpc.Log.Send.Request @@ -8186,14 +8186,14 @@ returns blockShow event for given version | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | message | [string](#string) | | | -| level | [Rpc.Log.Send.Request.Level](#anytype-Rpc-Log-Send-Request-Level) | | | +| level | [Rpc.Log.Send.Request.Level](#anytype.Rpc.Log.Send.Request.Level) | | | - + ### Rpc.Log.Send.Response @@ -8201,14 +8201,14 @@ returns blockShow event for given version | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Log.Send.Response.Error](#anytype-Rpc-Log-Send-Response-Error) | | | +| error | [Rpc.Log.Send.Response.Error](#anytype.Rpc.Log.Send.Response.Error) | | | - + ### Rpc.Log.Send.Response.Error @@ -8216,7 +8216,7 @@ returns blockShow event for given version | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Log.Send.Response.Error.Code](#anytype-Rpc-Log-Send-Response-Error-Code) | | | +| code | [Rpc.Log.Send.Response.Error.Code](#anytype.Rpc.Log.Send.Response.Error.Code) | | | | description | [string](#string) | | | @@ -8224,7 +8224,7 @@ returns blockShow event for given version - + ### Rpc.Metrics @@ -8234,7 +8234,7 @@ returns blockShow event for given version - + ### Rpc.Metrics.SetParameters @@ -8244,7 +8244,7 @@ returns blockShow event for given version - + ### Rpc.Metrics.SetParameters.Request @@ -8259,7 +8259,7 @@ returns blockShow event for given version - + ### Rpc.Metrics.SetParameters.Response @@ -8267,14 +8267,14 @@ returns blockShow event for given version | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Metrics.SetParameters.Response.Error](#anytype-Rpc-Metrics-SetParameters-Response-Error) | | | +| error | [Rpc.Metrics.SetParameters.Response.Error](#anytype.Rpc.Metrics.SetParameters.Response.Error) | | | - + ### Rpc.Metrics.SetParameters.Response.Error @@ -8282,7 +8282,7 @@ returns blockShow event for given version | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Metrics.SetParameters.Response.Error.Code](#anytype-Rpc-Metrics-SetParameters-Response-Error-Code) | | | +| code | [Rpc.Metrics.SetParameters.Response.Error.Code](#anytype.Rpc.Metrics.SetParameters.Response.Error.Code) | | | | description | [string](#string) | | | @@ -8290,7 +8290,7 @@ returns blockShow event for given version - + ### Rpc.Navigation @@ -8300,7 +8300,7 @@ returns blockShow event for given version - + ### Rpc.Navigation.GetObjectInfoWithLinks Get the info for page alongside with info for all inbound and outbound links from/to this page @@ -8310,7 +8310,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Navigation.GetObjectInfoWithLinks.Request @@ -8319,14 +8319,14 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | objectId | [string](#string) | | | -| context | [Rpc.Navigation.Context](#anytype-Rpc-Navigation-Context) | | | +| context | [Rpc.Navigation.Context](#anytype.Rpc.Navigation.Context) | | | - + ### Rpc.Navigation.GetObjectInfoWithLinks.Response @@ -8334,15 +8334,15 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Navigation.GetObjectInfoWithLinks.Response.Error](#anytype-Rpc-Navigation-GetObjectInfoWithLinks-Response-Error) | | | -| object | [model.ObjectInfoWithLinks](#anytype-model-ObjectInfoWithLinks) | | | +| error | [Rpc.Navigation.GetObjectInfoWithLinks.Response.Error](#anytype.Rpc.Navigation.GetObjectInfoWithLinks.Response.Error) | | | +| object | [model.ObjectInfoWithLinks](#anytype.model.ObjectInfoWithLinks) | | | - + ### Rpc.Navigation.GetObjectInfoWithLinks.Response.Error @@ -8350,7 +8350,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Navigation.GetObjectInfoWithLinks.Response.Error.Code](#anytype-Rpc-Navigation-GetObjectInfoWithLinks-Response-Error-Code) | | | +| code | [Rpc.Navigation.GetObjectInfoWithLinks.Response.Error.Code](#anytype.Rpc.Navigation.GetObjectInfoWithLinks.Response.Error.Code) | | | | description | [string](#string) | | | @@ -8358,7 +8358,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Navigation.ListObjects @@ -8368,7 +8368,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Navigation.ListObjects.Request @@ -8376,7 +8376,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| context | [Rpc.Navigation.Context](#anytype-Rpc-Navigation-Context) | | | +| context | [Rpc.Navigation.Context](#anytype.Rpc.Navigation.Context) | | | | fullText | [string](#string) | | | | limit | [int32](#int32) | | | | offset | [int32](#int32) | | | @@ -8386,7 +8386,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Navigation.ListObjects.Response @@ -8394,15 +8394,15 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Navigation.ListObjects.Response.Error](#anytype-Rpc-Navigation-ListObjects-Response-Error) | | | -| objects | [model.ObjectInfo](#anytype-model-ObjectInfo) | repeated | | +| error | [Rpc.Navigation.ListObjects.Response.Error](#anytype.Rpc.Navigation.ListObjects.Response.Error) | | | +| objects | [model.ObjectInfo](#anytype.model.ObjectInfo) | repeated | | - + ### Rpc.Navigation.ListObjects.Response.Error @@ -8410,7 +8410,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Navigation.ListObjects.Response.Error.Code](#anytype-Rpc-Navigation-ListObjects-Response-Error-Code) | | | +| code | [Rpc.Navigation.ListObjects.Response.Error.Code](#anytype.Rpc.Navigation.ListObjects.Response.Error.Code) | | | | description | [string](#string) | | | @@ -8418,7 +8418,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object @@ -8428,7 +8428,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.AddWithObjectId @@ -8438,7 +8438,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.AddWithObjectId.Request @@ -8454,7 +8454,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.AddWithObjectId.Response @@ -8462,14 +8462,14 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.AddWithObjectId.Response.Error](#anytype-Rpc-Object-AddWithObjectId-Response-Error) | | | +| error | [Rpc.Object.AddWithObjectId.Response.Error](#anytype.Rpc.Object.AddWithObjectId.Response.Error) | | | - + ### Rpc.Object.AddWithObjectId.Response.Error @@ -8477,7 +8477,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.AddWithObjectId.Response.Error.Code](#anytype-Rpc-Object-AddWithObjectId-Response-Error-Code) | | | +| code | [Rpc.Object.AddWithObjectId.Response.Error.Code](#anytype.Rpc.Object.AddWithObjectId.Response.Error.Code) | | | | description | [string](#string) | | | @@ -8485,7 +8485,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.ApplyTemplate @@ -8495,7 +8495,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.ApplyTemplate.Request @@ -8511,7 +8511,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.ApplyTemplate.Response @@ -8519,14 +8519,14 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.ApplyTemplate.Response.Error](#anytype-Rpc-Object-ApplyTemplate-Response-Error) | | | +| error | [Rpc.Object.ApplyTemplate.Response.Error](#anytype.Rpc.Object.ApplyTemplate.Response.Error) | | | - + ### Rpc.Object.ApplyTemplate.Response.Error @@ -8534,7 +8534,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.ApplyTemplate.Response.Error.Code](#anytype-Rpc-Object-ApplyTemplate-Response-Error-Code) | | | +| code | [Rpc.Object.ApplyTemplate.Response.Error.Code](#anytype.Rpc.Object.ApplyTemplate.Response.Error.Code) | | | | description | [string](#string) | | | @@ -8542,7 +8542,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.BookmarkFetch @@ -8552,7 +8552,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.BookmarkFetch.Request @@ -8568,7 +8568,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.BookmarkFetch.Response @@ -8576,14 +8576,14 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.BookmarkFetch.Response.Error](#anytype-Rpc-Object-BookmarkFetch-Response-Error) | | | +| error | [Rpc.Object.BookmarkFetch.Response.Error](#anytype.Rpc.Object.BookmarkFetch.Response.Error) | | | - + ### Rpc.Object.BookmarkFetch.Response.Error @@ -8591,7 +8591,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.BookmarkFetch.Response.Error.Code](#anytype-Rpc-Object-BookmarkFetch-Response-Error-Code) | | | +| code | [Rpc.Object.BookmarkFetch.Response.Error.Code](#anytype.Rpc.Object.BookmarkFetch.Response.Error.Code) | | | | description | [string](#string) | | | @@ -8599,7 +8599,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.Close @@ -8609,7 +8609,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.Close.Request @@ -8625,7 +8625,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.Close.Response @@ -8633,14 +8633,14 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.Close.Response.Error](#anytype-Rpc-Object-Close-Response-Error) | | | +| error | [Rpc.Object.Close.Response.Error](#anytype.Rpc.Object.Close.Response.Error) | | | - + ### Rpc.Object.Close.Response.Error @@ -8648,7 +8648,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.Close.Response.Error.Code](#anytype-Rpc-Object-Close-Response-Error-Code) | | | +| code | [Rpc.Object.Close.Response.Error.Code](#anytype.Rpc.Object.Close.Response.Error.Code) | | | | description | [string](#string) | | | @@ -8656,7 +8656,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.Create @@ -8666,7 +8666,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.Create.Request @@ -8674,8 +8674,8 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | object details | -| internalFlags | [model.InternalFlag](#anytype-model-InternalFlag) | repeated | | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | object details | +| internalFlags | [model.InternalFlag](#anytype.model.InternalFlag) | repeated | | | templateId | [string](#string) | | | @@ -8683,7 +8683,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.Create.Response @@ -8691,17 +8691,17 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.Create.Response.Error](#anytype-Rpc-Object-Create-Response-Error) | | | +| error | [Rpc.Object.Create.Response.Error](#anytype.Rpc.Object.Create.Response.Error) | | | | objectId | [string](#string) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### Rpc.Object.Create.Response.Error @@ -8709,7 +8709,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.Create.Response.Error.Code](#anytype-Rpc-Object-Create-Response-Error-Code) | | | +| code | [Rpc.Object.Create.Response.Error.Code](#anytype.Rpc.Object.Create.Response.Error.Code) | | | | description | [string](#string) | | | @@ -8717,7 +8717,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.CreateBookmark @@ -8727,7 +8727,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.CreateBookmark.Request @@ -8735,14 +8735,14 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### Rpc.Object.CreateBookmark.Response @@ -8750,16 +8750,16 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.CreateBookmark.Response.Error](#anytype-Rpc-Object-CreateBookmark-Response-Error) | | | +| error | [Rpc.Object.CreateBookmark.Response.Error](#anytype.Rpc.Object.CreateBookmark.Response.Error) | | | | objectId | [string](#string) | | | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### Rpc.Object.CreateBookmark.Response.Error @@ -8767,7 +8767,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.CreateBookmark.Response.Error.Code](#anytype-Rpc-Object-CreateBookmark-Response-Error-Code) | | | +| code | [Rpc.Object.CreateBookmark.Response.Error.Code](#anytype.Rpc.Object.CreateBookmark.Response.Error.Code) | | | | description | [string](#string) | | | @@ -8775,7 +8775,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.CreateObjectType @@ -8785,7 +8785,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.CreateObjectType.Request @@ -8793,15 +8793,15 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | | -| internalFlags | [model.InternalFlag](#anytype-model-InternalFlag) | repeated | | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | | +| internalFlags | [model.InternalFlag](#anytype.model.InternalFlag) | repeated | | - + ### Rpc.Object.CreateObjectType.Response @@ -8809,8 +8809,8 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.CreateObjectType.Response.Error](#anytype-Rpc-Object-CreateObjectType-Response-Error) | | | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| error | [Rpc.Object.CreateObjectType.Response.Error](#anytype.Rpc.Object.CreateObjectType.Response.Error) | | | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | | | objectId | [string](#string) | | | @@ -8818,7 +8818,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.CreateObjectType.Response.Error @@ -8826,7 +8826,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.CreateObjectType.Response.Error.Code](#anytype-Rpc-Object-CreateObjectType-Response-Error-Code) | | | +| code | [Rpc.Object.CreateObjectType.Response.Error.Code](#anytype.Rpc.Object.CreateObjectType.Response.Error.Code) | | | | description | [string](#string) | | | @@ -8834,7 +8834,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.CreateRelation @@ -8844,7 +8844,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.CreateRelation.Request @@ -8852,14 +8852,14 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### Rpc.Object.CreateRelation.Response @@ -8867,17 +8867,17 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.CreateRelation.Response.Error](#anytype-Rpc-Object-CreateRelation-Response-Error) | | | +| error | [Rpc.Object.CreateRelation.Response.Error](#anytype.Rpc.Object.CreateRelation.Response.Error) | | | | objectId | [string](#string) | | | | key | [string](#string) | | | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### Rpc.Object.CreateRelation.Response.Error @@ -8885,7 +8885,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.CreateRelation.Response.Error.Code](#anytype-Rpc-Object-CreateRelation-Response-Error-Code) | | | +| code | [Rpc.Object.CreateRelation.Response.Error.Code](#anytype.Rpc.Object.CreateRelation.Response.Error.Code) | | | | description | [string](#string) | | | @@ -8893,7 +8893,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.CreateRelationOption @@ -8903,7 +8903,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.CreateRelationOption.Request @@ -8911,14 +8911,14 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### Rpc.Object.CreateRelationOption.Response @@ -8926,16 +8926,16 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.CreateRelationOption.Response.Error](#anytype-Rpc-Object-CreateRelationOption-Response-Error) | | | +| error | [Rpc.Object.CreateRelationOption.Response.Error](#anytype.Rpc.Object.CreateRelationOption.Response.Error) | | | | objectId | [string](#string) | | | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### Rpc.Object.CreateRelationOption.Response.Error @@ -8943,7 +8943,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.CreateRelationOption.Response.Error.Code](#anytype-Rpc-Object-CreateRelationOption-Response-Error-Code) | | | +| code | [Rpc.Object.CreateRelationOption.Response.Error.Code](#anytype.Rpc.Object.CreateRelationOption.Response.Error.Code) | | | | description | [string](#string) | | | @@ -8951,7 +8951,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.CreateSet @@ -8961,7 +8961,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.CreateSet.Request @@ -8970,16 +8970,16 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | source | [string](#string) | repeated | | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | if omitted the name of page will be the same with object type | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | if omitted the name of page will be the same with object type | | templateId | [string](#string) | | optional template id for creating from template | -| internalFlags | [model.InternalFlag](#anytype-model-InternalFlag) | repeated | | +| internalFlags | [model.InternalFlag](#anytype.model.InternalFlag) | repeated | | - + ### Rpc.Object.CreateSet.Response @@ -8987,17 +8987,17 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.CreateSet.Response.Error](#anytype-Rpc-Object-CreateSet-Response-Error) | | | +| error | [Rpc.Object.CreateSet.Response.Error](#anytype.Rpc.Object.CreateSet.Response.Error) | | | | objectId | [string](#string) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### Rpc.Object.CreateSet.Response.Error @@ -9005,7 +9005,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.CreateSet.Response.Error.Code](#anytype-Rpc-Object-CreateSet-Response-Error-Code) | | | +| code | [Rpc.Object.CreateSet.Response.Error.Code](#anytype.Rpc.Object.CreateSet.Response.Error.Code) | | | | description | [string](#string) | | | @@ -9013,7 +9013,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.Duplicate @@ -9023,7 +9023,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.Duplicate.Request @@ -9038,7 +9038,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.Duplicate.Response @@ -9046,7 +9046,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.Duplicate.Response.Error](#anytype-Rpc-Object-Duplicate-Response-Error) | | | +| error | [Rpc.Object.Duplicate.Response.Error](#anytype.Rpc.Object.Duplicate.Response.Error) | | | | id | [string](#string) | | created template id | @@ -9054,7 +9054,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.Duplicate.Response.Error @@ -9062,7 +9062,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.Duplicate.Response.Error.Code](#anytype-Rpc-Object-Duplicate-Response-Error-Code) | | | +| code | [Rpc.Object.Duplicate.Response.Error.Code](#anytype.Rpc.Object.Duplicate.Response.Error.Code) | | | | description | [string](#string) | | | @@ -9070,7 +9070,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.Graph @@ -9080,7 +9080,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.Graph.Edge @@ -9091,7 +9091,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | source | [string](#string) | | | | target | [string](#string) | | | | name | [string](#string) | | | -| type | [Rpc.Object.Graph.Edge.Type](#anytype-Rpc-Object-Graph-Edge-Type) | | | +| type | [Rpc.Object.Graph.Edge.Type](#anytype.Rpc.Object.Graph.Edge.Type) | | | | description | [string](#string) | | | | iconImage | [string](#string) | | | | iconEmoji | [string](#string) | | | @@ -9102,7 +9102,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.Graph.Request @@ -9110,7 +9110,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| filters | [model.Block.Content.Dataview.Filter](#anytype-model-Block-Content-Dataview-Filter) | repeated | | +| filters | [model.Block.Content.Dataview.Filter](#anytype.model.Block.Content.Dataview.Filter) | repeated | | | limit | [int32](#int32) | | | | objectTypeFilter | [string](#string) | repeated | additional filter by objectTypes | | keys | [string](#string) | repeated | | @@ -9120,7 +9120,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.Graph.Response @@ -9128,16 +9128,16 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.Graph.Response.Error](#anytype-Rpc-Object-Graph-Response-Error) | | | -| nodes | [google.protobuf.Struct](#google-protobuf-Struct) | repeated | | -| edges | [Rpc.Object.Graph.Edge](#anytype-Rpc-Object-Graph-Edge) | repeated | | +| error | [Rpc.Object.Graph.Response.Error](#anytype.Rpc.Object.Graph.Response.Error) | | | +| nodes | [google.protobuf.Struct](#google.protobuf.Struct) | repeated | | +| edges | [Rpc.Object.Graph.Edge](#anytype.Rpc.Object.Graph.Edge) | repeated | | - + ### Rpc.Object.Graph.Response.Error @@ -9145,7 +9145,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.Graph.Response.Error.Code](#anytype-Rpc-Object-Graph-Response-Error-Code) | | | +| code | [Rpc.Object.Graph.Response.Error.Code](#anytype.Rpc.Object.Graph.Response.Error.Code) | | | | description | [string](#string) | | | @@ -9153,7 +9153,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.GroupsSubscribe @@ -9163,7 +9163,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.GroupsSubscribe.Request @@ -9173,7 +9173,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | ----- | ---- | ----- | ----------- | | subId | [string](#string) | | | | relationKey | [string](#string) | | | -| filters | [model.Block.Content.Dataview.Filter](#anytype-model-Block-Content-Dataview-Filter) | repeated | | +| filters | [model.Block.Content.Dataview.Filter](#anytype.model.Block.Content.Dataview.Filter) | repeated | | | source | [string](#string) | repeated | | @@ -9181,7 +9181,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.GroupsSubscribe.Response @@ -9189,8 +9189,8 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.GroupsSubscribe.Response.Error](#anytype-Rpc-Object-GroupsSubscribe-Response-Error) | | | -| groups | [model.Block.Content.Dataview.Group](#anytype-model-Block-Content-Dataview-Group) | repeated | | +| error | [Rpc.Object.GroupsSubscribe.Response.Error](#anytype.Rpc.Object.GroupsSubscribe.Response.Error) | | | +| groups | [model.Block.Content.Dataview.Group](#anytype.model.Block.Content.Dataview.Group) | repeated | | | subId | [string](#string) | | | @@ -9198,7 +9198,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.GroupsSubscribe.Response.Error @@ -9206,7 +9206,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.GroupsSubscribe.Response.Error.Code](#anytype-Rpc-Object-GroupsSubscribe-Response-Error-Code) | | | +| code | [Rpc.Object.GroupsSubscribe.Response.Error.Code](#anytype.Rpc.Object.GroupsSubscribe.Response.Error.Code) | | | | description | [string](#string) | | | @@ -9214,7 +9214,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.Import @@ -9224,7 +9224,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.Import.Request @@ -9232,19 +9232,19 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| notionParams | [Rpc.Object.Import.Request.NotionParams](#anytype-Rpc-Object-Import-Request-NotionParams) | | | -| bookmarksParams | [Rpc.Object.Import.Request.BookmarksParams](#anytype-Rpc-Object-Import-Request-BookmarksParams) | | for internal use | -| snapshots | [Rpc.Object.Import.Request.Snapshot](#anytype-Rpc-Object-Import-Request-Snapshot) | repeated | optional, for external developers usage | +| notionParams | [Rpc.Object.Import.Request.NotionParams](#anytype.Rpc.Object.Import.Request.NotionParams) | | | +| bookmarksParams | [Rpc.Object.Import.Request.BookmarksParams](#anytype.Rpc.Object.Import.Request.BookmarksParams) | | for internal use | +| snapshots | [Rpc.Object.Import.Request.Snapshot](#anytype.Rpc.Object.Import.Request.Snapshot) | repeated | optional, for external developers usage | | updateExistingObjects | [bool](#bool) | | | -| type | [Rpc.Object.Import.Request.Type](#anytype-Rpc-Object-Import-Request-Type) | | | -| mode | [Rpc.Object.Import.Request.Mode](#anytype-Rpc-Object-Import-Request-Mode) | | | +| type | [Rpc.Object.Import.Request.Type](#anytype.Rpc.Object.Import.Request.Type) | | | +| mode | [Rpc.Object.Import.Request.Mode](#anytype.Rpc.Object.Import.Request.Mode) | | | - + ### Rpc.Object.Import.Request.BookmarksParams @@ -9259,7 +9259,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.Import.Request.NotionParams @@ -9274,7 +9274,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.Import.Request.Snapshot @@ -9283,14 +9283,14 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| snapshot | [model.SmartBlockSnapshotBase](#anytype-model-SmartBlockSnapshotBase) | | | +| snapshot | [model.SmartBlockSnapshotBase](#anytype.model.SmartBlockSnapshotBase) | | | - + ### Rpc.Object.Import.Response @@ -9298,14 +9298,14 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.Import.Response.Error](#anytype-Rpc-Object-Import-Response-Error) | | | +| error | [Rpc.Object.Import.Response.Error](#anytype.Rpc.Object.Import.Response.Error) | | | - + ### Rpc.Object.Import.Response.Error @@ -9313,7 +9313,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.Import.Response.Error.Code](#anytype-Rpc-Object-Import-Response-Error-Code) | | | +| code | [Rpc.Object.Import.Response.Error.Code](#anytype.Rpc.Object.Import.Response.Error.Code) | | | | description | [string](#string) | | | @@ -9321,7 +9321,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.ImportList @@ -9331,7 +9331,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.ImportList.ImportResponse @@ -9339,14 +9339,14 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| type | [Rpc.Object.ImportList.ImportResponse.Type](#anytype-Rpc-Object-ImportList-ImportResponse-Type) | | | +| type | [Rpc.Object.ImportList.ImportResponse.Type](#anytype.Rpc.Object.ImportList.ImportResponse.Type) | | | - + ### Rpc.Object.ImportList.Request @@ -9356,7 +9356,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.ImportList.Response @@ -9364,15 +9364,15 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.ImportList.Response.Error](#anytype-Rpc-Object-ImportList-Response-Error) | | | -| response | [Rpc.Object.ImportList.ImportResponse](#anytype-Rpc-Object-ImportList-ImportResponse) | repeated | | +| error | [Rpc.Object.ImportList.Response.Error](#anytype.Rpc.Object.ImportList.Response.Error) | | | +| response | [Rpc.Object.ImportList.ImportResponse](#anytype.Rpc.Object.ImportList.ImportResponse) | repeated | | - + ### Rpc.Object.ImportList.Response.Error @@ -9380,7 +9380,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.ImportList.Response.Error.Code](#anytype-Rpc-Object-ImportList-Response-Error-Code) | | | +| code | [Rpc.Object.ImportList.Response.Error.Code](#anytype.Rpc.Object.ImportList.Response.Error.Code) | | | | description | [string](#string) | | | @@ -9388,7 +9388,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.ImportMarkdown @@ -9398,7 +9398,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.ImportMarkdown.Request @@ -9414,7 +9414,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.ImportMarkdown.Response @@ -9422,16 +9422,16 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.ImportMarkdown.Response.Error](#anytype-Rpc-Object-ImportMarkdown-Response-Error) | | | +| error | [Rpc.Object.ImportMarkdown.Response.Error](#anytype.Rpc.Object.ImportMarkdown.Response.Error) | | | | rootLinkIds | [string](#string) | repeated | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Object.ImportMarkdown.Response.Error @@ -9439,7 +9439,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.ImportMarkdown.Response.Error.Code](#anytype-Rpc-Object-ImportMarkdown-Response-Error-Code) | | | +| code | [Rpc.Object.ImportMarkdown.Response.Error.Code](#anytype.Rpc.Object.ImportMarkdown.Response.Error.Code) | | | | description | [string](#string) | | | @@ -9447,7 +9447,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.ListDelete @@ -9457,7 +9457,7 @@ Get the info for page alongside with info for all inbound and outbound links fro - + ### Rpc.Object.ListDelete.Request Deletes the object, keys from the local store and unsubscribe from remote changes. Also offloads all orphan files @@ -9472,7 +9472,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.ListDelete.Response @@ -9480,15 +9480,15 @@ Deletes the object, keys from the local store and unsubscribe from remote change | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.ListDelete.Response.Error](#anytype-Rpc-Object-ListDelete-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.Object.ListDelete.Response.Error](#anytype.Rpc.Object.ListDelete.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Object.ListDelete.Response.Error @@ -9496,7 +9496,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.ListDelete.Response.Error.Code](#anytype-Rpc-Object-ListDelete-Response-Error-Code) | | | +| code | [Rpc.Object.ListDelete.Response.Error.Code](#anytype.Rpc.Object.ListDelete.Response.Error.Code) | | | | description | [string](#string) | | | @@ -9504,7 +9504,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.ListDuplicate @@ -9514,7 +9514,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.ListDuplicate.Request @@ -9529,7 +9529,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.ListDuplicate.Response @@ -9537,7 +9537,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.ListDuplicate.Response.Error](#anytype-Rpc-Object-ListDuplicate-Response-Error) | | | +| error | [Rpc.Object.ListDuplicate.Response.Error](#anytype.Rpc.Object.ListDuplicate.Response.Error) | | | | ids | [string](#string) | repeated | | @@ -9545,7 +9545,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.ListDuplicate.Response.Error @@ -9553,7 +9553,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.ListDuplicate.Response.Error.Code](#anytype-Rpc-Object-ListDuplicate-Response-Error-Code) | | | +| code | [Rpc.Object.ListDuplicate.Response.Error.Code](#anytype.Rpc.Object.ListDuplicate.Response.Error.Code) | | | | description | [string](#string) | | | @@ -9561,7 +9561,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.ListExport @@ -9571,7 +9571,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.ListExport.Request @@ -9581,7 +9581,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change | ----- | ---- | ----- | ----------- | | path | [string](#string) | | the path where export files will place | | objectIds | [string](#string) | repeated | ids of documents for export, when empty - will export all available docs | -| format | [Rpc.Object.ListExport.Format](#anytype-Rpc-Object-ListExport-Format) | | export format | +| format | [Rpc.Object.ListExport.Format](#anytype.Rpc.Object.ListExport.Format) | | export format | | zip | [bool](#bool) | | save as zip file | | includeNested | [bool](#bool) | | include all nested | | includeFiles | [bool](#bool) | | include all files | @@ -9591,7 +9591,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.ListExport.Response @@ -9599,17 +9599,17 @@ Deletes the object, keys from the local store and unsubscribe from remote change | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.ListExport.Response.Error](#anytype-Rpc-Object-ListExport-Response-Error) | | | +| error | [Rpc.Object.ListExport.Response.Error](#anytype.Rpc.Object.ListExport.Response.Error) | | | | path | [string](#string) | | | | succeed | [int32](#int32) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Object.ListExport.Response.Error @@ -9617,7 +9617,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.ListExport.Response.Error.Code](#anytype-Rpc-Object-ListExport-Response-Error-Code) | | | +| code | [Rpc.Object.ListExport.Response.Error.Code](#anytype.Rpc.Object.ListExport.Response.Error.Code) | | | | description | [string](#string) | | | @@ -9625,7 +9625,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.ListSetIsArchived @@ -9635,7 +9635,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.ListSetIsArchived.Request @@ -9651,7 +9651,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.ListSetIsArchived.Response @@ -9659,14 +9659,14 @@ Deletes the object, keys from the local store and unsubscribe from remote change | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.ListSetIsArchived.Response.Error](#anytype-Rpc-Object-ListSetIsArchived-Response-Error) | | | +| error | [Rpc.Object.ListSetIsArchived.Response.Error](#anytype.Rpc.Object.ListSetIsArchived.Response.Error) | | | - + ### Rpc.Object.ListSetIsArchived.Response.Error @@ -9674,7 +9674,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.ListSetIsArchived.Response.Error.Code](#anytype-Rpc-Object-ListSetIsArchived-Response-Error-Code) | | | +| code | [Rpc.Object.ListSetIsArchived.Response.Error.Code](#anytype.Rpc.Object.ListSetIsArchived.Response.Error.Code) | | | | description | [string](#string) | | | @@ -9682,7 +9682,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.ListSetIsFavorite @@ -9692,7 +9692,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.ListSetIsFavorite.Request @@ -9708,7 +9708,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.ListSetIsFavorite.Response @@ -9716,14 +9716,14 @@ Deletes the object, keys from the local store and unsubscribe from remote change | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.ListSetIsFavorite.Response.Error](#anytype-Rpc-Object-ListSetIsFavorite-Response-Error) | | | +| error | [Rpc.Object.ListSetIsFavorite.Response.Error](#anytype.Rpc.Object.ListSetIsFavorite.Response.Error) | | | - + ### Rpc.Object.ListSetIsFavorite.Response.Error @@ -9731,7 +9731,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.ListSetIsFavorite.Response.Error.Code](#anytype-Rpc-Object-ListSetIsFavorite-Response-Error-Code) | | | +| code | [Rpc.Object.ListSetIsFavorite.Response.Error.Code](#anytype.Rpc.Object.ListSetIsFavorite.Response.Error.Code) | | | | description | [string](#string) | | | @@ -9739,7 +9739,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.Open @@ -9749,7 +9749,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.Open.Request @@ -9767,7 +9767,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.Open.Response @@ -9775,15 +9775,15 @@ Deletes the object, keys from the local store and unsubscribe from remote change | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.Open.Response.Error](#anytype-Rpc-Object-Open-Response-Error) | | | -| objectView | [model.ObjectView](#anytype-model-ObjectView) | | | +| error | [Rpc.Object.Open.Response.Error](#anytype.Rpc.Object.Open.Response.Error) | | | +| objectView | [model.ObjectView](#anytype.model.ObjectView) | | | - + ### Rpc.Object.Open.Response.Error @@ -9791,7 +9791,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.Open.Response.Error.Code](#anytype-Rpc-Object-Open-Response-Error-Code) | | | +| code | [Rpc.Object.Open.Response.Error.Code](#anytype.Rpc.Object.Open.Response.Error.Code) | | | | description | [string](#string) | | | @@ -9799,7 +9799,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.OpenBreadcrumbs @@ -9809,7 +9809,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.OpenBreadcrumbs.Request @@ -9825,7 +9825,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.OpenBreadcrumbs.Response @@ -9833,17 +9833,17 @@ Deletes the object, keys from the local store and unsubscribe from remote change | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.OpenBreadcrumbs.Response.Error](#anytype-Rpc-Object-OpenBreadcrumbs-Response-Error) | | | +| error | [Rpc.Object.OpenBreadcrumbs.Response.Error](#anytype.Rpc.Object.OpenBreadcrumbs.Response.Error) | | | | objectId | [string](#string) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | -| objectView | [model.ObjectView](#anytype-model-ObjectView) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | +| objectView | [model.ObjectView](#anytype.model.ObjectView) | | | - + ### Rpc.Object.OpenBreadcrumbs.Response.Error @@ -9851,7 +9851,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.OpenBreadcrumbs.Response.Error.Code](#anytype-Rpc-Object-OpenBreadcrumbs-Response-Error-Code) | | | +| code | [Rpc.Object.OpenBreadcrumbs.Response.Error.Code](#anytype.Rpc.Object.OpenBreadcrumbs.Response.Error.Code) | | | | description | [string](#string) | | | @@ -9859,7 +9859,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.Redo @@ -9869,7 +9869,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.Redo.Request @@ -9884,7 +9884,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.Redo.Response @@ -9892,16 +9892,16 @@ Deletes the object, keys from the local store and unsubscribe from remote change | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.Redo.Response.Error](#anytype-Rpc-Object-Redo-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | -| counters | [Rpc.Object.UndoRedoCounter](#anytype-Rpc-Object-UndoRedoCounter) | | | +| error | [Rpc.Object.Redo.Response.Error](#anytype.Rpc.Object.Redo.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | +| counters | [Rpc.Object.UndoRedoCounter](#anytype.Rpc.Object.UndoRedoCounter) | | | - + ### Rpc.Object.Redo.Response.Error @@ -9909,7 +9909,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.Redo.Response.Error.Code](#anytype-Rpc-Object-Redo-Response-Error-Code) | | | +| code | [Rpc.Object.Redo.Response.Error.Code](#anytype.Rpc.Object.Redo.Response.Error.Code) | | | | description | [string](#string) | | | @@ -9917,7 +9917,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.Search @@ -9927,7 +9927,7 @@ Deletes the object, keys from the local store and unsubscribe from remote change - + ### Rpc.Object.Search.Request @@ -9935,8 +9935,8 @@ Deletes the object, keys from the local store and unsubscribe from remote change | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| filters | [model.Block.Content.Dataview.Filter](#anytype-model-Block-Content-Dataview-Filter) | repeated | | -| sorts | [model.Block.Content.Dataview.Sort](#anytype-model-Block-Content-Dataview-Sort) | repeated | | +| filters | [model.Block.Content.Dataview.Filter](#anytype.model.Block.Content.Dataview.Filter) | repeated | | +| sorts | [model.Block.Content.Dataview.Sort](#anytype.model.Block.Content.Dataview.Sort) | repeated | | | fullText | [string](#string) | | | | offset | [int32](#int32) | | | | limit | [int32](#int32) | | | @@ -9950,7 +9950,7 @@ deprecated, to be removed | - + ### Rpc.Object.Search.Response @@ -9958,15 +9958,15 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.Search.Response.Error](#anytype-Rpc-Object-Search-Response-Error) | | | -| records | [google.protobuf.Struct](#google-protobuf-Struct) | repeated | | +| error | [Rpc.Object.Search.Response.Error](#anytype.Rpc.Object.Search.Response.Error) | | | +| records | [google.protobuf.Struct](#google.protobuf.Struct) | repeated | | - + ### Rpc.Object.Search.Response.Error @@ -9974,7 +9974,7 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.Search.Response.Error.Code](#anytype-Rpc-Object-Search-Response-Error-Code) | | | +| code | [Rpc.Object.Search.Response.Error.Code](#anytype.Rpc.Object.Search.Response.Error.Code) | | | | description | [string](#string) | | | @@ -9982,7 +9982,7 @@ deprecated, to be removed | - + ### Rpc.Object.SearchSubscribe @@ -9992,7 +9992,7 @@ deprecated, to be removed | - + ### Rpc.Object.SearchSubscribe.Request @@ -10001,8 +10001,8 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | subId | [string](#string) | | (optional) subscription identifier client can provide some string or middleware will generate it automatically if subId is already registered on middleware, the new query will replace previous subscription | -| filters | [model.Block.Content.Dataview.Filter](#anytype-model-Block-Content-Dataview-Filter) | repeated | filters | -| sorts | [model.Block.Content.Dataview.Sort](#anytype-model-Block-Content-Dataview-Sort) | repeated | sorts | +| filters | [model.Block.Content.Dataview.Filter](#anytype.model.Block.Content.Dataview.Filter) | repeated | filters | +| sorts | [model.Block.Content.Dataview.Sort](#anytype.model.Block.Content.Dataview.Sort) | repeated | sorts | | limit | [int64](#int64) | | results limit | | offset | [int64](#int64) | | initial offset; middleware will find afterId | | keys | [string](#string) | repeated | (required) needed keys in details for return, for object fields mw will return (and subscribe) objects as dependent | @@ -10017,7 +10017,7 @@ deprecated, to be removed | - + ### Rpc.Object.SearchSubscribe.Response @@ -10025,18 +10025,18 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.SearchSubscribe.Response.Error](#anytype-Rpc-Object-SearchSubscribe-Response-Error) | | | -| records | [google.protobuf.Struct](#google-protobuf-Struct) | repeated | | -| dependencies | [google.protobuf.Struct](#google-protobuf-Struct) | repeated | | +| error | [Rpc.Object.SearchSubscribe.Response.Error](#anytype.Rpc.Object.SearchSubscribe.Response.Error) | | | +| records | [google.protobuf.Struct](#google.protobuf.Struct) | repeated | | +| dependencies | [google.protobuf.Struct](#google.protobuf.Struct) | repeated | | | subId | [string](#string) | | | -| counters | [Event.Object.Subscription.Counters](#anytype-Event-Object-Subscription-Counters) | | | +| counters | [Event.Object.Subscription.Counters](#anytype.Event.Object.Subscription.Counters) | | | - + ### Rpc.Object.SearchSubscribe.Response.Error @@ -10044,7 +10044,7 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.SearchSubscribe.Response.Error.Code](#anytype-Rpc-Object-SearchSubscribe-Response-Error-Code) | | | +| code | [Rpc.Object.SearchSubscribe.Response.Error.Code](#anytype.Rpc.Object.SearchSubscribe.Response.Error.Code) | | | | description | [string](#string) | | | @@ -10052,7 +10052,7 @@ deprecated, to be removed | - + ### Rpc.Object.SearchUnsubscribe @@ -10062,7 +10062,7 @@ deprecated, to be removed | - + ### Rpc.Object.SearchUnsubscribe.Request @@ -10077,7 +10077,7 @@ deprecated, to be removed | - + ### Rpc.Object.SearchUnsubscribe.Response @@ -10085,14 +10085,14 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.SearchUnsubscribe.Response.Error](#anytype-Rpc-Object-SearchUnsubscribe-Response-Error) | | | +| error | [Rpc.Object.SearchUnsubscribe.Response.Error](#anytype.Rpc.Object.SearchUnsubscribe.Response.Error) | | | - + ### Rpc.Object.SearchUnsubscribe.Response.Error @@ -10100,7 +10100,7 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.SearchUnsubscribe.Response.Error.Code](#anytype-Rpc-Object-SearchUnsubscribe-Response-Error-Code) | | | +| code | [Rpc.Object.SearchUnsubscribe.Response.Error.Code](#anytype.Rpc.Object.SearchUnsubscribe.Response.Error.Code) | | | | description | [string](#string) | | | @@ -10108,7 +10108,7 @@ deprecated, to be removed | - + ### Rpc.Object.SetBreadcrumbs @@ -10118,7 +10118,7 @@ deprecated, to be removed | - + ### Rpc.Object.SetBreadcrumbs.Request @@ -10134,7 +10134,7 @@ deprecated, to be removed | - + ### Rpc.Object.SetBreadcrumbs.Response @@ -10142,15 +10142,15 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.SetBreadcrumbs.Response.Error](#anytype-Rpc-Object-SetBreadcrumbs-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.Object.SetBreadcrumbs.Response.Error](#anytype.Rpc.Object.SetBreadcrumbs.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Object.SetBreadcrumbs.Response.Error @@ -10158,7 +10158,7 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.SetBreadcrumbs.Response.Error.Code](#anytype-Rpc-Object-SetBreadcrumbs-Response-Error-Code) | | | +| code | [Rpc.Object.SetBreadcrumbs.Response.Error.Code](#anytype.Rpc.Object.SetBreadcrumbs.Response.Error.Code) | | | | description | [string](#string) | | | @@ -10166,7 +10166,7 @@ deprecated, to be removed | - + ### Rpc.Object.SetDetails @@ -10176,7 +10176,7 @@ deprecated, to be removed | - + ### Rpc.Object.SetDetails.Detail @@ -10185,14 +10185,14 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | key | [string](#string) | | | -| value | [google.protobuf.Value](#google-protobuf-Value) | | NUll - removes key | +| value | [google.protobuf.Value](#google.protobuf.Value) | | NUll - removes key | - + ### Rpc.Object.SetDetails.Request @@ -10201,14 +10201,14 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | -| details | [Rpc.Object.SetDetails.Detail](#anytype-Rpc-Object-SetDetails-Detail) | repeated | | +| details | [Rpc.Object.SetDetails.Detail](#anytype.Rpc.Object.SetDetails.Detail) | repeated | | - + ### Rpc.Object.SetDetails.Response @@ -10216,15 +10216,15 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.SetDetails.Response.Error](#anytype-Rpc-Object-SetDetails-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.Object.SetDetails.Response.Error](#anytype.Rpc.Object.SetDetails.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Object.SetDetails.Response.Error @@ -10232,7 +10232,7 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.SetDetails.Response.Error.Code](#anytype-Rpc-Object-SetDetails-Response-Error-Code) | | | +| code | [Rpc.Object.SetDetails.Response.Error.Code](#anytype.Rpc.Object.SetDetails.Response.Error.Code) | | | | description | [string](#string) | | | @@ -10240,7 +10240,7 @@ deprecated, to be removed | - + ### Rpc.Object.SetInternalFlags @@ -10250,7 +10250,7 @@ deprecated, to be removed | - + ### Rpc.Object.SetInternalFlags.Request @@ -10259,14 +10259,14 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | -| internalFlags | [model.InternalFlag](#anytype-model-InternalFlag) | repeated | | +| internalFlags | [model.InternalFlag](#anytype.model.InternalFlag) | repeated | | - + ### Rpc.Object.SetInternalFlags.Response @@ -10274,15 +10274,15 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.SetInternalFlags.Response.Error](#anytype-Rpc-Object-SetInternalFlags-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.Object.SetInternalFlags.Response.Error](#anytype.Rpc.Object.SetInternalFlags.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Object.SetInternalFlags.Response.Error @@ -10290,7 +10290,7 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.SetInternalFlags.Response.Error.Code](#anytype-Rpc-Object-SetInternalFlags-Response-Error-Code) | | | +| code | [Rpc.Object.SetInternalFlags.Response.Error.Code](#anytype.Rpc.Object.SetInternalFlags.Response.Error.Code) | | | | description | [string](#string) | | | @@ -10298,7 +10298,7 @@ deprecated, to be removed | - + ### Rpc.Object.SetIsArchived @@ -10308,7 +10308,7 @@ deprecated, to be removed | - + ### Rpc.Object.SetIsArchived.Request @@ -10324,7 +10324,7 @@ deprecated, to be removed | - + ### Rpc.Object.SetIsArchived.Response @@ -10332,15 +10332,15 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.SetIsArchived.Response.Error](#anytype-Rpc-Object-SetIsArchived-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.Object.SetIsArchived.Response.Error](#anytype.Rpc.Object.SetIsArchived.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Object.SetIsArchived.Response.Error @@ -10348,7 +10348,7 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.SetIsArchived.Response.Error.Code](#anytype-Rpc-Object-SetIsArchived-Response-Error-Code) | | | +| code | [Rpc.Object.SetIsArchived.Response.Error.Code](#anytype.Rpc.Object.SetIsArchived.Response.Error.Code) | | | | description | [string](#string) | | | @@ -10356,7 +10356,7 @@ deprecated, to be removed | - + ### Rpc.Object.SetIsFavorite @@ -10366,7 +10366,7 @@ deprecated, to be removed | - + ### Rpc.Object.SetIsFavorite.Request @@ -10382,7 +10382,7 @@ deprecated, to be removed | - + ### Rpc.Object.SetIsFavorite.Response @@ -10390,15 +10390,15 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.SetIsFavorite.Response.Error](#anytype-Rpc-Object-SetIsFavorite-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.Object.SetIsFavorite.Response.Error](#anytype.Rpc.Object.SetIsFavorite.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Object.SetIsFavorite.Response.Error @@ -10406,7 +10406,7 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.SetIsFavorite.Response.Error.Code](#anytype-Rpc-Object-SetIsFavorite-Response-Error-Code) | | | +| code | [Rpc.Object.SetIsFavorite.Response.Error.Code](#anytype.Rpc.Object.SetIsFavorite.Response.Error.Code) | | | | description | [string](#string) | | | @@ -10414,7 +10414,7 @@ deprecated, to be removed | - + ### Rpc.Object.SetLayout @@ -10424,7 +10424,7 @@ deprecated, to be removed | - + ### Rpc.Object.SetLayout.Request @@ -10433,14 +10433,14 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | contextId | [string](#string) | | | -| layout | [model.ObjectType.Layout](#anytype-model-ObjectType-Layout) | | | +| layout | [model.ObjectType.Layout](#anytype.model.ObjectType.Layout) | | | - + ### Rpc.Object.SetLayout.Response @@ -10448,15 +10448,15 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.SetLayout.Response.Error](#anytype-Rpc-Object-SetLayout-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.Object.SetLayout.Response.Error](#anytype.Rpc.Object.SetLayout.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Object.SetLayout.Response.Error @@ -10464,7 +10464,7 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.SetLayout.Response.Error.Code](#anytype-Rpc-Object-SetLayout-Response-Error-Code) | | | +| code | [Rpc.Object.SetLayout.Response.Error.Code](#anytype.Rpc.Object.SetLayout.Response.Error.Code) | | | | description | [string](#string) | | | @@ -10472,7 +10472,7 @@ deprecated, to be removed | - + ### Rpc.Object.SetObjectType @@ -10482,7 +10482,7 @@ deprecated, to be removed | - + ### Rpc.Object.SetObjectType.Request @@ -10498,7 +10498,7 @@ deprecated, to be removed | - + ### Rpc.Object.SetObjectType.Response @@ -10506,15 +10506,15 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.SetObjectType.Response.Error](#anytype-Rpc-Object-SetObjectType-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.Object.SetObjectType.Response.Error](#anytype.Rpc.Object.SetObjectType.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Object.SetObjectType.Response.Error @@ -10522,7 +10522,7 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.SetObjectType.Response.Error.Code](#anytype-Rpc-Object-SetObjectType-Response-Error-Code) | | | +| code | [Rpc.Object.SetObjectType.Response.Error.Code](#anytype.Rpc.Object.SetObjectType.Response.Error.Code) | | | | description | [string](#string) | | | @@ -10530,7 +10530,7 @@ deprecated, to be removed | - + ### Rpc.Object.ShareByLink @@ -10540,7 +10540,7 @@ deprecated, to be removed | - + ### Rpc.Object.ShareByLink.Request @@ -10555,7 +10555,7 @@ deprecated, to be removed | - + ### Rpc.Object.ShareByLink.Response @@ -10564,14 +10564,14 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | link | [string](#string) | | | -| error | [Rpc.Object.ShareByLink.Response.Error](#anytype-Rpc-Object-ShareByLink-Response-Error) | | | +| error | [Rpc.Object.ShareByLink.Response.Error](#anytype.Rpc.Object.ShareByLink.Response.Error) | | | - + ### Rpc.Object.ShareByLink.Response.Error @@ -10579,7 +10579,7 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.ShareByLink.Response.Error.Code](#anytype-Rpc-Object-ShareByLink-Response-Error-Code) | | | +| code | [Rpc.Object.ShareByLink.Response.Error.Code](#anytype.Rpc.Object.ShareByLink.Response.Error.Code) | | | | description | [string](#string) | | | @@ -10587,7 +10587,7 @@ deprecated, to be removed | - + ### Rpc.Object.Show @@ -10597,7 +10597,7 @@ deprecated, to be removed | - + ### Rpc.Object.Show.Request @@ -10615,7 +10615,7 @@ deprecated, to be removed | - + ### Rpc.Object.Show.Response @@ -10623,15 +10623,15 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.Show.Response.Error](#anytype-Rpc-Object-Show-Response-Error) | | | -| objectView | [model.ObjectView](#anytype-model-ObjectView) | | | +| error | [Rpc.Object.Show.Response.Error](#anytype.Rpc.Object.Show.Response.Error) | | | +| objectView | [model.ObjectView](#anytype.model.ObjectView) | | | - + ### Rpc.Object.Show.Response.Error @@ -10639,7 +10639,7 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.Show.Response.Error.Code](#anytype-Rpc-Object-Show-Response-Error-Code) | | | +| code | [Rpc.Object.Show.Response.Error.Code](#anytype.Rpc.Object.Show.Response.Error.Code) | | | | description | [string](#string) | | | @@ -10647,7 +10647,7 @@ deprecated, to be removed | - + ### Rpc.Object.SubscribeIds @@ -10657,7 +10657,7 @@ deprecated, to be removed | - + ### Rpc.Object.SubscribeIds.Request @@ -10675,7 +10675,7 @@ deprecated, to be removed | - + ### Rpc.Object.SubscribeIds.Response @@ -10683,9 +10683,9 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.SubscribeIds.Response.Error](#anytype-Rpc-Object-SubscribeIds-Response-Error) | | | -| records | [google.protobuf.Struct](#google-protobuf-Struct) | repeated | | -| dependencies | [google.protobuf.Struct](#google-protobuf-Struct) | repeated | | +| error | [Rpc.Object.SubscribeIds.Response.Error](#anytype.Rpc.Object.SubscribeIds.Response.Error) | | | +| records | [google.protobuf.Struct](#google.protobuf.Struct) | repeated | | +| dependencies | [google.protobuf.Struct](#google.protobuf.Struct) | repeated | | | subId | [string](#string) | | | @@ -10693,7 +10693,7 @@ deprecated, to be removed | - + ### Rpc.Object.SubscribeIds.Response.Error @@ -10701,7 +10701,7 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.SubscribeIds.Response.Error.Code](#anytype-Rpc-Object-SubscribeIds-Response-Error-Code) | | | +| code | [Rpc.Object.SubscribeIds.Response.Error.Code](#anytype.Rpc.Object.SubscribeIds.Response.Error.Code) | | | | description | [string](#string) | | | @@ -10709,7 +10709,7 @@ deprecated, to be removed | - + ### Rpc.Object.ToBookmark @@ -10719,7 +10719,7 @@ deprecated, to be removed | - + ### Rpc.Object.ToBookmark.Request @@ -10735,7 +10735,7 @@ deprecated, to be removed | - + ### Rpc.Object.ToBookmark.Response @@ -10743,7 +10743,7 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.ToBookmark.Response.Error](#anytype-Rpc-Object-ToBookmark-Response-Error) | | | +| error | [Rpc.Object.ToBookmark.Response.Error](#anytype.Rpc.Object.ToBookmark.Response.Error) | | | | objectId | [string](#string) | | | @@ -10751,7 +10751,7 @@ deprecated, to be removed | - + ### Rpc.Object.ToBookmark.Response.Error @@ -10759,7 +10759,7 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.ToBookmark.Response.Error.Code](#anytype-Rpc-Object-ToBookmark-Response-Error-Code) | | | +| code | [Rpc.Object.ToBookmark.Response.Error.Code](#anytype.Rpc.Object.ToBookmark.Response.Error.Code) | | | | description | [string](#string) | | | @@ -10767,7 +10767,7 @@ deprecated, to be removed | - + ### Rpc.Object.ToSet @@ -10777,7 +10777,7 @@ deprecated, to be removed | - + ### Rpc.Object.ToSet.Request @@ -10793,7 +10793,7 @@ deprecated, to be removed | - + ### Rpc.Object.ToSet.Response @@ -10801,7 +10801,7 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.ToSet.Response.Error](#anytype-Rpc-Object-ToSet-Response-Error) | | | +| error | [Rpc.Object.ToSet.Response.Error](#anytype.Rpc.Object.ToSet.Response.Error) | | | | setId | [string](#string) | | | @@ -10809,7 +10809,7 @@ deprecated, to be removed | - + ### Rpc.Object.ToSet.Response.Error @@ -10817,7 +10817,7 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.ToSet.Response.Error.Code](#anytype-Rpc-Object-ToSet-Response-Error-Code) | | | +| code | [Rpc.Object.ToSet.Response.Error.Code](#anytype.Rpc.Object.ToSet.Response.Error.Code) | | | | description | [string](#string) | | | @@ -10825,7 +10825,7 @@ deprecated, to be removed | - + ### Rpc.Object.Undo @@ -10835,7 +10835,7 @@ deprecated, to be removed | - + ### Rpc.Object.Undo.Request @@ -10850,7 +10850,7 @@ deprecated, to be removed | - + ### Rpc.Object.Undo.Response @@ -10858,16 +10858,16 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Object.Undo.Response.Error](#anytype-Rpc-Object-Undo-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | -| counters | [Rpc.Object.UndoRedoCounter](#anytype-Rpc-Object-UndoRedoCounter) | | | +| error | [Rpc.Object.Undo.Response.Error](#anytype.Rpc.Object.Undo.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | +| counters | [Rpc.Object.UndoRedoCounter](#anytype.Rpc.Object.UndoRedoCounter) | | | - + ### Rpc.Object.Undo.Response.Error @@ -10875,7 +10875,7 @@ deprecated, to be removed | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Object.Undo.Response.Error.Code](#anytype-Rpc-Object-Undo-Response-Error-Code) | | | +| code | [Rpc.Object.Undo.Response.Error.Code](#anytype.Rpc.Object.Undo.Response.Error.Code) | | | | description | [string](#string) | | | @@ -10883,7 +10883,7 @@ deprecated, to be removed | - + ### Rpc.Object.UndoRedoCounter Available undo/redo operations @@ -10899,7 +10899,7 @@ Available undo/redo operations - + ### Rpc.ObjectRelation @@ -10909,7 +10909,7 @@ Available undo/redo operations - + ### Rpc.ObjectRelation.Add @@ -10919,7 +10919,7 @@ Available undo/redo operations - + ### Rpc.ObjectRelation.Add.Request @@ -10935,7 +10935,7 @@ Available undo/redo operations - + ### Rpc.ObjectRelation.Add.Response @@ -10943,15 +10943,15 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.ObjectRelation.Add.Response.Error](#anytype-Rpc-ObjectRelation-Add-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.ObjectRelation.Add.Response.Error](#anytype.Rpc.ObjectRelation.Add.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.ObjectRelation.Add.Response.Error @@ -10959,7 +10959,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.ObjectRelation.Add.Response.Error.Code](#anytype-Rpc-ObjectRelation-Add-Response-Error-Code) | | | +| code | [Rpc.ObjectRelation.Add.Response.Error.Code](#anytype.Rpc.ObjectRelation.Add.Response.Error.Code) | | | | description | [string](#string) | | | @@ -10967,7 +10967,7 @@ Available undo/redo operations - + ### Rpc.ObjectRelation.AddFeatured @@ -10977,7 +10977,7 @@ Available undo/redo operations - + ### Rpc.ObjectRelation.AddFeatured.Request @@ -10993,7 +10993,7 @@ Available undo/redo operations - + ### Rpc.ObjectRelation.AddFeatured.Response @@ -11001,15 +11001,15 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.ObjectRelation.AddFeatured.Response.Error](#anytype-Rpc-ObjectRelation-AddFeatured-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.ObjectRelation.AddFeatured.Response.Error](#anytype.Rpc.ObjectRelation.AddFeatured.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.ObjectRelation.AddFeatured.Response.Error @@ -11017,7 +11017,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.ObjectRelation.AddFeatured.Response.Error.Code](#anytype-Rpc-ObjectRelation-AddFeatured-Response-Error-Code) | | | +| code | [Rpc.ObjectRelation.AddFeatured.Response.Error.Code](#anytype.Rpc.ObjectRelation.AddFeatured.Response.Error.Code) | | | | description | [string](#string) | | | @@ -11025,7 +11025,7 @@ Available undo/redo operations - + ### Rpc.ObjectRelation.Delete @@ -11035,7 +11035,7 @@ Available undo/redo operations - + ### Rpc.ObjectRelation.Delete.Request @@ -11051,7 +11051,7 @@ Available undo/redo operations - + ### Rpc.ObjectRelation.Delete.Response @@ -11059,15 +11059,15 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.ObjectRelation.Delete.Response.Error](#anytype-Rpc-ObjectRelation-Delete-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.ObjectRelation.Delete.Response.Error](#anytype.Rpc.ObjectRelation.Delete.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.ObjectRelation.Delete.Response.Error @@ -11075,7 +11075,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.ObjectRelation.Delete.Response.Error.Code](#anytype-Rpc-ObjectRelation-Delete-Response-Error-Code) | | | +| code | [Rpc.ObjectRelation.Delete.Response.Error.Code](#anytype.Rpc.ObjectRelation.Delete.Response.Error.Code) | | | | description | [string](#string) | | | @@ -11083,7 +11083,7 @@ Available undo/redo operations - + ### Rpc.ObjectRelation.ListAvailable @@ -11093,7 +11093,7 @@ Available undo/redo operations - + ### Rpc.ObjectRelation.ListAvailable.Request @@ -11108,7 +11108,7 @@ Available undo/redo operations - + ### Rpc.ObjectRelation.ListAvailable.Response @@ -11116,15 +11116,15 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.ObjectRelation.ListAvailable.Response.Error](#anytype-Rpc-ObjectRelation-ListAvailable-Response-Error) | | | -| relations | [model.Relation](#anytype-model-Relation) | repeated | | +| error | [Rpc.ObjectRelation.ListAvailable.Response.Error](#anytype.Rpc.ObjectRelation.ListAvailable.Response.Error) | | | +| relations | [model.Relation](#anytype.model.Relation) | repeated | | - + ### Rpc.ObjectRelation.ListAvailable.Response.Error @@ -11132,7 +11132,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.ObjectRelation.ListAvailable.Response.Error.Code](#anytype-Rpc-ObjectRelation-ListAvailable-Response-Error-Code) | | | +| code | [Rpc.ObjectRelation.ListAvailable.Response.Error.Code](#anytype.Rpc.ObjectRelation.ListAvailable.Response.Error.Code) | | | | description | [string](#string) | | | @@ -11140,7 +11140,7 @@ Available undo/redo operations - + ### Rpc.ObjectRelation.RemoveFeatured @@ -11150,7 +11150,7 @@ Available undo/redo operations - + ### Rpc.ObjectRelation.RemoveFeatured.Request @@ -11166,7 +11166,7 @@ Available undo/redo operations - + ### Rpc.ObjectRelation.RemoveFeatured.Response @@ -11174,15 +11174,15 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.ObjectRelation.RemoveFeatured.Response.Error](#anytype-Rpc-ObjectRelation-RemoveFeatured-Response-Error) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| error | [Rpc.ObjectRelation.RemoveFeatured.Response.Error](#anytype.Rpc.ObjectRelation.RemoveFeatured.Response.Error) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.ObjectRelation.RemoveFeatured.Response.Error @@ -11190,7 +11190,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.ObjectRelation.RemoveFeatured.Response.Error.Code](#anytype-Rpc-ObjectRelation-RemoveFeatured-Response-Error-Code) | | | +| code | [Rpc.ObjectRelation.RemoveFeatured.Response.Error.Code](#anytype.Rpc.ObjectRelation.RemoveFeatured.Response.Error.Code) | | | | description | [string](#string) | | | @@ -11198,7 +11198,7 @@ Available undo/redo operations - + ### Rpc.ObjectType @@ -11208,7 +11208,7 @@ Available undo/redo operations - + ### Rpc.ObjectType.Relation @@ -11218,7 +11218,7 @@ Available undo/redo operations - + ### Rpc.ObjectType.Relation.Add @@ -11228,7 +11228,7 @@ Available undo/redo operations - + ### Rpc.ObjectType.Relation.Add.Request @@ -11244,7 +11244,7 @@ Available undo/redo operations - + ### Rpc.ObjectType.Relation.Add.Response @@ -11252,15 +11252,15 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.ObjectType.Relation.Add.Response.Error](#anytype-Rpc-ObjectType-Relation-Add-Response-Error) | | | -| relations | [model.Relation](#anytype-model-Relation) | repeated | | +| error | [Rpc.ObjectType.Relation.Add.Response.Error](#anytype.Rpc.ObjectType.Relation.Add.Response.Error) | | | +| relations | [model.Relation](#anytype.model.Relation) | repeated | | - + ### Rpc.ObjectType.Relation.Add.Response.Error @@ -11268,7 +11268,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.ObjectType.Relation.Add.Response.Error.Code](#anytype-Rpc-ObjectType-Relation-Add-Response-Error-Code) | | | +| code | [Rpc.ObjectType.Relation.Add.Response.Error.Code](#anytype.Rpc.ObjectType.Relation.Add.Response.Error.Code) | | | | description | [string](#string) | | | @@ -11276,7 +11276,7 @@ Available undo/redo operations - + ### Rpc.ObjectType.Relation.List @@ -11286,7 +11286,7 @@ Available undo/redo operations - + ### Rpc.ObjectType.Relation.List.Request @@ -11302,7 +11302,7 @@ Available undo/redo operations - + ### Rpc.ObjectType.Relation.List.Response @@ -11310,15 +11310,15 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.ObjectType.Relation.List.Response.Error](#anytype-Rpc-ObjectType-Relation-List-Response-Error) | | | -| relations | [model.RelationLink](#anytype-model-RelationLink) | repeated | | +| error | [Rpc.ObjectType.Relation.List.Response.Error](#anytype.Rpc.ObjectType.Relation.List.Response.Error) | | | +| relations | [model.RelationLink](#anytype.model.RelationLink) | repeated | | - + ### Rpc.ObjectType.Relation.List.Response.Error @@ -11326,7 +11326,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.ObjectType.Relation.List.Response.Error.Code](#anytype-Rpc-ObjectType-Relation-List-Response-Error-Code) | | | +| code | [Rpc.ObjectType.Relation.List.Response.Error.Code](#anytype.Rpc.ObjectType.Relation.List.Response.Error.Code) | | | | description | [string](#string) | | | @@ -11334,7 +11334,7 @@ Available undo/redo operations - + ### Rpc.ObjectType.Relation.Remove @@ -11344,7 +11344,7 @@ Available undo/redo operations - + ### Rpc.ObjectType.Relation.Remove.Request @@ -11360,7 +11360,7 @@ Available undo/redo operations - + ### Rpc.ObjectType.Relation.Remove.Response @@ -11368,14 +11368,14 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.ObjectType.Relation.Remove.Response.Error](#anytype-Rpc-ObjectType-Relation-Remove-Response-Error) | | | +| error | [Rpc.ObjectType.Relation.Remove.Response.Error](#anytype.Rpc.ObjectType.Relation.Remove.Response.Error) | | | - + ### Rpc.ObjectType.Relation.Remove.Response.Error @@ -11383,7 +11383,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.ObjectType.Relation.Remove.Response.Error.Code](#anytype-Rpc-ObjectType-Relation-Remove-Response-Error-Code) | | | +| code | [Rpc.ObjectType.Relation.Remove.Response.Error.Code](#anytype.Rpc.ObjectType.Relation.Remove.Response.Error.Code) | | | | description | [string](#string) | | | @@ -11391,7 +11391,7 @@ Available undo/redo operations - + ### Rpc.Process @@ -11401,7 +11401,7 @@ Available undo/redo operations - + ### Rpc.Process.Cancel @@ -11411,7 +11411,7 @@ Available undo/redo operations - + ### Rpc.Process.Cancel.Request @@ -11426,7 +11426,7 @@ Available undo/redo operations - + ### Rpc.Process.Cancel.Response @@ -11434,14 +11434,14 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Process.Cancel.Response.Error](#anytype-Rpc-Process-Cancel-Response-Error) | | | +| error | [Rpc.Process.Cancel.Response.Error](#anytype.Rpc.Process.Cancel.Response.Error) | | | - + ### Rpc.Process.Cancel.Response.Error @@ -11449,7 +11449,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Process.Cancel.Response.Error.Code](#anytype-Rpc-Process-Cancel-Response-Error-Code) | | | +| code | [Rpc.Process.Cancel.Response.Error.Code](#anytype.Rpc.Process.Cancel.Response.Error.Code) | | | | description | [string](#string) | | | @@ -11457,7 +11457,7 @@ Available undo/redo operations - + ### Rpc.Relation @@ -11467,7 +11467,7 @@ Available undo/redo operations - + ### Rpc.Relation.ListRemoveOption @@ -11477,7 +11477,7 @@ Available undo/redo operations - + ### Rpc.Relation.ListRemoveOption.Request @@ -11493,7 +11493,7 @@ Available undo/redo operations - + ### Rpc.Relation.ListRemoveOption.Response @@ -11501,14 +11501,14 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Relation.ListRemoveOption.Response.Error](#anytype-Rpc-Relation-ListRemoveOption-Response-Error) | | | +| error | [Rpc.Relation.ListRemoveOption.Response.Error](#anytype.Rpc.Relation.ListRemoveOption.Response.Error) | | | - + ### Rpc.Relation.ListRemoveOption.Response.Error @@ -11516,7 +11516,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Relation.ListRemoveOption.Response.Error.Code](#anytype-Rpc-Relation-ListRemoveOption-Response-Error-Code) | | | +| code | [Rpc.Relation.ListRemoveOption.Response.Error.Code](#anytype.Rpc.Relation.ListRemoveOption.Response.Error.Code) | | | | description | [string](#string) | | | @@ -11524,7 +11524,7 @@ Available undo/redo operations - + ### Rpc.Relation.Options @@ -11534,7 +11534,7 @@ Available undo/redo operations - + ### Rpc.Relation.Options.Request @@ -11549,7 +11549,7 @@ Available undo/redo operations - + ### Rpc.Relation.Options.Response @@ -11557,15 +11557,15 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Relation.Options.Response.Error](#anytype-Rpc-Relation-Options-Response-Error) | | | -| options | [model.RelationOptions](#anytype-model-RelationOptions) | | | +| error | [Rpc.Relation.Options.Response.Error](#anytype.Rpc.Relation.Options.Response.Error) | | | +| options | [model.RelationOptions](#anytype.model.RelationOptions) | | | - + ### Rpc.Relation.Options.Response.Error @@ -11573,7 +11573,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Relation.Options.Response.Error.Code](#anytype-Rpc-Relation-Options-Response-Error-Code) | | | +| code | [Rpc.Relation.Options.Response.Error.Code](#anytype.Rpc.Relation.Options.Response.Error.Code) | | | | description | [string](#string) | | | @@ -11581,7 +11581,7 @@ Available undo/redo operations - + ### Rpc.Template @@ -11591,7 +11591,7 @@ Available undo/redo operations - + ### Rpc.Template.Clone @@ -11601,7 +11601,7 @@ Available undo/redo operations - + ### Rpc.Template.Clone.Request @@ -11616,7 +11616,7 @@ Available undo/redo operations - + ### Rpc.Template.Clone.Response @@ -11624,7 +11624,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Template.Clone.Response.Error](#anytype-Rpc-Template-Clone-Response-Error) | | | +| error | [Rpc.Template.Clone.Response.Error](#anytype.Rpc.Template.Clone.Response.Error) | | | | id | [string](#string) | | created template id | @@ -11632,7 +11632,7 @@ Available undo/redo operations - + ### Rpc.Template.Clone.Response.Error @@ -11640,7 +11640,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Template.Clone.Response.Error.Code](#anytype-Rpc-Template-Clone-Response-Error-Code) | | | +| code | [Rpc.Template.Clone.Response.Error.Code](#anytype.Rpc.Template.Clone.Response.Error.Code) | | | | description | [string](#string) | | | @@ -11648,7 +11648,7 @@ Available undo/redo operations - + ### Rpc.Template.CreateFromObject @@ -11658,7 +11658,7 @@ Available undo/redo operations - + ### Rpc.Template.CreateFromObject.Request @@ -11673,7 +11673,7 @@ Available undo/redo operations - + ### Rpc.Template.CreateFromObject.Response @@ -11681,7 +11681,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Template.CreateFromObject.Response.Error](#anytype-Rpc-Template-CreateFromObject-Response-Error) | | | +| error | [Rpc.Template.CreateFromObject.Response.Error](#anytype.Rpc.Template.CreateFromObject.Response.Error) | | | | id | [string](#string) | | created template id | @@ -11689,7 +11689,7 @@ Available undo/redo operations - + ### Rpc.Template.CreateFromObject.Response.Error @@ -11697,7 +11697,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Template.CreateFromObject.Response.Error.Code](#anytype-Rpc-Template-CreateFromObject-Response-Error-Code) | | | +| code | [Rpc.Template.CreateFromObject.Response.Error.Code](#anytype.Rpc.Template.CreateFromObject.Response.Error.Code) | | | | description | [string](#string) | | | @@ -11705,7 +11705,7 @@ Available undo/redo operations - + ### Rpc.Template.CreateFromObjectType @@ -11715,7 +11715,7 @@ Available undo/redo operations - + ### Rpc.Template.CreateFromObjectType.Request @@ -11730,7 +11730,7 @@ Available undo/redo operations - + ### Rpc.Template.CreateFromObjectType.Response @@ -11738,7 +11738,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Template.CreateFromObjectType.Response.Error](#anytype-Rpc-Template-CreateFromObjectType-Response-Error) | | | +| error | [Rpc.Template.CreateFromObjectType.Response.Error](#anytype.Rpc.Template.CreateFromObjectType.Response.Error) | | | | id | [string](#string) | | created template id | @@ -11746,7 +11746,7 @@ Available undo/redo operations - + ### Rpc.Template.CreateFromObjectType.Response.Error @@ -11754,7 +11754,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Template.CreateFromObjectType.Response.Error.Code](#anytype-Rpc-Template-CreateFromObjectType-Response-Error-Code) | | | +| code | [Rpc.Template.CreateFromObjectType.Response.Error.Code](#anytype.Rpc.Template.CreateFromObjectType.Response.Error.Code) | | | | description | [string](#string) | | | @@ -11762,7 +11762,7 @@ Available undo/redo operations - + ### Rpc.Template.ExportAll @@ -11772,7 +11772,7 @@ Available undo/redo operations - + ### Rpc.Template.ExportAll.Request @@ -11787,7 +11787,7 @@ Available undo/redo operations - + ### Rpc.Template.ExportAll.Response @@ -11795,16 +11795,16 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Template.ExportAll.Response.Error](#anytype-Rpc-Template-ExportAll-Response-Error) | | | +| error | [Rpc.Template.ExportAll.Response.Error](#anytype.Rpc.Template.ExportAll.Response.Error) | | | | path | [string](#string) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Template.ExportAll.Response.Error @@ -11812,7 +11812,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Template.ExportAll.Response.Error.Code](#anytype-Rpc-Template-ExportAll-Response-Error-Code) | | | +| code | [Rpc.Template.ExportAll.Response.Error.Code](#anytype.Rpc.Template.ExportAll.Response.Error.Code) | | | | description | [string](#string) | | | @@ -11820,7 +11820,7 @@ Available undo/redo operations - + ### Rpc.Unsplash @@ -11830,7 +11830,7 @@ Available undo/redo operations - + ### Rpc.Unsplash.Download @@ -11840,7 +11840,7 @@ Available undo/redo operations - + ### Rpc.Unsplash.Download.Request @@ -11855,7 +11855,7 @@ Available undo/redo operations - + ### Rpc.Unsplash.Download.Response @@ -11863,7 +11863,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Unsplash.Download.Response.Error](#anytype-Rpc-Unsplash-Download-Response-Error) | | | +| error | [Rpc.Unsplash.Download.Response.Error](#anytype.Rpc.Unsplash.Download.Response.Error) | | | | hash | [string](#string) | | | @@ -11871,7 +11871,7 @@ Available undo/redo operations - + ### Rpc.Unsplash.Download.Response.Error @@ -11879,7 +11879,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Unsplash.Download.Response.Error.Code](#anytype-Rpc-Unsplash-Download-Response-Error-Code) | | | +| code | [Rpc.Unsplash.Download.Response.Error.Code](#anytype.Rpc.Unsplash.Download.Response.Error.Code) | | | | description | [string](#string) | | | @@ -11887,7 +11887,7 @@ Available undo/redo operations - + ### Rpc.Unsplash.Search @@ -11897,7 +11897,7 @@ Available undo/redo operations - + ### Rpc.Unsplash.Search.Request @@ -11913,7 +11913,7 @@ Available undo/redo operations - + ### Rpc.Unsplash.Search.Response @@ -11921,15 +11921,15 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Unsplash.Search.Response.Error](#anytype-Rpc-Unsplash-Search-Response-Error) | | | -| pictures | [Rpc.Unsplash.Search.Response.Picture](#anytype-Rpc-Unsplash-Search-Response-Picture) | repeated | | +| error | [Rpc.Unsplash.Search.Response.Error](#anytype.Rpc.Unsplash.Search.Response.Error) | | | +| pictures | [Rpc.Unsplash.Search.Response.Picture](#anytype.Rpc.Unsplash.Search.Response.Picture) | repeated | | - + ### Rpc.Unsplash.Search.Response.Error @@ -11937,7 +11937,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Unsplash.Search.Response.Error.Code](#anytype-Rpc-Unsplash-Search-Response-Error-Code) | | | +| code | [Rpc.Unsplash.Search.Response.Error.Code](#anytype.Rpc.Unsplash.Search.Response.Error.Code) | | | | description | [string](#string) | | | @@ -11945,7 +11945,7 @@ Available undo/redo operations - + ### Rpc.Unsplash.Search.Response.Picture @@ -11963,7 +11963,7 @@ Available undo/redo operations - + ### Rpc.Wallet @@ -11973,7 +11973,7 @@ Available undo/redo operations - + ### Rpc.Wallet.CloseSession @@ -11983,7 +11983,7 @@ Available undo/redo operations - + ### Rpc.Wallet.CloseSession.Request @@ -11998,7 +11998,7 @@ Available undo/redo operations - + ### Rpc.Wallet.CloseSession.Response @@ -12006,14 +12006,14 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Wallet.CloseSession.Response.Error](#anytype-Rpc-Wallet-CloseSession-Response-Error) | | | +| error | [Rpc.Wallet.CloseSession.Response.Error](#anytype.Rpc.Wallet.CloseSession.Response.Error) | | | - + ### Rpc.Wallet.CloseSession.Response.Error @@ -12021,7 +12021,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Wallet.CloseSession.Response.Error.Code](#anytype-Rpc-Wallet-CloseSession-Response-Error-Code) | | | +| code | [Rpc.Wallet.CloseSession.Response.Error.Code](#anytype.Rpc.Wallet.CloseSession.Response.Error.Code) | | | | description | [string](#string) | | | @@ -12029,7 +12029,7 @@ Available undo/redo operations - + ### Rpc.Wallet.Convert @@ -12039,7 +12039,7 @@ Available undo/redo operations - + ### Rpc.Wallet.Convert.Request @@ -12055,7 +12055,7 @@ Available undo/redo operations - + ### Rpc.Wallet.Convert.Response @@ -12063,7 +12063,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Wallet.Convert.Response.Error](#anytype-Rpc-Wallet-Convert-Response-Error) | | Error while trying to recover a wallet | +| error | [Rpc.Wallet.Convert.Response.Error](#anytype.Rpc.Wallet.Convert.Response.Error) | | Error while trying to recover a wallet | | entropy | [string](#string) | | | | mnemonic | [string](#string) | | | @@ -12072,7 +12072,7 @@ Available undo/redo operations - + ### Rpc.Wallet.Convert.Response.Error @@ -12080,7 +12080,7 @@ Available undo/redo operations | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Wallet.Convert.Response.Error.Code](#anytype-Rpc-Wallet-Convert-Response-Error-Code) | | | +| code | [Rpc.Wallet.Convert.Response.Error.Code](#anytype.Rpc.Wallet.Convert.Response.Error.Code) | | | | description | [string](#string) | | | @@ -12088,7 +12088,7 @@ Available undo/redo operations - + ### Rpc.Wallet.Create @@ -12098,7 +12098,7 @@ Available undo/redo operations - + ### Rpc.Wallet.Create.Request Front-end-to-middleware request to create a new wallet @@ -12113,7 +12113,7 @@ Front-end-to-middleware request to create a new wallet - + ### Rpc.Wallet.Create.Response Middleware-to-front-end response, that can contain mnemonic of a created account and a NULL error or an empty mnemonic and a non-NULL error @@ -12121,7 +12121,7 @@ Middleware-to-front-end response, that can contain mnemonic of a created account | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Wallet.Create.Response.Error](#anytype-Rpc-Wallet-Create-Response-Error) | | | +| error | [Rpc.Wallet.Create.Response.Error](#anytype.Rpc.Wallet.Create.Response.Error) | | | | mnemonic | [string](#string) | | Mnemonic of a new account (sequence of words, divided by spaces) | @@ -12129,7 +12129,7 @@ Middleware-to-front-end response, that can contain mnemonic of a created account - + ### Rpc.Wallet.Create.Response.Error @@ -12137,7 +12137,7 @@ Middleware-to-front-end response, that can contain mnemonic of a created account | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Wallet.Create.Response.Error.Code](#anytype-Rpc-Wallet-Create-Response-Error-Code) | | | +| code | [Rpc.Wallet.Create.Response.Error.Code](#anytype.Rpc.Wallet.Create.Response.Error.Code) | | | | description | [string](#string) | | | @@ -12145,7 +12145,7 @@ Middleware-to-front-end response, that can contain mnemonic of a created account - + ### Rpc.Wallet.CreateSession @@ -12155,7 +12155,7 @@ Middleware-to-front-end response, that can contain mnemonic of a created account - + ### Rpc.Wallet.CreateSession.Request @@ -12170,7 +12170,7 @@ Middleware-to-front-end response, that can contain mnemonic of a created account - + ### Rpc.Wallet.CreateSession.Response @@ -12178,7 +12178,7 @@ Middleware-to-front-end response, that can contain mnemonic of a created account | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Wallet.CreateSession.Response.Error](#anytype-Rpc-Wallet-CreateSession-Response-Error) | | | +| error | [Rpc.Wallet.CreateSession.Response.Error](#anytype.Rpc.Wallet.CreateSession.Response.Error) | | | | token | [string](#string) | | | @@ -12186,7 +12186,7 @@ Middleware-to-front-end response, that can contain mnemonic of a created account - + ### Rpc.Wallet.CreateSession.Response.Error @@ -12194,7 +12194,7 @@ Middleware-to-front-end response, that can contain mnemonic of a created account | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Wallet.CreateSession.Response.Error.Code](#anytype-Rpc-Wallet-CreateSession-Response-Error-Code) | | | +| code | [Rpc.Wallet.CreateSession.Response.Error.Code](#anytype.Rpc.Wallet.CreateSession.Response.Error.Code) | | | | description | [string](#string) | | | @@ -12202,7 +12202,7 @@ Middleware-to-front-end response, that can contain mnemonic of a created account - + ### Rpc.Wallet.Recover @@ -12212,7 +12212,7 @@ Middleware-to-front-end response, that can contain mnemonic of a created account - + ### Rpc.Wallet.Recover.Request Front end to middleware request-to-recover-a wallet with this mnemonic and a rootPath @@ -12228,7 +12228,7 @@ Front end to middleware request-to-recover-a wallet with this mnemonic and a roo - + ### Rpc.Wallet.Recover.Response Middleware-to-front-end response, that can contain a NULL error or a non-NULL error @@ -12236,14 +12236,14 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Wallet.Recover.Response.Error](#anytype-Rpc-Wallet-Recover-Response-Error) | | Error while trying to recover a wallet | +| error | [Rpc.Wallet.Recover.Response.Error](#anytype.Rpc.Wallet.Recover.Response.Error) | | Error while trying to recover a wallet | - + ### Rpc.Wallet.Recover.Response.Error @@ -12251,7 +12251,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Wallet.Recover.Response.Error.Code](#anytype-Rpc-Wallet-Recover-Response-Error-Code) | | | +| code | [Rpc.Wallet.Recover.Response.Error.Code](#anytype.Rpc.Wallet.Recover.Response.Error.Code) | | | | description | [string](#string) | | | @@ -12259,7 +12259,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace @@ -12269,7 +12269,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Create @@ -12279,7 +12279,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Create.Request @@ -12294,7 +12294,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Create.Response @@ -12302,7 +12302,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Workspace.Create.Response.Error](#anytype-Rpc-Workspace-Create-Response-Error) | | | +| error | [Rpc.Workspace.Create.Response.Error](#anytype.Rpc.Workspace.Create.Response.Error) | | | | workspaceId | [string](#string) | | | @@ -12310,7 +12310,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Create.Response.Error @@ -12318,7 +12318,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Workspace.Create.Response.Error.Code](#anytype-Rpc-Workspace-Create-Response-Error-Code) | | | +| code | [Rpc.Workspace.Create.Response.Error.Code](#anytype.Rpc.Workspace.Create.Response.Error.Code) | | | | description | [string](#string) | | | @@ -12326,7 +12326,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Export @@ -12336,7 +12336,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Export.Request @@ -12352,7 +12352,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Export.Response @@ -12360,16 +12360,16 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Workspace.Export.Response.Error](#anytype-Rpc-Workspace-Export-Response-Error) | | | +| error | [Rpc.Workspace.Export.Response.Error](#anytype.Rpc.Workspace.Export.Response.Error) | | | | path | [string](#string) | | | -| event | [ResponseEvent](#anytype-ResponseEvent) | | | +| event | [ResponseEvent](#anytype.ResponseEvent) | | | - + ### Rpc.Workspace.Export.Response.Error @@ -12377,7 +12377,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Workspace.Export.Response.Error.Code](#anytype-Rpc-Workspace-Export-Response-Error-Code) | | | +| code | [Rpc.Workspace.Export.Response.Error.Code](#anytype.Rpc.Workspace.Export.Response.Error.Code) | | | | description | [string](#string) | | | @@ -12385,7 +12385,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.GetAll @@ -12395,7 +12395,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.GetAll.Request @@ -12405,7 +12405,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.GetAll.Response @@ -12413,7 +12413,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Workspace.GetAll.Response.Error](#anytype-Rpc-Workspace-GetAll-Response-Error) | | | +| error | [Rpc.Workspace.GetAll.Response.Error](#anytype.Rpc.Workspace.GetAll.Response.Error) | | | | workspaceIds | [string](#string) | repeated | | @@ -12421,7 +12421,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.GetAll.Response.Error @@ -12429,7 +12429,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Workspace.GetAll.Response.Error.Code](#anytype-Rpc-Workspace-GetAll-Response-Error-Code) | | | +| code | [Rpc.Workspace.GetAll.Response.Error.Code](#anytype.Rpc.Workspace.GetAll.Response.Error.Code) | | | | description | [string](#string) | | | @@ -12437,7 +12437,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.GetCurrent @@ -12447,7 +12447,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.GetCurrent.Request @@ -12457,7 +12457,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.GetCurrent.Response @@ -12465,7 +12465,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Workspace.GetCurrent.Response.Error](#anytype-Rpc-Workspace-GetCurrent-Response-Error) | | | +| error | [Rpc.Workspace.GetCurrent.Response.Error](#anytype.Rpc.Workspace.GetCurrent.Response.Error) | | | | workspaceId | [string](#string) | | | @@ -12473,7 +12473,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.GetCurrent.Response.Error @@ -12481,7 +12481,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Workspace.GetCurrent.Response.Error.Code](#anytype-Rpc-Workspace-GetCurrent-Response-Error-Code) | | | +| code | [Rpc.Workspace.GetCurrent.Response.Error.Code](#anytype.Rpc.Workspace.GetCurrent.Response.Error.Code) | | | | description | [string](#string) | | | @@ -12489,7 +12489,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Object @@ -12499,7 +12499,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Object.Add @@ -12509,7 +12509,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Object.Add.Request @@ -12524,7 +12524,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Object.Add.Response @@ -12532,16 +12532,16 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Workspace.Object.Add.Response.Error](#anytype-Rpc-Workspace-Object-Add-Response-Error) | | | +| error | [Rpc.Workspace.Object.Add.Response.Error](#anytype.Rpc.Workspace.Object.Add.Response.Error) | | | | objectId | [string](#string) | | | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### Rpc.Workspace.Object.Add.Response.Error @@ -12549,7 +12549,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Workspace.Object.Add.Response.Error.Code](#anytype-Rpc-Workspace-Object-Add-Response-Error-Code) | | | +| code | [Rpc.Workspace.Object.Add.Response.Error.Code](#anytype.Rpc.Workspace.Object.Add.Response.Error.Code) | | | | description | [string](#string) | | | @@ -12557,7 +12557,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Object.ListAdd @@ -12567,7 +12567,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Object.ListAdd.Request @@ -12582,7 +12582,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Object.ListAdd.Response @@ -12590,7 +12590,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Workspace.Object.ListAdd.Response.Error](#anytype-Rpc-Workspace-Object-ListAdd-Response-Error) | | | +| error | [Rpc.Workspace.Object.ListAdd.Response.Error](#anytype.Rpc.Workspace.Object.ListAdd.Response.Error) | | | | objectIds | [string](#string) | repeated | | @@ -12598,7 +12598,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Object.ListAdd.Response.Error @@ -12606,7 +12606,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Workspace.Object.ListAdd.Response.Error.Code](#anytype-Rpc-Workspace-Object-ListAdd-Response-Error-Code) | | | +| code | [Rpc.Workspace.Object.ListAdd.Response.Error.Code](#anytype.Rpc.Workspace.Object.ListAdd.Response.Error.Code) | | | | description | [string](#string) | | | @@ -12614,7 +12614,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Object.ListRemove @@ -12624,7 +12624,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Object.ListRemove.Request @@ -12639,7 +12639,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Object.ListRemove.Response @@ -12647,7 +12647,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Workspace.Object.ListRemove.Response.Error](#anytype-Rpc-Workspace-Object-ListRemove-Response-Error) | | | +| error | [Rpc.Workspace.Object.ListRemove.Response.Error](#anytype.Rpc.Workspace.Object.ListRemove.Response.Error) | | | | ids | [string](#string) | repeated | | @@ -12655,7 +12655,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Object.ListRemove.Response.Error @@ -12663,7 +12663,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Workspace.Object.ListRemove.Response.Error.Code](#anytype-Rpc-Workspace-Object-ListRemove-Response-Error-Code) | | | +| code | [Rpc.Workspace.Object.ListRemove.Response.Error.Code](#anytype.Rpc.Workspace.Object.ListRemove.Response.Error.Code) | | | | description | [string](#string) | | | @@ -12671,7 +12671,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Select @@ -12681,7 +12681,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Select.Request @@ -12696,7 +12696,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Select.Response @@ -12704,14 +12704,14 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Workspace.Select.Response.Error](#anytype-Rpc-Workspace-Select-Response-Error) | | | +| error | [Rpc.Workspace.Select.Response.Error](#anytype.Rpc.Workspace.Select.Response.Error) | | | - + ### Rpc.Workspace.Select.Response.Error @@ -12719,7 +12719,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Workspace.Select.Response.Error.Code](#anytype-Rpc-Workspace-Select-Response-Error-Code) | | | +| code | [Rpc.Workspace.Select.Response.Error.Code](#anytype.Rpc.Workspace.Select.Response.Error.Code) | | | | description | [string](#string) | | | @@ -12727,7 +12727,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.SetIsHighlighted @@ -12737,7 +12737,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.SetIsHighlighted.Request @@ -12753,7 +12753,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.SetIsHighlighted.Response @@ -12761,14 +12761,14 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| error | [Rpc.Workspace.SetIsHighlighted.Response.Error](#anytype-Rpc-Workspace-SetIsHighlighted-Response-Error) | | | +| error | [Rpc.Workspace.SetIsHighlighted.Response.Error](#anytype.Rpc.Workspace.SetIsHighlighted.Response.Error) | | | - + ### Rpc.Workspace.SetIsHighlighted.Response.Error @@ -12776,7 +12776,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| code | [Rpc.Workspace.SetIsHighlighted.Response.Error.Code](#anytype-Rpc-Workspace-SetIsHighlighted-Response-Error-Code) | | | +| code | [Rpc.Workspace.SetIsHighlighted.Response.Error.Code](#anytype.Rpc.Workspace.SetIsHighlighted.Response.Error.Code) | | | | description | [string](#string) | | | @@ -12784,7 +12784,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### StreamRequest @@ -12801,7 +12801,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Account.ConfigUpdate.Response.Error.Code @@ -12817,7 +12817,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Account.ConfigUpdate.Timezones @@ -12855,7 +12855,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Account.Create.Response.Error.Code @@ -12878,7 +12878,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Account.Delete.Response.Error.Code @@ -12893,7 +12893,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Account.Move.Response.Error.Code @@ -12912,7 +12912,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Account.Recover.Response.Error.Code @@ -12934,7 +12934,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Account.Select.Response.Error.Code @@ -12955,7 +12955,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Account.Stop.Response.Error.Code @@ -12971,7 +12971,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.App.GetVersion.Response.Error.Code @@ -12987,7 +12987,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.App.SetDeviceState.Request.DeviceState @@ -12999,7 +12999,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.App.SetDeviceState.Response.Error.Code @@ -13013,7 +13013,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.App.Shutdown.Response.Error.Code @@ -13027,7 +13027,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.Copy.Response.Error.Code @@ -13040,7 +13040,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.Create.Response.Error.Code @@ -13053,7 +13053,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.CreateWidget.Response.Error.Code @@ -13066,7 +13066,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.Cut.Response.Error.Code @@ -13079,7 +13079,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.Download.Response.Error.Code @@ -13092,7 +13092,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.Export.Response.Error.Code @@ -13105,7 +13105,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.ListConvertToObjects.Response.Error.Code @@ -13118,7 +13118,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.ListDelete.Response.Error.Code @@ -13131,7 +13131,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.ListDuplicate.Response.Error.Code @@ -13144,7 +13144,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.ListMoveToExistingObject.Response.Error.Code @@ -13157,7 +13157,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.ListMoveToNewObject.Response.Error.Code @@ -13170,7 +13170,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.ListSetAlign.Response.Error.Code @@ -13183,7 +13183,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.ListSetBackgroundColor.Response.Error.Code @@ -13196,7 +13196,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.ListSetFields.Response.Error.Code @@ -13209,7 +13209,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.ListSetVerticalAlign.Response.Error.Code @@ -13222,7 +13222,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.ListTurnInto.Response.Error.Code @@ -13235,7 +13235,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.Merge.Response.Error.Code @@ -13248,7 +13248,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.Paste.Response.Error.Code @@ -13261,7 +13261,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.Replace.Response.Error.Code @@ -13274,7 +13274,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.SetFields.Response.Error.Code @@ -13287,7 +13287,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.Split.Request.Mode @@ -13301,7 +13301,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.Split.Response.Error.Code @@ -13314,7 +13314,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Block.Upload.Response.Error.Code @@ -13327,7 +13327,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockBookmark.CreateAndFetch.Response.Error.Code @@ -13340,7 +13340,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockBookmark.Fetch.Response.Error.Code @@ -13353,7 +13353,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockDataview.CreateBookmark.Response.Error.Code @@ -13366,7 +13366,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockDataview.GroupOrder.Update.Response.Error.Code @@ -13379,7 +13379,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockDataview.ObjectOrder.Update.Response.Error.Code @@ -13392,7 +13392,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockDataview.Relation.Add.Response.Error.Code @@ -13405,7 +13405,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockDataview.Relation.Delete.Response.Error.Code @@ -13418,7 +13418,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockDataview.Relation.ListAvailable.Response.Error.Code @@ -13432,7 +13432,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockDataview.SetSource.Response.Error.Code @@ -13445,7 +13445,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockDataview.View.Create.Response.Error.Code @@ -13458,7 +13458,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockDataview.View.Delete.Response.Error.Code @@ -13471,7 +13471,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockDataview.View.SetActive.Response.Error.Code @@ -13484,7 +13484,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockDataview.View.SetPosition.Response.Error.Code @@ -13497,7 +13497,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockDataview.View.Update.Response.Error.Code @@ -13510,7 +13510,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockDiv.ListSetStyle.Response.Error.Code @@ -13523,7 +13523,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockFile.CreateAndUpload.Response.Error.Code @@ -13536,7 +13536,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockFile.ListSetStyle.Response.Error.Code @@ -13549,7 +13549,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockFile.SetName.Response.Error.Code @@ -13562,7 +13562,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockImage.SetName.Response.Error.Code @@ -13575,7 +13575,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockImage.SetWidth.Response.Error.Code @@ -13588,7 +13588,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockLatex.SetText.Response.Error.Code @@ -13601,7 +13601,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockLink.CreateWithObject.Response.Error.Code @@ -13614,7 +13614,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockLink.ListSetAppearance.Response.Error.Code @@ -13627,7 +13627,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockRelation.Add.Response.Error.Code @@ -13640,7 +13640,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockRelation.SetKey.Response.Error.Code @@ -13653,7 +13653,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockTable.ColumnCreate.Response.Error.Code @@ -13666,7 +13666,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockTable.ColumnDelete.Response.Error.Code @@ -13679,7 +13679,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockTable.ColumnDuplicate.Response.Error.Code @@ -13692,7 +13692,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockTable.ColumnListFill.Response.Error.Code @@ -13705,7 +13705,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockTable.ColumnMove.Response.Error.Code @@ -13718,7 +13718,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockTable.Create.Response.Error.Code @@ -13731,7 +13731,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockTable.Expand.Response.Error.Code @@ -13744,7 +13744,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockTable.RowCreate.Response.Error.Code @@ -13757,7 +13757,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockTable.RowDelete.Response.Error.Code @@ -13770,7 +13770,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockTable.RowDuplicate.Response.Error.Code @@ -13783,7 +13783,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockTable.RowListClean.Response.Error.Code @@ -13796,7 +13796,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockTable.RowListFill.Response.Error.Code @@ -13809,7 +13809,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockTable.RowSetHeader.Response.Error.Code @@ -13822,7 +13822,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockTable.Sort.Response.Error.Code @@ -13835,7 +13835,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockText.ListClearContent.Response.Error.Code @@ -13848,7 +13848,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockText.ListClearStyle.Response.Error.Code @@ -13861,7 +13861,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockText.ListSetColor.Response.Error.Code @@ -13874,7 +13874,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockText.ListSetMark.Response.Error.Code @@ -13887,7 +13887,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockText.ListSetStyle.Response.Error.Code @@ -13900,7 +13900,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockText.SetChecked.Response.Error.Code @@ -13913,7 +13913,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockText.SetColor.Response.Error.Code @@ -13926,7 +13926,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockText.SetIcon.Response.Error.Code @@ -13939,7 +13939,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockText.SetMarks.Get.Response.Error.Code @@ -13952,7 +13952,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockText.SetStyle.Response.Error.Code @@ -13965,7 +13965,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockText.SetText.Response.Error.Code @@ -13978,7 +13978,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockVideo.SetName.Response.Error.Code @@ -13991,7 +13991,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.BlockVideo.SetWidth.Response.Error.Code @@ -14004,7 +14004,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Debug.ExportLocalstore.Response.Error.Code @@ -14017,7 +14017,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Debug.Ping.Response.Error.Code @@ -14030,7 +14030,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Debug.Sync.Response.Error.Code @@ -14043,7 +14043,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Debug.Thread.Response.Error.Code @@ -14056,7 +14056,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Debug.Tree.Response.Error.Code @@ -14069,7 +14069,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.File.Download.Response.Error.Code @@ -14083,7 +14083,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.File.Drop.Response.Error.Code @@ -14096,7 +14096,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.File.ListOffload.Response.Error.Code @@ -14110,7 +14110,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.File.Offload.Response.Error.Code @@ -14125,7 +14125,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.File.Upload.Response.Error.Code @@ -14138,7 +14138,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.GenericErrorResponse.Error.Code @@ -14151,7 +14151,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.History.GetVersions.Response.Error.Code @@ -14164,7 +14164,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.History.SetVersion.Response.Error.Code @@ -14177,7 +14177,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.History.ShowVersion.Response.Error.Code @@ -14190,7 +14190,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.LinkPreview.Response.Error.Code @@ -14203,7 +14203,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Log.Send.Request.Level @@ -14219,7 +14219,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Log.Send.Response.Error.Code @@ -14234,7 +14234,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Metrics.SetParameters.Response.Error.Code @@ -14247,7 +14247,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Navigation.Context @@ -14260,7 +14260,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Navigation.GetObjectInfoWithLinks.Response.Error.Code @@ -14273,7 +14273,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Navigation.ListObjects.Response.Error.Code @@ -14286,7 +14286,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.AddWithObjectId.Response.Error.Code @@ -14299,7 +14299,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.ApplyTemplate.Response.Error.Code @@ -14312,7 +14312,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.BookmarkFetch.Response.Error.Code @@ -14325,7 +14325,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.Close.Response.Error.Code @@ -14338,7 +14338,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.Create.Response.Error.Code @@ -14351,7 +14351,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.CreateBookmark.Response.Error.Code @@ -14364,7 +14364,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.CreateObjectType.Response.Error.Code @@ -14378,7 +14378,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.CreateRelation.Response.Error.Code @@ -14391,7 +14391,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.CreateRelationOption.Response.Error.Code @@ -14404,7 +14404,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.CreateSet.Response.Error.Code @@ -14418,7 +14418,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.Duplicate.Response.Error.Code @@ -14431,7 +14431,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.Graph.Edge.Type @@ -14443,7 +14443,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.Graph.Response.Error.Code @@ -14456,7 +14456,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.GroupsSubscribe.Response.Error.Code @@ -14469,7 +14469,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.Import.Request.Mode @@ -14481,7 +14481,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.Import.Request.Type @@ -14493,7 +14493,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.Import.Response.Error.Code @@ -14507,7 +14507,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.ImportList.ImportResponse.Type @@ -14518,7 +14518,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.ImportList.Response.Error.Code @@ -14532,7 +14532,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.ImportMarkdown.Response.Error.Code @@ -14545,7 +14545,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.ListDelete.Response.Error.Code @@ -14558,7 +14558,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.ListDuplicate.Response.Error.Code @@ -14571,7 +14571,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.ListExport.Format @@ -14587,7 +14587,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.ListExport.Response.Error.Code @@ -14600,7 +14600,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.ListSetIsArchived.Response.Error.Code @@ -14613,7 +14613,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.ListSetIsFavorite.Response.Error.Code @@ -14626,7 +14626,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.Open.Response.Error.Code @@ -14641,7 +14641,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.OpenBreadcrumbs.Response.Error.Code @@ -14654,7 +14654,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.Redo.Response.Error.Code @@ -14668,7 +14668,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.Search.Response.Error.Code @@ -14681,7 +14681,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.SearchSubscribe.Response.Error.Code @@ -14694,7 +14694,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.SearchUnsubscribe.Response.Error.Code @@ -14707,7 +14707,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.SetBreadcrumbs.Response.Error.Code @@ -14720,7 +14720,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.SetDetails.Response.Error.Code @@ -14733,7 +14733,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.SetInternalFlags.Response.Error.Code @@ -14747,7 +14747,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.SetIsArchived.Response.Error.Code @@ -14760,7 +14760,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.SetIsFavorite.Response.Error.Code @@ -14773,7 +14773,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.SetLayout.Response.Error.Code @@ -14786,7 +14786,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.SetObjectType.Response.Error.Code @@ -14800,7 +14800,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.ShareByLink.Response.Error.Code @@ -14813,7 +14813,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.Show.Response.Error.Code @@ -14828,7 +14828,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.SubscribeIds.Response.Error.Code @@ -14841,7 +14841,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.ToBookmark.Response.Error.Code @@ -14854,7 +14854,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.ToSet.Response.Error.Code @@ -14867,7 +14867,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Object.Undo.Response.Error.Code @@ -14881,7 +14881,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.ObjectRelation.Add.Response.Error.Code @@ -14894,7 +14894,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.ObjectRelation.AddFeatured.Response.Error.Code @@ -14907,7 +14907,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.ObjectRelation.Delete.Response.Error.Code @@ -14920,7 +14920,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.ObjectRelation.ListAvailable.Response.Error.Code @@ -14933,7 +14933,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.ObjectRelation.RemoveFeatured.Response.Error.Code @@ -14946,7 +14946,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.ObjectType.Relation.Add.Response.Error.Code @@ -14961,7 +14961,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.ObjectType.Relation.List.Response.Error.Code @@ -14975,7 +14975,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.ObjectType.Relation.Remove.Response.Error.Code @@ -14990,7 +14990,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Process.Cancel.Response.Error.Code @@ -15003,7 +15003,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Relation.ListRemoveOption.Response.Error.Code @@ -15017,7 +15017,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Relation.Options.Response.Error.Code @@ -15030,7 +15030,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Template.Clone.Response.Error.Code @@ -15043,7 +15043,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Template.CreateFromObject.Response.Error.Code @@ -15056,7 +15056,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Template.CreateFromObjectType.Response.Error.Code @@ -15069,7 +15069,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Template.ExportAll.Response.Error.Code @@ -15082,7 +15082,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Unsplash.Download.Response.Error.Code @@ -15096,7 +15096,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Unsplash.Search.Response.Error.Code @@ -15110,7 +15110,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Wallet.CloseSession.Response.Error.Code @@ -15123,7 +15123,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Wallet.Convert.Response.Error.Code @@ -15136,7 +15136,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Wallet.Create.Response.Error.Code @@ -15150,7 +15150,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Wallet.CreateSession.Response.Error.Code @@ -15163,7 +15163,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Wallet.Recover.Response.Error.Code @@ -15177,7 +15177,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Create.Response.Error.Code @@ -15190,7 +15190,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Export.Response.Error.Code @@ -15203,7 +15203,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.GetAll.Response.Error.Code @@ -15216,7 +15216,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.GetCurrent.Response.Error.Code @@ -15229,7 +15229,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Object.Add.Response.Error.Code @@ -15242,7 +15242,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Object.ListAdd.Response.Error.Code @@ -15255,7 +15255,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Object.ListRemove.Response.Error.Code @@ -15268,7 +15268,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.Select.Response.Error.Code @@ -15281,7 +15281,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### Rpc.Workspace.SetIsHighlighted.Response.Error.Code @@ -15296,7 +15296,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - + ### File-level Extensions | Extension | Type | Base | Number | Description | @@ -15309,14 +15309,14 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er - +

Top

## pb/protos/events.proto - + ### Event Event – type of message, that could be sent from a middleware to the corresponding front-end. @@ -15324,9 +15324,9 @@ Event – type of message, that could be sent from a middleware to the correspon | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| messages | [Event.Message](#anytype-Event-Message) | repeated | | +| messages | [Event.Message](#anytype.Event.Message) | repeated | | | contextId | [string](#string) | | | -| initiator | [model.Account](#anytype-model-Account) | | | +| initiator | [model.Account](#anytype.model.Account) | | | | traceId | [string](#string) | | | @@ -15334,7 +15334,7 @@ Event – type of message, that could be sent from a middleware to the correspon - + ### Event.Account @@ -15344,7 +15344,7 @@ Event – type of message, that could be sent from a middleware to the correspon - + ### Event.Account.Config @@ -15354,7 +15354,7 @@ Event – type of message, that could be sent from a middleware to the correspon - + ### Event.Account.Config.Update @@ -15362,15 +15362,15 @@ Event – type of message, that could be sent from a middleware to the correspon | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| config | [model.Account.Config](#anytype-model-Account-Config) | | | -| status | [model.Account.Status](#anytype-model-Account-Status) | | | +| config | [model.Account.Config](#anytype.model.Account.Config) | | | +| status | [model.Account.Status](#anytype.model.Account.Status) | | | - + ### Event.Account.Details @@ -15379,14 +15379,14 @@ Event – type of message, that could be sent from a middleware to the correspon | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | profileId | [string](#string) | | | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### Event.Account.Show Message, that will be sent to the front on each account found after an AccountRecoverRequest @@ -15395,14 +15395,14 @@ Message, that will be sent to the front on each account found after an AccountRe | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | index | [int32](#int32) | | Number of an account in an all found accounts list | -| account | [model.Account](#anytype-model-Account) | | An Account, that has been found for the mnemonic | +| account | [model.Account](#anytype.model.Account) | | An Account, that has been found for the mnemonic | - + ### Event.Account.Update @@ -15410,15 +15410,15 @@ Message, that will be sent to the front on each account found after an AccountRe | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| config | [model.Account.Config](#anytype-model-Account-Config) | | | -| status | [model.Account.Status](#anytype-model-Account-Status) | | | +| config | [model.Account.Config](#anytype.model.Account.Config) | | | +| status | [model.Account.Status](#anytype.model.Account.Status) | | | - + ### Event.Block @@ -15428,7 +15428,7 @@ Message, that will be sent to the front on each account found after an AccountRe - + ### Event.Block.Add Event to show internal blocks on a client. @@ -15445,14 +15445,14 @@ B. Partial block load | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| blocks | [model.Block](#anytype-model-Block) | repeated | id -> block | +| blocks | [model.Block](#anytype.model.Block) | repeated | id -> block | - + ### Event.Block.Dataview @@ -15462,7 +15462,7 @@ B. Partial block load - + ### Event.Block.Dataview.GroupOrderUpdate @@ -15471,14 +15471,14 @@ B. Partial block load | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | dataview block's id | -| groupOrder | [model.Block.Content.Dataview.GroupOrder](#anytype-model-Block-Content-Dataview-GroupOrder) | | | +| groupOrder | [model.Block.Content.Dataview.GroupOrder](#anytype.model.Block.Content.Dataview.GroupOrder) | | | - + ### Event.Block.Dataview.ObjectOrderUpdate @@ -15489,14 +15489,14 @@ B. Partial block load | id | [string](#string) | | dataview block's id | | viewId | [string](#string) | | | | groupId | [string](#string) | | | -| sliceChanges | [Event.Block.Dataview.SliceChange](#anytype-Event-Block-Dataview-SliceChange) | repeated | | +| sliceChanges | [Event.Block.Dataview.SliceChange](#anytype.Event.Block.Dataview.SliceChange) | repeated | | - + ### Event.Block.Dataview.OldRelationDelete @@ -15512,7 +15512,7 @@ B. Partial block load - + ### Event.Block.Dataview.OldRelationSet sent when the dataview relation has been changed or added @@ -15522,14 +15522,14 @@ sent when the dataview relation has been changed or added | ----- | ---- | ----- | ----------- | | id | [string](#string) | | dataview block's id | | relationKey | [string](#string) | | relation key to update | -| relation | [model.Relation](#anytype-model-Relation) | | | +| relation | [model.Relation](#anytype.model.Relation) | | | - + ### Event.Block.Dataview.RelationDelete @@ -15545,7 +15545,7 @@ sent when the dataview relation has been changed or added - + ### Event.Block.Dataview.RelationSet sent when the dataview relation has been changed or added @@ -15554,14 +15554,14 @@ sent when the dataview relation has been changed or added | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | dataview block's id | -| relationLinks | [model.RelationLink](#anytype-model-RelationLink) | repeated | relation id to update | +| relationLinks | [model.RelationLink](#anytype.model.RelationLink) | repeated | relation id to update | - + ### Event.Block.Dataview.SliceChange @@ -15569,7 +15569,7 @@ sent when the dataview relation has been changed or added | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| op | [Event.Block.Dataview.SliceOperation](#anytype-Event-Block-Dataview-SliceOperation) | | | +| op | [Event.Block.Dataview.SliceOperation](#anytype.Event.Block.Dataview.SliceOperation) | | | | ids | [string](#string) | repeated | | | afterId | [string](#string) | | | @@ -15578,7 +15578,7 @@ sent when the dataview relation has been changed or added - + ### Event.Block.Dataview.SourceSet @@ -15594,7 +15594,7 @@ sent when the dataview relation has been changed or added - + ### Event.Block.Dataview.ViewDelete @@ -15610,7 +15610,7 @@ sent when the dataview relation has been changed or added - + ### Event.Block.Dataview.ViewOrder @@ -15626,7 +15626,7 @@ sent when the dataview relation has been changed or added - + ### Event.Block.Dataview.ViewSet sent when the view have been changed or added @@ -15636,14 +15636,14 @@ sent when the view have been changed or added | ----- | ---- | ----- | ----------- | | id | [string](#string) | | dataview block's id | | viewId | [string](#string) | | view id, client should double check this to make sure client doesn't switch the active view in the middle | -| view | [model.Block.Content.Dataview.View](#anytype-model-Block-Content-Dataview-View) | | | +| view | [model.Block.Content.Dataview.View](#anytype.model.Block.Content.Dataview.View) | | | - + ### Event.Block.Delete @@ -15658,7 +15658,7 @@ sent when the view have been changed or added - + ### Event.Block.FilesUpload Middleware to front end event message, that will be sent on one of this scenarios: @@ -15677,7 +15677,7 @@ Precondition: user A opened a block - + ### Event.Block.Fill @@ -15687,7 +15687,7 @@ Precondition: user A opened a block - + ### Event.Block.Fill.Align @@ -15696,14 +15696,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| align | [model.Block.Align](#anytype-model-Block-Align) | | | +| align | [model.Block.Align](#anytype.model.Block.Align) | | | - + ### Event.Block.Fill.BackgroundColor @@ -15719,7 +15719,7 @@ Precondition: user A opened a block - + ### Event.Block.Fill.Bookmark @@ -15728,20 +15728,20 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| url | [Event.Block.Fill.Bookmark.Url](#anytype-Event-Block-Fill-Bookmark-Url) | | | -| title | [Event.Block.Fill.Bookmark.Title](#anytype-Event-Block-Fill-Bookmark-Title) | | | -| description | [Event.Block.Fill.Bookmark.Description](#anytype-Event-Block-Fill-Bookmark-Description) | | | -| imageHash | [Event.Block.Fill.Bookmark.ImageHash](#anytype-Event-Block-Fill-Bookmark-ImageHash) | | | -| faviconHash | [Event.Block.Fill.Bookmark.FaviconHash](#anytype-Event-Block-Fill-Bookmark-FaviconHash) | | | -| type | [Event.Block.Fill.Bookmark.Type](#anytype-Event-Block-Fill-Bookmark-Type) | | | -| targetObjectId | [Event.Block.Fill.Bookmark.TargetObjectId](#anytype-Event-Block-Fill-Bookmark-TargetObjectId) | | | +| url | [Event.Block.Fill.Bookmark.Url](#anytype.Event.Block.Fill.Bookmark.Url) | | | +| title | [Event.Block.Fill.Bookmark.Title](#anytype.Event.Block.Fill.Bookmark.Title) | | | +| description | [Event.Block.Fill.Bookmark.Description](#anytype.Event.Block.Fill.Bookmark.Description) | | | +| imageHash | [Event.Block.Fill.Bookmark.ImageHash](#anytype.Event.Block.Fill.Bookmark.ImageHash) | | | +| faviconHash | [Event.Block.Fill.Bookmark.FaviconHash](#anytype.Event.Block.Fill.Bookmark.FaviconHash) | | | +| type | [Event.Block.Fill.Bookmark.Type](#anytype.Event.Block.Fill.Bookmark.Type) | | | +| targetObjectId | [Event.Block.Fill.Bookmark.TargetObjectId](#anytype.Event.Block.Fill.Bookmark.TargetObjectId) | | | - + ### Event.Block.Fill.Bookmark.Description @@ -15756,7 +15756,7 @@ Precondition: user A opened a block - + ### Event.Block.Fill.Bookmark.FaviconHash @@ -15771,7 +15771,7 @@ Precondition: user A opened a block - + ### Event.Block.Fill.Bookmark.ImageHash @@ -15786,7 +15786,7 @@ Precondition: user A opened a block - + ### Event.Block.Fill.Bookmark.TargetObjectId @@ -15801,7 +15801,7 @@ Precondition: user A opened a block - + ### Event.Block.Fill.Bookmark.Title @@ -15816,7 +15816,7 @@ Precondition: user A opened a block - + ### Event.Block.Fill.Bookmark.Type @@ -15824,14 +15824,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.LinkPreview.Type](#anytype-model-LinkPreview-Type) | | | +| value | [model.LinkPreview.Type](#anytype.model.LinkPreview.Type) | | | - + ### Event.Block.Fill.Bookmark.Url @@ -15846,7 +15846,7 @@ Precondition: user A opened a block - + ### Event.Block.Fill.ChildrenIds @@ -15862,7 +15862,7 @@ Precondition: user A opened a block - + ### Event.Block.Fill.DatabaseRecords @@ -15871,14 +15871,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| records | [google.protobuf.Struct](#google-protobuf-Struct) | repeated | | +| records | [google.protobuf.Struct](#google.protobuf.Struct) | repeated | | - + ### Event.Block.Fill.Details @@ -15887,14 +15887,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### Event.Block.Fill.Div @@ -15903,14 +15903,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| style | [Event.Block.Fill.Div.Style](#anytype-Event-Block-Fill-Div-Style) | | | +| style | [Event.Block.Fill.Div.Style](#anytype.Event.Block.Fill.Div.Style) | | | - + ### Event.Block.Fill.Div.Style @@ -15918,14 +15918,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.Block.Content.Div.Style](#anytype-model-Block-Content-Div-Style) | | | +| value | [model.Block.Content.Div.Style](#anytype.model.Block.Content.Div.Style) | | | - + ### Event.Block.Fill.Fields @@ -15934,14 +15934,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| fields | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| fields | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### Event.Block.Fill.File @@ -15950,20 +15950,20 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| type | [Event.Block.Fill.File.Type](#anytype-Event-Block-Fill-File-Type) | | | -| state | [Event.Block.Fill.File.State](#anytype-Event-Block-Fill-File-State) | | | -| mime | [Event.Block.Fill.File.Mime](#anytype-Event-Block-Fill-File-Mime) | | | -| hash | [Event.Block.Fill.File.Hash](#anytype-Event-Block-Fill-File-Hash) | | | -| name | [Event.Block.Fill.File.Name](#anytype-Event-Block-Fill-File-Name) | | | -| size | [Event.Block.Fill.File.Size](#anytype-Event-Block-Fill-File-Size) | | | -| style | [Event.Block.Fill.File.Style](#anytype-Event-Block-Fill-File-Style) | | | +| type | [Event.Block.Fill.File.Type](#anytype.Event.Block.Fill.File.Type) | | | +| state | [Event.Block.Fill.File.State](#anytype.Event.Block.Fill.File.State) | | | +| mime | [Event.Block.Fill.File.Mime](#anytype.Event.Block.Fill.File.Mime) | | | +| hash | [Event.Block.Fill.File.Hash](#anytype.Event.Block.Fill.File.Hash) | | | +| name | [Event.Block.Fill.File.Name](#anytype.Event.Block.Fill.File.Name) | | | +| size | [Event.Block.Fill.File.Size](#anytype.Event.Block.Fill.File.Size) | | | +| style | [Event.Block.Fill.File.Style](#anytype.Event.Block.Fill.File.Style) | | | - + ### Event.Block.Fill.File.Hash @@ -15978,7 +15978,7 @@ Precondition: user A opened a block - + ### Event.Block.Fill.File.Mime @@ -15993,7 +15993,7 @@ Precondition: user A opened a block - + ### Event.Block.Fill.File.Name @@ -16008,7 +16008,7 @@ Precondition: user A opened a block - + ### Event.Block.Fill.File.Size @@ -16023,7 +16023,7 @@ Precondition: user A opened a block - + ### Event.Block.Fill.File.State @@ -16031,14 +16031,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.Block.Content.File.State](#anytype-model-Block-Content-File-State) | | | +| value | [model.Block.Content.File.State](#anytype.model.Block.Content.File.State) | | | - + ### Event.Block.Fill.File.Style @@ -16046,14 +16046,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.Block.Content.File.Style](#anytype-model-Block-Content-File-Style) | | | +| value | [model.Block.Content.File.Style](#anytype.model.Block.Content.File.Style) | | | - + ### Event.Block.Fill.File.Type @@ -16061,14 +16061,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.Block.Content.File.Type](#anytype-model-Block-Content-File-Type) | | | +| value | [model.Block.Content.File.Type](#anytype.model.Block.Content.File.Type) | | | - + ### Event.Block.Fill.File.Width @@ -16083,7 +16083,7 @@ Precondition: user A opened a block - + ### Event.Block.Fill.Link @@ -16092,16 +16092,16 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| targetBlockId | [Event.Block.Fill.Link.TargetBlockId](#anytype-Event-Block-Fill-Link-TargetBlockId) | | | -| style | [Event.Block.Fill.Link.Style](#anytype-Event-Block-Fill-Link-Style) | | | -| fields | [Event.Block.Fill.Link.Fields](#anytype-Event-Block-Fill-Link-Fields) | | | +| targetBlockId | [Event.Block.Fill.Link.TargetBlockId](#anytype.Event.Block.Fill.Link.TargetBlockId) | | | +| style | [Event.Block.Fill.Link.Style](#anytype.Event.Block.Fill.Link.Style) | | | +| fields | [Event.Block.Fill.Link.Fields](#anytype.Event.Block.Fill.Link.Fields) | | | - + ### Event.Block.Fill.Link.Fields @@ -16109,14 +16109,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| value | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### Event.Block.Fill.Link.Style @@ -16124,14 +16124,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.Block.Content.Link.Style](#anytype-model-Block-Content-Link-Style) | | | +| value | [model.Block.Content.Link.Style](#anytype.model.Block.Content.Link.Style) | | | - + ### Event.Block.Fill.Link.TargetBlockId @@ -16146,7 +16146,7 @@ Precondition: user A opened a block - + ### Event.Block.Fill.Restrictions @@ -16155,14 +16155,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| restrictions | [model.Block.Restrictions](#anytype-model-Block-Restrictions) | | | +| restrictions | [model.Block.Restrictions](#anytype.model.Block.Restrictions) | | | - + ### Event.Block.Fill.Text @@ -16171,18 +16171,18 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| text | [Event.Block.Fill.Text.Text](#anytype-Event-Block-Fill-Text-Text) | | | -| style | [Event.Block.Fill.Text.Style](#anytype-Event-Block-Fill-Text-Style) | | | -| marks | [Event.Block.Fill.Text.Marks](#anytype-Event-Block-Fill-Text-Marks) | | | -| checked | [Event.Block.Fill.Text.Checked](#anytype-Event-Block-Fill-Text-Checked) | | | -| color | [Event.Block.Fill.Text.Color](#anytype-Event-Block-Fill-Text-Color) | | | +| text | [Event.Block.Fill.Text.Text](#anytype.Event.Block.Fill.Text.Text) | | | +| style | [Event.Block.Fill.Text.Style](#anytype.Event.Block.Fill.Text.Style) | | | +| marks | [Event.Block.Fill.Text.Marks](#anytype.Event.Block.Fill.Text.Marks) | | | +| checked | [Event.Block.Fill.Text.Checked](#anytype.Event.Block.Fill.Text.Checked) | | | +| color | [Event.Block.Fill.Text.Color](#anytype.Event.Block.Fill.Text.Color) | | | - + ### Event.Block.Fill.Text.Checked @@ -16197,7 +16197,7 @@ Precondition: user A opened a block - + ### Event.Block.Fill.Text.Color @@ -16212,7 +16212,7 @@ Precondition: user A opened a block - + ### Event.Block.Fill.Text.Marks @@ -16220,14 +16220,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.Block.Content.Text.Marks](#anytype-model-Block-Content-Text-Marks) | | | +| value | [model.Block.Content.Text.Marks](#anytype.model.Block.Content.Text.Marks) | | | - + ### Event.Block.Fill.Text.Style @@ -16235,14 +16235,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.Block.Content.Text.Style](#anytype-model-Block-Content-Text-Style) | | | +| value | [model.Block.Content.Text.Style](#anytype.model.Block.Content.Text.Style) | | | - + ### Event.Block.Fill.Text.Text @@ -16257,7 +16257,7 @@ Precondition: user A opened a block - + ### Event.Block.MarksInfo @@ -16265,14 +16265,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| marksInRange | [model.Block.Content.Text.Mark.Type](#anytype-model-Block-Content-Text-Mark-Type) | repeated | | +| marksInRange | [model.Block.Content.Text.Mark.Type](#anytype.model.Block.Content.Text.Mark.Type) | repeated | | - + ### Event.Block.Set @@ -16282,7 +16282,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.Align @@ -16291,14 +16291,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| align | [model.Block.Align](#anytype-model-Block-Align) | | | +| align | [model.Block.Align](#anytype.model.Block.Align) | | | - + ### Event.Block.Set.BackgroundColor @@ -16314,7 +16314,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.Bookmark @@ -16323,21 +16323,21 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| url | [Event.Block.Set.Bookmark.Url](#anytype-Event-Block-Set-Bookmark-Url) | | | -| title | [Event.Block.Set.Bookmark.Title](#anytype-Event-Block-Set-Bookmark-Title) | | | -| description | [Event.Block.Set.Bookmark.Description](#anytype-Event-Block-Set-Bookmark-Description) | | | -| imageHash | [Event.Block.Set.Bookmark.ImageHash](#anytype-Event-Block-Set-Bookmark-ImageHash) | | | -| faviconHash | [Event.Block.Set.Bookmark.FaviconHash](#anytype-Event-Block-Set-Bookmark-FaviconHash) | | | -| type | [Event.Block.Set.Bookmark.Type](#anytype-Event-Block-Set-Bookmark-Type) | | | -| targetObjectId | [Event.Block.Set.Bookmark.TargetObjectId](#anytype-Event-Block-Set-Bookmark-TargetObjectId) | | | -| state | [Event.Block.Set.Bookmark.State](#anytype-Event-Block-Set-Bookmark-State) | | | +| url | [Event.Block.Set.Bookmark.Url](#anytype.Event.Block.Set.Bookmark.Url) | | | +| title | [Event.Block.Set.Bookmark.Title](#anytype.Event.Block.Set.Bookmark.Title) | | | +| description | [Event.Block.Set.Bookmark.Description](#anytype.Event.Block.Set.Bookmark.Description) | | | +| imageHash | [Event.Block.Set.Bookmark.ImageHash](#anytype.Event.Block.Set.Bookmark.ImageHash) | | | +| faviconHash | [Event.Block.Set.Bookmark.FaviconHash](#anytype.Event.Block.Set.Bookmark.FaviconHash) | | | +| type | [Event.Block.Set.Bookmark.Type](#anytype.Event.Block.Set.Bookmark.Type) | | | +| targetObjectId | [Event.Block.Set.Bookmark.TargetObjectId](#anytype.Event.Block.Set.Bookmark.TargetObjectId) | | | +| state | [Event.Block.Set.Bookmark.State](#anytype.Event.Block.Set.Bookmark.State) | | | - + ### Event.Block.Set.Bookmark.Description @@ -16352,7 +16352,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.Bookmark.FaviconHash @@ -16367,7 +16367,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.Bookmark.ImageHash @@ -16382,7 +16382,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.Bookmark.State @@ -16390,14 +16390,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.Block.Content.Bookmark.State](#anytype-model-Block-Content-Bookmark-State) | | | +| value | [model.Block.Content.Bookmark.State](#anytype.model.Block.Content.Bookmark.State) | | | - + ### Event.Block.Set.Bookmark.TargetObjectId @@ -16412,7 +16412,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.Bookmark.Title @@ -16427,7 +16427,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.Bookmark.Type @@ -16435,14 +16435,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.LinkPreview.Type](#anytype-model-LinkPreview-Type) | | | +| value | [model.LinkPreview.Type](#anytype.model.LinkPreview.Type) | | | - + ### Event.Block.Set.Bookmark.Url @@ -16457,7 +16457,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.ChildrenIds @@ -16473,7 +16473,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.Div @@ -16482,14 +16482,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| style | [Event.Block.Set.Div.Style](#anytype-Event-Block-Set-Div-Style) | | | +| style | [Event.Block.Set.Div.Style](#anytype.Event.Block.Set.Div.Style) | | | - + ### Event.Block.Set.Div.Style @@ -16497,14 +16497,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.Block.Content.Div.Style](#anytype-model-Block-Content-Div-Style) | | | +| value | [model.Block.Content.Div.Style](#anytype.model.Block.Content.Div.Style) | | | - + ### Event.Block.Set.Fields @@ -16513,14 +16513,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| fields | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| fields | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### Event.Block.Set.File @@ -16529,20 +16529,20 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| type | [Event.Block.Set.File.Type](#anytype-Event-Block-Set-File-Type) | | | -| state | [Event.Block.Set.File.State](#anytype-Event-Block-Set-File-State) | | | -| mime | [Event.Block.Set.File.Mime](#anytype-Event-Block-Set-File-Mime) | | | -| hash | [Event.Block.Set.File.Hash](#anytype-Event-Block-Set-File-Hash) | | | -| name | [Event.Block.Set.File.Name](#anytype-Event-Block-Set-File-Name) | | | -| size | [Event.Block.Set.File.Size](#anytype-Event-Block-Set-File-Size) | | | -| style | [Event.Block.Set.File.Style](#anytype-Event-Block-Set-File-Style) | | | +| type | [Event.Block.Set.File.Type](#anytype.Event.Block.Set.File.Type) | | | +| state | [Event.Block.Set.File.State](#anytype.Event.Block.Set.File.State) | | | +| mime | [Event.Block.Set.File.Mime](#anytype.Event.Block.Set.File.Mime) | | | +| hash | [Event.Block.Set.File.Hash](#anytype.Event.Block.Set.File.Hash) | | | +| name | [Event.Block.Set.File.Name](#anytype.Event.Block.Set.File.Name) | | | +| size | [Event.Block.Set.File.Size](#anytype.Event.Block.Set.File.Size) | | | +| style | [Event.Block.Set.File.Style](#anytype.Event.Block.Set.File.Style) | | | - + ### Event.Block.Set.File.Hash @@ -16557,7 +16557,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.File.Mime @@ -16572,7 +16572,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.File.Name @@ -16587,7 +16587,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.File.Size @@ -16602,7 +16602,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.File.State @@ -16610,14 +16610,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.Block.Content.File.State](#anytype-model-Block-Content-File-State) | | | +| value | [model.Block.Content.File.State](#anytype.model.Block.Content.File.State) | | | - + ### Event.Block.Set.File.Style @@ -16625,14 +16625,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.Block.Content.File.Style](#anytype-model-Block-Content-File-Style) | | | +| value | [model.Block.Content.File.Style](#anytype.model.Block.Content.File.Style) | | | - + ### Event.Block.Set.File.Type @@ -16640,14 +16640,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.Block.Content.File.Type](#anytype-model-Block-Content-File-Type) | | | +| value | [model.Block.Content.File.Type](#anytype.model.Block.Content.File.Type) | | | - + ### Event.Block.Set.File.Width @@ -16662,7 +16662,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.Latex @@ -16671,14 +16671,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| text | [Event.Block.Set.Latex.Text](#anytype-Event-Block-Set-Latex-Text) | | | +| text | [Event.Block.Set.Latex.Text](#anytype.Event.Block.Set.Latex.Text) | | | - + ### Event.Block.Set.Latex.Text @@ -16693,7 +16693,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.Link @@ -16702,20 +16702,20 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| targetBlockId | [Event.Block.Set.Link.TargetBlockId](#anytype-Event-Block-Set-Link-TargetBlockId) | | | -| style | [Event.Block.Set.Link.Style](#anytype-Event-Block-Set-Link-Style) | | | -| fields | [Event.Block.Set.Link.Fields](#anytype-Event-Block-Set-Link-Fields) | | | -| iconSize | [Event.Block.Set.Link.IconSize](#anytype-Event-Block-Set-Link-IconSize) | | | -| cardStyle | [Event.Block.Set.Link.CardStyle](#anytype-Event-Block-Set-Link-CardStyle) | | | -| description | [Event.Block.Set.Link.Description](#anytype-Event-Block-Set-Link-Description) | | | -| relations | [Event.Block.Set.Link.Relations](#anytype-Event-Block-Set-Link-Relations) | | | +| targetBlockId | [Event.Block.Set.Link.TargetBlockId](#anytype.Event.Block.Set.Link.TargetBlockId) | | | +| style | [Event.Block.Set.Link.Style](#anytype.Event.Block.Set.Link.Style) | | | +| fields | [Event.Block.Set.Link.Fields](#anytype.Event.Block.Set.Link.Fields) | | | +| iconSize | [Event.Block.Set.Link.IconSize](#anytype.Event.Block.Set.Link.IconSize) | | | +| cardStyle | [Event.Block.Set.Link.CardStyle](#anytype.Event.Block.Set.Link.CardStyle) | | | +| description | [Event.Block.Set.Link.Description](#anytype.Event.Block.Set.Link.Description) | | | +| relations | [Event.Block.Set.Link.Relations](#anytype.Event.Block.Set.Link.Relations) | | | - + ### Event.Block.Set.Link.CardStyle @@ -16723,14 +16723,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.Block.Content.Link.CardStyle](#anytype-model-Block-Content-Link-CardStyle) | | | +| value | [model.Block.Content.Link.CardStyle](#anytype.model.Block.Content.Link.CardStyle) | | | - + ### Event.Block.Set.Link.Description @@ -16738,14 +16738,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.Block.Content.Link.Description](#anytype-model-Block-Content-Link-Description) | | | +| value | [model.Block.Content.Link.Description](#anytype.model.Block.Content.Link.Description) | | | - + ### Event.Block.Set.Link.Fields @@ -16753,14 +16753,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| value | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### Event.Block.Set.Link.IconSize @@ -16768,14 +16768,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.Block.Content.Link.IconSize](#anytype-model-Block-Content-Link-IconSize) | | | +| value | [model.Block.Content.Link.IconSize](#anytype.model.Block.Content.Link.IconSize) | | | - + ### Event.Block.Set.Link.Relations @@ -16790,7 +16790,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.Link.Style @@ -16798,14 +16798,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.Block.Content.Link.Style](#anytype-model-Block-Content-Link-Style) | | | +| value | [model.Block.Content.Link.Style](#anytype.model.Block.Content.Link.Style) | | | - + ### Event.Block.Set.Link.TargetBlockId @@ -16820,7 +16820,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.Relation @@ -16829,14 +16829,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| key | [Event.Block.Set.Relation.Key](#anytype-Event-Block-Set-Relation-Key) | | | +| key | [Event.Block.Set.Relation.Key](#anytype.Event.Block.Set.Relation.Key) | | | - + ### Event.Block.Set.Relation.Key @@ -16851,7 +16851,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.Restrictions @@ -16860,14 +16860,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| restrictions | [model.Block.Restrictions](#anytype-model-Block-Restrictions) | | | +| restrictions | [model.Block.Restrictions](#anytype.model.Block.Restrictions) | | | - + ### Event.Block.Set.TableRow @@ -16876,14 +16876,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| isHeader | [Event.Block.Set.TableRow.IsHeader](#anytype-Event-Block-Set-TableRow-IsHeader) | | | +| isHeader | [Event.Block.Set.TableRow.IsHeader](#anytype.Event.Block.Set.TableRow.IsHeader) | | | - + ### Event.Block.Set.TableRow.IsHeader @@ -16898,7 +16898,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.Text @@ -16907,20 +16907,20 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| text | [Event.Block.Set.Text.Text](#anytype-Event-Block-Set-Text-Text) | | | -| style | [Event.Block.Set.Text.Style](#anytype-Event-Block-Set-Text-Style) | | | -| marks | [Event.Block.Set.Text.Marks](#anytype-Event-Block-Set-Text-Marks) | | | -| checked | [Event.Block.Set.Text.Checked](#anytype-Event-Block-Set-Text-Checked) | | | -| color | [Event.Block.Set.Text.Color](#anytype-Event-Block-Set-Text-Color) | | | -| iconEmoji | [Event.Block.Set.Text.IconEmoji](#anytype-Event-Block-Set-Text-IconEmoji) | | | -| iconImage | [Event.Block.Set.Text.IconImage](#anytype-Event-Block-Set-Text-IconImage) | | | +| text | [Event.Block.Set.Text.Text](#anytype.Event.Block.Set.Text.Text) | | | +| style | [Event.Block.Set.Text.Style](#anytype.Event.Block.Set.Text.Style) | | | +| marks | [Event.Block.Set.Text.Marks](#anytype.Event.Block.Set.Text.Marks) | | | +| checked | [Event.Block.Set.Text.Checked](#anytype.Event.Block.Set.Text.Checked) | | | +| color | [Event.Block.Set.Text.Color](#anytype.Event.Block.Set.Text.Color) | | | +| iconEmoji | [Event.Block.Set.Text.IconEmoji](#anytype.Event.Block.Set.Text.IconEmoji) | | | +| iconImage | [Event.Block.Set.Text.IconImage](#anytype.Event.Block.Set.Text.IconImage) | | | - + ### Event.Block.Set.Text.Checked @@ -16935,7 +16935,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.Text.Color @@ -16950,7 +16950,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.Text.IconEmoji @@ -16965,7 +16965,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.Text.IconImage @@ -16980,7 +16980,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.Text.Marks @@ -16988,14 +16988,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.Block.Content.Text.Marks](#anytype-model-Block-Content-Text-Marks) | | | +| value | [model.Block.Content.Text.Marks](#anytype.model.Block.Content.Text.Marks) | | | - + ### Event.Block.Set.Text.Style @@ -17003,14 +17003,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.Block.Content.Text.Style](#anytype-model-Block-Content-Text-Style) | | | +| value | [model.Block.Content.Text.Style](#anytype.model.Block.Content.Text.Style) | | | - + ### Event.Block.Set.Text.Text @@ -17025,7 +17025,7 @@ Precondition: user A opened a block - + ### Event.Block.Set.VerticalAlign @@ -17034,14 +17034,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| verticalAlign | [model.Block.VerticalAlign](#anytype-model-Block-VerticalAlign) | | | +| verticalAlign | [model.Block.VerticalAlign](#anytype.model.Block.VerticalAlign) | | | - + ### Event.Block.Set.Widget @@ -17050,14 +17050,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| layout | [Event.Block.Set.Widget.Layout](#anytype-Event-Block-Set-Widget-Layout) | | | +| layout | [Event.Block.Set.Widget.Layout](#anytype.Event.Block.Set.Widget.Layout) | | | - + ### Event.Block.Set.Widget.Layout @@ -17065,14 +17065,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [model.Block.Content.Widget.Layout](#anytype-model-Block-Content-Widget-Layout) | | | +| value | [model.Block.Content.Widget.Layout](#anytype.model.Block.Content.Widget.Layout) | | | - + ### Event.Message @@ -17080,66 +17080,66 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| accountShow | [Event.Account.Show](#anytype-Event-Account-Show) | | | -| accountDetails | [Event.Account.Details](#anytype-Event-Account-Details) | | | -| accountConfigUpdate | [Event.Account.Config.Update](#anytype-Event-Account-Config-Update) | | | -| accountUpdate | [Event.Account.Update](#anytype-Event-Account-Update) | | | -| objectDetailsSet | [Event.Object.Details.Set](#anytype-Event-Object-Details-Set) | | | -| objectDetailsAmend | [Event.Object.Details.Amend](#anytype-Event-Object-Details-Amend) | | | -| objectDetailsUnset | [Event.Object.Details.Unset](#anytype-Event-Object-Details-Unset) | | | -| objectRelationsAmend | [Event.Object.Relations.Amend](#anytype-Event-Object-Relations-Amend) | | | -| objectRelationsRemove | [Event.Object.Relations.Remove](#anytype-Event-Object-Relations-Remove) | | | -| objectRemove | [Event.Object.Remove](#anytype-Event-Object-Remove) | | | -| subscriptionAdd | [Event.Object.Subscription.Add](#anytype-Event-Object-Subscription-Add) | | | -| subscriptionRemove | [Event.Object.Subscription.Remove](#anytype-Event-Object-Subscription-Remove) | | | -| subscriptionPosition | [Event.Object.Subscription.Position](#anytype-Event-Object-Subscription-Position) | | | -| subscriptionCounters | [Event.Object.Subscription.Counters](#anytype-Event-Object-Subscription-Counters) | | | -| subscriptionGroups | [Event.Object.Subscription.Groups](#anytype-Event-Object-Subscription-Groups) | | | -| blockAdd | [Event.Block.Add](#anytype-Event-Block-Add) | | | -| blockDelete | [Event.Block.Delete](#anytype-Event-Block-Delete) | | | -| filesUpload | [Event.Block.FilesUpload](#anytype-Event-Block-FilesUpload) | | | -| marksInfo | [Event.Block.MarksInfo](#anytype-Event-Block-MarksInfo) | | | -| blockSetFields | [Event.Block.Set.Fields](#anytype-Event-Block-Set-Fields) | | | -| blockSetChildrenIds | [Event.Block.Set.ChildrenIds](#anytype-Event-Block-Set-ChildrenIds) | | | -| blockSetRestrictions | [Event.Block.Set.Restrictions](#anytype-Event-Block-Set-Restrictions) | | | -| blockSetBackgroundColor | [Event.Block.Set.BackgroundColor](#anytype-Event-Block-Set-BackgroundColor) | | | -| blockSetText | [Event.Block.Set.Text](#anytype-Event-Block-Set-Text) | | | -| blockSetFile | [Event.Block.Set.File](#anytype-Event-Block-Set-File) | | | -| blockSetLink | [Event.Block.Set.Link](#anytype-Event-Block-Set-Link) | | | -| blockSetBookmark | [Event.Block.Set.Bookmark](#anytype-Event-Block-Set-Bookmark) | | | -| blockSetAlign | [Event.Block.Set.Align](#anytype-Event-Block-Set-Align) | | | -| blockSetDiv | [Event.Block.Set.Div](#anytype-Event-Block-Set-Div) | | | -| blockSetRelation | [Event.Block.Set.Relation](#anytype-Event-Block-Set-Relation) | | | -| blockSetLatex | [Event.Block.Set.Latex](#anytype-Event-Block-Set-Latex) | | | -| blockSetVerticalAlign | [Event.Block.Set.VerticalAlign](#anytype-Event-Block-Set-VerticalAlign) | | | -| blockSetTableRow | [Event.Block.Set.TableRow](#anytype-Event-Block-Set-TableRow) | | | -| blockSetWidget | [Event.Block.Set.Widget](#anytype-Event-Block-Set-Widget) | | | -| blockDataviewViewSet | [Event.Block.Dataview.ViewSet](#anytype-Event-Block-Dataview-ViewSet) | | | -| blockDataviewViewDelete | [Event.Block.Dataview.ViewDelete](#anytype-Event-Block-Dataview-ViewDelete) | | | -| blockDataviewViewOrder | [Event.Block.Dataview.ViewOrder](#anytype-Event-Block-Dataview-ViewOrder) | | | -| blockDataviewSourceSet | [Event.Block.Dataview.SourceSet](#anytype-Event-Block-Dataview-SourceSet) | | | -| blockDataViewGroupOrderUpdate | [Event.Block.Dataview.GroupOrderUpdate](#anytype-Event-Block-Dataview-GroupOrderUpdate) | | | -| blockDataViewObjectOrderUpdate | [Event.Block.Dataview.ObjectOrderUpdate](#anytype-Event-Block-Dataview-ObjectOrderUpdate) | | | -| blockDataviewRelationDelete | [Event.Block.Dataview.RelationDelete](#anytype-Event-Block-Dataview-RelationDelete) | | | -| blockDataviewRelationSet | [Event.Block.Dataview.RelationSet](#anytype-Event-Block-Dataview-RelationSet) | | | -| blockDataviewOldRelationDelete | [Event.Block.Dataview.OldRelationDelete](#anytype-Event-Block-Dataview-OldRelationDelete) | | deprecated | -| blockDataviewOldRelationSet | [Event.Block.Dataview.OldRelationSet](#anytype-Event-Block-Dataview-OldRelationSet) | | deprecated | -| userBlockJoin | [Event.User.Block.Join](#anytype-Event-User-Block-Join) | | | -| userBlockLeft | [Event.User.Block.Left](#anytype-Event-User-Block-Left) | | | -| userBlockSelectRange | [Event.User.Block.SelectRange](#anytype-Event-User-Block-SelectRange) | | | -| userBlockTextRange | [Event.User.Block.TextRange](#anytype-Event-User-Block-TextRange) | | | -| ping | [Event.Ping](#anytype-Event-Ping) | | | -| processNew | [Event.Process.New](#anytype-Event-Process-New) | | | -| processUpdate | [Event.Process.Update](#anytype-Event-Process-Update) | | | -| processDone | [Event.Process.Done](#anytype-Event-Process-Done) | | | -| threadStatus | [Event.Status.Thread](#anytype-Event-Status-Thread) | | | +| accountShow | [Event.Account.Show](#anytype.Event.Account.Show) | | | +| accountDetails | [Event.Account.Details](#anytype.Event.Account.Details) | | | +| accountConfigUpdate | [Event.Account.Config.Update](#anytype.Event.Account.Config.Update) | | | +| accountUpdate | [Event.Account.Update](#anytype.Event.Account.Update) | | | +| objectDetailsSet | [Event.Object.Details.Set](#anytype.Event.Object.Details.Set) | | | +| objectDetailsAmend | [Event.Object.Details.Amend](#anytype.Event.Object.Details.Amend) | | | +| objectDetailsUnset | [Event.Object.Details.Unset](#anytype.Event.Object.Details.Unset) | | | +| objectRelationsAmend | [Event.Object.Relations.Amend](#anytype.Event.Object.Relations.Amend) | | | +| objectRelationsRemove | [Event.Object.Relations.Remove](#anytype.Event.Object.Relations.Remove) | | | +| objectRemove | [Event.Object.Remove](#anytype.Event.Object.Remove) | | | +| subscriptionAdd | [Event.Object.Subscription.Add](#anytype.Event.Object.Subscription.Add) | | | +| subscriptionRemove | [Event.Object.Subscription.Remove](#anytype.Event.Object.Subscription.Remove) | | | +| subscriptionPosition | [Event.Object.Subscription.Position](#anytype.Event.Object.Subscription.Position) | | | +| subscriptionCounters | [Event.Object.Subscription.Counters](#anytype.Event.Object.Subscription.Counters) | | | +| subscriptionGroups | [Event.Object.Subscription.Groups](#anytype.Event.Object.Subscription.Groups) | | | +| blockAdd | [Event.Block.Add](#anytype.Event.Block.Add) | | | +| blockDelete | [Event.Block.Delete](#anytype.Event.Block.Delete) | | | +| filesUpload | [Event.Block.FilesUpload](#anytype.Event.Block.FilesUpload) | | | +| marksInfo | [Event.Block.MarksInfo](#anytype.Event.Block.MarksInfo) | | | +| blockSetFields | [Event.Block.Set.Fields](#anytype.Event.Block.Set.Fields) | | | +| blockSetChildrenIds | [Event.Block.Set.ChildrenIds](#anytype.Event.Block.Set.ChildrenIds) | | | +| blockSetRestrictions | [Event.Block.Set.Restrictions](#anytype.Event.Block.Set.Restrictions) | | | +| blockSetBackgroundColor | [Event.Block.Set.BackgroundColor](#anytype.Event.Block.Set.BackgroundColor) | | | +| blockSetText | [Event.Block.Set.Text](#anytype.Event.Block.Set.Text) | | | +| blockSetFile | [Event.Block.Set.File](#anytype.Event.Block.Set.File) | | | +| blockSetLink | [Event.Block.Set.Link](#anytype.Event.Block.Set.Link) | | | +| blockSetBookmark | [Event.Block.Set.Bookmark](#anytype.Event.Block.Set.Bookmark) | | | +| blockSetAlign | [Event.Block.Set.Align](#anytype.Event.Block.Set.Align) | | | +| blockSetDiv | [Event.Block.Set.Div](#anytype.Event.Block.Set.Div) | | | +| blockSetRelation | [Event.Block.Set.Relation](#anytype.Event.Block.Set.Relation) | | | +| blockSetLatex | [Event.Block.Set.Latex](#anytype.Event.Block.Set.Latex) | | | +| blockSetVerticalAlign | [Event.Block.Set.VerticalAlign](#anytype.Event.Block.Set.VerticalAlign) | | | +| blockSetTableRow | [Event.Block.Set.TableRow](#anytype.Event.Block.Set.TableRow) | | | +| blockSetWidget | [Event.Block.Set.Widget](#anytype.Event.Block.Set.Widget) | | | +| blockDataviewViewSet | [Event.Block.Dataview.ViewSet](#anytype.Event.Block.Dataview.ViewSet) | | | +| blockDataviewViewDelete | [Event.Block.Dataview.ViewDelete](#anytype.Event.Block.Dataview.ViewDelete) | | | +| blockDataviewViewOrder | [Event.Block.Dataview.ViewOrder](#anytype.Event.Block.Dataview.ViewOrder) | | | +| blockDataviewSourceSet | [Event.Block.Dataview.SourceSet](#anytype.Event.Block.Dataview.SourceSet) | | | +| blockDataViewGroupOrderUpdate | [Event.Block.Dataview.GroupOrderUpdate](#anytype.Event.Block.Dataview.GroupOrderUpdate) | | | +| blockDataViewObjectOrderUpdate | [Event.Block.Dataview.ObjectOrderUpdate](#anytype.Event.Block.Dataview.ObjectOrderUpdate) | | | +| blockDataviewRelationDelete | [Event.Block.Dataview.RelationDelete](#anytype.Event.Block.Dataview.RelationDelete) | | | +| blockDataviewRelationSet | [Event.Block.Dataview.RelationSet](#anytype.Event.Block.Dataview.RelationSet) | | | +| blockDataviewOldRelationDelete | [Event.Block.Dataview.OldRelationDelete](#anytype.Event.Block.Dataview.OldRelationDelete) | | deprecated | +| blockDataviewOldRelationSet | [Event.Block.Dataview.OldRelationSet](#anytype.Event.Block.Dataview.OldRelationSet) | | deprecated | +| userBlockJoin | [Event.User.Block.Join](#anytype.Event.User.Block.Join) | | | +| userBlockLeft | [Event.User.Block.Left](#anytype.Event.User.Block.Left) | | | +| userBlockSelectRange | [Event.User.Block.SelectRange](#anytype.Event.User.Block.SelectRange) | | | +| userBlockTextRange | [Event.User.Block.TextRange](#anytype.Event.User.Block.TextRange) | | | +| ping | [Event.Ping](#anytype.Event.Ping) | | | +| processNew | [Event.Process.New](#anytype.Event.Process.New) | | | +| processUpdate | [Event.Process.Update](#anytype.Event.Process.Update) | | | +| processDone | [Event.Process.Done](#anytype.Event.Process.Done) | | | +| threadStatus | [Event.Status.Thread](#anytype.Event.Status.Thread) | | | - + ### Event.Object @@ -17149,7 +17149,7 @@ Precondition: user A opened a block - + ### Event.Object.Details @@ -17159,7 +17159,7 @@ Precondition: user A opened a block - + ### Event.Object.Details.Amend Amend (i.e. add a new key-value pair or update an existing key-value pair) existing state @@ -17168,7 +17168,7 @@ Amend (i.e. add a new key-value pair or update an existing key-value pair) exist | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | context objectId | -| details | [Event.Object.Details.Amend.KeyValue](#anytype-Event-Object-Details-Amend-KeyValue) | repeated | slice of changed key-values | +| details | [Event.Object.Details.Amend.KeyValue](#anytype.Event.Object.Details.Amend.KeyValue) | repeated | slice of changed key-values | | subIds | [string](#string) | repeated | | @@ -17176,7 +17176,7 @@ Amend (i.e. add a new key-value pair or update an existing key-value pair) exist - + ### Event.Object.Details.Amend.KeyValue @@ -17185,14 +17185,14 @@ Amend (i.e. add a new key-value pair or update an existing key-value pair) exist | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | key | [string](#string) | | | -| value | [google.protobuf.Value](#google-protobuf-Value) | | should not be null | +| value | [google.protobuf.Value](#google.protobuf.Value) | | should not be null | - + ### Event.Object.Details.Set Overwrite current state @@ -17201,7 +17201,7 @@ Overwrite current state | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | context objectId | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | can not be a partial state. Should replace client details state | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | can not be a partial state. Should replace client details state | | subIds | [string](#string) | repeated | | @@ -17209,7 +17209,7 @@ Overwrite current state - + ### Event.Object.Details.Unset Unset existing detail keys @@ -17226,7 +17226,7 @@ Unset existing detail keys - + ### Event.Object.Relations @@ -17236,7 +17236,7 @@ Unset existing detail keys - + ### Event.Object.Relations.Amend @@ -17245,14 +17245,14 @@ Unset existing detail keys | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | context objectId | -| relationLinks | [model.RelationLink](#anytype-model-RelationLink) | repeated | | +| relationLinks | [model.RelationLink](#anytype.model.RelationLink) | repeated | | - + ### Event.Object.Relations.Remove @@ -17268,7 +17268,7 @@ Unset existing detail keys - + ### Event.Object.Remove @@ -17283,7 +17283,7 @@ Unset existing detail keys - + ### Event.Object.Restriction @@ -17292,14 +17292,14 @@ Unset existing detail keys | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| restrictions | [model.Restrictions](#anytype-model-Restrictions) | | | +| restrictions | [model.Restrictions](#anytype.model.Restrictions) | | | - + ### Event.Object.Subscription @@ -17309,7 +17309,7 @@ Unset existing detail keys - + ### Event.Object.Subscription.Add Adds new document to subscriptions @@ -17326,7 +17326,7 @@ Adds new document to subscriptions - + ### Event.Object.Subscription.Counters @@ -17344,7 +17344,7 @@ Adds new document to subscriptions - + ### Event.Object.Subscription.Groups @@ -17353,7 +17353,7 @@ Adds new document to subscriptions | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | subId | [string](#string) | | | -| group | [model.Block.Content.Dataview.Group](#anytype-model-Block-Content-Dataview-Group) | | | +| group | [model.Block.Content.Dataview.Group](#anytype.model.Block.Content.Dataview.Group) | | | | remove | [bool](#bool) | | | @@ -17361,7 +17361,7 @@ Adds new document to subscriptions - + ### Event.Object.Subscription.Position Indicates new position of document @@ -17378,7 +17378,7 @@ Indicates new position of document - + ### Event.Object.Subscription.Remove Removes document from subscription @@ -17394,7 +17394,7 @@ Removes document from subscription - + ### Event.Ping @@ -17409,7 +17409,7 @@ Removes document from subscription - + ### Event.Process @@ -17419,7 +17419,7 @@ Removes document from subscription - + ### Event.Process.Done @@ -17427,14 +17427,14 @@ Removes document from subscription | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| process | [Model.Process](#anytype-Model-Process) | | | +| process | [Model.Process](#anytype.Model.Process) | | | - + ### Event.Process.New @@ -17442,14 +17442,14 @@ Removes document from subscription | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| process | [Model.Process](#anytype-Model-Process) | | | +| process | [Model.Process](#anytype.Model.Process) | | | - + ### Event.Process.Update @@ -17457,14 +17457,14 @@ Removes document from subscription | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| process | [Model.Process](#anytype-Model-Process) | | | +| process | [Model.Process](#anytype.Model.Process) | | | - + ### Event.Status @@ -17474,7 +17474,7 @@ Removes document from subscription - + ### Event.Status.Thread @@ -17482,16 +17482,16 @@ Removes document from subscription | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| summary | [Event.Status.Thread.Summary](#anytype-Event-Status-Thread-Summary) | | | -| cafe | [Event.Status.Thread.Cafe](#anytype-Event-Status-Thread-Cafe) | | | -| accounts | [Event.Status.Thread.Account](#anytype-Event-Status-Thread-Account) | repeated | | +| summary | [Event.Status.Thread.Summary](#anytype.Event.Status.Thread.Summary) | | | +| cafe | [Event.Status.Thread.Cafe](#anytype.Event.Status.Thread.Cafe) | | | +| accounts | [Event.Status.Thread.Account](#anytype.Event.Status.Thread.Account) | repeated | | - + ### Event.Status.Thread.Account @@ -17505,14 +17505,14 @@ Removes document from subscription | online | [bool](#bool) | | | | lastPulled | [int64](#int64) | | | | lastEdited | [int64](#int64) | | | -| devices | [Event.Status.Thread.Device](#anytype-Event-Status-Thread-Device) | repeated | | +| devices | [Event.Status.Thread.Device](#anytype.Event.Status.Thread.Device) | repeated | | - + ### Event.Status.Thread.Cafe @@ -17520,17 +17520,17 @@ Removes document from subscription | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| status | [Event.Status.Thread.SyncStatus](#anytype-Event-Status-Thread-SyncStatus) | | | +| status | [Event.Status.Thread.SyncStatus](#anytype.Event.Status.Thread.SyncStatus) | | | | lastPulled | [int64](#int64) | | | | lastPushSucceed | [bool](#bool) | | | -| files | [Event.Status.Thread.Cafe.PinStatus](#anytype-Event-Status-Thread-Cafe-PinStatus) | | | +| files | [Event.Status.Thread.Cafe.PinStatus](#anytype.Event.Status.Thread.Cafe.PinStatus) | | | - + ### Event.Status.Thread.Cafe.PinStatus @@ -17548,7 +17548,7 @@ Removes document from subscription - + ### Event.Status.Thread.Device @@ -17566,7 +17566,7 @@ Removes document from subscription - + ### Event.Status.Thread.Summary @@ -17574,14 +17574,14 @@ Removes document from subscription | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| status | [Event.Status.Thread.SyncStatus](#anytype-Event-Status-Thread-SyncStatus) | | | +| status | [Event.Status.Thread.SyncStatus](#anytype.Event.Status.Thread.SyncStatus) | | | - + ### Event.User @@ -17591,7 +17591,7 @@ Removes document from subscription - + ### Event.User.Block @@ -17601,7 +17601,7 @@ Removes document from subscription - + ### Event.User.Block.Join Middleware to front end event message, that will be sent in this scenario: @@ -17612,14 +17612,14 @@ Precondition: user A opened a block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| account | [Event.Account](#anytype-Event-Account) | | Account of the user, that opened a block | +| account | [Event.Account](#anytype.Event.Account) | | Account of the user, that opened a block | - + ### Event.User.Block.Left Middleware to front end event message, that will be sent in this scenario: @@ -17630,14 +17630,14 @@ Precondition: user A and user B opened the same block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| account | [Event.Account](#anytype-Event-Account) | | Account of the user, that left the block | +| account | [Event.Account](#anytype.Event.Account) | | Account of the user, that left the block | - + ### Event.User.Block.SelectRange Middleware to front end event message, that will be sent in this scenario: @@ -17648,7 +17648,7 @@ Precondition: user A and user B opened the same block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| account | [Event.Account](#anytype-Event-Account) | | Account of the user, that selected blocks | +| account | [Event.Account](#anytype.Event.Account) | | Account of the user, that selected blocks | | blockIdsArray | [string](#string) | repeated | Ids of selected blocks. | @@ -17656,7 +17656,7 @@ Precondition: user A and user B opened the same block - + ### Event.User.Block.TextRange Middleware to front end event message, that will be sent in this scenario: @@ -17667,16 +17667,16 @@ Precondition: user A and user B opened the same block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| account | [Event.Account](#anytype-Event-Account) | | Account of the user, that selected a text | +| account | [Event.Account](#anytype.Event.Account) | | Account of the user, that selected a text | | blockId | [string](#string) | | Id of the text block, that have a selection | -| range | [model.Range](#anytype-model-Range) | | Range of the selection | +| range | [model.Range](#anytype.model.Range) | | Range of the selection | - + ### Model @@ -17686,7 +17686,7 @@ Precondition: user A and user B opened the same block - + ### Model.Process @@ -17695,16 +17695,16 @@ Precondition: user A and user B opened the same block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| type | [Model.Process.Type](#anytype-Model-Process-Type) | | | -| state | [Model.Process.State](#anytype-Model-Process-State) | | | -| progress | [Model.Process.Progress](#anytype-Model-Process-Progress) | | | +| type | [Model.Process.Type](#anytype.Model.Process.Type) | | | +| state | [Model.Process.State](#anytype.Model.Process.State) | | | +| progress | [Model.Process.Progress](#anytype.Model.Process.Progress) | | | - + ### Model.Process.Progress @@ -17721,7 +17721,7 @@ Precondition: user A and user B opened the same block - + ### ResponseEvent @@ -17729,7 +17729,7 @@ Precondition: user A and user B opened the same block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| messages | [Event.Message](#anytype-Event-Message) | repeated | | +| messages | [Event.Message](#anytype.Event.Message) | repeated | | | contextId | [string](#string) | | | | traceId | [string](#string) | | | @@ -17740,7 +17740,7 @@ Precondition: user A and user B opened the same block - + ### Event.Block.Dataview.SliceOperation @@ -17755,7 +17755,7 @@ Precondition: user A and user B opened the same block - + ### Event.Status.Thread.SyncStatus @@ -17770,7 +17770,7 @@ Precondition: user A and user B opened the same block - + ### Model.Process.State @@ -17785,7 +17785,7 @@ Precondition: user A and user B opened the same block - + ### Model.Process.Type @@ -17807,14 +17807,14 @@ Precondition: user A and user B opened the same block - +

Top

## pkg/lib/pb/model/protos/localstore.proto - + ### ObjectDetails @@ -17822,14 +17822,14 @@ Precondition: user A and user B opened the same block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### ObjectInfo @@ -17839,18 +17839,18 @@ Precondition: user A and user B opened the same block | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | | objectTypeUrls | [string](#string) | repeated | deprecated | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | | -| relations | [Relation](#anytype-model-Relation) | repeated | | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | | +| relations | [Relation](#anytype.model.Relation) | repeated | | | snippet | [string](#string) | | | | hasInboundLinks | [bool](#bool) | | | -| objectType | [SmartBlockType](#anytype-model-SmartBlockType) | | | +| objectType | [SmartBlockType](#anytype.model.SmartBlockType) | | | - + ### ObjectInfoWithLinks @@ -17859,15 +17859,15 @@ Precondition: user A and user B opened the same block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| info | [ObjectInfo](#anytype-model-ObjectInfo) | | | -| links | [ObjectLinksInfo](#anytype-model-ObjectLinksInfo) | | | +| info | [ObjectInfo](#anytype.model.ObjectInfo) | | | +| links | [ObjectLinksInfo](#anytype.model.ObjectLinksInfo) | | | - + ### ObjectInfoWithOutboundLinks @@ -17876,15 +17876,15 @@ Precondition: user A and user B opened the same block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| info | [ObjectInfo](#anytype-model-ObjectInfo) | | | -| outboundLinks | [ObjectInfo](#anytype-model-ObjectInfo) | repeated | | +| info | [ObjectInfo](#anytype.model.ObjectInfo) | | | +| outboundLinks | [ObjectInfo](#anytype.model.ObjectInfo) | repeated | | - + ### ObjectInfoWithOutboundLinksIDs @@ -17893,7 +17893,7 @@ Precondition: user A and user B opened the same block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| info | [ObjectInfo](#anytype-model-ObjectInfo) | | | +| info | [ObjectInfo](#anytype.model.ObjectInfo) | | | | outboundLinks | [string](#string) | repeated | | @@ -17901,7 +17901,7 @@ Precondition: user A and user B opened the same block - + ### ObjectLinks @@ -17917,7 +17917,7 @@ Precondition: user A and user B opened the same block - + ### ObjectLinksInfo @@ -17925,15 +17925,15 @@ Precondition: user A and user B opened the same block | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| inbound | [ObjectInfo](#anytype-model-ObjectInfo) | repeated | | -| outbound | [ObjectInfo](#anytype-model-ObjectInfo) | repeated | | +| inbound | [ObjectInfo](#anytype.model.ObjectInfo) | repeated | | +| outbound | [ObjectInfo](#anytype.model.ObjectInfo) | repeated | | - + ### ObjectStoreChecksums @@ -17966,14 +17966,14 @@ Precondition: user A and user B opened the same block - +

Top

## pkg/lib/pb/model/protos/models.proto - + ### Account Contains basic information about a user account @@ -17983,17 +17983,17 @@ Contains basic information about a user account | ----- | ---- | ----- | ----------- | | id | [string](#string) | | User's thread id | | name | [string](#string) | | User name, that associated with this account | -| avatar | [Account.Avatar](#anytype-model-Account-Avatar) | | Avatar of a user's account | -| config | [Account.Config](#anytype-model-Account-Config) | | | -| status | [Account.Status](#anytype-model-Account-Status) | | | -| info | [Account.Info](#anytype-model-Account-Info) | | | +| avatar | [Account.Avatar](#anytype.model.Account.Avatar) | | Avatar of a user's account | +| config | [Account.Config](#anytype.model.Account.Config) | | | +| status | [Account.Status](#anytype.model.Account.Status) | | | +| info | [Account.Info](#anytype.model.Account.Info) | | | - + ### Account.Avatar Avatar of a user's account. It could be an image or color @@ -18001,7 +18001,7 @@ Avatar of a user's account. It could be an image or color | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| image | [Block.Content.File](#anytype-model-Block-Content-File) | | Image of the avatar. Contains the hash to retrieve the image. | +| image | [Block.Content.File](#anytype.model.Block.Content.File) | | Image of the avatar. Contains the hash to retrieve the image. | | color | [string](#string) | | Color of the avatar, used if image not set. | @@ -18009,7 +18009,7 @@ Avatar of a user's account. It could be an image or color - + ### Account.Config @@ -18021,14 +18021,14 @@ Avatar of a user's account. It could be an image or color | enableDebug | [bool](#bool) | | | | enablePrereleaseChannel | [bool](#bool) | | | | enableSpaces | [bool](#bool) | | | -| extra | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| extra | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### Account.Info @@ -18055,7 +18055,7 @@ Avatar of a user's account. It could be an image or color - + ### Account.Status @@ -18063,7 +18063,7 @@ Avatar of a user's account. It could be an image or color | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| statusType | [Account.StatusType](#anytype-model-Account-StatusType) | | | +| statusType | [Account.StatusType](#anytype.model.Account.StatusType) | | | | deletionDate | [int64](#int64) | | | @@ -18071,7 +18071,7 @@ Avatar of a user's account. It could be an image or color - + ### Block @@ -18080,36 +18080,36 @@ Avatar of a user's account. It could be an image or color | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| fields | [google.protobuf.Struct](#google-protobuf-Struct) | | | -| restrictions | [Block.Restrictions](#anytype-model-Block-Restrictions) | | | +| fields | [google.protobuf.Struct](#google.protobuf.Struct) | | | +| restrictions | [Block.Restrictions](#anytype.model.Block.Restrictions) | | | | childrenIds | [string](#string) | repeated | | | backgroundColor | [string](#string) | | | -| align | [Block.Align](#anytype-model-Block-Align) | | | -| verticalAlign | [Block.VerticalAlign](#anytype-model-Block-VerticalAlign) | | | -| smartblock | [Block.Content.Smartblock](#anytype-model-Block-Content-Smartblock) | | | -| text | [Block.Content.Text](#anytype-model-Block-Content-Text) | | | -| file | [Block.Content.File](#anytype-model-Block-Content-File) | | | -| layout | [Block.Content.Layout](#anytype-model-Block-Content-Layout) | | | -| div | [Block.Content.Div](#anytype-model-Block-Content-Div) | | | -| bookmark | [Block.Content.Bookmark](#anytype-model-Block-Content-Bookmark) | | | -| icon | [Block.Content.Icon](#anytype-model-Block-Content-Icon) | | | -| link | [Block.Content.Link](#anytype-model-Block-Content-Link) | | | -| dataview | [Block.Content.Dataview](#anytype-model-Block-Content-Dataview) | | | -| relation | [Block.Content.Relation](#anytype-model-Block-Content-Relation) | | | -| featuredRelations | [Block.Content.FeaturedRelations](#anytype-model-Block-Content-FeaturedRelations) | | | -| latex | [Block.Content.Latex](#anytype-model-Block-Content-Latex) | | | -| tableOfContents | [Block.Content.TableOfContents](#anytype-model-Block-Content-TableOfContents) | | | -| table | [Block.Content.Table](#anytype-model-Block-Content-Table) | | | -| tableColumn | [Block.Content.TableColumn](#anytype-model-Block-Content-TableColumn) | | | -| tableRow | [Block.Content.TableRow](#anytype-model-Block-Content-TableRow) | | | -| widget | [Block.Content.Widget](#anytype-model-Block-Content-Widget) | | | +| align | [Block.Align](#anytype.model.Block.Align) | | | +| verticalAlign | [Block.VerticalAlign](#anytype.model.Block.VerticalAlign) | | | +| smartblock | [Block.Content.Smartblock](#anytype.model.Block.Content.Smartblock) | | | +| text | [Block.Content.Text](#anytype.model.Block.Content.Text) | | | +| file | [Block.Content.File](#anytype.model.Block.Content.File) | | | +| layout | [Block.Content.Layout](#anytype.model.Block.Content.Layout) | | | +| div | [Block.Content.Div](#anytype.model.Block.Content.Div) | | | +| bookmark | [Block.Content.Bookmark](#anytype.model.Block.Content.Bookmark) | | | +| icon | [Block.Content.Icon](#anytype.model.Block.Content.Icon) | | | +| link | [Block.Content.Link](#anytype.model.Block.Content.Link) | | | +| dataview | [Block.Content.Dataview](#anytype.model.Block.Content.Dataview) | | | +| relation | [Block.Content.Relation](#anytype.model.Block.Content.Relation) | | | +| featuredRelations | [Block.Content.FeaturedRelations](#anytype.model.Block.Content.FeaturedRelations) | | | +| latex | [Block.Content.Latex](#anytype.model.Block.Content.Latex) | | | +| tableOfContents | [Block.Content.TableOfContents](#anytype.model.Block.Content.TableOfContents) | | | +| table | [Block.Content.Table](#anytype.model.Block.Content.Table) | | | +| tableColumn | [Block.Content.TableColumn](#anytype.model.Block.Content.TableColumn) | | | +| tableRow | [Block.Content.TableRow](#anytype.model.Block.Content.TableRow) | | | +| widget | [Block.Content.Widget](#anytype.model.Block.Content.Widget) | | | - + ### Block.Content @@ -18119,7 +18119,7 @@ Avatar of a user's account. It could be an image or color - + ### Block.Content.Bookmark Bookmark is to keep a web-link and to preview a content. @@ -18132,16 +18132,16 @@ Bookmark is to keep a web-link and to preview a content. | description | [string](#string) | | Deprecated. Get this data from the target object. | | imageHash | [string](#string) | | Deprecated. Get this data from the target object. | | faviconHash | [string](#string) | | Deprecated. Get this data from the target object. | -| type | [LinkPreview.Type](#anytype-model-LinkPreview-Type) | | | +| type | [LinkPreview.Type](#anytype.model.LinkPreview.Type) | | | | targetObjectId | [string](#string) | | | -| state | [Block.Content.Bookmark.State](#anytype-model-Block-Content-Bookmark-State) | | | +| state | [Block.Content.Bookmark.State](#anytype.model.Block.Content.Bookmark.State) | | | - + ### Block.Content.Dataview @@ -18150,19 +18150,19 @@ Bookmark is to keep a web-link and to preview a content. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | source | [string](#string) | repeated | | -| views | [Block.Content.Dataview.View](#anytype-model-Block-Content-Dataview-View) | repeated | | -| relations | [Relation](#anytype-model-Relation) | repeated | deprecated | +| views | [Block.Content.Dataview.View](#anytype.model.Block.Content.Dataview.View) | repeated | | +| relations | [Relation](#anytype.model.Relation) | repeated | deprecated | | activeView | [string](#string) | | saved within a session | -| groupOrders | [Block.Content.Dataview.GroupOrder](#anytype-model-Block-Content-Dataview-GroupOrder) | repeated | | -| objectOrders | [Block.Content.Dataview.ObjectOrder](#anytype-model-Block-Content-Dataview-ObjectOrder) | repeated | | -| relationLinks | [RelationLink](#anytype-model-RelationLink) | repeated | | +| groupOrders | [Block.Content.Dataview.GroupOrder](#anytype.model.Block.Content.Dataview.GroupOrder) | repeated | | +| objectOrders | [Block.Content.Dataview.ObjectOrder](#anytype.model.Block.Content.Dataview.ObjectOrder) | repeated | | +| relationLinks | [RelationLink](#anytype.model.RelationLink) | repeated | | - + ### Block.Content.Dataview.Checkbox @@ -18177,7 +18177,7 @@ Bookmark is to keep a web-link and to preview a content. - + ### Block.Content.Dataview.Date @@ -18187,7 +18187,7 @@ Bookmark is to keep a web-link and to preview a content. - + ### Block.Content.Dataview.Filter @@ -18195,13 +18195,13 @@ Bookmark is to keep a web-link and to preview a content. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| operator | [Block.Content.Dataview.Filter.Operator](#anytype-model-Block-Content-Dataview-Filter-Operator) | | looks not applicable? | +| operator | [Block.Content.Dataview.Filter.Operator](#anytype.model.Block.Content.Dataview.Filter.Operator) | | looks not applicable? | | RelationKey | [string](#string) | | | | relationProperty | [string](#string) | | | -| condition | [Block.Content.Dataview.Filter.Condition](#anytype-model-Block-Content-Dataview-Filter-Condition) | | | -| value | [google.protobuf.Value](#google-protobuf-Value) | | | -| quickOption | [Block.Content.Dataview.Filter.QuickOption](#anytype-model-Block-Content-Dataview-Filter-QuickOption) | | | -| format | [RelationFormat](#anytype-model-RelationFormat) | | | +| condition | [Block.Content.Dataview.Filter.Condition](#anytype.model.Block.Content.Dataview.Filter.Condition) | | | +| value | [google.protobuf.Value](#google.protobuf.Value) | | | +| quickOption | [Block.Content.Dataview.Filter.QuickOption](#anytype.model.Block.Content.Dataview.Filter.QuickOption) | | | +| format | [RelationFormat](#anytype.model.RelationFormat) | | | | includeTime | [bool](#bool) | | | @@ -18209,7 +18209,7 @@ Bookmark is to keep a web-link and to preview a content. - + ### Block.Content.Dataview.Group @@ -18218,17 +18218,17 @@ Bookmark is to keep a web-link and to preview a content. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| status | [Block.Content.Dataview.Status](#anytype-model-Block-Content-Dataview-Status) | | | -| tag | [Block.Content.Dataview.Tag](#anytype-model-Block-Content-Dataview-Tag) | | | -| checkbox | [Block.Content.Dataview.Checkbox](#anytype-model-Block-Content-Dataview-Checkbox) | | | -| date | [Block.Content.Dataview.Date](#anytype-model-Block-Content-Dataview-Date) | | | +| status | [Block.Content.Dataview.Status](#anytype.model.Block.Content.Dataview.Status) | | | +| tag | [Block.Content.Dataview.Tag](#anytype.model.Block.Content.Dataview.Tag) | | | +| checkbox | [Block.Content.Dataview.Checkbox](#anytype.model.Block.Content.Dataview.Checkbox) | | | +| date | [Block.Content.Dataview.Date](#anytype.model.Block.Content.Dataview.Date) | | | - + ### Block.Content.Dataview.GroupOrder @@ -18237,14 +18237,14 @@ Bookmark is to keep a web-link and to preview a content. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | viewId | [string](#string) | | | -| viewGroups | [Block.Content.Dataview.ViewGroup](#anytype-model-Block-Content-Dataview-ViewGroup) | repeated | | +| viewGroups | [Block.Content.Dataview.ViewGroup](#anytype.model.Block.Content.Dataview.ViewGroup) | repeated | | - + ### Block.Content.Dataview.ObjectOrder @@ -18261,7 +18261,7 @@ Bookmark is to keep a web-link and to preview a content. - + ### Block.Content.Dataview.Relation @@ -18273,15 +18273,15 @@ Bookmark is to keep a web-link and to preview a content. | isVisible | [bool](#bool) | | | | width | [int32](#int32) | | the displayed column % calculated based on other visible relations | | dateIncludeTime | [bool](#bool) | | | -| timeFormat | [Block.Content.Dataview.Relation.TimeFormat](#anytype-model-Block-Content-Dataview-Relation-TimeFormat) | | | -| dateFormat | [Block.Content.Dataview.Relation.DateFormat](#anytype-model-Block-Content-Dataview-Relation-DateFormat) | | | +| timeFormat | [Block.Content.Dataview.Relation.TimeFormat](#anytype.model.Block.Content.Dataview.Relation.TimeFormat) | | | +| dateFormat | [Block.Content.Dataview.Relation.DateFormat](#anytype.model.Block.Content.Dataview.Relation.DateFormat) | | | - + ### Block.Content.Dataview.Sort @@ -18290,15 +18290,15 @@ Bookmark is to keep a web-link and to preview a content. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | RelationKey | [string](#string) | | | -| type | [Block.Content.Dataview.Sort.Type](#anytype-model-Block-Content-Dataview-Sort-Type) | | | -| customOrder | [google.protobuf.Value](#google-protobuf-Value) | repeated | | +| type | [Block.Content.Dataview.Sort.Type](#anytype.model.Block.Content.Dataview.Sort.Type) | | | +| customOrder | [google.protobuf.Value](#google.protobuf.Value) | repeated | | - + ### Block.Content.Dataview.Status @@ -18313,7 +18313,7 @@ Bookmark is to keep a web-link and to preview a content. - + ### Block.Content.Dataview.Tag @@ -18328,7 +18328,7 @@ Bookmark is to keep a web-link and to preview a content. - + ### Block.Content.Dataview.View @@ -18337,14 +18337,14 @@ Bookmark is to keep a web-link and to preview a content. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| type | [Block.Content.Dataview.View.Type](#anytype-model-Block-Content-Dataview-View-Type) | | | +| type | [Block.Content.Dataview.View.Type](#anytype.model.Block.Content.Dataview.View.Type) | | | | name | [string](#string) | | | -| sorts | [Block.Content.Dataview.Sort](#anytype-model-Block-Content-Dataview-Sort) | repeated | | -| filters | [Block.Content.Dataview.Filter](#anytype-model-Block-Content-Dataview-Filter) | repeated | | -| relations | [Block.Content.Dataview.Relation](#anytype-model-Block-Content-Dataview-Relation) | repeated | relations fields/columns options, also used to provide the order | +| sorts | [Block.Content.Dataview.Sort](#anytype.model.Block.Content.Dataview.Sort) | repeated | | +| filters | [Block.Content.Dataview.Filter](#anytype.model.Block.Content.Dataview.Filter) | repeated | | +| relations | [Block.Content.Dataview.Relation](#anytype.model.Block.Content.Dataview.Relation) | repeated | relations fields/columns options, also used to provide the order | | coverRelationKey | [string](#string) | | Relation used for cover in gallery | | hideIcon | [bool](#bool) | | Hide icon near name | -| cardSize | [Block.Content.Dataview.View.Size](#anytype-model-Block-Content-Dataview-View-Size) | | Gallery card size | +| cardSize | [Block.Content.Dataview.View.Size](#anytype.model.Block.Content.Dataview.View.Size) | | Gallery card size | | coverFit | [bool](#bool) | | Image fits container | | groupRelationKey | [string](#string) | | Group view by this relationKey | | groupBackgroundColors | [bool](#bool) | | Enable backgrounds in groups | @@ -18354,7 +18354,7 @@ Bookmark is to keep a web-link and to preview a content. - + ### Block.Content.Dataview.ViewGroup @@ -18372,7 +18372,7 @@ Bookmark is to keep a web-link and to preview a content. - + ### Block.Content.Div Divider: block, that contains only one horizontal thin line @@ -18380,14 +18380,14 @@ Divider: block, that contains only one horizontal thin line | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| style | [Block.Content.Div.Style](#anytype-model-Block-Content-Div-Style) | | | +| style | [Block.Content.Div.Style](#anytype.model.Block.Content.Div.Style) | | | - + ### Block.Content.FeaturedRelations @@ -18397,7 +18397,7 @@ Divider: block, that contains only one horizontal thin line - + ### Block.Content.File @@ -18407,19 +18407,19 @@ Divider: block, that contains only one horizontal thin line | ----- | ---- | ----- | ----------- | | hash | [string](#string) | | | | name | [string](#string) | | | -| type | [Block.Content.File.Type](#anytype-model-Block-Content-File-Type) | | | +| type | [Block.Content.File.Type](#anytype.model.Block.Content.File.Type) | | | | mime | [string](#string) | | | | size | [int64](#int64) | | | | addedAt | [int64](#int64) | | | -| state | [Block.Content.File.State](#anytype-model-Block-Content-File-State) | | | -| style | [Block.Content.File.Style](#anytype-model-Block-Content-File-Style) | | | +| state | [Block.Content.File.State](#anytype.model.Block.Content.File.State) | | | +| style | [Block.Content.File.Style](#anytype.model.Block.Content.File.Style) | | | - + ### Block.Content.Icon @@ -18434,7 +18434,7 @@ Divider: block, that contains only one horizontal thin line - + ### Block.Content.Latex @@ -18449,7 +18449,7 @@ Divider: block, that contains only one horizontal thin line - + ### Block.Content.Layout Layout have no visual representation, but affects on blocks, that it contains. @@ -18458,14 +18458,14 @@ Row/Column layout blocks creates only automatically, after some of a D&D ope | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| style | [Block.Content.Layout.Style](#anytype-model-Block-Content-Layout-Style) | | | +| style | [Block.Content.Layout.Style](#anytype.model.Block.Content.Layout.Style) | | | - + ### Block.Content.Link Link: block to link some content from an external sources. @@ -18474,11 +18474,11 @@ Link: block to link some content from an external sources. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | targetBlockId | [string](#string) | | id of the target block | -| style | [Block.Content.Link.Style](#anytype-model-Block-Content-Link-Style) | | deprecated | -| fields | [google.protobuf.Struct](#google-protobuf-Struct) | | | -| iconSize | [Block.Content.Link.IconSize](#anytype-model-Block-Content-Link-IconSize) | | | -| cardStyle | [Block.Content.Link.CardStyle](#anytype-model-Block-Content-Link-CardStyle) | | | -| description | [Block.Content.Link.Description](#anytype-model-Block-Content-Link-Description) | | | +| style | [Block.Content.Link.Style](#anytype.model.Block.Content.Link.Style) | | deprecated | +| fields | [google.protobuf.Struct](#google.protobuf.Struct) | | | +| iconSize | [Block.Content.Link.IconSize](#anytype.model.Block.Content.Link.IconSize) | | | +| cardStyle | [Block.Content.Link.CardStyle](#anytype.model.Block.Content.Link.CardStyle) | | | +| description | [Block.Content.Link.Description](#anytype.model.Block.Content.Link.Description) | | | | relations | [string](#string) | repeated | | @@ -18486,7 +18486,7 @@ Link: block to link some content from an external sources. - + ### Block.Content.Relation @@ -18501,7 +18501,7 @@ Link: block to link some content from an external sources. - + ### Block.Content.Smartblock @@ -18511,7 +18511,7 @@ Link: block to link some content from an external sources. - + ### Block.Content.Table @@ -18521,7 +18521,7 @@ Link: block to link some content from an external sources. - + ### Block.Content.TableColumn @@ -18531,7 +18531,7 @@ Link: block to link some content from an external sources. - + ### Block.Content.TableOfContents @@ -18541,7 +18541,7 @@ Link: block to link some content from an external sources. - + ### Block.Content.TableRow @@ -18556,7 +18556,7 @@ Link: block to link some content from an external sources. - + ### Block.Content.Text @@ -18565,8 +18565,8 @@ Link: block to link some content from an external sources. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | text | [string](#string) | | | -| style | [Block.Content.Text.Style](#anytype-model-Block-Content-Text-Style) | | | -| marks | [Block.Content.Text.Marks](#anytype-model-Block-Content-Text-Marks) | | list of marks to apply to the text | +| style | [Block.Content.Text.Style](#anytype.model.Block.Content.Text.Style) | | | +| marks | [Block.Content.Text.Marks](#anytype.model.Block.Content.Text.Marks) | | list of marks to apply to the text | | checked | [bool](#bool) | | | | color | [string](#string) | | | | iconEmoji | [string](#string) | | used with style Callout | @@ -18577,7 +18577,7 @@ Link: block to link some content from an external sources. - + ### Block.Content.Text.Mark @@ -18585,8 +18585,8 @@ Link: block to link some content from an external sources. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| range | [Range](#anytype-model-Range) | | range of symbols to apply this mark. From(symbol) To(symbol) | -| type | [Block.Content.Text.Mark.Type](#anytype-model-Block-Content-Text-Mark-Type) | | | +| range | [Range](#anytype.model.Range) | | range of symbols to apply this mark. From(symbol) To(symbol) | +| type | [Block.Content.Text.Mark.Type](#anytype.model.Block.Content.Text.Mark.Type) | | | | param | [string](#string) | | link, color, etc | @@ -18594,7 +18594,7 @@ Link: block to link some content from an external sources. - + ### Block.Content.Text.Marks @@ -18602,14 +18602,14 @@ Link: block to link some content from an external sources. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| marks | [Block.Content.Text.Mark](#anytype-model-Block-Content-Text-Mark) | repeated | | +| marks | [Block.Content.Text.Mark](#anytype.model.Block.Content.Text.Mark) | repeated | | - + ### Block.Content.Widget @@ -18617,14 +18617,14 @@ Link: block to link some content from an external sources. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| layout | [Block.Content.Widget.Layout](#anytype-model-Block-Content-Widget-Layout) | | | +| layout | [Block.Content.Widget.Layout](#anytype.model.Block.Content.Widget.Layout) | | | - + ### Block.Restrictions @@ -18643,7 +18643,7 @@ Link: block to link some content from an external sources. - + ### BlockMetaOnly Used to decode block meta only, without the content itself @@ -18652,14 +18652,14 @@ Used to decode block meta only, without the content itself | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | -| fields | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| fields | [google.protobuf.Struct](#google.protobuf.Struct) | | | - + ### InternalFlag @@ -18667,14 +18667,14 @@ Used to decode block meta only, without the content itself | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| value | [InternalFlag.Value](#anytype-model-InternalFlag-Value) | | | +| value | [InternalFlag.Value](#anytype.model.InternalFlag.Value) | | | - + ### Layout @@ -18682,16 +18682,16 @@ Used to decode block meta only, without the content itself | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| id | [ObjectType.Layout](#anytype-model-ObjectType-Layout) | | | +| id | [ObjectType.Layout](#anytype.model.ObjectType.Layout) | | | | name | [string](#string) | | | -| requiredRelations | [Relation](#anytype-model-Relation) | repeated | relations required for this object type | +| requiredRelations | [Relation](#anytype.model.Relation) | repeated | relations required for this object type | - + ### LinkPreview @@ -18704,14 +18704,14 @@ Used to decode block meta only, without the content itself | description | [string](#string) | | | | imageUrl | [string](#string) | | | | faviconUrl | [string](#string) | | | -| type | [LinkPreview.Type](#anytype-model-LinkPreview-Type) | | | +| type | [LinkPreview.Type](#anytype.model.LinkPreview.Type) | | | - + ### ObjectType @@ -18721,13 +18721,13 @@ Used to decode block meta only, without the content itself | ----- | ---- | ----- | ----------- | | url | [string](#string) | | leave empty in case you want to create the new one | | name | [string](#string) | | name of objectType (can be localized for bundled types) | -| relationLinks | [RelationLink](#anytype-model-RelationLink) | repeated | cannot contain more than one Relation with the same RelationType | -| layout | [ObjectType.Layout](#anytype-model-ObjectType-Layout) | | | +| relationLinks | [RelationLink](#anytype.model.RelationLink) | repeated | cannot contain more than one Relation with the same RelationType | +| layout | [ObjectType.Layout](#anytype.model.ObjectType.Layout) | | | | iconEmoji | [string](#string) | | emoji symbol | | description | [string](#string) | | | | hidden | [bool](#bool) | | | | readonly | [bool](#bool) | | | -| types | [SmartBlockType](#anytype-model-SmartBlockType) | repeated | | +| types | [SmartBlockType](#anytype.model.SmartBlockType) | repeated | | | isArchived | [bool](#bool) | | sets locally to hide object type from set and some other places | | installedByDefault | [bool](#bool) | | | @@ -18736,7 +18736,7 @@ Used to decode block meta only, without the content itself - + ### ObjectView Works with a smart blocks: Page, Dashboard @@ -18746,20 +18746,20 @@ Dashboard opened, click on a page, Rpc.Block.open, Block.ShowFullscreen(PageBloc | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | rootId | [string](#string) | | Root block id | -| blocks | [Block](#anytype-model-Block) | repeated | dependent simple blocks (descendants) | -| details | [ObjectView.DetailsSet](#anytype-model-ObjectView-DetailsSet) | repeated | details for the current and dependent objects | -| type | [SmartBlockType](#anytype-model-SmartBlockType) | | | -| relations | [Relation](#anytype-model-Relation) | repeated | DEPRECATED, use relationLinks instead | -| relationLinks | [RelationLink](#anytype-model-RelationLink) | repeated | | -| restrictions | [Restrictions](#anytype-model-Restrictions) | | object restrictions | -| history | [ObjectView.HistorySize](#anytype-model-ObjectView-HistorySize) | | | +| blocks | [Block](#anytype.model.Block) | repeated | dependent simple blocks (descendants) | +| details | [ObjectView.DetailsSet](#anytype.model.ObjectView.DetailsSet) | repeated | details for the current and dependent objects | +| type | [SmartBlockType](#anytype.model.SmartBlockType) | | | +| relations | [Relation](#anytype.model.Relation) | repeated | DEPRECATED, use relationLinks instead | +| relationLinks | [RelationLink](#anytype.model.RelationLink) | repeated | | +| restrictions | [Restrictions](#anytype.model.Restrictions) | | object restrictions | +| history | [ObjectView.HistorySize](#anytype.model.ObjectView.HistorySize) | | | - + ### ObjectView.DetailsSet @@ -18768,7 +18768,7 @@ Dashboard opened, click on a page, Rpc.Block.open, Block.ShowFullscreen(PageBloc | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | id | [string](#string) | | context objectId | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | can not be a partial state. Should replace client details state | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | can not be a partial state. Should replace client details state | | subIds | [string](#string) | repeated | | @@ -18776,7 +18776,7 @@ Dashboard opened, click on a page, Rpc.Block.open, Block.ShowFullscreen(PageBloc - + ### ObjectView.HistorySize @@ -18792,7 +18792,7 @@ Dashboard opened, click on a page, Rpc.Block.open, Block.ShowFullscreen(PageBloc - + ### ObjectView.RelationWithValuePerObject @@ -18801,14 +18801,14 @@ Dashboard opened, click on a page, Rpc.Block.open, Block.ShowFullscreen(PageBloc | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | objectId | [string](#string) | | | -| relations | [RelationWithValue](#anytype-model-RelationWithValue) | repeated | | +| relations | [RelationWithValue](#anytype.model.RelationWithValue) | repeated | | - + ### Range General purpose structure, uses in Mark. @@ -18824,7 +18824,7 @@ General purpose structure, uses in Mark. - + ### Relation Relation describe the human-interpreted relation type. It may be something like "Date of creation, format=date" or "Assignee, format=objectId, objectType=person" @@ -18834,21 +18834,21 @@ Relation describe the human-interpreted relation type. It may be something like | ----- | ---- | ----- | ----------- | | id | [string](#string) | | | | key | [string](#string) | | Key under which the value is stored in the map. Must be unique for the object type. It usually auto-generated bsonid, but also may be something human-readable in case of prebuilt types. | -| format | [RelationFormat](#anytype-model-RelationFormat) | | format of the underlying data | +| format | [RelationFormat](#anytype.model.RelationFormat) | | format of the underlying data | | name | [string](#string) | | name to show (can be localized for bundled types) | -| defaultValue | [google.protobuf.Value](#google-protobuf-Value) | | | -| dataSource | [Relation.DataSource](#anytype-model-Relation-DataSource) | | where the data is stored | +| defaultValue | [google.protobuf.Value](#google.protobuf.Value) | | | +| dataSource | [Relation.DataSource](#anytype.model.Relation.DataSource) | | where the data is stored | | hidden | [bool](#bool) | | internal, not displayed to user (e.g. coverX, coverY) | | readOnly | [bool](#bool) | | value not editable by user tobe renamed to readonlyValue | | readOnlyRelation | [bool](#bool) | | relation metadata, eg name and format is not editable by user | | multi | [bool](#bool) | | allow multiple values (stored in pb list) | | objectTypes | [string](#string) | repeated | URL of object type, empty to allow link to any object | -| selectDict | [Relation.Option](#anytype-model-Relation-Option) | repeated | index 10, 11 was used in internal-only builds. Can be reused, but may break some test accounts +| selectDict | [Relation.Option](#anytype.model.Relation.Option) | repeated | index 10, 11 was used in internal-only builds. Can be reused, but may break some test accounts default dictionary with unique values to choose for select/multiSelect format | | maxCount | [int32](#int32) | | max number of values can be set for this relation. 0 means no limit. 1 means the value can be stored in non-repeated field | | description | [string](#string) | | | -| scope | [Relation.Scope](#anytype-model-Relation-Scope) | | on-store fields, injected only locally +| scope | [Relation.Scope](#anytype.model.Relation.Scope) | | on-store fields, injected only locally scope from which this relation have been aggregated | | creator | [string](#string) | | creator profile id | @@ -18858,7 +18858,7 @@ scope from which this relation have been aggregated | - + ### Relation.Option @@ -18878,7 +18878,7 @@ stored | - + ### RelationLink @@ -18887,14 +18887,14 @@ stored | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | key | [string](#string) | | | -| format | [RelationFormat](#anytype-model-RelationFormat) | | | +| format | [RelationFormat](#anytype.model.RelationFormat) | | | - + ### RelationOptions @@ -18902,14 +18902,14 @@ stored | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| options | [Relation.Option](#anytype-model-Relation-Option) | repeated | | +| options | [Relation.Option](#anytype.model.Relation.Option) | repeated | | - + ### RelationWithValue @@ -18917,15 +18917,15 @@ stored | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| relation | [Relation](#anytype-model-Relation) | | | -| value | [google.protobuf.Value](#google-protobuf-Value) | | | +| relation | [Relation](#anytype.model.Relation) | | | +| value | [google.protobuf.Value](#google.protobuf.Value) | | | - + ### Relations @@ -18933,14 +18933,14 @@ stored | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| relations | [Relation](#anytype-model-Relation) | repeated | | +| relations | [Relation](#anytype.model.Relation) | repeated | | - + ### Restrictions @@ -18948,15 +18948,15 @@ stored | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| object | [Restrictions.ObjectRestriction](#anytype-model-Restrictions-ObjectRestriction) | repeated | | -| dataview | [Restrictions.DataviewRestrictions](#anytype-model-Restrictions-DataviewRestrictions) | repeated | | +| object | [Restrictions.ObjectRestriction](#anytype.model.Restrictions.ObjectRestriction) | repeated | | +| dataview | [Restrictions.DataviewRestrictions](#anytype.model.Restrictions.DataviewRestrictions) | repeated | | - + ### Restrictions.DataviewRestrictions @@ -18965,14 +18965,14 @@ stored | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | blockId | [string](#string) | | | -| restrictions | [Restrictions.DataviewRestriction](#anytype-model-Restrictions-DataviewRestriction) | repeated | | +| restrictions | [Restrictions.DataviewRestriction](#anytype.model.Restrictions.DataviewRestriction) | repeated | | - + ### SmartBlockSnapshotBase @@ -18980,21 +18980,21 @@ stored | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| blocks | [Block](#anytype-model-Block) | repeated | | -| details | [google.protobuf.Struct](#google-protobuf-Struct) | | | -| fileKeys | [google.protobuf.Struct](#google-protobuf-Struct) | | | -| extraRelations | [Relation](#anytype-model-Relation) | repeated | deprecated | +| blocks | [Block](#anytype.model.Block) | repeated | | +| details | [google.protobuf.Struct](#google.protobuf.Struct) | | | +| fileKeys | [google.protobuf.Struct](#google.protobuf.Struct) | | | +| extraRelations | [Relation](#anytype.model.Relation) | repeated | deprecated | | objectTypes | [string](#string) | repeated | | -| collections | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| collections | [google.protobuf.Struct](#google.protobuf.Struct) | | | | removedCollectionKeys | [string](#string) | repeated | | -| relationLinks | [RelationLink](#anytype-model-RelationLink) | repeated | | +| relationLinks | [RelationLink](#anytype.model.RelationLink) | repeated | | - + ### ThreadCreateQueueEntry @@ -19010,7 +19010,7 @@ stored | - + ### ThreadDeeplinkPayload @@ -19028,7 +19028,7 @@ stored | - + ### Account.StatusType @@ -19042,7 +19042,7 @@ stored | - + ### Block.Align @@ -19055,7 +19055,7 @@ stored | - + ### Block.Content.Bookmark.State @@ -19069,7 +19069,7 @@ stored | - + ### Block.Content.Dataview.Filter.Condition @@ -19085,8 +19085,8 @@ stored | | LessOrEqual | 6 | | | Like | 7 | | | NotLike | 8 | | -| In | 9 | | -| NotIn | 10 | | +| In | 9 | "at least one value(from the provided list) is IN" | +| NotIn | 10 | "none of provided values are IN" | | Empty | 11 | | | NotEmpty | 12 | | | AllIn | 13 | | @@ -19096,7 +19096,7 @@ stored | - + ### Block.Content.Dataview.Filter.Operator @@ -19108,7 +19108,7 @@ stored | - + ### Block.Content.Dataview.Filter.QuickOption @@ -19130,7 +19130,7 @@ stored | - + ### Block.Content.Dataview.Relation.DateFormat @@ -19145,7 +19145,7 @@ stored | - + ### Block.Content.Dataview.Relation.TimeFormat @@ -19157,7 +19157,7 @@ stored | - + ### Block.Content.Dataview.Sort.Type @@ -19170,7 +19170,7 @@ stored | - + ### Block.Content.Dataview.View.Size @@ -19183,7 +19183,7 @@ stored | - + ### Block.Content.Dataview.View.Type @@ -19197,7 +19197,7 @@ stored | - + ### Block.Content.Div.Style @@ -19209,7 +19209,7 @@ stored | - + ### Block.Content.File.State @@ -19223,7 +19223,7 @@ stored | - + ### Block.Content.File.Style @@ -19236,7 +19236,7 @@ stored | - + ### Block.Content.File.Type @@ -19252,7 +19252,7 @@ stored | - + ### Block.Content.Layout.Style @@ -19268,7 +19268,7 @@ stored | - + ### Block.Content.Link.CardStyle @@ -19281,7 +19281,7 @@ stored | - + ### Block.Content.Link.Description @@ -19294,7 +19294,7 @@ stored | - + ### Block.Content.Link.IconSize @@ -19307,7 +19307,7 @@ stored | - + ### Block.Content.Link.Style @@ -19321,7 +19321,7 @@ stored | - + ### Block.Content.Text.Mark.Type @@ -19342,7 +19342,7 @@ stored | - + ### Block.Content.Text.Style @@ -19366,7 +19366,7 @@ stored | - + ### Block.Content.Widget.Layout @@ -19378,7 +19378,7 @@ stored | - + ### Block.Position @@ -19396,7 +19396,7 @@ stored | - + ### Block.VerticalAlign @@ -19409,7 +19409,7 @@ stored | - + ### InternalFlag.Value Use such a weird construction due to the issue with imported repeated enum type @@ -19423,7 +19423,7 @@ Look https://github.com/golang/protobuf/issues/1135 for more information. - + ### LinkPreview.Type @@ -19437,7 +19437,7 @@ Look https://github.com/golang/protobuf/issues/1135 for more information. - + ### ObjectType.Layout @@ -19462,7 +19462,7 @@ Look https://github.com/golang/protobuf/issues/1135 for more information. - + ### Relation.DataSource @@ -19476,7 +19476,7 @@ Look https://github.com/golang/protobuf/issues/1135 for more information. - + ### Relation.Scope @@ -19491,7 +19491,7 @@ Look https://github.com/golang/protobuf/issues/1135 for more information. - + ### RelationFormat RelationFormat describes how the underlying data is stored in the google.protobuf.Value and how it should be validated/sanitized @@ -19515,7 +19515,7 @@ RelationFormat describes how the underlying data is stored in the google.protobu - + ### Restrictions.DataviewRestriction @@ -19529,7 +19529,7 @@ RelationFormat describes how the underlying data is stored in the google.protobu - + ### Restrictions.ObjectRestriction @@ -19548,7 +19548,7 @@ RelationFormat describes how the underlying data is stored in the google.protobu - + ### SmartBlockType diff --git a/pkg/lib/pb/model/protos/models.proto b/pkg/lib/pb/model/protos/models.proto index a9b17d054..90b6e8576 100644 --- a/pkg/lib/pb/model/protos/models.proto +++ b/pkg/lib/pb/model/protos/models.proto @@ -406,8 +406,8 @@ message Block { LessOrEqual = 6; Like = 7; NotLike = 8; - In = 9; - NotIn = 10; + In = 9; // "at least one value(from the provided list) is IN" + NotIn = 10; // "none of provided values are IN" Empty = 11; NotEmpty = 12; AllIn = 13; From 3487455addfe4bb25f0befefb845ff5b1a7eee85 Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Tue, 10 Jan 2023 15:57:54 +0800 Subject: [PATCH 65/68] GO-512: fix comments Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/objectcreator.go | 10 ++- core/block/import/objectupdater.go | 94 +++++++++++++--------------- core/block/import/relationcreator.go | 83 ++++++++++++------------ core/block/import/types.go | 7 +-- 4 files changed, 89 insertions(+), 105 deletions(-) diff --git a/core/block/import/objectcreator.go b/core/block/import/objectcreator.go index 33e26a355..121db39fd 100644 --- a/core/block/import/objectcreator.go +++ b/core/block/import/objectcreator.go @@ -72,10 +72,8 @@ func (oc *ObjectCreator) Create(ctx *session.Context, if details, filesToDelete, err = oc.updater.Update(ctx, snapshot, relations, pageID); err == nil { return details, nil } - if err != nil { - for _, hash := range filesToDelete { - oc.deleteFile(hash) - } + for _, hash := range filesToDelete { + oc.deleteFile(hash) } log.Warn("failed to update existing object: %s", err) } @@ -121,7 +119,7 @@ func (oc *ObjectCreator) Create(ctx *session.Context, } var oldRelationBlocksToNew map[string]*model.Block - filesToDelete, oldRelationBlocksToNew, err = oc.relationCreator.CreateRelations(ctx, snapshot, pageID, relations, nil) + filesToDelete, oldRelationBlocksToNew, err = oc.relationCreator.CreateRelations(ctx, snapshot, pageID, relations) if err != nil { return nil, fmt.Errorf("relation create '%s'", err) } @@ -134,7 +132,7 @@ func (oc *ObjectCreator) Create(ctx *session.Context, } } - oc.relationCreator.ReplaceRelationBlock(ctx, st, oldRelationBlocksToNew, pageID) + oc.relationCreator.ReplaceRelationBlock(ctx, oldRelationBlocksToNew, pageID) st.Iterate(func(bl simple.Block) (isContinue bool) { s := oc.syncFactory.GetSyncer(bl) diff --git a/core/block/import/objectupdater.go b/core/block/import/objectupdater.go index e225f2e50..2fab4b6a3 100644 --- a/core/block/import/objectupdater.go +++ b/core/block/import/objectupdater.go @@ -2,6 +2,7 @@ package importer import ( "fmt" + "go.uber.org/zap" "github.com/gogo/protobuf/types" @@ -56,7 +57,7 @@ func (ou *ObjectUpdater) Update(ctx *session.Context, }) if err == nil { if len(records) > 0 { - filesToDelete, err := ou.update(ctx, snapshot, records, relations, pageID) + filesToDelete, err := ou.update(ctx, snapshot, records[0], relations, pageID) return records[0].Details, filesToDelete, err } } @@ -75,7 +76,7 @@ func (ou *ObjectUpdater) Update(ctx *session.Context, }) if err == nil { if len(records) > 0 { - filesToDelete, err := ou.update(ctx, snapshot, records, relations, pageID) + filesToDelete, err := ou.update(ctx, snapshot, records[0], relations, pageID) return records[0].Details, filesToDelete, err } } @@ -85,67 +86,60 @@ func (ou *ObjectUpdater) Update(ctx *session.Context, func (ou *ObjectUpdater) update(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, - records []database.Record, + details database.Record, relations []*converter.Relation, pageID string) ([]string, error) { - details := records[0] simpleBlocks := make([]simple.Block, 0) var ( filesToDelete = make([]string, 0) oldRelationBlockToNew = make(map[string]*model.Block, 0) ) id := details.Details.Fields[bundle.RelationKeyId.String()].GetStringValue() - if details.Details != nil { - allBlocksIds := make([]string, 0) - if err := ou.service.Do(id, func(b sb.SmartBlock) error { - s := b.NewStateCtx(ctx) - if err := b.Iterate(func(b simple.Block) (isContinue bool) { - if b.Model().GetLink() == nil && id != b.Model().Id { - allBlocksIds = append(allBlocksIds, b.Model().Id) - } - return true - }); err != nil { - return err + allBlocksIds := make([]string, 0) + if err := ou.service.Do(id, func(b sb.SmartBlock) error { + s := b.NewStateCtx(ctx) + if err := b.Iterate(func(b simple.Block) (isContinue bool) { + if b.Model().GetLink() == nil && id != b.Model().Id { + allBlocksIds = append(allBlocksIds, b.Model().Id) } - for _, v := range allBlocksIds { - s.Unlink(v) - } - for _, block := range snapshot.Blocks { - if block.GetLink() != nil { - // we don't add link to non-existing object,so checking existence of the object with TargetBlockId in Do - if err := ou.service.Do(block.GetLink().TargetBlockId, func(b sb.SmartBlock) error { - return nil - }); err != nil { - continue - } - } - if block.Id != pageID { - simpleBlocks = append(simpleBlocks, simple.New(block)) - } - } - if err := basic.NewBasic(b).PasteBlocks(s, "", model.Block_Bottom, simpleBlocks); err != nil { - return err - } - return b.Apply(s) + return true }); err != nil { - return nil, err + return err } - var err error - filesToDelete, oldRelationBlockToNew, err = ou.relationCreator.CreateRelations(ctx, snapshot, id, relations, nil) - if err != nil { - return nil, err + for _, v := range allBlocksIds { + s.Unlink(v) } - if err := ou.service.Do(id, func(b sb.SmartBlock) error { - s := b.NewStateCtx(ctx) - ou.relationCreator.ReplaceRelationBlock(ctx, s, oldRelationBlockToNew, id) - return nil - }); err != nil { - return nil, err + for _, block := range snapshot.Blocks { + if block.GetLink() != nil { + // we don't add link to non-existing object,so checking existence of the object with TargetBlockId in Do + if err := ou.service.Do(block.GetLink().TargetBlockId, func(b sb.SmartBlock) error { + return nil + }); err != nil { + continue + } + } + if block.Id != pageID { + simpleBlocks = append(simpleBlocks, simple.New(block)) + } } - for _, b := range simpleBlocks { - s := ou.syncFactory.GetSyncer(b) - if s != nil { - s.Sync(ctx, id, b) + if err := basic.NewBasic(b).PasteBlocks(s, "", model.Block_Bottom, simpleBlocks); err != nil { + return err + } + return b.Apply(s) + }); err != nil { + return nil, err + } + var err error + filesToDelete, oldRelationBlockToNew, err = ou.relationCreator.CreateRelations(ctx, snapshot, id, relations) + if err != nil { + return nil, err + } + ou.relationCreator.ReplaceRelationBlock(ctx, oldRelationBlockToNew, id) + for _, b := range simpleBlocks { + s := ou.syncFactory.GetSyncer(b) + if s != nil { + if err := s.Sync(ctx, id, b); err != nil { + log.With(zap.String("object id", pageID)).Errorf("failed to sync %s", err.Error()) } } } diff --git a/core/block/import/relationcreator.go b/core/block/import/relationcreator.go index d8e59fd93..dc6a2de84 100644 --- a/core/block/import/relationcreator.go +++ b/core/block/import/relationcreator.go @@ -9,7 +9,6 @@ import ( "github.com/anytypeio/go-anytype-middleware/core/block" editor "github.com/anytypeio/go-anytype-middleware/core/block/editor/smartblock" - "github.com/anytypeio/go-anytype-middleware/core/block/editor/state" "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/core/block/simple" "github.com/anytypeio/go-anytype-middleware/core/session" @@ -54,8 +53,7 @@ func NewRelationCreator(service *block.Service, func (rc *RelationService) CreateRelations(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, pageID string, - relations []*converter.Relation, - relationsLinks pbtypes.RelationLinks) ([]string, map[string]*model.Block, error) { + relations []*converter.Relation) ([]string, map[string]*model.Block, error) { notExistedRelations := make([]*converter.Relation, 0) existedRelations := make(map[string]*converter.Relation, 0) for _, r := range relations { @@ -86,38 +84,37 @@ func (rc *RelationService) CreateRelations(ctx *session.Context, }, Limit: 1, }) - if err == nil { - if len(records) > 0 { - id := records[0].Details.Fields[bundle.RelationKeyRelationKey.String()].GetStringValue() - existedRelations[id] = r - continue - } + if err == nil && len(records) > 0 { + id := pbtypes.GetString(records[0].Details, bundle.RelationKeyRelationKey.String()) + existedRelations[id] = r + continue } notExistedRelations = append(notExistedRelations, r) } - filesToDelete, oldRelationBlockToNew, failedRelations, err := rc.update(ctx, snapshot, existedRelations, pageID) + filesToDelete, oldRelationBlockToNewUpdate, failedRelations, err := rc.update(ctx, snapshot, existedRelations, pageID) if err != nil { return nil, nil, err } notExistedRelations = append(notExistedRelations, failedRelations...) - createfilesToDelete, relationsBlocks, err := rc.create(ctx, snapshot, notExistedRelations, pageID) + createfilesToDelete, oldRelationBlockToNewCreate, err := rc.create(ctx, snapshot, notExistedRelations, pageID) if err != nil { return nil, nil, err } filesToDelete = append(filesToDelete, createfilesToDelete...) - relationBlocks := make(map[string]*model.Block, len(relationsBlocks)+len(oldRelationBlockToNew)) - if len(oldRelationBlockToNew) == 0 { - for k, b := range oldRelationBlockToNew { - relationBlocks[k] = b + totalNumberOfRelationBlocks := len(oldRelationBlockToNewCreate) + len(oldRelationBlockToNewUpdate) + oldRelationBlockToNewTotal := make(map[string]*model.Block, totalNumberOfRelationBlocks) + if len(oldRelationBlockToNewUpdate) == 0 { + for k, b := range oldRelationBlockToNewUpdate { + oldRelationBlockToNewTotal[k] = b } } - if len(relationsBlocks) == 0 { - for k, b := range relationsBlocks { - relationBlocks[k] = b + if len(oldRelationBlockToNewCreate) == 0 { + for k, b := range oldRelationBlockToNewCreate { + oldRelationBlockToNewTotal[k] = b } } - return filesToDelete, relationBlocks, nil + return filesToDelete, oldRelationBlockToNewTotal, nil } // Create read relations link from snaphot and create according relations in anytype, @@ -276,35 +273,33 @@ func (rc *RelationService) update(ctx *session.Context, } func (rc *RelationService) ReplaceRelationBlock(ctx *session.Context, - st *state.State, oldRelationBlocksToNew map[string]*model.Block, pageID string) { - if err := st.Iterate(func(b simple.Block) (isContinue bool) { - if b.Model().GetRelation() == nil { - return true - } - bl, ok := oldRelationBlocksToNew[b.Model().GetId()] - if !ok { - return true - } - if sbErr := rc.service.Do(pageID, func(sb editor.SmartBlock) error { - s := sb.NewStateCtx(ctx) + if sbErr := rc.service.Do(pageID, func(sb editor.SmartBlock) error { + s := sb.NewStateCtx(ctx) + if err := s.Iterate(func(b simple.Block) (isContinue bool) { + if b.Model().GetRelation() == nil { + return true + } + bl, ok := oldRelationBlocksToNew[b.Model().GetId()] + if !ok { + return true + } simpleBlock := simple.New(bl) s.Add(simpleBlock) if err := s.InsertTo(b.Model().GetId(), model.Block_Replace, simpleBlock.Model().GetId()); err != nil { - return err + log.With(zap.String("object id", pageID)).Errorf("failed to insert: %w", err) } if err := sb.Apply(s); err != nil { - return err + log.With(zap.String("object id", pageID)).Errorf("failed to apply state: %w", err) } - return nil - }); sbErr != nil { - log.With(zap.String("object id", pageID)).Errorf("failed to replace relation block: %w", sbErr) + return true + }); err != nil { + return err } - - return true - }); err != nil { - log.With(zap.String("object id", pageID)).Errorf("failed to replace relation block: %w", err) + return nil + }); sbErr != nil { + log.With(zap.String("object id", pageID)).Errorf("failed to replace relation block: %w", sbErr) } } @@ -330,7 +325,7 @@ func (rc *RelationService) handleListValue(ctx *session.Context, r *converter.Relation, relationID string) { var ( - optionsIds = make([]string, 0) + optionIDs = make([]string, 0) id string err error existedOptions = make(map[string]string, 0) @@ -343,8 +338,8 @@ func (rc *RelationService) handleListValue(ctx *session.Context, existedOptions[ro.Text] = ro.Id } for _, tag := range r.SelectDict { - if optionID, ok := existedOptions[tag]; ok { - optionsIds = append(optionsIds, optionID) + if optionID, ok := existedOptions[tag.Text]; ok { + optionIDs = append(optionIDs, optionID) continue } if id, _, err = rc.objCreator.CreateSubObjectInWorkspace(&types.Struct{ @@ -358,9 +353,9 @@ func (rc *RelationService) handleListValue(ctx *session.Context, }, rc.core.PredefinedBlocks().Account); err != nil { log.Errorf("add extra relation %s", err) } - optionsIds = append(optionsIds, id) + optionIDs = append(optionIDs, id) } - snapshot.Details.Fields[r.Name] = pbtypes.StringList(optionsIds) + snapshot.Details.Fields[r.Name] = pbtypes.StringList(optionIDs) } func (rc *RelationService) handleFileRelation(ctx *session.Context, diff --git a/core/block/import/types.go b/core/block/import/types.go index 010729c78..5eb1a1f14 100644 --- a/core/block/import/types.go +++ b/core/block/import/types.go @@ -4,14 +4,11 @@ import ( "github.com/gogo/protobuf/types" "github.com/anytypeio/go-anytype-middleware/app" - "github.com/anytypeio/go-anytype-middleware/core/block/editor/state" "github.com/anytypeio/go-anytype-middleware/core/block/import/converter" "github.com/anytypeio/go-anytype-middleware/core/session" "github.com/anytypeio/go-anytype-middleware/pb" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" - "github.com/anytypeio/go-anytype-middleware/util/pbtypes" - // import plugins _ "github.com/anytypeio/go-anytype-middleware/core/block/import/markdown" _ "github.com/anytypeio/go-anytype-middleware/core/block/import/notion" @@ -41,7 +38,7 @@ type Updater interface { // RelationCreator incapsulates logic for creation of relations type RelationCreator interface { //nolint: lll - ReplaceRelationBlock(ctx *session.Context, st *state.State, oldRelationBlocksToNew map[string]*model.Block, pageID string) + ReplaceRelationBlock(ctx *session.Context, oldRelationBlocksToNew map[string]*model.Block, pageID string) //nolint: lll - CreateRelations(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, pageID string, relations []*converter.Relation, relationsLinks pbtypes.RelationLinks) ([]string, map[string]*model.Block, error) + CreateRelations(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, pageID string, relations []*converter.Relation) ([]string, map[string]*model.Block, error) } From 7af3e66fc072b75c81316be7c712cee4dcb5b028 Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Tue, 10 Jan 2023 16:16:33 +0800 Subject: [PATCH 66/68] GO-665: fix import Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/objectupdater.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/block/import/objectupdater.go b/core/block/import/objectupdater.go index 2fab4b6a3..76f33ce61 100644 --- a/core/block/import/objectupdater.go +++ b/core/block/import/objectupdater.go @@ -2,9 +2,9 @@ package importer import ( "fmt" - "go.uber.org/zap" "github.com/gogo/protobuf/types" + "go.uber.org/zap" "github.com/anytypeio/go-anytype-middleware/core/block" "github.com/anytypeio/go-anytype-middleware/core/block/editor/basic" From 16d97ef06bfa9a3851be10afe44a1755f7c44cbd Mon Sep 17 00:00:00 2001 From: Roman Khafizianov Date: Tue, 10 Jan 2023 09:45:42 +0100 Subject: [PATCH 67/68] Fix ci webp (#1697) ci: fix brew and CGO --- .github/workflows/build.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b887628f7..0614f4b87 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,7 +38,10 @@ jobs: curl https://raw.githubusercontent.com/Homebrew/homebrew-core/31b24d65a7210ea0a5689d5ad00dd8d1bf5211db/Formula/protobuf.rb --output protobuf.rb HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 brew install ./protobuf.rb HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 brew install --ignore-dependencies swift-protobuf - HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 brew install mingw-w64 jq FiloSottile/musl-cross/musl-cross + HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 brew install mingw-w64 + brew tap filosottile/musl-cross + brew install filosottile/musl-cross/musl-cross -h + brew install filosottile/musl-cross/musl-cross --with-aarch64 npm i -g node-gyp - name: Checkout uses: actions/checkout@v2 @@ -72,9 +75,11 @@ jobs: run: | echo $FLAGS mkdir -p .release - gox -ldflags="$FLAGS" -osarch="darwin/amd64 darwin/arm64 linux/amd64 linux/arm64" --tags="nographviz nowatchdog nosigar nomutexdeadlockdetector" -output="{{.OS}}-{{.Arch}}" github.com/anytypeio/go-anytype-middleware/cmd/grpcserver + gox -cgo -ldflags="$FLAGS" -osarch="darwin/amd64 darwin/arm64" --tags="nographviz nowatchdog nosigar nomutexdeadlockdetector" -output="{{.OS}}-{{.Arch}}" github.com/anytypeio/go-anytype-middleware/cmd/grpcserver + CC="x86_64-linux-musl-gcc" CXX="x86_64-linux-musl-g++" gox -cgo -osarch="linux/amd64" --tags="nographviz nowatchdog nosigar nomutexdeadlockdetector" -output="{{.OS}}-{{.Arch}}" github.com/anytypeio/go-anytype-middleware/cmd/grpcserver + CC="aarch64-linux-musl-gcc" CXX="aarch64-linux-musl-g++" gox -cgo -osarch="linux/arm64" --tags="nographviz nowatchdog nosigar nomutexdeadlockdetector" -output="{{.OS}}-{{.Arch}}" github.com/anytypeio/go-anytype-middleware/cmd/grpcserver make protos-server - CC="x86_64-w64-mingw32-gcc" CXX="x86_64-w64-mingw32-g++" gox -ldflags="$FLAGS" -osarch="windows/amd64" --tags="nographviz nowatchdog nosigar nomutexdeadlockdetector" -output="{{.OS}}-{{.Arch}}" github.com/anytypeio/go-anytype-middleware/cmd/grpcserver + CC="x86_64-w64-mingw32-gcc" CXX="x86_64-w64-mingw32-g++" gox -cgo -ldflags="$FLAGS" -osarch="windows/amd64" --tags="nographviz nowatchdog nosigar nomutexdeadlockdetector" -output="{{.OS}}-{{.Arch}}" github.com/anytypeio/go-anytype-middleware/cmd/grpcserver ls -lha . - name: Make JS protos run: | From a77d3910d5d69255a2745c6ed8dff77110054919 Mon Sep 17 00:00:00 2001 From: AnastasiaShemyakinskaya Date: Tue, 10 Jan 2023 20:10:21 +0800 Subject: [PATCH 68/68] GO-512: fix comments Signed-off-by: AnastasiaShemyakinskaya --- core/block/import/objectupdater.go | 8 ++++---- core/block/import/relationcreator.go | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/core/block/import/objectupdater.go b/core/block/import/objectupdater.go index 76f33ce61..1e5f8ec73 100644 --- a/core/block/import/objectupdater.go +++ b/core/block/import/objectupdater.go @@ -57,7 +57,7 @@ func (ou *ObjectUpdater) Update(ctx *session.Context, }) if err == nil { if len(records) > 0 { - filesToDelete, err := ou.update(ctx, snapshot, records[0], relations, pageID) + filesToDelete, err := ou.update(ctx, snapshot, records[0].Details, relations, pageID) return records[0].Details, filesToDelete, err } } @@ -76,7 +76,7 @@ func (ou *ObjectUpdater) Update(ctx *session.Context, }) if err == nil { if len(records) > 0 { - filesToDelete, err := ou.update(ctx, snapshot, records[0], relations, pageID) + filesToDelete, err := ou.update(ctx, snapshot, records[0].Details, relations, pageID) return records[0].Details, filesToDelete, err } } @@ -86,7 +86,7 @@ func (ou *ObjectUpdater) Update(ctx *session.Context, func (ou *ObjectUpdater) update(ctx *session.Context, snapshot *model.SmartBlockSnapshotBase, - details database.Record, + details *types.Struct, relations []*converter.Relation, pageID string) ([]string, error) { simpleBlocks := make([]simple.Block, 0) @@ -94,7 +94,7 @@ func (ou *ObjectUpdater) update(ctx *session.Context, filesToDelete = make([]string, 0) oldRelationBlockToNew = make(map[string]*model.Block, 0) ) - id := details.Details.Fields[bundle.RelationKeyId.String()].GetStringValue() + id := details.Fields[bundle.RelationKeyId.String()].GetStringValue() allBlocksIds := make([]string, 0) if err := ou.service.Do(id, func(b sb.SmartBlock) error { s := b.NewStateCtx(ctx) diff --git a/core/block/import/relationcreator.go b/core/block/import/relationcreator.go index dc6a2de84..0ae41a274 100644 --- a/core/block/import/relationcreator.go +++ b/core/block/import/relationcreator.go @@ -290,13 +290,14 @@ func (rc *RelationService) ReplaceRelationBlock(ctx *session.Context, if err := s.InsertTo(b.Model().GetId(), model.Block_Replace, simpleBlock.Model().GetId()); err != nil { log.With(zap.String("object id", pageID)).Errorf("failed to insert: %w", err) } - if err := sb.Apply(s); err != nil { - log.With(zap.String("object id", pageID)).Errorf("failed to apply state: %w", err) - } return true }); err != nil { return err } + if err := sb.Apply(s); err != nil { + log.With(zap.String("object id", pageID)).Errorf("failed to apply state: %w", err) + return err + } return nil }); sbErr != nil { log.With(zap.String("object id", pageID)).Errorf("failed to replace relation block: %w", sbErr)