1
0
Fork 0
mirror of https://github.com/anyproto/anytype-heart.git synced 2025-06-09 17:44:59 +09:00
This commit is contained in:
Sergey Cherepanov 2022-02-21 13:59:49 +03:00
commit a30a3b1e7f
No known key found for this signature in database
GPG key ID: 87F8EDE8FBDF637C
47 changed files with 4297 additions and 2811 deletions

View file

@ -10,15 +10,12 @@ jobs:
- name: Install Go
uses: actions/setup-go@v1
with:
go-version: 1.17.3
go-version: 1.17.6
- name: Setup GO
run: |
echo GOPATH=$(go env GOPATH) >> $GITHUB_ENV
echo GOBIN=$(go env GOPATH)/bin >> $GITHUB_ENV
echo $(go env GOPATH)/bin >> $GITHUB_PATH
wget https://at9412003.fra1.digitaloceanspaces.com/goroot.tar.gz
tar -xzf goroot.tar.gz -C $GOROOT
go version
- name: Install patched gox
run: |
mkdir -p $GOPATH/src/github.com/mitchellh
@ -148,7 +145,7 @@ jobs:
run: |
gomobile bind -tags "nogrpcserver gomobile" -ldflags "$FLAGS" -v -target=ios -o Lib.xcframework github.com/anytypeio/go-anytype-middleware/clientlibrary/service github.com/anytypeio/go-anytype-middleware/core
sudo /usr/sbin/purge
gtar -czvf ios_framework_${VERSION}.tar.gz Lib.xcframework protobuf
gtar --exclude ".*" -czvf ios_framework_${VERSION}.tar.gz Lib.xcframework protobuf
mv ios_framework_${VERSION}.tar.gz .release/
- name: Make java protos
run: |
@ -163,7 +160,7 @@ jobs:
run: |
gomobile bind -tags "nogrpcserver gomobile" -ldflags "$FLAGS" -v -target=android -o lib.aar github.com/anytypeio/go-anytype-middleware/clientlibrary/service github.com/anytypeio/go-anytype-middleware/core
sudo /usr/sbin/purge
gtar -czvf android_lib_${VERSION}.tar.gz lib.aar protobuf
gtar --exclude ".*" -czvf android_lib_${VERSION}.tar.gz lib.aar protobuf
mv android_lib_${VERSION}.tar.gz .release/
- name: Publish android lib to maven
run: |
@ -187,7 +184,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v1
with:
go-version: 1.16
go-version: 1.17.6
- name: Checkout
uses: actions/checkout@v2
- name: Set env vars

View file

@ -24,197 +24,197 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
func init() { proto.RegisterFile("pb/protos/service/service.proto", fileDescriptor_93a29dc403579097) }
var fileDescriptor_93a29dc403579097 = []byte{
// 3026 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x9b, 0x5b, 0x6f, 0xdc, 0xc6,
0x15, 0x80, 0xb3, 0x40, 0x91, 0xa4, 0x93, 0xc4, 0x71, 0xd8, 0x3a, 0xb1, 0xe5, 0x54, 0xbe, 0xc4,
0xf2, 0x45, 0xb6, 0x28, 0x59, 0x6e, 0x53, 0xf4, 0x1a, 0x48, 0x2b, 0x5b, 0x16, 0x22, 0xdb, 0xaa,
0x56, 0xb2, 0x8a, 0xf4, 0x4a, 0x91, 0xe3, 0x5d, 0x46, 0x5c, 0x0e, 0x43, 0xce, 0xae, 0xbc, 0x01,
0x5a, 0xf4, 0x86, 0x02, 0x7d, 0x0b, 0xd0, 0xc7, 0x3e, 0xf5, 0xa9, 0x40, 0x7f, 0x49, 0x1f, 0xf3,
0xd8, 0xc7, 0xc2, 0xfe, 0x23, 0xc5, 0x70, 0x0e, 0x67, 0x38, 0xc3, 0x99, 0x21, 0xd7, 0x4f, 0x82,
0x78, 0xbe, 0x73, 0xe1, 0xf0, 0xcc, 0x99, 0x33, 0xe4, 0x2c, 0xba, 0x94, 0x1d, 0xaf, 0x66, 0x39,
0xa1, 0xa4, 0x58, 0x2d, 0x70, 0x3e, 0x8d, 0x43, 0x5c, 0xfd, 0xf5, 0xcb, 0xcb, 0xde, 0x1b, 0x41,
0x3a, 0xa3, 0xb3, 0x0c, 0x2f, 0x9c, 0x97, 0x64, 0x48, 0xc6, 0xe3, 0x20, 0x8d, 0x0a, 0x8e, 0x2c,
0xbc, 0x2f, 0x25, 0x78, 0x8a, 0x53, 0x0a, 0xd7, 0xd7, 0xff, 0xf5, 0x25, 0x3a, 0xd3, 0x4f, 0x62,
0x9c, 0xd2, 0x3e, 0x28, 0x78, 0x39, 0x3a, 0xf7, 0xe4, 0xf8, 0x73, 0x1c, 0xd2, 0x8d, 0x28, 0x3a,
0x8a, 0xe9, 0x88, 0xff, 0xb3, 0x13, 0x79, 0xb7, 0x7d, 0xf0, 0xe3, 0xef, 0x67, 0xa1, 0xcf, 0x2f,
0xfb, 0x1a, 0xe4, 0xef, 0xe3, 0x2f, 0x26, 0xb8, 0xa0, 0x0b, 0x77, 0xba, 0xc1, 0x45, 0x46, 0xd2,
0x02, 0x7b, 0xcf, 0xd0, 0x7b, 0xfc, 0xe2, 0x60, 0x14, 0xe4, 0x78, 0x73, 0xb6, 0x1b, 0xa7, 0x27,
0xde, 0x0d, 0x93, 0x89, 0x1a, 0x20, 0x7c, 0xdd, 0x6c, 0x07, 0xc1, 0xcf, 0x11, 0x7a, 0xfb, 0x28,
0x48, 0x12, 0x4c, 0xfb, 0x39, 0x0e, 0x28, 0xf6, 0xae, 0x2a, 0x9a, 0x5c, 0xe4, 0x73, 0x99, 0xb0,
0xfe, 0x91, 0x93, 0x01, 0xc3, 0x9f, 0xa1, 0x77, 0xb8, 0x64, 0x1f, 0x87, 0x64, 0x8a, 0x73, 0xcf,
0xa8, 0x05, 0x42, 0x61, 0xfa, 0x9a, 0x1b, 0xd2, 0x6d, 0xf7, 0x49, 0x3a, 0xc5, 0x39, 0x35, 0xdb,
0x06, 0xa1, 0xdb, 0xb6, 0x84, 0xc0, 0xf6, 0x6f, 0xd1, 0xbb, 0x47, 0x24, 0x3f, 0x29, 0xb2, 0x20,
0xc4, 0x30, 0x26, 0x4b, 0xaa, 0x62, 0x25, 0xd5, 0x87, 0xe5, 0x7a, 0x1b, 0x66, 0xf0, 0x30, 0xc0,
0x09, 0x0e, 0xa9, 0xd5, 0x03, 0x17, 0xb7, 0x7a, 0x10, 0x18, 0x78, 0x48, 0xd0, 0xb7, 0x84, 0x70,
0x1b, 0xd3, 0xfe, 0x24, 0xcf, 0x71, 0x4a, 0xbd, 0x5b, 0x16, 0x75, 0x89, 0x08, 0x4f, 0xcb, 0x5d,
0x50, 0xc3, 0xfd, 0x6c, 0x63, 0xba, 0x91, 0x24, 0xd6, 0xfb, 0xe1, 0xe2, 0xd6, 0xfb, 0x11, 0x18,
0x78, 0xf8, 0x3d, 0xba, 0x50, 0x1b, 0x31, 0xba, 0x53, 0x3c, 0x8c, 0x87, 0xa3, 0x24, 0x1e, 0x8e,
0x28, 0x8e, 0xbc, 0x55, 0xeb, 0xa0, 0xa8, 0xa0, 0xf0, 0xba, 0xd6, 0x5d, 0x01, 0xfc, 0xff, 0x0a,
0x9d, 0xd9, 0x08, 0x43, 0x32, 0x49, 0x45, 0x32, 0xab, 0xb9, 0x04, 0xc2, 0x46, 0x36, 0x2f, 0xb5,
0x50, 0x32, 0x9d, 0x41, 0x06, 0x09, 0xf7, 0x91, 0x51, 0x4f, 0x4b, 0xb7, 0x6b, 0x6e, 0xa8, 0x61,
0x1b, 0x52, 0xcd, 0x6c, 0x5b, 0x4b, 0xb4, 0x6b, 0x6e, 0x08, 0x6c, 0x1f, 0xa0, 0xb7, 0x2a, 0xdb,
0x94, 0x64, 0xde, 0x15, 0xb3, 0x12, 0x25, 0x99, 0xb0, 0x7b, 0xd5, 0x85, 0x48, 0xab, 0x0f, 0xe2,
0x04, 0x3f, 0x79, 0xf6, 0x2c, 0x21, 0x41, 0xa4, 0x59, 0x65, 0x12, 0x1f, 0x44, 0x16, 0xab, 0x1a,
0x22, 0x93, 0x94, 0x09, 0x76, 0xe3, 0x82, 0x56, 0x96, 0x97, 0x1a, 0x6a, 0x4c, 0xda, 0xb0, 0x7e,
0xbd, 0x0d, 0x03, 0x0f, 0x3f, 0x43, 0xe8, 0x29, 0xce, 0x8b, 0x98, 0xa4, 0xdb, 0x98, 0x7a, 0x97,
0x15, 0x2d, 0x10, 0xb0, 0xc4, 0x16, 0x76, 0xaf, 0x38, 0x08, 0x30, 0xf9, 0x10, 0xbd, 0xb1, 0x4b,
0x86, 0x03, 0x9c, 0x46, 0xde, 0x77, 0x14, 0x7a, 0x97, 0x0c, 0x7d, 0x76, 0x59, 0x18, 0x5b, 0xb4,
0x89, 0xc1, 0xd2, 0x63, 0xf4, 0xcd, 0x3e, 0x49, 0x9f, 0xc5, 0x43, 0x16, 0xdb, 0x25, 0x05, 0xe6,
0xd7, 0x95, 0xd0, 0x2e, 0xdb, 0x01, 0xb0, 0xb7, 0x83, 0xde, 0x1c, 0x8c, 0x26, 0x34, 0x22, 0xa7,
0xa9, 0x16, 0x5a, 0x75, 0xd9, 0x12, 0x5a, 0x4d, 0x2c, 0x57, 0xba, 0xfb, 0xcf, 0x29, 0xce, 0xd3,
0x20, 0xd9, 0xca, 0x49, 0xc6, 0x06, 0xb8, 0xd0, 0x56, 0xba, 0xba, 0xbc, 0x7c, 0x02, 0x85, 0x65,
0xa5, 0x33, 0x82, 0xb2, 0x28, 0xd6, 0xc5, 0x7d, 0x92, 0xd2, 0x66, 0x51, 0x54, 0x0c, 0x00, 0x62,
0x29, 0x8a, 0x16, 0x14, 0xbc, 0xed, 0xa3, 0xb7, 0xd8, 0x42, 0xbb, 0x97, 0xe3, 0x69, 0x8c, 0x4f,
0xb5, 0x74, 0xa8, 0x49, 0x2c, 0xe9, 0xa0, 0x12, 0x60, 0xf3, 0x09, 0x42, 0x87, 0x19, 0x4b, 0x3a,
0x76, 0x67, 0xda, 0x53, 0x94, 0x02, 0xcb, 0x53, 0x54, 0x00, 0x30, 0x78, 0x88, 0xde, 0xde, 0x22,
0xa7, 0xa9, 0x30, 0xa9, 0xc6, 0x50, 0x17, 0x59, 0xe6, 0x9a, 0x86, 0xc8, 0x19, 0xbc, 0x99, 0x90,
0xf0, 0x84, 0xbb, 0xd4, 0xac, 0x96, 0x12, 0x88, 0xc6, 0x62, 0x55, 0x43, 0x64, 0xa7, 0x52, 0x0a,
0xf6, 0x71, 0x96, 0x04, 0xa1, 0xde, 0xa9, 0x70, 0x1d, 0x90, 0x59, 0x3a, 0x15, 0x9d, 0x01, 0xc3,
0x31, 0xf2, 0x20, 0xdc, 0x28, 0xa0, 0xb8, 0xca, 0x8b, 0x9b, 0xc6, 0x90, 0x6a, 0x84, 0x70, 0x72,
0xab, 0x03, 0x29, 0xa7, 0x61, 0x29, 0x7f, 0x92, 0xe1, 0x54, 0x7b, 0x80, 0x5c, 0x8f, 0x09, 0x2c,
0x0f, 0x50, 0x01, 0x34, 0x7b, 0x83, 0x11, 0x39, 0x35, 0xda, 0x63, 0x02, 0xa7, 0x3d, 0x00, 0xc0,
0x1e, 0x41, 0xdf, 0x2e, 0x2f, 0x6f, 0x63, 0xba, 0x37, 0x39, 0x4e, 0xe2, 0xf0, 0x08, 0x1f, 0x1f,
0xee, 0xef, 0x7a, 0xcb, 0x06, 0x4d, 0x8d, 0x11, 0x5e, 0x6e, 0x77, 0x62, 0x35, 0x87, 0xec, 0xb6,
0x36, 0x73, 0x1c, 0x44, 0x61, 0x3e, 0x19, 0x1f, 0x17, 0x46, 0x87, 0x1a, 0xe3, 0x74, 0xd8, 0x64,
0x65, 0x15, 0xe0, 0x23, 0x86, 0x69, 0xdd, 0x9f, 0xe9, 0x19, 0xaa, 0x88, 0xa5, 0x0a, 0x58, 0x50,
0x6d, 0x26, 0xc0, 0xba, 0x6e, 0x9a, 0x09, 0xda, 0xaa, 0x7e, 0xd5, 0x85, 0xc8, 0xb5, 0xac, 0x66,
0x75, 0x2f, 0x18, 0xea, 0x2d, 0x6a, 0x5d, 0x8d, 0x89, 0x2d, 0x6b, 0x99, 0x01, 0x93, 0x0d, 0x4f,
0xcd, 0xc3, 0x00, 0x53, 0xad, 0xe1, 0xa9, 0x6b, 0x0e, 0x6a, 0x0b, 0xc7, 0x52, 0x0b, 0xa5, 0x17,
0x88, 0x34, 0x61, 0xdb, 0x1a, 0x63, 0x81, 0x28, 0x45, 0xee, 0x02, 0x51, 0x21, 0x72, 0x01, 0xe6,
0x41, 0x27, 0xa4, 0xc0, 0x9e, 0x29, 0xd9, 0x4b, 0x89, 0xa5, 0xe2, 0xaa, 0x84, 0xec, 0x9e, 0xca,
0xeb, 0x55, 0x9d, 0xf3, 0x4c, 0x05, 0xa5, 0x12, 0x5a, 0xba, 0xa7, 0x06, 0x04, 0xb6, 0x7f, 0x09,
0xb6, 0xb7, 0x31, 0x7d, 0x14, 0xe4, 0x27, 0x85, 0x71, 0x88, 0xd9, 0xa2, 0x5b, 0x4a, 0x9d, 0x43,
0x5c, 0xa7, 0xb4, 0xca, 0x70, 0x98, 0x46, 0xc4, 0x58, 0x19, 0x98, 0xc0, 0x59, 0x19, 0x00, 0xd0,
0xec, 0xed, 0x63, 0x8b, 0x3d, 0x26, 0x70, 0xda, 0x03, 0x00, 0xec, 0xfd, 0x06, 0x32, 0x6c, 0x80,
0xe9, 0x83, 0x18, 0x27, 0x51, 0x61, 0x4c, 0x61, 0x96, 0x35, 0x5c, 0xec, 0x4c, 0x61, 0x05, 0x03,
0x07, 0x5f, 0x40, 0x65, 0x19, 0xb0, 0x1d, 0x68, 0x41, 0xf3, 0x38, 0xa4, 0x31, 0x49, 0x0b, 0xef,
0xb6, 0x45, 0xbf, 0x0e, 0x59, 0xf6, 0xec, 0x56, 0x58, 0xcb, 0x16, 0xd6, 0x1f, 0x3e, 0x22, 0x53,
0x6c, 0xca, 0x96, 0xb2, 0x77, 0x64, 0x42, 0x57, 0xb6, 0xd4, 0x21, 0xb0, 0x3d, 0x41, 0xef, 0x2b,
0xb6, 0x0f, 0xc8, 0x63, 0x7c, 0x5a, 0x4e, 0xfd, 0x3b, 0x0e, 0x7d, 0x41, 0x09, 0x6f, 0x2b, 0x1d,
0x69, 0x70, 0xfb, 0x55, 0x0f, 0x5d, 0x12, 0x10, 0xec, 0x95, 0xfb, 0xa3, 0x38, 0x89, 0x72, 0x9c,
0x1e, 0x10, 0xc6, 0x16, 0xde, 0xf7, 0x2c, 0x26, 0xcd, 0xb8, 0x88, 0xe4, 0xe3, 0x79, 0xd5, 0x20,
0xa4, 0x13, 0x58, 0xae, 0x19, 0x2c, 0xb3, 0xe7, 0x96, 0xc5, 0x9a, 0x21, 0x83, 0x96, 0xbb, 0xa0,
0xe0, 0x6c, 0x8a, 0xce, 0xd5, 0x9d, 0x1d, 0xe0, 0xe7, 0x74, 0x40, 0x67, 0x09, 0xf6, 0x56, 0x1c,
0x46, 0x18, 0xe5, 0x97, 0x98, 0xf0, 0xe9, 0x77, 0xc5, 0xb5, 0x9e, 0x84, 0x41, 0x5b, 0x93, 0x2c,
0x89, 0x43, 0xb6, 0x7e, 0xdc, 0xb4, 0x58, 0x11, 0x84, 0xab, 0x27, 0x69, 0x90, 0xe0, 0xea, 0xaf,
0x3d, 0x74, 0xb1, 0x7e, 0x8f, 0x9b, 0x41, 0x78, 0x32, 0xcc, 0xc9, 0x24, 0x8d, 0xfa, 0x24, 0x21,
0xb9, 0xb7, 0xee, 0x08, 0x5d, 0x63, 0x85, 0xfb, 0x7b, 0x73, 0xe9, 0x40, 0x20, 0x23, 0xf4, 0x5e,
0x3d, 0x8e, 0x8d, 0x24, 0x1e, 0xa6, 0xd6, 0x5b, 0x66, 0x96, 0x4a, 0xa2, 0xf5, 0x96, 0xeb, 0x24,
0x78, 0x2a, 0xa0, 0x36, 0x80, 0xa7, 0xad, 0x78, 0xca, 0x1f, 0xea, 0x1d, 0x87, 0x89, 0xad, 0x78,
0xaa, 0x3d, 0xd3, 0x95, 0x8e, 0xb4, 0x39, 0x95, 0x58, 0xcb, 0xdc, 0x9e, 0x4a, 0x65, 0x63, 0xdd,
0x3d, 0x95, 0x14, 0x5c, 0xee, 0xaf, 0x04, 0x74, 0x30, 0xc9, 0xd3, 0x9d, 0x94, 0x12, 0x6d, 0x7f,
0x25, 0x8d, 0x54, 0x80, 0x65, 0x7f, 0x65, 0x04, 0xc1, 0xcf, 0xe7, 0xe0, 0x67, 0x80, 0xe9, 0x6e,
0x40, 0xf1, 0x73, 0x96, 0xd6, 0xb6, 0xbe, 0xca, 0x2f, 0x09, 0x9e, 0xf9, 0x2d, 0x7d, 0x95, 0x8a,
0x82, 0xaf, 0x21, 0x3a, 0x5b, 0xf9, 0x62, 0x82, 0xd2, 0xd5, 0x4d, 0x8b, 0x7e, 0xa9, 0xa9, 0x78,
0xba, 0xd5, 0x81, 0x6c, 0xde, 0x14, 0x13, 0xf0, 0x19, 0xe1, 0xd4, 0x57, 0x27, 0xc2, 0x72, 0x17,
0xd4, 0x5e, 0x6b, 0xb8, 0xbf, 0xd6, 0x5a, 0xa3, 0xfa, 0xf4, 0xbb, 0xe2, 0xe6, 0xd9, 0xc0, 0x10,
0xd6, 0x4c, 0x38, 0x67, 0x43, 0x69, 0x87, 0x51, 0x9d, 0x66, 0x43, 0x9d, 0x36, 0x0f, 0x2c, 0x9f,
0x09, 0xce, 0x81, 0x55, 0x67, 0xc1, 0x72, 0x17, 0x14, 0x7c, 0x65, 0xb2, 0xe7, 0x2f, 0x07, 0x75,
0x84, 0xc3, 0x13, 0x1c, 0x59, 0x3b, 0x01, 0x3e, 0x46, 0x1c, 0x6a, 0xed, 0x04, 0x34, 0x58, 0x6b,
0x45, 0x07, 0x59, 0x12, 0x53, 0x63, 0x2b, 0x5a, 0x4a, 0x9c, 0xad, 0x68, 0x45, 0x68, 0x26, 0x1f,
0xe1, 0x7c, 0x68, 0xee, 0x6e, 0x4b, 0x89, 0xd3, 0x64, 0x45, 0x68, 0x3d, 0x5d, 0x9f, 0x64, 0x33,
0x63, 0x4f, 0xc7, 0x04, 0xce, 0x9e, 0x0e, 0x00, 0x2d, 0xc4, 0xbd, 0xa0, 0xa0, 0xe6, 0x10, 0x4b,
0x89, 0x33, 0xc4, 0x8a, 0x00, 0x93, 0x9f, 0xa2, 0x37, 0x79, 0x88, 0x13, 0xea, 0x2d, 0x9a, 0x02,
0x98, 0xc8, 0x41, 0xbc, 0x64, 0x95, 0x6b, 0xdb, 0x8e, 0xfb, 0xcf, 0x33, 0x92, 0x53, 0xe3, 0xb6,
0x83, 0x8b, 0x9c, 0xdb, 0x0e, 0x81, 0x68, 0x3b, 0xca, 0x9d, 0x31, 0xbb, 0xce, 0xb2, 0xbc, 0x7c,
0x2b, 0x66, 0xca, 0x65, 0x15, 0x71, 0xe6, 0x72, 0x03, 0x6d, 0x56, 0x3e, 0x56, 0xec, 0x1f, 0x07,
0x63, 0x6c, 0xad, 0x7c, 0xe5, 0x6a, 0xc0, 0x88, 0xd6, 0xca, 0x57, 0x27, 0x9b, 0x13, 0x74, 0x67,
0x1c, 0x0c, 0xb9, 0x27, 0x9b, 0x7e, 0x49, 0xa8, 0xae, 0x96, 0xbb, 0xa0, 0xe0, 0x6b, 0x0c, 0xdd,
0x4e, 0xe5, 0xeb, 0x28, 0x8e, 0xe8, 0xc8, 0x73, 0x5b, 0x28, 0x19, 0xe7, 0x3b, 0x80, 0x26, 0xdb,
0xbc, 0xb5, 0xa7, 0x71, 0x84, 0x89, 0xf3, 0xd6, 0x4a, 0xa2, 0xdb, 0xad, 0x29, 0x68, 0xf3, 0xd6,
0x4a, 0xb1, 0xfb, 0xd6, 0xb8, 0x85, 0x6e, 0xb7, 0xa6, 0xb2, 0xe0, 0xee, 0x4f, 0x3d, 0x74, 0x41,
0xac, 0xc2, 0x71, 0x7a, 0x72, 0x10, 0xe4, 0x43, 0x4c, 0x79, 0x7e, 0x46, 0xde, 0x5d, 0xdb, 0x12,
0xcb, 0xf6, 0xd1, 0x0a, 0x2a, 0xbc, 0xaf, 0xcf, 0xa3, 0xa2, 0x75, 0xe8, 0x9b, 0x84, 0x9c, 0x8c,
0x83, 0xfc, 0xe4, 0x01, 0xa6, 0xe1, 0xc8, 0x38, 0xc0, 0x15, 0xe1, 0x97, 0x88, 0x73, 0x80, 0x1b,
0xa8, 0xde, 0xbe, 0x56, 0x00, 0x7f, 0xdf, 0xb0, 0x91, 0x46, 0xdc, 0xed, 0xba, 0xcb, 0x96, 0xca,
0xba, 0xda, 0x57, 0x87, 0x0e, 0x04, 0xf2, 0x3b, 0x74, 0xbe, 0x24, 0xd9, 0x5c, 0x12, 0x0c, 0xbc,
0x02, 0x5d, 0x35, 0x18, 0x2c, 0xe7, 0x9c, 0x06, 0x5a, 0xbe, 0x51, 0x39, 0x15, 0xc0, 0x7d, 0x0a,
0x65, 0x68, 0x1f, 0x27, 0x01, 0xdb, 0x97, 0x0e, 0x30, 0xfd, 0x14, 0xcf, 0x8c, 0x99, 0x56, 0x21,
0x3e, 0x67, 0x9c, 0x99, 0xd6, 0x64, 0xc1, 0x1f, 0x86, 0x42, 0x54, 0x01, 0x1b, 0x51, 0x64, 0xea,
0x2a, 0xa5, 0x81, 0x8d, 0x28, 0x72, 0x75, 0x95, 0x3a, 0x08, 0x6e, 0xbe, 0x44, 0x1f, 0xf0, 0x37,
0x30, 0x01, 0x0d, 0xa6, 0x31, 0x3e, 0x7d, 0x1a, 0xe3, 0x53, 0x78, 0x9b, 0xe6, 0x9b, 0x5e, 0xb3,
0x00, 0xe6, 0x4b, 0x4e, 0x38, 0x5d, 0xed, 0xcc, 0x3b, 0x7c, 0x6f, 0xe1, 0x04, 0x77, 0xf1, 0xcd,
0xb9, 0xee, 0xbe, 0x05, 0xef, 0xf0, 0xcd, 0x5f, 0x2a, 0xb7, 0xfb, 0xe6, 0x5c, 0x77, 0xdf, 0x82,
0x07, 0xdf, 0x7f, 0xee, 0xa1, 0x85, 0x86, 0x73, 0xb6, 0x23, 0x0b, 0x69, 0x3c, 0xc5, 0xc6, 0x2a,
0xa2, 0xd8, 0x13, 0xa8, 0xb3, 0x8a, 0x58, 0x55, 0x20, 0x8a, 0xbf, 0xf5, 0xd0, 0x87, 0xa6, 0x28,
0xf6, 0x48, 0x11, 0xb3, 0x3c, 0xf1, 0xee, 0x75, 0x30, 0x5a, 0xc1, 0x22, 0x92, 0xef, 0xce, 0xa7,
0x04, 0xb1, 0x9c, 0xc2, 0xdb, 0x97, 0x8a, 0x1c, 0x60, 0x3a, 0x20, 0x93, 0x3c, 0x34, 0x6e, 0xde,
0xa4, 0x3d, 0x81, 0xb9, 0x7a, 0x73, 0x33, 0xae, 0x15, 0x95, 0x8a, 0xa9, 0xcf, 0x36, 0xe7, 0x73,
0xad, 0x81, 0xce, 0xa2, 0x62, 0x51, 0xd0, 0x8b, 0xab, 0xee, 0x1f, 0x52, 0x71, 0xbd, 0x8b, 0x45,
0x2d, 0x1d, 0xef, 0xcd, 0xa5, 0xd3, 0x16, 0x08, 0xcc, 0xc7, 0x4e, 0x81, 0x68, 0x73, 0xf2, 0xde,
0x5c, 0x3a, 0x10, 0xc8, 0x3f, 0x7a, 0xe8, 0xaa, 0x31, 0x10, 0xb6, 0xd9, 0xd9, 0x98, 0x06, 0x71,
0x12, 0x1c, 0x27, 0xd8, 0xfb, 0x41, 0x17, 0xdb, 0x8a, 0x8a, 0x08, 0xeb, 0x87, 0xaf, 0xa2, 0x0a,
0xd1, 0xfd, 0xa1, 0x5a, 0xfe, 0x65, 0x74, 0x21, 0xc9, 0x23, 0x28, 0x98, 0x2d, 0xcf, 0x5f, 0x92,
0x22, 0x96, 0xbb, 0x73, 0x68, 0x40, 0x08, 0xff, 0xec, 0xa1, 0x6b, 0x86, 0x10, 0xaa, 0xc0, 0x9f,
0x64, 0x55, 0xfa, 0xfe, 0xa8, 0xdd, 0x76, 0x43, 0x49, 0x04, 0xf6, 0xe3, 0x57, 0x53, 0x86, 0x18,
0xff, 0xdd, 0x43, 0x37, 0x5a, 0x63, 0x84, 0x14, 0xff, 0xe9, 0xbc, 0x9e, 0xb4, 0x74, 0xff, 0xe4,
0x95, 0xf5, 0xe7, 0x09, 0x16, 0xa6, 0xc1, 0xdc, 0xc1, 0x6a, 0x53, 0xe2, 0x93, 0x57, 0xd6, 0xd7,
0x5a, 0x3f, 0x7e, 0xe4, 0xec, 0x60, 0x96, 0x95, 0x1f, 0x8f, 0x4c, 0xad, 0x9f, 0x24, 0xfc, 0xfa,
0x17, 0xa4, 0xe5, 0x2e, 0x28, 0x38, 0xcb, 0xd1, 0xb9, 0xc7, 0xc1, 0x34, 0x1e, 0x8a, 0x19, 0xc1,
0x41, 0xfd, 0x1d, 0xbf, 0x64, 0xfc, 0x1a, 0x64, 0xd9, 0xd9, 0x5b, 0x61, 0xf0, 0xf9, 0xf7, 0x1e,
0xba, 0x2c, 0x99, 0x6d, 0x0c, 0xc4, 0x4e, 0xfa, 0x8c, 0x1c, 0xc5, 0x74, 0xc4, 0xda, 0xe2, 0xc2,
0xfb, 0xd8, 0x66, 0xd2, 0xcc, 0x8b, 0x50, 0xbe, 0x3f, 0xb7, 0x9e, 0xdc, 0xd9, 0x72, 0xf9, 0x76,
0x1e, 0x64, 0x23, 0x6d, 0x67, 0x0b, 0xc7, 0xff, 0x4a, 0x91, 0x65, 0x67, 0xab, 0x21, 0xf2, 0x8b,
0x3b, 0x9c, 0x41, 0xc4, 0x41, 0x1e, 0x8e, 0x3c, 0xa3, 0x0e, 0x97, 0x59, 0xbe, 0xb8, 0xeb, 0x8c,
0x7c, 0x70, 0x75, 0xc3, 0x83, 0xc9, 0x71, 0x11, 0xe6, 0xf1, 0x31, 0x36, 0x1f, 0xa8, 0xd4, 0x20,
0xf7, 0x81, 0xca, 0x26, 0x2c, 0xdf, 0xa8, 0x57, 0xa7, 0x2c, 0x0b, 0xe9, 0xd0, 0x78, 0x50, 0xb2,
0x4e, 0x58, 0xb6, 0xce, 0x66, 0x12, 0x5c, 0x3d, 0x47, 0x1f, 0xd4, 0x6f, 0xef, 0x30, 0x2d, 0x84,
0xbf, 0x15, 0x7b, 0xcc, 0x35, 0xcc, 0xd2, 0x2e, 0x38, 0x70, 0xfd, 0xd4, 0xa8, 0xbd, 0x2b, 0x07,
0x23, 0xa6, 0xfe, 0xe0, 0x66, 0x3b, 0x28, 0x3f, 0xdb, 0xab, 0x7e, 0xa0, 0x58, 0x2e, 0xbb, 0x2c,
0x68, 0x85, 0xf1, 0x76, 0x27, 0xd6, 0xe6, 0x10, 0x0a, 0x9e, 0xd3, 0xa1, 0x56, 0xdc, 0x6e, 0x77,
0x62, 0xf5, 0x67, 0xd8, 0x5c, 0xb8, 0x56, 0x5c, 0x76, 0x9a, 0x4b, 0x95, 0xdf, 0x15, 0x07, 0xcf,
0x7f, 0xec, 0xa1, 0x05, 0x93, 0x6b, 0x18, 0xe2, 0xb5, 0x76, 0x73, 0xda, 0x40, 0xdf, 0x9d, 0x43,
0xa3, 0x25, 0x06, 0x18, 0xf5, 0x0e, 0x31, 0x68, 0x63, 0x7f, 0x77, 0x0e, 0x0d, 0x88, 0xe1, 0x2f,
0x3d, 0x74, 0x51, 0x8d, 0x41, 0x6d, 0xb1, 0x9c, 0x26, 0xcd, 0xad, 0xd5, 0xfa, 0x3c, 0x2a, 0xf2,
0xb0, 0x45, 0x35, 0x99, 0xe9, 0x6e, 0x30, 0x23, 0x13, 0xfd, 0xb4, 0xae, 0x98, 0x95, 0x20, 0xb6,
0x7c, 0xa9, 0x36, 0x60, 0xb5, 0xa6, 0x8d, 0x4b, 0x1f, 0xe0, 0x80, 0x4e, 0x72, 0x1c, 0xd5, 0x67,
0xaf, 0x71, 0xac, 0x75, 0x50, 0xd9, 0x5c, 0xdf, 0x9d, 0x43, 0xa3, 0xb6, 0xd7, 0x32, 0x87, 0xb0,
0x8f, 0xc7, 0x64, 0x8a, 0xb5, 0xbd, 0x96, 0xcd, 0x26, 0x87, 0x2d, 0x7b, 0xad, 0x56, 0x25, 0xf9,
0x3e, 0x55, 0x0c, 0xf8, 0x4e, 0xf1, 0x20, 0x98, 0x92, 0x3c, 0xa6, 0xfa, 0xfb, 0x39, 0x39, 0x9a,
0x12, 0xb1, 0xf4, 0x10, 0x16, 0xd4, 0xe8, 0x6d, 0x23, 0x0f, 0x47, 0xf1, 0x14, 0x47, 0x0e, 0x6f,
0x15, 0xd2, 0xc1, 0x5b, 0x0d, 0xd5, 0xd7, 0xe9, 0x03, 0xc2, 0xfa, 0x22, 0xe3, 0x3a, 0x5d, 0x8a,
0xdc, 0xeb, 0x74, 0x85, 0x80, 0xd5, 0x10, 0x9d, 0xe5, 0x82, 0xf2, 0x6b, 0x31, 0x9f, 0xa2, 0xa6,
0xe4, 0xe3, 0x5f, 0x80, 0xd5, 0x89, 0x79, 0xa3, 0x95, 0x93, 0x2f, 0x24, 0xa4, 0x54, 0x1d, 0x2c,
0xdf, 0x66, 0xa3, 0x7c, 0x03, 0xdb, 0x1c, 0xb1, 0xd5, 0xce, 0xbc, 0xd5, 0xb7, 0x48, 0x8b, 0x16,
0xdf, 0x8d, 0xdc, 0x58, 0xed, 0xcc, 0x83, 0xef, 0x63, 0x38, 0x6c, 0x35, 0xc0, 0x74, 0x0b, 0xd3,
0x20, 0x4e, 0x0a, 0xcf, 0x76, 0x04, 0x05, 0xe4, 0x96, 0xb1, 0x35, 0x71, 0xf2, 0xc3, 0xc9, 0x5e,
0x30, 0xac, 0x7e, 0x6e, 0xa0, 0x7e, 0x38, 0x29, 0xcf, 0x63, 0x68, 0xdb, 0xb2, 0x2b, 0x0e, 0x42,
0x7e, 0xdb, 0x19, 0x88, 0x1f, 0x75, 0xa8, 0x5f, 0x46, 0x06, 0xcd, 0x5f, 0x74, 0x5c, 0xb6, 0x03,
0x72, 0x01, 0x7e, 0x84, 0x69, 0x1e, 0x87, 0xc5, 0x00, 0xd3, 0xbd, 0x20, 0x0f, 0xc6, 0x98, 0xe2,
0x5c, 0x3f, 0xa8, 0x07, 0x88, 0xaf, 0x30, 0x96, 0x05, 0xd8, 0xc6, 0xea, 0x49, 0xcd, 0xfa, 0x7e,
0xb8, 0x0f, 0x53, 0x52, 0x97, 0xdb, 0x02, 0xed, 0x76, 0x6e, 0xb4, 0x72, 0xf2, 0x9c, 0x9b, 0x94,
0xb2, 0x34, 0xd0, 0x0e, 0x61, 0xd5, 0x54, 0xcb, 0x24, 0x31, 0x1f, 0xc2, 0x6a, 0x52, 0xf2, 0xb5,
0x91, 0x94, 0xd5, 0xd7, 0x19, 0x63, 0x0f, 0x51, 0x1a, 0x10, 0x65, 0x51, 0xf1, 0xe7, 0x77, 0xc5,
0xc1, 0x31, 0xad, 0x1a, 0xec, 0xba, 0x63, 0xb6, 0x9a, 0xdc, 0x69, 0x35, 0x54, 0x5f, 0x49, 0x56,
0x3a, 0xd2, 0xf2, 0x65, 0x55, 0xd3, 0x2b, 0xb4, 0x2d, 0xab, 0xad, 0xa6, 0xb4, 0xae, 0x65, 0xad,
0xbb, 0x82, 0xcb, 0x3d, 0xac, 0x5f, 0xed, 0xee, 0xb5, 0xb5, 0x6b, 0xad, 0xbb, 0x02, 0xb8, 0xff,
0x09, 0xfa, 0xc6, 0x5e, 0x9c, 0x0e, 0xbd, 0x0b, 0xea, 0xe4, 0x8c, 0xd3, 0xa1, 0x30, 0xba, 0x60,
0x12, 0xc9, 0xc3, 0x63, 0x7b, 0x39, 0x09, 0x71, 0x51, 0xf4, 0x83, 0x34, 0xc4, 0x89, 0x76, 0x78,
0x0c, 0x64, 0x3e, 0x17, 0x5a, 0x0e, 0x8f, 0x35, 0x20, 0xb9, 0xec, 0x3c, 0x8c, 0x0b, 0x4a, 0xf2,
0x59, 0x79, 0x50, 0x58, 0x2d, 0x1f, 0x20, 0x51, 0x8f, 0x0a, 0x5f, 0x75, 0x21, 0xb2, 0x33, 0x02,
0x01, 0xfc, 0x78, 0x41, 0x3f, 0xc3, 0x57, 0xa9, 0x55, 0x62, 0x4b, 0x67, 0x64, 0xc0, 0xe4, 0x76,
0xa6, 0x8a, 0x1b, 0x53, 0x10, 0x6b, 0xdb, 0x19, 0x11, 0x9a, 0x00, 0x2c, 0xdb, 0x19, 0x23, 0x08,
0x7e, 0xfa, 0xe8, 0x75, 0xf8, 0x26, 0x7c, 0x51, 0x3b, 0xe2, 0xaf, 0x7c, 0x0d, 0xfe, 0xd0, 0x2c,
0x04, 0x23, 0xbf, 0x46, 0xef, 0xf2, 0x4b, 0xe2, 0x17, 0x45, 0x5a, 0x31, 0xd1, 0xa4, 0x96, 0x62,
0xd2, 0xa4, 0x74, 0xfb, 0x07, 0x78, 0x9c, 0x25, 0x01, 0xc5, 0x85, 0xd1, 0xbe, 0x90, 0x3a, 0xed,
0xd7, 0x29, 0xb0, 0x1f, 0xa0, 0xb3, 0x5c, 0xb6, 0x4b, 0xc2, 0x20, 0x61, 0x83, 0xa5, 0x1f, 0x2b,
0xd6, 0xc5, 0x96, 0xe7, 0x69, 0xc0, 0xe4, 0xef, 0x0d, 0x1e, 0x05, 0x27, 0xb8, 0x72, 0xae, 0x25,
0x62, 0x5d, 0x64, 0x49, 0x44, 0x0d, 0x01, 0xb3, 0x33, 0x74, 0xbe, 0x2e, 0xd8, 0x9c, 0xc9, 0xe9,
0xaa, 0x15, 0x5a, 0x1b, 0x66, 0x29, 0xb4, 0x0e, 0x1c, 0x5c, 0xff, 0x1c, 0xbd, 0xd3, 0x4f, 0x48,
0x2a, 0x6f, 0x49, 0x8d, 0x57, 0x91, 0x59, 0xde, 0x91, 0xe8, 0x8c, 0x7c, 0xdc, 0xdc, 0xa1, 0x3c,
0xfe, 0x67, 0x5a, 0x9b, 0x9a, 0x47, 0xff, 0x96, 0x5a, 0x28, 0xb0, 0xff, 0x0b, 0x74, 0xe6, 0x30,
0x2d, 0xb2, 0x24, 0x28, 0x46, 0xf0, 0x7a, 0x47, 0x0d, 0x4b, 0x15, 0x5a, 0x0a, 0x4e, 0x03, 0x92,
0xb9, 0x54, 0x89, 0xc4, 0xd1, 0xe9, 0x25, 0xa3, 0x66, 0xe3, 0xf0, 0xf4, 0xf5, 0x36, 0x4c, 0x8e,
0xfc, 0x46, 0x96, 0x25, 0x33, 0xcb, 0xc8, 0x2b, 0x32, 0xcb, 0xc8, 0xeb, 0x8c, 0x6c, 0x9d, 0xb6,
0xf0, 0xf1, 0x64, 0x38, 0x98, 0xa5, 0xa1, 0xd6, 0x3a, 0x95, 0xd7, 0x7d, 0x26, 0xb0, 0xb4, 0x4e,
0x0a, 0x20, 0xab, 0x6f, 0x79, 0xf9, 0x60, 0x94, 0xe3, 0xc6, 0xcf, 0x61, 0xb8, 0x02, 0x17, 0xd9,
0x7e, 0x64, 0xa3, 0x22, 0x5a, 0x94, 0x07, 0x39, 0xc6, 0xc6, 0x28, 0x99, 0xc0, 0x19, 0x25, 0x00,
0x60, 0x6f, 0x0d, 0xbd, 0xcd, 0x7a, 0x08, 0x9c, 0xde, 0x2f, 0x7f, 0x0d, 0xed, 0x9d, 0x11, 0x1a,
0xf7, 0xc7, 0x19, 0x9d, 0x2d, 0xd4, 0xfe, 0x67, 0xc0, 0x5a, 0x6f, 0xf3, 0xca, 0x7f, 0x5e, 0x2c,
0xf6, 0xbe, 0x7e, 0xb1, 0xd8, 0xfb, 0xdf, 0x8b, 0xc5, 0xde, 0x57, 0x2f, 0x17, 0x5f, 0xfb, 0xfa,
0xe5, 0xe2, 0x6b, 0xff, 0x7d, 0xb9, 0xf8, 0xda, 0x67, 0x6f, 0xc0, 0xaf, 0xb1, 0x8f, 0x5f, 0x2f,
0x7f, 0x53, 0x7d, 0xef, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc9, 0xf7, 0xef, 0xa6, 0xb1, 0x3d,
0x00, 0x00,
// 3040 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x9b, 0x5b, 0x73, 0xdc, 0xb6,
0xf5, 0xc0, 0xb3, 0x33, 0xff, 0x49, 0xf2, 0x47, 0x12, 0xc7, 0x61, 0xeb, 0xc4, 0x96, 0x53, 0xf9,
0x12, 0xcb, 0x17, 0xd9, 0xa2, 0x64, 0xb9, 0x4d, 0xa7, 0xd7, 0x8c, 0xb4, 0xb2, 0x65, 0x4d, 0x64,
0x5b, 0xd5, 0x4a, 0x56, 0x27, 0xbd, 0x52, 0x24, 0xbc, 0xcb, 0x88, 0x4b, 0x30, 0x24, 0x76, 0xe5,
0x6d, 0xa7, 0x9d, 0xde, 0xa6, 0x33, 0x7d, 0xf3, 0x4c, 0x1f, 0xfb, 0xd4, 0xd7, 0x7e, 0x92, 0x3e,
0xe6, 0xb1, 0x8f, 0x1d, 0xfb, 0x8b, 0x74, 0x40, 0x1c, 0x02, 0x04, 0x08, 0x80, 0x5c, 0x3f, 0x69,
0xc4, 0xf3, 0x3b, 0x17, 0x82, 0x07, 0x07, 0x07, 0x24, 0x16, 0x5d, 0xca, 0x8e, 0x57, 0xb3, 0x9c,
0x50, 0x52, 0xac, 0x16, 0x38, 0x9f, 0xc6, 0x21, 0xae, 0xfe, 0xfa, 0xe5, 0x65, 0xef, 0xad, 0x20,
0x9d, 0xd1, 0x59, 0x86, 0x17, 0xce, 0x4b, 0x32, 0x24, 0xe3, 0x71, 0x90, 0x46, 0x05, 0x47, 0x16,
0x3e, 0x94, 0x12, 0x3c, 0xc5, 0x29, 0x85, 0xeb, 0xeb, 0x2f, 0x7e, 0x8b, 0xce, 0xf4, 0x93, 0x18,
0xa7, 0xb4, 0x0f, 0x0a, 0x5e, 0x8e, 0xce, 0x3d, 0x39, 0xfe, 0x12, 0x87, 0x74, 0x23, 0x8a, 0x8e,
0x62, 0x3a, 0xe2, 0xff, 0xec, 0x44, 0xde, 0x6d, 0x1f, 0xfc, 0xf8, 0xfb, 0x59, 0xe8, 0xf3, 0xcb,
0xbe, 0x06, 0xf9, 0xfb, 0xf8, 0xab, 0x09, 0x2e, 0xe8, 0xc2, 0x9d, 0x6e, 0x70, 0x91, 0x91, 0xb4,
0xc0, 0xde, 0x33, 0xf4, 0x01, 0xbf, 0x38, 0x18, 0x05, 0x39, 0xde, 0x9c, 0xed, 0xc6, 0xe9, 0x89,
0x77, 0xc3, 0x64, 0xa2, 0x06, 0x08, 0x5f, 0x37, 0xdb, 0x41, 0xf0, 0x73, 0x84, 0xde, 0x3d, 0x0a,
0x92, 0x04, 0xd3, 0x7e, 0x8e, 0x03, 0x8a, 0xbd, 0xab, 0x8a, 0x26, 0x17, 0xf9, 0x5c, 0x26, 0xac,
0x7f, 0xe2, 0x64, 0xc0, 0xf0, 0x17, 0xe8, 0x3d, 0x2e, 0xd9, 0xc7, 0x21, 0x99, 0xe2, 0xdc, 0x33,
0x6a, 0x81, 0x50, 0x98, 0xbe, 0xe6, 0x86, 0x74, 0xdb, 0x7d, 0x92, 0x4e, 0x71, 0x4e, 0xcd, 0xb6,
0x41, 0xe8, 0xb6, 0x2d, 0x21, 0xb0, 0xfd, 0x6b, 0xf4, 0xfe, 0x11, 0xc9, 0x4f, 0x8a, 0x2c, 0x08,
0x31, 0x8c, 0xc9, 0x92, 0xaa, 0x58, 0x49, 0xf5, 0x61, 0xb9, 0xde, 0x86, 0x19, 0x3c, 0x0c, 0x70,
0x82, 0x43, 0x6a, 0xf5, 0xc0, 0xc5, 0xad, 0x1e, 0x04, 0x06, 0x1e, 0x12, 0xf4, 0x0d, 0x21, 0xdc,
0xc6, 0xb4, 0x3f, 0xc9, 0x73, 0x9c, 0x52, 0xef, 0x96, 0x45, 0x5d, 0x22, 0xc2, 0xd3, 0x72, 0x17,
0xd4, 0x70, 0x3f, 0xdb, 0x98, 0x6e, 0x24, 0x89, 0xf5, 0x7e, 0xb8, 0xb8, 0xf5, 0x7e, 0x04, 0x06,
0x1e, 0x7e, 0x8f, 0x2e, 0xd4, 0x46, 0x8c, 0xee, 0x14, 0x0f, 0xe3, 0xe1, 0x28, 0x89, 0x87, 0x23,
0x8a, 0x23, 0x6f, 0xd5, 0x3a, 0x28, 0x2a, 0x28, 0xbc, 0xae, 0x75, 0x57, 0x00, 0xff, 0xbf, 0x40,
0x67, 0x36, 0xc2, 0x90, 0x4c, 0x52, 0x91, 0xcc, 0x6a, 0x2e, 0x81, 0xb0, 0x91, 0xcd, 0x4b, 0x2d,
0x94, 0x4c, 0x67, 0x90, 0x41, 0xc2, 0x7d, 0x62, 0xd4, 0xd3, 0xd2, 0xed, 0x9a, 0x1b, 0x6a, 0xd8,
0x86, 0x54, 0x33, 0xdb, 0xd6, 0x12, 0xed, 0x9a, 0x1b, 0x02, 0xdb, 0x07, 0xe8, 0x9d, 0xca, 0x36,
0x25, 0x99, 0x77, 0xc5, 0xac, 0x44, 0x49, 0x26, 0xec, 0x5e, 0x75, 0x21, 0xd2, 0xea, 0x83, 0x38,
0xc1, 0x4f, 0x9e, 0x3d, 0x4b, 0x48, 0x10, 0x69, 0x56, 0x99, 0xc4, 0x07, 0x91, 0xc5, 0xaa, 0x86,
0xc8, 0x24, 0x65, 0x82, 0xdd, 0xb8, 0xa0, 0x95, 0xe5, 0xa5, 0x86, 0x1a, 0x93, 0x36, 0xac, 0x5f,
0x6f, 0xc3, 0xc0, 0xc3, 0x4f, 0x10, 0x7a, 0x8a, 0xf3, 0x22, 0x26, 0xe9, 0x36, 0xa6, 0xde, 0x65,
0x45, 0x0b, 0x04, 0x2c, 0xb1, 0x85, 0xdd, 0x2b, 0x0e, 0x02, 0x4c, 0x3e, 0x44, 0x6f, 0xed, 0x92,
0xe1, 0x00, 0xa7, 0x91, 0xf7, 0x2d, 0x85, 0xde, 0x25, 0x43, 0x9f, 0x5d, 0x16, 0xc6, 0x16, 0x6d,
0x62, 0xb0, 0xf4, 0x18, 0xfd, 0x7f, 0x9f, 0xa4, 0xcf, 0xe2, 0x21, 0x8b, 0xed, 0x92, 0x02, 0xf3,
0xeb, 0x4a, 0x68, 0x97, 0xed, 0x00, 0xd8, 0xdb, 0x41, 0x6f, 0x0f, 0x46, 0x13, 0x1a, 0x91, 0xd3,
0x54, 0x0b, 0xad, 0xba, 0x6c, 0x09, 0xad, 0x26, 0x96, 0x2b, 0xdd, 0xfd, 0xe7, 0x14, 0xe7, 0x69,
0x90, 0x6c, 0xe5, 0x24, 0x63, 0x03, 0x5c, 0x68, 0x2b, 0x5d, 0x5d, 0x5e, 0x3e, 0x81, 0xc2, 0xb2,
0xd2, 0x19, 0x41, 0x59, 0x14, 0xeb, 0xe2, 0x3e, 0x49, 0x69, 0xb3, 0x28, 0x2a, 0x06, 0x00, 0xb1,
0x14, 0x45, 0x0b, 0x0a, 0xde, 0xf6, 0xd1, 0x3b, 0x6c, 0xa1, 0xdd, 0xcb, 0xf1, 0x34, 0xc6, 0xa7,
0x5a, 0x3a, 0xd4, 0x24, 0x96, 0x74, 0x50, 0x09, 0xb0, 0xf9, 0x04, 0xa1, 0xc3, 0x8c, 0x25, 0x1d,
0xbb, 0x33, 0xed, 0x29, 0x4a, 0x81, 0xe5, 0x29, 0x2a, 0x00, 0x18, 0x3c, 0x44, 0xef, 0x6e, 0x91,
0xd3, 0x54, 0x98, 0x54, 0x63, 0xa8, 0x8b, 0x2c, 0x73, 0x4d, 0x43, 0xe4, 0x0c, 0xde, 0x4c, 0x48,
0x78, 0xc2, 0x5d, 0x6a, 0x56, 0x4b, 0x09, 0x44, 0x63, 0xb1, 0xaa, 0x21, 0xb2, 0x53, 0x29, 0x05,
0xfb, 0x38, 0x4b, 0x82, 0x50, 0xef, 0x54, 0xb8, 0x0e, 0xc8, 0x2c, 0x9d, 0x8a, 0xce, 0x80, 0xe1,
0x18, 0x79, 0x10, 0x6e, 0x14, 0x50, 0x5c, 0xe5, 0xc5, 0x4d, 0x63, 0x48, 0x35, 0x42, 0x38, 0xb9,
0xd5, 0x81, 0x94, 0xd3, 0xb0, 0x94, 0x3f, 0xc9, 0x70, 0xaa, 0x3d, 0x40, 0xae, 0xc7, 0x04, 0x96,
0x07, 0xa8, 0x00, 0x9a, 0xbd, 0xc1, 0x88, 0x9c, 0x1a, 0xed, 0x31, 0x81, 0xd3, 0x1e, 0x00, 0x60,
0x8f, 0xa0, 0x6f, 0x96, 0x97, 0xb7, 0x31, 0xdd, 0x9b, 0x1c, 0x27, 0x71, 0x78, 0x84, 0x8f, 0x0f,
0xf7, 0x77, 0xbd, 0x65, 0x83, 0xa6, 0xc6, 0x08, 0x2f, 0xb7, 0x3b, 0xb1, 0x9a, 0x43, 0x76, 0x5b,
0x9b, 0x39, 0x0e, 0xa2, 0x30, 0x9f, 0x8c, 0x8f, 0x0b, 0xa3, 0x43, 0x8d, 0x71, 0x3a, 0x6c, 0xb2,
0xb2, 0x0a, 0xf0, 0x11, 0xc3, 0xb4, 0xee, 0xcf, 0xf4, 0x0c, 0x55, 0xc4, 0x52, 0x05, 0x2c, 0xa8,
0x36, 0x13, 0x60, 0x5d, 0x37, 0xcd, 0x04, 0x6d, 0x55, 0xbf, 0xea, 0x42, 0xe4, 0x5a, 0x56, 0xb3,
0xba, 0x17, 0x0c, 0xf5, 0x16, 0xb5, 0xae, 0xc6, 0xc4, 0x96, 0xb5, 0xcc, 0x80, 0xc9, 0x86, 0xa7,
0xe6, 0x61, 0x80, 0xa9, 0xd6, 0xf0, 0xd4, 0x35, 0x07, 0xb5, 0x85, 0x63, 0xa9, 0x85, 0xd2, 0x0b,
0x44, 0x9a, 0xb0, 0x6d, 0x8d, 0xb1, 0x40, 0x94, 0x22, 0x77, 0x81, 0xa8, 0x10, 0xb9, 0x00, 0xf3,
0xa0, 0x13, 0x52, 0x60, 0xcf, 0x94, 0xec, 0xa5, 0xc4, 0x52, 0x71, 0x55, 0x42, 0x76, 0x4f, 0xe5,
0xf5, 0xaa, 0xce, 0x79, 0xa6, 0x82, 0x52, 0x09, 0x2d, 0xdd, 0x53, 0x03, 0x02, 0xdb, 0x3f, 0x07,
0xdb, 0xdb, 0x98, 0x3e, 0x0a, 0xf2, 0x93, 0xc2, 0x38, 0xc4, 0x6c, 0xd1, 0x2d, 0xa5, 0xce, 0x21,
0xae, 0x53, 0x5a, 0x65, 0x38, 0x4c, 0x23, 0x62, 0xac, 0x0c, 0x4c, 0xe0, 0xac, 0x0c, 0x00, 0x68,
0xf6, 0xf6, 0xb1, 0xc5, 0x1e, 0x13, 0x38, 0xed, 0x01, 0x00, 0xf6, 0x7e, 0x05, 0x19, 0x36, 0xc0,
0xf4, 0x41, 0x8c, 0x93, 0xa8, 0x30, 0xa6, 0x30, 0xcb, 0x1a, 0x2e, 0x76, 0xa6, 0xb0, 0x82, 0x81,
0x83, 0xaf, 0xa0, 0xb2, 0x0c, 0xd8, 0x0e, 0xb4, 0xa0, 0x79, 0x1c, 0xd2, 0x98, 0xa4, 0x85, 0x77,
0xdb, 0xa2, 0x5f, 0x87, 0x2c, 0x7b, 0x76, 0x2b, 0xac, 0x65, 0x0b, 0xeb, 0x0f, 0x1f, 0x91, 0x29,
0x36, 0x65, 0x4b, 0xd9, 0x3b, 0x32, 0xa1, 0x2b, 0x5b, 0xea, 0x10, 0xd8, 0x9e, 0xa0, 0x0f, 0x15,
0xdb, 0x07, 0xe4, 0x31, 0x3e, 0x2d, 0xa7, 0xfe, 0x1d, 0x87, 0xbe, 0xa0, 0x84, 0xb7, 0x95, 0x8e,
0x34, 0xb8, 0x7d, 0xd1, 0x43, 0x97, 0x04, 0x04, 0x7b, 0xe5, 0xfe, 0x28, 0x4e, 0xa2, 0x1c, 0xa7,
0x07, 0x84, 0xb1, 0x85, 0xf7, 0x1d, 0x8b, 0x49, 0x33, 0x2e, 0x22, 0xf9, 0x74, 0x5e, 0x35, 0x08,
0xe9, 0x04, 0x96, 0x6b, 0x06, 0xcb, 0xec, 0xb9, 0x65, 0xb1, 0x66, 0xc8, 0xa0, 0xe5, 0x2e, 0x28,
0x38, 0x9b, 0xa2, 0x73, 0x75, 0x67, 0x07, 0xf8, 0x39, 0x1d, 0xd0, 0x59, 0x82, 0xbd, 0x15, 0x87,
0x11, 0x46, 0xf9, 0x25, 0x26, 0x7c, 0xfa, 0x5d, 0x71, 0xad, 0x27, 0x61, 0xd0, 0xd6, 0x24, 0x4b,
0xe2, 0x90, 0xad, 0x1f, 0x37, 0x2d, 0x56, 0x04, 0xe1, 0xea, 0x49, 0x1a, 0x24, 0xb8, 0xfa, 0x6b,
0x0f, 0x5d, 0xac, 0xdf, 0xe3, 0x66, 0x10, 0x9e, 0x0c, 0x73, 0x32, 0x49, 0xa3, 0x3e, 0x49, 0x48,
0xee, 0xad, 0x3b, 0x42, 0xd7, 0x58, 0xe1, 0xfe, 0xde, 0x5c, 0x3a, 0x10, 0xc8, 0x08, 0x7d, 0x50,
0x8f, 0x63, 0x23, 0x89, 0x87, 0xa9, 0xf5, 0x96, 0x99, 0xa5, 0x92, 0x68, 0xbd, 0xe5, 0x3a, 0x09,
0x9e, 0x0a, 0xa8, 0x0d, 0xe0, 0x69, 0x2b, 0x9e, 0xf2, 0x87, 0x7a, 0xc7, 0x61, 0x62, 0x2b, 0x9e,
0x6a, 0xcf, 0x74, 0xa5, 0x23, 0x6d, 0x4e, 0x25, 0xd6, 0x32, 0xb7, 0xa7, 0x52, 0xd9, 0x58, 0x77,
0x4f, 0x25, 0x05, 0x97, 0xfb, 0x2b, 0x01, 0x1d, 0x4c, 0xf2, 0x74, 0x27, 0xa5, 0x44, 0xdb, 0x5f,
0x49, 0x23, 0x15, 0x60, 0xd9, 0x5f, 0x19, 0x41, 0xf0, 0xf3, 0x25, 0xf8, 0x19, 0x60, 0xba, 0x1b,
0x50, 0xfc, 0x9c, 0xa5, 0xb5, 0xad, 0xaf, 0xf2, 0x4b, 0x82, 0x67, 0x7e, 0x4b, 0x5f, 0xa5, 0xa2,
0xe0, 0x6b, 0x88, 0xce, 0x56, 0xbe, 0x98, 0xa0, 0x74, 0x75, 0xd3, 0xa2, 0x5f, 0x6a, 0x2a, 0x9e,
0x6e, 0x75, 0x20, 0x9b, 0x37, 0xc5, 0x04, 0x7c, 0x46, 0x38, 0xf5, 0xd5, 0x89, 0xb0, 0xdc, 0x05,
0xb5, 0xd7, 0x1a, 0xee, 0xaf, 0xb5, 0xd6, 0xa8, 0x3e, 0xfd, 0xae, 0xb8, 0x79, 0x36, 0x30, 0x84,
0x35, 0x13, 0xce, 0xd9, 0x50, 0xda, 0x61, 0x54, 0xa7, 0xd9, 0x50, 0xa7, 0xcd, 0x03, 0xcb, 0x67,
0x82, 0x73, 0x60, 0xd5, 0x59, 0xb0, 0xdc, 0x05, 0x05, 0x5f, 0x99, 0xec, 0xf9, 0xcb, 0x41, 0x1d,
0xe1, 0xf0, 0x04, 0x47, 0xd6, 0x4e, 0x80, 0x8f, 0x11, 0x87, 0x5a, 0x3b, 0x01, 0x0d, 0x36, 0xe7,
0xe7, 0x4e, 0x48, 0x52, 0x77, 0x7e, 0x32, 0xa2, 0x5b, 0x7e, 0x02, 0xa9, 0xf5, 0xbc, 0x83, 0x2c,
0x89, 0xa9, 0xb1, 0xe7, 0x2d, 0x25, 0xce, 0x9e, 0xb7, 0x22, 0x34, 0x93, 0x8f, 0x70, 0x3e, 0x34,
0xb7, 0xd1, 0xa5, 0xc4, 0x69, 0xb2, 0x22, 0xb4, 0xe6, 0xb1, 0x4f, 0xb2, 0x99, 0xb1, 0x79, 0x64,
0x02, 0x67, 0xf3, 0x08, 0x80, 0x16, 0xe2, 0x5e, 0x50, 0x50, 0x73, 0x88, 0xa5, 0xc4, 0x19, 0x62,
0x45, 0x80, 0xc9, 0xcf, 0xd1, 0xdb, 0x3c, 0xc4, 0x09, 0xf5, 0x16, 0x4d, 0x01, 0x4c, 0xe4, 0x20,
0x5e, 0xb2, 0xca, 0xb5, 0xfd, 0xcd, 0xfd, 0xe7, 0x19, 0xc9, 0xa9, 0x71, 0x7f, 0xc3, 0x45, 0xce,
0xfd, 0x8d, 0x40, 0xb4, 0xad, 0xeb, 0xce, 0x98, 0x5d, 0x67, 0xd3, 0xa9, 0x7c, 0xfd, 0x66, 0xca,
0x16, 0x15, 0x71, 0x4e, 0x9a, 0x06, 0xda, 0x4c, 0x61, 0xb6, 0xaa, 0x3c, 0x0e, 0xc6, 0xd8, 0x9a,
0xc2, 0xe5, 0xb2, 0xc3, 0x88, 0xd6, 0x14, 0xae, 0x93, 0xcd, 0x4a, 0xb0, 0x33, 0x0e, 0x86, 0xdc,
0x93, 0x4d, 0xbf, 0x24, 0x54, 0x57, 0xcb, 0x5d, 0x50, 0xf0, 0x35, 0x86, 0xb6, 0xaa, 0xf2, 0x75,
0x14, 0x47, 0x74, 0xe4, 0xb9, 0x2d, 0x94, 0x8c, 0xf3, 0x65, 0x43, 0x93, 0x6d, 0xde, 0xda, 0xd3,
0x38, 0xc2, 0xc4, 0x79, 0x6b, 0x25, 0xd1, 0xed, 0xd6, 0x14, 0xb4, 0x79, 0x6b, 0xa5, 0xd8, 0x7d,
0x6b, 0xdc, 0x42, 0xb7, 0x5b, 0x53, 0x59, 0x70, 0xf7, 0xa7, 0x1e, 0xba, 0x20, 0x96, 0xfb, 0x38,
0x3d, 0x39, 0x08, 0xf2, 0x21, 0xa6, 0x3c, 0x3f, 0x23, 0xef, 0xae, 0x6d, 0x2d, 0x67, 0x1b, 0x76,
0x05, 0x15, 0xde, 0xd7, 0xe7, 0x51, 0xd1, 0xb6, 0x02, 0x9b, 0x84, 0x9c, 0x8c, 0x83, 0xfc, 0xe4,
0x01, 0xa6, 0xe1, 0xc8, 0x38, 0xc0, 0x15, 0xe1, 0x97, 0x88, 0x73, 0x80, 0x1b, 0xa8, 0xde, 0x27,
0x57, 0x00, 0x7f, 0xb1, 0xb1, 0x91, 0x46, 0xdc, 0xed, 0xba, 0xcb, 0x96, 0xca, 0xba, 0xfa, 0x64,
0x87, 0x0e, 0x04, 0xf2, 0x3b, 0x74, 0xbe, 0x24, 0xd9, 0x5c, 0x12, 0x0c, 0xbc, 0x6b, 0x5d, 0x35,
0x18, 0x2c, 0xe7, 0x9c, 0x06, 0x5a, 0x3e, 0x86, 0x39, 0x15, 0xc0, 0x7d, 0x0a, 0x65, 0x68, 0x1f,
0x27, 0x01, 0xdb, 0x00, 0x0f, 0x30, 0xfd, 0x1c, 0xcf, 0x8c, 0x99, 0x56, 0x21, 0x3e, 0x67, 0x9c,
0x99, 0xd6, 0x64, 0xc1, 0x1f, 0x86, 0x42, 0x54, 0x01, 0x1b, 0x51, 0x64, 0x6a, 0x5f, 0xa5, 0x81,
0x8d, 0x28, 0x72, 0xb5, 0xaf, 0x3a, 0x08, 0x6e, 0x7e, 0x83, 0x3e, 0xe2, 0xaf, 0x7a, 0x02, 0x1a,
0x4c, 0x63, 0x7c, 0xfa, 0x34, 0xc6, 0xa7, 0xf0, 0xda, 0xce, 0x37, 0xbd, 0xcf, 0x01, 0xcc, 0x97,
0x9c, 0x70, 0xba, 0xda, 0x99, 0x77, 0xf8, 0xde, 0xc2, 0x09, 0xee, 0xe2, 0x9b, 0x73, 0xdd, 0x7d,
0x0b, 0xde, 0xe1, 0x9b, 0xbf, 0xbd, 0x6e, 0xf7, 0xcd, 0xb9, 0xee, 0xbe, 0x05, 0x0f, 0xbe, 0xff,
0xdc, 0x43, 0x0b, 0x0d, 0xe7, 0x6c, 0xeb, 0x17, 0xd2, 0x78, 0x8a, 0x8d, 0x55, 0x44, 0xb1, 0x27,
0x50, 0x67, 0x15, 0xb1, 0xaa, 0x40, 0x14, 0x7f, 0xeb, 0xa1, 0x8f, 0x4d, 0x51, 0xec, 0x91, 0x22,
0x66, 0x79, 0xe2, 0xdd, 0xeb, 0x60, 0xb4, 0x82, 0x45, 0x24, 0xdf, 0x9e, 0x4f, 0x09, 0x62, 0x39,
0x85, 0xd7, 0x3c, 0x15, 0x39, 0xc0, 0x74, 0x40, 0x26, 0x79, 0x68, 0xdc, 0x25, 0x4a, 0x7b, 0x02,
0x73, 0x6d, 0x02, 0xcc, 0xb8, 0x56, 0x54, 0x2a, 0xa6, 0x3e, 0xdb, 0x9c, 0xcf, 0xb5, 0x06, 0x3a,
0x8b, 0x8a, 0x45, 0x41, 0x2f, 0xae, 0xba, 0x7f, 0x48, 0xc5, 0xf5, 0x2e, 0x16, 0xb5, 0x74, 0xbc,
0x37, 0x97, 0x4e, 0x5b, 0x20, 0x30, 0x1f, 0x3b, 0x05, 0xa2, 0xcd, 0xc9, 0x7b, 0x73, 0xe9, 0x40,
0x20, 0xff, 0xe8, 0xa1, 0xab, 0xc6, 0x40, 0xd8, 0xae, 0x6a, 0x63, 0x1a, 0xc4, 0x49, 0x70, 0x9c,
0x60, 0xef, 0x7b, 0x5d, 0x6c, 0x2b, 0x2a, 0x22, 0xac, 0xef, 0xbf, 0x8e, 0x2a, 0x44, 0xf7, 0x87,
0x6a, 0xf9, 0x97, 0xd1, 0x85, 0x24, 0x8f, 0xa0, 0x60, 0xb6, 0x3c, 0x7f, 0x49, 0x8a, 0x58, 0xee,
0xce, 0xa1, 0x01, 0x21, 0xfc, 0xb3, 0x87, 0xae, 0x19, 0x42, 0xa8, 0x02, 0x7f, 0x92, 0x55, 0xe9,
0xfb, 0x83, 0x76, 0xdb, 0x0d, 0x25, 0x11, 0xd8, 0x0f, 0x5f, 0x4f, 0x19, 0x62, 0xfc, 0x57, 0x0f,
0xdd, 0x68, 0x8d, 0x11, 0x52, 0xfc, 0xc7, 0xf3, 0x7a, 0xd2, 0xd2, 0xfd, 0xb3, 0xd7, 0xd6, 0x9f,
0x27, 0x58, 0x98, 0x06, 0x73, 0x07, 0xab, 0x4d, 0x89, 0xcf, 0x5e, 0x5b, 0x5f, 0x6b, 0xfd, 0xf8,
0xd9, 0xb6, 0x83, 0x59, 0x56, 0x7e, 0xa5, 0x32, 0xb5, 0x7e, 0x92, 0xf0, 0xeb, 0x9f, 0xaa, 0x96,
0xbb, 0xa0, 0xe0, 0x2c, 0x47, 0xe7, 0x1e, 0x07, 0xd3, 0x78, 0x28, 0x66, 0x04, 0x07, 0xf5, 0x8f,
0x09, 0x92, 0xf1, 0x6b, 0x90, 0xe5, 0x15, 0x82, 0x15, 0x06, 0x9f, 0x7f, 0xef, 0xa1, 0xcb, 0x92,
0xd9, 0xc6, 0x40, 0xec, 0xa4, 0xcf, 0xc8, 0x51, 0x4c, 0x47, 0xac, 0x2d, 0x2e, 0xbc, 0x4f, 0x6d,
0x26, 0xcd, 0xbc, 0x08, 0xe5, 0xbb, 0x73, 0xeb, 0xc9, 0x9d, 0x2d, 0x97, 0x6f, 0xe7, 0x41, 0x36,
0xd2, 0x76, 0xb6, 0x70, 0xce, 0xb0, 0x14, 0x59, 0x76, 0xb6, 0x1a, 0x22, 0x3f, 0xed, 0xc3, 0x61,
0x47, 0x1c, 0xe4, 0xe1, 0xc8, 0x33, 0xea, 0x70, 0x99, 0xe5, 0xd3, 0xbe, 0xce, 0xc8, 0x07, 0x57,
0x37, 0x3c, 0x98, 0x1c, 0x17, 0x61, 0x1e, 0x1f, 0x63, 0xf3, 0xc9, 0x4d, 0x0d, 0x72, 0x9f, 0xdc,
0x6c, 0xc2, 0xf2, 0xd5, 0x7d, 0x75, 0x9c, 0xb3, 0x90, 0x0e, 0x8d, 0x27, 0x32, 0xeb, 0x84, 0x65,
0xeb, 0x6c, 0x26, 0xc1, 0xd5, 0x73, 0xf4, 0x51, 0xfd, 0xf6, 0x0e, 0xd3, 0x42, 0xf8, 0x5b, 0xb1,
0xc7, 0x5c, 0xc3, 0x2c, 0xed, 0x82, 0x03, 0xd7, 0x8f, 0xa7, 0xda, 0xbb, 0x72, 0x30, 0x62, 0xea,
0x0f, 0x6e, 0xb6, 0x83, 0xf2, 0x7c, 0x80, 0xea, 0x07, 0x8a, 0xe5, 0xb2, 0xcb, 0x82, 0x56, 0x18,
0x6f, 0x77, 0x62, 0x6d, 0x0e, 0xa1, 0xe0, 0x39, 0x1d, 0x6a, 0xc5, 0xed, 0x76, 0x27, 0x56, 0x7f,
0x86, 0xcd, 0x85, 0x6b, 0xc5, 0x65, 0xa7, 0xb9, 0x54, 0xf9, 0x5d, 0x71, 0xf0, 0xfc, 0xc7, 0x1e,
0x5a, 0x30, 0xb9, 0x86, 0x21, 0x5e, 0x6b, 0x37, 0xa7, 0x0d, 0xf4, 0xdd, 0x39, 0x34, 0x5a, 0x62,
0x80, 0x51, 0xef, 0x10, 0x83, 0x36, 0xf6, 0x77, 0xe7, 0xd0, 0x80, 0x18, 0xfe, 0xd2, 0x43, 0x17,
0xd5, 0x18, 0xd4, 0x16, 0xcb, 0x69, 0xd2, 0xdc, 0x5a, 0xad, 0xcf, 0xa3, 0x22, 0x4f, 0x75, 0x54,
0x93, 0x99, 0xee, 0x06, 0x33, 0x32, 0xd1, 0x8f, 0x05, 0x8b, 0x59, 0x09, 0x62, 0xcb, 0x27, 0x71,
0x03, 0x56, 0x6b, 0xda, 0xb8, 0xf4, 0x01, 0x0e, 0xe8, 0x24, 0xc7, 0x51, 0x7d, 0xf6, 0x1a, 0xc7,
0x5a, 0x07, 0x95, 0xcd, 0xf5, 0xdd, 0x39, 0x34, 0x6a, 0x7b, 0x2d, 0x73, 0x08, 0xfb, 0x78, 0x4c,
0xa6, 0x58, 0xdb, 0x6b, 0xd9, 0x6c, 0x72, 0xd8, 0xb2, 0xd7, 0x6a, 0x55, 0x92, 0xef, 0x53, 0xc5,
0x80, 0xef, 0x14, 0x0f, 0x82, 0x29, 0xc9, 0x63, 0xaa, 0xbf, 0x9f, 0x93, 0xa3, 0x29, 0x11, 0x4b,
0x0f, 0x61, 0x41, 0x8d, 0xde, 0x36, 0xf2, 0x70, 0x14, 0x4f, 0x71, 0xe4, 0xf0, 0x56, 0x21, 0x1d,
0xbc, 0xd5, 0x50, 0x7d, 0x9d, 0x3e, 0x20, 0xac, 0x2f, 0x32, 0xae, 0xd3, 0xa5, 0xc8, 0xbd, 0x4e,
0x57, 0x08, 0x58, 0x0d, 0xd1, 0x59, 0x2e, 0x28, 0x3f, 0x4b, 0xf3, 0x29, 0x6a, 0x4a, 0x3e, 0xfe,
0xa9, 0x59, 0x9d, 0x98, 0x37, 0x5a, 0x39, 0xf9, 0x42, 0x42, 0x4a, 0xd5, 0xc1, 0xf2, 0x6d, 0x36,
0xca, 0x37, 0xb0, 0xcd, 0x11, 0x5b, 0xed, 0xcc, 0x5b, 0x7d, 0x8b, 0xb4, 0x68, 0xf1, 0xdd, 0xc8,
0x8d, 0xd5, 0xce, 0x3c, 0xf8, 0x3e, 0x86, 0x53, 0x5d, 0x03, 0x4c, 0xb7, 0x30, 0x0d, 0xe2, 0xa4,
0xf0, 0x6c, 0x67, 0x5d, 0x40, 0x6e, 0x19, 0x5b, 0x13, 0x27, 0x3f, 0x9c, 0xec, 0x05, 0xc3, 0xea,
0x77, 0x0d, 0xea, 0x87, 0x93, 0xf2, 0xe0, 0x87, 0xb6, 0x2d, 0xbb, 0xe2, 0x20, 0xe4, 0xb7, 0x9d,
0x81, 0xf8, 0xf5, 0x88, 0xfa, 0x65, 0x64, 0xd0, 0xfc, 0xe9, 0xc8, 0x65, 0x3b, 0x20, 0x17, 0xe0,
0x47, 0x98, 0xe6, 0x71, 0x58, 0x0c, 0x30, 0xdd, 0x0b, 0xf2, 0x60, 0x8c, 0x29, 0xce, 0xf5, 0x13,
0x81, 0x80, 0xf8, 0x0a, 0x63, 0x59, 0x80, 0x6d, 0xac, 0x9e, 0xd4, 0xac, 0xef, 0x87, 0xfb, 0x30,
0x25, 0x75, 0xb9, 0x2d, 0xd0, 0x6e, 0xe7, 0x46, 0x2b, 0x27, 0x0f, 0xd4, 0x49, 0x29, 0x4b, 0x03,
0xed, 0xb4, 0x57, 0x4d, 0xb5, 0x4c, 0x12, 0xf3, 0x69, 0xaf, 0x26, 0x25, 0x5f, 0x1b, 0x49, 0x59,
0x7d, 0x9d, 0x31, 0xf6, 0x10, 0xa5, 0x01, 0x51, 0x16, 0x15, 0x7f, 0x7e, 0x57, 0x1c, 0x1c, 0xd3,
0xaa, 0xc1, 0xae, 0x3b, 0x66, 0xab, 0xc9, 0x9d, 0x56, 0x43, 0xf5, 0x95, 0x64, 0xa5, 0x23, 0x2d,
0x5f, 0x56, 0x35, 0xbd, 0x42, 0xdb, 0xb2, 0xda, 0x6a, 0x4a, 0xeb, 0x5a, 0xd6, 0xba, 0x2b, 0xb8,
0xdc, 0xc3, 0xfa, 0xd5, 0xee, 0x5e, 0x5b, 0xbb, 0xd6, 0xba, 0x2b, 0x80, 0xfb, 0x1f, 0xa1, 0xff,
0xdb, 0x8b, 0xd3, 0xa1, 0x77, 0x41, 0x9d, 0x9c, 0x71, 0x3a, 0x14, 0x46, 0x17, 0x4c, 0x22, 0x79,
0x4a, 0x6d, 0x2f, 0x27, 0x21, 0x2e, 0x8a, 0x7e, 0x90, 0x86, 0x38, 0xd1, 0x4e, 0xa9, 0x81, 0xcc,
0xe7, 0x42, 0xcb, 0x29, 0xb5, 0x06, 0x24, 0x97, 0x9d, 0x87, 0x71, 0x41, 0x49, 0x3e, 0x2b, 0x4f,
0x24, 0xab, 0xe5, 0x03, 0x24, 0xea, 0x99, 0xe4, 0xab, 0x2e, 0x44, 0x76, 0x46, 0x20, 0x80, 0x5f,
0x49, 0xe8, 0x87, 0x05, 0x2b, 0xb5, 0x4a, 0x6c, 0xe9, 0x8c, 0x0c, 0x98, 0xdc, 0xce, 0x54, 0x71,
0x63, 0x0a, 0x62, 0x6d, 0x3b, 0x23, 0x42, 0x13, 0x80, 0x65, 0x3b, 0x63, 0x04, 0xc1, 0x4f, 0x1f,
0xbd, 0x09, 0xdf, 0x84, 0x2f, 0x6a, 0xbf, 0x25, 0x50, 0xbe, 0x06, 0x7f, 0x6c, 0x16, 0x82, 0x91,
0x5f, 0xa2, 0xf7, 0xf9, 0x25, 0xf1, 0xd3, 0x25, 0xad, 0x98, 0x68, 0x52, 0x4b, 0x31, 0x69, 0x52,
0xba, 0xfd, 0x03, 0x3c, 0xce, 0x92, 0x80, 0xe2, 0xc2, 0x68, 0x5f, 0x48, 0x9d, 0xf6, 0xeb, 0x14,
0xd8, 0x0f, 0xd0, 0x59, 0x2e, 0xdb, 0x25, 0x61, 0x90, 0xb0, 0xc1, 0xd2, 0xcf, 0x2f, 0xeb, 0x62,
0xcb, 0xf3, 0x34, 0x60, 0xf2, 0x87, 0x0d, 0x8f, 0x82, 0x13, 0x5c, 0x39, 0xd7, 0x12, 0xb1, 0x2e,
0xb2, 0x24, 0xa2, 0x86, 0x80, 0xd9, 0x19, 0x3a, 0x5f, 0x17, 0x6c, 0xce, 0xe4, 0x74, 0xd5, 0x0a,
0xad, 0x0d, 0xb3, 0x14, 0x5a, 0x07, 0x0e, 0xae, 0x7f, 0x8a, 0xde, 0xeb, 0x27, 0x24, 0x95, 0xb7,
0xa4, 0xc6, 0xab, 0xc8, 0x2c, 0xef, 0x48, 0x74, 0x46, 0x3e, 0x6e, 0xee, 0x50, 0x9e, 0x33, 0x34,
0xad, 0x4d, 0xcd, 0x33, 0x86, 0x4b, 0x2d, 0x14, 0xd8, 0xff, 0x19, 0x3a, 0x73, 0x98, 0x16, 0x59,
0x12, 0x14, 0x23, 0x78, 0xbd, 0xa3, 0x86, 0xa5, 0x0a, 0x2d, 0x05, 0xa7, 0x01, 0xc9, 0x5c, 0xaa,
0x44, 0xe2, 0x8c, 0xf6, 0x92, 0x51, 0xb3, 0x71, 0x4a, 0xfb, 0x7a, 0x1b, 0x26, 0x47, 0x7e, 0x23,
0xcb, 0x92, 0x99, 0x65, 0xe4, 0x15, 0x99, 0x65, 0xe4, 0x75, 0x46, 0xb6, 0x4e, 0x5b, 0xf8, 0x78,
0x32, 0x1c, 0xcc, 0xd2, 0x50, 0x6b, 0x9d, 0xca, 0xeb, 0x3e, 0x13, 0x58, 0x5a, 0x27, 0x05, 0x90,
0xd5, 0xb7, 0xbc, 0x7c, 0x30, 0xca, 0x71, 0xe3, 0x77, 0x37, 0x5c, 0x81, 0x8b, 0x6c, 0xbf, 0xe6,
0x51, 0x11, 0x2d, 0xca, 0x83, 0x1c, 0x63, 0x63, 0x94, 0x4c, 0xe0, 0x8c, 0x12, 0x00, 0xb0, 0xb7,
0x86, 0xde, 0x65, 0x3d, 0x04, 0x4e, 0xef, 0x97, 0x3f, 0xbb, 0xf6, 0xce, 0x08, 0x8d, 0xfb, 0xe3,
0x8c, 0xce, 0x16, 0x6a, 0xff, 0x33, 0x60, 0xad, 0xb7, 0x79, 0xe5, 0xdf, 0x2f, 0x17, 0x7b, 0x5f,
0xbf, 0x5c, 0xec, 0xfd, 0xf7, 0xe5, 0x62, 0xef, 0xc5, 0xab, 0xc5, 0x37, 0xbe, 0x7e, 0xb5, 0xf8,
0xc6, 0x7f, 0x5e, 0x2d, 0xbe, 0xf1, 0xc5, 0x5b, 0xf0, 0xb3, 0xef, 0xe3, 0x37, 0xcb, 0x1f, 0x6f,
0xdf, 0xfb, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc6, 0xf6, 0x17, 0x7b, 0x1a, 0x3e, 0x00, 0x00,
}
// This is a compile-time assertion to ensure that this generated file
@ -287,6 +287,7 @@ type ClientCommandsHandler interface {
BlockListSetTextMark(*pb.RpcBlockListSetTextMarkRequest) *pb.RpcBlockListSetTextMarkResponse
BlockSetTextStyle(*pb.RpcBlockSetTextStyleRequest) *pb.RpcBlockSetTextStyleResponse
BlockSetTextChecked(*pb.RpcBlockSetTextCheckedRequest) *pb.RpcBlockSetTextCheckedResponse
BlockSetTextIcon(*pb.RpcBlockSetTextIconRequest) *pb.RpcBlockSetTextIconResponse
BlockSplit(*pb.RpcBlockSplitRequest) *pb.RpcBlockSplitResponse
BlockMerge(*pb.RpcBlockMergeRequest) *pb.RpcBlockMergeResponse
BlockCopy(*pb.RpcBlockCopyRequest) *pb.RpcBlockCopyResponse
@ -1636,6 +1637,26 @@ func BlockSetTextChecked(b []byte) (resp []byte) {
return resp
}
func BlockSetTextIcon(b []byte) (resp []byte) {
defer func() {
if PanicHandler != nil {
if r := recover(); r != nil {
resp, _ = (&pb.RpcBlockSetTextIconResponse{Error: &pb.RpcBlockSetTextIconResponseError{Code: pb.RpcBlockSetTextIconResponseError_UNKNOWN_ERROR, Description: "panic recovered"}}).Marshal()
PanicHandler(r)
}
}
}()
in := new(pb.RpcBlockSetTextIconRequest)
if err := in.Unmarshal(b); err != nil {
resp, _ = (&pb.RpcBlockSetTextIconResponse{Error: &pb.RpcBlockSetTextIconResponseError{Code: pb.RpcBlockSetTextIconResponseError_BAD_INPUT, Description: err.Error()}}).Marshal()
return resp
}
resp, _ = clientCommandsHandler.BlockSetTextIcon(in).Marshal()
return resp
}
func BlockSplit(b []byte) (resp []byte) {
defer func() {
if PanicHandler != nil {
@ -3466,6 +3487,8 @@ func CommandAsync(cmd string, data []byte, callback func(data []byte)) {
cd = BlockSetTextStyle(data)
case "BlockSetTextChecked":
cd = BlockSetTextChecked(data)
case "BlockSetTextIcon":
cd = BlockSetTextIcon(data)
case "BlockSplit":
cd = BlockSplit(data)
case "BlockMerge":

View file

@ -1,6 +1,7 @@
package main
import (
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/core/debug"
"github.com/anytypeio/go-anytype-middleware/core/event"
@ -33,13 +34,12 @@ var dumpTree = &cobra.Command{
console.Fatal("please specify thread")
}
comps, err := anytype.BootstrapConfigAndWallet(false, debugRepoPath, debugAccount)
if err != nil {
console.Fatal("failed to bootstrap anytype: %s", err.Error())
comps := []app.Component{
anytype.BootstrapConfig(false, false),
anytype.BootstrapWallet(debugRepoPath, debugAccount),
event.NewCallbackSender(func(event *pb.Event) {}),
}
comps = append(comps, event.NewCallbackSender(func(event *pb.Event) {}))
app, err := anytype.StartNewApp(comps...)
if err != nil {
console.Fatal("failed to start anytype: %s", err.Error())
@ -62,13 +62,12 @@ var dumpLocalstore = &cobra.Command{
console.Fatal("please specify account")
}
comps, err := anytype.BootstrapConfigAndWallet(false, debugRepoPath, debugAccount)
if err != nil {
console.Fatal("failed to bootstrap anytype: %s", err.Error())
comps := []app.Component{
anytype.BootstrapConfig(false, false),
anytype.BootstrapWallet(debugRepoPath, debugAccount),
event.NewCallbackSender(func(event *pb.Event) {}),
}
comps = append(comps, event.NewCallbackSender(func(event *pb.Event) {}))
app, err := anytype.StartNewApp(comps...)
if err != nil {
console.Fatal("failed to start anytype: %s", err.Error())

View file

@ -7,14 +7,19 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/url"
"os"
"path/filepath"
"strings"
"sync"
"syscall"
"time"
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/core/anytype"
"github.com/anytypeio/go-anytype-middleware/core/anytype/config"
"github.com/anytypeio/go-anytype-middleware/core/block"
"github.com/anytypeio/go-anytype-middleware/core/configfetcher"
"github.com/anytypeio/go-anytype-middleware/metrics"
@ -26,9 +31,6 @@ import (
"github.com/anytypeio/go-anytype-middleware/util/pbtypes"
)
const defaultCafeUrl = "https://cafe1.anytype.io"
const defaultCafePeerId = "12D3KooWKwPC165PptjnzYzGrEs7NSjsF5vvMmxmuqpA2VfaBbLw"
// we cannot check the constant error from badger because they hardcoded it there
const errSubstringMultipleAnytypeInstance = "Cannot acquire directory lock"
@ -45,9 +47,9 @@ type AlphaInviteErrorResponse struct {
Error string `json:"error"`
}
func checkInviteCode(code string, account string) error {
func checkInviteCode(cfg *config.Config, code string, account string) (errorCode pb.RpcAccountCreateResponseErrorCode, err error) {
if code == "" {
return fmt.Errorf("invite code is empty")
return pb.RpcAccountCreateResponseError_BAD_INPUT, fmt.Errorf("invite code is empty")
}
jsonStr, err := json.Marshal(AlphaInviteRequest{
@ -57,54 +59,95 @@ func checkInviteCode(code string, account string) error {
// TODO: here we always using the default cafe address, because we want to check invite code only on our server
// this code should be removed with a public release
req, err := http.NewRequest("POST", defaultCafeUrl+"/alpha-invite", bytes.NewBuffer(jsonStr))
req, err := http.NewRequest("POST", cfg.CafeUrl()+"/alpha-invite", bytes.NewBuffer(jsonStr))
req.Header.Set("Content-Type", "application/json")
checkNetError := func(err error) (netOpError bool, dnsError bool, offline bool) {
if err == nil {
return false, false, false
}
if netErr, ok := err.(*net.OpError); ok {
if syscallErr, ok := netErr.Err.(*os.SyscallError); ok {
if syscallErr.Err == syscall.ENETDOWN || syscallErr.Err == syscall.ENETUNREACH {
return true, false, true
}
}
if _, ok := netErr.Err.(*net.DNSError); ok {
return true, true, false
}
return true, false, false
}
return false, false, false
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("failed to access cafe server: %s", err.Error())
var netOpErr, dnsError bool
if urlErr, ok := err.(*url.Error); ok {
var offline bool
if netOpErr, dnsError, offline = checkNetError(urlErr.Err); offline {
return pb.RpcAccountCreateResponseError_NET_OFFLINE, err
}
}
if dnsError {
// we can receive DNS error in case device is offline, lets check the SHOULD-BE-ALWAYS-ONLINE OpenDNS IP address on the 80 port
c, err2 := net.DialTimeout("tcp", "1.1.1.1:80", time.Second*5)
if c != nil {
_ = c.Close()
}
_, _, offline := checkNetError(err2)
if offline {
return pb.RpcAccountCreateResponseError_NET_OFFLINE, err
}
}
if netOpErr {
return pb.RpcAccountCreateResponseError_NET_CONNECTION_REFUSED, err
}
return pb.RpcAccountCreateResponseError_NET_ERROR, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read response body: %s", err.Error())
return pb.RpcAccountCreateResponseError_NET_ERROR, fmt.Errorf("failed to read response body: %s", err.Error())
}
if resp.StatusCode != 200 {
respJson := AlphaInviteErrorResponse{}
err = json.Unmarshal(body, &respJson)
return fmt.Errorf(respJson.Error)
return pb.RpcAccountCreateResponseError_BAD_INVITE_CODE, fmt.Errorf(respJson.Error)
}
respJson := AlphaInviteResponse{}
err = json.Unmarshal(body, &respJson)
if err != nil {
return fmt.Errorf("failed to decode response json: %s", err.Error())
return pb.RpcAccountCreateResponseError_UNKNOWN_ERROR, fmt.Errorf("failed to decode response json: %s", err.Error())
}
pubk, err := wallet.NewPubKeyFromAddress(wallet.KeypairTypeDevice, defaultCafePeerId)
pubk, err := wallet.NewPubKeyFromAddress(wallet.KeypairTypeDevice, cfg.CafePeerId)
if err != nil {
return fmt.Errorf("failed to decode cafe pubkey: %s", err.Error())
return pb.RpcAccountCreateResponseError_UNKNOWN_ERROR, fmt.Errorf("failed to decode cafe pubkey: %s", err.Error())
}
signature, err := base64.RawStdEncoding.DecodeString(respJson.Signature)
if err != nil {
return fmt.Errorf("failed to decode cafe signature: %s", err.Error())
return pb.RpcAccountCreateResponseError_UNKNOWN_ERROR, fmt.Errorf("failed to decode cafe signature: %s", err.Error())
}
valid, err := pubk.Verify([]byte(code+account), signature)
if err != nil {
return fmt.Errorf("failed to verify cafe signature: %s", err.Error())
return pb.RpcAccountCreateResponseError_UNKNOWN_ERROR, fmt.Errorf("failed to verify cafe signature: %s", err.Error())
}
if !valid {
return fmt.Errorf("invalid signature")
return pb.RpcAccountCreateResponseError_UNKNOWN_ERROR, fmt.Errorf("invalid signature")
}
return nil
return pb.RpcAccountCreateResponseError_NULL, nil
}
func (mw *Middleware) getAccountConfig() *pb.RpcAccountConfig {
@ -143,6 +186,7 @@ func (mw *Middleware) AccountCreate(req *pb.RpcAccountCreateRequest) *pb.RpcAcco
response(nil, pb.RpcAccountCreateResponseError_FAILED_TO_STOP_RUNNING_NODE, err)
}
cfg := anytype.BootstrapConfig(true, os.Getenv("ANYTYPE_STAGING") == "1")
index := len(mw.foundAccounts)
var account wallet.Keypair
for {
@ -162,8 +206,8 @@ func (mw *Middleware) AccountCreate(req *pb.RpcAccountCreateRequest) *pb.RpcAcco
continue
}
if err := checkInviteCode(req.AlphaInviteCode, account.Address()); err != nil {
return response(nil, pb.RpcAccountCreateResponseError_BAD_INVITE_CODE, err)
if code, err := checkInviteCode(cfg, req.AlphaInviteCode, account.Address()); err != nil {
return response(nil, code, err)
}
seedRaw, err := account.Raw()
@ -177,13 +221,12 @@ func (mw *Middleware) AccountCreate(req *pb.RpcAccountCreateRequest) *pb.RpcAcco
newAcc := &model.Account{Id: account.Address()}
comps, err := anytype.BootstrapConfigAndWallet(true, mw.rootPath, account.Address())
if err != nil {
return response(nil, pb.RpcAccountCreateResponseError_UNKNOWN_ERROR, err)
comps := []app.Component{
cfg,
anytype.BootstrapWallet(mw.rootPath, account.Address()),
mw.EventSender,
}
comps = append(comps, mw.EventSender)
if mw.app, err = anytype.StartNewApp(comps...); err != nil {
return response(newAcc, pb.RpcAccountCreateResponseError_ACCOUNT_CREATED_BUT_FAILED_TO_START_NODE, err)
}
@ -217,11 +260,6 @@ func (mw *Middleware) AccountCreate(req *pb.RpcAccountCreateRequest) *pb.RpcAcco
Value: pbtypes.String(hash),
})
}
} else if req.GetAvatarColor() != "" {
details = append(details, &pb.RpcBlockSetDetailsDetail{
Key: "iconColor",
Value: pbtypes.String(req.GetAvatarColor()),
})
}
if err = bs.SetDetails(nil, pb.RpcBlockSetDetailsRequest{
@ -468,12 +506,13 @@ func (mw *Middleware) AccountSelect(req *pb.RpcAccountSelectRequest) *pb.RpcAcco
}
}
comps, err := anytype.BootstrapConfigAndWallet(false, mw.rootPath, req.Id)
if err != nil {
return response(nil, pb.RpcAccountSelectResponseError_UNKNOWN_ERROR, err)
comps := []app.Component{
anytype.BootstrapConfig(false, os.Getenv("ANYTYPE_STAGING") == "1"),
anytype.BootstrapWallet(mw.rootPath, req.Id),
mw.EventSender,
}
var err error
comps = append(comps, mw.EventSender)
if mw.app, err = anytype.StartNewApp(comps...); err != nil {
if err == core.ErrRepoCorrupted {
return response(nil, pb.RpcAccountSelectResponseError_LOCAL_REPO_EXISTS_BUT_CORRUPTED, err)

View file

@ -1,6 +1,8 @@
package anytype
import (
"os"
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/core/anytype/config"
"github.com/anytypeio/go-anytype-middleware/core/block"
@ -45,11 +47,12 @@ func StartAccountRecoverApp(eventSender event.Sender, accountPrivKey walletUtil.
return nil, err
}
cfg := config.DefaultConfig
cfg.DisableFileConfig = true // do not load/save config to file because we don't have a libp2p node and repo in this mode
a.Register(wallet.NewWithRepoPathAndKeys("", accountPrivKey, device)).
Register(&cfg).
Register(config.New(
config.WithStagingCafe(os.Getenv("ANYTYPE_STAGING") == "1"),
config.DisableFileConfig(true), // do not load/save config to file because we don't have a libp2p node and repo in this mode
),
).
Register(cafe.New()).
Register(profilefinder.New()).
Register(eventSender)
@ -61,13 +64,15 @@ func StartAccountRecoverApp(eventSender event.Sender, accountPrivKey walletUtil.
return a, nil
}
func BootstrapConfigAndWallet(newAccount bool, rootPath, accountId string) ([]app.Component, error) {
return []app.Component{
wallet.NewWithAccountRepo(rootPath, accountId),
config.New(func(c *config.Config) {
c.NewAccount = newAccount
}),
}, nil
func BootstrapConfig(newAccount bool, isStaging bool) *config.Config {
return config.New(
config.WithStagingCafe(isStaging),
config.WithNewAccount(newAccount),
)
}
func BootstrapWallet(rootPath, accountId string) wallet.Wallet {
return wallet.NewWithAccountRepo(rootPath, accountId)
}
func StartNewApp(components ...app.Component) (a *app.App, err error) {

View file

@ -6,6 +6,7 @@ import (
"net"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/kelseyhightower/envconfig"
@ -22,8 +23,6 @@ var log = logging.Logger("anytype-config")
const (
CName = "config"
defaultCafeNodeGRPC = "cafe1.anytype.io:3006"
)
type ConfigRequired struct {
@ -34,8 +33,6 @@ type Config struct {
ConfigRequired `json:",inline"`
NewAccount bool `ignored:"true"` // set to true if a new account is creating. This option controls whether mw should wait for the existing data to arrive before creating the new log
Offline bool
CafeAPIInsecure bool
CafeAPIHost string
DisableThreadsSyncEvents bool
PrivateNetworkSecret string
@ -45,6 +42,12 @@ type Config struct {
BootstrapNodes []string
RelayNodes []string
CafeAddr string
CafeGrpcPort int
CafeP2PPort int
CafePeerId string
CafeAPIInsecure bool
Threads threads.Config
DS clientds.Config
DisableFileConfig bool `ignored:"true"` // set in order to skip reading/writing config from/to file
@ -68,21 +71,70 @@ var DefaultConfig = Config{
"/dns4/relay2.anytype.io/tcp/4101/p2p/12D3KooWMLuW43JqNzUHbXMJH2Ted5Nf26sxv1VMcZAxXV3d3YtB",
"/dns4/relay1.anytype.io/tcp/4101/p2p/12D3KooWNPqCu4BC5WMBuHmqdiNWwAHGTNKbNy6JP5W1DML2psg1",
},
CafeAPIHost: defaultCafeNodeGRPC,
CafeAPIInsecure: false,
CafeAddr: "cafe1.anytype.io",
CafeP2PPort: 4001,
CafeGrpcPort: 3006,
CafePeerId: "12D3KooWKwPC165PptjnzYzGrEs7NSjsF5vvMmxmuqpA2VfaBbLw",
DS: clientds.DefaultConfig,
Threads: threads.DefaultConfig,
}
func New(apply func(*Config)) *Config {
cfg := DefaultConfig
if apply != nil {
apply(&cfg)
func WithNewAccount(isNewAccount bool) func(*Config) {
return func(c *Config) {
c.NewAccount = isNewAccount
}
}
func WithStagingCafe(isStaging bool) func(*Config) {
return func(c *Config) {
if isStaging {
c.CafeAddr = "cafe-staging.anytype.io"
c.CafePeerId = "12D3KooWPGR6LQyTEtBzFnJ7fGEMe6hKiQKeNof29zLH4bGq2djR"
}
}
}
func DisableFileConfig(disable bool) func(*Config) {
return func(c *Config) {
c.DisableFileConfig = disable
}
}
func New(options ...func(*Config)) *Config {
cfg := DefaultConfig
for _, opt := range options {
opt(&cfg)
}
cfg.Threads.CafeP2PAddr = cfg.CafeP2PFullAddr()
return &cfg
}
func (c *Config) CafeNodeGrpcAddr() string {
return c.CafeAddr + ":" + strconv.Itoa(c.CafeGrpcPort)
}
func (c *Config) CafeUrl() string {
if net.ParseIP(c.CafeAddr) != nil {
return c.CafeAddr
}
prefix := "https://"
if c.CafeAPIInsecure {
prefix = "http://"
}
return prefix + c.CafeAddr
}
func (c *Config) CafeP2PFullAddr() string {
prefix := "dns4"
if net.ParseIP(c.CafeAddr) != nil {
prefix = "ip4"
}
return fmt.Sprintf("/%s/%s/tcp/%d/p2p/%s", prefix, c.CafeAddr, c.CafeP2PPort, c.CafePeerId)
}
func (c *Config) Init(a *app.App) (err error) {
repoPath := a.MustComponent(wallet.CName).(wallet.Wallet).RepoPath()
if err = c.initFromFileAndEnv(repoPath); err != nil {
@ -92,10 +144,10 @@ func (c *Config) Init(a *app.App) (err error) {
return
}
func (cfg *Config) initFromFileAndEnv(repoPath string) error {
func (c *Config) initFromFileAndEnv(repoPath string) error {
var configFileNotExists bool
if !cfg.DisableFileConfig {
if !c.DisableFileConfig {
cfgFilePath := filepath.Join(repoPath, configFileName)
cfgFile, err := os.OpenFile(cfgFilePath, os.O_RDONLY, 0655)
if err != nil {
@ -106,7 +158,7 @@ func (cfg *Config) initFromFileAndEnv(repoPath string) error {
}
if err == nil {
defer cfgFile.Close()
err = json.NewDecoder(cfgFile).Decode(&cfg)
err = json.NewDecoder(cfgFile).Decode(&c)
if err != nil {
return fmt.Errorf("invalid format: %w", err)
}
@ -119,7 +171,7 @@ func (cfg *Config) initFromFileAndEnv(repoPath string) error {
log.Errorf("failed to get random port for gateway, go with the default %d: %s", port, err.Error())
}
cfg.HostAddr = fmt.Sprintf("/ip4/0.0.0.0/tcp/%d", port)
c.HostAddr = fmt.Sprintf("/ip4/0.0.0.0/tcp/%d", port)
// we need to save selected port in order in order to increase chances of incoming connections
if cfgFile != nil {
@ -134,21 +186,21 @@ func (cfg *Config) initFromFileAndEnv(repoPath string) error {
defer cfgFile.Close()
err = json.NewEncoder(cfgFile).Encode(cfg.ConfigRequired)
err = json.NewEncoder(cfgFile).Encode(c.ConfigRequired)
if err != nil {
return fmt.Errorf("failed to save port to the cfg file: %s", err.Error())
}
return nil
}
if cfg.HostAddr == "" && configFileNotExists {
if c.HostAddr == "" && configFileNotExists {
err = saveRandomHostAddr()
if err != nil {
return err
}
} else {
parts := strings.Split(cfg.HostAddr, "/")
parts := strings.Split(c.HostAddr, "/")
if len(parts) == 0 {
log.Errorf("failed to parse cfg.HostAddr: %s", cfg.HostAddr)
log.Errorf("failed to parse cfg.HostAddr: %s", c.HostAddr)
} else {
// lets test the existing port in config
addr, err := net.ResolveTCPAddr("tcp4", "0.0.0.0:"+parts[len(parts)-1])
@ -170,7 +222,7 @@ func (cfg *Config) initFromFileAndEnv(repoPath string) error {
}
err := envconfig.Process("ANYTYPE", cfg)
err := envconfig.Process("ANYTYPE", c)
if err != nil {
log.Errorf("failed to read config from env: %v", err)
}

View file

@ -915,6 +915,26 @@ func (mw *Middleware) BlockSetTextStyle(req *pb.RpcBlockSetTextStyleRequest) *pb
return response(pb.RpcBlockSetTextStyleResponseError_NULL, nil)
}
func (mw *Middleware) BlockSetTextIcon(req *pb.RpcBlockSetTextIconRequest) *pb.RpcBlockSetTextIconResponse {
ctx := state.NewContext(nil)
response := func(code pb.RpcBlockSetTextIconResponseErrorCode, err error) *pb.RpcBlockSetTextIconResponse {
m := &pb.RpcBlockSetTextIconResponse{Error: &pb.RpcBlockSetTextIconResponseError{Code: code}}
if err != nil {
m.Error.Description = err.Error()
} else {
m.Event = ctx.GetResponseEvent()
}
return m
}
err := mw.doBlockService(func(bs block.Service) (err error) {
return bs.SetTextIcon(ctx, req.ContextId, req.IconImage, req.IconEmoji, req.BlockId)
})
if err != nil {
return response(pb.RpcBlockSetTextIconResponseError_UNKNOWN_ERROR, err)
}
return response(pb.RpcBlockSetTextIconResponseError_NULL, nil)
}
func (mw *Middleware) BlockSetTextChecked(req *pb.RpcBlockSetTextCheckedRequest) *pb.RpcBlockSetTextCheckedResponse {
ctx := state.NewContext(nil)
response := func(code pb.RpcBlockSetTextCheckedResponseErrorCode, err error) *pb.RpcBlockSetTextCheckedResponse {

View file

@ -549,6 +549,12 @@ func (s *service) SetTextMark(ctx *state.Context, contextId string, mark *model.
})
}
func (s *service) SetTextIcon(ctx *state.Context, contextId, image, emoji string, blockIds ...string) error {
return s.DoText(contextId, func(b stext.Text) error {
return b.SetIcon(ctx, image, emoji, blockIds...)
})
}
func (s *service) SetBackgroundColor(ctx *state.Context, contextId string, color string, blockIds ...string) (err error) {
return s.DoBasic(contextId, func(b basic.Basic) error {
return b.Update(ctx, func(b simple.Block) error {

View file

@ -417,7 +417,7 @@ func (sb *smartBlock) fetchMeta() (details []*pb.EventObjectDetailsSet, objectTy
}
recordsCh := make(chan *types.Struct, 10)
sb.recordsSub = database.NewSubscription(nil, recordsCh)
sb.depIds = sb.dependentSmartIds(true, true)
sb.depIds = sb.dependentSmartIds(true, true, true)
sort.Strings(sb.depIds)
var records []database.Record
if records, sb.closeRecordsSub, err = sb.objectStore.QueryByIdAndSubscribeForChanges(sb.depIds, sb.recordsSub); err != nil {
@ -544,7 +544,7 @@ func (sb *smartBlock) onMetaChange(details *types.Struct) {
}
// dependentSmartIds returns list of dependent objects in this order: Simple blocks(Link, mentions in Text), Relations. Both of them are returned in the order of original blocks/relations
func (sb *smartBlock) dependentSmartIds(includeObjTypes bool, includeCreatorModifier bool) (ids []string) {
func (sb *smartBlock) dependentSmartIds(includeObjTypes bool, includeCreatorModifier bool, includeHidden bool) (ids []string) {
ids = sb.Doc.(*state.State).DepSmartIds()
if sb.Type() != model.SmartBlockType_Breadcrumbs {
@ -562,7 +562,8 @@ func (sb *smartBlock) dependentSmartIds(includeObjTypes bool, includeCreatorModi
for _, rel := range sb.RelationsState(sb.Doc.(*state.State), false) {
// do not index local dates such as lastOpened/lastModified
if rel.Format == model.RelationFormat_date && (slice.FindPos(bundle.LocalRelationsKeys, rel.Key) == 0) && (slice.FindPos(bundle.DerivedRelationsKeys, rel.Key) == 0) {
if rel.Format == model.RelationFormat_date &&
(slice.FindPos(bundle.LocalRelationsKeys, rel.Key) == 0) && (slice.FindPos(bundle.DerivedRelationsKeys, rel.Key) == 0) {
relInt := pbtypes.GetInt64(details, rel.Key)
if relInt > 0 {
t := time.Unix(relInt, 0)
@ -572,6 +573,24 @@ func (sb *smartBlock) dependentSmartIds(includeObjTypes bool, includeCreatorModi
continue
}
if rel.Key == bundle.RelationKeyCreator.String() || rel.Key == bundle.RelationKeyLastModifiedBy.String() {
if includeCreatorModifier {
v := pbtypes.GetString(details, rel.Key)
ids = append(ids, v)
}
continue
}
if rel.Hidden && !includeHidden {
continue
}
if rel.Key == bundle.RelationKeyId.String() ||
rel.Key == bundle.RelationKeyType.String() || // always skip type because it was proceed above
rel.Key == bundle.RelationKeyFeaturedRelations.String() {
continue
}
if rel.Key == bundle.RelationKeyCoverId.String() {
v := pbtypes.GetString(details, rel.Key)
_, err := cid.Decode(v)
@ -586,17 +605,6 @@ func (sb *smartBlock) dependentSmartIds(includeObjTypes bool, includeCreatorModi
continue
}
if rel.Hidden {
continue
}
if rel.Key == bundle.RelationKeyId.String() ||
rel.Key == bundle.RelationKeyType.String() ||
rel.Key == bundle.RelationKeyFeaturedRelations.String() ||
!includeCreatorModifier && (rel.Key == bundle.RelationKeyCreator.String() || rel.Key == bundle.RelationKeyLastModifiedBy.String()) {
continue
}
// add all object relation values as dependents
for _, targetId := range pbtypes.GetStringList(details, rel.Key) {
if targetId != "" {
@ -764,7 +772,7 @@ func (sb *smartBlock) ResetToVersion(s *state.State) (err error) {
}
func (sb *smartBlock) CheckSubscriptions() (changed bool) {
depIds := sb.dependentSmartIds(true, true)
depIds := sb.dependentSmartIds(true, true, true)
sort.Strings(depIds)
if !slice.SortedEquals(sb.depIds, depIds) {
sb.depIds = depIds
@ -1670,18 +1678,13 @@ func (sb *smartBlock) getDocInfo(st *state.State) doc.DocInfo {
}
}
links := sb.dependentSmartIds(false, false)
for _, fileHash := range fileHashes {
if slice.FindPos(links, fileHash) == -1 {
links = append(links, fileHash)
}
}
// we don't want any hidden or internal relations here. We want to capture the meaningful outgoing links only
links := sb.dependentSmartIds(false, false, false)
links = slice.Remove(links, sb.Id())
// so links will have this order
// 1. Simple blocks: links, mentions in the text
// 2. Relations(format==Object)
// 3. Files
return doc.DocInfo{
Id: sb.Id(),
Links: links,

View file

@ -27,6 +27,7 @@ type Text interface {
Split(ctx *state.Context, req pb.RpcBlockSplitRequest) (newId string, err error)
Merge(ctx *state.Context, firstId, secondId string) (err error)
SetMark(ctx *state.Context, mark *model.BlockContentTextMark, blockIds ...string) error
SetIcon(ctx *state.Context, image, emoji string, blockIds ...string) error
SetText(req pb.RpcBlockSetTextTextRequest) (err error)
TurnInto(ctx *state.Context, style model.BlockContentTextStyle, ids ...string) error
}
@ -209,6 +210,22 @@ func (t *textImpl) SetMark(ctx *state.Context, mark *model.BlockContentTextMark,
return t.Apply(s)
}
// SetIcon sets an icon for the text block with style BlockContentText_Callout(13)
func (t *textImpl) SetIcon(ctx *state.Context, image string, emoji string, blockIds ...string) (err error) {
s := t.NewStateCtx(ctx)
for _, id := range blockIds {
tb, err := getText(s, id)
if err != nil {
continue
}
tb.SetIconImage(image)
tb.SetIconEmoji(emoji)
}
return t.Apply(s)
}
func (t *textImpl) newSetTextState(blockId string, ctx *state.Context) *state.State {
if t.lastSetTextState != nil && t.lastSetTextId == blockId {
return t.lastSetTextState

View file

@ -141,6 +141,7 @@ type Service interface {
SetTextChecked(ctx *state.Context, req pb.RpcBlockSetTextCheckedRequest) error
SetTextColor(ctx *state.Context, contextId string, color string, blockIds ...string) error
SetTextMark(ctx *state.Context, id string, mark *model.BlockContentTextMark, ids ...string) error
SetTextIcon(ctx *state.Context, contextId, image, emoji string, blockIds ...string) error
SetBackgroundColor(ctx *state.Context, contextId string, color string, blockIds ...string) error
SetAlign(ctx *state.Context, contextId string, align model.BlockAlign, blockIds ...string) (err error)
SetLayout(ctx *state.Context, id string, layout model.ObjectTypeLayout) error

View file

@ -133,7 +133,7 @@ func (td *textDetails) Diff(s simple.Block) (msgs []simple.EventMessage, err err
}
}
if st := msg.Msg.GetBlockSetText(); st != nil {
if st.Text == nil && st.Checked == nil && st.Marks == nil && st.Style == nil && st.Color == nil {
if st.Text == nil && st.Checked == nil && st.Marks == nil && st.Style == nil && st.Color == nil && st.IconImage == nil && st.IconEmoji == nil {
toRemove = i
}
}

View file

@ -51,6 +51,9 @@ type Block interface {
RemoveMarkType(markType model.BlockContentTextMarkType)
HasMarkForAllText(mark *model.BlockContentTextMark) bool
SetTextColor(color string)
SetIconEmoji(emoji string)
SetIconImage(imageHash string)
Split(pos int32) (simple.Block, error)
RangeSplit(from int32, to int32, top bool) (newBlock simple.Block, err error)
RangeTextPaste(rangeFrom int32, rangeTo int32, copiedBlock *model.Block, isPartOfBlock bool) (caretPosition int32, err error)
@ -127,6 +130,14 @@ func (t *Text) Diff(b simple.Block) (msgs []simple.EventMessage, err error) {
hasChanges = true
changes.Color = &pb.EventBlockSetTextColor{Value: text.content.Color}
}
if t.content.IconImage != text.content.IconImage {
hasChanges = true
changes.IconImage = &pb.EventBlockSetTextIconImage{Value: text.content.IconImage}
}
if t.content.IconEmoji != text.content.IconEmoji {
hasChanges = true
changes.IconEmoji = &pb.EventBlockSetTextIconEmoji{Value: text.content.IconEmoji}
}
if hasChanges {
msgs = append(msgs, simple.EventMessage{Msg: &pb.EventMessage{Value: &pb.EventMessageValueOfBlockSetText{BlockSetText: changes}}})
}
@ -149,6 +160,14 @@ func (t *Text) SetTextColor(color string) {
t.content.Color = color
}
func (t *Text) SetIconEmoji(emoji string) {
t.content.IconEmoji = emoji
}
func (t *Text) SetIconImage(imageHash string) {
t.content.IconImage = imageHash
}
func (t *Text) SetMarkForAllText(mark *model.BlockContentTextMark) {
mRange := &model.Range{
To: int32(utf8.RuneCountInString(t.content.Text)),
@ -605,5 +624,11 @@ func (t *Text) ApplyEvent(e *pb.EventBlockSetText) error {
if e.Color != nil {
t.content.Color = e.Color.GetValue()
}
if e.IconImage != nil {
t.content.IconImage = e.IconImage.GetValue()
}
if e.IconEmoji != nil {
t.content.IconEmoji = e.IconEmoji.GetValue()
}
return nil
}

View file

@ -39,17 +39,18 @@ const (
CName = "indexer"
// increasing counters below will trigger existing account to reindex their data
ForceThreadsObjectsReindexCounter int32 = 4 // reindex thread-based objects
ForceThreadsObjectsReindexCounter int32 = 6 // reindex thread-based objects
ForceFilesReindexCounter int32 = 5 // reindex ipfs-file-based objects
ForceBundledObjectsReindexCounter int32 = 3 // reindex objects like anytypeProfile
ForceIdxRebuildCounter int32 = 12 // erases localstore indexes and reindex all type of objects (no need to increase ForceThreadsObjectsReindexCounter & ForceFilesReindexCounter)
ForceFulltextIndexCounter int32 = 2 // performs fulltext indexing for all type of objects (useful when we change fulltext config)
ForceFulltextIndexCounter int32 = 3 // performs fulltext indexing for all type of objects (useful when we change fulltext config)
)
var log = logging.Logger("anytype-doc-indexer")
var (
ftIndexInterval = time.Minute / 3
ftIndexInterval = time.Minute
ftIndexForceMinInterval = time.Second * 10
)
func New() Indexer {
@ -57,6 +58,7 @@ func New() Indexer {
}
type Indexer interface {
ForceFTIndex()
app.ComponentRunnable
}
@ -96,6 +98,7 @@ type indexer struct {
archivedMap map[string]struct{}
favoriteMap map[string]struct{}
newAccount bool
forceFt chan struct{}
}
func (i *indexer) Init(a *app.App) (err error) {
@ -112,7 +115,7 @@ func (i *indexer) Init(a *app.App) (err error) {
i.quit = make(chan struct{})
i.archivedMap = make(map[string]struct{}, 100)
i.favoriteMap = make(map[string]struct{}, 100)
i.forceFt = make(chan struct{})
return
}
@ -165,6 +168,13 @@ func (i *indexer) Run() (err error) {
return
}
func (i *indexer) ForceFTIndex() {
select {
case i.forceFt <- struct{}{}:
default:
}
}
func (i *indexer) migrateRemoveNonindexableObjects() {
ids, err := i.getIdsForTypes(
smartblock.SmartblockTypeMarketplaceType, smartblock.SmartblockTypeMarketplaceRelation,
@ -728,7 +738,7 @@ func (i *indexer) index(ctx context.Context, info doc.DocInfo) error {
func (i *indexer) ftLoop() {
ticker := time.NewTicker(ftIndexInterval)
i.ftIndex()
var lastForceIndex time.Time
i.mu.Lock()
quit := i.quit
i.mu.Unlock()
@ -738,6 +748,11 @@ func (i *indexer) ftLoop() {
return
case <-ticker.C:
i.ftIndex()
case <-i.forceFt:
if time.Since(lastForceIndex) > ftIndexForceMinInterval {
i.ftIndex()
lastForceIndex = time.Now()
}
}
}
}
@ -800,14 +815,21 @@ func (i *indexer) ftIndexDoc(id string, _ time.Time) (err error) {
}
if fts := i.store.FTSearch(); fts != nil {
if err := fts.Index(ftsearch.SearchDoc{
title := pbtypes.GetString(info.State.Details(), bundle.RelationKeyName.String())
if info.State.ObjectType() == bundle.TypeKeyNote.String() || title == "" {
title = info.State.Snippet()
}
ftDoc := ftsearch.SearchDoc{
Id: id,
Title: pbtypes.GetString(info.State.Details(), bundle.RelationKeyName.String()),
Title: title,
Text: info.State.SearchText(),
}); err != nil {
}
if err := fts.Index(ftDoc); err != nil {
log.Errorf("can't ft index doc: %v", err)
}
log.Debugf("ft search indexed with title: '%s'", ftDoc.Title)
}
log.With("thread", id).Infof("ft index updated for a %v", time.Since(st))
return
}

View file

@ -2,6 +2,7 @@ package core
import (
"fmt"
"github.com/anytypeio/go-anytype-middleware/core/indexer"
"strings"
"time"
@ -110,7 +111,9 @@ func (mw *Middleware) ObjectSearch(req *pb.RpcObjectSearchRequest) *pb.RpcObject
}
at := mw.app.MustComponent(core.CName).(core.Service)
if req.FullText != "" {
mw.app.MustComponent(indexer.CName).(indexer.Indexer).ForceFTIndex()
}
records, _, err := at.ObjectStore().Query(nil, database.Query{
Filters: req.Filters,
Sorts: req.Sorts,
@ -306,8 +309,10 @@ func (mw *Middleware) ObjectGraph(req *pb.RpcObjectGraphRequest) *pb.RpcObjectGr
continue
}
if rel.Key == bundle.RelationKeyId.String() || rel.Key == bundle.RelationKeyType.String() || rel.Key == bundle.RelationKeyCreator.String() || rel.Key == bundle.RelationKeyLastModifiedBy.String() {
outgoingRelationLink[l] = struct{}{}
if rel.Hidden ||
rel.Key == bundle.RelationKeyId.String() ||
rel.Key == bundle.RelationKeyCreator.String() ||
rel.Key == bundle.RelationKeyLastModifiedBy.String() {
continue
}
@ -323,7 +328,7 @@ func (mw *Middleware) ObjectGraph(req *pb.RpcObjectGraphRequest) *pb.RpcObjectGr
}
}
}
links, _ := at.ObjectStore().GetOutboundLinksById(id)
links := pbtypes.GetStringList(rec.Details, bundle.RelationKeyLinks.String())
for _, link := range links {
sbType, _ := smartblock.SmartBlockTypeFromID(link)
// ignore files because we index all file blocks as outgoing links
@ -375,6 +380,10 @@ func (mw *Middleware) ObjectRelationAdd(req *pb.RpcObjectRelationAddRequest) *pb
return response(nil, pb.RpcObjectRelationAddResponseError_BAD_INPUT, err)
}
if len(relations) == 0 {
return response(nil, pb.RpcObjectRelationAddResponseError_ALREADY_EXISTS, nil)
}
return response(relations[0], pb.RpcObjectRelationAddResponseError_NULL, nil)
}

View file

@ -1,8 +1,7 @@
package status
import (
"github.com/anytypeio/go-anytype-middleware/core/anytype/config"
"github.com/anytypeio/go-anytype-middleware/core/event"
"fmt"
"sort"
"sync"
"time"
@ -16,6 +15,8 @@ import (
"github.com/textileio/go-threads/core/thread"
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/core/anytype/config"
"github.com/anytypeio/go-anytype-middleware/core/event"
"github.com/anytypeio/go-anytype-middleware/pb"
cafepb "github.com/anytypeio/go-anytype-middleware/pkg/lib/cafe/pb"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/core"
@ -34,9 +35,6 @@ const (
profileInformationLifetime = 30 * time.Second
cafeLastPullTimeout = 10 * time.Minute
// TODO: move to global config component
cafePeerId = "12D3KooWKwPC165PptjnzYzGrEs7NSjsF5vvMmxmuqpA2VfaBbLw"
// truncate device names and account IDs to last symbols
maxNameLength = 8
)
@ -110,7 +108,7 @@ func (s *service) Init(a *app.App) (err error) {
cafePeer, _ = cafeAddr.ValueForProtocol(ma.P_P2P)
}
if cafePeer == "" {
cafePeer = cafePeerId
return fmt.Errorf("cafe address must be specified at start time")
}
cafePid, _ := peer.Decode(cafePeer)

View file

@ -9,10 +9,9 @@ import (
)
type opChange struct {
id string
subId string
keys []string
afterId string
id string
subId string
keys []string
}
type opRemove struct {
@ -24,6 +23,8 @@ type opPosition struct {
id string
subId string
afterId string
keys []string
isAdd bool
}
type opCounter struct {
@ -37,7 +38,6 @@ type opCtx struct {
// subIds for remove
remove []opRemove
change []opChange
add []opChange
position []opPosition
counters []opCounter
entries []*entry
@ -54,18 +54,30 @@ type opCtx struct {
func (ctx *opCtx) apply() (event *pb.Event) {
var subMsgs = make([]*pb.EventMessage, 0, 10)
// adds
for _, add := range ctx.add {
ctx.collectKeys(add.id, add.subId, add.keys)
subMsgs = append(subMsgs, &pb.EventMessage{
Value: &pb.EventMessageValueOfSubscriptionAdd{
SubscriptionAdd: &pb.EventObjectSubscriptionAdd{
Id: add.id,
AfterId: add.afterId,
SubId: add.subId,
// adds, positions
for _, pos := range ctx.position {
if pos.isAdd {
ctx.collectKeys(pos.id, pos.subId, pos.keys)
subMsgs = append(subMsgs, &pb.EventMessage{
Value: &pb.EventMessageValueOfSubscriptionAdd{
SubscriptionAdd: &pb.EventObjectSubscriptionAdd{
Id: pos.id,
AfterId: pos.afterId,
SubId: pos.subId,
},
},
},
})
})
} else {
subMsgs = append(subMsgs, &pb.EventMessage{
Value: &pb.EventMessageValueOfSubscriptionPosition{
SubscriptionPosition: &pb.EventObjectSubscriptionPosition{
Id: pos.id,
AfterId: pos.afterId,
SubId: pos.subId,
},
},
})
}
}
// changes
@ -76,19 +88,6 @@ func (ctx *opCtx) apply() (event *pb.Event) {
// details events
eventMsgs := ctx.detailsEvents()
// positions
for _, pos := range ctx.position {
subMsgs = append(subMsgs, &pb.EventMessage{
Value: &pb.EventMessageValueOfSubscriptionPosition{
SubscriptionPosition: &pb.EventObjectSubscriptionPosition{
Id: pos.id,
AfterId: pos.afterId,
SubId: pos.subId,
},
},
})
}
// removes
for _, rem := range ctx.remove {
subMsgs = append(subMsgs, &pb.EventMessage{
@ -172,8 +171,8 @@ func (ctx *opCtx) collectKeys(id string, subId string, keys []string) {
if kb.id == id {
found = true
for _, k := range keys {
if slice.FindPos(kb.keys, k) == -1 {
ctx.keysBuf[i].keys = append(kb.keys, k)
if slice.FindPos(ctx.keysBuf[i].keys, k) == -1 {
ctx.keysBuf[i].keys = append(ctx.keysBuf[i].keys, k)
}
}
if slice.FindPos(kb.subIds, subId) == -1 {
@ -205,7 +204,6 @@ func (ctx *opCtx) getEntry(id string) *entry {
func (ctx *opCtx) reset() {
ctx.remove = ctx.remove[:0]
ctx.change = ctx.change[:0]
ctx.add = ctx.add[:0]
ctx.position = ctx.position[:0]
ctx.counters = ctx.counters[:0]
ctx.keysBuf = ctx.keysBuf[:0]

View file

@ -23,19 +23,22 @@ type dependencyService struct {
func (ds *dependencyService) makeSubscriptionByEntries(subId string, allEntries, activeEntries []*entry, keys, depKeys, filterDepIds []string) *simpleSub {
depSub := ds.s.newSimpleSub(subId, keys, true)
depSub.forceIds = filterDepIds
depEntries := ds.depEntriesByEntries(&opCtx{entries: allEntries}, activeEntries, depKeys, depSub.forceIds)
depEntries := ds.depEntriesByEntries(&opCtx{entries: allEntries}, ds.depIdsByEntries(activeEntries, depKeys, depSub.forceIds))
depSub.init(depEntries)
return depSub
}
func (ds *dependencyService) refillSubscription(ctx *opCtx, sub *simpleSub, entries []*entry, depKeys []string) {
depEntries := ds.depEntriesByEntries(ctx, entries, depKeys, sub.forceIds)
sub.refill(ctx, depEntries)
depIds := ds.depIdsByEntries(entries, depKeys, sub.forceIds)
if !sub.isEqualIds(depIds) {
depEntries := ds.depEntriesByEntries(ctx, depIds)
sub.refill(ctx, depEntries)
}
return
}
func (ds *dependencyService) depEntriesByEntries(ctx *opCtx, entries []*entry, depKeys, forceIds []string) (depEntries []*entry) {
var depIds = forceIds
func (ds *dependencyService) depIdsByEntries(entries []*entry, depKeys, forceIds []string) (depIds []string) {
depIds = forceIds
for _, e := range entries {
for _, k := range depKeys {
for _, depId := range pbtypes.GetStringList(e.data, k) {
@ -45,36 +48,50 @@ func (ds *dependencyService) depEntriesByEntries(ctx *opCtx, entries []*entry, d
}
}
}
return
}
func (ds *dependencyService) depEntriesByEntries(ctx *opCtx, depIds []string) (depEntries []*entry) {
if len(depIds) == 0 {
return
}
depRecords, err := ds.s.objectStore.QueryById(depIds)
if err != nil {
log.Errorf("can't query by id: %v", err)
}
depEntries = make([]*entry, 0, len(depRecords))
for _, r := range depRecords {
var missIds []string
for _, id := range depIds {
var e *entry
id := pbtypes.GetString(r.Details, "id")
// priority: ctx.entries, cache, objectStore
if e = ctx.getEntry(id); e == nil {
if e = ds.s.cache.Get(id); e == nil {
e = &entry{
id: id,
data: r.Details,
}
} else {
if e = ds.s.cache.Get(id); e != nil {
e = &entry{
id: id,
data: e.data,
subIds: e.subIds,
subIsActive: e.subIsActive,
}
} else {
missIds = append(missIds, id)
}
if e != nil {
ctx.entries = append(ctx.entries, e)
}
}
if e != nil {
depEntries = append(depEntries, e)
}
}
if len(missIds) > 0 {
records, err := ds.s.objectStore.QueryById(missIds)
if err != nil {
log.Errorf("can't query by id: %v", err)
}
for _, r := range records {
e := &entry{
id: pbtypes.GetString(r.Details, "id"),
data: r.Details,
}
ctx.entries = append(ctx.entries, e)
depEntries = append(depEntries, e)
}
depEntries = append(depEntries, e)
}
return
}

94
core/subscription/diff.go Normal file
View file

@ -0,0 +1,94 @@
package subscription
import (
"github.com/mb0/diff"
)
func newListDiff(ids []string) *listDiff {
ld := &listDiff{
beforeIds: ids,
beforeIdsM: map[string]struct{}{},
afterIdsM: map[string]struct{}{},
}
for _, id := range ids {
ld.beforeIdsM[id] = struct{}{}
}
return ld
}
type listDiff struct {
beforeIds, afterIds []string
beforeIdsM, afterIdsM map[string]struct{}
}
func (ld *listDiff) Equal(i, j int) bool { return ld.beforeIds[i] == ld.afterIds[j] }
func (ld *listDiff) fillAfter(id string) {
ld.afterIds = append(ld.afterIds, id)
}
func (ld *listDiff) reverse() {
for i, j := 0, len(ld.afterIds)-1; i < j; i, j = i+1, j-1 {
ld.afterIds[i], ld.afterIds[j] = ld.afterIds[j], ld.afterIds[i]
}
}
func (ld *listDiff) reset() {
ld.beforeIds, ld.afterIds = ld.afterIds, ld.beforeIds
ld.afterIds = ld.afterIds[:0]
ld.beforeIdsM = ld.afterIdsM
ld.afterIdsM = make(map[string]struct{})
}
func (ld *listDiff) diff(ctx *opCtx, subId string, keys []string) (wasAddOrRemove bool) {
for _, id := range ld.afterIds {
ld.afterIdsM[id] = struct{}{}
}
hasBefore := func(id string) bool {
if _, ok := ld.beforeIdsM[id]; ok {
return true
}
return false
}
hasAfter := func(id string) bool {
if _, ok := ld.afterIdsM[id]; ok {
return true
}
return false
}
getPrevId := func(s []string, i int) string {
if i == 0 {
return ""
}
return s[i-1]
}
diffData := diff.Diff(len(ld.beforeIds), len(ld.afterIds), ld)
for _, ch := range diffData {
for i := 0; i < ch.Ins; i++ {
idx := ch.B + i
isAdd := !hasBefore(ld.afterIds[idx])
ctx.position = append(ctx.position, opPosition{
id: ld.afterIds[idx],
subId: subId,
keys: keys,
afterId: getPrevId(ld.afterIds, idx),
isAdd: isAdd,
})
if isAdd {
wasAddOrRemove = true
}
}
for i := 0; i < ch.Del; i++ {
idx := ch.A + i
if !hasAfter(ld.beforeIds[idx]) {
ctx.remove = append(ctx.remove, opRemove{
id: ld.beforeIds[idx],
subId: subId,
})
wasAddOrRemove = true
}
}
}
return
}

View file

@ -0,0 +1,142 @@
package subscription
import (
"fmt"
"github.com/anytypeio/go-anytype-middleware/util/slice"
"github.com/stretchr/testify/assert"
"math/rand"
"strings"
"testing"
"time"
)
func TestListDiffFuzz(t *testing.T) {
var genRandomUniqueSeq = func(l int) []string {
ids := map[string]struct{}{}
for len(ids) < l {
ids[fmt.Sprint(rand.Intn(int(float64(l)*1.2)))] = struct{}{}
}
res := make([]string, 0, l)
for id := range ids {
res = append(res, id)
}
return res
}
var chToString = func(ch opPosition) string {
if ch.isAdd {
return fmt.Sprintf("add: %s after: %s", ch.id, ch.afterId)
}
return fmt.Sprintf("move: %s after: %s", ch.id, ch.afterId)
}
var checkBeforeAfter = func(before, after []string) (ok bool) {
var debug []string
d := newListDiff(before)
for _, id := range after {
d.fillAfter(id)
}
ctx := &opCtx{}
d.diff(ctx, "", nil)
var resAfter = make([]string, len(before))
copy(resAfter, before)
for i, ch := range ctx.position {
if !ch.isAdd {
resAfter = slice.Remove(resAfter, ch.id)
}
if ch.afterId == "" {
resAfter = append([]string{ch.id}, resAfter...)
} else {
pos := slice.FindPos(resAfter, ch.afterId)
resAfter = slice.Insert(resAfter, pos+1, ch.id)
}
debug = append(debug, fmt.Sprintf("%d:\t %+v", i, chToString(ch)))
debug = append(debug, fmt.Sprintf("%d:\t %v", i, resAfter))
}
for i, rm := range ctx.remove {
resAfter = slice.Remove(resAfter, rm.id)
debug = append(debug, fmt.Sprintf("%d:\t remove %+v", i, rm.id))
debug = append(debug, fmt.Sprintf("%d:\t %v", i, resAfter))
}
ok = assert.ObjectsAreEqual(after, resAfter)
if !ok {
t.Log("after", after)
t.Log("afterRes", resAfter)
t.Log("before", before)
for _, dbg := range debug {
t.Log(dbg)
}
} else {
t.Logf("ch: %d; rm: %d; %v", len(ctx.position), len(ctx.remove), len(resAfter))
}
assert.True(t, ok)
return
}
/*
checkBeforeAfter([]string{"1", "2", "3", "4", "5", "6"}, []string{"6", "2", "3", "4", "5", "1"})
return
*/
rand.Seed(time.Now().UnixNano())
var initialLen = 30
var before, after []string
before = genRandomUniqueSeq(initialLen)
for i := 0; i < 1000; i++ {
after = genRandomUniqueSeq(initialLen + rand.Intn(1+5))
if !checkBeforeAfter(before, after) {
break
}
before = after
}
}
func BenchmarkDiff(b *testing.B) {
b.ReportAllocs()
genData := func(n int, reverse bool) []string {
res := make([]string, n)
for i := 0; i < n; i++ {
if reverse {
res[i] = strings.Repeat("x", 40) + fmt.Sprint(n-i)
} else {
res[i] = strings.Repeat("x", 40) + fmt.Sprint(i)
}
}
return res
}
benchmark := func(before, after []string) func(b *testing.B) {
d := newListDiff(before)
ctx := &opCtx{}
return func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
for _, id := range after {
d.fillAfter(id)
}
d.diff(ctx, "", nil)
d.reset()
ctx.reset()
after, before = before, after
}
}
}
var before, after []string
for _, n := range []int{
100, 1000, 10000,
} {
b.Run(fmt.Sprintf("big-diff-%d", n), benchmark(genData(n, false), genData(n, true)))
before = genData(n, false)
after = genData(n, false)
after[(n/2)-1], after[(n/2)] = after[(n/2)], after[(n/2)-1]
b.Run(fmt.Sprintf("small-diff-%d", n), benchmark(before, after))
before = genData(n, false)
b.Run(fmt.Sprintf("equal-%d", n), benchmark(before, before))
}
}

View file

@ -3,6 +3,7 @@ package subscription
import (
"fmt"
"sync"
"time"
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/core/event"
@ -26,6 +27,8 @@ const CName = "subscription"
var log = logging.Logger("anytype-mw-subscription")
var batchTime = 50 * time.Millisecond
func New() Service {
return new(service)
}
@ -45,6 +48,7 @@ type subscription interface {
counters() (prev, next int)
onChange(ctx *opCtx)
getActiveRecords() (res []*types.Struct)
hasDep() bool
close()
}
@ -129,7 +133,11 @@ func (s *service) Search(req pb.RpcObjectSearchSubscribeRequest) (resp *pb.RpcOb
req.Limit = 0
}
sub := s.newSortedSub(req.SubId, req.Keys, f.FilterObj, f.Order, int(req.Limit), int(req.Offset))
sub.forceSubIds = filterDepIds
if req.NoDepSubscription {
sub.disableDep = true
} else {
sub.forceSubIds = filterDepIds
}
entries := make([]*entry, 0, len(records))
for _, r := range records {
entries = append(entries, &entry{
@ -233,33 +241,64 @@ func (s *service) UnsubscribeAll() (err error) {
func (s *service) recordsHandler() {
var entries []*entry
nilIfExists := func(id string) {
for i, e := range entries {
if e != nil && e.id == id {
entries[i] = nil
return
}
}
}
for {
records := s.recBatch.Wait()
if len(records) == 0 {
return
}
for _, rec := range records {
id := pbtypes.GetString(rec.(database.Record).Details, "id")
// nil previous version
nilIfExists(id)
entries = append(entries, &entry{
id: pbtypes.GetString(rec.(database.Record).Details, "id"),
id: id,
data: rec.(database.Record).Details,
})
}
s.onChange(entries)
// filter nil entries
var filtered = entries[:0]
for _, e := range entries {
if e != nil {
filtered = append(filtered, e)
}
}
log.Debugf("batch rewrite: %d->%d", len(entries), len(filtered))
if s.onChange(filtered) < batchTime {
time.Sleep(batchTime)
}
entries = entries[:0]
}
}
func (s *service) onChange(entries []*entry) {
func (s *service) onChange(entries []*entry) time.Duration {
s.m.Lock()
defer s.m.Unlock()
var subCount, depCount int
st := time.Now()
s.ctxBuf.reset()
s.ctxBuf.entries = entries
for _, sub := range s.subscriptions {
sub.onChange(s.ctxBuf)
subCount++
if sub.hasDep() {
depCount++
}
}
log.Debugf("handle %d etries; ctx: %#v", len(entries), s.ctxBuf)
handleTime := time.Since(st)
event := s.ctxBuf.apply()
dur := time.Since(st)
log.Debugf("handle %d entries; %v(handle:%v;genEvents:%v); cacheSize: %d; subCount:%d; subDepCount:%d", len(entries), dur, handleTime, dur-handleTime, len(s.cache.entries), subCount, depCount)
s.sendEvent(event)
return dur
}
func (s *service) filtersFromSource(sources []string) (filter.Filter, error) {

View file

@ -44,7 +44,7 @@ func TestService_Search(t *testing.T) {
"id": pbtypes.String("author1"),
"name": pbtypes.String("author1"),
}}},
}, nil)
}, nil).AnyTimes()
resp, err := fx.Search(pb.RpcObjectSearchSubscribeRequest{
SubId: subId,
@ -63,7 +63,7 @@ func TestService_Search(t *testing.T) {
newSub(fx, "test")
fx.store.EXPECT().QueryById([]string{"author2", "author3", "1"}).Return([]database.Record{
fx.store.EXPECT().QueryById([]string{"author2", "author3"}).Return([]database.Record{
{Details: &types.Struct{Fields: map[string]*types.Value{
"id": pbtypes.String("author2"),
"name": pbtypes.String("author2"),
@ -72,11 +72,6 @@ func TestService_Search(t *testing.T) {
"id": pbtypes.String("author3"),
"name": pbtypes.String("author3"),
}}},
{Details: &types.Struct{Fields: map[string]*types.Value{
"id": pbtypes.String("1"),
"name": pbtypes.String("one"),
"author": pbtypes.StringList([]string{"author2", "author3", "1"}),
}}},
}, nil)
fx.Service.(*service).onChange([]*entry{
@ -175,6 +170,72 @@ func TestService_Search(t *testing.T) {
assert.Len(t, resp.Dependencies, 2)
})
t.Run("add with limit", func(t *testing.T) {
fx := newFixture(t)
defer fx.a.Close()
defer fx.ctrl.Finish()
fx.store.EXPECT().QueryRaw(gomock.Any()).Return(
[]database.Record{
{Details: &types.Struct{Fields: map[string]*types.Value{
"id": pbtypes.String("1"),
"name": pbtypes.String("1"),
}}},
{Details: &types.Struct{Fields: map[string]*types.Value{
"id": pbtypes.String("2"),
"name": pbtypes.String("2"),
}}},
{Details: &types.Struct{Fields: map[string]*types.Value{
"id": pbtypes.String("3"),
"name": pbtypes.String("3"),
}}},
},
nil,
)
fx.store.EXPECT().GetRelation(bundle.RelationKeyName.String()).Return(&model.Relation{
Key: bundle.RelationKeyName.String(),
Format: model.RelationFormat_shorttext,
}, nil).AnyTimes()
resp, err := fx.Search(pb.RpcObjectSearchSubscribeRequest{
SubId: "test",
Sorts: []*model.BlockContentDataviewSort{
{
RelationKey: "name",
Type: model.BlockContentDataviewSort_Desc,
},
},
Limit: 2,
Keys: []string{"id", "name"},
})
require.NoError(t, err)
// should be 3,2 (1)
require.Len(t, resp.Records, 2)
assert.Equal(t, "3", pbtypes.GetString(resp.Records[0], "id"))
assert.Equal(t, "2", pbtypes.GetString(resp.Records[1], "id"))
fx.Service.(*service).onChange([]*entry{
{id: "1", data: &types.Struct{Fields: map[string]*types.Value{
"id": pbtypes.String("1"),
"name": pbtypes.String("4"),
}}},
})
// should be 1,3 (2)
require.Len(t, fx.events[0].Messages, 3)
assert.NotEmpty(t, fx.events[0].Messages[0].GetObjectDetailsSet())
assert.NotEmpty(t, fx.events[0].Messages[1].GetSubscriptionAdd())
assert.NotEmpty(t, fx.events[0].Messages[2].GetSubscriptionRemove())
fx.Service.(*service).onChange([]*entry{
{id: "2", data: &types.Struct{Fields: map[string]*types.Value{
"id": pbtypes.String("2"),
"name": pbtypes.String("6"),
}}},
})
// should be 2,1 (3)
t.Log(pbtypes.Sprint(fx.events[1]))
})
}
func newFixture(t *testing.T) *fixture {

View file

@ -47,6 +47,18 @@ func (s *simpleSub) init(entries []*entry) (err error) {
return
}
func (s *simpleSub) isEqualIds(ids []string) bool {
if len(s.set) != len(ids) {
return false
}
for _, id := range ids {
if _, ok := s.set[id]; !ok {
return false
}
}
return true
}
func (s *simpleSub) refill(ctx *opCtx, entries []*entry) {
var newSet = make(map[string]struct{})
for _, e := range entries {
@ -57,10 +69,11 @@ func (s *simpleSub) refill(ctx *opCtx, entries []*entry) {
keys: s.keys,
})
} else {
ctx.add = append(ctx.add, opChange{
ctx.position = append(ctx.position, opPosition{
id: e.id,
subId: s.id,
keys: s.keys,
isAdd: true,
})
}
newSet[e.id] = struct{}{}
@ -115,6 +128,10 @@ func (s *simpleSub) getActiveRecords() (res []*types.Struct) {
return
}
func (s *simpleSub) hasDep() bool {
return s.depSub != nil
}
func (s *simpleSub) close() {
for id := range s.set {
s.cache.RemoveSubId(id, s.id)

View file

@ -2,7 +2,6 @@ package subscription
import (
"errors"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/database/filter"
"github.com/anytypeio/go-anytype-middleware/util/pbtypes"
"github.com/gogo/protobuf/types"
@ -46,6 +45,11 @@ type sortedSub struct {
activeEntriesBuf []*entry
forceSubIds []string
disableDep bool
diff *listDiff
compCountBefore, compCountAfter opCounter
cache *cache
ds *dependencyService
@ -59,11 +63,10 @@ func (s *sortedSub) init(entries []*entry) (err error) {
s.close()
}
}()
for i, e := range entries {
e = s.cache.GetOrSet(e)
entries[i] = e
e.SetSub(s.id, true)
e.SetSub(s.id, false)
s.skl.Set(e, nil)
}
if s.afterId != "" {
@ -107,11 +110,17 @@ func (s *sortedSub) init(entries []*entry) (err error) {
}
activeEntries := s.getActiveEntries()
for _, ae := range activeEntries {
var activeIds = make([]string, len(activeEntries))
for i, ae := range activeEntries {
ae.SetSub(s.id, true)
activeIds[i] = ae.id
}
s.diff = newListDiff(activeIds)
s.compCountBefore.subId = s.id
s.compCountBefore.prevCount, s.compCountBefore.nextCount = s.counters()
s.compCountBefore.total = s.skl.Len()
if s.ds != nil {
if s.ds != nil && !s.disableDep {
s.depKeys = s.ds.depKeys(s.keys)
if len(s.depKeys) > 0 || len(s.forceSubIds) > 0 {
s.depSub = s.ds.makeSubscriptionByEntries(s.id+"/dep", entries, activeEntries, s.keys, s.depKeys, s.forceSubIds)
@ -121,286 +130,89 @@ func (s *sortedSub) init(entries []*entry) (err error) {
}
func (s *sortedSub) onChange(ctx *opCtx) {
var countersChanged, activeChanged bool
var changed bool
for _, e := range ctx.entries {
ch, ac := s.onEntryChange(ctx, e)
if ch {
countersChanged = true
}
if ac {
activeChanged = true
if !s.onEntryChange(ctx, e) {
changed = true
}
}
if countersChanged {
prev, next := s.counters()
ctx.counters = append(ctx.counters, opCounter{
subId: s.id,
total: s.skl.Len(),
prevCount: prev,
nextCount: next,
})
if !changed {
return
}
if activeChanged && s.depSub != nil {
s.ds.refillSubscription(ctx, s.depSub, s.getActiveEntries(), s.depKeys)
defer s.diff.reset()
s.activeEntriesBuf = s.activeEntriesBuf[:0]
if s.iterateActive(func(e *entry) {
s.diff.fillAfter(e.id)
if s.depSub != nil {
s.activeEntriesBuf = append(s.activeEntriesBuf, e)
}
}) {
s.diff.reverse()
}
s.compCountAfter.subId = s.id
s.compCountAfter.prevCount, s.compCountAfter.nextCount = s.counters()
s.compCountAfter.total = s.skl.Len()
if s.compCountAfter != s.compCountBefore {
ctx.counters = append(ctx.counters, s.compCountAfter)
s.compCountBefore = s.compCountAfter
}
wasAddOrRemove := s.diff.diff(ctx, s.id, s.keys)
hasChanges := false
for _, e := range ctx.entries {
if _, ok := s.diff.afterIdsM[e.id]; ok {
e.SetSub(s.id, true)
ctx.change = append(ctx.change, opChange{
id: e.id,
subId: s.id,
keys: s.keys,
})
hasChanges = true
}
}
if (wasAddOrRemove || hasChanges) && s.depSub != nil {
s.ds.refillSubscription(ctx, s.depSub, s.activeEntriesBuf, s.depKeys)
}
}
func (s *sortedSub) onEntryChange(ctx *opCtx, e *entry) (countersChanged, activeChanged bool) {
func (s *sortedSub) onEntryChange(ctx *opCtx, e *entry) (noChange bool) {
newInSet := true
if s.filter != nil {
newInSet = s.filter.FilterObject(e)
}
curInSet, currInActive := s.lookup(s.cache.Get(e.id))
curr := s.cache.Get(e.id)
curInSet := curr != nil
// nothing
if !curInSet && !newInSet {
return false, false
return true
}
// remove
if curInSet && !newInSet {
if currInActive {
s.removeActive(ctx, e)
activeChanged = true
} else {
s.removeNonActive(e.id)
}
countersChanged = true
s.skl.Remove(curr)
e.RemoveSubId(s.id)
return
}
// add
if !curInSet && newInSet {
return s.add(ctx, e)
s.skl.Set(e, nil)
e.SetSub(s.id, false)
return
}
// change
if curInSet && newInSet {
return s.change(ctx, e, currInActive)
s.skl.Remove(curr)
s.skl.Set(e, nil)
e.SetSub(s.id, false)
return
}
panic("subscription: check algo")
}
func (s *sortedSub) removeNonActive(id string) {
e := s.cache.Get(id)
if s.afterEl != nil {
if comp := s.Compare(s.afterEl.Key(), s.skl.Get(e).Key()); comp <= 0 {
if comp == 0 {
s.afterEl = s.afterEl.Prev()
if s.afterEl != nil {
s.afterId = s.afterEl.Key().(*entry).id
}
}
}
} else if s.beforeEl != nil {
if comp := s.Compare(s.beforeEl.Key(), s.skl.Get(e).Key()); comp >= 0 {
if comp == 0 {
s.beforeEl = s.beforeEl.Next()
if s.beforeEl != nil {
s.beforeId = s.beforeEl.Key().(*entry).id
}
}
}
}
s.skl.Remove(e)
}
func (s *sortedSub) removeActive(ctx *opCtx, e *entry) {
s.skl.Remove(s.cache.Get(e.id))
ctx.remove = append(ctx.remove, opRemove{
id: e.id,
subId: s.id,
})
s.alignAdd(ctx)
}
func (s *sortedSub) add(ctx *opCtx, e *entry) (countersChanged, activeChanged bool) {
s.skl.Set(e, nil)
_, inActive := s.lookup(e)
if inActive {
var afterId string
if prev := s.skl.Get(e).Prev(); prev != nil {
afterId = prev.Key().(*entry).id
}
ctx.add = append(ctx.add, opChange{
id: e.id,
subId: s.id,
keys: s.keys,
afterId: afterId,
})
s.alignRemove(ctx)
e.SetSub(s.id, true)
return true, true
}
e.SetSub(s.id, false)
return true, false
}
func (s *sortedSub) change(ctx *opCtx, e *entry, currInActive bool) (countersChanged, activeChanged bool) {
var currAfterId string
if currInActive {
if prev := s.skl.Get(s.cache.Get(e.id)).Prev(); prev != nil {
currAfterId = prev.Key().(*entry).id
}
}
s.skl.Remove(s.cache.Get(e.id))
s.skl.Set(e, nil)
_, newInActive := s.lookup(e)
if newInActive {
var newAfterId string
if prev := s.skl.Get(e).Prev(); prev != nil {
newAfterId = prev.Key().(*entry).id
}
if currAfterId != newAfterId {
ctx.position = append(ctx.position, opPosition{
id: e.id,
subId: s.id,
afterId: newAfterId,
})
}
if !currInActive {
countersChanged = true
} else {
activeChanged = true
}
ctx.change = append(ctx.change, opChange{
id: e.id,
subId: s.id,
keys: s.keys,
})
e.SetSub(s.id, true)
} else {
if currInActive {
ctx.remove = append(ctx.remove, opRemove{
id: e.id,
subId: s.id,
})
s.alignAdd(ctx)
activeChanged = true
}
countersChanged = true
e.SetSub(s.id, false)
}
return
}
func (s *sortedSub) alignAdd(ctx *opCtx) {
if s.limit > 0 {
if s.beforeEl != nil {
ctx.add = append(ctx.add, opChange{
id: s.beforeEl.Key().(*entry).id,
subId: s.id,
keys: s.keys,
})
s.beforeEl = s.beforeEl.Next()
if s.beforeEl != nil {
s.beforeId = s.beforeEl.Key().(*entry).id
}
} else {
var i int
var next = s.afterEl
if next == nil {
next = s.skl.Front()
} else {
next = next.Next()
}
for next != nil {
i++
if i == s.limit {
break
}
next = next.Next()
}
if next != nil {
afterId := ""
prev := next.Prev()
if prev != nil {
afterId = prev.Key().(*entry).id
}
ctx.add = append(ctx.add, opChange{
id: next.Key().(*entry).id,
afterId: afterId,
subId: s.id,
keys: s.keys,
})
}
}
}
}
func (s *sortedSub) alignRemove(ctx *opCtx) {
if s.limit > 0 {
if s.beforeEl != nil {
ctx.remove = append(ctx.remove, opRemove{
id: s.beforeEl.Key().(*entry).id,
subId: s.id,
})
s.beforeEl = s.beforeEl.Prev()
if s.beforeEl != nil {
s.beforeId = s.beforeEl.Key().(*entry).id
}
} else {
var i int
var next = s.afterEl
if next == nil {
next = s.skl.Front()
} else {
next = next.Next()
}
for next != nil {
if i == s.limit {
break
}
next = next.Next()
i++
}
if next != nil {
ctx.remove = append(ctx.remove, opRemove{
id: next.Key().(*entry).id,
subId: s.id,
})
}
}
}
}
func (s *sortedSub) lookup(e *entry) (inSet, inActive bool) {
if e == nil {
return
}
el := s.skl.Get(e)
if el == nil {
return
}
inSet = true
var (
startEl *skiplist.Element
backward bool
)
if s.afterEl != nil {
startEl = s.afterEl
} else if s.beforeEl != nil {
startEl = s.beforeEl
backward = true
}
if startEl != nil {
comp := s.Compare(startEl.Key(), e)
if comp == 0 {
return
}
if (comp < 0 && backward) || (comp > 0 && !backward) {
return
}
if s.limit > 0 {
if s.inDistance(startEl, e.id, s.limit, backward) {
inActive = true
}
} else {
inActive = true
}
} else if s.limit > 0 {
if s.inDistance(s.skl.Front(), e.id, s.limit-1, false) {
inActive = true
}
} else {
inActive = true
}
return
}
func (s *sortedSub) counters() (prev, next int) {
if s.beforeEl == nil && s.afterEl == nil && s.limit <= 0 {
// no pagination - no counters
@ -452,25 +264,6 @@ func (s *sortedSub) counters() (prev, next int) {
return
}
func (s *sortedSub) inDistance(el *skiplist.Element, id string, distance int, backward bool) bool {
var i int
for el != nil {
if el.Key().(*entry).id == id {
return true
}
i++
if i > distance {
return false
}
if backward {
el = el.Prev()
} else {
el = el.Next()
}
}
return false
}
func (s *sortedSub) getActiveRecords() (res []*types.Struct) {
reverse := s.iterateActive(func(e *entry) {
res = append(res, pbtypes.StructFilterKeys(e.data, s.keys))
@ -548,6 +341,10 @@ func (s *sortedSub) CalcScore(key interface{}) float64 {
return 0
}
func (s *sortedSub) hasDep() bool {
return s.depSub != nil
}
func (s *sortedSub) close() {
el := s.skl.Front()
for el != nil {

View file

@ -11,243 +11,6 @@ import (
"github.com/stretchr/testify/require"
)
func TestSubscription_Internal(t *testing.T) {
t.Run("init", func(t *testing.T) {
t.Run("afterId err", func(t *testing.T) {
sub := &sortedSub{
order: testOrder,
cache: newCache(),
afterId: "id101",
}
require.Equal(t, ErrAfterId, sub.init(genEntries(100, false)))
assert.Len(t, sub.cache.entries, 0)
})
t.Run("beforeId err", func(t *testing.T) {
sub := &sortedSub{
order: testOrder,
cache: newCache(),
beforeId: "id101",
}
require.Equal(t, ErrBeforeId, sub.init(genEntries(100, false)))
assert.Len(t, sub.cache.entries, 0)
})
})
t.Run("lookup", func(t *testing.T) {
t.Run("no limits", func(t *testing.T) {
sub := &sortedSub{
order: testOrder,
cache: newCache(),
}
require.NoError(t, sub.init(genEntries(100, false)))
inSet, inActive := sub.lookup(sub.cache.Get("id50"))
assert.True(t, inSet, "inSet")
assert.True(t, inActive, "inActive")
assert.Len(t, sub.cache.entries, 100)
for _, e := range sub.cache.entries {
assert.Len(t, e.SubIds(), 1)
}
})
t.Run("with limit", func(t *testing.T) {
sub := &sortedSub{
order: testOrder,
cache: newCache(),
limit: 10,
}
require.NoError(t, sub.init(genEntries(100, false)))
inSet, inActive := sub.lookup(sub.cache.Get("id11"))
assert.True(t, inSet, "inSet")
assert.False(t, inActive, "inActive")
inSet, inActive = sub.lookup(sub.cache.Get("id10"))
assert.True(t, inSet, "inSet")
assert.True(t, inActive, "inActive")
})
t.Run("afterId no limit", func(t *testing.T) {
sub := &sortedSub{
order: testOrder,
cache: newCache(),
afterId: "id50",
}
require.NoError(t, sub.init(genEntries(100, false)))
inSet, inActive := sub.lookup(sub.cache.Get("id49"))
assert.True(t, inSet, "inSet")
assert.False(t, inActive, "inActive")
inSet, inActive = sub.lookup(sub.cache.Get("id50"))
assert.True(t, inSet, "inSet")
assert.False(t, inActive, "inActive")
inSet, inActive = sub.lookup(sub.cache.Get("id51"))
assert.True(t, inSet, "inSet")
assert.True(t, inActive, "inActive")
})
t.Run("beforeId no limit", func(t *testing.T) {
sub := &sortedSub{
order: testOrder,
cache: newCache(),
beforeId: "id50",
}
require.NoError(t, sub.init(genEntries(100, false)))
inSet, inActive := sub.lookup(sub.cache.Get("id51"))
assert.True(t, inSet, "inSet")
assert.False(t, inActive, "inActive")
inSet, inActive = sub.lookup(sub.cache.Get("id50"))
assert.True(t, inSet, "inSet")
assert.False(t, inActive, "inActive")
inSet, inActive = sub.lookup(sub.cache.Get("id49"))
assert.True(t, inSet, "inSet")
assert.True(t, inActive, "inActive")
})
t.Run("afterId limit", func(t *testing.T) {
sub := &sortedSub{
order: testOrder,
cache: newCache(),
afterId: "id50",
limit: 10,
}
require.NoError(t, sub.init(genEntries(100, false)))
inSet, inActive := sub.lookup(sub.cache.Get("id49"))
assert.True(t, inSet, "inSet")
assert.False(t, inActive, "inActive")
inSet, inActive = sub.lookup(sub.cache.Get("id60"))
assert.True(t, inSet, "inSet")
assert.True(t, inActive, "inActive")
inSet, inActive = sub.lookup(sub.cache.Get("id61"))
assert.True(t, inSet, "inSet")
assert.False(t, inActive, "inActive")
})
t.Run("beforeId limit", func(t *testing.T) {
sub := &sortedSub{
order: testOrder,
cache: newCache(),
beforeId: "id50",
limit: 10,
}
require.NoError(t, sub.init(genEntries(100, false)))
inSet, inActive := sub.lookup(sub.cache.Get("id51"))
assert.True(t, inSet, "inSet")
assert.False(t, inActive, "inActive")
inSet, inActive = sub.lookup(sub.cache.Get("id40"))
assert.True(t, inSet, "inSet")
assert.True(t, inActive, "inActive")
inSet, inActive = sub.lookup(sub.cache.Get("id39"))
assert.True(t, inSet, "inSet")
assert.False(t, inActive, "inActive")
})
})
t.Run("counters", func(t *testing.T) {
t.Run("no limits", func(t *testing.T) {
sub := &sortedSub{
order: testOrder,
cache: newCache(),
}
require.NoError(t, sub.init(genEntries(6, false)))
prev, next := sub.counters()
assert.Equal(t, 0, prev, "prevCount")
assert.Equal(t, 0, next, "nextCount")
})
t.Run("limit only", func(t *testing.T) {
sub := &sortedSub{
order: testOrder,
cache: newCache(),
limit: 2,
}
require.NoError(t, sub.init(genEntries(6, false)))
prev, next := sub.counters()
assert.Equal(t, 0, prev, "prevCount")
assert.Equal(t, 4, next, "nextCount")
})
t.Run("afterId no limit", func(t *testing.T) {
sub := &sortedSub{
order: testOrder,
cache: newCache(),
afterId: "id2",
}
require.NoError(t, sub.init(genEntries(6, false)))
prev, next := sub.counters()
assert.Equal(t, 2, prev, "prevCount")
assert.Equal(t, 0, next, "nextCount")
})
t.Run("beforeId no limit", func(t *testing.T) {
sub := &sortedSub{
order: testOrder,
cache: newCache(),
beforeId: "id3",
}
require.NoError(t, sub.init(genEntries(6, false)))
prev, next := sub.counters()
assert.Equal(t, 0, prev, "prevCount")
assert.Equal(t, 4, next, "nextCount")
})
t.Run("afterId with limit", func(t *testing.T) {
sub := &sortedSub{
order: testOrder,
cache: newCache(),
afterId: "id2",
limit: 2,
}
require.NoError(t, sub.init(genEntries(6, false)))
prev, next := sub.counters()
assert.Equal(t, 2, prev, "prevCount")
assert.Equal(t, 2, next, "nextCount")
})
t.Run("beforeId with limit", func(t *testing.T) {
sub := &sortedSub{
order: testOrder,
cache: newCache(),
beforeId: "id5",
limit: 2,
}
require.NoError(t, sub.init(genEntries(6, false)))
prev, next := sub.counters()
assert.Equal(t, 2, prev, "prevCount")
assert.Equal(t, 2, next, "nextCount")
})
t.Run("limit only - big limit", func(t *testing.T) {
sub := &sortedSub{
order: testOrder,
cache: newCache(),
limit: 20,
}
require.NoError(t, sub.init(genEntries(6, false)))
prev, next := sub.counters()
assert.Equal(t, 0, prev, "prevCount")
assert.Equal(t, 0, next, "nextCount")
})
t.Run("afterId - big limit", func(t *testing.T) {
sub := &sortedSub{
order: testOrder,
cache: newCache(),
limit: 20,
afterId: "id2",
}
require.NoError(t, sub.init(genEntries(6, false)))
prev, next := sub.counters()
assert.Equal(t, 2, prev, "prevCount")
assert.Equal(t, 0, next, "nextCount")
})
t.Run("beforeId - big limit", func(t *testing.T) {
sub := &sortedSub{
order: testOrder,
cache: newCache(),
limit: 20,
beforeId: "id5",
}
require.NoError(t, sub.init(genEntries(6, false)))
prev, next := sub.counters()
assert.Equal(t, 0, prev, "prevCount")
assert.Equal(t, 2, next, "nextCount")
})
})
}
func TestSubscription_Add(t *testing.T) {
t.Run("add", func(t *testing.T) {
sub := &sortedSub{
@ -270,7 +33,7 @@ func TestSubscription_Add(t *testing.T) {
ctx := &opCtx{c: sub.cache, entries: newEntries}
sub.onChange(ctx)
assertCtxAdd(t, ctx, "newActiveId1", "id3")
assertCtxAdd(t, ctx, "newActiveId1", "")
assertCtxAdd(t, ctx, "newActiveId2", "newActiveId1")
assertCtxRemove(t, ctx, "id5", "id6")
assertCtxCounters(t, ctx, opCounter{subId: "test", total: 14, prevCount: 4, nextCount: 7})
@ -338,7 +101,7 @@ func TestSubscription_Change(t *testing.T) {
data: &types.Struct{Fields: map[string]*types.Value{"id": pbtypes.String("id4"), "order": pbtypes.Int64(6)}},
})
sub.onChange(ctx)
assertCtxPosition(t, ctx, "id4", "id5")
assertCtxPosition(t, ctx, "id5", "")
assertCtxChange(t, ctx, "id4")
})
}

View file

@ -40,10 +40,11 @@ func genEntry(id string, ord int64) *entry {
func assertCtxAdd(t *testing.T, ctx *opCtx, id, afterId string) {
var found bool
for _, add := range ctx.add {
if add.id == id {
for _, add := range ctx.position {
if add.isAdd && add.id == id {
found = true
assert.Equal(t, afterId, add.afterId, "add after id not equal")
break
}
}
assert.True(t, found, fmt.Sprintf("add id %v not found", id))
@ -55,6 +56,7 @@ func assertCtxPosition(t *testing.T, ctx *opCtx, id, afterId string) {
if pos.id == id {
found = true
assert.Equal(t, afterId, pos.afterId, "pos after id not equal")
break
}
}
assert.True(t, found, fmt.Sprintf("pos id %v not found", id))
@ -93,7 +95,6 @@ func assertCtxChange(t *testing.T, ctx *opCtx, ids ...string) {
}
func assertCtxEmpty(t *testing.T, ctx *opCtx) {
assert.Len(t, ctx.add, 0, "add not empty")
assert.Len(t, ctx.remove, 0, "remove not empty")
assert.Len(t, ctx.counters, 0, "counters not empty")
assert.Len(t, ctx.change, 0, "change not empty")

View file

@ -271,6 +271,10 @@
- [Rpc.Block.Set.Text.Color.Request](#anytype.Rpc.Block.Set.Text.Color.Request)
- [Rpc.Block.Set.Text.Color.Response](#anytype.Rpc.Block.Set.Text.Color.Response)
- [Rpc.Block.Set.Text.Color.Response.Error](#anytype.Rpc.Block.Set.Text.Color.Response.Error)
- [Rpc.Block.Set.Text.Icon](#anytype.Rpc.Block.Set.Text.Icon)
- [Rpc.Block.Set.Text.Icon.Request](#anytype.Rpc.Block.Set.Text.Icon.Request)
- [Rpc.Block.Set.Text.Icon.Response](#anytype.Rpc.Block.Set.Text.Icon.Response)
- [Rpc.Block.Set.Text.Icon.Response.Error](#anytype.Rpc.Block.Set.Text.Icon.Response.Error)
- [Rpc.Block.Set.Text.Style](#anytype.Rpc.Block.Set.Text.Style)
- [Rpc.Block.Set.Text.Style.Request](#anytype.Rpc.Block.Set.Text.Style.Request)
- [Rpc.Block.Set.Text.Style.Response](#anytype.Rpc.Block.Set.Text.Style.Response)
@ -744,6 +748,7 @@
- [Rpc.Block.Set.Restrictions.Response.Error.Code](#anytype.Rpc.Block.Set.Restrictions.Response.Error.Code)
- [Rpc.Block.Set.Text.Checked.Response.Error.Code](#anytype.Rpc.Block.Set.Text.Checked.Response.Error.Code)
- [Rpc.Block.Set.Text.Color.Response.Error.Code](#anytype.Rpc.Block.Set.Text.Color.Response.Error.Code)
- [Rpc.Block.Set.Text.Icon.Response.Error.Code](#anytype.Rpc.Block.Set.Text.Icon.Response.Error.Code)
- [Rpc.Block.Set.Text.Style.Response.Error.Code](#anytype.Rpc.Block.Set.Text.Style.Response.Error.Code)
- [Rpc.Block.Set.Text.Text.Response.Error.Code](#anytype.Rpc.Block.Set.Text.Text.Response.Error.Code)
- [Rpc.Block.Set.Video.Name.Response.Error.Code](#anytype.Rpc.Block.Set.Video.Name.Response.Error.Code)
@ -936,6 +941,8 @@
- [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)
@ -1154,6 +1161,7 @@
| BlockListSetTextMark | [Rpc.BlockList.Set.Text.Mark.Request](#anytype.Rpc.BlockList.Set.Text.Mark.Request) | [Rpc.BlockList.Set.Text.Mark.Response](#anytype.Rpc.BlockList.Set.Text.Mark.Response) | |
| BlockSetTextStyle | [Rpc.Block.Set.Text.Style.Request](#anytype.Rpc.Block.Set.Text.Style.Request) | [Rpc.Block.Set.Text.Style.Response](#anytype.Rpc.Block.Set.Text.Style.Response) | |
| BlockSetTextChecked | [Rpc.Block.Set.Text.Checked.Request](#anytype.Rpc.Block.Set.Text.Checked.Request) | [Rpc.Block.Set.Text.Checked.Response](#anytype.Rpc.Block.Set.Text.Checked.Response) | |
| BlockSetTextIcon | [Rpc.Block.Set.Text.Icon.Request](#anytype.Rpc.Block.Set.Text.Icon.Request) | [Rpc.Block.Set.Text.Icon.Response](#anytype.Rpc.Block.Set.Text.Icon.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) | |
@ -1708,7 +1716,6 @@ Front end to middleware request-to-create-an account
| ----- | ---- | ----- | ----------- |
| name | [string](#string) | | Account name |
| avatarLocalPath | [string](#string) | | Path to an image, that will be used as an avatar of this account |
| avatarColor | [string](#string) | | Avatar color as an alternative for avatar image |
| alphaInviteCode | [string](#string) | | |
@ -5162,6 +5169,66 @@ Image/Video/File blocks then:
<a name="anytype.Rpc.Block.Set.Text.Icon"></a>
### Rpc.Block.Set.Text.Icon
<a name="anytype.Rpc.Block.Set.Text.Icon.Request"></a>
### Rpc.Block.Set.Text.Icon.Request
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| contextId | [string](#string) | | |
| blockId | [string](#string) | | |
| iconImage | [string](#string) | | in case both image and emoji are set, image has a priority to show |
| iconEmoji | [string](#string) | | |
<a name="anytype.Rpc.Block.Set.Text.Icon.Response"></a>
### Rpc.Block.Set.Text.Icon.Response
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| error | [Rpc.Block.Set.Text.Icon.Response.Error](#anytype.Rpc.Block.Set.Text.Icon.Response.Error) | | |
| event | [ResponseEvent](#anytype.ResponseEvent) | | |
<a name="anytype.Rpc.Block.Set.Text.Icon.Response.Error"></a>
### Rpc.Block.Set.Text.Icon.Response.Error
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| code | [Rpc.Block.Set.Text.Icon.Response.Error.Code](#anytype.Rpc.Block.Set.Text.Icon.Response.Error.Code) | | |
| description | [string](#string) | | |
<a name="anytype.Rpc.Block.Set.Text.Style"></a>
### Rpc.Block.Set.Text.Style
@ -9148,6 +9215,7 @@ deprecated, to be removed |
| beforeId | [string](#string) | | (optional) pagination: middleware will return results before given id |
| source | [string](#string) | repeated | |
| ignoreWorkspace | [string](#string) | | |
| noDepSubscription | [bool](#bool) | | disable dependent subscription |
@ -11196,6 +11264,9 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er
| ACCOUNT_CREATED_BUT_FAILED_TO_SET_AVATAR | 103 | |
| FAILED_TO_STOP_RUNNING_NODE | 104 | |
| BAD_INVITE_CODE | 900 | |
| NET_ERROR | 901 | means general network error |
| NET_CONNECTION_REFUSED | 902 | means we wasn&#39;t able to connect to the cafe server |
| NET_OFFLINE | 903 | client can additionally support this error code to notify user that device is offline |
@ -11926,6 +11997,19 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er
<a name="anytype.Rpc.Block.Set.Text.Icon.Response.Error.Code"></a>
### Rpc.Block.Set.Text.Icon.Response.Error.Code
| Name | Number | Description |
| ---- | ------ | ----------- |
| NULL | 0 | |
| UNKNOWN_ERROR | 1 | |
| BAD_INPUT | 2 | ... |
<a name="anytype.Rpc.Block.Set.Text.Style.Response.Error.Code"></a>
### Rpc.Block.Set.Text.Style.Response.Error.Code
@ -12719,6 +12803,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er
| NULL | 0 | |
| UNKNOWN_ERROR | 1 | |
| BAD_INPUT | 2 | |
| ALREADY_EXISTS | 10 | |
@ -14642,6 +14727,8 @@ Precondition: user A opened a block
| 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) | | |
@ -14678,6 +14765,36 @@ Precondition: user A opened a block
<a name="anytype.Event.Block.Set.Text.IconEmoji"></a>
### Event.Block.Set.Text.IconEmoji
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| value | [string](#string) | | |
<a name="anytype.Event.Block.Set.Text.IconImage"></a>
### Event.Block.Set.Text.IconImage
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| value | [string](#string) | | |
<a name="anytype.Event.Block.Set.Text.Marks"></a>
### Event.Block.Set.Text.Marks
@ -16052,6 +16169,8 @@ Link: block to link some content from an external sources.
| 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 |
| iconImage | [string](#string) | | in case both image and emoji are set, image should has a priority in the UI |
@ -16625,6 +16744,7 @@ scope from which this relation have been aggregated |
| Numbered | 10 | |
| Toggle | 11 | |
| Description | 12 | currently only only one block of this style can exists on a page |
| Callout | 13 | currently only only one block of this style can exists on a page |

5
go.mod
View file

@ -10,7 +10,8 @@ require (
github.com/anytypeio/go-slip10 v0.0.0-20200330112030-a352ca8495e4
github.com/anytypeio/go-slip21 v0.0.0-20200218204727-e2e51e20ab51
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
github.com/blevesearch/bleve v1.0.14
github.com/blevesearch/bleve/v2 v2.3.0 // indirect
github.com/blevesearch/bleve_index_api v1.0.1 // indirect
github.com/cheggaaa/mb v1.0.3
github.com/dave/jennifer v1.4.1
github.com/dgraph-io/badger v1.6.2
@ -101,7 +102,7 @@ require (
replace github.com/JohannesKaufmann/html-to-markdown => github.com/anytypeio/html-to-markdown v0.0.0-20200617145221-2afd2a14bae1
replace github.com/textileio/go-threads => github.com/anytypeio/go-threads v1.1.0-rc1.0.20211224084450-be1392aa8d22
replace github.com/textileio/go-threads => github.com/anytypeio/go-threads v1.1.0-rc1.0.20220212122526-59f785ec84c5
replace github.com/msingleton/amplitude-go => github.com/anytypeio/amplitude-go v0.0.0-20211130222238-8d16496a9b31

430
go.sum

File diff suppressed because it is too large Load diff

View file

@ -69,6 +69,34 @@ func (t *threadsMetrics) CreateRecord(threadId string, prepareMs int64, newRecor
})
}
func (t *threadsMetrics) NumberOfRecordsSentForLog(num int) {}
func (t *threadsMetrics) NumberOfRecordsSentTotal(num int) {}
func (t *threadsMetrics) GetRecordsGetThreadDuration(duration time.Duration) {}
func (t *threadsMetrics) GetRecordsHeadsChangedDuration(duration time.Duration) {}
func (t *threadsMetrics) GetLocalRecordsGetLogDuration(duration time.Duration) {}
func (t *threadsMetrics) GetLocalRecordsCborGetRecordsDuration(duration time.Duration) {}
func (t *threadsMetrics) UpdateRecordsDuration(duration time.Duration) {}
func (t *threadsMetrics) SemaphoreAcquireDuration(duration time.Duration) {}
func (t *threadsMetrics) SemaphoreHoldDuration(duration time.Duration) {}
func (t *threadsMetrics) SemaphoreAcquire() {}
func (t *threadsMetrics) ThreadServed() {}
func (t *threadsMetrics) ThreadPulled() {}
func (t *threadsMetrics) ThreadPullDuration(duration time.Duration) {}
func (t *threadsMetrics) UpdateRecordsDelayAfterExchangeEdges(duration time.Duration) {}
var (
Enabled bool
once sync.Once

View file

@ -7,9 +7,9 @@
"build:protos": "webpack -o ./build/web/commands-web.js ./build/web/pb/protos/service/service_grpc_web_pb.js"
},
"dependencies": {
"google-protobuf": "^3.6.1",
"grpc-web": "latest",
"protobufjs": "^6.8.8"
"google-protobuf": "~3.19.4",
"grpc-web": "~1.3.1",
"protobufjs": "~6.11.2"
},
"devDependencies": {
"webpack": "^4.16.5",

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -933,7 +933,6 @@ message Rpc {
}
}
message Style {
message Request {
string contextId = 1;
@ -983,6 +982,32 @@ message Rpc {
}
}
}
message Icon {
message Request {
string contextId = 1;
string blockId = 2;
string iconImage = 3; // in case both image and emoji are set, image has a priority to show
string iconEmoji = 5;
}
message Response {
Error error = 1;
ResponseEvent event = 2;
message Error {
Code code = 1;
string description = 2;
enum Code {
NULL = 0;
UNKNOWN_ERROR = 1;
BAD_INPUT = 2;
// ...
}
}
}
}
}
message File {
@ -2318,7 +2343,6 @@ message Rpc {
string name = 1; // Account name
oneof avatar {
string avatarLocalPath = 2; // Path to an image, that will be used as an avatar of this account
string avatarColor = 3; // Avatar color as an alternative for avatar image
}
@ -2347,6 +2371,10 @@ message Rpc {
FAILED_TO_STOP_RUNNING_NODE = 104;
BAD_INVITE_CODE = 900;
NET_ERROR = 901; // means general network error
NET_CONNECTION_REFUSED = 902; // means we wasn't able to connect to the cafe server
NET_OFFLINE = 903; // client can additionally support this error code to notify user that device is offline
}
}
}
@ -3175,6 +3203,7 @@ message Rpc {
NULL = 0;
UNKNOWN_ERROR = 1;
BAD_INPUT = 2;
ALREADY_EXISTS = 10;
}
}
}
@ -3429,6 +3458,8 @@ message Rpc {
repeated string source = 10;
string ignoreWorkspace = 12;
// disable dependent subscription
bool noDepSubscription = 13;
}
message Response {

View file

@ -303,6 +303,8 @@ message Event {
Marks marks = 4;
Checked checked = 5;
Color color = 6;
IconEmoji iconEmoji = 7;
IconImage iconImage = 8;
message Text {
string value = 1;
@ -324,6 +326,13 @@ message Event {
string value = 1;
}
message IconEmoji {
string value = 1;
}
message IconImage {
string value = 1;
}
}
message Latex {
string id = 1;

View file

@ -83,6 +83,7 @@ service ClientCommands {
rpc BlockListSetTextMark (anytype.Rpc.BlockList.Set.Text.Mark.Request) returns (anytype.Rpc.BlockList.Set.Text.Mark.Response);
rpc BlockSetTextStyle (anytype.Rpc.Block.Set.Text.Style.Request) returns (anytype.Rpc.Block.Set.Text.Style.Response);
rpc BlockSetTextChecked (anytype.Rpc.Block.Set.Text.Checked.Request) returns (anytype.Rpc.Block.Set.Text.Checked.Response);
rpc BlockSetTextIcon (anytype.Rpc.Block.Set.Text.Icon.Request) returns (anytype.Rpc.Block.Set.Text.Icon.Response);
rpc BlockSplit (anytype.Rpc.Block.Split.Request) returns (anytype.Rpc.Block.Split.Response);
rpc BlockMerge (anytype.Rpc.Block.Merge.Request) returns (anytype.Rpc.Block.Merge.Response);

View file

@ -26,197 +26,197 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
func init() { proto.RegisterFile("pb/protos/service/service.proto", fileDescriptor_93a29dc403579097) }
var fileDescriptor_93a29dc403579097 = []byte{
// 3026 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x9b, 0x5b, 0x6f, 0xdc, 0xc6,
0x15, 0x80, 0xb3, 0x40, 0x91, 0xa4, 0x93, 0xc4, 0x71, 0xd8, 0x3a, 0xb1, 0xe5, 0x54, 0xbe, 0xc4,
0xf2, 0x45, 0xb6, 0x28, 0x59, 0x6e, 0x53, 0xf4, 0x1a, 0x48, 0x2b, 0x5b, 0x16, 0x22, 0xdb, 0xaa,
0x56, 0xb2, 0x8a, 0xf4, 0x4a, 0x91, 0xe3, 0x5d, 0x46, 0x5c, 0x0e, 0x43, 0xce, 0xae, 0xbc, 0x01,
0x5a, 0xf4, 0x86, 0x02, 0x7d, 0x0b, 0xd0, 0xc7, 0x3e, 0xf5, 0xa9, 0x40, 0x7f, 0x49, 0x1f, 0xf3,
0xd8, 0xc7, 0xc2, 0xfe, 0x23, 0xc5, 0x70, 0x0e, 0x67, 0x38, 0xc3, 0x99, 0x21, 0xd7, 0x4f, 0x82,
0x78, 0xbe, 0x73, 0xe1, 0xf0, 0xcc, 0x99, 0x33, 0xe4, 0x2c, 0xba, 0x94, 0x1d, 0xaf, 0x66, 0x39,
0xa1, 0xa4, 0x58, 0x2d, 0x70, 0x3e, 0x8d, 0x43, 0x5c, 0xfd, 0xf5, 0xcb, 0xcb, 0xde, 0x1b, 0x41,
0x3a, 0xa3, 0xb3, 0x0c, 0x2f, 0x9c, 0x97, 0x64, 0x48, 0xc6, 0xe3, 0x20, 0x8d, 0x0a, 0x8e, 0x2c,
0xbc, 0x2f, 0x25, 0x78, 0x8a, 0x53, 0x0a, 0xd7, 0xd7, 0xff, 0xf5, 0x25, 0x3a, 0xd3, 0x4f, 0x62,
0x9c, 0xd2, 0x3e, 0x28, 0x78, 0x39, 0x3a, 0xf7, 0xe4, 0xf8, 0x73, 0x1c, 0xd2, 0x8d, 0x28, 0x3a,
0x8a, 0xe9, 0x88, 0xff, 0xb3, 0x13, 0x79, 0xb7, 0x7d, 0xf0, 0xe3, 0xef, 0x67, 0xa1, 0xcf, 0x2f,
0xfb, 0x1a, 0xe4, 0xef, 0xe3, 0x2f, 0x26, 0xb8, 0xa0, 0x0b, 0x77, 0xba, 0xc1, 0x45, 0x46, 0xd2,
0x02, 0x7b, 0xcf, 0xd0, 0x7b, 0xfc, 0xe2, 0x60, 0x14, 0xe4, 0x78, 0x73, 0xb6, 0x1b, 0xa7, 0x27,
0xde, 0x0d, 0x93, 0x89, 0x1a, 0x20, 0x7c, 0xdd, 0x6c, 0x07, 0xc1, 0xcf, 0x11, 0x7a, 0xfb, 0x28,
0x48, 0x12, 0x4c, 0xfb, 0x39, 0x0e, 0x28, 0xf6, 0xae, 0x2a, 0x9a, 0x5c, 0xe4, 0x73, 0x99, 0xb0,
0xfe, 0x91, 0x93, 0x01, 0xc3, 0x9f, 0xa1, 0x77, 0xb8, 0x64, 0x1f, 0x87, 0x64, 0x8a, 0x73, 0xcf,
0xa8, 0x05, 0x42, 0x61, 0xfa, 0x9a, 0x1b, 0xd2, 0x6d, 0xf7, 0x49, 0x3a, 0xc5, 0x39, 0x35, 0xdb,
0x06, 0xa1, 0xdb, 0xb6, 0x84, 0xc0, 0xf6, 0x6f, 0xd1, 0xbb, 0x47, 0x24, 0x3f, 0x29, 0xb2, 0x20,
0xc4, 0x30, 0x26, 0x4b, 0xaa, 0x62, 0x25, 0xd5, 0x87, 0xe5, 0x7a, 0x1b, 0x66, 0xf0, 0x30, 0xc0,
0x09, 0x0e, 0xa9, 0xd5, 0x03, 0x17, 0xb7, 0x7a, 0x10, 0x18, 0x78, 0x48, 0xd0, 0xb7, 0x84, 0x70,
0x1b, 0xd3, 0xfe, 0x24, 0xcf, 0x71, 0x4a, 0xbd, 0x5b, 0x16, 0x75, 0x89, 0x08, 0x4f, 0xcb, 0x5d,
0x50, 0xc3, 0xfd, 0x6c, 0x63, 0xba, 0x91, 0x24, 0xd6, 0xfb, 0xe1, 0xe2, 0xd6, 0xfb, 0x11, 0x18,
0x78, 0xf8, 0x3d, 0xba, 0x50, 0x1b, 0x31, 0xba, 0x53, 0x3c, 0x8c, 0x87, 0xa3, 0x24, 0x1e, 0x8e,
0x28, 0x8e, 0xbc, 0x55, 0xeb, 0xa0, 0xa8, 0xa0, 0xf0, 0xba, 0xd6, 0x5d, 0x01, 0xfc, 0xff, 0x0a,
0x9d, 0xd9, 0x08, 0x43, 0x32, 0x49, 0x45, 0x32, 0xab, 0xb9, 0x04, 0xc2, 0x46, 0x36, 0x2f, 0xb5,
0x50, 0x32, 0x9d, 0x41, 0x06, 0x09, 0xf7, 0x91, 0x51, 0x4f, 0x4b, 0xb7, 0x6b, 0x6e, 0xa8, 0x61,
0x1b, 0x52, 0xcd, 0x6c, 0x5b, 0x4b, 0xb4, 0x6b, 0x6e, 0x08, 0x6c, 0x1f, 0xa0, 0xb7, 0x2a, 0xdb,
0x94, 0x64, 0xde, 0x15, 0xb3, 0x12, 0x25, 0x99, 0xb0, 0x7b, 0xd5, 0x85, 0x48, 0xab, 0x0f, 0xe2,
0x04, 0x3f, 0x79, 0xf6, 0x2c, 0x21, 0x41, 0xa4, 0x59, 0x65, 0x12, 0x1f, 0x44, 0x16, 0xab, 0x1a,
0x22, 0x93, 0x94, 0x09, 0x76, 0xe3, 0x82, 0x56, 0x96, 0x97, 0x1a, 0x6a, 0x4c, 0xda, 0xb0, 0x7e,
0xbd, 0x0d, 0x03, 0x0f, 0x3f, 0x43, 0xe8, 0x29, 0xce, 0x8b, 0x98, 0xa4, 0xdb, 0x98, 0x7a, 0x97,
0x15, 0x2d, 0x10, 0xb0, 0xc4, 0x16, 0x76, 0xaf, 0x38, 0x08, 0x30, 0xf9, 0x10, 0xbd, 0xb1, 0x4b,
0x86, 0x03, 0x9c, 0x46, 0xde, 0x77, 0x14, 0x7a, 0x97, 0x0c, 0x7d, 0x76, 0x59, 0x18, 0x5b, 0xb4,
0x89, 0xc1, 0xd2, 0x63, 0xf4, 0xcd, 0x3e, 0x49, 0x9f, 0xc5, 0x43, 0x16, 0xdb, 0x25, 0x05, 0xe6,
0xd7, 0x95, 0xd0, 0x2e, 0xdb, 0x01, 0xb0, 0xb7, 0x83, 0xde, 0x1c, 0x8c, 0x26, 0x34, 0x22, 0xa7,
0xa9, 0x16, 0x5a, 0x75, 0xd9, 0x12, 0x5a, 0x4d, 0x2c, 0x57, 0xba, 0xfb, 0xcf, 0x29, 0xce, 0xd3,
0x20, 0xd9, 0xca, 0x49, 0xc6, 0x06, 0xb8, 0xd0, 0x56, 0xba, 0xba, 0xbc, 0x7c, 0x02, 0x85, 0x65,
0xa5, 0x33, 0x82, 0xb2, 0x28, 0xd6, 0xc5, 0x7d, 0x92, 0xd2, 0x66, 0x51, 0x54, 0x0c, 0x00, 0x62,
0x29, 0x8a, 0x16, 0x14, 0xbc, 0xed, 0xa3, 0xb7, 0xd8, 0x42, 0xbb, 0x97, 0xe3, 0x69, 0x8c, 0x4f,
0xb5, 0x74, 0xa8, 0x49, 0x2c, 0xe9, 0xa0, 0x12, 0x60, 0xf3, 0x09, 0x42, 0x87, 0x19, 0x4b, 0x3a,
0x76, 0x67, 0xda, 0x53, 0x94, 0x02, 0xcb, 0x53, 0x54, 0x00, 0x30, 0x78, 0x88, 0xde, 0xde, 0x22,
0xa7, 0xa9, 0x30, 0xa9, 0xc6, 0x50, 0x17, 0x59, 0xe6, 0x9a, 0x86, 0xc8, 0x19, 0xbc, 0x99, 0x90,
0xf0, 0x84, 0xbb, 0xd4, 0xac, 0x96, 0x12, 0x88, 0xc6, 0x62, 0x55, 0x43, 0x64, 0xa7, 0x52, 0x0a,
0xf6, 0x71, 0x96, 0x04, 0xa1, 0xde, 0xa9, 0x70, 0x1d, 0x90, 0x59, 0x3a, 0x15, 0x9d, 0x01, 0xc3,
0x31, 0xf2, 0x20, 0xdc, 0x28, 0xa0, 0xb8, 0xca, 0x8b, 0x9b, 0xc6, 0x90, 0x6a, 0x84, 0x70, 0x72,
0xab, 0x03, 0x29, 0xa7, 0x61, 0x29, 0x7f, 0x92, 0xe1, 0x54, 0x7b, 0x80, 0x5c, 0x8f, 0x09, 0x2c,
0x0f, 0x50, 0x01, 0x34, 0x7b, 0x83, 0x11, 0x39, 0x35, 0xda, 0x63, 0x02, 0xa7, 0x3d, 0x00, 0xc0,
0x1e, 0x41, 0xdf, 0x2e, 0x2f, 0x6f, 0x63, 0xba, 0x37, 0x39, 0x4e, 0xe2, 0xf0, 0x08, 0x1f, 0x1f,
0xee, 0xef, 0x7a, 0xcb, 0x06, 0x4d, 0x8d, 0x11, 0x5e, 0x6e, 0x77, 0x62, 0x35, 0x87, 0xec, 0xb6,
0x36, 0x73, 0x1c, 0x44, 0x61, 0x3e, 0x19, 0x1f, 0x17, 0x46, 0x87, 0x1a, 0xe3, 0x74, 0xd8, 0x64,
0x65, 0x15, 0xe0, 0x23, 0x86, 0x69, 0xdd, 0x9f, 0xe9, 0x19, 0xaa, 0x88, 0xa5, 0x0a, 0x58, 0x50,
0x6d, 0x26, 0xc0, 0xba, 0x6e, 0x9a, 0x09, 0xda, 0xaa, 0x7e, 0xd5, 0x85, 0xc8, 0xb5, 0xac, 0x66,
0x75, 0x2f, 0x18, 0xea, 0x2d, 0x6a, 0x5d, 0x8d, 0x89, 0x2d, 0x6b, 0x99, 0x01, 0x93, 0x0d, 0x4f,
0xcd, 0xc3, 0x00, 0x53, 0xad, 0xe1, 0xa9, 0x6b, 0x0e, 0x6a, 0x0b, 0xc7, 0x52, 0x0b, 0xa5, 0x17,
0x88, 0x34, 0x61, 0xdb, 0x1a, 0x63, 0x81, 0x28, 0x45, 0xee, 0x02, 0x51, 0x21, 0x72, 0x01, 0xe6,
0x41, 0x27, 0xa4, 0xc0, 0x9e, 0x29, 0xd9, 0x4b, 0x89, 0xa5, 0xe2, 0xaa, 0x84, 0xec, 0x9e, 0xca,
0xeb, 0x55, 0x9d, 0xf3, 0x4c, 0x05, 0xa5, 0x12, 0x5a, 0xba, 0xa7, 0x06, 0x04, 0xb6, 0x7f, 0x09,
0xb6, 0xb7, 0x31, 0x7d, 0x14, 0xe4, 0x27, 0x85, 0x71, 0x88, 0xd9, 0xa2, 0x5b, 0x4a, 0x9d, 0x43,
0x5c, 0xa7, 0xb4, 0xca, 0x70, 0x98, 0x46, 0xc4, 0x58, 0x19, 0x98, 0xc0, 0x59, 0x19, 0x00, 0xd0,
0xec, 0xed, 0x63, 0x8b, 0x3d, 0x26, 0x70, 0xda, 0x03, 0x00, 0xec, 0xfd, 0x06, 0x32, 0x6c, 0x80,
0xe9, 0x83, 0x18, 0x27, 0x51, 0x61, 0x4c, 0x61, 0x96, 0x35, 0x5c, 0xec, 0x4c, 0x61, 0x05, 0x03,
0x07, 0x5f, 0x40, 0x65, 0x19, 0xb0, 0x1d, 0x68, 0x41, 0xf3, 0x38, 0xa4, 0x31, 0x49, 0x0b, 0xef,
0xb6, 0x45, 0xbf, 0x0e, 0x59, 0xf6, 0xec, 0x56, 0x58, 0xcb, 0x16, 0xd6, 0x1f, 0x3e, 0x22, 0x53,
0x6c, 0xca, 0x96, 0xb2, 0x77, 0x64, 0x42, 0x57, 0xb6, 0xd4, 0x21, 0xb0, 0x3d, 0x41, 0xef, 0x2b,
0xb6, 0x0f, 0xc8, 0x63, 0x7c, 0x5a, 0x4e, 0xfd, 0x3b, 0x0e, 0x7d, 0x41, 0x09, 0x6f, 0x2b, 0x1d,
0x69, 0x70, 0xfb, 0x55, 0x0f, 0x5d, 0x12, 0x10, 0xec, 0x95, 0xfb, 0xa3, 0x38, 0x89, 0x72, 0x9c,
0x1e, 0x10, 0xc6, 0x16, 0xde, 0xf7, 0x2c, 0x26, 0xcd, 0xb8, 0x88, 0xe4, 0xe3, 0x79, 0xd5, 0x20,
0xa4, 0x13, 0x58, 0xae, 0x19, 0x2c, 0xb3, 0xe7, 0x96, 0xc5, 0x9a, 0x21, 0x83, 0x96, 0xbb, 0xa0,
0xe0, 0x6c, 0x8a, 0xce, 0xd5, 0x9d, 0x1d, 0xe0, 0xe7, 0x74, 0x40, 0x67, 0x09, 0xf6, 0x56, 0x1c,
0x46, 0x18, 0xe5, 0x97, 0x98, 0xf0, 0xe9, 0x77, 0xc5, 0xb5, 0x9e, 0x84, 0x41, 0x5b, 0x93, 0x2c,
0x89, 0x43, 0xb6, 0x7e, 0xdc, 0xb4, 0x58, 0x11, 0x84, 0xab, 0x27, 0x69, 0x90, 0xe0, 0xea, 0xaf,
0x3d, 0x74, 0xb1, 0x7e, 0x8f, 0x9b, 0x41, 0x78, 0x32, 0xcc, 0xc9, 0x24, 0x8d, 0xfa, 0x24, 0x21,
0xb9, 0xb7, 0xee, 0x08, 0x5d, 0x63, 0x85, 0xfb, 0x7b, 0x73, 0xe9, 0x40, 0x20, 0x23, 0xf4, 0x5e,
0x3d, 0x8e, 0x8d, 0x24, 0x1e, 0xa6, 0xd6, 0x5b, 0x66, 0x96, 0x4a, 0xa2, 0xf5, 0x96, 0xeb, 0x24,
0x78, 0x2a, 0xa0, 0x36, 0x80, 0xa7, 0xad, 0x78, 0xca, 0x1f, 0xea, 0x1d, 0x87, 0x89, 0xad, 0x78,
0xaa, 0x3d, 0xd3, 0x95, 0x8e, 0xb4, 0x39, 0x95, 0x58, 0xcb, 0xdc, 0x9e, 0x4a, 0x65, 0x63, 0xdd,
0x3d, 0x95, 0x14, 0x5c, 0xee, 0xaf, 0x04, 0x74, 0x30, 0xc9, 0xd3, 0x9d, 0x94, 0x12, 0x6d, 0x7f,
0x25, 0x8d, 0x54, 0x80, 0x65, 0x7f, 0x65, 0x04, 0xc1, 0xcf, 0xe7, 0xe0, 0x67, 0x80, 0xe9, 0x6e,
0x40, 0xf1, 0x73, 0x96, 0xd6, 0xb6, 0xbe, 0xca, 0x2f, 0x09, 0x9e, 0xf9, 0x2d, 0x7d, 0x95, 0x8a,
0x82, 0xaf, 0x21, 0x3a, 0x5b, 0xf9, 0x62, 0x82, 0xd2, 0xd5, 0x4d, 0x8b, 0x7e, 0xa9, 0xa9, 0x78,
0xba, 0xd5, 0x81, 0x6c, 0xde, 0x14, 0x13, 0xf0, 0x19, 0xe1, 0xd4, 0x57, 0x27, 0xc2, 0x72, 0x17,
0xd4, 0x5e, 0x6b, 0xb8, 0xbf, 0xd6, 0x5a, 0xa3, 0xfa, 0xf4, 0xbb, 0xe2, 0xe6, 0xd9, 0xc0, 0x10,
0xd6, 0x4c, 0x38, 0x67, 0x43, 0x69, 0x87, 0x51, 0x9d, 0x66, 0x43, 0x9d, 0x36, 0x0f, 0x2c, 0x9f,
0x09, 0xce, 0x81, 0x55, 0x67, 0xc1, 0x72, 0x17, 0x14, 0x7c, 0x65, 0xb2, 0xe7, 0x2f, 0x07, 0x75,
0x84, 0xc3, 0x13, 0x1c, 0x59, 0x3b, 0x01, 0x3e, 0x46, 0x1c, 0x6a, 0xed, 0x04, 0x34, 0x58, 0x6b,
0x45, 0x07, 0x59, 0x12, 0x53, 0x63, 0x2b, 0x5a, 0x4a, 0x9c, 0xad, 0x68, 0x45, 0x68, 0x26, 0x1f,
0xe1, 0x7c, 0x68, 0xee, 0x6e, 0x4b, 0x89, 0xd3, 0x64, 0x45, 0x68, 0x3d, 0x5d, 0x9f, 0x64, 0x33,
0x63, 0x4f, 0xc7, 0x04, 0xce, 0x9e, 0x0e, 0x00, 0x2d, 0xc4, 0xbd, 0xa0, 0xa0, 0xe6, 0x10, 0x4b,
0x89, 0x33, 0xc4, 0x8a, 0x00, 0x93, 0x9f, 0xa2, 0x37, 0x79, 0x88, 0x13, 0xea, 0x2d, 0x9a, 0x02,
0x98, 0xc8, 0x41, 0xbc, 0x64, 0x95, 0x6b, 0xdb, 0x8e, 0xfb, 0xcf, 0x33, 0x92, 0x53, 0xe3, 0xb6,
0x83, 0x8b, 0x9c, 0xdb, 0x0e, 0x81, 0x68, 0x3b, 0xca, 0x9d, 0x31, 0xbb, 0xce, 0xb2, 0xbc, 0x7c,
0x2b, 0x66, 0xca, 0x65, 0x15, 0x71, 0xe6, 0x72, 0x03, 0x6d, 0x56, 0x3e, 0x56, 0xec, 0x1f, 0x07,
0x63, 0x6c, 0xad, 0x7c, 0xe5, 0x6a, 0xc0, 0x88, 0xd6, 0xca, 0x57, 0x27, 0x9b, 0x13, 0x74, 0x67,
0x1c, 0x0c, 0xb9, 0x27, 0x9b, 0x7e, 0x49, 0xa8, 0xae, 0x96, 0xbb, 0xa0, 0xe0, 0x6b, 0x0c, 0xdd,
0x4e, 0xe5, 0xeb, 0x28, 0x8e, 0xe8, 0xc8, 0x73, 0x5b, 0x28, 0x19, 0xe7, 0x3b, 0x80, 0x26, 0xdb,
0xbc, 0xb5, 0xa7, 0x71, 0x84, 0x89, 0xf3, 0xd6, 0x4a, 0xa2, 0xdb, 0xad, 0x29, 0x68, 0xf3, 0xd6,
0x4a, 0xb1, 0xfb, 0xd6, 0xb8, 0x85, 0x6e, 0xb7, 0xa6, 0xb2, 0xe0, 0xee, 0x4f, 0x3d, 0x74, 0x41,
0xac, 0xc2, 0x71, 0x7a, 0x72, 0x10, 0xe4, 0x43, 0x4c, 0x79, 0x7e, 0x46, 0xde, 0x5d, 0xdb, 0x12,
0xcb, 0xf6, 0xd1, 0x0a, 0x2a, 0xbc, 0xaf, 0xcf, 0xa3, 0xa2, 0x75, 0xe8, 0x9b, 0x84, 0x9c, 0x8c,
0x83, 0xfc, 0xe4, 0x01, 0xa6, 0xe1, 0xc8, 0x38, 0xc0, 0x15, 0xe1, 0x97, 0x88, 0x73, 0x80, 0x1b,
0xa8, 0xde, 0xbe, 0x56, 0x00, 0x7f, 0xdf, 0xb0, 0x91, 0x46, 0xdc, 0xed, 0xba, 0xcb, 0x96, 0xca,
0xba, 0xda, 0x57, 0x87, 0x0e, 0x04, 0xf2, 0x3b, 0x74, 0xbe, 0x24, 0xd9, 0x5c, 0x12, 0x0c, 0xbc,
0x02, 0x5d, 0x35, 0x18, 0x2c, 0xe7, 0x9c, 0x06, 0x5a, 0xbe, 0x51, 0x39, 0x15, 0xc0, 0x7d, 0x0a,
0x65, 0x68, 0x1f, 0x27, 0x01, 0xdb, 0x97, 0x0e, 0x30, 0xfd, 0x14, 0xcf, 0x8c, 0x99, 0x56, 0x21,
0x3e, 0x67, 0x9c, 0x99, 0xd6, 0x64, 0xc1, 0x1f, 0x86, 0x42, 0x54, 0x01, 0x1b, 0x51, 0x64, 0xea,
0x2a, 0xa5, 0x81, 0x8d, 0x28, 0x72, 0x75, 0x95, 0x3a, 0x08, 0x6e, 0xbe, 0x44, 0x1f, 0xf0, 0x37,
0x30, 0x01, 0x0d, 0xa6, 0x31, 0x3e, 0x7d, 0x1a, 0xe3, 0x53, 0x78, 0x9b, 0xe6, 0x9b, 0x5e, 0xb3,
0x00, 0xe6, 0x4b, 0x4e, 0x38, 0x5d, 0xed, 0xcc, 0x3b, 0x7c, 0x6f, 0xe1, 0x04, 0x77, 0xf1, 0xcd,
0xb9, 0xee, 0xbe, 0x05, 0xef, 0xf0, 0xcd, 0x5f, 0x2a, 0xb7, 0xfb, 0xe6, 0x5c, 0x77, 0xdf, 0x82,
0x07, 0xdf, 0x7f, 0xee, 0xa1, 0x85, 0x86, 0x73, 0xb6, 0x23, 0x0b, 0x69, 0x3c, 0xc5, 0xc6, 0x2a,
0xa2, 0xd8, 0x13, 0xa8, 0xb3, 0x8a, 0x58, 0x55, 0x20, 0x8a, 0xbf, 0xf5, 0xd0, 0x87, 0xa6, 0x28,
0xf6, 0x48, 0x11, 0xb3, 0x3c, 0xf1, 0xee, 0x75, 0x30, 0x5a, 0xc1, 0x22, 0x92, 0xef, 0xce, 0xa7,
0x04, 0xb1, 0x9c, 0xc2, 0xdb, 0x97, 0x8a, 0x1c, 0x60, 0x3a, 0x20, 0x93, 0x3c, 0x34, 0x6e, 0xde,
0xa4, 0x3d, 0x81, 0xb9, 0x7a, 0x73, 0x33, 0xae, 0x15, 0x95, 0x8a, 0xa9, 0xcf, 0x36, 0xe7, 0x73,
0xad, 0x81, 0xce, 0xa2, 0x62, 0x51, 0xd0, 0x8b, 0xab, 0xee, 0x1f, 0x52, 0x71, 0xbd, 0x8b, 0x45,
0x2d, 0x1d, 0xef, 0xcd, 0xa5, 0xd3, 0x16, 0x08, 0xcc, 0xc7, 0x4e, 0x81, 0x68, 0x73, 0xf2, 0xde,
0x5c, 0x3a, 0x10, 0xc8, 0x3f, 0x7a, 0xe8, 0xaa, 0x31, 0x10, 0xb6, 0xd9, 0xd9, 0x98, 0x06, 0x71,
0x12, 0x1c, 0x27, 0xd8, 0xfb, 0x41, 0x17, 0xdb, 0x8a, 0x8a, 0x08, 0xeb, 0x87, 0xaf, 0xa2, 0x0a,
0xd1, 0xfd, 0xa1, 0x5a, 0xfe, 0x65, 0x74, 0x21, 0xc9, 0x23, 0x28, 0x98, 0x2d, 0xcf, 0x5f, 0x92,
0x22, 0x96, 0xbb, 0x73, 0x68, 0x40, 0x08, 0xff, 0xec, 0xa1, 0x6b, 0x86, 0x10, 0xaa, 0xc0, 0x9f,
0x64, 0x55, 0xfa, 0xfe, 0xa8, 0xdd, 0x76, 0x43, 0x49, 0x04, 0xf6, 0xe3, 0x57, 0x53, 0x86, 0x18,
0xff, 0xdd, 0x43, 0x37, 0x5a, 0x63, 0x84, 0x14, 0xff, 0xe9, 0xbc, 0x9e, 0xb4, 0x74, 0xff, 0xe4,
0x95, 0xf5, 0xe7, 0x09, 0x16, 0xa6, 0xc1, 0xdc, 0xc1, 0x6a, 0x53, 0xe2, 0x93, 0x57, 0xd6, 0xd7,
0x5a, 0x3f, 0x7e, 0xe4, 0xec, 0x60, 0x96, 0x95, 0x1f, 0x8f, 0x4c, 0xad, 0x9f, 0x24, 0xfc, 0xfa,
0x17, 0xa4, 0xe5, 0x2e, 0x28, 0x38, 0xcb, 0xd1, 0xb9, 0xc7, 0xc1, 0x34, 0x1e, 0x8a, 0x19, 0xc1,
0x41, 0xfd, 0x1d, 0xbf, 0x64, 0xfc, 0x1a, 0x64, 0xd9, 0xd9, 0x5b, 0x61, 0xf0, 0xf9, 0xf7, 0x1e,
0xba, 0x2c, 0x99, 0x6d, 0x0c, 0xc4, 0x4e, 0xfa, 0x8c, 0x1c, 0xc5, 0x74, 0xc4, 0xda, 0xe2, 0xc2,
0xfb, 0xd8, 0x66, 0xd2, 0xcc, 0x8b, 0x50, 0xbe, 0x3f, 0xb7, 0x9e, 0xdc, 0xd9, 0x72, 0xf9, 0x76,
0x1e, 0x64, 0x23, 0x6d, 0x67, 0x0b, 0xc7, 0xff, 0x4a, 0x91, 0x65, 0x67, 0xab, 0x21, 0xf2, 0x8b,
0x3b, 0x9c, 0x41, 0xc4, 0x41, 0x1e, 0x8e, 0x3c, 0xa3, 0x0e, 0x97, 0x59, 0xbe, 0xb8, 0xeb, 0x8c,
0x7c, 0x70, 0x75, 0xc3, 0x83, 0xc9, 0x71, 0x11, 0xe6, 0xf1, 0x31, 0x36, 0x1f, 0xa8, 0xd4, 0x20,
0xf7, 0x81, 0xca, 0x26, 0x2c, 0xdf, 0xa8, 0x57, 0xa7, 0x2c, 0x0b, 0xe9, 0xd0, 0x78, 0x50, 0xb2,
0x4e, 0x58, 0xb6, 0xce, 0x66, 0x12, 0x5c, 0x3d, 0x47, 0x1f, 0xd4, 0x6f, 0xef, 0x30, 0x2d, 0x84,
0xbf, 0x15, 0x7b, 0xcc, 0x35, 0xcc, 0xd2, 0x2e, 0x38, 0x70, 0xfd, 0xd4, 0xa8, 0xbd, 0x2b, 0x07,
0x23, 0xa6, 0xfe, 0xe0, 0x66, 0x3b, 0x28, 0x3f, 0xdb, 0xab, 0x7e, 0xa0, 0x58, 0x2e, 0xbb, 0x2c,
0x68, 0x85, 0xf1, 0x76, 0x27, 0xd6, 0xe6, 0x10, 0x0a, 0x9e, 0xd3, 0xa1, 0x56, 0xdc, 0x6e, 0x77,
0x62, 0xf5, 0x67, 0xd8, 0x5c, 0xb8, 0x56, 0x5c, 0x76, 0x9a, 0x4b, 0x95, 0xdf, 0x15, 0x07, 0xcf,
0x7f, 0xec, 0xa1, 0x05, 0x93, 0x6b, 0x18, 0xe2, 0xb5, 0x76, 0x73, 0xda, 0x40, 0xdf, 0x9d, 0x43,
0xa3, 0x25, 0x06, 0x18, 0xf5, 0x0e, 0x31, 0x68, 0x63, 0x7f, 0x77, 0x0e, 0x0d, 0x88, 0xe1, 0x2f,
0x3d, 0x74, 0x51, 0x8d, 0x41, 0x6d, 0xb1, 0x9c, 0x26, 0xcd, 0xad, 0xd5, 0xfa, 0x3c, 0x2a, 0xf2,
0xb0, 0x45, 0x35, 0x99, 0xe9, 0x6e, 0x30, 0x23, 0x13, 0xfd, 0xb4, 0xae, 0x98, 0x95, 0x20, 0xb6,
0x7c, 0xa9, 0x36, 0x60, 0xb5, 0xa6, 0x8d, 0x4b, 0x1f, 0xe0, 0x80, 0x4e, 0x72, 0x1c, 0xd5, 0x67,
0xaf, 0x71, 0xac, 0x75, 0x50, 0xd9, 0x5c, 0xdf, 0x9d, 0x43, 0xa3, 0xb6, 0xd7, 0x32, 0x87, 0xb0,
0x8f, 0xc7, 0x64, 0x8a, 0xb5, 0xbd, 0x96, 0xcd, 0x26, 0x87, 0x2d, 0x7b, 0xad, 0x56, 0x25, 0xf9,
0x3e, 0x55, 0x0c, 0xf8, 0x4e, 0xf1, 0x20, 0x98, 0x92, 0x3c, 0xa6, 0xfa, 0xfb, 0x39, 0x39, 0x9a,
0x12, 0xb1, 0xf4, 0x10, 0x16, 0xd4, 0xe8, 0x6d, 0x23, 0x0f, 0x47, 0xf1, 0x14, 0x47, 0x0e, 0x6f,
0x15, 0xd2, 0xc1, 0x5b, 0x0d, 0xd5, 0xd7, 0xe9, 0x03, 0xc2, 0xfa, 0x22, 0xe3, 0x3a, 0x5d, 0x8a,
0xdc, 0xeb, 0x74, 0x85, 0x80, 0xd5, 0x10, 0x9d, 0xe5, 0x82, 0xf2, 0x6b, 0x31, 0x9f, 0xa2, 0xa6,
0xe4, 0xe3, 0x5f, 0x80, 0xd5, 0x89, 0x79, 0xa3, 0x95, 0x93, 0x2f, 0x24, 0xa4, 0x54, 0x1d, 0x2c,
0xdf, 0x66, 0xa3, 0x7c, 0x03, 0xdb, 0x1c, 0xb1, 0xd5, 0xce, 0xbc, 0xd5, 0xb7, 0x48, 0x8b, 0x16,
0xdf, 0x8d, 0xdc, 0x58, 0xed, 0xcc, 0x83, 0xef, 0x63, 0x38, 0x6c, 0x35, 0xc0, 0x74, 0x0b, 0xd3,
0x20, 0x4e, 0x0a, 0xcf, 0x76, 0x04, 0x05, 0xe4, 0x96, 0xb1, 0x35, 0x71, 0xf2, 0xc3, 0xc9, 0x5e,
0x30, 0xac, 0x7e, 0x6e, 0xa0, 0x7e, 0x38, 0x29, 0xcf, 0x63, 0x68, 0xdb, 0xb2, 0x2b, 0x0e, 0x42,
0x7e, 0xdb, 0x19, 0x88, 0x1f, 0x75, 0xa8, 0x5f, 0x46, 0x06, 0xcd, 0x5f, 0x74, 0x5c, 0xb6, 0x03,
0x72, 0x01, 0x7e, 0x84, 0x69, 0x1e, 0x87, 0xc5, 0x00, 0xd3, 0xbd, 0x20, 0x0f, 0xc6, 0x98, 0xe2,
0x5c, 0x3f, 0xa8, 0x07, 0x88, 0xaf, 0x30, 0x96, 0x05, 0xd8, 0xc6, 0xea, 0x49, 0xcd, 0xfa, 0x7e,
0xb8, 0x0f, 0x53, 0x52, 0x97, 0xdb, 0x02, 0xed, 0x76, 0x6e, 0xb4, 0x72, 0xf2, 0x9c, 0x9b, 0x94,
0xb2, 0x34, 0xd0, 0x0e, 0x61, 0xd5, 0x54, 0xcb, 0x24, 0x31, 0x1f, 0xc2, 0x6a, 0x52, 0xf2, 0xb5,
0x91, 0x94, 0xd5, 0xd7, 0x19, 0x63, 0x0f, 0x51, 0x1a, 0x10, 0x65, 0x51, 0xf1, 0xe7, 0x77, 0xc5,
0xc1, 0x31, 0xad, 0x1a, 0xec, 0xba, 0x63, 0xb6, 0x9a, 0xdc, 0x69, 0x35, 0x54, 0x5f, 0x49, 0x56,
0x3a, 0xd2, 0xf2, 0x65, 0x55, 0xd3, 0x2b, 0xb4, 0x2d, 0xab, 0xad, 0xa6, 0xb4, 0xae, 0x65, 0xad,
0xbb, 0x82, 0xcb, 0x3d, 0xac, 0x5f, 0xed, 0xee, 0xb5, 0xb5, 0x6b, 0xad, 0xbb, 0x02, 0xb8, 0xff,
0x09, 0xfa, 0xc6, 0x5e, 0x9c, 0x0e, 0xbd, 0x0b, 0xea, 0xe4, 0x8c, 0xd3, 0xa1, 0x30, 0xba, 0x60,
0x12, 0xc9, 0xc3, 0x63, 0x7b, 0x39, 0x09, 0x71, 0x51, 0xf4, 0x83, 0x34, 0xc4, 0x89, 0x76, 0x78,
0x0c, 0x64, 0x3e, 0x17, 0x5a, 0x0e, 0x8f, 0x35, 0x20, 0xb9, 0xec, 0x3c, 0x8c, 0x0b, 0x4a, 0xf2,
0x59, 0x79, 0x50, 0x58, 0x2d, 0x1f, 0x20, 0x51, 0x8f, 0x0a, 0x5f, 0x75, 0x21, 0xb2, 0x33, 0x02,
0x01, 0xfc, 0x78, 0x41, 0x3f, 0xc3, 0x57, 0xa9, 0x55, 0x62, 0x4b, 0x67, 0x64, 0xc0, 0xe4, 0x76,
0xa6, 0x8a, 0x1b, 0x53, 0x10, 0x6b, 0xdb, 0x19, 0x11, 0x9a, 0x00, 0x2c, 0xdb, 0x19, 0x23, 0x08,
0x7e, 0xfa, 0xe8, 0x75, 0xf8, 0x26, 0x7c, 0x51, 0x3b, 0xe2, 0xaf, 0x7c, 0x0d, 0xfe, 0xd0, 0x2c,
0x04, 0x23, 0xbf, 0x46, 0xef, 0xf2, 0x4b, 0xe2, 0x17, 0x45, 0x5a, 0x31, 0xd1, 0xa4, 0x96, 0x62,
0xd2, 0xa4, 0x74, 0xfb, 0x07, 0x78, 0x9c, 0x25, 0x01, 0xc5, 0x85, 0xd1, 0xbe, 0x90, 0x3a, 0xed,
0xd7, 0x29, 0xb0, 0x1f, 0xa0, 0xb3, 0x5c, 0xb6, 0x4b, 0xc2, 0x20, 0x61, 0x83, 0xa5, 0x1f, 0x2b,
0xd6, 0xc5, 0x96, 0xe7, 0x69, 0xc0, 0xe4, 0xef, 0x0d, 0x1e, 0x05, 0x27, 0xb8, 0x72, 0xae, 0x25,
0x62, 0x5d, 0x64, 0x49, 0x44, 0x0d, 0x01, 0xb3, 0x33, 0x74, 0xbe, 0x2e, 0xd8, 0x9c, 0xc9, 0xe9,
0xaa, 0x15, 0x5a, 0x1b, 0x66, 0x29, 0xb4, 0x0e, 0x1c, 0x5c, 0xff, 0x1c, 0xbd, 0xd3, 0x4f, 0x48,
0x2a, 0x6f, 0x49, 0x8d, 0x57, 0x91, 0x59, 0xde, 0x91, 0xe8, 0x8c, 0x7c, 0xdc, 0xdc, 0xa1, 0x3c,
0xfe, 0x67, 0x5a, 0x9b, 0x9a, 0x47, 0xff, 0x96, 0x5a, 0x28, 0xb0, 0xff, 0x0b, 0x74, 0xe6, 0x30,
0x2d, 0xb2, 0x24, 0x28, 0x46, 0xf0, 0x7a, 0x47, 0x0d, 0x4b, 0x15, 0x5a, 0x0a, 0x4e, 0x03, 0x92,
0xb9, 0x54, 0x89, 0xc4, 0xd1, 0xe9, 0x25, 0xa3, 0x66, 0xe3, 0xf0, 0xf4, 0xf5, 0x36, 0x4c, 0x8e,
0xfc, 0x46, 0x96, 0x25, 0x33, 0xcb, 0xc8, 0x2b, 0x32, 0xcb, 0xc8, 0xeb, 0x8c, 0x6c, 0x9d, 0xb6,
0xf0, 0xf1, 0x64, 0x38, 0x98, 0xa5, 0xa1, 0xd6, 0x3a, 0x95, 0xd7, 0x7d, 0x26, 0xb0, 0xb4, 0x4e,
0x0a, 0x20, 0xab, 0x6f, 0x79, 0xf9, 0x60, 0x94, 0xe3, 0xc6, 0xcf, 0x61, 0xb8, 0x02, 0x17, 0xd9,
0x7e, 0x64, 0xa3, 0x22, 0x5a, 0x94, 0x07, 0x39, 0xc6, 0xc6, 0x28, 0x99, 0xc0, 0x19, 0x25, 0x00,
0x60, 0x6f, 0x0d, 0xbd, 0xcd, 0x7a, 0x08, 0x9c, 0xde, 0x2f, 0x7f, 0x0d, 0xed, 0x9d, 0x11, 0x1a,
0xf7, 0xc7, 0x19, 0x9d, 0x2d, 0xd4, 0xfe, 0x67, 0xc0, 0x5a, 0x6f, 0xf3, 0xca, 0x7f, 0x5e, 0x2c,
0xf6, 0xbe, 0x7e, 0xb1, 0xd8, 0xfb, 0xdf, 0x8b, 0xc5, 0xde, 0x57, 0x2f, 0x17, 0x5f, 0xfb, 0xfa,
0xe5, 0xe2, 0x6b, 0xff, 0x7d, 0xb9, 0xf8, 0xda, 0x67, 0x6f, 0xc0, 0xaf, 0xb1, 0x8f, 0x5f, 0x2f,
0x7f, 0x53, 0x7d, 0xef, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc9, 0xf7, 0xef, 0xa6, 0xb1, 0x3d,
0x00, 0x00,
// 3040 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x9b, 0x5b, 0x73, 0xdc, 0xb6,
0xf5, 0xc0, 0xb3, 0x33, 0xff, 0x49, 0xf2, 0x47, 0x12, 0xc7, 0x61, 0xeb, 0xc4, 0x96, 0x53, 0xf9,
0x12, 0xcb, 0x17, 0xd9, 0xa2, 0x64, 0xb9, 0x4d, 0xa7, 0xd7, 0x8c, 0xb4, 0xb2, 0x65, 0x4d, 0x64,
0x5b, 0xd5, 0x4a, 0x56, 0x27, 0xbd, 0x52, 0x24, 0xbc, 0xcb, 0x88, 0x4b, 0x30, 0x24, 0x76, 0xe5,
0x6d, 0xa7, 0x9d, 0xde, 0xa6, 0x33, 0x7d, 0xf3, 0x4c, 0x1f, 0xfb, 0xd4, 0xd7, 0x7e, 0x92, 0x3e,
0xe6, 0xb1, 0x8f, 0x1d, 0xfb, 0x8b, 0x74, 0x40, 0x1c, 0x02, 0x04, 0x08, 0x80, 0x5c, 0x3f, 0x69,
0xc4, 0xf3, 0x3b, 0x17, 0x82, 0x07, 0x07, 0x07, 0x24, 0x16, 0x5d, 0xca, 0x8e, 0x57, 0xb3, 0x9c,
0x50, 0x52, 0xac, 0x16, 0x38, 0x9f, 0xc6, 0x21, 0xae, 0xfe, 0xfa, 0xe5, 0x65, 0xef, 0xad, 0x20,
0x9d, 0xd1, 0x59, 0x86, 0x17, 0xce, 0x4b, 0x32, 0x24, 0xe3, 0x71, 0x90, 0x46, 0x05, 0x47, 0x16,
0x3e, 0x94, 0x12, 0x3c, 0xc5, 0x29, 0x85, 0xeb, 0xeb, 0x2f, 0x7e, 0x8b, 0xce, 0xf4, 0x93, 0x18,
0xa7, 0xb4, 0x0f, 0x0a, 0x5e, 0x8e, 0xce, 0x3d, 0x39, 0xfe, 0x12, 0x87, 0x74, 0x23, 0x8a, 0x8e,
0x62, 0x3a, 0xe2, 0xff, 0xec, 0x44, 0xde, 0x6d, 0x1f, 0xfc, 0xf8, 0xfb, 0x59, 0xe8, 0xf3, 0xcb,
0xbe, 0x06, 0xf9, 0xfb, 0xf8, 0xab, 0x09, 0x2e, 0xe8, 0xc2, 0x9d, 0x6e, 0x70, 0x91, 0x91, 0xb4,
0xc0, 0xde, 0x33, 0xf4, 0x01, 0xbf, 0x38, 0x18, 0x05, 0x39, 0xde, 0x9c, 0xed, 0xc6, 0xe9, 0x89,
0x77, 0xc3, 0x64, 0xa2, 0x06, 0x08, 0x5f, 0x37, 0xdb, 0x41, 0xf0, 0x73, 0x84, 0xde, 0x3d, 0x0a,
0x92, 0x04, 0xd3, 0x7e, 0x8e, 0x03, 0x8a, 0xbd, 0xab, 0x8a, 0x26, 0x17, 0xf9, 0x5c, 0x26, 0xac,
0x7f, 0xe2, 0x64, 0xc0, 0xf0, 0x17, 0xe8, 0x3d, 0x2e, 0xd9, 0xc7, 0x21, 0x99, 0xe2, 0xdc, 0x33,
0x6a, 0x81, 0x50, 0x98, 0xbe, 0xe6, 0x86, 0x74, 0xdb, 0x7d, 0x92, 0x4e, 0x71, 0x4e, 0xcd, 0xb6,
0x41, 0xe8, 0xb6, 0x2d, 0x21, 0xb0, 0xfd, 0x6b, 0xf4, 0xfe, 0x11, 0xc9, 0x4f, 0x8a, 0x2c, 0x08,
0x31, 0x8c, 0xc9, 0x92, 0xaa, 0x58, 0x49, 0xf5, 0x61, 0xb9, 0xde, 0x86, 0x19, 0x3c, 0x0c, 0x70,
0x82, 0x43, 0x6a, 0xf5, 0xc0, 0xc5, 0xad, 0x1e, 0x04, 0x06, 0x1e, 0x12, 0xf4, 0x0d, 0x21, 0xdc,
0xc6, 0xb4, 0x3f, 0xc9, 0x73, 0x9c, 0x52, 0xef, 0x96, 0x45, 0x5d, 0x22, 0xc2, 0xd3, 0x72, 0x17,
0xd4, 0x70, 0x3f, 0xdb, 0x98, 0x6e, 0x24, 0x89, 0xf5, 0x7e, 0xb8, 0xb8, 0xf5, 0x7e, 0x04, 0x06,
0x1e, 0x7e, 0x8f, 0x2e, 0xd4, 0x46, 0x8c, 0xee, 0x14, 0x0f, 0xe3, 0xe1, 0x28, 0x89, 0x87, 0x23,
0x8a, 0x23, 0x6f, 0xd5, 0x3a, 0x28, 0x2a, 0x28, 0xbc, 0xae, 0x75, 0x57, 0x00, 0xff, 0xbf, 0x40,
0x67, 0x36, 0xc2, 0x90, 0x4c, 0x52, 0x91, 0xcc, 0x6a, 0x2e, 0x81, 0xb0, 0x91, 0xcd, 0x4b, 0x2d,
0x94, 0x4c, 0x67, 0x90, 0x41, 0xc2, 0x7d, 0x62, 0xd4, 0xd3, 0xd2, 0xed, 0x9a, 0x1b, 0x6a, 0xd8,
0x86, 0x54, 0x33, 0xdb, 0xd6, 0x12, 0xed, 0x9a, 0x1b, 0x02, 0xdb, 0x07, 0xe8, 0x9d, 0xca, 0x36,
0x25, 0x99, 0x77, 0xc5, 0xac, 0x44, 0x49, 0x26, 0xec, 0x5e, 0x75, 0x21, 0xd2, 0xea, 0x83, 0x38,
0xc1, 0x4f, 0x9e, 0x3d, 0x4b, 0x48, 0x10, 0x69, 0x56, 0x99, 0xc4, 0x07, 0x91, 0xc5, 0xaa, 0x86,
0xc8, 0x24, 0x65, 0x82, 0xdd, 0xb8, 0xa0, 0x95, 0xe5, 0xa5, 0x86, 0x1a, 0x93, 0x36, 0xac, 0x5f,
0x6f, 0xc3, 0xc0, 0xc3, 0x4f, 0x10, 0x7a, 0x8a, 0xf3, 0x22, 0x26, 0xe9, 0x36, 0xa6, 0xde, 0x65,
0x45, 0x0b, 0x04, 0x2c, 0xb1, 0x85, 0xdd, 0x2b, 0x0e, 0x02, 0x4c, 0x3e, 0x44, 0x6f, 0xed, 0x92,
0xe1, 0x00, 0xa7, 0x91, 0xf7, 0x2d, 0x85, 0xde, 0x25, 0x43, 0x9f, 0x5d, 0x16, 0xc6, 0x16, 0x6d,
0x62, 0xb0, 0xf4, 0x18, 0xfd, 0x7f, 0x9f, 0xa4, 0xcf, 0xe2, 0x21, 0x8b, 0xed, 0x92, 0x02, 0xf3,
0xeb, 0x4a, 0x68, 0x97, 0xed, 0x00, 0xd8, 0xdb, 0x41, 0x6f, 0x0f, 0x46, 0x13, 0x1a, 0x91, 0xd3,
0x54, 0x0b, 0xad, 0xba, 0x6c, 0x09, 0xad, 0x26, 0x96, 0x2b, 0xdd, 0xfd, 0xe7, 0x14, 0xe7, 0x69,
0x90, 0x6c, 0xe5, 0x24, 0x63, 0x03, 0x5c, 0x68, 0x2b, 0x5d, 0x5d, 0x5e, 0x3e, 0x81, 0xc2, 0xb2,
0xd2, 0x19, 0x41, 0x59, 0x14, 0xeb, 0xe2, 0x3e, 0x49, 0x69, 0xb3, 0x28, 0x2a, 0x06, 0x00, 0xb1,
0x14, 0x45, 0x0b, 0x0a, 0xde, 0xf6, 0xd1, 0x3b, 0x6c, 0xa1, 0xdd, 0xcb, 0xf1, 0x34, 0xc6, 0xa7,
0x5a, 0x3a, 0xd4, 0x24, 0x96, 0x74, 0x50, 0x09, 0xb0, 0xf9, 0x04, 0xa1, 0xc3, 0x8c, 0x25, 0x1d,
0xbb, 0x33, 0xed, 0x29, 0x4a, 0x81, 0xe5, 0x29, 0x2a, 0x00, 0x18, 0x3c, 0x44, 0xef, 0x6e, 0x91,
0xd3, 0x54, 0x98, 0x54, 0x63, 0xa8, 0x8b, 0x2c, 0x73, 0x4d, 0x43, 0xe4, 0x0c, 0xde, 0x4c, 0x48,
0x78, 0xc2, 0x5d, 0x6a, 0x56, 0x4b, 0x09, 0x44, 0x63, 0xb1, 0xaa, 0x21, 0xb2, 0x53, 0x29, 0x05,
0xfb, 0x38, 0x4b, 0x82, 0x50, 0xef, 0x54, 0xb8, 0x0e, 0xc8, 0x2c, 0x9d, 0x8a, 0xce, 0x80, 0xe1,
0x18, 0x79, 0x10, 0x6e, 0x14, 0x50, 0x5c, 0xe5, 0xc5, 0x4d, 0x63, 0x48, 0x35, 0x42, 0x38, 0xb9,
0xd5, 0x81, 0x94, 0xd3, 0xb0, 0x94, 0x3f, 0xc9, 0x70, 0xaa, 0x3d, 0x40, 0xae, 0xc7, 0x04, 0x96,
0x07, 0xa8, 0x00, 0x9a, 0xbd, 0xc1, 0x88, 0x9c, 0x1a, 0xed, 0x31, 0x81, 0xd3, 0x1e, 0x00, 0x60,
0x8f, 0xa0, 0x6f, 0x96, 0x97, 0xb7, 0x31, 0xdd, 0x9b, 0x1c, 0x27, 0x71, 0x78, 0x84, 0x8f, 0x0f,
0xf7, 0x77, 0xbd, 0x65, 0x83, 0xa6, 0xc6, 0x08, 0x2f, 0xb7, 0x3b, 0xb1, 0x9a, 0x43, 0x76, 0x5b,
0x9b, 0x39, 0x0e, 0xa2, 0x30, 0x9f, 0x8c, 0x8f, 0x0b, 0xa3, 0x43, 0x8d, 0x71, 0x3a, 0x6c, 0xb2,
0xb2, 0x0a, 0xf0, 0x11, 0xc3, 0xb4, 0xee, 0xcf, 0xf4, 0x0c, 0x55, 0xc4, 0x52, 0x05, 0x2c, 0xa8,
0x36, 0x13, 0x60, 0x5d, 0x37, 0xcd, 0x04, 0x6d, 0x55, 0xbf, 0xea, 0x42, 0xe4, 0x5a, 0x56, 0xb3,
0xba, 0x17, 0x0c, 0xf5, 0x16, 0xb5, 0xae, 0xc6, 0xc4, 0x96, 0xb5, 0xcc, 0x80, 0xc9, 0x86, 0xa7,
0xe6, 0x61, 0x80, 0xa9, 0xd6, 0xf0, 0xd4, 0x35, 0x07, 0xb5, 0x85, 0x63, 0xa9, 0x85, 0xd2, 0x0b,
0x44, 0x9a, 0xb0, 0x6d, 0x8d, 0xb1, 0x40, 0x94, 0x22, 0x77, 0x81, 0xa8, 0x10, 0xb9, 0x00, 0xf3,
0xa0, 0x13, 0x52, 0x60, 0xcf, 0x94, 0xec, 0xa5, 0xc4, 0x52, 0x71, 0x55, 0x42, 0x76, 0x4f, 0xe5,
0xf5, 0xaa, 0xce, 0x79, 0xa6, 0x82, 0x52, 0x09, 0x2d, 0xdd, 0x53, 0x03, 0x02, 0xdb, 0x3f, 0x07,
0xdb, 0xdb, 0x98, 0x3e, 0x0a, 0xf2, 0x93, 0xc2, 0x38, 0xc4, 0x6c, 0xd1, 0x2d, 0xa5, 0xce, 0x21,
0xae, 0x53, 0x5a, 0x65, 0x38, 0x4c, 0x23, 0x62, 0xac, 0x0c, 0x4c, 0xe0, 0xac, 0x0c, 0x00, 0x68,
0xf6, 0xf6, 0xb1, 0xc5, 0x1e, 0x13, 0x38, 0xed, 0x01, 0x00, 0xf6, 0x7e, 0x05, 0x19, 0x36, 0xc0,
0xf4, 0x41, 0x8c, 0x93, 0xa8, 0x30, 0xa6, 0x30, 0xcb, 0x1a, 0x2e, 0x76, 0xa6, 0xb0, 0x82, 0x81,
0x83, 0xaf, 0xa0, 0xb2, 0x0c, 0xd8, 0x0e, 0xb4, 0xa0, 0x79, 0x1c, 0xd2, 0x98, 0xa4, 0x85, 0x77,
0xdb, 0xa2, 0x5f, 0x87, 0x2c, 0x7b, 0x76, 0x2b, 0xac, 0x65, 0x0b, 0xeb, 0x0f, 0x1f, 0x91, 0x29,
0x36, 0x65, 0x4b, 0xd9, 0x3b, 0x32, 0xa1, 0x2b, 0x5b, 0xea, 0x10, 0xd8, 0x9e, 0xa0, 0x0f, 0x15,
0xdb, 0x07, 0xe4, 0x31, 0x3e, 0x2d, 0xa7, 0xfe, 0x1d, 0x87, 0xbe, 0xa0, 0x84, 0xb7, 0x95, 0x8e,
0x34, 0xb8, 0x7d, 0xd1, 0x43, 0x97, 0x04, 0x04, 0x7b, 0xe5, 0xfe, 0x28, 0x4e, 0xa2, 0x1c, 0xa7,
0x07, 0x84, 0xb1, 0x85, 0xf7, 0x1d, 0x8b, 0x49, 0x33, 0x2e, 0x22, 0xf9, 0x74, 0x5e, 0x35, 0x08,
0xe9, 0x04, 0x96, 0x6b, 0x06, 0xcb, 0xec, 0xb9, 0x65, 0xb1, 0x66, 0xc8, 0xa0, 0xe5, 0x2e, 0x28,
0x38, 0x9b, 0xa2, 0x73, 0x75, 0x67, 0x07, 0xf8, 0x39, 0x1d, 0xd0, 0x59, 0x82, 0xbd, 0x15, 0x87,
0x11, 0x46, 0xf9, 0x25, 0x26, 0x7c, 0xfa, 0x5d, 0x71, 0xad, 0x27, 0x61, 0xd0, 0xd6, 0x24, 0x4b,
0xe2, 0x90, 0xad, 0x1f, 0x37, 0x2d, 0x56, 0x04, 0xe1, 0xea, 0x49, 0x1a, 0x24, 0xb8, 0xfa, 0x6b,
0x0f, 0x5d, 0xac, 0xdf, 0xe3, 0x66, 0x10, 0x9e, 0x0c, 0x73, 0x32, 0x49, 0xa3, 0x3e, 0x49, 0x48,
0xee, 0xad, 0x3b, 0x42, 0xd7, 0x58, 0xe1, 0xfe, 0xde, 0x5c, 0x3a, 0x10, 0xc8, 0x08, 0x7d, 0x50,
0x8f, 0x63, 0x23, 0x89, 0x87, 0xa9, 0xf5, 0x96, 0x99, 0xa5, 0x92, 0x68, 0xbd, 0xe5, 0x3a, 0x09,
0x9e, 0x0a, 0xa8, 0x0d, 0xe0, 0x69, 0x2b, 0x9e, 0xf2, 0x87, 0x7a, 0xc7, 0x61, 0x62, 0x2b, 0x9e,
0x6a, 0xcf, 0x74, 0xa5, 0x23, 0x6d, 0x4e, 0x25, 0xd6, 0x32, 0xb7, 0xa7, 0x52, 0xd9, 0x58, 0x77,
0x4f, 0x25, 0x05, 0x97, 0xfb, 0x2b, 0x01, 0x1d, 0x4c, 0xf2, 0x74, 0x27, 0xa5, 0x44, 0xdb, 0x5f,
0x49, 0x23, 0x15, 0x60, 0xd9, 0x5f, 0x19, 0x41, 0xf0, 0xf3, 0x25, 0xf8, 0x19, 0x60, 0xba, 0x1b,
0x50, 0xfc, 0x9c, 0xa5, 0xb5, 0xad, 0xaf, 0xf2, 0x4b, 0x82, 0x67, 0x7e, 0x4b, 0x5f, 0xa5, 0xa2,
0xe0, 0x6b, 0x88, 0xce, 0x56, 0xbe, 0x98, 0xa0, 0x74, 0x75, 0xd3, 0xa2, 0x5f, 0x6a, 0x2a, 0x9e,
0x6e, 0x75, 0x20, 0x9b, 0x37, 0xc5, 0x04, 0x7c, 0x46, 0x38, 0xf5, 0xd5, 0x89, 0xb0, 0xdc, 0x05,
0xb5, 0xd7, 0x1a, 0xee, 0xaf, 0xb5, 0xd6, 0xa8, 0x3e, 0xfd, 0xae, 0xb8, 0x79, 0x36, 0x30, 0x84,
0x35, 0x13, 0xce, 0xd9, 0x50, 0xda, 0x61, 0x54, 0xa7, 0xd9, 0x50, 0xa7, 0xcd, 0x03, 0xcb, 0x67,
0x82, 0x73, 0x60, 0xd5, 0x59, 0xb0, 0xdc, 0x05, 0x05, 0x5f, 0x99, 0xec, 0xf9, 0xcb, 0x41, 0x1d,
0xe1, 0xf0, 0x04, 0x47, 0xd6, 0x4e, 0x80, 0x8f, 0x11, 0x87, 0x5a, 0x3b, 0x01, 0x0d, 0x36, 0xe7,
0xe7, 0x4e, 0x48, 0x52, 0x77, 0x7e, 0x32, 0xa2, 0x5b, 0x7e, 0x02, 0xa9, 0xf5, 0xbc, 0x83, 0x2c,
0x89, 0xa9, 0xb1, 0xe7, 0x2d, 0x25, 0xce, 0x9e, 0xb7, 0x22, 0x34, 0x93, 0x8f, 0x70, 0x3e, 0x34,
0xb7, 0xd1, 0xa5, 0xc4, 0x69, 0xb2, 0x22, 0xb4, 0xe6, 0xb1, 0x4f, 0xb2, 0x99, 0xb1, 0x79, 0x64,
0x02, 0x67, 0xf3, 0x08, 0x80, 0x16, 0xe2, 0x5e, 0x50, 0x50, 0x73, 0x88, 0xa5, 0xc4, 0x19, 0x62,
0x45, 0x80, 0xc9, 0xcf, 0xd1, 0xdb, 0x3c, 0xc4, 0x09, 0xf5, 0x16, 0x4d, 0x01, 0x4c, 0xe4, 0x20,
0x5e, 0xb2, 0xca, 0xb5, 0xfd, 0xcd, 0xfd, 0xe7, 0x19, 0xc9, 0xa9, 0x71, 0x7f, 0xc3, 0x45, 0xce,
0xfd, 0x8d, 0x40, 0xb4, 0xad, 0xeb, 0xce, 0x98, 0x5d, 0x67, 0xd3, 0xa9, 0x7c, 0xfd, 0x66, 0xca,
0x16, 0x15, 0x71, 0x4e, 0x9a, 0x06, 0xda, 0x4c, 0x61, 0xb6, 0xaa, 0x3c, 0x0e, 0xc6, 0xd8, 0x9a,
0xc2, 0xe5, 0xb2, 0xc3, 0x88, 0xd6, 0x14, 0xae, 0x93, 0xcd, 0x4a, 0xb0, 0x33, 0x0e, 0x86, 0xdc,
0x93, 0x4d, 0xbf, 0x24, 0x54, 0x57, 0xcb, 0x5d, 0x50, 0xf0, 0x35, 0x86, 0xb6, 0xaa, 0xf2, 0x75,
0x14, 0x47, 0x74, 0xe4, 0xb9, 0x2d, 0x94, 0x8c, 0xf3, 0x65, 0x43, 0x93, 0x6d, 0xde, 0xda, 0xd3,
0x38, 0xc2, 0xc4, 0x79, 0x6b, 0x25, 0xd1, 0xed, 0xd6, 0x14, 0xb4, 0x79, 0x6b, 0xa5, 0xd8, 0x7d,
0x6b, 0xdc, 0x42, 0xb7, 0x5b, 0x53, 0x59, 0x70, 0xf7, 0xa7, 0x1e, 0xba, 0x20, 0x96, 0xfb, 0x38,
0x3d, 0x39, 0x08, 0xf2, 0x21, 0xa6, 0x3c, 0x3f, 0x23, 0xef, 0xae, 0x6d, 0x2d, 0x67, 0x1b, 0x76,
0x05, 0x15, 0xde, 0xd7, 0xe7, 0x51, 0xd1, 0xb6, 0x02, 0x9b, 0x84, 0x9c, 0x8c, 0x83, 0xfc, 0xe4,
0x01, 0xa6, 0xe1, 0xc8, 0x38, 0xc0, 0x15, 0xe1, 0x97, 0x88, 0x73, 0x80, 0x1b, 0xa8, 0xde, 0x27,
0x57, 0x00, 0x7f, 0xb1, 0xb1, 0x91, 0x46, 0xdc, 0xed, 0xba, 0xcb, 0x96, 0xca, 0xba, 0xfa, 0x64,
0x87, 0x0e, 0x04, 0xf2, 0x3b, 0x74, 0xbe, 0x24, 0xd9, 0x5c, 0x12, 0x0c, 0xbc, 0x6b, 0x5d, 0x35,
0x18, 0x2c, 0xe7, 0x9c, 0x06, 0x5a, 0x3e, 0x86, 0x39, 0x15, 0xc0, 0x7d, 0x0a, 0x65, 0x68, 0x1f,
0x27, 0x01, 0xdb, 0x00, 0x0f, 0x30, 0xfd, 0x1c, 0xcf, 0x8c, 0x99, 0x56, 0x21, 0x3e, 0x67, 0x9c,
0x99, 0xd6, 0x64, 0xc1, 0x1f, 0x86, 0x42, 0x54, 0x01, 0x1b, 0x51, 0x64, 0x6a, 0x5f, 0xa5, 0x81,
0x8d, 0x28, 0x72, 0xb5, 0xaf, 0x3a, 0x08, 0x6e, 0x7e, 0x83, 0x3e, 0xe2, 0xaf, 0x7a, 0x02, 0x1a,
0x4c, 0x63, 0x7c, 0xfa, 0x34, 0xc6, 0xa7, 0xf0, 0xda, 0xce, 0x37, 0xbd, 0xcf, 0x01, 0xcc, 0x97,
0x9c, 0x70, 0xba, 0xda, 0x99, 0x77, 0xf8, 0xde, 0xc2, 0x09, 0xee, 0xe2, 0x9b, 0x73, 0xdd, 0x7d,
0x0b, 0xde, 0xe1, 0x9b, 0xbf, 0xbd, 0x6e, 0xf7, 0xcd, 0xb9, 0xee, 0xbe, 0x05, 0x0f, 0xbe, 0xff,
0xdc, 0x43, 0x0b, 0x0d, 0xe7, 0x6c, 0xeb, 0x17, 0xd2, 0x78, 0x8a, 0x8d, 0x55, 0x44, 0xb1, 0x27,
0x50, 0x67, 0x15, 0xb1, 0xaa, 0x40, 0x14, 0x7f, 0xeb, 0xa1, 0x8f, 0x4d, 0x51, 0xec, 0x91, 0x22,
0x66, 0x79, 0xe2, 0xdd, 0xeb, 0x60, 0xb4, 0x82, 0x45, 0x24, 0xdf, 0x9e, 0x4f, 0x09, 0x62, 0x39,
0x85, 0xd7, 0x3c, 0x15, 0x39, 0xc0, 0x74, 0x40, 0x26, 0x79, 0x68, 0xdc, 0x25, 0x4a, 0x7b, 0x02,
0x73, 0x6d, 0x02, 0xcc, 0xb8, 0x56, 0x54, 0x2a, 0xa6, 0x3e, 0xdb, 0x9c, 0xcf, 0xb5, 0x06, 0x3a,
0x8b, 0x8a, 0x45, 0x41, 0x2f, 0xae, 0xba, 0x7f, 0x48, 0xc5, 0xf5, 0x2e, 0x16, 0xb5, 0x74, 0xbc,
0x37, 0x97, 0x4e, 0x5b, 0x20, 0x30, 0x1f, 0x3b, 0x05, 0xa2, 0xcd, 0xc9, 0x7b, 0x73, 0xe9, 0x40,
0x20, 0xff, 0xe8, 0xa1, 0xab, 0xc6, 0x40, 0xd8, 0xae, 0x6a, 0x63, 0x1a, 0xc4, 0x49, 0x70, 0x9c,
0x60, 0xef, 0x7b, 0x5d, 0x6c, 0x2b, 0x2a, 0x22, 0xac, 0xef, 0xbf, 0x8e, 0x2a, 0x44, 0xf7, 0x87,
0x6a, 0xf9, 0x97, 0xd1, 0x85, 0x24, 0x8f, 0xa0, 0x60, 0xb6, 0x3c, 0x7f, 0x49, 0x8a, 0x58, 0xee,
0xce, 0xa1, 0x01, 0x21, 0xfc, 0xb3, 0x87, 0xae, 0x19, 0x42, 0xa8, 0x02, 0x7f, 0x92, 0x55, 0xe9,
0xfb, 0x83, 0x76, 0xdb, 0x0d, 0x25, 0x11, 0xd8, 0x0f, 0x5f, 0x4f, 0x19, 0x62, 0xfc, 0x57, 0x0f,
0xdd, 0x68, 0x8d, 0x11, 0x52, 0xfc, 0xc7, 0xf3, 0x7a, 0xd2, 0xd2, 0xfd, 0xb3, 0xd7, 0xd6, 0x9f,
0x27, 0x58, 0x98, 0x06, 0x73, 0x07, 0xab, 0x4d, 0x89, 0xcf, 0x5e, 0x5b, 0x5f, 0x6b, 0xfd, 0xf8,
0xd9, 0xb6, 0x83, 0x59, 0x56, 0x7e, 0xa5, 0x32, 0xb5, 0x7e, 0x92, 0xf0, 0xeb, 0x9f, 0xaa, 0x96,
0xbb, 0xa0, 0xe0, 0x2c, 0x47, 0xe7, 0x1e, 0x07, 0xd3, 0x78, 0x28, 0x66, 0x04, 0x07, 0xf5, 0x8f,
0x09, 0x92, 0xf1, 0x6b, 0x90, 0xe5, 0x15, 0x82, 0x15, 0x06, 0x9f, 0x7f, 0xef, 0xa1, 0xcb, 0x92,
0xd9, 0xc6, 0x40, 0xec, 0xa4, 0xcf, 0xc8, 0x51, 0x4c, 0x47, 0xac, 0x2d, 0x2e, 0xbc, 0x4f, 0x6d,
0x26, 0xcd, 0xbc, 0x08, 0xe5, 0xbb, 0x73, 0xeb, 0xc9, 0x9d, 0x2d, 0x97, 0x6f, 0xe7, 0x41, 0x36,
0xd2, 0x76, 0xb6, 0x70, 0xce, 0xb0, 0x14, 0x59, 0x76, 0xb6, 0x1a, 0x22, 0x3f, 0xed, 0xc3, 0x61,
0x47, 0x1c, 0xe4, 0xe1, 0xc8, 0x33, 0xea, 0x70, 0x99, 0xe5, 0xd3, 0xbe, 0xce, 0xc8, 0x07, 0x57,
0x37, 0x3c, 0x98, 0x1c, 0x17, 0x61, 0x1e, 0x1f, 0x63, 0xf3, 0xc9, 0x4d, 0x0d, 0x72, 0x9f, 0xdc,
0x6c, 0xc2, 0xf2, 0xd5, 0x7d, 0x75, 0x9c, 0xb3, 0x90, 0x0e, 0x8d, 0x27, 0x32, 0xeb, 0x84, 0x65,
0xeb, 0x6c, 0x26, 0xc1, 0xd5, 0x73, 0xf4, 0x51, 0xfd, 0xf6, 0x0e, 0xd3, 0x42, 0xf8, 0x5b, 0xb1,
0xc7, 0x5c, 0xc3, 0x2c, 0xed, 0x82, 0x03, 0xd7, 0x8f, 0xa7, 0xda, 0xbb, 0x72, 0x30, 0x62, 0xea,
0x0f, 0x6e, 0xb6, 0x83, 0xf2, 0x7c, 0x80, 0xea, 0x07, 0x8a, 0xe5, 0xb2, 0xcb, 0x82, 0x56, 0x18,
0x6f, 0x77, 0x62, 0x6d, 0x0e, 0xa1, 0xe0, 0x39, 0x1d, 0x6a, 0xc5, 0xed, 0x76, 0x27, 0x56, 0x7f,
0x86, 0xcd, 0x85, 0x6b, 0xc5, 0x65, 0xa7, 0xb9, 0x54, 0xf9, 0x5d, 0x71, 0xf0, 0xfc, 0xc7, 0x1e,
0x5a, 0x30, 0xb9, 0x86, 0x21, 0x5e, 0x6b, 0x37, 0xa7, 0x0d, 0xf4, 0xdd, 0x39, 0x34, 0x5a, 0x62,
0x80, 0x51, 0xef, 0x10, 0x83, 0x36, 0xf6, 0x77, 0xe7, 0xd0, 0x80, 0x18, 0xfe, 0xd2, 0x43, 0x17,
0xd5, 0x18, 0xd4, 0x16, 0xcb, 0x69, 0xd2, 0xdc, 0x5a, 0xad, 0xcf, 0xa3, 0x22, 0x4f, 0x75, 0x54,
0x93, 0x99, 0xee, 0x06, 0x33, 0x32, 0xd1, 0x8f, 0x05, 0x8b, 0x59, 0x09, 0x62, 0xcb, 0x27, 0x71,
0x03, 0x56, 0x6b, 0xda, 0xb8, 0xf4, 0x01, 0x0e, 0xe8, 0x24, 0xc7, 0x51, 0x7d, 0xf6, 0x1a, 0xc7,
0x5a, 0x07, 0x95, 0xcd, 0xf5, 0xdd, 0x39, 0x34, 0x6a, 0x7b, 0x2d, 0x73, 0x08, 0xfb, 0x78, 0x4c,
0xa6, 0x58, 0xdb, 0x6b, 0xd9, 0x6c, 0x72, 0xd8, 0xb2, 0xd7, 0x6a, 0x55, 0x92, 0xef, 0x53, 0xc5,
0x80, 0xef, 0x14, 0x0f, 0x82, 0x29, 0xc9, 0x63, 0xaa, 0xbf, 0x9f, 0x93, 0xa3, 0x29, 0x11, 0x4b,
0x0f, 0x61, 0x41, 0x8d, 0xde, 0x36, 0xf2, 0x70, 0x14, 0x4f, 0x71, 0xe4, 0xf0, 0x56, 0x21, 0x1d,
0xbc, 0xd5, 0x50, 0x7d, 0x9d, 0x3e, 0x20, 0xac, 0x2f, 0x32, 0xae, 0xd3, 0xa5, 0xc8, 0xbd, 0x4e,
0x57, 0x08, 0x58, 0x0d, 0xd1, 0x59, 0x2e, 0x28, 0x3f, 0x4b, 0xf3, 0x29, 0x6a, 0x4a, 0x3e, 0xfe,
0xa9, 0x59, 0x9d, 0x98, 0x37, 0x5a, 0x39, 0xf9, 0x42, 0x42, 0x4a, 0xd5, 0xc1, 0xf2, 0x6d, 0x36,
0xca, 0x37, 0xb0, 0xcd, 0x11, 0x5b, 0xed, 0xcc, 0x5b, 0x7d, 0x8b, 0xb4, 0x68, 0xf1, 0xdd, 0xc8,
0x8d, 0xd5, 0xce, 0x3c, 0xf8, 0x3e, 0x86, 0x53, 0x5d, 0x03, 0x4c, 0xb7, 0x30, 0x0d, 0xe2, 0xa4,
0xf0, 0x6c, 0x67, 0x5d, 0x40, 0x6e, 0x19, 0x5b, 0x13, 0x27, 0x3f, 0x9c, 0xec, 0x05, 0xc3, 0xea,
0x77, 0x0d, 0xea, 0x87, 0x93, 0xf2, 0xe0, 0x87, 0xb6, 0x2d, 0xbb, 0xe2, 0x20, 0xe4, 0xb7, 0x9d,
0x81, 0xf8, 0xf5, 0x88, 0xfa, 0x65, 0x64, 0xd0, 0xfc, 0xe9, 0xc8, 0x65, 0x3b, 0x20, 0x17, 0xe0,
0x47, 0x98, 0xe6, 0x71, 0x58, 0x0c, 0x30, 0xdd, 0x0b, 0xf2, 0x60, 0x8c, 0x29, 0xce, 0xf5, 0x13,
0x81, 0x80, 0xf8, 0x0a, 0x63, 0x59, 0x80, 0x6d, 0xac, 0x9e, 0xd4, 0xac, 0xef, 0x87, 0xfb, 0x30,
0x25, 0x75, 0xb9, 0x2d, 0xd0, 0x6e, 0xe7, 0x46, 0x2b, 0x27, 0x0f, 0xd4, 0x49, 0x29, 0x4b, 0x03,
0xed, 0xb4, 0x57, 0x4d, 0xb5, 0x4c, 0x12, 0xf3, 0x69, 0xaf, 0x26, 0x25, 0x5f, 0x1b, 0x49, 0x59,
0x7d, 0x9d, 0x31, 0xf6, 0x10, 0xa5, 0x01, 0x51, 0x16, 0x15, 0x7f, 0x7e, 0x57, 0x1c, 0x1c, 0xd3,
0xaa, 0xc1, 0xae, 0x3b, 0x66, 0xab, 0xc9, 0x9d, 0x56, 0x43, 0xf5, 0x95, 0x64, 0xa5, 0x23, 0x2d,
0x5f, 0x56, 0x35, 0xbd, 0x42, 0xdb, 0xb2, 0xda, 0x6a, 0x4a, 0xeb, 0x5a, 0xd6, 0xba, 0x2b, 0xb8,
0xdc, 0xc3, 0xfa, 0xd5, 0xee, 0x5e, 0x5b, 0xbb, 0xd6, 0xba, 0x2b, 0x80, 0xfb, 0x1f, 0xa1, 0xff,
0xdb, 0x8b, 0xd3, 0xa1, 0x77, 0x41, 0x9d, 0x9c, 0x71, 0x3a, 0x14, 0x46, 0x17, 0x4c, 0x22, 0x79,
0x4a, 0x6d, 0x2f, 0x27, 0x21, 0x2e, 0x8a, 0x7e, 0x90, 0x86, 0x38, 0xd1, 0x4e, 0xa9, 0x81, 0xcc,
0xe7, 0x42, 0xcb, 0x29, 0xb5, 0x06, 0x24, 0x97, 0x9d, 0x87, 0x71, 0x41, 0x49, 0x3e, 0x2b, 0x4f,
0x24, 0xab, 0xe5, 0x03, 0x24, 0xea, 0x99, 0xe4, 0xab, 0x2e, 0x44, 0x76, 0x46, 0x20, 0x80, 0x5f,
0x49, 0xe8, 0x87, 0x05, 0x2b, 0xb5, 0x4a, 0x6c, 0xe9, 0x8c, 0x0c, 0x98, 0xdc, 0xce, 0x54, 0x71,
0x63, 0x0a, 0x62, 0x6d, 0x3b, 0x23, 0x42, 0x13, 0x80, 0x65, 0x3b, 0x63, 0x04, 0xc1, 0x4f, 0x1f,
0xbd, 0x09, 0xdf, 0x84, 0x2f, 0x6a, 0xbf, 0x25, 0x50, 0xbe, 0x06, 0x7f, 0x6c, 0x16, 0x82, 0x91,
0x5f, 0xa2, 0xf7, 0xf9, 0x25, 0xf1, 0xd3, 0x25, 0xad, 0x98, 0x68, 0x52, 0x4b, 0x31, 0x69, 0x52,
0xba, 0xfd, 0x03, 0x3c, 0xce, 0x92, 0x80, 0xe2, 0xc2, 0x68, 0x5f, 0x48, 0x9d, 0xf6, 0xeb, 0x14,
0xd8, 0x0f, 0xd0, 0x59, 0x2e, 0xdb, 0x25, 0x61, 0x90, 0xb0, 0xc1, 0xd2, 0xcf, 0x2f, 0xeb, 0x62,
0xcb, 0xf3, 0x34, 0x60, 0xf2, 0x87, 0x0d, 0x8f, 0x82, 0x13, 0x5c, 0x39, 0xd7, 0x12, 0xb1, 0x2e,
0xb2, 0x24, 0xa2, 0x86, 0x80, 0xd9, 0x19, 0x3a, 0x5f, 0x17, 0x6c, 0xce, 0xe4, 0x74, 0xd5, 0x0a,
0xad, 0x0d, 0xb3, 0x14, 0x5a, 0x07, 0x0e, 0xae, 0x7f, 0x8a, 0xde, 0xeb, 0x27, 0x24, 0x95, 0xb7,
0xa4, 0xc6, 0xab, 0xc8, 0x2c, 0xef, 0x48, 0x74, 0x46, 0x3e, 0x6e, 0xee, 0x50, 0x9e, 0x33, 0x34,
0xad, 0x4d, 0xcd, 0x33, 0x86, 0x4b, 0x2d, 0x14, 0xd8, 0xff, 0x19, 0x3a, 0x73, 0x98, 0x16, 0x59,
0x12, 0x14, 0x23, 0x78, 0xbd, 0xa3, 0x86, 0xa5, 0x0a, 0x2d, 0x05, 0xa7, 0x01, 0xc9, 0x5c, 0xaa,
0x44, 0xe2, 0x8c, 0xf6, 0x92, 0x51, 0xb3, 0x71, 0x4a, 0xfb, 0x7a, 0x1b, 0x26, 0x47, 0x7e, 0x23,
0xcb, 0x92, 0x99, 0x65, 0xe4, 0x15, 0x99, 0x65, 0xe4, 0x75, 0x46, 0xb6, 0x4e, 0x5b, 0xf8, 0x78,
0x32, 0x1c, 0xcc, 0xd2, 0x50, 0x6b, 0x9d, 0xca, 0xeb, 0x3e, 0x13, 0x58, 0x5a, 0x27, 0x05, 0x90,
0xd5, 0xb7, 0xbc, 0x7c, 0x30, 0xca, 0x71, 0xe3, 0x77, 0x37, 0x5c, 0x81, 0x8b, 0x6c, 0xbf, 0xe6,
0x51, 0x11, 0x2d, 0xca, 0x83, 0x1c, 0x63, 0x63, 0x94, 0x4c, 0xe0, 0x8c, 0x12, 0x00, 0xb0, 0xb7,
0x86, 0xde, 0x65, 0x3d, 0x04, 0x4e, 0xef, 0x97, 0x3f, 0xbb, 0xf6, 0xce, 0x08, 0x8d, 0xfb, 0xe3,
0x8c, 0xce, 0x16, 0x6a, 0xff, 0x33, 0x60, 0xad, 0xb7, 0x79, 0xe5, 0xdf, 0x2f, 0x17, 0x7b, 0x5f,
0xbf, 0x5c, 0xec, 0xfd, 0xf7, 0xe5, 0x62, 0xef, 0xc5, 0xab, 0xc5, 0x37, 0xbe, 0x7e, 0xb5, 0xf8,
0xc6, 0x7f, 0x5e, 0x2d, 0xbe, 0xf1, 0xc5, 0x5b, 0xf0, 0xb3, 0xef, 0xe3, 0x37, 0xcb, 0x1f, 0x6f,
0xdf, 0xfb, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc6, 0xf6, 0x17, 0x7b, 0x1a, 0x3e, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@ -294,6 +294,7 @@ type ClientCommandsClient interface {
BlockListSetTextMark(ctx context.Context, in *pb.RpcBlockListSetTextMarkRequest, opts ...grpc.CallOption) (*pb.RpcBlockListSetTextMarkResponse, error)
BlockSetTextStyle(ctx context.Context, in *pb.RpcBlockSetTextStyleRequest, opts ...grpc.CallOption) (*pb.RpcBlockSetTextStyleResponse, error)
BlockSetTextChecked(ctx context.Context, in *pb.RpcBlockSetTextCheckedRequest, opts ...grpc.CallOption) (*pb.RpcBlockSetTextCheckedResponse, error)
BlockSetTextIcon(ctx context.Context, in *pb.RpcBlockSetTextIconRequest, opts ...grpc.CallOption) (*pb.RpcBlockSetTextIconResponse, error)
BlockSplit(ctx context.Context, in *pb.RpcBlockSplitRequest, opts ...grpc.CallOption) (*pb.RpcBlockSplitResponse, error)
BlockMerge(ctx context.Context, in *pb.RpcBlockMergeRequest, opts ...grpc.CallOption) (*pb.RpcBlockMergeResponse, error)
BlockCopy(ctx context.Context, in *pb.RpcBlockCopyRequest, opts ...grpc.CallOption) (*pb.RpcBlockCopyResponse, error)
@ -965,6 +966,15 @@ func (c *clientCommandsClient) BlockSetTextChecked(ctx context.Context, in *pb.R
return out, nil
}
func (c *clientCommandsClient) BlockSetTextIcon(ctx context.Context, in *pb.RpcBlockSetTextIconRequest, opts ...grpc.CallOption) (*pb.RpcBlockSetTextIconResponse, error) {
out := new(pb.RpcBlockSetTextIconResponse)
err := c.cc.Invoke(ctx, "/anytype.ClientCommands/BlockSetTextIcon", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *clientCommandsClient) BlockSplit(ctx context.Context, in *pb.RpcBlockSplitRequest, opts ...grpc.CallOption) (*pb.RpcBlockSplitResponse, error) {
out := new(pb.RpcBlockSplitResponse)
err := c.cc.Invoke(ctx, "/anytype.ClientCommands/BlockSplit", in, out, opts...)
@ -1827,6 +1837,7 @@ type ClientCommandsServer interface {
BlockListSetTextMark(*pb.RpcBlockListSetTextMarkRequest) *pb.RpcBlockListSetTextMarkResponse
BlockSetTextStyle(*pb.RpcBlockSetTextStyleRequest) *pb.RpcBlockSetTextStyleResponse
BlockSetTextChecked(*pb.RpcBlockSetTextCheckedRequest) *pb.RpcBlockSetTextCheckedResponse
BlockSetTextIcon(*pb.RpcBlockSetTextIconRequest) *pb.RpcBlockSetTextIconResponse
BlockSplit(*pb.RpcBlockSplitRequest) *pb.RpcBlockSplitResponse
BlockMerge(*pb.RpcBlockMergeRequest) *pb.RpcBlockMergeResponse
BlockCopy(*pb.RpcBlockCopyRequest) *pb.RpcBlockCopyResponse
@ -2122,6 +2133,9 @@ func (*UnimplementedClientCommandsServer) BlockSetTextStyle(req *pb.RpcBlockSetT
func (*UnimplementedClientCommandsServer) BlockSetTextChecked(req *pb.RpcBlockSetTextCheckedRequest) *pb.RpcBlockSetTextCheckedResponse {
return nil
}
func (*UnimplementedClientCommandsServer) BlockSetTextIcon(req *pb.RpcBlockSetTextIconRequest) *pb.RpcBlockSetTextIconResponse {
return nil
}
func (*UnimplementedClientCommandsServer) BlockSplit(req *pb.RpcBlockSplitRequest) *pb.RpcBlockSplitResponse {
return nil
}
@ -3501,6 +3515,24 @@ func _ClientCommands_BlockSetTextChecked_Handler(srv interface{}, ctx context.Co
return interceptor(ctx, in, info, handler)
}
func _ClientCommands_BlockSetTextIcon_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(pb.RpcBlockSetTextIconRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ClientCommandsServer).BlockSetTextIcon(in), nil
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/anytype.ClientCommands/BlockSetTextIcon",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ClientCommandsServer).BlockSetTextIcon(req.(*pb.RpcBlockSetTextIconRequest)), nil
}
return interceptor(ctx, in, info, handler)
}
func _ClientCommands_BlockSplit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(pb.RpcBlockSplitRequest)
if err := dec(in); err != nil {
@ -5305,6 +5337,10 @@ var _ClientCommands_serviceDesc = grpc.ServiceDesc{
MethodName: "BlockSetTextChecked",
Handler: _ClientCommands_BlockSetTextChecked_Handler,
},
{
MethodName: "BlockSetTextIcon",
Handler: _ClientCommands_BlockSetTextIcon_Handler,
},
{
MethodName: "BlockSplit",
Handler: _ClientCommands_BlockSplit_Handler,

View file

@ -6,7 +6,7 @@ package bundle
import "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
const RelationChecksum = "1d97526495f8cb6ac369ef725a5c9e39058fc0c65c5cae464a96c9d206e81d60"
const RelationChecksum = "2e7a4c8295b7aea78b9a072ae48d59dc44fac5ad86df13244ca8da527ad5fcd3"
type RelationKey string
@ -1224,7 +1224,7 @@ var (
},
RelationKeyLinks: {
DataSource: model.Relation_local,
DataSource: model.Relation_derived,
Description: "",
Format: model.RelationFormat_object,
Hidden: true,

View file

@ -69,7 +69,7 @@ func (c *Online) Init(a *app.App) (err error) {
} else {
opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(nil)))
}
conn, err := grpc.Dial(cfg.CafeAPIHost, opts...)
conn, err := grpc.Dial(cfg.CafeNodeGrpcAddr(), opts...)
if err != nil {
return err
}

View file

@ -115,7 +115,6 @@ func injectDefaultFilters(filters []*model.BlockContentDataviewFilter) []*model.
if filter.RelationKey == bundle.RelationKeyIsDeleted.String() {
hasDeletedFilter = true
break
}
}

View file

@ -1,26 +1,34 @@
package ftsearch
import (
"path/filepath"
"strings"
"github.com/blevesearch/bleve"
"github.com/blevesearch/bleve/search/query"
"github.com/anytypeio/go-anytype-middleware/app"
"github.com/anytypeio/go-anytype-middleware/core/wallet"
"github.com/anytypeio/go-anytype-middleware/metrics"
"github.com/blevesearch/bleve/v2/analysis/analyzer/custom"
"github.com/blevesearch/bleve/v2/analysis/lang/en"
"github.com/blevesearch/bleve/v2/analysis/token/lowercase"
"github.com/blevesearch/bleve/v2/analysis/tokenizer/single"
"os"
"path/filepath"
"strings"
"github.com/blevesearch/bleve/v2"
"github.com/blevesearch/bleve/v2/analysis/analyzer/standard"
"github.com/blevesearch/bleve/v2/mapping"
"github.com/blevesearch/bleve/v2/search/query"
)
const (
CName = "fts"
ftsDir = "fts"
ftsVer = "1"
)
type SearchDoc struct {
Id string
Title string
Text string
Id string
Title string
TitleNoTerms string
Text string
}
func New() FTSearch {
@ -37,13 +45,17 @@ type FTSearch interface {
}
type ftSearch struct {
path string
index bleve.Index
rootPath string
ftsPath string
index bleve.Index
enStopWordsMap map[string]bool
}
func (f *ftSearch) Init(a *app.App) (err error) {
repoPath := a.MustComponent(wallet.CName).(wallet.Wallet).RepoPath()
f.path = filepath.Join(repoPath, ftsDir)
f.rootPath = filepath.Join(repoPath, ftsDir)
f.ftsPath = filepath.Join(repoPath, ftsDir, ftsVer)
f.enStopWordsMap, _ = en.TokenMapConstructor(nil, nil)
return nil
}
@ -52,59 +64,131 @@ func (f *ftSearch) Name() (name string) {
}
func (f *ftSearch) Run() (err error) {
f.index, err = bleve.Open(f.path)
f.index, err = bleve.Open(f.ftsPath)
if err == bleve.ErrorIndexPathDoesNotExist || err == bleve.ErrorIndexMetaMissing {
mapping := bleve.NewIndexMapping()
if f.index, err = bleve.New(f.path, mapping); err != nil {
if f.index, err = bleve.New(f.ftsPath, f.makeMapping()); err != nil {
return
}
// cleanup old indexes
if strings.HasSuffix(f.rootPath, ftsDir) {
de, e := os.ReadDir(f.rootPath)
if e == nil {
// cleanup old index versions
for _, d := range de {
if d.Name() != ftsVer {
os.RemoveAll(filepath.Join(f.rootPath, d.Name()))
}
}
}
}
} else if err != nil {
return
}
return nil
}
func (f *ftSearch) makeMapping() mapping.IndexMapping {
mapping := bleve.NewIndexMapping()
keywordMapping := bleve.NewTextFieldMapping()
keywordMapping.Analyzer = "noTerms"
mapping.DefaultMapping.AddFieldMappingsAt("TitleNoTerms", keywordMapping)
mapping.DefaultMapping.AddFieldMappingsAt("Id", keywordMapping)
standardMapping := bleve.NewTextFieldMapping()
standardMapping.Analyzer = standard.Name
mapping.DefaultMapping.AddFieldMappingsAt("Title", standardMapping)
mapping.DefaultMapping.AddFieldMappingsAt("Text", standardMapping)
mapping.AddCustomAnalyzer("noTerms",
map[string]interface{}{
"type": custom.Name,
"tokenizer": single.Name,
"token_filters": []string{
lowercase.Name,
},
})
return mapping
}
func (f *ftSearch) Index(d SearchDoc) (err error) {
metrics.ObjectFTUpdatedCounter.Inc()
d.TitleNoTerms = d.Title
return f.index.Index(d.Id, d)
}
func (f *ftSearch) Search(text string) (results []string, err error) {
text = strings.ToLower(strings.TrimSpace(text))
var queries = make([]query.Query, 0, 4)
terms := append([]string{text}, strings.Split(text, " ")...)
termsFiltered := terms[:0]
// id match
if len(text) > 10 {
im := bleve.NewMatchQuery(text)
im.SetField("Id")
im.SetBoost(30)
queries = append(queries, im)
for _, t := range terms {
t = strings.TrimSpace(t)
if t != "" && !f.enStopWordsMap[t] {
termsFiltered = append(termsFiltered, t)
}
}
terms = termsFiltered
var exactQueries = make([]query.Query, 0, 4)
// id match
if len(text) > 5 {
im := bleve.NewDocIDQuery([]string{text})
im.SetBoost(30)
exactQueries = append(exactQueries, im)
}
// title prefix
tp := bleve.NewPrefixQuery(text)
tp.SetField("Title")
tp.SetField("TitleNoTerms")
tp.SetBoost(40)
queries = append(queries, tp)
exactQueries = append(exactQueries, tp)
// title substr
tss := bleve.NewWildcardQuery("*" + strings.ReplaceAll(text, "*", `\*`) + "*")
tss.SetField("Title")
tss.SetField("TitleNoTerms")
tss.SetBoost(8)
queries = append(queries, tss)
// title match
tm := bleve.NewMatchQuery(text)
tm.SetFuzziness(2)
tm.SetField("Title")
tm.SetBoost(7)
queries = append(queries, tm)
// text match
txtm := bleve.NewMatchQuery(text)
txtm.SetFuzziness(1)
txtm.SetField("Text")
queries = append(queries, txtm)
exactQueries = append(exactQueries, tss)
sr := bleve.NewSearchRequest(bleve.NewDisjunctionQuery(queries...))
var notExactQueriesGroup = make([]query.Query, 0, 5)
for i, t := range terms {
// fulltext queries
var notExactQueries = make([]query.Query, 0, 3)
tp = bleve.NewPrefixQuery(t)
tp.SetField("Title")
if i == 0 {
tp.SetBoost(8)
}
notExactQueries = append(notExactQueries, tp)
// title match
tm := bleve.NewMatchQuery(t)
tm.SetFuzziness(1)
tm.SetField("Title")
if i == 0 {
tm.SetBoost(7)
}
notExactQueries = append(notExactQueries, tm)
// text match
txtm := bleve.NewMatchQuery(t)
txtm.SetFuzziness(0)
txtm.SetField("Text")
if i == 0 {
txtm.SetBoost(2)
}
notExactQueries = append(notExactQueries, txtm)
notExactQueriesGroup = append(notExactQueriesGroup, bleve.NewDisjunctionQuery(notExactQueries...))
}
//exactQueries = []query.Query{bleve.NewDisjunctionQuery(notExactQueriesGroup...)}
exactQueries = append(exactQueries, bleve.NewConjunctionQuery(notExactQueriesGroup...))
sr := bleve.NewSearchRequest(bleve.NewDisjunctionQuery(exactQueries...))
sr.Size = 100
sr.Explain = true
res, err := f.index.Search(sr)
//fmt.Println(res.String())
if err != nil {
return
}

View file

@ -52,93 +52,3 @@ func TestNewFTSearch(t *testing.T) {
assert.Len(t, res, 1)
ft.Close()
}
func TestFtSearch_Search(t *testing.T) {
tmpDir, _ := ioutil.TempDir("", "")
fixture := newFixture(tmpDir, t)
ft := fixture.ft
defer ft.Close()
var docs = [...]SearchDoc{
{
Id: "1",
Title: "First one",
Text: "one two two",
},
{
Id: "2",
Title: "Second two",
Text: "one two three",
},
{
Id: "3",
Title: "Third three",
Text: "some text with 3",
},
{
Id: "4",
Title: "Fours four",
Text: "some text with four and some text five",
},
{
Id: "5",
Title: "Fives five",
Text: "some text with five and one and two ans rs",
},
{
Id: "6",
Title: "Rs six some",
Text: "some text with six",
},
{
Id: "somelongidentifier",
},
{
Id: "eczq5t",
Title: "FERRARI styling CENter with somethinglong ",
},
}
for _, d := range docs {
require.NoError(t, ft.Index(d))
}
searches := [...]struct {
Query string
Result []string
}{
{
"one",
[]string{"1", "2", "5"},
},
{
"rs",
[]string{"6", "1", "4", "5"},
},
{
"two",
[]string{"2", "1", "5"},
},
{
"six",
[]string{"6"},
},
{
"some tex",
[]string{"6", "2", "4", "3", "5"},
},
{
"somelongidentifier",
[]string{"somelongidentifier"},
},
{
"FeRRa",
[]string{"eczq5t"},
},
}
for _, st := range searches {
ids, err := ft.Search(st.Query)
require.NoError(t, err)
assert.Equal(t, st.Result, ids, st.Query)
t.Logf("%s:\t%v\t%v", st.Query, ids, st.Result)
}
}

View file

@ -354,6 +354,7 @@ const (
BlockContentText_Numbered BlockContentTextStyle = 10
BlockContentText_Toggle BlockContentTextStyle = 11
BlockContentText_Description BlockContentTextStyle = 12
BlockContentText_Callout BlockContentTextStyle = 13
)
var BlockContentTextStyle_name = map[int32]string{
@ -370,6 +371,7 @@ var BlockContentTextStyle_name = map[int32]string{
10: "Numbered",
11: "Toggle",
12: "Description",
13: "Callout",
}
var BlockContentTextStyle_value = map[string]int32{
@ -386,6 +388,7 @@ var BlockContentTextStyle_value = map[string]int32{
"Numbered": 10,
"Toggle": 11,
"Description": 12,
"Callout": 13,
}
func (x BlockContentTextStyle) String() string {
@ -1827,11 +1830,13 @@ func (m *BlockContentFeaturedRelations) XXX_DiscardUnknown() {
var xxx_messageInfo_BlockContentFeaturedRelations proto.InternalMessageInfo
type BlockContentText struct {
Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"`
Style BlockContentTextStyle `protobuf:"varint,2,opt,name=style,proto3,enum=anytype.model.BlockContentTextStyle" json:"style,omitempty"`
Marks *BlockContentTextMarks `protobuf:"bytes,3,opt,name=marks,proto3" json:"marks,omitempty"`
Checked bool `protobuf:"varint,4,opt,name=checked,proto3" json:"checked,omitempty"`
Color string `protobuf:"bytes,5,opt,name=color,proto3" json:"color,omitempty"`
Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"`
Style BlockContentTextStyle `protobuf:"varint,2,opt,name=style,proto3,enum=anytype.model.BlockContentTextStyle" json:"style,omitempty"`
Marks *BlockContentTextMarks `protobuf:"bytes,3,opt,name=marks,proto3" json:"marks,omitempty"`
Checked bool `protobuf:"varint,4,opt,name=checked,proto3" json:"checked,omitempty"`
Color string `protobuf:"bytes,5,opt,name=color,proto3" json:"color,omitempty"`
IconEmoji string `protobuf:"bytes,6,opt,name=iconEmoji,proto3" json:"iconEmoji,omitempty"`
IconImage string `protobuf:"bytes,7,opt,name=iconImage,proto3" json:"iconImage,omitempty"`
}
func (m *BlockContentText) Reset() { *m = BlockContentText{} }
@ -1902,6 +1907,20 @@ func (m *BlockContentText) GetColor() string {
return ""
}
func (m *BlockContentText) GetIconEmoji() string {
if m != nil {
return m.IconEmoji
}
return ""
}
func (m *BlockContentText) GetIconImage() string {
if m != nil {
return m.IconImage
}
return ""
}
type BlockContentTextMarks struct {
Marks []*BlockContentTextMark `protobuf:"bytes,1,rep,name=marks,proto3" json:"marks,omitempty"`
}
@ -3907,237 +3926,238 @@ func init() {
}
var fileDescriptor_98a910b73321e591 = []byte{
// 3665 bytes of a gzipped FileDescriptorProto
// 3691 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x3a, 0x4d, 0x73, 0x23, 0xc7,
0x75, 0x1c, 0x60, 0xf0, 0xf5, 0xc8, 0xc5, 0x36, 0x7b, 0x29, 0x0a, 0x86, 0x64, 0x66, 0x33, 0x51,
0xe4, 0xf5, 0x5a, 0xc6, 0x4a, 0x5c, 0xc9, 0x8e, 0x94, 0xe8, 0x83, 0x24, 0x76, 0x4d, 0xd6, 0xae,
0x75, 0x1c, 0x60, 0xf0, 0xf5, 0x48, 0x62, 0x9b, 0xbd, 0x14, 0x05, 0x43, 0xf2, 0x7a, 0x33, 0x51,
0xe4, 0xcd, 0x5a, 0xc6, 0x4a, 0x5c, 0xc9, 0x8e, 0x94, 0xe8, 0x83, 0x24, 0x76, 0x4d, 0xd6, 0xae,
0xc4, 0xd5, 0x80, 0x4b, 0x27, 0xae, 0x54, 0x4a, 0x8d, 0x99, 0x26, 0x30, 0xe2, 0x60, 0x1a, 0xee,
0x69, 0x70, 0x09, 0x57, 0x0e, 0x76, 0x1c, 0xc7, 0x39, 0x3a, 0x49, 0xa5, 0x92, 0xa3, 0x73, 0xc9,
0xc9, 0x55, 0x39, 0xa4, 0x52, 0x95, 0x5f, 0x90, 0x4a, 0xaa, 0x72, 0xd0, 0xd1, 0xbe, 0xa5, 0xa4,
0xca, 0x3d, 0x95, 0x63, 0x2a, 0x87, 0xd4, 0xeb, 0xee, 0x19, 0x0c, 0x40, 0x2e, 0x17, 0xab, 0xf8,
0x36, 0xef, 0xcd, 0x7b, 0xaf, 0x5f, 0xf7, 0xbc, 0xef, 0x1e, 0x78, 0x65, 0x7c, 0x3a, 0xb8, 0x13,
0x47, 0xfd, 0x3b, 0xe3, 0xfe, 0x9d, 0x91, 0x08, 0x79, 0x7c, 0x67, 0x2c, 0x85, 0x12, 0xa9, 0x01,
0xd2, 0x8e, 0x86, 0xe8, 0x35, 0x96, 0x4c, 0xd5, 0x74, 0xcc, 0x3b, 0x1a, 0xdb, 0x7e, 0x79, 0x20,
0xc4, 0x20, 0xe6, 0x86, 0xb4, 0x3f, 0x39, 0xb9, 0x93, 0x2a, 0x39, 0x09, 0x94, 0x21, 0xf6, 0xfe,
0xbd, 0x04, 0x9b, 0xbd, 0x11, 0x93, 0x6a, 0x37, 0x16, 0xc1, 0x69, 0x2f, 0x61, 0xe3, 0x74, 0x28,
0xd4, 0x2e, 0x4b, 0x39, 0x7d, 0x0d, 0xaa, 0x7d, 0x44, 0xa6, 0x2d, 0xe7, 0x66, 0xf9, 0xd6, 0xea,
0xf6, 0x46, 0x67, 0x4e, 0x70, 0x47, 0x73, 0xf8, 0x96, 0x86, 0xbe, 0x01, 0xb5, 0x90, 0x2b, 0x16,
0xc5, 0x69, 0xab, 0x74, 0xd3, 0xb9, 0xb5, 0xba, 0xfd, 0x62, 0xc7, 0x2c, 0xdc, 0xc9, 0x16, 0xee,
0xf4, 0xf4, 0xc2, 0x7e, 0x46, 0x47, 0xef, 0x42, 0xfd, 0x24, 0x8a, 0xf9, 0x03, 0x3e, 0x4d, 0x5b,
0xe5, 0xab, 0x79, 0x72, 0x42, 0xfa, 0x3e, 0x34, 0xf9, 0xb9, 0x92, 0xcc, 0xe7, 0x31, 0x53, 0x91,
0x48, 0xd2, 0x96, 0xab, 0xb5, 0x7b, 0x71, 0x41, 0xbb, 0xec, 0xbd, 0xbf, 0x40, 0x4e, 0x6f, 0xc2,
0xaa, 0xe8, 0x7f, 0xca, 0x03, 0x75, 0x34, 0x1d, 0xf3, 0xb4, 0x55, 0xb9, 0x59, 0xbe, 0xd5, 0xf0,
0x8b, 0x28, 0xfa, 0x36, 0xac, 0x06, 0x22, 0x8e, 0x79, 0x60, 0xe4, 0x57, 0xaf, 0x56, 0xad, 0x48,
0xeb, 0xfd, 0xcf, 0xd7, 0xa1, 0xa2, 0xcf, 0x85, 0x36, 0xa1, 0x14, 0x85, 0x2d, 0xe7, 0xa6, 0x73,
0xab, 0xe1, 0x97, 0xa2, 0x90, 0xde, 0x81, 0xea, 0x49, 0xc4, 0xe3, 0xf0, 0x99, 0xc7, 0x63, 0xc9,
0xe8, 0x3d, 0x58, 0x93, 0x3c, 0x55, 0x32, 0xb2, 0x6a, 0x98, 0x13, 0xfa, 0xcd, 0xcb, 0x3e, 0x42,
0xc7, 0x2f, 0x10, 0xfa, 0x73, 0x6c, 0xb8, 0xdd, 0x60, 0x18, 0xc5, 0xa1, 0xe4, 0xc9, 0x41, 0x68,
0x0e, 0xab, 0xe1, 0x17, 0x51, 0xf4, 0x16, 0x5c, 0xef, 0xb3, 0xe0, 0x74, 0x20, 0xc5, 0x24, 0x09,
0xf7, 0x44, 0x2c, 0x64, 0xab, 0xa2, 0xd5, 0x5e, 0x44, 0xd3, 0xd7, 0xa1, 0xc2, 0xe2, 0x68, 0x90,
0xe8, 0x23, 0x69, 0x6e, 0xb7, 0x2f, 0xd5, 0x65, 0x07, 0x29, 0x7c, 0x43, 0x48, 0x0f, 0x00, 0x52,
0xb4, 0x2e, 0x6d, 0x24, 0xad, 0x55, 0xbd, 0x85, 0xaf, 0x5d, 0xca, 0xb6, 0x27, 0x12, 0xc5, 0x13,
0xd5, 0xe9, 0xe5, 0xe4, 0xfb, 0x2b, 0x7e, 0x81, 0x99, 0x7e, 0x1b, 0x5c, 0xc5, 0xcf, 0x55, 0xab,
0x79, 0xc5, 0x39, 0x64, 0x42, 0x8e, 0xf8, 0xb9, 0xda, 0x5f, 0xf1, 0x35, 0x03, 0x32, 0xa2, 0xf5,
0xb4, 0xae, 0x2f, 0xc1, 0x78, 0x3f, 0x8a, 0x39, 0x32, 0x22, 0x03, 0x7d, 0x17, 0xaa, 0x31, 0x9b,
0x8a, 0x89, 0x6a, 0x11, 0xcd, 0xfa, 0x5b, 0x57, 0xb2, 0x3e, 0xd4, 0xa4, 0xfb, 0x2b, 0xbe, 0x65,
0xa2, 0x6f, 0x42, 0x39, 0x8c, 0xce, 0x5a, 0xeb, 0x9a, 0xf7, 0xe6, 0x95, 0xbc, 0xdd, 0xe8, 0x6c,
0x7f, 0xc5, 0x47, 0x72, 0xba, 0x07, 0xf5, 0xbe, 0x10, 0xa7, 0x23, 0x26, 0x4f, 0x5b, 0x54, 0xb3,
0xfe, 0xf6, 0x95, 0xac, 0xbb, 0x96, 0x78, 0x7f, 0xc5, 0xcf, 0x19, 0x71, 0xcb, 0x51, 0x20, 0x92,
0xd6, 0x8d, 0x25, 0xb6, 0x7c, 0x10, 0x88, 0x04, 0xb7, 0x8c, 0x0c, 0xc8, 0x18, 0x47, 0xc9, 0x69,
0x6b, 0x63, 0x09, 0xc6, 0x87, 0x51, 0x82, 0xab, 0x6a, 0x06, 0x54, 0x3b, 0x64, 0x8a, 0x9d, 0x45,
0xfc, 0x49, 0xeb, 0x85, 0x25, 0xd4, 0xee, 0x5a, 0x62, 0x54, 0x3b, 0x63, 0x44, 0x21, 0xd2, 0xfa,
0x69, 0x6b, 0x73, 0x09, 0x21, 0x99, 0x53, 0xa3, 0x90, 0x8c, 0x91, 0xfe, 0x11, 0xac, 0x9f, 0x70,
0xa6, 0x26, 0x92, 0x87, 0xb3, 0x18, 0xf1, 0xa2, 0x96, 0xd6, 0xb9, 0xfa, 0xdb, 0x2f, 0x72, 0xed,
0x69, 0x70, 0x09, 0x57, 0x0e, 0x76, 0x1c, 0xc7, 0x39, 0x3a, 0x49, 0xa5, 0x92, 0xa3, 0x93, 0x43,
0x4e, 0xbe, 0xa5, 0x52, 0x95, 0x54, 0xe5, 0x96, 0xaa, 0x54, 0x52, 0x95, 0x83, 0x8e, 0xce, 0x2d,
0x25, 0x55, 0xfe, 0x40, 0xce, 0x39, 0xa4, 0x5e, 0x77, 0xcf, 0x60, 0x00, 0x72, 0xb9, 0x58, 0xc5,
0x37, 0xbc, 0x37, 0xef, 0xbd, 0x7e, 0xfd, 0xfa, 0x7d, 0xf5, 0x6b, 0xc0, 0x2b, 0xe3, 0xd3, 0xc1,
0x9d, 0x38, 0xea, 0xdf, 0x19, 0xf7, 0xef, 0x8c, 0x44, 0xc8, 0xe3, 0x3b, 0x63, 0x29, 0x94, 0x48,
0x0d, 0x90, 0x76, 0x34, 0x44, 0xd7, 0x59, 0x32, 0x55, 0xd3, 0x31, 0xef, 0x68, 0x6c, 0xfb, 0xe5,
0x81, 0x10, 0x83, 0x98, 0x1b, 0xd2, 0xfe, 0xe4, 0xe4, 0x4e, 0xaa, 0xe4, 0x24, 0x50, 0x86, 0xd8,
0xfb, 0x8f, 0x12, 0x6c, 0xf5, 0x46, 0x4c, 0xaa, 0xdd, 0x58, 0x04, 0xa7, 0xbd, 0x84, 0x8d, 0xd3,
0xa1, 0x50, 0xbb, 0x2c, 0xe5, 0xf4, 0x35, 0xa8, 0xf6, 0x11, 0x99, 0xb6, 0x9c, 0x9b, 0xe5, 0x5b,
0xab, 0xdb, 0x9b, 0x9d, 0x39, 0xc1, 0x1d, 0xcd, 0xe1, 0x5b, 0x1a, 0xfa, 0x06, 0xd4, 0x42, 0xae,
0x58, 0x14, 0xa7, 0xad, 0xd2, 0x4d, 0xe7, 0xd6, 0xea, 0xf6, 0x8b, 0x1d, 0xb3, 0x70, 0x27, 0x5b,
0xb8, 0xd3, 0xd3, 0x0b, 0xfb, 0x19, 0x1d, 0xbd, 0x0b, 0xf5, 0x93, 0x28, 0xe6, 0x0f, 0xf8, 0x34,
0x6d, 0x95, 0xaf, 0xe6, 0xc9, 0x09, 0xe9, 0xfb, 0xd0, 0xe4, 0xe7, 0x4a, 0x32, 0x9f, 0xc7, 0x4c,
0x45, 0x22, 0x49, 0x5b, 0xae, 0xd6, 0xee, 0xc5, 0x05, 0xed, 0xb2, 0xef, 0xfe, 0x02, 0x39, 0xbd,
0x09, 0xab, 0xa2, 0xff, 0x29, 0x0f, 0xd4, 0xd1, 0x74, 0xcc, 0xd3, 0x56, 0xe5, 0x66, 0xf9, 0x56,
0xc3, 0x2f, 0xa2, 0xe8, 0xdb, 0xb0, 0x1a, 0x88, 0x38, 0xe6, 0x81, 0x91, 0x5f, 0xbd, 0x5a, 0xb5,
0x22, 0xad, 0xf7, 0x2f, 0xb7, 0xa1, 0xa2, 0xed, 0x42, 0x9b, 0x50, 0x8a, 0xc2, 0x96, 0x73, 0xd3,
0xb9, 0xd5, 0xf0, 0x4b, 0x51, 0x48, 0xef, 0x40, 0xf5, 0x24, 0xe2, 0x71, 0xf8, 0x4c, 0xf3, 0x58,
0x32, 0x7a, 0x0f, 0xd6, 0x24, 0x4f, 0x95, 0x8c, 0xac, 0x1a, 0xc6, 0x42, 0xbf, 0x76, 0xd9, 0x21,
0x74, 0xfc, 0x02, 0xa1, 0x3f, 0xc7, 0x86, 0xdb, 0x0d, 0x86, 0x51, 0x1c, 0x4a, 0x9e, 0x1c, 0x84,
0xc6, 0x58, 0x0d, 0xbf, 0x88, 0xa2, 0xb7, 0xe0, 0x5a, 0x9f, 0x05, 0xa7, 0x03, 0x29, 0x26, 0x49,
0xb8, 0x27, 0x62, 0x21, 0x5b, 0x15, 0xad, 0xf6, 0x22, 0x9a, 0xbe, 0x0e, 0x15, 0x16, 0x47, 0x83,
0x44, 0x9b, 0xa4, 0xb9, 0xdd, 0xbe, 0x54, 0x97, 0x1d, 0xa4, 0xf0, 0x0d, 0x21, 0x3d, 0x00, 0x48,
0xd1, 0xbb, 0xb4, 0x93, 0xb4, 0x56, 0xf5, 0x16, 0xbe, 0x7e, 0x29, 0xdb, 0x9e, 0x48, 0x14, 0x4f,
0x54, 0xa7, 0x97, 0x93, 0xef, 0xaf, 0xf8, 0x05, 0x66, 0xfa, 0x6d, 0x70, 0x15, 0x3f, 0x57, 0xad,
0xe6, 0x15, 0x76, 0xc8, 0x84, 0x1c, 0xf1, 0x73, 0xb5, 0xbf, 0xe2, 0x6b, 0x06, 0x64, 0x44, 0xef,
0x69, 0x5d, 0x5b, 0x82, 0xf1, 0x7e, 0x14, 0x73, 0x64, 0x44, 0x06, 0xfa, 0x2e, 0x54, 0x63, 0x36,
0x15, 0x13, 0xd5, 0x22, 0x9a, 0xf5, 0xd7, 0xaf, 0x64, 0x7d, 0xa8, 0x49, 0xf7, 0x57, 0x7c, 0xcb,
0x44, 0xdf, 0x84, 0x72, 0x18, 0x9d, 0xb5, 0x36, 0x34, 0xef, 0xcd, 0x2b, 0x79, 0xbb, 0xd1, 0xd9,
0xfe, 0x8a, 0x8f, 0xe4, 0x74, 0x0f, 0xea, 0x7d, 0x21, 0x4e, 0x47, 0x4c, 0x9e, 0xb6, 0xa8, 0x66,
0xfd, 0x8d, 0x2b, 0x59, 0x77, 0x2d, 0xf1, 0xfe, 0x8a, 0x9f, 0x33, 0xe2, 0x96, 0xa3, 0x40, 0x24,
0xad, 0xeb, 0x4b, 0x6c, 0xf9, 0x20, 0x10, 0x09, 0x6e, 0x19, 0x19, 0x90, 0x31, 0x8e, 0x92, 0xd3,
0xd6, 0xe6, 0x12, 0x8c, 0x0f, 0xa3, 0x04, 0x57, 0xd5, 0x0c, 0xa8, 0x76, 0xc8, 0x14, 0x3b, 0x8b,
0xf8, 0x93, 0xd6, 0x0b, 0x4b, 0xa8, 0xdd, 0xb5, 0xc4, 0xa8, 0x76, 0xc6, 0x88, 0x42, 0xa4, 0x8d,
0xd3, 0xd6, 0xd6, 0x12, 0x42, 0xb2, 0xa0, 0x46, 0x21, 0x19, 0x23, 0xfd, 0x03, 0xd8, 0x38, 0xe1,
0x4c, 0x4d, 0x24, 0x0f, 0x67, 0x39, 0xe2, 0x45, 0x2d, 0xad, 0x73, 0xf5, 0xd9, 0x2f, 0x72, 0xed,
0xaf, 0xf8, 0x17, 0x45, 0xd1, 0x77, 0xa0, 0x12, 0x33, 0xc5, 0xcf, 0x5b, 0x2d, 0x2d, 0xd3, 0x7b,
0x86, 0x51, 0x28, 0x7e, 0xbe, 0xbf, 0xe2, 0x1b, 0x16, 0xfa, 0xfb, 0x70, 0x5d, 0xb1, 0x7e, 0xcc,
0x0f, 0x4f, 0x2c, 0x41, 0xda, 0xfa, 0x8a, 0x96, 0xf2, 0xda, 0xd5, 0xe6, 0x3c, 0xcf, 0xb3, 0xbf,
0xe2, 0x2f, 0x8a, 0x69, 0xff, 0x00, 0xd6, 0x8a, 0x41, 0x80, 0x52, 0x70, 0x25, 0x67, 0x26, 0x00,
0xd5, 0x7d, 0xfd, 0x8c, 0x38, 0x1e, 0x46, 0x4a, 0x07, 0xa0, 0xba, 0xaf, 0x9f, 0xe9, 0x26, 0x54,
0x25, 0x1f, 0x89, 0x33, 0xae, 0xe3, 0x4b, 0xdd, 0xb7, 0x10, 0xd2, 0x86, 0x92, 0x0d, 0x5a, 0xae,
0xa1, 0xc5, 0x67, 0xa4, 0x0d, 0xa5, 0x18, 0x1f, 0x26, 0x3a, 0x3e, 0xd4, 0x7d, 0x0b, 0xb5, 0x7f,
0xb5, 0x05, 0x35, 0xab, 0x48, 0xfb, 0x8f, 0xa1, 0x6a, 0x1c, 0x81, 0xbe, 0x0f, 0x95, 0x54, 0x4d,
0x63, 0xae, 0x55, 0x68, 0x6e, 0x7f, 0x7d, 0x09, 0xe7, 0xe9, 0xf4, 0x90, 0xc1, 0x37, 0x7c, 0xde,
0x1b, 0x50, 0xd1, 0x30, 0xad, 0x41, 0xd9, 0x17, 0x4f, 0xc8, 0x0a, 0x05, 0xa8, 0xee, 0x89, 0x78,
0x32, 0x4a, 0x88, 0x83, 0xc8, 0x6e, 0x74, 0x46, 0x4a, 0x88, 0xdc, 0xe7, 0x2c, 0xe4, 0x92, 0x94,
0xdb, 0xbf, 0x72, 0xc0, 0x45, 0xb3, 0xa4, 0xaf, 0xc0, 0x35, 0xc5, 0xe4, 0x80, 0x9b, 0xb4, 0x76,
0x90, 0x05, 0xe2, 0x79, 0x24, 0x7d, 0x37, 0x53, 0xb1, 0xa4, 0x55, 0xfc, 0xda, 0x33, 0xcd, 0x7d,
0x4e, 0xc1, 0x42, 0x48, 0x2f, 0x2f, 0x15, 0xd2, 0xbd, 0xdf, 0xcd, 0x76, 0x54, 0x07, 0xf7, 0x11,
0x1b, 0x70, 0xb2, 0x42, 0xd7, 0xa0, 0x9e, 0xb9, 0x02, 0x71, 0xe8, 0x35, 0x68, 0x74, 0x59, 0x3a,
0xec, 0x0b, 0x26, 0x43, 0x52, 0xa2, 0xab, 0x50, 0xdb, 0x91, 0xc1, 0x30, 0x3a, 0xe3, 0xa4, 0xdc,
0xfe, 0x44, 0x6f, 0x98, 0xfe, 0xde, 0xfc, 0xb1, 0xbe, 0xfa, 0xac, 0xb8, 0x32, 0x7f, 0xa6, 0x2f,
0x15, 0x34, 0x78, 0x18, 0x25, 0xa8, 0x41, 0x1d, 0xdc, 0xae, 0x50, 0x29, 0x71, 0xda, 0xff, 0xe6,
0x40, 0x3d, 0x0b, 0x27, 0x94, 0x40, 0x79, 0x22, 0x63, 0x7b, 0x6e, 0xf8, 0x48, 0x37, 0xa0, 0xa2,
0x22, 0x65, 0x4f, 0xab, 0xe1, 0x1b, 0x00, 0xf3, 0x4b, 0xc8, 0xd3, 0x40, 0x46, 0x63, 0xed, 0xb6,
0x65, 0xfd, 0xae, 0x88, 0xa2, 0x2f, 0x43, 0x23, 0x1a, 0xb1, 0x01, 0xdf, 0x67, 0xe9, 0x50, 0xdb,
0x53, 0xc3, 0x9f, 0x21, 0x90, 0xff, 0x84, 0x9d, 0x61, 0xf0, 0xd1, 0xef, 0x4d, 0xe6, 0x29, 0xa2,
0xe8, 0x5d, 0x70, 0x71, 0x83, 0x36, 0xe9, 0xfc, 0xc6, 0xc2, 0x86, 0xf1, 0xb3, 0x3c, 0x92, 0x1c,
0x0f, 0xb0, 0x83, 0xe9, 0xdb, 0xd7, 0xc4, 0xed, 0x36, 0xb8, 0x18, 0xd8, 0xd0, 0x8e, 0x13, 0x36,
0xe2, 0x76, 0x1f, 0xfa, 0xb9, 0x7d, 0x03, 0xd6, 0x2f, 0xf8, 0x7a, 0xfb, 0xbf, 0x2a, 0xe0, 0x62,
0xda, 0x40, 0x0e, 0x9d, 0x67, 0x2c, 0x87, 0x4e, 0x21, 0xcf, 0x65, 0x28, 0x28, 0x65, 0xde, 0x50,
0xde, 0x85, 0x0a, 0x9e, 0x69, 0x66, 0x27, 0x4b, 0xb0, 0x7f, 0x88, 0xe4, 0xbe, 0xe1, 0xa2, 0x2d,
0xa8, 0x05, 0x43, 0x1e, 0x9c, 0xf2, 0xd0, 0xba, 0x63, 0x06, 0xe2, 0x27, 0x09, 0x0a, 0x09, 0xdb,
0x00, 0xed, 0x7b, 0x50, 0xd1, 0xfc, 0x68, 0x2b, 0x66, 0x5d, 0x53, 0xc0, 0xbd, 0xba, 0xdc, 0xba,
0x76, 0xd9, 0xf6, 0x2f, 0x4a, 0xe0, 0x22, 0x4c, 0x6f, 0x43, 0x45, 0xb2, 0x64, 0x60, 0x0e, 0xf1,
0x62, 0x1d, 0xe8, 0xe3, 0x3b, 0xdf, 0x90, 0xd0, 0xf7, 0xed, 0xc7, 0x32, 0x07, 0xf5, 0x8d, 0xe5,
0x56, 0x2c, 0x7c, 0x38, 0xdc, 0xd2, 0x98, 0x49, 0x36, 0xb2, 0x96, 0x64, 0x00, 0xef, 0xe7, 0x0e,
0xb8, 0x48, 0x44, 0xd7, 0xe1, 0x5a, 0x4f, 0xc9, 0xe8, 0x94, 0xab, 0xa1, 0x14, 0x93, 0xc1, 0xd0,
0xb8, 0xd0, 0x03, 0x3e, 0x35, 0x3e, 0xe3, 0x60, 0x38, 0x38, 0x50, 0x2c, 0x8e, 0x02, 0x52, 0x42,
0xd3, 0xde, 0x15, 0x71, 0x48, 0xca, 0xf4, 0x3a, 0xac, 0x3e, 0x4e, 0x42, 0x2e, 0xd3, 0x40, 0x48,
0x1e, 0x12, 0xd7, 0xda, 0xff, 0x29, 0xa9, 0xa0, 0xcf, 0xa1, 0x22, 0xba, 0xc2, 0x21, 0x55, 0x7a,
0x03, 0xae, 0xef, 0xce, 0x97, 0x3d, 0xa4, 0x86, 0x8e, 0xf8, 0x21, 0x4f, 0xd0, 0x50, 0x48, 0x9d,
0x36, 0xa0, 0x72, 0x6f, 0x24, 0x3e, 0x8d, 0x48, 0x03, 0x17, 0x3b, 0xd4, 0x85, 0x23, 0x01, 0xef,
0x1f, 0x9c, 0xcc, 0xb7, 0xae, 0x41, 0xe3, 0x11, 0x93, 0x6c, 0x20, 0xd9, 0x18, 0xf5, 0x5b, 0x85,
0x9a, 0x09, 0x50, 0x6f, 0x10, 0x67, 0x06, 0x6c, 0x1b, 0xff, 0x36, 0xc0, 0x5d, 0x52, 0x9e, 0x01,
0x6f, 0x12, 0x17, 0xd7, 0xf8, 0x78, 0x22, 0x14, 0x27, 0x15, 0xd4, 0x74, 0x4f, 0x84, 0x9c, 0x54,
0x11, 0x79, 0x84, 0x3e, 0x47, 0x6a, 0xb8, 0xe7, 0x3d, 0xb4, 0x81, 0xbe, 0x38, 0x27, 0x75, 0x54,
0x03, 0x8f, 0x91, 0x87, 0xa4, 0x81, 0x6f, 0x3e, 0x9a, 0x8c, 0xfa, 0x1c, 0xb7, 0x09, 0xf8, 0xe6,
0x48, 0x0c, 0x06, 0x31, 0x27, 0xab, 0x78, 0x06, 0xdd, 0x99, 0x5b, 0x92, 0xb5, 0xf6, 0x67, 0x65,
0x70, 0xb1, 0xe0, 0x41, 0x93, 0x1f, 0xa2, 0xf3, 0x59, 0x93, 0xc7, 0xe7, 0xdc, 0x71, 0x4a, 0x33,
0xc7, 0xa1, 0xef, 0xd8, 0x8f, 0x5b, 0x5e, 0x22, 0xf4, 0xa0, 0xe0, 0xe2, 0x77, 0xa5, 0xe0, 0x8e,
0xa2, 0x11, 0xb7, 0x01, 0x40, 0x3f, 0x23, 0x2e, 0x8d, 0x7e, 0xc0, 0xb5, 0xf5, 0x96, 0x7d, 0xfd,
0x8c, 0xc6, 0xce, 0xc2, 0x90, 0x87, 0x3b, 0x4a, 0x3b, 0x7c, 0xd9, 0xcf, 0x40, 0xe3, 0x84, 0x4c,
0xf1, 0x56, 0x6d, 0x09, 0x27, 0xd4, 0xcb, 0xf7, 0x90, 0xdc, 0x37, 0x5c, 0x33, 0x1f, 0xae, 0x2f,
0xcf, 0x5e, 0x88, 0x9c, 0x5d, 0x6b, 0x80, 0x75, 0x70, 0x3f, 0x12, 0x59, 0xe0, 0x44, 0x32, 0xe2,
0xe0, 0x87, 0x39, 0xc0, 0x80, 0x46, 0x4a, 0xf8, 0x78, 0x1c, 0x85, 0x5c, 0x90, 0x32, 0x3e, 0xee,
0x4c, 0xc2, 0x48, 0x10, 0x17, 0x93, 0xd5, 0xa3, 0xee, 0x7d, 0x52, 0xf1, 0x5e, 0x2d, 0xc4, 0xdf,
0x9d, 0x89, 0x12, 0x46, 0x8c, 0xb6, 0x44, 0xc7, 0x18, 0x56, 0x9f, 0x87, 0xa4, 0xe4, 0x7d, 0x0b,
0xe9, 0x50, 0x6b, 0x8d, 0x1b, 0xab, 0x29, 0x59, 0x41, 0xb3, 0x7a, 0x3c, 0x8e, 0x05, 0x0b, 0xa3,
0x64, 0x40, 0x1c, 0x13, 0xb7, 0x13, 0xbb, 0xe6, 0x3d, 0x29, 0x05, 0x26, 0xc0, 0x35, 0x80, 0x59,
0x01, 0xdd, 0xfe, 0xef, 0xe6, 0x2c, 0xbb, 0x60, 0xf6, 0x4e, 0xc5, 0x44, 0x06, 0x5c, 0x47, 0x83,
0x86, 0x6f, 0x21, 0xfa, 0x01, 0x54, 0xf0, 0x3d, 0xf6, 0x25, 0x18, 0x24, 0x6e, 0x2f, 0x55, 0xb6,
0x75, 0x8e, 0x23, 0xfe, 0xc4, 0x37, 0x8c, 0xf4, 0x2d, 0x68, 0xc8, 0x65, 0xbb, 0xb1, 0x19, 0x25,
0xdd, 0x02, 0x60, 0x81, 0x8a, 0xce, 0x38, 0xca, 0xb2, 0xee, 0x5e, 0xc0, 0xb4, 0x7f, 0xe9, 0x82,
0x8b, 0x0f, 0x17, 0x5a, 0xa9, 0xbd, 0xb9, 0x18, 0x73, 0x67, 0x79, 0x85, 0x17, 0xec, 0x51, 0xdb,
0x77, 0xb9, 0x60, 0xdf, 0x1f, 0x40, 0x25, 0x15, 0x52, 0x65, 0x9b, 0x58, 0xf2, 0x28, 0x7a, 0x42,
0x2a, 0xdf, 0x30, 0xd2, 0xfb, 0x50, 0x3b, 0x89, 0x62, 0xc5, 0xa5, 0x69, 0x2c, 0x9f, 0x55, 0xd8,
0xe5, 0x32, 0xee, 0x6b, 0x26, 0x3f, 0x63, 0xa6, 0x0f, 0x8b, 0x47, 0x5a, 0xd5, 0x92, 0x3a, 0xcb,
0x49, 0xba, 0xec, 0xa4, 0x6f, 0x03, 0x09, 0xc4, 0x19, 0x97, 0xd9, 0xbb, 0x07, 0x7c, 0xaa, 0x9d,
0xa8, 0xe1, 0x5f, 0xc0, 0xd3, 0x36, 0xd4, 0x87, 0x51, 0xc8, 0x31, 0x79, 0x6a, 0x4f, 0xa9, 0xfb,
0x39, 0x4c, 0x1f, 0x40, 0x3d, 0x60, 0x32, 0xec, 0xa1, 0xcf, 0x36, 0x9e, 0xfb, 0xf0, 0x91, 0xcd,
0xcf, 0x05, 0xe0, 0x42, 0x7a, 0xf1, 0xfb, 0x91, 0x6a, 0x81, 0x59, 0x28, 0x83, 0xbd, 0x37, 0xad,
0xb3, 0x61, 0xc4, 0xc3, 0x42, 0x37, 0x73, 0x93, 0x54, 0x99, 0x10, 0xfa, 0x1d, 0x16, 0xc7, 0x5c,
0x4e, 0x4d, 0xf5, 0xf7, 0x80, 0x25, 0x7d, 0x96, 0x90, 0xb2, 0x77, 0x0b, 0x5c, 0x2d, 0xb9, 0x01,
0x95, 0xde, 0x88, 0xc5, 0xb1, 0xa9, 0x18, 0x3f, 0xe4, 0x61, 0x34, 0x19, 0x19, 0xf7, 0x7a, 0x88,
0xe5, 0x1f, 0x29, 0xb5, 0xff, 0xb9, 0x0c, 0xf5, 0x6c, 0xd3, 0x58, 0xe9, 0x9c, 0xf2, 0x69, 0x56,
0xe9, 0x9c, 0xf2, 0xa9, 0xae, 0x58, 0xd2, 0xe3, 0x28, 0x8d, 0xfa, 0x36, 0xe5, 0xd7, 0xfd, 0x19,
0x02, 0x33, 0xd4, 0x93, 0x28, 0x54, 0x43, 0x6d, 0x3a, 0x15, 0xdf, 0x00, 0xd8, 0x45, 0x87, 0x4c,
0xf1, 0x83, 0x24, 0x88, 0x27, 0x21, 0x3f, 0xc2, 0x50, 0x67, 0xaa, 0xe4, 0x45, 0x34, 0xfd, 0x03,
0x00, 0x15, 0x8d, 0xf8, 0x7d, 0x21, 0x47, 0x4c, 0xd9, 0xaa, 0xe6, 0xed, 0xe7, 0xfb, 0xb8, 0x9d,
0xa3, 0x5c, 0x80, 0x5f, 0x10, 0x86, 0xa2, 0x71, 0x35, 0x2b, 0xba, 0xf6, 0xa5, 0x44, 0x77, 0x73,
0x01, 0x7e, 0x41, 0x98, 0xf7, 0x87, 0x00, 0xb3, 0x37, 0x74, 0x13, 0xe8, 0x87, 0x22, 0x51, 0xc3,
0x9d, 0x7e, 0x5f, 0xee, 0xf2, 0x13, 0x21, 0x79, 0x97, 0x61, 0x8c, 0x7a, 0x01, 0xd6, 0x73, 0xfc,
0xce, 0x89, 0xe2, 0x12, 0xd1, 0xfa, 0xe8, 0x7b, 0x43, 0x21, 0x95, 0xc9, 0x79, 0xfa, 0xf1, 0x71,
0x8f, 0x94, 0x31, 0x2e, 0x1e, 0xf4, 0x0e, 0x89, 0xeb, 0xdd, 0x02, 0x98, 0x6d, 0x09, 0x73, 0x98,
0x79, 0x7a, 0x63, 0xdb, 0xe4, 0x77, 0x03, 0x6d, 0xbf, 0x49, 0x9c, 0xf6, 0x9f, 0x3b, 0xe0, 0xa2,
0xc7, 0x61, 0xe1, 0x58, 0xb4, 0x67, 0xf3, 0xf9, 0x8a, 0xa8, 0x2f, 0x17, 0x27, 0x50, 0x76, 0x21,
0x4e, 0x78, 0x5f, 0xb1, 0xa6, 0x58, 0x83, 0xf2, 0x4e, 0x1a, 0xd8, 0x7a, 0x99, 0xa7, 0x01, 0x71,
0xda, 0x7f, 0xe5, 0x42, 0xd5, 0x38, 0x2e, 0xfd, 0x18, 0xea, 0x62, 0xcc, 0x25, 0x53, 0x42, 0xda,
0xc2, 0xfc, 0xad, 0xe7, 0x71, 0xfc, 0xce, 0xa1, 0x65, 0xf6, 0x73, 0x31, 0x8b, 0xfb, 0x2b, 0x5d,
0xdc, 0xdf, 0x6d, 0x20, 0x99, 0x8f, 0x3f, 0x92, 0xc8, 0xa7, 0xa6, 0xb6, 0x10, 0xbc, 0x80, 0xa7,
0x47, 0xd0, 0x08, 0x44, 0x12, 0x46, 0x79, 0x91, 0xde, 0xdc, 0xfe, 0xd6, 0x73, 0x69, 0xb8, 0x97,
0x71, 0xfb, 0x33, 0x41, 0xf4, 0x35, 0xa8, 0x9c, 0xb1, 0x78, 0x62, 0xb2, 0xfa, 0xea, 0xf6, 0xe6,
0x85, 0x06, 0xe8, 0x18, 0xdf, 0xfa, 0x86, 0xc8, 0x7b, 0x09, 0xea, 0xd9, 0x3e, 0xf5, 0x71, 0x26,
0x21, 0x59, 0xa1, 0x55, 0x28, 0x1d, 0x4a, 0xe2, 0x78, 0xff, 0xe2, 0x40, 0x23, 0x5f, 0xa3, 0x90,
0x65, 0x31, 0xb9, 0x7d, 0x7f, 0xc2, 0x62, 0xe2, 0xe8, 0xd2, 0x46, 0x28, 0x03, 0x69, 0x43, 0xfa,
0x8e, 0xe4, 0x4c, 0x61, 0xe3, 0xa7, 0xa3, 0x03, 0x4f, 0x53, 0xe2, 0x52, 0x0a, 0x4d, 0x8b, 0x3e,
0x94, 0x86, 0xb4, 0x82, 0x95, 0x0f, 0xbe, 0xcd, 0x10, 0x55, 0x13, 0x4c, 0x4e, 0xb9, 0xa9, 0xec,
0x3e, 0x12, 0x4a, 0x03, 0x75, 0xd4, 0xe5, 0x20, 0x21, 0x0d, 0x5c, 0xf3, 0x23, 0xa1, 0x0e, 0x12,
0x02, 0xb3, 0xfc, 0xbb, 0x9a, 0x2d, 0xaf, 0xa1, 0x35, 0x9d, 0xdd, 0xe3, 0xf8, 0x20, 0x21, 0xd7,
0xec, 0x0b, 0x03, 0x35, 0xdb, 0x2f, 0x5f, 0x15, 0x5a, 0xda, 0x2f, 0x61, 0x10, 0x52, 0xfc, 0xfc,
0xb2, 0x36, 0xa3, 0xbd, 0x0e, 0xd7, 0x17, 0x5a, 0x7d, 0xef, 0x04, 0xea, 0x8f, 0x44, 0xba, 0x78,
0x28, 0x35, 0x28, 0x1f, 0x89, 0xb1, 0xa9, 0x76, 0x77, 0x85, 0x52, 0x62, 0x64, 0xaa, 0xdd, 0x87,
0xfc, 0x44, 0x99, 0xca, 0xc3, 0x8f, 0x06, 0x43, 0x65, 0x0a, 0xc9, 0x83, 0x24, 0xe1, 0x92, 0x54,
0x70, 0xab, 0x3e, 0x1f, 0xc7, 0x2c, 0xc0, 0x5a, 0xb2, 0x09, 0xa0, 0xf1, 0xf7, 0x23, 0x99, 0x2a,
0x52, 0xf3, 0xbe, 0x8d, 0xdb, 0x89, 0x06, 0x09, 0x56, 0x19, 0xfa, 0x41, 0x8b, 0x5a, 0xc1, 0xa3,
0xd3, 0xe0, 0x1e, 0x4f, 0xf0, 0xa4, 0x1d, 0x64, 0x34, 0x13, 0x3e, 0xbd, 0x40, 0x69, 0xb7, 0x01,
0xb5, 0xc0, 0x28, 0xeb, 0x3d, 0x82, 0x6b, 0xda, 0x86, 0x3e, 0xe4, 0x8a, 0x1d, 0x26, 0xf1, 0xf4,
0xff, 0x3d, 0x03, 0xf5, 0xbe, 0x01, 0x15, 0xdd, 0x5d, 0xe0, 0x69, 0x9d, 0x48, 0x31, 0xd2, 0xb2,
0x2a, 0xbe, 0x7e, 0x46, 0xe9, 0x4a, 0x68, 0x49, 0x15, 0xbf, 0xa4, 0x84, 0xf7, 0x8f, 0x65, 0xa8,
0xed, 0x04, 0x81, 0x98, 0x24, 0xea, 0xc2, 0xca, 0x97, 0x55, 0xb3, 0x6f, 0x41, 0x95, 0x9d, 0x31,
0xc5, 0xa4, 0x6d, 0xcb, 0xbe, 0xba, 0xe0, 0x0f, 0x56, 0x56, 0x67, 0x47, 0x13, 0xf9, 0x96, 0xb8,
0xcd, 0xa1, 0x6a, 0x30, 0xf4, 0x6d, 0xa8, 0xe8, 0x3e, 0xd6, 0xf6, 0x45, 0x4b, 0x4d, 0x16, 0x0d,
0x07, 0xdd, 0xcc, 0x1a, 0x37, 0xad, 0x10, 0xe2, 0x35, 0xb8, 0x5b, 0xcf, 0x74, 0x6a, 0xff, 0xa7,
0x03, 0xd5, 0x3d, 0x91, 0x9c, 0x44, 0x03, 0xfa, 0x2a, 0x34, 0x79, 0x82, 0x76, 0x91, 0xf9, 0xa4,
0x9d, 0xea, 0x2c, 0x60, 0x31, 0x62, 0x58, 0x0c, 0xef, 0x4f, 0x06, 0x36, 0x71, 0x15, 0x51, 0xf4,
0x3d, 0x68, 0x1b, 0xd0, 0xe7, 0x31, 0x67, 0x29, 0xdf, 0x1b, 0xb2, 0x24, 0xe1, 0x71, 0xef, 0x49,
0xa4, 0x82, 0xa1, 0x9d, 0x00, 0x5d, 0x41, 0x41, 0x3d, 0x58, 0x33, 0x6f, 0x7b, 0x63, 0x16, 0xf0,
0xd4, 0xb6, 0xa3, 0x73, 0x38, 0xfa, 0x4d, 0xa8, 0xe8, 0x89, 0x7b, 0x2b, 0xbc, 0xfa, 0x1b, 0x1b,
0x2a, 0xef, 0x7f, 0x1d, 0x58, 0x2d, 0xf4, 0xf0, 0xbf, 0xc6, 0xb9, 0x43, 0x1b, 0xea, 0xfa, 0xb0,
0x1f, 0xcb, 0xd8, 0x76, 0x1d, 0x39, 0x8c, 0xb5, 0xa7, 0x1d, 0x31, 0xe0, 0x5b, 0x13, 0x34, 0x0b,
0x98, 0x2f, 0x35, 0x73, 0xf0, 0xb6, 0x6d, 0xaa, 0x58, 0x85, 0xda, 0xe3, 0xe4, 0x34, 0x11, 0x4f,
0x12, 0x93, 0x2e, 0xf4, 0xa8, 0x67, 0xae, 0x4b, 0xa8, 0x9b, 0x59, 0x03, 0x29, 0x7b, 0x3f, 0x76,
0x17, 0x06, 0x77, 0xf7, 0xa0, 0x6a, 0xee, 0x22, 0x74, 0x99, 0xde, 0xdc, 0xfe, 0xe6, 0x85, 0x4a,
0x7a, 0x46, 0xdc, 0x31, 0xcd, 0x67, 0x01, 0xe5, 0x5b, 0x66, 0xfa, 0xb0, 0x30, 0x8f, 0x35, 0x85,
0xfd, 0xeb, 0x57, 0x09, 0xca, 0x6c, 0x68, 0xee, 0x22, 0x21, 0x97, 0xd0, 0xfe, 0x89, 0x03, 0x1b,
0x97, 0x91, 0x60, 0xb7, 0xd6, 0x9f, 0x9b, 0xb0, 0x65, 0x20, 0xed, 0x2d, 0x5c, 0x5f, 0x94, 0xf4,
0x6e, 0xee, 0x3c, 0xa7, 0x12, 0xf3, 0x97, 0x19, 0xde, 0x8f, 0x1c, 0x58, 0xbf, 0xb0, 0xe7, 0x42,
0x5c, 0x04, 0xa8, 0x76, 0x79, 0xcc, 0x15, 0x37, 0xb3, 0xb4, 0x7c, 0xba, 0x63, 0x0a, 0x45, 0xed,
0x90, 0xa9, 0x69, 0xb5, 0xbb, 0xe6, 0x0e, 0x8a, 0xb8, 0x18, 0xd0, 0xf0, 0xab, 0xa1, 0xa1, 0x0f,
0xb0, 0xdf, 0x26, 0xb0, 0x66, 0xa6, 0x91, 0x16, 0x53, 0xc5, 0xf8, 0x7e, 0xc4, 0x47, 0xe3, 0x98,
0x29, 0x4e, 0x6a, 0x9e, 0x0f, 0x37, 0x2e, 0x51, 0x54, 0x2f, 0x7d, 0x6c, 0xd5, 0x68, 0x02, 0x74,
0x8f, 0xb3, 0xc5, 0x89, 0x83, 0x39, 0xa9, 0x7b, 0xbc, 0xa7, 0xb3, 0x92, 0x1d, 0x17, 0xe8, 0xf4,
0xd5, 0x3d, 0xc6, 0xba, 0x38, 0x25, 0x65, 0xef, 0x7d, 0x78, 0xe1, 0x68, 0x28, 0x39, 0x0b, 0xbb,
0x9c, 0x8f, 0x63, 0xb4, 0x2e, 0x36, 0xc5, 0x4e, 0xef, 0x92, 0xda, 0x74, 0x03, 0x2a, 0x2c, 0x0c,
0xa5, 0x39, 0xd0, 0x86, 0x6f, 0x00, 0xef, 0x13, 0xd8, 0x34, 0x02, 0xcc, 0x2a, 0x1f, 0x4f, 0xf8,
0x84, 0xdf, 0x4b, 0x94, 0x9c, 0x9a, 0xda, 0x3f, 0xbb, 0xa0, 0x32, 0x34, 0x56, 0xdc, 0x05, 0x3c,
0x7a, 0x8c, 0xd2, 0x4f, 0x07, 0xa1, 0x75, 0xb6, 0x1c, 0xf6, 0x7e, 0xea, 0x02, 0x1c, 0xe6, 0x97,
0x64, 0x97, 0xb8, 0xe9, 0xe5, 0x21, 0xb6, 0xd0, 0xc6, 0x94, 0x97, 0xee, 0x0c, 0x7f, 0x27, 0xbf,
0x78, 0x71, 0xb5, 0xff, 0x2d, 0x5e, 0x9e, 0xcc, 0xf4, 0xb0, 0x83, 0xe3, 0xfc, 0xce, 0x05, 0x2b,
0xf7, 0x40, 0x24, 0x7a, 0x3e, 0x63, 0xdd, 0x7a, 0x86, 0x58, 0x8c, 0x19, 0xd5, 0x8b, 0x31, 0x63,
0x13, 0xaa, 0xc3, 0x28, 0x0c, 0x79, 0xa2, 0x8b, 0xe7, 0xba, 0x6f, 0x21, 0x3c, 0x19, 0x3c, 0x07,
0x91, 0xc4, 0xd3, 0xac, 0x59, 0xc9, 0x60, 0x7a, 0x17, 0x2a, 0x4a, 0x5f, 0x25, 0xd6, 0xb5, 0x89,
0x2f, 0xa6, 0x91, 0xd9, 0xed, 0xaa, 0x0e, 0x15, 0x86, 0x16, 0x03, 0x50, 0x94, 0xda, 0xe1, 0x6e,
0xa8, 0x9b, 0xa9, 0xba, 0x5f, 0xc0, 0x78, 0x7f, 0xeb, 0xe4, 0x83, 0xf4, 0x06, 0x54, 0xfa, 0x2c,
0x8d, 0x02, 0x33, 0x4a, 0x1a, 0x4b, 0x71, 0x62, 0xa6, 0x0e, 0x75, 0x70, 0x95, 0x08, 0x05, 0x29,
0x61, 0x39, 0x90, 0x72, 0x4c, 0xfc, 0x4d, 0x80, 0xd9, 0x45, 0x26, 0x71, 0xd1, 0x72, 0xb3, 0x53,
0x35, 0x93, 0x24, 0xcd, 0x5a, 0x45, 0xdf, 0x08, 0xf3, 0x39, 0x73, 0x0d, 0x57, 0xd0, 0x91, 0x91,
0xd4, 0x91, 0x26, 0x11, 0x8a, 0x9b, 0x22, 0x28, 0xc5, 0x88, 0x4e, 0x00, 0xc5, 0x60, 0x28, 0xe8,
0xb3, 0x94, 0x93, 0x0d, 0xef, 0xaf, 0x67, 0xaa, 0xbd, 0x9e, 0xa7, 0xd9, 0x65, 0x3e, 0xd2, 0xd3,
0x12, 0xf1, 0x3d, 0x58, 0x97, 0xfc, 0xfb, 0x93, 0x68, 0xee, 0xc6, 0xe6, 0x19, 0xd6, 0x72, 0x91,
0xc3, 0x3b, 0x83, 0xf5, 0x0c, 0xf8, 0x6e, 0xa4, 0x86, 0xba, 0xf4, 0xa4, 0x77, 0x0b, 0x57, 0x4a,
0x8e, 0x4d, 0x48, 0x4f, 0x11, 0x39, 0xbb, 0x42, 0xca, 0xcb, 0xda, 0xd2, 0x32, 0x65, 0xed, 0xdf,
0xd4, 0xae, 0x6c, 0x26, 0xdf, 0x82, 0xea, 0x89, 0xe9, 0xc7, 0x4c, 0x1f, 0xf2, 0xd5, 0xa7, 0xac,
0x6f, 0x7b, 0x2e, 0x4b, 0x7c, 0xe9, 0x7c, 0xe2, 0x1d, 0x58, 0x0b, 0xf9, 0x09, 0x9b, 0xc4, 0xea,
0x78, 0x89, 0xaa, 0x7b, 0x8e, 0x96, 0xee, 0xea, 0xd6, 0x90, 0xf5, 0xcc, 0x08, 0xa8, 0xa2, 0x55,
0xf1, 0x9e, 0xa2, 0x8a, 0x8e, 0xc4, 0x86, 0xd2, 0x2f, 0x70, 0x15, 0xbc, 0xa3, 0x7a, 0x99, 0x77,
0x60, 0xcd, 0x67, 0xfd, 0x26, 0x87, 0x4d, 0x93, 0x62, 0x9e, 0x33, 0xf1, 0xfa, 0x26, 0xb6, 0xee,
0x5f, 0xc0, 0x63, 0x6c, 0x1b, 0x4d, 0x62, 0x15, 0xd9, 0xc1, 0x83, 0x01, 0x16, 0x2f, 0xec, 0x1b,
0x17, 0x2f, 0xec, 0xdf, 0x03, 0x48, 0x39, 0x86, 0xb2, 0x6e, 0x14, 0xa8, 0xd6, 0x9a, 0xb6, 0x9c,
0xad, 0xa7, 0xed, 0xed, 0x50, 0x7b, 0xba, 0x5f, 0xe0, 0x40, 0xfd, 0x47, 0xec, 0x7c, 0x0f, 0xab,
0xbd, 0xd6, 0x35, 0x5d, 0x4f, 0xe6, 0xf0, 0x62, 0xcc, 0x68, 0x5e, 0x8c, 0x19, 0x77, 0xa1, 0x92,
0x06, 0x62, 0xcc, 0xf5, 0xa5, 0xe9, 0xd3, 0xbf, 0x6f, 0xa7, 0x87, 0x44, 0xbe, 0xa1, 0xd5, 0x33,
0x7d, 0x0c, 0xd5, 0x42, 0xea, 0xeb, 0xd2, 0x86, 0x9f, 0x81, 0xed, 0x5f, 0x38, 0x50, 0x35, 0x3a,
0x5e, 0x56, 0xc5, 0xea, 0x9e, 0xa1, 0x54, 0xb8, 0x9a, 0xc8, 0xaf, 0x00, 0xca, 0x85, 0x2b, 0x00,
0xfa, 0x4e, 0xa6, 0x93, 0x09, 0xa0, 0xaf, 0x5c, 0x7d, 0x18, 0x73, 0xaa, 0x79, 0xaf, 0x41, 0x45,
0xc3, 0x18, 0x01, 0x62, 0x11, 0xb0, 0xd8, 0xf4, 0xe0, 0x72, 0x96, 0xcf, 0x20, 0x33, 0x69, 0x52,
0xf2, 0xbe, 0x97, 0x51, 0x43, 0x56, 0xb8, 0x98, 0xa2, 0x07, 0x57, 0x23, 0x0e, 0xdd, 0x00, 0x92,
0x72, 0x75, 0x78, 0x72, 0x34, 0xe4, 0x3d, 0x36, 0xe2, 0x3a, 0x2e, 0x95, 0x68, 0x0b, 0x36, 0x0c,
0x6d, 0x3a, 0xff, 0x46, 0xa7, 0xe6, 0x38, 0xea, 0x4b, 0x26, 0xa7, 0xc4, 0xf5, 0xde, 0xd3, 0x33,
0x87, 0xcc, 0xfa, 0x56, 0xf3, 0x3f, 0x4c, 0x4c, 0x24, 0x0c, 0xb9, 0xc4, 0x50, 0x69, 0x26, 0x42,
0xcc, 0x14, 0xeb, 0x66, 0x1a, 0x6a, 0xb4, 0x2e, 0x7b, 0xbb, 0x85, 0x12, 0x60, 0x3e, 0x17, 0x39,
0xcb, 0xe6, 0x22, 0xef, 0x01, 0x5c, 0xcf, 0xd0, 0xe6, 0xb0, 0x30, 0x3d, 0xd5, 0xc4, 0xb8, 0x28,
0xe7, 0x59, 0xb6, 0x96, 0x91, 0xdf, 0xfe, 0xfb, 0x32, 0x34, 0xe7, 0xf3, 0x81, 0xee, 0xa7, 0x8c,
0xee, 0x87, 0x71, 0x68, 0x1a, 0xae, 0x5d, 0x74, 0x8c, 0x40, 0x4e, 0x46, 0xfd, 0xd4, 0x84, 0x79,
0x5d, 0x40, 0x12, 0x7c, 0xf5, 0xc8, 0x44, 0x7f, 0x8d, 0x58, 0xc7, 0x57, 0xfb, 0x62, 0xc4, 0xc9,
0xcd, 0xe2, 0x4d, 0xe1, 0xeb, 0xd9, 0x9d, 0xa2, 0x0e, 0xd7, 0x1f, 0x60, 0x72, 0xe8, 0x71, 0x45,
0x76, 0xb0, 0xb0, 0xe9, 0x1d, 0xcd, 0xa2, 0x32, 0xf9, 0x84, 0x36, 0xec, 0x04, 0xfb, 0x87, 0x25,
0x7a, 0xad, 0x50, 0xe3, 0xfc, 0xbc, 0x44, 0x37, 0xe0, 0xfa, 0xee, 0x24, 0x09, 0x63, 0x1e, 0xe6,
0xd8, 0xbf, 0xd3, 0x58, 0x7d, 0xcf, 0xa0, 0x74, 0x17, 0xa9, 0x85, 0xfc, 0x0c, 0x3f, 0xe6, 0x8d,
0x02, 0x36, 0x2f, 0x7b, 0xfe, 0x62, 0xf1, 0x4d, 0x2e, 0xe9, 0x2f, 0x8b, 0xf2, 0x73, 0xfa, 0x1f,
0xba, 0x88, 0x3d, 0x48, 0x42, 0x7e, 0x5e, 0xc0, 0xfe, 0xc8, 0xa5, 0x9b, 0xb0, 0x6e, 0x69, 0x0b,
0xca, 0xff, 0x89, 0x4b, 0x6f, 0x40, 0x73, 0xc7, 0x1c, 0xbb, 0x3d, 0x15, 0xf2, 0x63, 0xec, 0x77,
0xdd, 0x2e, 0xae, 0xf1, 0xa7, 0x2e, 0x5d, 0x87, 0xb5, 0xef, 0x0a, 0x79, 0xaa, 0x93, 0x18, 0x9e,
0xed, 0x4f, 0xb0, 0xd6, 0x6b, 0xe4, 0x28, 0xf2, 0x67, 0x2e, 0x7d, 0x11, 0xe8, 0xfc, 0xc7, 0xd5,
0x23, 0xc6, 0x9f, 0xba, 0xb7, 0xff, 0xc9, 0x81, 0xe6, 0x7c, 0x60, 0xc6, 0x53, 0x8d, 0x45, 0x32,
0x40, 0xa7, 0x33, 0xc3, 0xf8, 0x74, 0x28, 0xa4, 0xd2, 0xa0, 0xf6, 0x88, 0x44, 0xdf, 0xba, 0x98,
0x4a, 0x33, 0x55, 0x4c, 0x4d, 0x52, 0x33, 0xe0, 0x52, 0x6c, 0x40, 0x56, 0xf1, 0x53, 0x85, 0xa8,
0x97, 0x9b, 0x67, 0xe1, 0x0a, 0x4a, 0x0c, 0xb2, 0x4b, 0x9c, 0x2a, 0x92, 0x4e, 0x64, 0x6c, 0xb2,
0x31, 0x1f, 0xb1, 0x28, 0x36, 0x57, 0x4d, 0xe3, 0x21, 0xd6, 0x94, 0x0d, 0x83, 0x15, 0x9f, 0x46,
0xe6, 0x52, 0xc7, 0x7a, 0x5a, 0x88, 0x7a, 0xe4, 0xb6, 0x4a, 0xf8, 0xee, 0xed, 0x7f, 0xfd, 0x7c,
0xcb, 0xf9, 0xec, 0xf3, 0x2d, 0xe7, 0x3f, 0x3e, 0xdf, 0x72, 0x7e, 0xf6, 0xc5, 0xd6, 0xca, 0x67,
0x5f, 0x6c, 0xad, 0xfc, 0xf2, 0x8b, 0xad, 0x95, 0xef, 0x91, 0xc5, 0x7f, 0xc7, 0xfa, 0x55, 0x9d,
0x2f, 0xee, 0xfe, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x59, 0xda, 0x4e, 0x6c, 0x56, 0x26, 0x00,
0x00,
0x86, 0x53, 0x28, 0x7e, 0xbe, 0xbf, 0xe2, 0x1b, 0x16, 0xfa, 0xbb, 0x70, 0x4d, 0xb1, 0x7e, 0xcc,
0x0f, 0x4f, 0x2c, 0x41, 0xda, 0xfa, 0x8a, 0x96, 0xf2, 0xda, 0xd5, 0xee, 0x3c, 0xcf, 0xb3, 0xbf,
0xe2, 0x2f, 0x8a, 0x69, 0xff, 0x00, 0xd6, 0x8a, 0x49, 0x80, 0x52, 0x70, 0x25, 0x67, 0x26, 0x01,
0xd5, 0x7d, 0xfd, 0x1b, 0x71, 0x3c, 0x8c, 0x94, 0x4e, 0x40, 0x75, 0x5f, 0xff, 0xa6, 0x5b, 0x50,
0x95, 0x7c, 0x24, 0xce, 0xb8, 0xce, 0x2f, 0x75, 0xdf, 0x42, 0x48, 0x1b, 0x4a, 0x36, 0x68, 0xb9,
0x86, 0x16, 0x7f, 0x23, 0x6d, 0x28, 0xc5, 0xf8, 0x30, 0xd1, 0xf9, 0xa1, 0xee, 0x5b, 0xa8, 0xfd,
0xb7, 0x5f, 0x83, 0x9a, 0x55, 0xa4, 0xfd, 0x87, 0x50, 0x35, 0x81, 0x40, 0xdf, 0x87, 0x4a, 0xaa,
0xa6, 0x31, 0xd7, 0x2a, 0x34, 0xb7, 0x7f, 0x73, 0x89, 0xe0, 0xe9, 0xf4, 0x90, 0xc1, 0x37, 0x7c,
0xde, 0x1b, 0x50, 0xd1, 0x30, 0xad, 0x41, 0xd9, 0x17, 0x4f, 0xc8, 0x0a, 0x05, 0xa8, 0xee, 0x89,
0x78, 0x32, 0x4a, 0x88, 0x83, 0xc8, 0x6e, 0x74, 0x46, 0x4a, 0x88, 0xdc, 0xe7, 0x2c, 0xe4, 0x92,
0x94, 0xdb, 0xff, 0xe9, 0x80, 0x8b, 0x6e, 0x49, 0x5f, 0x81, 0x75, 0xc5, 0xe4, 0x80, 0x9b, 0xb2,
0x76, 0x90, 0x25, 0xe2, 0x79, 0x24, 0x7d, 0x37, 0x53, 0xb1, 0xa4, 0x55, 0xfc, 0xfa, 0x33, 0xdd,
0x7d, 0x4e, 0xc1, 0x42, 0x4a, 0x2f, 0x2f, 0x95, 0xd2, 0xbd, 0xdf, 0xce, 0x76, 0x54, 0x07, 0xf7,
0x11, 0x1b, 0x70, 0xb2, 0x42, 0xd7, 0xa0, 0x9e, 0x85, 0x02, 0x71, 0xe8, 0x3a, 0x34, 0xba, 0x2c,
0x1d, 0xf6, 0x05, 0x93, 0x21, 0x29, 0xd1, 0x55, 0xa8, 0xed, 0xc8, 0x60, 0x18, 0x9d, 0x71, 0x52,
0x6e, 0x7f, 0xa2, 0x37, 0x4c, 0x7f, 0x67, 0xde, 0xac, 0xaf, 0x3e, 0x2b, 0xaf, 0xcc, 0xdb, 0xf4,
0xa5, 0x82, 0x06, 0x0f, 0xa3, 0x04, 0x35, 0xa8, 0x83, 0xdb, 0x15, 0x2a, 0x25, 0x4e, 0xfb, 0xdf,
0x1d, 0xa8, 0x67, 0xe9, 0x84, 0x12, 0x28, 0x4f, 0x64, 0x6c, 0xed, 0x86, 0x3f, 0xe9, 0x26, 0x54,
0x54, 0xa4, 0xac, 0xb5, 0x1a, 0xbe, 0x01, 0xb0, 0xbe, 0x84, 0x3c, 0x0d, 0x64, 0x34, 0xd6, 0x61,
0x5b, 0xd6, 0xdf, 0x8a, 0x28, 0xfa, 0x32, 0x34, 0xa2, 0x11, 0x1b, 0xf0, 0x7d, 0x96, 0x0e, 0xb5,
0x3f, 0x35, 0xfc, 0x19, 0x02, 0xf9, 0x4f, 0xd8, 0x19, 0x26, 0x1f, 0xfd, 0xdd, 0x54, 0x9e, 0x22,
0x8a, 0xde, 0x05, 0x17, 0x37, 0x68, 0x8b, 0xce, 0xd7, 0x16, 0x36, 0x8c, 0xc7, 0xf2, 0x48, 0x72,
0x34, 0x60, 0x07, 0xcb, 0xb7, 0xaf, 0x89, 0xdb, 0x6d, 0x70, 0x31, 0xb1, 0xa1, 0x1f, 0x27, 0x6c,
0xc4, 0xed, 0x3e, 0xf4, 0xef, 0xf6, 0x75, 0xd8, 0xb8, 0x10, 0xeb, 0xed, 0x7f, 0xaa, 0x82, 0x8b,
0x65, 0x03, 0x39, 0x74, 0x9d, 0xb1, 0x1c, 0xba, 0x84, 0x3c, 0x97, 0xa3, 0xa0, 0x94, 0x79, 0x47,
0x79, 0x17, 0x2a, 0x68, 0xd3, 0xcc, 0x4f, 0x96, 0x60, 0xff, 0x10, 0xc9, 0x7d, 0xc3, 0x45, 0x5b,
0x50, 0x0b, 0x86, 0x3c, 0x38, 0xe5, 0xa1, 0x0d, 0xc7, 0x0c, 0xc4, 0x23, 0x09, 0x0a, 0x05, 0xdb,
0x00, 0xda, 0xe0, 0x81, 0x48, 0xee, 0x8d, 0xc4, 0xa7, 0x91, 0xb6, 0x1a, 0x1a, 0x3c, 0x43, 0x64,
0x5f, 0x0f, 0xf0, 0x04, 0x5a, 0xb5, 0xd9, 0x57, 0x8d, 0x68, 0xdf, 0x83, 0x8a, 0x5e, 0x1b, 0xfd,
0xcc, 0xe8, 0x6c, 0x9a, 0xbf, 0x57, 0x97, 0xd3, 0xd9, 0xaa, 0xdc, 0xfe, 0x45, 0x09, 0x5c, 0x84,
0xe9, 0x6d, 0xa8, 0x48, 0x96, 0x0c, 0xcc, 0x01, 0x5c, 0xec, 0x21, 0x7d, 0xfc, 0xe6, 0x1b, 0x12,
0xfa, 0xbe, 0x3d, 0x68, 0x63, 0xe4, 0x6f, 0x2c, 0xb7, 0x62, 0xe1, 0xd0, 0xd1, 0x1c, 0x63, 0x26,
0xd9, 0xc8, 0x7a, 0xa1, 0x01, 0xbc, 0x9f, 0x3b, 0xe0, 0x22, 0x11, 0xdd, 0x80, 0xf5, 0x9e, 0x92,
0xd1, 0x29, 0x57, 0x43, 0x29, 0x26, 0x83, 0xa1, 0x09, 0xbf, 0x07, 0x7c, 0x6a, 0xe2, 0xcd, 0xc1,
0x54, 0x72, 0xa0, 0x58, 0x1c, 0x05, 0xa4, 0x84, 0x61, 0xb1, 0x2b, 0xe2, 0x90, 0x94, 0xe9, 0x35,
0x58, 0x7d, 0x9c, 0x84, 0x5c, 0xa6, 0x81, 0x90, 0x3c, 0x24, 0xae, 0x8d, 0x9d, 0x53, 0x52, 0xc1,
0x78, 0x45, 0x45, 0x74, 0x77, 0x44, 0xaa, 0xf4, 0x3a, 0x5c, 0xdb, 0x9d, 0x6f, 0x99, 0x48, 0x0d,
0x83, 0xf8, 0x43, 0x9e, 0xa0, 0x93, 0x91, 0x3a, 0x6d, 0x40, 0x45, 0x9f, 0x02, 0x69, 0xe0, 0x62,
0x87, 0xba, 0xe9, 0x24, 0xe0, 0xfd, 0xb3, 0x93, 0xc5, 0xe5, 0x3a, 0x34, 0x1e, 0x31, 0xc9, 0x06,
0x92, 0x8d, 0x51, 0xbf, 0x55, 0xa8, 0x99, 0xe4, 0xf6, 0x06, 0x71, 0x66, 0xc0, 0xb6, 0xc9, 0x0d,
0x06, 0xb8, 0x4b, 0xca, 0x33, 0xe0, 0x4d, 0xe2, 0xe2, 0x1a, 0x1f, 0x4f, 0x84, 0xe2, 0xa4, 0x82,
0x9a, 0xee, 0x89, 0x90, 0x93, 0x2a, 0x22, 0x8f, 0x30, 0x5e, 0x49, 0x0d, 0xf7, 0xbc, 0x87, 0xfe,
0xd3, 0x17, 0xe7, 0xa4, 0x8e, 0x6a, 0xa0, 0x19, 0x79, 0x48, 0x1a, 0xf8, 0xe5, 0xa3, 0xc9, 0xa8,
0xcf, 0x71, 0x9b, 0x80, 0x5f, 0x8e, 0xc4, 0x60, 0x10, 0x73, 0xb2, 0x8a, 0x36, 0xe8, 0xce, 0x42,
0x9a, 0xac, 0xe1, 0x8a, 0x7b, 0x2c, 0x8e, 0xc5, 0x44, 0x91, 0xf5, 0xf6, 0x67, 0x65, 0x70, 0xb1,
0x73, 0xc2, 0xd8, 0x19, 0x62, 0x14, 0xdb, 0xd8, 0xc1, 0xdf, 0x79, 0x04, 0x96, 0x66, 0x11, 0x48,
0xdf, 0xb1, 0x27, 0x5d, 0x5e, 0x22, 0x87, 0xa1, 0xe0, 0xe2, 0x21, 0x53, 0x70, 0x47, 0xd1, 0x88,
0xdb, 0x4c, 0xa2, 0x7f, 0x23, 0x2e, 0x8d, 0x7e, 0xc0, 0x75, 0x18, 0x94, 0x7d, 0xfd, 0x1b, 0xa3,
0x86, 0x85, 0x21, 0x0f, 0x77, 0x94, 0x8e, 0x81, 0xb2, 0x9f, 0x81, 0x26, 0x9a, 0x99, 0x32, 0xde,
0xff, 0xac, 0x68, 0xd6, 0xcb, 0xf7, 0x90, 0xdc, 0x37, 0x5c, 0xb3, 0x64, 0x50, 0x5f, 0x9e, 0xbd,
0x90, 0x82, 0xbb, 0xd6, 0x1b, 0xeb, 0xe0, 0x7e, 0x24, 0xb2, 0x0c, 0x8c, 0x64, 0xc4, 0xc1, 0x53,
0xd2, 0x61, 0x48, 0x4a, 0xf8, 0xf3, 0x38, 0x0a, 0xb9, 0x20, 0x65, 0xfc, 0xb9, 0x33, 0x09, 0x23,
0x41, 0x5c, 0xac, 0x7a, 0x8f, 0xba, 0xf7, 0x49, 0xc5, 0x7b, 0xb5, 0x90, 0xc8, 0x77, 0x26, 0x4a,
0x18, 0x31, 0xda, 0x2d, 0x1d, 0xe3, 0x65, 0x7d, 0x1e, 0x92, 0x92, 0xf7, 0x2d, 0xa4, 0x43, 0xad,
0x35, 0x6e, 0xac, 0xa6, 0x64, 0x05, 0x7d, 0xec, 0xf1, 0x38, 0x16, 0x2c, 0x8c, 0x92, 0x01, 0x71,
0x4c, 0x01, 0x48, 0xec, 0x9a, 0xf7, 0xa4, 0x14, 0x58, 0x49, 0xd7, 0x00, 0x66, 0x9d, 0x78, 0xfb,
0x7f, 0x9a, 0xb3, 0x32, 0x85, 0x6d, 0x40, 0x2a, 0x26, 0x32, 0xe0, 0x3a, 0x35, 0x34, 0x7c, 0x0b,
0xd1, 0x0f, 0xa0, 0x82, 0xdf, 0xf1, 0x82, 0x83, 0x19, 0xe3, 0xf6, 0x52, 0xfd, 0x5f, 0xe7, 0x38,
0xe2, 0x4f, 0x7c, 0xc3, 0x48, 0xdf, 0x82, 0x86, 0x5c, 0xf6, 0x5a, 0x37, 0xa3, 0xa4, 0x37, 0x00,
0x58, 0xa0, 0xa2, 0x33, 0x8e, 0xb2, 0x6c, 0xec, 0x17, 0x30, 0xed, 0x5f, 0xba, 0xe0, 0xe2, 0x8f,
0x0b, 0x77, 0xb2, 0xbd, 0xb9, 0x84, 0x73, 0x67, 0x79, 0x85, 0x17, 0xfc, 0x51, 0xfb, 0x77, 0xb9,
0xe0, 0xdf, 0x1f, 0x40, 0x25, 0x15, 0x52, 0x65, 0x9b, 0x58, 0xd2, 0x14, 0x3d, 0x21, 0x95, 0x6f,
0x18, 0xe9, 0x7d, 0xa8, 0x9d, 0x44, 0xb1, 0xe2, 0xd2, 0xdc, 0x50, 0x9f, 0xd5, 0x21, 0xe6, 0x32,
0xee, 0x6b, 0x26, 0x3f, 0x63, 0xa6, 0x0f, 0x8b, 0x26, 0xad, 0x6a, 0x49, 0x9d, 0xe5, 0x24, 0x5d,
0x66, 0xe9, 0xdb, 0x40, 0x02, 0x71, 0xc6, 0x65, 0xf6, 0xed, 0x01, 0x9f, 0xda, 0x12, 0x72, 0x01,
0x4f, 0xdb, 0x50, 0x1f, 0x46, 0x21, 0xc7, 0x2a, 0xac, 0x23, 0xa5, 0xee, 0xe7, 0x30, 0x7d, 0x00,
0xf5, 0x80, 0xc9, 0xb0, 0x87, 0x31, 0xdb, 0x78, 0x6e, 0xe3, 0x23, 0x9b, 0x9f, 0x0b, 0xc0, 0x85,
0xf4, 0xe2, 0xf7, 0x23, 0xd5, 0x02, 0xb3, 0x50, 0x06, 0x7b, 0x6f, 0xda, 0x60, 0xc3, 0xf4, 0x87,
0x1d, 0x73, 0x16, 0x26, 0xa9, 0x32, 0xf9, 0xf4, 0x3b, 0x2c, 0x8e, 0xb9, 0x9c, 0x9a, 0x36, 0xf2,
0x01, 0x4b, 0xfa, 0x2c, 0x21, 0x65, 0xef, 0x16, 0xb8, 0x5a, 0x72, 0x03, 0x2a, 0xbd, 0x11, 0x8b,
0x63, 0xd3, 0x7a, 0x7e, 0xc8, 0xc3, 0x68, 0x32, 0x32, 0xe1, 0xf5, 0x10, 0xfb, 0x48, 0x52, 0x6a,
0xff, 0x63, 0x19, 0xea, 0xd9, 0xa6, 0xb1, 0x65, 0x3a, 0xe5, 0xd3, 0xac, 0x65, 0x3a, 0xe5, 0x53,
0x5d, 0x6b, 0xd3, 0xe3, 0x28, 0x8d, 0xfa, 0xb6, 0x77, 0xa8, 0xfb, 0x33, 0x04, 0x96, 0xab, 0x27,
0x51, 0xa8, 0x86, 0xda, 0x75, 0x2a, 0xbe, 0x01, 0xf0, 0x3a, 0x1e, 0x32, 0xc5, 0x0f, 0x92, 0x20,
0x9e, 0x84, 0xfc, 0x08, 0x53, 0x9d, 0x69, 0xb7, 0x17, 0xd1, 0xf4, 0xf7, 0x00, 0x54, 0x34, 0xe2,
0xf7, 0x85, 0x1c, 0x31, 0x65, 0xdb, 0xa3, 0xb7, 0x9f, 0xef, 0x70, 0x3b, 0x47, 0xb9, 0x00, 0xbf,
0x20, 0x0c, 0x45, 0xe3, 0x6a, 0x56, 0x74, 0xed, 0x4b, 0x89, 0xee, 0xe6, 0x02, 0xfc, 0x82, 0x30,
0xef, 0xf7, 0x01, 0x66, 0x5f, 0xe8, 0x16, 0xd0, 0x0f, 0x45, 0xa2, 0x86, 0x3b, 0xfd, 0xbe, 0xdc,
0xe5, 0x27, 0x42, 0xf2, 0x2e, 0xc3, 0x1c, 0xf5, 0x02, 0x6c, 0xe4, 0xf8, 0x9d, 0x13, 0xc5, 0x25,
0xa2, 0xb5, 0xe9, 0x7b, 0x43, 0x21, 0x95, 0x29, 0x80, 0xfa, 0xe7, 0xe3, 0x1e, 0x29, 0x63, 0x5e,
0x3c, 0xe8, 0x1d, 0x12, 0xd7, 0xbb, 0x05, 0x30, 0xdb, 0x12, 0x16, 0x34, 0xf3, 0xeb, 0x8d, 0x6d,
0x53, 0xec, 0x0d, 0xb4, 0xfd, 0x26, 0x71, 0xda, 0x7f, 0xea, 0x80, 0x8b, 0x11, 0x87, 0x1d, 0x68,
0xd1, 0x9f, 0xcd, 0xf1, 0x15, 0x51, 0x5f, 0x2e, 0x4f, 0xa0, 0xec, 0x42, 0x9e, 0xf0, 0xbe, 0x62,
0x5d, 0xb1, 0x06, 0xe5, 0x9d, 0x34, 0xb0, 0x8d, 0x37, 0x4f, 0x03, 0xe2, 0xb4, 0xff, 0xc2, 0x85,
0xaa, 0x09, 0x5c, 0xfa, 0x31, 0xd4, 0xc5, 0x98, 0x4b, 0xa6, 0x84, 0xb4, 0x1d, 0xfe, 0x5b, 0xcf,
0x13, 0xf8, 0x9d, 0x43, 0xcb, 0xec, 0xe7, 0x62, 0x16, 0xf7, 0x57, 0xba, 0xb8, 0xbf, 0xdb, 0x40,
0xb2, 0x18, 0x7f, 0x24, 0x91, 0x4f, 0x4d, 0x6d, 0x47, 0x79, 0x01, 0x4f, 0x8f, 0xa0, 0x11, 0x88,
0x24, 0x8c, 0xf2, 0x6e, 0xbf, 0xb9, 0xfd, 0xad, 0xe7, 0xd2, 0x70, 0x2f, 0xe3, 0xf6, 0x67, 0x82,
0xe8, 0x6b, 0x50, 0x39, 0x63, 0xf1, 0xc4, 0x54, 0xf5, 0xd5, 0xed, 0xad, 0x0b, 0x37, 0xa9, 0x63,
0xfc, 0xea, 0x1b, 0x22, 0xef, 0x25, 0xa8, 0x67, 0xfb, 0xd4, 0xe6, 0x4c, 0x42, 0xb2, 0x42, 0xab,
0x50, 0x3a, 0x94, 0xc4, 0xf1, 0xfe, 0xd5, 0x81, 0x46, 0xbe, 0x46, 0xa1, 0xca, 0x62, 0x71, 0xfb,
0xfe, 0x84, 0xc5, 0xc4, 0xd1, 0x7d, 0x8e, 0x50, 0x06, 0xd2, 0x8e, 0xf4, 0x1d, 0xc9, 0x99, 0xc2,
0x1b, 0xa4, 0xce, 0x0e, 0x3c, 0x4d, 0x89, 0x4b, 0x29, 0x34, 0x2d, 0xfa, 0x50, 0x1a, 0xd2, 0x0a,
0xb6, 0x41, 0xf8, 0x35, 0x43, 0x54, 0x4d, 0x32, 0x39, 0xe5, 0xa6, 0xcd, 0xfb, 0x48, 0x28, 0x0d,
0xd4, 0x51, 0x97, 0x83, 0x84, 0x34, 0x70, 0xcd, 0x8f, 0x84, 0x3a, 0x48, 0x08, 0xcc, 0xea, 0xef,
0x6a, 0xb6, 0xbc, 0x86, 0xd6, 0x74, 0x75, 0x8f, 0xe3, 0x83, 0x84, 0xac, 0xdb, 0x0f, 0x06, 0x6a,
0xb6, 0x5f, 0xbe, 0x2a, 0xb5, 0xb4, 0x5f, 0xc2, 0x24, 0xa4, 0xf8, 0xf9, 0x65, 0xf7, 0x95, 0xf6,
0x06, 0x5c, 0x5b, 0x98, 0x19, 0x78, 0x27, 0x50, 0x7f, 0x24, 0xd2, 0x45, 0xa3, 0xd4, 0xa0, 0x7c,
0x24, 0xc6, 0xa6, 0xf5, 0xdd, 0x15, 0x4a, 0x89, 0x91, 0x69, 0x7d, 0x1f, 0xf2, 0x13, 0x65, 0x3a,
0x0f, 0x3f, 0x1a, 0x0c, 0x95, 0xe9, 0x2a, 0x0f, 0x92, 0x84, 0x4b, 0x52, 0xc1, 0xad, 0xfa, 0x7c,
0x1c, 0xb3, 0x00, 0x1b, 0xcb, 0x26, 0x80, 0xc6, 0xdf, 0x8f, 0x64, 0xaa, 0x48, 0xcd, 0xfb, 0x36,
0x6e, 0x27, 0x1a, 0x24, 0xd8, 0x65, 0xe8, 0x1f, 0x5a, 0xd4, 0x0a, 0x9a, 0x4e, 0x83, 0x7b, 0x3c,
0x41, 0x4b, 0x3b, 0xc8, 0x68, 0x46, 0x85, 0x7a, 0x81, 0xd2, 0x6e, 0x03, 0x6a, 0x81, 0x51, 0xd6,
0x7b, 0x04, 0xeb, 0xda, 0x87, 0x3e, 0xe4, 0x8a, 0x1d, 0x26, 0xf1, 0xf4, 0xff, 0x3d, 0x4c, 0xf5,
0xbe, 0x01, 0x15, 0x7d, 0xd5, 0x40, 0x6b, 0x9d, 0x48, 0x31, 0xd2, 0xb2, 0x2a, 0xbe, 0xfe, 0x8d,
0xd2, 0x95, 0xd0, 0x92, 0x2a, 0x7e, 0x49, 0x09, 0xef, 0xef, 0xcb, 0x50, 0xdb, 0x09, 0x02, 0x31,
0x49, 0xd4, 0x85, 0x95, 0x2f, 0xeb, 0x66, 0xdf, 0x82, 0x2a, 0x3b, 0x63, 0x8a, 0x49, 0x7b, 0xbf,
0xfb, 0xea, 0x42, 0x3c, 0x58, 0x59, 0x9d, 0x1d, 0x4d, 0xe4, 0x5b, 0xe2, 0x36, 0x87, 0xaa, 0xc1,
0xd0, 0xb7, 0xa1, 0xa2, 0x2f, 0xc4, 0xf6, 0x92, 0xb4, 0xd4, 0x88, 0xd2, 0x70, 0xd0, 0xad, 0xec,
0x06, 0xa8, 0x15, 0x42, 0xbc, 0x06, 0x77, 0xeb, 0x99, 0x4e, 0xed, 0xff, 0x76, 0xa0, 0xba, 0x27,
0x92, 0x93, 0x68, 0x40, 0x5f, 0x85, 0x26, 0x4f, 0xd0, 0x2f, 0xb2, 0x98, 0xb4, 0xe3, 0xa1, 0x05,
0x2c, 0x66, 0x0c, 0x8b, 0xe1, 0xfd, 0xc9, 0xc0, 0x16, 0xae, 0x22, 0x8a, 0xbe, 0x07, 0x6d, 0x03,
0xfa, 0x3c, 0xe6, 0x2c, 0xe5, 0x7b, 0x43, 0x96, 0x24, 0x3c, 0xee, 0x3d, 0x89, 0x54, 0x30, 0xb4,
0xa3, 0xa4, 0x2b, 0x28, 0xa8, 0x07, 0x6b, 0xe6, 0x6b, 0x6f, 0xcc, 0x02, 0x9e, 0xda, 0x7b, 0xed,
0x1c, 0x8e, 0x7e, 0x13, 0x2a, 0x7a, 0x74, 0xdf, 0x0a, 0xaf, 0x3e, 0x63, 0x43, 0xe5, 0xfd, 0xaf,
0x03, 0xab, 0x85, 0x61, 0xc0, 0xaf, 0x70, 0x80, 0xd1, 0x86, 0xba, 0x36, 0xf6, 0x63, 0x19, 0xdb,
0x5b, 0x47, 0x0e, 0x63, 0xef, 0x69, 0x67, 0x15, 0xf8, 0xd5, 0x24, 0xcd, 0x02, 0xe6, 0x4b, 0x0d,
0x2f, 0xbc, 0x6d, 0x5b, 0x2a, 0x56, 0xa1, 0xf6, 0x38, 0x39, 0x4d, 0xc4, 0x93, 0xc4, 0x94, 0x0b,
0x3d, 0x33, 0x9a, 0xbb, 0x25, 0xd4, 0xcd, 0xd0, 0x82, 0x94, 0xbd, 0x1f, 0xbb, 0x0b, 0x13, 0xc0,
0x7b, 0x50, 0x35, 0x8f, 0x1a, 0xba, 0x4d, 0x6f, 0x6e, 0x7f, 0xf3, 0x42, 0x27, 0x3d, 0x23, 0xee,
0x98, 0x9b, 0x68, 0x01, 0xe5, 0x5b, 0x66, 0xfa, 0xb0, 0x30, 0xd8, 0x35, 0x8d, 0xfd, 0xeb, 0x57,
0x09, 0xca, 0x7c, 0x68, 0xee, 0x45, 0x22, 0x97, 0xd0, 0xfe, 0x89, 0x03, 0x9b, 0x97, 0x91, 0xe0,
0x6d, 0xad, 0x3f, 0x37, 0xaa, 0xcb, 0x40, 0xda, 0x5b, 0x78, 0x07, 0x29, 0xe9, 0xdd, 0xdc, 0x79,
0x4e, 0x25, 0xe6, 0x5f, 0x45, 0xbc, 0x1f, 0x39, 0xb0, 0x71, 0x61, 0xcf, 0x85, 0xbc, 0x08, 0x50,
0xed, 0xf2, 0x98, 0x2b, 0x6e, 0x86, 0x72, 0xf9, 0x98, 0xc8, 0x34, 0x8a, 0x3a, 0x20, 0x53, 0x73,
0xef, 0xee, 0x9a, 0xc7, 0x2c, 0xe2, 0x62, 0x42, 0xc3, 0x53, 0x43, 0x47, 0x1f, 0xe0, 0xe5, 0x9b,
0xc0, 0x9a, 0x19, 0x6b, 0x5a, 0x4c, 0x15, 0xf3, 0xfb, 0x11, 0x1f, 0x8d, 0x63, 0xa6, 0x38, 0xa9,
0x79, 0x3e, 0x5c, 0xbf, 0x44, 0x51, 0xbd, 0xf4, 0xb1, 0x55, 0xa3, 0x09, 0xd0, 0x3d, 0xce, 0x16,
0x27, 0x0e, 0xd6, 0xa4, 0xee, 0xf1, 0x9e, 0xae, 0x4a, 0x76, 0x76, 0xa0, 0xcb, 0x57, 0xf7, 0x18,
0xfb, 0xe2, 0x94, 0x94, 0xbd, 0xf7, 0xe1, 0x85, 0xa3, 0xa1, 0xe4, 0x2c, 0xec, 0x72, 0x3e, 0x8e,
0xd1, 0xbb, 0xd8, 0x14, 0x6f, 0x7a, 0x97, 0xf4, 0xa6, 0x9b, 0x50, 0x61, 0x61, 0x28, 0x8d, 0x41,
0x1b, 0xbe, 0x01, 0xbc, 0x4f, 0x60, 0xcb, 0x08, 0x30, 0xab, 0x7c, 0x3c, 0xe1, 0x13, 0x7e, 0x2f,
0x51, 0x72, 0x6a, 0x7a, 0xff, 0xec, 0xa5, 0xcb, 0xd0, 0x58, 0x71, 0x17, 0xf0, 0x18, 0x31, 0x4a,
0xff, 0x3a, 0x08, 0x6d, 0xb0, 0xe5, 0xb0, 0xf7, 0x53, 0x17, 0xe0, 0x30, 0x7f, 0x6d, 0xbb, 0x24,
0x4c, 0x2f, 0x4f, 0xb1, 0x85, 0x6b, 0x4c, 0x79, 0xe9, 0x9b, 0xe1, 0x6f, 0xe5, 0x2f, 0x38, 0xae,
0x8e, 0xbf, 0xc5, 0x57, 0x98, 0x99, 0x1e, 0x76, 0x02, 0x9d, 0x3f, 0xde, 0xcc, 0xcd, 0xd0, 0x2a,
0x8b, 0x33, 0xb4, 0x85, 0x9c, 0x51, 0xbd, 0x98, 0x33, 0xb6, 0xa0, 0x3a, 0x8c, 0xc2, 0x90, 0x27,
0xba, 0x79, 0xae, 0xfb, 0x16, 0x42, 0xcb, 0xa0, 0x1d, 0x44, 0x12, 0x4f, 0xb3, 0xcb, 0x4a, 0x06,
0xd3, 0xbb, 0x50, 0x51, 0xfa, 0x4d, 0xb2, 0xae, 0x5d, 0x7c, 0xb1, 0x8c, 0xcc, 0x9e, 0x69, 0x75,
0xaa, 0x30, 0xb4, 0x98, 0x80, 0xa2, 0xd4, 0x4e, 0x89, 0x43, 0x7d, 0x99, 0xaa, 0xfb, 0x05, 0x8c,
0xf7, 0xd7, 0x4e, 0x3e, 0x91, 0x6f, 0x40, 0xa5, 0xcf, 0xd2, 0x28, 0x30, 0x73, 0xa5, 0xb1, 0x14,
0x27, 0x66, 0xea, 0x50, 0x07, 0x57, 0x89, 0x50, 0x90, 0x12, 0xb6, 0x03, 0x29, 0xc7, 0xc2, 0xdf,
0x04, 0x98, 0xbd, 0x88, 0x12, 0x17, 0x3d, 0x37, 0xb3, 0xaa, 0x19, 0x2b, 0x69, 0xd6, 0x2a, 0xc6,
0x46, 0x98, 0x0f, 0xac, 0x6b, 0xb8, 0x82, 0xce, 0x8c, 0xa4, 0x8e, 0x34, 0x89, 0x50, 0xdc, 0x34,
0x41, 0x29, 0x66, 0x74, 0x02, 0x28, 0x06, 0x53, 0x41, 0x9f, 0xa5, 0x9c, 0x6c, 0x7a, 0x7f, 0x39,
0x53, 0xed, 0xf5, 0xbc, 0xcc, 0x2e, 0x73, 0x48, 0x4f, 0x2b, 0xc4, 0xf7, 0x60, 0x43, 0xf2, 0xef,
0x4f, 0xa2, 0xb9, 0xa7, 0x9f, 0x67, 0x78, 0xcb, 0x45, 0x0e, 0xef, 0x0c, 0x36, 0x32, 0xe0, 0xbb,
0x91, 0x1a, 0xea, 0xd6, 0x93, 0xde, 0x2d, 0xbc, 0x4d, 0x39, 0xb6, 0x20, 0x3d, 0x45, 0xe4, 0xec,
0x2d, 0x2a, 0x6f, 0x6b, 0x4b, 0xcb, 0xb4, 0xb5, 0x7f, 0x55, 0xbb, 0xf2, 0x32, 0xf9, 0x16, 0x54,
0x4f, 0xcc, 0x7d, 0xcc, 0xdc, 0x43, 0xbe, 0xfa, 0x94, 0xf5, 0xed, 0x9d, 0xcb, 0x12, 0x5f, 0x3a,
0x9f, 0x78, 0x07, 0xd6, 0x42, 0x7e, 0xc2, 0x26, 0xb1, 0x3a, 0x5e, 0xa2, 0xeb, 0x9e, 0xa3, 0xa5,
0xbb, 0xfa, 0x6a, 0xc8, 0x7a, 0x66, 0x04, 0x54, 0xd1, 0xaa, 0x78, 0x4f, 0x51, 0x45, 0x67, 0x62,
0x43, 0xe9, 0x17, 0xb8, 0x0a, 0xd1, 0x51, 0xbd, 0x2c, 0x3a, 0xb0, 0xe7, 0xb3, 0x71, 0x93, 0xc3,
0xe6, 0x92, 0x62, 0x7e, 0x67, 0xe2, 0xf5, 0x93, 0x6e, 0xdd, 0xbf, 0x80, 0xc7, 0xdc, 0x36, 0x9a,
0xc4, 0x2a, 0xb2, 0x83, 0x07, 0x03, 0x2c, 0xbe, 0xfc, 0x37, 0x2e, 0xbe, 0xfc, 0xbf, 0x07, 0x90,
0x72, 0x4c, 0x65, 0xdd, 0x28, 0x50, 0xad, 0x35, 0xed, 0x39, 0x37, 0x9e, 0xb6, 0xb7, 0x43, 0x1d,
0xe9, 0x7e, 0x81, 0x03, 0xf5, 0x1f, 0xb1, 0xf3, 0x3d, 0xec, 0xf6, 0x5a, 0xeb, 0xba, 0x9f, 0xcc,
0xe1, 0xc5, 0x9c, 0xd1, 0xbc, 0x98, 0x33, 0xee, 0x42, 0x25, 0x0d, 0xc4, 0x98, 0xeb, 0xd7, 0xd7,
0xa7, 0x9f, 0x6f, 0xa7, 0x87, 0x44, 0xbe, 0xa1, 0xd5, 0x8f, 0x03, 0x98, 0xaa, 0x85, 0xd4, 0xef,
0xae, 0x0d, 0x3f, 0x03, 0xdb, 0xbf, 0x70, 0xa0, 0x6a, 0x74, 0xbc, 0xac, 0x8b, 0xd5, 0x77, 0x86,
0x52, 0xe1, 0x8d, 0x23, 0x7f, 0x4b, 0x28, 0x17, 0xdf, 0x12, 0xde, 0xc9, 0x74, 0x32, 0x09, 0xf4,
0x95, 0xab, 0x8d, 0x31, 0xa7, 0x9a, 0xf7, 0x1a, 0x54, 0x34, 0x8c, 0x19, 0x20, 0x16, 0x01, 0x8b,
0xcd, 0x1d, 0x5c, 0xce, 0xea, 0x19, 0x64, 0x2e, 0x4d, 0x4a, 0xde, 0xf7, 0x32, 0x6a, 0xc8, 0x1a,
0x17, 0xd3, 0xf4, 0xe0, 0x6a, 0xc4, 0xa1, 0x9b, 0x40, 0x52, 0xae, 0x0e, 0x4f, 0x8e, 0x86, 0xbc,
0xc7, 0x46, 0x5c, 0xe7, 0xa5, 0x12, 0x6d, 0xc1, 0xa6, 0xa1, 0x4d, 0xe7, 0xbf, 0xe8, 0xd2, 0x1c,
0x47, 0x7d, 0xc9, 0xe4, 0x94, 0xb8, 0xde, 0x7b, 0x7a, 0xe6, 0x90, 0x79, 0xdf, 0x6a, 0xfe, 0x57,
0x15, 0x93, 0x09, 0x43, 0x2e, 0x31, 0x55, 0x9a, 0x89, 0x10, 0x33, 0xcd, 0xba, 0x99, 0x86, 0x1a,
0xad, 0xcb, 0xde, 0x6e, 0xa1, 0x05, 0x98, 0xaf, 0x45, 0xce, 0xb2, 0xb5, 0xc8, 0x7b, 0x00, 0xd7,
0x32, 0xb4, 0x31, 0x16, 0x96, 0xa7, 0x9a, 0x18, 0x17, 0xe5, 0x3c, 0xcb, 0xd7, 0x32, 0xf2, 0xdb,
0x7f, 0x57, 0x86, 0xe6, 0x7c, 0x3d, 0xd0, 0xf7, 0x29, 0xa3, 0xfb, 0x61, 0x1c, 0x9a, 0x0b, 0xd7,
0x2e, 0x06, 0x46, 0x20, 0x27, 0xa3, 0x7e, 0x6a, 0xd2, 0xbc, 0x6e, 0x20, 0x09, 0x7e, 0x7a, 0x64,
0xb2, 0xbf, 0x46, 0x6c, 0xe0, 0xa7, 0x7d, 0x31, 0xe2, 0xe4, 0x66, 0xf1, 0xc9, 0xf1, 0xf5, 0xec,
0x71, 0x52, 0xa7, 0xeb, 0x0f, 0xb0, 0x38, 0xf4, 0xb8, 0x22, 0x3b, 0xd8, 0xd8, 0xf4, 0x8e, 0x66,
0x59, 0x99, 0x7c, 0x42, 0x1b, 0x76, 0x82, 0xfd, 0xc3, 0x12, 0x5d, 0x2f, 0xf4, 0x38, 0x3f, 0x2f,
0xd1, 0x4d, 0xb8, 0xb6, 0x3b, 0x49, 0xc2, 0x98, 0x87, 0x39, 0xf6, 0x6f, 0x34, 0x56, 0x3f, 0x3a,
0x28, 0x7d, 0x8b, 0xd4, 0x42, 0x7e, 0x86, 0x87, 0x79, 0xbd, 0x80, 0xcd, 0xdb, 0x9e, 0x3f, 0x5b,
0xfc, 0x92, 0x4b, 0xfa, 0xf3, 0xa2, 0xfc, 0x9c, 0xfe, 0x87, 0x2e, 0x62, 0x0f, 0x92, 0x90, 0x9f,
0x17, 0xb0, 0x3f, 0x72, 0xe9, 0x16, 0x6c, 0x58, 0xda, 0x82, 0xf2, 0x7f, 0xe4, 0xd2, 0xeb, 0xd0,
0xdc, 0x31, 0x66, 0xb7, 0x56, 0x21, 0x3f, 0xc6, 0xfb, 0xae, 0xdb, 0xc5, 0x35, 0xfe, 0xd8, 0xa5,
0x1b, 0xb0, 0xf6, 0x5d, 0x21, 0x4f, 0x75, 0x11, 0x43, 0xdb, 0xfe, 0x04, 0x7b, 0xbd, 0x46, 0x8e,
0x22, 0x7f, 0xe2, 0xd2, 0x17, 0x81, 0xce, 0x1f, 0xae, 0x1e, 0x31, 0xfe, 0xd4, 0xbd, 0xfd, 0x0f,
0x0e, 0x34, 0xe7, 0x13, 0x33, 0x5a, 0x35, 0x16, 0xc9, 0x00, 0x83, 0xce, 0x0c, 0xe3, 0xd3, 0xa1,
0x90, 0x4a, 0x83, 0x3a, 0x22, 0x12, 0xfd, 0x04, 0x63, 0x3a, 0xcd, 0x54, 0x31, 0x35, 0x49, 0xcd,
0x80, 0x4b, 0xb1, 0x01, 0x59, 0xc5, 0xa3, 0x0a, 0x51, 0x2f, 0x37, 0xaf, 0xc2, 0x15, 0x94, 0x18,
0x64, 0x2f, 0x3a, 0x55, 0x24, 0x9d, 0xc8, 0xd8, 0x54, 0x63, 0x3e, 0x62, 0x51, 0x6c, 0xde, 0x9d,
0xc6, 0x43, 0xec, 0x29, 0x1b, 0x06, 0x2b, 0x3e, 0x8d, 0xcc, 0x0b, 0x8f, 0x8d, 0xb4, 0x10, 0xf5,
0xc8, 0x7d, 0x95, 0xf0, 0xdd, 0xdb, 0xff, 0xf6, 0xf9, 0x0d, 0xe7, 0xb3, 0xcf, 0x6f, 0x38, 0xff,
0xf5, 0xf9, 0x0d, 0xe7, 0x67, 0x5f, 0xdc, 0x58, 0xf9, 0xec, 0x8b, 0x1b, 0x2b, 0xbf, 0xfc, 0xe2,
0xc6, 0xca, 0xf7, 0xc8, 0xe2, 0x9f, 0xd0, 0xfa, 0x55, 0x5d, 0x2f, 0xee, 0xfe, 0x5f, 0x00, 0x00,
0x00, 0xff, 0xff, 0x34, 0x93, 0x9a, 0x90, 0x9f, 0x26, 0x00, 0x00,
}
func (m *SmartBlockSnapshotBase) Marshal() (dAtA []byte, err error) {
@ -4948,6 +4968,20 @@ func (m *BlockContentText) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if len(m.IconImage) > 0 {
i -= len(m.IconImage)
copy(dAtA[i:], m.IconImage)
i = encodeVarintModels(dAtA, i, uint64(len(m.IconImage)))
i--
dAtA[i] = 0x3a
}
if len(m.IconEmoji) > 0 {
i -= len(m.IconEmoji)
copy(dAtA[i:], m.IconEmoji)
i = encodeVarintModels(dAtA, i, uint64(len(m.IconEmoji)))
i--
dAtA[i] = 0x32
}
if len(m.Color) > 0 {
i -= len(m.Color)
copy(dAtA[i:], m.Color)
@ -6988,6 +7022,14 @@ func (m *BlockContentText) Size() (n int) {
if l > 0 {
n += 1 + l + sovModels(uint64(l))
}
l = len(m.IconEmoji)
if l > 0 {
n += 1 + l + sovModels(uint64(l))
}
l = len(m.IconImage)
if l > 0 {
n += 1 + l + sovModels(uint64(l))
}
return n
}
@ -9649,6 +9691,70 @@ func (m *BlockContentText) Unmarshal(dAtA []byte) error {
}
m.Color = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 6:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field IconEmoji", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowModels
}
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 ErrInvalidLengthModels
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthModels
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.IconEmoji = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 7:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field IconImage", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowModels
}
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 ErrInvalidLengthModels
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthModels
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.IconImage = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipModels(dAtA[iNdEx:])

View file

@ -172,6 +172,8 @@ message Block {
Marks marks = 3; // list of marks to apply to the text
bool checked = 4;
string color = 5;
string iconEmoji = 6; // used with style Callout
string iconImage = 7; // in case both image and emoji are set, image should has a priority in the UI
message Marks {
repeated Mark marks = 1;
@ -211,6 +213,8 @@ message Block {
Numbered = 10;
Toggle = 11;
Description = 12; // currently only only one block of this style can exists on a page
Callout = 13; // currently only only one block of this style can exists on a page
}
}

View file

@ -6,10 +6,6 @@ import (
cafePb "github.com/anytypeio/go-anytype-middleware/pkg/lib/cafe/pb"
)
const (
defaultCafeNodeP2P = "/dns4/cafe1.anytype.io/tcp/4001/p2p/12D3KooWKwPC165PptjnzYzGrEs7NSjsF5vvMmxmuqpA2VfaBbLw"
)
type CafeConfigFetcher interface {
GetCafeConfig() *cafePb.GetConfigResponseConfig
}
@ -47,6 +43,7 @@ var DefaultConfig = Config{
Debug: false,
Metrics: false,
PubSub: true,
CafeP2PAddr: defaultCafeNodeP2P,
CafePermanentConnection: true,
// CafeP2PAddr is being set later when we have the global config
// We probably should refactor this default config logic for threads
}

View file

@ -27,7 +27,6 @@ import (
"github.com/textileio/go-threads/crypto/symmetric"
threadsDb "github.com/textileio/go-threads/db"
"github.com/textileio/go-threads/db/keytransform"
threadsMetrics "github.com/textileio/go-threads/metrics"
"google.golang.org/grpc"
"github.com/anytypeio/go-anytype-middleware/app"
@ -216,13 +215,12 @@ func (s *service) Run() (err error) {
syncBook = s.logstore
}
ctx := context.WithValue(s.ctx, threadsMetrics.ContextKey{}, metrics.NewThreadsMetrics())
s.t, err = threadsNet.NewNetwork(ctx, s.ipfsNode.GetHost(), s.ipfsNode.BlockStore(), s.ipfsNode, s.logstore, threadsNet.Config{
s.t, err = threadsNet.NewNetwork(s.ctx, s.ipfsNode.GetHost(), s.ipfsNode.BlockStore(), s.ipfsNode, s.logstore, threadsNet.Config{
Debug: s.Debug,
PubSub: s.PubSub,
SyncTracking: s.SyncTracking,
SyncBook: syncBook,
Metrics: metrics.NewThreadsMetrics(),
}, s.GRPCServerOptions, s.GRPCDialOptions)
if err != nil {
return err

View file

@ -203,7 +203,14 @@ func (l *unsplashService) Download(ctx context.Context, id string) (imgPath stri
return "", err
}
}
req, err := http.NewRequest("GET", picture.PictureFullUrl, nil)
// we must call download endpoint according to the API guidelines
picUrl, _, err := l.client.Photos.DownloadLink(id)
if err != nil {
return "", err
}
req, err := http.NewRequest("GET", picUrl.String(), nil)
if err != nil {
return "", err
}