1
0
Fork 0
mirror of https://github.com/anyproto/anytype-heart.git synced 2025-06-09 17:44:59 +09:00

GO-4144 Merge branch 'go-4450-extract-details-structs' into go-4144-refactor-internal-details-structure

# Conflicts:
#	core/block/backlinks/watcher.go
#	core/block/delete.go
#	core/block/detailservice/set_details.go
#	core/block/editor/basic/details_test.go
#	core/block/editor/file/file_test.go
#	core/block/editor/spaceview.go
#	core/block/object/objectcreator/chat.go
#	core/block/object/objectcreator/creator.go
#	core/block/source/date.go
#	core/block/source/mock_source/mock_Service.go
#	core/block/source/service.go
#	core/domain/genericmap_test.go
#	core/domain/value.go
#	core/object.go
#	core/syncstatus/detailsupdater/updater.go
#	core/syncstatus/detailsupdater/updater_test.go
#	core/syncstatus/syncsubscriptions/syncingobjects.go
#	pkg/lib/localstore/objectstore/fixture.go
#	pkg/lib/localstore/objectstore/spaceindex/fixture.go
#	pkg/lib/localstore/objectstore/spaceindex/objects.go
#	pkg/lib/localstore/objectstore/spaceindex/queries_test.go
#	pkg/lib/localstore/objectstore/spaceindex/store.go
#	pkg/lib/localstore/objectstore/spaceindex/update.go
#	util/pbtypes/anyenc_test.go
#	util/pbtypes/pbtypes.go
This commit is contained in:
Sergey 2024-11-06 14:10:49 +01:00
commit 5743f1a7f8
No known key found for this signature in database
GPG key ID: 3B6BEF79160221C6
98 changed files with 6912 additions and 3116 deletions

View file

@ -10,7 +10,7 @@ on:
run-on-runner:
description: 'Specify the runner to use'
required: true
default: 'ARM64'
default: 'arm64'
perf-test:
description: 'Run perf test times'
required: true
@ -32,19 +32,19 @@ permissions:
name: Build
jobs:
build:
runs-on: ${{ github.event_name == 'push' && 'macos-12' || (github.event.inputs.run-on-runner || 'ARM64') }}
runs-on: ${{ github.event_name == 'push' && 'arm64' || (github.event.inputs.run-on-runner || 'arm64') }}
steps:
- name: validate agent
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ github.event.inputs.run-on-runner }}" != "ARM64" ]]; then
if [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ github.event.inputs.run-on-runner }}" != "arm64" ]]; then
echo "Invalid runner"
exit 1
fi
- name: Install Go
uses: actions/setup-go@v1
with:
go-version: 1.22.8
if: github.event.inputs.run-on-runner != 'ARM64' && github.event_name != 'schedule'
go-version: 1.23.2
if: runner.name != 'mac-mini-org-heart'
- name: Setup GO
run: |
go version
@ -61,7 +61,12 @@ jobs:
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 brew install grpcurl
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 brew tap messense/macos-cross-toolchains && brew install x86_64-unknown-linux-musl
npm i -g node-gyp
if: github.event.inputs.run-on-runner != 'ARM64' && github.event_name != 'schedule'
echo "Azaza"
protoc --version
which x86_64-w64-mingw32-gcc
which protoc
echo "Azaza2"
if: runner.name != 'mac-mini-org-heart'
- name: Checkout
uses: actions/checkout@v3
- uses: actions/cache@v3
@ -73,7 +78,7 @@ jobs:
${{ runner.os }}-go-${{ matrix.go-version }}-
- name: Install old MacOS SDK (for backward compatibility of CGO)
run: source .github/install_macos_sdk.sh 10.15
if: github.event.inputs.run-on-runner != 'ARM64' && github.event_name != 'schedule'
if: runner.name != 'mac-mini-org-heart'
- name: Set env vars
env:
UNSPLASH_KEY: ${{ secrets.UNSPLASH_KEY }}
@ -133,14 +138,14 @@ jobs:
TEST_MNEMONIC: ${{ secrets.TEST_MNEMONIC }}
PROM_KEY: ${{ secrets.PROMETHEUS_USERNAME }}
PROM_PASSWORD: ${{ secrets.PROMETHEUS_PASSWORD }}
if: github.event.inputs.perf-test != '0' || github.event_name == 'schedule'
if: github.event.inputs.perf-test != '0'
- name: Archive perf tests results
uses: actions/upload-artifact@v4
with:
name: pprofs
path: |
*.pprof
if: github.event.inputs.perf-test != '0' || github.event_name == 'schedule'
if: github.event.inputs.perf-test != '0'
- name: end run perf tests
run: |
rm -rf *.pprof
@ -149,7 +154,7 @@ jobs:
gh run watch ${{ github.run_id }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
if: github.event.inputs.perf-test != '0' || github.event_name == 'schedule'
if: github.event.inputs.perf-test != '0'
- name: Make JS protos
run: |
make protos-js
@ -252,7 +257,7 @@ jobs:
cp pkg/lib/bundle/internalTypes.json ./json
- name: Compile android lib
run: |
gomobile bind -tags "envproduction nogrpcserver gomobile nowatchdog nosigar nomutexdeadlockdetector timetzdata rasterizesvg" -ldflags "$FLAGS" -v -target=android -androidapi 19 -o lib.aar github.com/anyproto/anytype-heart/clientlibrary/service github.com/anyproto/anytype-heart/core || true
gomobile bind -tags "envproduction nogrpcserver gomobile nowatchdog nosigar nomutexdeadlockdetector timetzdata rasterizesvg" -ldflags "$FLAGS" -v -target=android -androidapi 26 -o lib.aar github.com/anyproto/anytype-heart/clientlibrary/service github.com/anyproto/anytype-heart/core || true
gtar --exclude ".*" -czvf android_lib_${VERSION}.tar.gz lib.aar protobuf json
mv android_lib_${VERSION}.tar.gz .release/
- name: Publish android lib to maven

View file

@ -160,7 +160,7 @@ build-android: setup-go setup-gomobile
ifdef ANY_SYNC_NETWORK
@$(eval TAGS := $(TAGS) envnetworkcustom)
endif
gomobile bind -tags "$(TAGS)" -ldflags "$(FLAGS)" $(BUILD_FLAGS) -target=android -androidapi 19 -o lib.aar github.com/anyproto/anytype-heart/clientlibrary/service github.com/anyproto/anytype-heart/core
gomobile bind -tags "$(TAGS)" -ldflags "$(FLAGS)" $(BUILD_FLAGS) -target=android -androidapi 26 -o lib.aar github.com/anyproto/anytype-heart/clientlibrary/service github.com/anyproto/anytype-heart/core
@mkdir -p dist/android/ && mv lib.aar dist/android/
@go mod tidy

View file

@ -44,11 +44,6 @@ func RunDebugServer(addr *C.char) {
service.RunDebugServer(C.GoString(addr))
}
//export SetLogLevels
func SetLogLevels(levels *C.char) {
service.SetLogLevels(C.GoString(levels))
}
//export Command
func Command(cmd *C.char, data unsafe.Pointer, dataLen C.int, callback C.proxyFunc, callbackContext unsafe.Pointer) {
service.CommandAsync(C.GoString(cmd), C.GoBytes(data, dataLen), func(data []byte) {

View file

@ -64,10 +64,6 @@ func RunDebugServer(addr string) {
})
}
func SetLogLevels(levels string) {
logging.SetLogLevels(levels)
}
func SetEnv(key, value string) {
os.Setenv(key, value)
}

View file

@ -25,330 +25,332 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
func init() { proto.RegisterFile("pb/protos/service/service.proto", fileDescriptor_93a29dc403579097) }
var fileDescriptor_93a29dc403579097 = []byte{
// 5164 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x9d, 0x5b, 0x6f, 0x24, 0x49,
0x56, 0xf8, 0xa7, 0x5e, 0xfe, 0xf3, 0x27, 0x97, 0x1d, 0xa0, 0x06, 0x86, 0xd9, 0x61, 0xb7, 0xbb,
0xa7, 0x6f, 0xee, 0x6e, 0xdb, 0xe9, 0x9e, 0xee, 0xe9, 0x99, 0xd5, 0x2e, 0x12, 0x72, 0xdb, 0x6d,
0x8f, 0x59, 0xdb, 0x6d, 0x5c, 0xe5, 0x6e, 0x69, 0x24, 0x24, 0xc2, 0x99, 0xe1, 0x72, 0xe2, 0xac,
0x8c, 0xdc, 0xcc, 0xa8, 0x72, 0xd7, 0x22, 0x10, 0x08, 0x04, 0x02, 0x81, 0x58, 0x71, 0x7b, 0x45,
0xe2, 0x89, 0x8f, 0xc2, 0xe3, 0x3e, 0xf2, 0x88, 0x66, 0xf8, 0x20, 0x28, 0x23, 0x22, 0xe3, 0x72,
0x32, 0x4e, 0x64, 0x7a, 0x9f, 0xba, 0x55, 0xe7, 0x77, 0xce, 0x89, 0xeb, 0x89, 0x13, 0x91, 0x91,
0xe9, 0xe8, 0x76, 0x79, 0xbe, 0x55, 0x56, 0x8c, 0xb3, 0x7a, 0xab, 0xa6, 0xd5, 0x32, 0x4b, 0x68,
0xfb, 0x6f, 0x2c, 0x7e, 0x1e, 0xbf, 0x4f, 0x8a, 0x15, 0x5f, 0x95, 0xf4, 0x93, 0x8f, 0x0d, 0x99,
0xb0, 0xf9, 0x9c, 0x14, 0x69, 0x2d, 0x91, 0x4f, 0x3e, 0x32, 0x12, 0xba, 0xa4, 0x05, 0x57, 0xbf,
0x3f, 0xfb, 0xcf, 0xff, 0x1d, 0x45, 0x1f, 0xec, 0xe4, 0x19, 0x2d, 0xf8, 0x8e, 0xd2, 0x18, 0x7f,
0x1d, 0x7d, 0x77, 0xbb, 0x2c, 0xf7, 0x29, 0x7f, 0x43, 0xab, 0x3a, 0x63, 0xc5, 0xf8, 0x5e, 0xac,
0x1c, 0xc4, 0xa7, 0x65, 0x12, 0x6f, 0x97, 0x65, 0x6c, 0x84, 0xf1, 0x29, 0xfd, 0xe9, 0x82, 0xd6,
0xfc, 0x93, 0xfb, 0x61, 0xa8, 0x2e, 0x59, 0x51, 0xd3, 0xf1, 0x45, 0xf4, 0x1b, 0xdb, 0x65, 0x39,
0xa1, 0x7c, 0x97, 0x36, 0x15, 0x98, 0x70, 0xc2, 0xe9, 0x78, 0xad, 0xa3, 0xea, 0x02, 0xda, 0xc7,
0xa3, 0x7e, 0x50, 0xf9, 0x99, 0x46, 0xdf, 0x69, 0xfc, 0x5c, 0x2e, 0x78, 0xca, 0xae, 0x8b, 0xf1,
0xa7, 0x5d, 0x45, 0x25, 0xd2, 0xb6, 0xef, 0x86, 0x10, 0x65, 0xf5, 0x6d, 0xf4, 0xab, 0x6f, 0x49,
0x9e, 0x53, 0xbe, 0x53, 0xd1, 0xa6, 0xe0, 0xae, 0x8e, 0x14, 0xc5, 0x52, 0xa6, 0xed, 0xde, 0x0b,
0x32, 0xca, 0xf0, 0xd7, 0xd1, 0x77, 0xa5, 0xe4, 0x94, 0x26, 0x6c, 0x49, 0xab, 0xb1, 0x57, 0x4b,
0x09, 0x91, 0x26, 0xef, 0x40, 0xd0, 0xf6, 0x0e, 0x2b, 0x96, 0xb4, 0xe2, 0x7e, 0xdb, 0x4a, 0x18,
0xb6, 0x6d, 0x20, 0x65, 0xfb, 0x6f, 0x47, 0xd1, 0xf7, 0xb7, 0x93, 0x84, 0x2d, 0x0a, 0x7e, 0xc8,
0x12, 0x92, 0x1f, 0x66, 0xc5, 0xd5, 0x31, 0xbd, 0xde, 0xb9, 0x6c, 0xf8, 0x62, 0x46, 0xc7, 0xcf,
0xdd, 0x56, 0x95, 0x68, 0xac, 0xd9, 0xd8, 0x86, 0xb5, 0xef, 0xcf, 0x6f, 0xa6, 0xa4, 0xca, 0xf2,
0x8f, 0xa3, 0xe8, 0x16, 0x2c, 0xcb, 0x84, 0xe5, 0x4b, 0x6a, 0x4a, 0xf3, 0xa2, 0xc7, 0xb0, 0x8b,
0xeb, 0xf2, 0x7c, 0x71, 0x53, 0x35, 0x55, 0xa2, 0x3c, 0xfa, 0xd0, 0x1e, 0x2e, 0x13, 0x5a, 0x8b,
0xe9, 0xf4, 0x18, 0x1f, 0x11, 0x0a, 0xd1, 0x9e, 0x9f, 0x0c, 0x41, 0x95, 0xb7, 0x2c, 0x1a, 0x2b,
0x6f, 0x39, 0xab, 0xb5, 0xb3, 0x47, 0x5e, 0x0b, 0x16, 0xa1, 0x7d, 0x3d, 0x1e, 0x40, 0x2a, 0x57,
0x7f, 0x14, 0xfd, 0xda, 0x5b, 0x56, 0x5d, 0xd5, 0x25, 0x49, 0xa8, 0x9a, 0x0a, 0x0f, 0x5c, 0xed,
0x56, 0x0a, 0x67, 0xc3, 0xc3, 0x3e, 0xcc, 0x1a, 0xb4, 0xad, 0xf0, 0x75, 0x49, 0x61, 0x0c, 0x32,
0x8a, 0x8d, 0x10, 0x1b, 0xb4, 0x10, 0x52, 0xb6, 0xaf, 0xa2, 0xb1, 0xb1, 0x7d, 0xfe, 0xc7, 0x34,
0xe1, 0xdb, 0x69, 0x0a, 0x7b, 0xc5, 0xe8, 0x0a, 0x22, 0xde, 0x4e, 0x53, 0xac, 0x57, 0xfc, 0xa8,
0x72, 0x76, 0x1d, 0x7d, 0x04, 0x9c, 0x1d, 0x66, 0xb5, 0x70, 0xb8, 0x19, 0xb6, 0xa2, 0x30, 0xed,
0x34, 0x1e, 0x8a, 0x2b, 0xc7, 0x7f, 0x3e, 0x8a, 0xbe, 0xe7, 0xf1, 0x7c, 0x4a, 0xe7, 0x6c, 0x49,
0xc7, 0x4f, 0xfb, 0xad, 0x49, 0x52, 0xfb, 0xff, 0xec, 0x06, 0x1a, 0x9e, 0x61, 0x32, 0xa1, 0x39,
0x4d, 0x38, 0x3a, 0x4c, 0xa4, 0xb8, 0x77, 0x98, 0x68, 0xcc, 0x9a, 0x61, 0xad, 0x70, 0x9f, 0xf2,
0x9d, 0x45, 0x55, 0xd1, 0x82, 0xa3, 0x7d, 0x69, 0x90, 0xde, 0xbe, 0x74, 0x50, 0x4f, 0x7d, 0xf6,
0x29, 0xdf, 0xce, 0x73, 0xb4, 0x3e, 0x52, 0xdc, 0x5b, 0x1f, 0x8d, 0x29, 0x0f, 0x49, 0xf4, 0xeb,
0x56, 0x8b, 0xf1, 0x83, 0xe2, 0x82, 0x8d, 0xf1, 0xb6, 0x10, 0x72, 0xed, 0x63, 0xad, 0x97, 0xf3,
0x54, 0xe3, 0xd5, 0xbb, 0x92, 0x55, 0x78, 0xb7, 0x48, 0x71, 0x6f, 0x35, 0x34, 0xa6, 0x3c, 0xfc,
0x61, 0xf4, 0x81, 0x8a, 0x92, 0xed, 0x7a, 0x76, 0xdf, 0x1b, 0x42, 0xe1, 0x82, 0xf6, 0xa0, 0x87,
0x32, 0xc1, 0x41, 0xc9, 0x54, 0xf0, 0xb9, 0xe7, 0xd5, 0x03, 0xa1, 0xe7, 0x7e, 0x18, 0xea, 0xd8,
0xde, 0xa5, 0x39, 0x45, 0x6d, 0x4b, 0x61, 0x8f, 0x6d, 0x0d, 0x29, 0xdb, 0x55, 0xf4, 0x5b, 0xba,
0x59, 0x9a, 0x75, 0x54, 0xc8, 0x9b, 0x20, 0xbd, 0x8e, 0xd4, 0xdb, 0x86, 0xb4, 0xaf, 0x8d, 0x61,
0x70, 0xa7, 0x3e, 0x6a, 0x06, 0xfa, 0xeb, 0x03, 0xe6, 0xdf, 0xfd, 0x30, 0xa4, 0x6c, 0xff, 0xdd,
0x28, 0xfa, 0x81, 0x92, 0xbd, 0x2a, 0xc8, 0x79, 0x4e, 0xc5, 0x92, 0x78, 0x4c, 0xf9, 0x35, 0xab,
0xae, 0x26, 0xab, 0x22, 0x41, 0x96, 0x7f, 0x3f, 0xdc, 0xb3, 0xfc, 0xa3, 0x4a, 0x56, 0xc6, 0xa7,
0x2a, 0xca, 0x59, 0x09, 0x33, 0xbe, 0xb6, 0x06, 0x9c, 0x95, 0x58, 0xc6, 0xe7, 0x22, 0x1d, 0xab,
0x47, 0x4d, 0xd8, 0xf4, 0x5b, 0x3d, 0xb2, 0xe3, 0xe4, 0xdd, 0x10, 0x62, 0xc2, 0x56, 0x3b, 0x80,
0x59, 0x71, 0x91, 0xcd, 0xce, 0xca, 0xb4, 0x19, 0xc6, 0x8f, 0xfd, 0x23, 0xd4, 0x42, 0x90, 0xb0,
0x85, 0xa0, 0xca, 0xdb, 0x3f, 0x98, 0xc4, 0x48, 0x4d, 0xa5, 0xbd, 0x8a, 0xcd, 0x0f, 0xe9, 0x8c,
0x24, 0x2b, 0x35, 0xff, 0x3f, 0x0f, 0x4d, 0x3c, 0x48, 0xeb, 0x42, 0xbc, 0xb8, 0xa1, 0x96, 0x2a,
0xcf, 0xbf, 0x8f, 0xa2, 0xfb, 0x6d, 0xf5, 0x2f, 0x49, 0x31, 0xa3, 0xaa, 0x3f, 0x65, 0xe9, 0xb7,
0x8b, 0xf4, 0x94, 0xd6, 0x9c, 0x54, 0x7c, 0xfc, 0x23, 0x7f, 0x25, 0x43, 0x3a, 0xba, 0x6c, 0x3f,
0xfe, 0xa5, 0x74, 0x4d, 0xaf, 0x4f, 0x9a, 0xc0, 0xa6, 0x42, 0x80, 0xdb, 0xeb, 0x42, 0x02, 0x03,
0xc0, 0xdd, 0x10, 0x62, 0x7a, 0x5d, 0x08, 0x0e, 0x8a, 0x65, 0xc6, 0xe9, 0x3e, 0x2d, 0x68, 0xd5,
0xed, 0x75, 0xa9, 0xea, 0x22, 0x48, 0xaf, 0x23, 0xa8, 0x09, 0x36, 0x8e, 0x37, 0xbd, 0x38, 0xae,
0x07, 0x8c, 0x74, 0x96, 0xc7, 0x8d, 0x61, 0xb0, 0xd9, 0xdd, 0x59, 0x3e, 0x4f, 0xe9, 0x92, 0x5d,
0xc1, 0xdd, 0x9d, 0x6d, 0x42, 0x02, 0xc8, 0xee, 0xce, 0x0b, 0x9a, 0x15, 0xcc, 0xf2, 0xf3, 0x26,
0xa3, 0xd7, 0x60, 0x05, 0xb3, 0x95, 0x1b, 0x31, 0xb2, 0x82, 0x79, 0x30, 0xe5, 0xe1, 0x38, 0xfa,
0x15, 0x21, 0xfc, 0x7d, 0x96, 0x15, 0xe3, 0xdb, 0x1e, 0xa5, 0x46, 0xa0, 0xad, 0xde, 0xc1, 0x01,
0x50, 0xe2, 0xe6, 0xd7, 0x1d, 0x52, 0x24, 0x34, 0xf7, 0x96, 0xd8, 0x88, 0x83, 0x25, 0x76, 0x30,
0x93, 0x3a, 0x08, 0x61, 0x13, 0xbf, 0x26, 0x97, 0xa4, 0xca, 0x8a, 0xd9, 0xd8, 0xa7, 0x6b, 0xc9,
0x91, 0xd4, 0xc1, 0xc7, 0x81, 0x21, 0xac, 0x14, 0xb7, 0xcb, 0xb2, 0x6a, 0xc2, 0xa2, 0x6f, 0x08,
0xbb, 0x48, 0x70, 0x08, 0x77, 0x50, 0xbf, 0xb7, 0x5d, 0x9a, 0xe4, 0x59, 0x11, 0xf4, 0xa6, 0x90,
0x21, 0xde, 0x0c, 0x0a, 0x06, 0xef, 0x21, 0x25, 0x4b, 0xda, 0xd6, 0xcc, 0xd7, 0x32, 0x36, 0x10,
0x1c, 0xbc, 0x00, 0x34, 0xfb, 0x34, 0x21, 0x3e, 0x22, 0x57, 0xb4, 0x69, 0x60, 0xda, 0xac, 0x6b,
0x63, 0x9f, 0xbe, 0x43, 0x20, 0xfb, 0x34, 0x3f, 0xa9, 0x5c, 0x2d, 0xa2, 0x8f, 0x84, 0xfc, 0x84,
0x54, 0x3c, 0x4b, 0xb2, 0x92, 0x14, 0x6d, 0xfe, 0xef, 0x9b, 0xd7, 0x1d, 0x4a, 0xbb, 0xdc, 0x1c,
0x48, 0x2b, 0xb7, 0xff, 0x36, 0x8a, 0x3e, 0x85, 0x7e, 0x4f, 0x68, 0x35, 0xcf, 0xc4, 0x36, 0xb2,
0x96, 0x41, 0x78, 0xfc, 0x65, 0xd8, 0x68, 0x47, 0x41, 0x97, 0xe6, 0x87, 0x37, 0x57, 0x54, 0x05,
0xfb, 0x83, 0x28, 0x92, 0xdb, 0x15, 0xb1, 0xa5, 0x74, 0x67, 0xad, 0xda, 0xc7, 0x38, 0xfb, 0xc9,
0x4f, 0x03, 0x84, 0x59, 0x2a, 0xe4, 0xef, 0x62, 0xa7, 0x3c, 0xf6, 0x6a, 0x08, 0x11, 0xb2, 0x54,
0x00, 0x04, 0x16, 0x74, 0x72, 0xc9, 0xae, 0xfd, 0x05, 0x6d, 0x24, 0xe1, 0x82, 0x2a, 0xc2, 0x9c,
0x5d, 0xa9, 0x82, 0xfa, 0xce, 0xae, 0xda, 0x62, 0x84, 0xce, 0xae, 0x20, 0xa3, 0x0c, 0xb3, 0xe8,
0x37, 0x6d, 0xc3, 0x2f, 0x19, 0xbb, 0x9a, 0x93, 0xea, 0x6a, 0xfc, 0x04, 0x57, 0x6e, 0x19, 0xed,
0x68, 0x7d, 0x10, 0x6b, 0xc2, 0x82, 0xed, 0xb0, 0x49, 0x34, 0xce, 0xaa, 0x1c, 0x84, 0x05, 0xc7,
0x86, 0x42, 0x90, 0xb0, 0x80, 0xa0, 0x26, 0x72, 0xdb, 0xde, 0x26, 0x14, 0xee, 0x96, 0x1c, 0xf5,
0x09, 0xc5, 0x76, 0x4b, 0x1e, 0x0c, 0x0e, 0xa1, 0xfd, 0x8a, 0x94, 0x97, 0xfe, 0x21, 0x24, 0x44,
0xe1, 0x21, 0xd4, 0x22, 0xb0, 0xbf, 0x27, 0x94, 0x54, 0xc9, 0xa5, 0xbf, 0xbf, 0xa5, 0x2c, 0xdc,
0xdf, 0x9a, 0x81, 0xfd, 0x2d, 0x05, 0x6f, 0x33, 0x7e, 0x79, 0x44, 0x39, 0xf1, 0xf7, 0xb7, 0xcb,
0x84, 0xfb, 0xbb, 0xc3, 0x9a, 0x4c, 0xc6, 0x76, 0x38, 0x59, 0x9c, 0xd7, 0x49, 0x95, 0x9d, 0xd3,
0x71, 0xc0, 0x8a, 0x86, 0x90, 0x4c, 0x06, 0x85, 0x95, 0xcf, 0x9f, 0x8f, 0xa2, 0xdb, 0x6d, 0xb7,
0xb3, 0xba, 0x96, 0x2b, 0x2b, 0x70, 0xff, 0xc2, 0xdf, 0xbf, 0x08, 0x8e, 0x9c, 0x26, 0x0e, 0x50,
0xb3, 0xa2, 0xaa, 0xbf, 0x48, 0x67, 0x45, 0xad, 0x0b, 0xf5, 0xe5, 0x10, 0xeb, 0x96, 0x02, 0x12,
0x55, 0x07, 0x29, 0x9a, 0x05, 0x4d, 0xf5, 0x4f, 0x2b, 0x3b, 0x48, 0x6b, 0xb0, 0xa0, 0xb5, 0xed,
0x6d, 0x11, 0xc8, 0x82, 0xe6, 0x27, 0xe1, 0x50, 0xd8, 0xaf, 0xd8, 0xa2, 0xac, 0x7b, 0x86, 0x02,
0x80, 0xc2, 0x43, 0xa1, 0x0b, 0x2b, 0x9f, 0xef, 0xa2, 0xdf, 0xb6, 0x87, 0x9f, 0xdd, 0xd8, 0x9b,
0xf8, 0x98, 0xf2, 0x35, 0x71, 0x3c, 0x14, 0x37, 0x29, 0x5d, 0xeb, 0x99, 0xef, 0x52, 0x4e, 0xb2,
0xbc, 0x1e, 0x3f, 0xf4, 0xdb, 0x68, 0xe5, 0x48, 0x4a, 0xe7, 0xe3, 0x60, 0x7c, 0xdb, 0x5d, 0x94,
0x79, 0x96, 0x74, 0xcf, 0x72, 0x95, 0xae, 0x16, 0x87, 0xe3, 0x9b, 0x8d, 0xc1, 0x78, 0x3d, 0xa1,
0x5c, 0xfe, 0x67, 0xba, 0x2a, 0xa9, 0x3f, 0x5e, 0x3b, 0x48, 0x38, 0x5e, 0x43, 0x14, 0xd6, 0x67,
0x42, 0xf9, 0x21, 0x59, 0xb1, 0x05, 0x12, 0xaf, 0xb5, 0x38, 0x5c, 0x1f, 0x1b, 0x33, 0x59, 0x95,
0xf6, 0x70, 0x50, 0x70, 0x5a, 0x15, 0x24, 0xdf, 0xcb, 0xc9, 0xac, 0x1e, 0x23, 0x31, 0xc6, 0xa5,
0x90, 0xac, 0x0a, 0xa7, 0x3d, 0xcd, 0x78, 0x50, 0xef, 0x91, 0x25, 0xab, 0x32, 0x8e, 0x37, 0xa3,
0x41, 0x7a, 0x9b, 0xd1, 0x41, 0xbd, 0xde, 0xb6, 0xab, 0xe4, 0x32, 0x5b, 0xd2, 0x34, 0xe0, 0xad,
0x45, 0x06, 0x78, 0xb3, 0x50, 0x4f, 0xa7, 0x4d, 0xd8, 0xa2, 0x4a, 0x28, 0xda, 0x69, 0x52, 0xdc,
0xdb, 0x69, 0x1a, 0x53, 0x1e, 0xfe, 0x6a, 0x14, 0xfd, 0x8e, 0x94, 0xda, 0x07, 0xac, 0xbb, 0xa4,
0xbe, 0x3c, 0x67, 0xa4, 0x4a, 0xc7, 0x9f, 0xf9, 0xec, 0x78, 0x51, 0xed, 0xfa, 0xd9, 0x4d, 0x54,
0x60, 0xb3, 0x1e, 0x66, 0xb5, 0x35, 0xe3, 0xbc, 0xcd, 0xea, 0x20, 0xe1, 0x66, 0x85, 0x28, 0x0c,
0x20, 0x42, 0x2e, 0x0f, 0x33, 0x1e, 0xa2, 0xfa, 0xee, 0x89, 0xc6, 0x5a, 0x2f, 0x07, 0xe3, 0x63,
0x23, 0x74, 0x47, 0xcb, 0x26, 0x66, 0xc3, 0x3f, 0x62, 0xe2, 0xa1, 0x38, 0xea, 0x59, 0xcf, 0x8a,
0xb0, 0xe7, 0xce, 0xcc, 0x88, 0x87, 0xe2, 0x88, 0x67, 0x2b, 0xac, 0x85, 0x3c, 0x7b, 0x42, 0x5b,
0x3c, 0x14, 0x87, 0xd9, 0x97, 0x62, 0xda, 0x75, 0xe1, 0x49, 0xc0, 0x0e, 0x5c, 0x1b, 0xd6, 0x07,
0xb1, 0xca, 0xe1, 0xdf, 0x8c, 0xa2, 0xef, 0x1b, 0x8f, 0x47, 0x2c, 0xcd, 0x2e, 0x56, 0x12, 0x7a,
0x43, 0xf2, 0x05, 0xad, 0xc7, 0xcf, 0x30, 0x6b, 0x5d, 0x56, 0x97, 0xe0, 0xf9, 0x8d, 0x74, 0xe0,
0xdc, 0xd9, 0x2e, 0xcb, 0x7c, 0x35, 0xa5, 0xf3, 0x32, 0x47, 0xe7, 0x8e, 0x83, 0x84, 0xe7, 0x0e,
0x44, 0x61, 0x56, 0x3e, 0x65, 0x4d, 0xce, 0xef, 0xcd, 0xca, 0x85, 0x28, 0x9c, 0x95, 0xb7, 0x08,
0xcc, 0x95, 0xa6, 0x6c, 0x87, 0xe5, 0x39, 0x4d, 0x78, 0xf7, 0x21, 0xad, 0xd6, 0x34, 0x44, 0x38,
0x57, 0x02, 0xa4, 0x39, 0xcf, 0x68, 0xf7, 0x90, 0xa4, 0xa2, 0x2f, 0x57, 0x87, 0x59, 0x71, 0x35,
0xf6, 0xa7, 0x05, 0x06, 0x40, 0xce, 0x33, 0xbc, 0x20, 0xdc, 0xab, 0x9e, 0x15, 0x29, 0xf3, 0xef,
0x55, 0x1b, 0x49, 0x78, 0xaf, 0xaa, 0x08, 0x68, 0xf2, 0x94, 0x62, 0x26, 0x1b, 0x49, 0xd8, 0xa4,
0x22, 0x7c, 0xa1, 0x50, 0x9d, 0x7a, 0xa3, 0xa1, 0x10, 0x9c, 0x73, 0xaf, 0xf5, 0x72, 0x70, 0x84,
0xb6, 0x9b, 0xd6, 0x3d, 0xca, 0x93, 0x4b, 0xff, 0x08, 0x75, 0x90, 0xf0, 0x08, 0x85, 0x28, 0xac,
0xd2, 0x94, 0xe9, 0x4d, 0xf7, 0x43, 0xff, 0xf8, 0xe8, 0x6c, 0xb8, 0xd7, 0x7a, 0x39, 0xb8, 0x8d,
0x3c, 0x98, 0x8b, 0x36, 0xf3, 0x0e, 0x72, 0x29, 0x0b, 0x6f, 0x23, 0x35, 0x03, 0x4b, 0x2f, 0x05,
0x4d, 0x73, 0xfa, 0x4b, 0x6f, 0xe4, 0xe1, 0xd2, 0x3b, 0x9c, 0x72, 0xf2, 0x2f, 0x7a, 0x1b, 0x27,
0xa5, 0xc7, 0xac, 0x99, 0x23, 0x6f, 0x48, 0x9e, 0xa5, 0x84, 0xd3, 0x29, 0xbb, 0xa2, 0x85, 0x7f,
0xc7, 0xa4, 0x4a, 0x2b, 0xf9, 0xd8, 0x51, 0x08, 0xef, 0x98, 0xc2, 0x8a, 0x70, 0x9c, 0x48, 0xfa,
0xac, 0xa6, 0x3b, 0xa4, 0x46, 0x22, 0x99, 0x83, 0x84, 0xc7, 0x09, 0x44, 0x61, 0xbe, 0x2a, 0xe5,
0xaf, 0xde, 0x95, 0xb4, 0xca, 0x68, 0x91, 0x50, 0x7f, 0xbe, 0x0a, 0xa9, 0x70, 0xbe, 0xea, 0xa1,
0x3b, 0xc7, 0x34, 0x3a, 0x38, 0x75, 0xef, 0x59, 0x40, 0x22, 0x70, 0xcf, 0x02, 0x41, 0x61, 0x25,
0x0d, 0xe0, 0x3d, 0xea, 0xec, 0x58, 0x09, 0x1e, 0x75, 0xe2, 0x74, 0xe7, 0xf0, 0x4b, 0x33, 0x93,
0x66, 0x9a, 0xf4, 0x14, 0x7d, 0x62, 0x4f, 0x97, 0xf5, 0x41, 0xac, 0xff, 0xb4, 0xed, 0x94, 0xe6,
0x44, 0x2c, 0x21, 0x81, 0x23, 0xad, 0x96, 0x19, 0x72, 0xda, 0x66, 0xb1, 0xca, 0xe1, 0x5f, 0x8c,
0xa2, 0x4f, 0x7c, 0x1e, 0x5f, 0x97, 0xc2, 0xef, 0xd3, 0x7e, 0x5b, 0x92, 0x44, 0x2e, 0x92, 0x84,
0x35, 0x54, 0x19, 0xfe, 0x24, 0xfa, 0xb8, 0x15, 0x99, 0x7b, 0x26, 0xaa, 0x00, 0x6e, 0x02, 0xa5,
0xcb, 0x0f, 0x39, 0xed, 0x7e, 0x6b, 0x30, 0x6f, 0xf6, 0x26, 0x6e, 0xb9, 0x6a, 0xb0, 0x37, 0xd1,
0x36, 0x94, 0x18, 0xd9, 0x9b, 0x78, 0x30, 0x73, 0xaa, 0x61, 0x57, 0xef, 0x6d, 0xc6, 0x2f, 0x45,
0xee, 0x03, 0x4e, 0x35, 0x9c, 0xb2, 0x6a, 0x08, 0x39, 0xd5, 0x40, 0x61, 0x98, 0x1d, 0xb4, 0x60,
0x33, 0x37, 0x7d, 0x71, 0x55, 0x1b, 0xb2, 0x67, 0xe6, 0xa3, 0x7e, 0x10, 0x8e, 0xd7, 0x56, 0xac,
0xb6, 0x21, 0x4f, 0x42, 0x16, 0xc0, 0x56, 0x64, 0x7d, 0x10, 0xab, 0x1c, 0xfe, 0x59, 0xf4, 0xbd,
0x4e, 0xc5, 0xf6, 0x28, 0xe1, 0x8b, 0x8a, 0xa6, 0xe3, 0xad, 0x9e, 0x72, 0xb7, 0xa0, 0x76, 0xfd,
0x74, 0xb8, 0x42, 0x27, 0x5f, 0x6e, 0x39, 0x39, 0xac, 0x74, 0x19, 0x9e, 0x85, 0x4c, 0xba, 0x6c,
0x30, 0x5f, 0xc6, 0x75, 0x3a, 0x5b, 0x5e, 0x7b, 0x74, 0x6d, 0x2f, 0x49, 0x96, 0x8b, 0x47, 0x4e,
0x9f, 0x85, 0x8c, 0x3a, 0x68, 0x70, 0xcb, 0x8b, 0xaa, 0x74, 0x22, 0xb3, 0x98, 0xe3, 0xd6, 0x56,
0x69, 0x03, 0x8f, 0x04, 0x9e, 0x9d, 0xd2, 0xe6, 0x40, 0x5a, 0xb9, 0xe5, 0xed, 0x51, 0x61, 0xf3,
0xb3, 0x3d, 0xc8, 0x7d, 0x5e, 0x95, 0xaa, 0x67, 0xa4, 0x6f, 0x0e, 0xa4, 0x95, 0xd7, 0x3f, 0x8d,
0x3e, 0xee, 0x7a, 0x55, 0x0b, 0xd1, 0x56, 0xaf, 0x29, 0xb0, 0x16, 0x3d, 0x1d, 0xae, 0x60, 0xb6,
0x17, 0x5f, 0x65, 0x35, 0x67, 0xd5, 0x6a, 0x72, 0xc9, 0xae, 0xdb, 0xfb, 0xdb, 0xee, 0x6c, 0x55,
0x40, 0x6c, 0x11, 0xc8, 0xf6, 0xc2, 0x4f, 0x76, 0x5c, 0x99, 0x7b, 0xde, 0x35, 0xe2, 0xca, 0x22,
0x7a, 0x5c, 0xb9, 0xa4, 0x89, 0x55, 0x6d, 0xad, 0xcc, 0xa5, 0xf4, 0x35, 0x7f, 0x51, 0xbb, 0x17,
0xd3, 0x1f, 0xf5, 0x83, 0x26, 0x63, 0x51, 0xe2, 0xdd, 0xec, 0xe2, 0x42, 0xd7, 0xc9, 0x5f, 0x52,
0x1b, 0x41, 0x32, 0x16, 0x04, 0x35, 0x09, 0xf0, 0x5e, 0x96, 0x53, 0x71, 0xba, 0xfe, 0xfa, 0xe2,
0x22, 0x67, 0x24, 0x05, 0x09, 0x70, 0x23, 0x8e, 0x6d, 0x39, 0x92, 0x00, 0xfb, 0x38, 0x73, 0xfd,
0xab, 0x91, 0x9e, 0xd2, 0x84, 0x15, 0x49, 0x96, 0xc3, 0xeb, 0x6c, 0x42, 0x53, 0x0b, 0x91, 0xeb,
0x5f, 0x1d, 0xc8, 0x2c, 0x8c, 0x8d, 0xa8, 0x99, 0xf6, 0x6d, 0xf9, 0x1f, 0x74, 0x15, 0x2d, 0x31,
0xb2, 0x30, 0x7a, 0x30, 0xb3, 0x0f, 0x6c, 0x84, 0x67, 0xa5, 0x30, 0x7e, 0xa7, 0xab, 0x25, 0x25,
0xc8, 0x3e, 0xd0, 0x25, 0xcc, 0x7e, 0xa6, 0xf9, 0x7d, 0x97, 0x5d, 0x17, 0xc2, 0xe8, 0xdd, 0xae,
0x4a, 0x2b, 0x43, 0xf6, 0x33, 0x90, 0x51, 0x86, 0x7f, 0x12, 0xfd, 0x7f, 0x61, 0xb8, 0x62, 0xe5,
0xf8, 0x96, 0x47, 0xa1, 0xb2, 0x6e, 0x9e, 0xdd, 0x46, 0xe5, 0xe6, 0x02, 0xa5, 0x1e, 0x1b, 0x67,
0x35, 0x99, 0xd1, 0xf1, 0x7d, 0xa4, 0xc7, 0x85, 0x14, 0xb9, 0x40, 0xd9, 0xa5, 0xdc, 0x51, 0x71,
0xcc, 0x52, 0x65, 0xdd, 0x53, 0x43, 0x2d, 0x0c, 0x8d, 0x0a, 0x1b, 0x32, 0xc9, 0xcc, 0x31, 0x59,
0x66, 0x33, 0xbd, 0xe0, 0xc8, 0xb8, 0x55, 0x83, 0x64, 0xc6, 0x30, 0xb1, 0x05, 0x21, 0xc9, 0x0c,
0x0a, 0x2b, 0x9f, 0xff, 0x3c, 0x8a, 0xee, 0x18, 0x66, 0xbf, 0x3d, 0x39, 0x3b, 0x28, 0x2e, 0x58,
0x93, 0xfa, 0x1c, 0x66, 0xc5, 0x55, 0x3d, 0xfe, 0x02, 0x33, 0xe9, 0xe7, 0x75, 0x51, 0xbe, 0xbc,
0xb1, 0x9e, 0xc9, 0x5a, 0xdb, 0x63, 0x25, 0xf3, 0x6c, 0x59, 0x6a, 0x80, 0xac, 0x55, 0x9f, 0x3e,
0x41, 0x0e, 0xc9, 0x5a, 0x43, 0xbc, 0xe9, 0x62, 0xed, 0x3c, 0x67, 0x05, 0xec, 0x62, 0x63, 0xa1,
0x11, 0x22, 0x5d, 0xdc, 0x81, 0x4c, 0x3c, 0x6e, 0x45, 0xf2, 0x04, 0x64, 0x3b, 0xcf, 0x41, 0x3c,
0xd6, 0xaa, 0x1a, 0x40, 0xe2, 0xb1, 0x17, 0x54, 0x7e, 0x4e, 0xa3, 0xef, 0x34, 0x4d, 0x7a, 0x52,
0xd1, 0x65, 0x46, 0xe1, 0x35, 0x08, 0x4b, 0x82, 0xcc, 0x7f, 0x97, 0x30, 0x33, 0xeb, 0xac, 0xa8,
0xcb, 0x9c, 0xd4, 0x97, 0xea, 0xc1, 0xb8, 0x5b, 0xe7, 0x56, 0x08, 0x1f, 0x8d, 0x3f, 0xe8, 0xa1,
0x4c, 0x50, 0x6f, 0x65, 0x3a, 0xc4, 0x3c, 0xf4, 0xab, 0x76, 0xc2, 0xcc, 0x5a, 0x2f, 0x67, 0x4e,
0x9f, 0xf7, 0x49, 0x9e, 0xd3, 0x6a, 0xd5, 0xca, 0x8e, 0x48, 0x91, 0x5d, 0xd0, 0x9a, 0x83, 0xd3,
0x67, 0x45, 0xc5, 0x10, 0x43, 0x4e, 0x9f, 0x03, 0xb8, 0xc9, 0xe6, 0x81, 0xe7, 0x83, 0x22, 0xa5,
0xef, 0x40, 0x36, 0x0f, 0xed, 0x08, 0x06, 0xc9, 0xe6, 0x31, 0xd6, 0x9c, 0xc2, 0xbe, 0xcc, 0x59,
0x72, 0xa5, 0x96, 0x00, 0xb7, 0x83, 0x85, 0x04, 0xae, 0x01, 0x77, 0x43, 0x88, 0x59, 0x04, 0x84,
0xe0, 0x94, 0x96, 0x39, 0x49, 0xe0, 0x5d, 0x18, 0xa9, 0xa3, 0x64, 0xc8, 0x22, 0x00, 0x19, 0x50,
0x5c, 0x75, 0xc7, 0xc6, 0x57, 0x5c, 0x70, 0xc5, 0xe6, 0x6e, 0x08, 0x31, 0xcb, 0xa0, 0x10, 0x4c,
0xca, 0x3c, 0xe3, 0x60, 0x1a, 0x48, 0x0d, 0x21, 0x41, 0xa6, 0x81, 0x4b, 0x00, 0x93, 0x47, 0xb4,
0x9a, 0x51, 0xaf, 0x49, 0x21, 0x09, 0x9a, 0x6c, 0x09, 0x73, 0x65, 0x52, 0xd6, 0x9d, 0x95, 0x2b,
0x70, 0x65, 0x52, 0x55, 0x8b, 0x95, 0x2b, 0xe4, 0xca, 0xa4, 0x03, 0x80, 0x22, 0x9e, 0x90, 0x9a,
0xfb, 0x8b, 0x28, 0x24, 0xc1, 0x22, 0xb6, 0x84, 0x59, 0xa3, 0x65, 0x11, 0x17, 0x1c, 0xac, 0xd1,
0xaa, 0x00, 0xd6, 0xd3, 0xe0, 0xdb, 0xa8, 0xdc, 0x44, 0x12, 0xd9, 0x2b, 0x94, 0xef, 0x65, 0x34,
0x4f, 0x6b, 0x10, 0x49, 0x54, 0xbb, 0xb7, 0x52, 0x24, 0x92, 0x74, 0x29, 0x30, 0x94, 0xd4, 0x59,
0xb5, 0xaf, 0x76, 0xe0, 0x98, 0xfa, 0x6e, 0x08, 0x31, 0xf1, 0xa9, 0x2d, 0xf4, 0x0e, 0xa9, 0xaa,
0xac, 0x59, 0xfc, 0x1f, 0xfa, 0x0b, 0xd4, 0xca, 0x91, 0xf8, 0xe4, 0xe3, 0xc0, 0xf4, 0x6a, 0x03,
0xb7, 0xaf, 0x60, 0x30, 0x74, 0xdf, 0x0b, 0x32, 0x26, 0xe3, 0x14, 0x12, 0xeb, 0x71, 0xa6, 0xaf,
0x35, 0x3d, 0x4f, 0x33, 0x1f, 0xf6, 0x61, 0xd6, 0x2b, 0x0d, 0xda, 0xc5, 0x11, 0x5b, 0xd2, 0x29,
0x7b, 0xf5, 0x2e, 0xab, 0x79, 0x56, 0xcc, 0xd4, 0xca, 0xfd, 0x1c, 0xb1, 0xe4, 0x83, 0x91, 0x57,
0x1a, 0x7a, 0x95, 0x4c, 0x02, 0x01, 0xca, 0x72, 0x4c, 0xaf, 0xbd, 0x09, 0x04, 0xb4, 0xa8, 0x39,
0x24, 0x81, 0x08, 0xf1, 0xe6, 0x1c, 0x45, 0x3b, 0x57, 0xef, 0x7d, 0x4e, 0x59, 0x9b, 0xcb, 0x61,
0xd6, 0x20, 0x88, 0x6c, 0x65, 0x83, 0x0a, 0x66, 0x7f, 0xa9, 0xfd, 0x9b, 0x29, 0xf6, 0x08, 0xb1,
0xd3, 0x9d, 0x66, 0x8f, 0x07, 0x90, 0x1e, 0x57, 0xe6, 0x99, 0x3c, 0xe6, 0xaa, 0xfb, 0x48, 0xfe,
0xf1, 0x00, 0xd2, 0x3a, 0x93, 0xb1, 0xab, 0xf5, 0x92, 0x24, 0x57, 0xb3, 0x8a, 0x2d, 0x8a, 0x74,
0x87, 0xe5, 0xac, 0x02, 0x67, 0x32, 0x4e, 0xa9, 0x01, 0x8a, 0x9c, 0xc9, 0xf4, 0xa8, 0x98, 0x0c,
0xce, 0x2e, 0xc5, 0x76, 0x9e, 0xcd, 0xe0, 0x8e, 0xda, 0x31, 0x24, 0x00, 0x24, 0x83, 0xf3, 0x82,
0x9e, 0x41, 0x24, 0x77, 0xdc, 0x3c, 0x4b, 0x48, 0x2e, 0xfd, 0x6d, 0xe1, 0x66, 0x1c, 0xb0, 0x77,
0x10, 0x79, 0x14, 0x3c, 0xf5, 0x9c, 0x2e, 0xaa, 0xe2, 0xa0, 0xe0, 0x0c, 0xad, 0x67, 0x0b, 0xf4,
0xd6, 0xd3, 0x02, 0x41, 0x58, 0x9d, 0xd2, 0x77, 0x4d, 0x69, 0x9a, 0x7f, 0x7c, 0x61, 0xb5, 0xf9,
0x3d, 0x56, 0xf2, 0x50, 0x58, 0x05, 0x1c, 0xa8, 0x8c, 0x72, 0x22, 0x07, 0x4c, 0x40, 0xdb, 0x1d,
0x26, 0x8f, 0xfa, 0x41, 0xbf, 0x9f, 0x09, 0x5f, 0xe5, 0x34, 0xe4, 0x47, 0x00, 0x43, 0xfc, 0xb4,
0xa0, 0x39, 0x6e, 0x71, 0xea, 0x73, 0x49, 0x93, 0xab, 0xce, 0x15, 0x23, 0xb7, 0xa0, 0x12, 0x41,
0x8e, 0x5b, 0x10, 0xd4, 0xdf, 0x45, 0x07, 0x09, 0x2b, 0x42, 0x5d, 0xd4, 0xc8, 0x87, 0x74, 0x91,
0xe2, 0xcc, 0xe6, 0x57, 0x4b, 0xd5, 0xc8, 0x94, 0xdd, 0xb4, 0x8e, 0x58, 0xb0, 0x21, 0x64, 0xf3,
0x8b, 0xc2, 0x26, 0x27, 0x87, 0x3e, 0x8f, 0xba, 0xf7, 0xaf, 0x3b, 0x56, 0x8e, 0xf0, 0xfb, 0xd7,
0x18, 0x8b, 0x57, 0x52, 0x8e, 0x91, 0x1e, 0x2b, 0xee, 0x38, 0xd9, 0x18, 0x06, 0x9b, 0x2d, 0x8f,
0xe3, 0x73, 0x27, 0xa7, 0xa4, 0x92, 0x5e, 0x37, 0x03, 0x86, 0x0c, 0x86, 0x6c, 0x79, 0x02, 0x38,
0x08, 0x61, 0x8e, 0xe7, 0x1d, 0x56, 0x70, 0x5a, 0x70, 0x5f, 0x08, 0x73, 0x8d, 0x29, 0x30, 0x14,
0xc2, 0x30, 0x05, 0x30, 0x6e, 0xc5, 0x79, 0x10, 0xe5, 0xc7, 0x64, 0xee, 0xcd, 0xd8, 0xe4, 0x59,
0x8f, 0x94, 0x87, 0xc6, 0x2d, 0xe0, 0xac, 0x87, 0x7c, 0xb6, 0x97, 0x29, 0xa9, 0x66, 0xfa, 0x74,
0x23, 0x1d, 0x3f, 0xc5, 0xed, 0xb8, 0x24, 0xf2, 0x90, 0x2f, 0xac, 0x01, 0xc2, 0xce, 0xc1, 0x9c,
0xcc, 0x74, 0x4d, 0x3d, 0x35, 0x10, 0xf2, 0x4e, 0x55, 0x1f, 0xf5, 0x83, 0xc0, 0xcf, 0x9b, 0x2c,
0xa5, 0x2c, 0xe0, 0x47, 0xc8, 0x87, 0xf8, 0x81, 0x20, 0xc8, 0xde, 0x9a, 0x7a, 0xcb, 0x1d, 0xdd,
0x76, 0x91, 0xaa, 0x7d, 0x6c, 0x8c, 0x34, 0x0f, 0xe0, 0x42, 0xd9, 0x1b, 0xc2, 0x83, 0x39, 0xda,
0x1e, 0xd0, 0x86, 0xe6, 0xa8, 0x3e, 0x7f, 0x1d, 0x32, 0x47, 0x7d, 0xb0, 0xf2, 0xf9, 0x33, 0x35,
0x47, 0x77, 0x09, 0x27, 0x4d, 0xde, 0xfe, 0x26, 0xa3, 0xd7, 0x6a, 0x23, 0xec, 0xa9, 0x6f, 0x4b,
0xc5, 0xe2, 0xc5, 0x3b, 0xb0, 0x2b, 0xde, 0x1a, 0xcc, 0x07, 0x7c, 0xab, 0x1d, 0x42, 0xaf, 0x6f,
0xb0, 0x55, 0xd8, 0x1a, 0xcc, 0x07, 0x7c, 0xab, 0x37, 0x7a, 0x7b, 0x7d, 0x83, 0xd7, 0x7a, 0xb7,
0x06, 0xf3, 0xca, 0xf7, 0x5f, 0xb6, 0x13, 0xd7, 0x76, 0xde, 0xe4, 0x61, 0x09, 0xcf, 0x96, 0xd4,
0x97, 0x4e, 0xba, 0xf6, 0x34, 0x1a, 0x4a, 0x27, 0x71, 0x15, 0xeb, 0x33, 0x30, 0xbe, 0x52, 0x9c,
0xb0, 0x3a, 0x13, 0x0f, 0xe9, 0x9f, 0x0f, 0x30, 0xda, 0xc2, 0xa1, 0x4d, 0x53, 0x48, 0xc9, 0x3c,
0x6e, 0x74, 0x50, 0x73, 0xa3, 0x78, 0x23, 0x60, 0xaf, 0x7b, 0xb1, 0x78, 0x73, 0x20, 0x6d, 0x1e,
0xfc, 0x39, 0x8c, 0xfd, 0xc4, 0x31, 0xd4, 0xab, 0xde, 0x87, 0x8e, 0x4f, 0x87, 0x2b, 0x28, 0xf7,
0x7f, 0xdd, 0xee, 0x2b, 0xa0, 0x7f, 0x35, 0x09, 0x9e, 0x0d, 0xb1, 0x08, 0x26, 0xc2, 0xf3, 0x1b,
0xe9, 0xa8, 0x82, 0xfc, 0x7d, 0xbb, 0x81, 0x6e, 0x51, 0xf1, 0x5e, 0xc5, 0xeb, 0x2a, 0xa5, 0x95,
0x9a, 0x13, 0xa1, 0x6e, 0x35, 0x30, 0x9c, 0x19, 0x2f, 0x6e, 0xa8, 0x65, 0x7d, 0x14, 0xc8, 0x81,
0xd5, 0xfb, 0x7f, 0x56, 0x79, 0x42, 0x96, 0x2d, 0x1a, 0x16, 0xe8, 0x8b, 0x9b, 0xaa, 0x61, 0x73,
0xc5, 0x82, 0xc5, 0x37, 0x06, 0x9e, 0x0f, 0x34, 0xec, 0x7c, 0x75, 0xe0, 0xf3, 0x9b, 0x29, 0xa9,
0xb2, 0xfc, 0xc7, 0x28, 0x7a, 0xe0, 0xb0, 0xe6, 0x79, 0x02, 0x38, 0xf5, 0xf8, 0x71, 0xc0, 0x3e,
0xa6, 0xa4, 0x0b, 0xf7, 0xbb, 0xbf, 0x9c, 0xb2, 0xf9, 0x82, 0x8e, 0xa3, 0xb2, 0x97, 0xe5, 0x9c,
0x56, 0xdd, 0x2f, 0xe8, 0xb8, 0x76, 0x25, 0x15, 0xe3, 0x5f, 0xd0, 0x09, 0xe0, 0xd6, 0x17, 0x74,
0x3c, 0x9e, 0xbd, 0x5f, 0xd0, 0xf1, 0x5a, 0x0b, 0x7e, 0x41, 0x27, 0xac, 0x81, 0x85, 0xf7, 0xb6,
0x08, 0xf2, 0xdc, 0x7a, 0x90, 0x45, 0xf7, 0x18, 0xfb, 0xd9, 0x4d, 0x54, 0x90, 0x05, 0x4e, 0x72,
0xe2, 0x9e, 0xdb, 0x80, 0x36, 0x75, 0xee, 0xba, 0x6d, 0x0d, 0xe6, 0x95, 0xef, 0x9f, 0xaa, 0xdd,
0x8d, 0x0e, 0xe7, 0xac, 0x12, 0x5f, 0x4f, 0x5a, 0x0f, 0x85, 0xe7, 0xc6, 0x82, 0xdd, 0xf3, 0x1b,
0xc3, 0x60, 0xa4, 0xba, 0x0d, 0xa1, 0x3a, 0x3d, 0xee, 0x33, 0x04, 0xba, 0x7c, 0x6b, 0x30, 0x8f,
0x2c, 0x23, 0xd2, 0xb7, 0xec, 0xed, 0x01, 0xc6, 0xdc, 0xbe, 0x7e, 0x3a, 0x5c, 0x41, 0xb9, 0x5f,
0xaa, 0xb4, 0xd1, 0x76, 0x2f, 0xfa, 0x79, 0xb3, 0xcf, 0xd4, 0xc4, 0xe9, 0xe6, 0x78, 0x28, 0x1e,
0x4a, 0x20, 0xec, 0x25, 0xb4, 0x2f, 0x81, 0xf0, 0x2e, 0xa3, 0x9f, 0xdf, 0x4c, 0x49, 0x95, 0xe5,
0x9f, 0x46, 0xd1, 0x6d, 0xb4, 0x2c, 0x6a, 0x1c, 0x7c, 0x31, 0xd4, 0x32, 0x18, 0x0f, 0x5f, 0xde,
0x58, 0x4f, 0x15, 0xea, 0x5f, 0x47, 0xd1, 0x9d, 0x40, 0xa1, 0xe4, 0x00, 0xb9, 0x81, 0x75, 0x77,
0xa0, 0xfc, 0xf0, 0xe6, 0x8a, 0xd8, 0x72, 0x6f, 0xe3, 0x93, 0xee, 0xa7, 0x65, 0x02, 0xb6, 0x27,
0xf8, 0xa7, 0x65, 0xfa, 0xb5, 0xe0, 0x21, 0x0f, 0x39, 0x6f, 0x37, 0x5d, 0xde, 0x43, 0x1e, 0x71,
0x43, 0x0d, 0xec, 0x39, 0xd6, 0x7a, 0x39, 0x9f, 0x93, 0x57, 0xef, 0x4a, 0x52, 0xa4, 0xb8, 0x13,
0x29, 0xef, 0x77, 0xa2, 0x39, 0x78, 0x38, 0xd6, 0x48, 0x4f, 0x59, 0xbb, 0x91, 0x7a, 0x8c, 0xe9,
0x6b, 0x24, 0x78, 0x38, 0xd6, 0x41, 0x11, 0x6f, 0x2a, 0x6b, 0x0c, 0x79, 0x03, 0xc9, 0xe2, 0x93,
0x21, 0x28, 0x48, 0xd1, 0xb5, 0x37, 0x7d, 0xe6, 0xbe, 0x11, 0xb2, 0xd2, 0x39, 0x77, 0xdf, 0x1c,
0x48, 0x23, 0x6e, 0x27, 0x94, 0x7f, 0x45, 0x49, 0x4a, 0xab, 0xa0, 0x5b, 0x4d, 0x0d, 0x72, 0x6b,
0xd3, 0x3e, 0xb7, 0x3b, 0x2c, 0x5f, 0xcc, 0x0b, 0xd5, 0x99, 0xa8, 0x5b, 0x9b, 0xea, 0x77, 0x0b,
0x68, 0x78, 0x2c, 0x68, 0xdc, 0x8a, 0xf4, 0xf2, 0x49, 0xd8, 0x8c, 0x93, 0x55, 0xae, 0x0f, 0x62,
0xf1, 0x7a, 0xaa, 0x61, 0xd4, 0x53, 0x4f, 0x30, 0x92, 0x36, 0x07, 0xd2, 0xf0, 0x7c, 0xce, 0x72,
0xab, 0xc7, 0xd3, 0x56, 0x8f, 0xad, 0xce, 0x90, 0x7a, 0x3a, 0x5c, 0x01, 0x9e, 0x86, 0xaa, 0x51,
0x75, 0x98, 0xd5, 0x7c, 0x2f, 0xcb, 0xf3, 0xf1, 0x7a, 0x60, 0x98, 0xb4, 0x50, 0xf0, 0x34, 0xd4,
0x03, 0x23, 0x23, 0xb9, 0x3d, 0x3d, 0x2c, 0xc6, 0x7d, 0x76, 0x04, 0x35, 0x68, 0x24, 0xdb, 0x34,
0x38, 0xd1, 0xb2, 0x9a, 0x5a, 0xd7, 0x36, 0x0e, 0x37, 0x5c, 0xa7, 0xc2, 0x5b, 0x83, 0x79, 0xf0,
0xb8, 0x5d, 0x50, 0x62, 0x65, 0xb9, 0x8f, 0x99, 0x70, 0x56, 0x92, 0x07, 0x3d, 0x14, 0x38, 0x15,
0x94, 0xd3, 0xe8, 0x6d, 0x96, 0xce, 0x28, 0xf7, 0x3e, 0x29, 0xb2, 0x81, 0xe0, 0x93, 0x22, 0x00,
0x82, 0xae, 0x93, 0xbf, 0xeb, 0xe3, 0xd0, 0x83, 0xd4, 0xd7, 0x75, 0x4a, 0xd9, 0xa2, 0x42, 0x5d,
0xe7, 0xa5, 0x41, 0x34, 0xd0, 0x6e, 0xd5, 0xab, 0xf1, 0x4f, 0x42, 0x66, 0xc0, 0xfb, 0xf1, 0xeb,
0x83, 0x58, 0xb0, 0xa2, 0x18, 0x87, 0xd9, 0x3c, 0xe3, 0xbe, 0x15, 0xc5, 0xb2, 0xd1, 0x20, 0xa1,
0x15, 0xa5, 0x8b, 0x62, 0xd5, 0x6b, 0x72, 0x84, 0x83, 0x34, 0x5c, 0x3d, 0xc9, 0x0c, 0xab, 0x9e,
0x66, 0x3b, 0x0f, 0x36, 0x0b, 0x3d, 0x64, 0xf8, 0xa5, 0xda, 0x2c, 0x7b, 0xc6, 0xb6, 0x78, 0x65,
0x12, 0x82, 0xa1, 0xa8, 0x83, 0x29, 0xc0, 0x03, 0xfb, 0x86, 0x6b, 0x9f, 0xbd, 0x96, 0x25, 0x25,
0x15, 0x29, 0x12, 0xef, 0xe6, 0x54, 0x18, 0xec, 0x90, 0xa1, 0xcd, 0x29, 0xaa, 0x01, 0x1e, 0x9b,
0xbb, 0x2f, 0x3b, 0x7a, 0xa6, 0x82, 0x7e, 0xab, 0xd0, 0x7d, 0xd7, 0xf1, 0xf1, 0x00, 0x12, 0x3e,
0x36, 0x6f, 0x01, 0x7d, 0xf0, 0x2d, 0x9d, 0x7e, 0x16, 0x30, 0xe5, 0xa2, 0xa1, 0x8d, 0x30, 0xae,
0x02, 0x06, 0xb5, 0x4e, 0x70, 0x29, 0xff, 0x09, 0x5d, 0xf9, 0x06, 0xb5, 0xc9, 0x4f, 0x05, 0x12,
0x1a, 0xd4, 0x5d, 0x14, 0xe4, 0x99, 0xf6, 0x3e, 0xe8, 0x61, 0x40, 0xdf, 0xde, 0xfa, 0xac, 0xf5,
0x72, 0x60, 0xe6, 0xec, 0x66, 0x4b, 0xe7, 0x39, 0x81, 0xa7, 0xa0, 0xbb, 0xd9, 0xd2, 0xff, 0x98,
0x60, 0x7d, 0x10, 0x0b, 0x1f, 0xc9, 0x13, 0x4e, 0xdf, 0xb5, 0xcf, 0xca, 0x3d, 0xc5, 0x15, 0xf2,
0xce, 0xc3, 0xf2, 0x47, 0xfd, 0xa0, 0xb9, 0x00, 0x7b, 0x52, 0xb1, 0x84, 0xd6, 0xb5, 0xfa, 0xde,
0x9e, 0x7b, 0xc3, 0x48, 0xc9, 0x62, 0xf0, 0xb5, 0xbd, 0xfb, 0x61, 0x48, 0xd9, 0xfe, 0x2a, 0x7a,
0xff, 0x90, 0xcd, 0x26, 0xb4, 0x48, 0xc7, 0x3f, 0x70, 0xaf, 0x9c, 0xb2, 0x59, 0xdc, 0xfc, 0xac,
0xed, 0xdd, 0xc2, 0xc4, 0xe6, 0xd2, 0xdc, 0x2e, 0x3d, 0x5f, 0xcc, 0x26, 0x9c, 0x70, 0x70, 0x69,
0x4e, 0xfc, 0x1e, 0x37, 0x02, 0xe4, 0xd2, 0x9c, 0x03, 0x00, 0x7b, 0xd3, 0x8a, 0x52, 0xaf, 0xbd,
0x46, 0x10, 0xb4, 0xa7, 0x00, 0xb3, 0xea, 0x6a, 0x7b, 0x4d, 0x62, 0x0b, 0x2f, 0xb9, 0x19, 0x1d,
0x21, 0x45, 0x56, 0xdd, 0x2e, 0x65, 0x06, 0x83, 0xac, 0xbe, 0xf8, 0x62, 0xc6, 0x62, 0x3e, 0x27,
0xd5, 0x0a, 0x0c, 0x06, 0x55, 0x4b, 0x0b, 0x40, 0x06, 0x83, 0x17, 0x34, 0xa3, 0xbc, 0x6d, 0xe6,
0xe4, 0x6a, 0x9f, 0x55, 0x6c, 0xc1, 0xb3, 0x82, 0xc2, 0xaf, 0x26, 0xe8, 0x06, 0xb5, 0x19, 0x64,
0x94, 0x63, 0xac, 0xc9, 0x0a, 0x05, 0x21, 0xef, 0xdf, 0x89, 0xaf, 0xd6, 0xd6, 0x9c, 0x55, 0xf0,
0xf9, 0x9b, 0xb4, 0x02, 0x21, 0x24, 0x2b, 0x44, 0x61, 0xd0, 0xf7, 0x27, 0x59, 0x31, 0xf3, 0xf6,
0xfd, 0x89, 0xfd, 0xcd, 0xc7, 0x3b, 0x38, 0x60, 0xe2, 0xbb, 0x6c, 0x34, 0xf9, 0x65, 0x22, 0xf5,
0xee, 0xa3, 0xb7, 0xd1, 0x6d, 0x02, 0x89, 0xef, 0x7e, 0x12, 0xb8, 0x7a, 0x5d, 0xd2, 0x82, 0xa6,
0xed, 0x2d, 0x33, 0x9f, 0x2b, 0x87, 0x08, 0xba, 0x82, 0xa4, 0x89, 0xaa, 0x42, 0x7e, 0xba, 0x28,
0x4e, 0x2a, 0x76, 0x91, 0xe5, 0xb4, 0x02, 0x51, 0x55, 0xaa, 0x5b, 0x72, 0x24, 0xaa, 0xfa, 0x38,
0x73, 0x5d, 0x41, 0x48, 0x9d, 0x4f, 0x2f, 0x4f, 0x2b, 0x92, 0xc0, 0xeb, 0x0a, 0xd2, 0x46, 0x17,
0x43, 0x4e, 0xd2, 0x02, 0xb8, 0x95, 0x18, 0x48, 0xd7, 0xc5, 0x4a, 0x8c, 0x0f, 0xf5, 0xee, 0x9d,
0xf8, 0x12, 0x62, 0x0d, 0x12, 0x03, 0x65, 0xce, 0x47, 0x22, 0x89, 0x41, 0x58, 0xc3, 0xcc, 0xb6,
0x23, 0xca, 0xab, 0x2c, 0xa9, 0x27, 0x94, 0x9f, 0x90, 0x8a, 0xcc, 0x29, 0xa7, 0x15, 0x9c, 0x6d,
0x0a, 0x89, 0x1d, 0x06, 0x99, 0x6d, 0x18, 0xab, 0x1c, 0xfe, 0x5e, 0xf4, 0x61, 0xb3, 0xd8, 0xd0,
0x42, 0xfd, 0xa5, 0x82, 0x57, 0xe2, 0x4f, 0x9c, 0x8c, 0x3f, 0xd2, 0x36, 0x26, 0xbc, 0xa2, 0x64,
0xde, 0xda, 0xfe, 0x40, 0xff, 0x2e, 0xc0, 0xa7, 0xa3, 0x66, 0x50, 0x1c, 0x33, 0x9e, 0x5d, 0x34,
0x7b, 0x3b, 0xf5, 0xda, 0x0a, 0x18, 0x14, 0xb6, 0x38, 0x0e, 0x7c, 0x8c, 0xc0, 0xc7, 0x99, 0x60,
0x67, 0x4b, 0x4f, 0x69, 0x99, 0xc3, 0x60, 0xe7, 0x68, 0x0b, 0x00, 0x09, 0x76, 0x5e, 0xd0, 0x8c,
0x70, 0x5b, 0x3c, 0xa5, 0xe1, 0xca, 0x4c, 0xe9, 0xb0, 0xca, 0x4c, 0x9d, 0x37, 0x01, 0xf2, 0xe8,
0xc3, 0x23, 0x3a, 0x3f, 0xa7, 0x55, 0x7d, 0x99, 0x95, 0xfb, 0xcd, 0x2a, 0x4f, 0xf8, 0x02, 0xbe,
0x2b, 0x67, 0x88, 0x58, 0x23, 0x48, 0x2a, 0x84, 0xa0, 0x26, 0x9c, 0x1a, 0xe0, 0xa0, 0x3e, 0x26,
0x73, 0x2a, 0x3e, 0xad, 0x30, 0x5e, 0xc7, 0x8c, 0x58, 0x10, 0x12, 0x4e, 0x51, 0xd8, 0x7a, 0xa9,
0xc8, 0x30, 0xa7, 0x74, 0xd6, 0x8c, 0xb0, 0xea, 0x84, 0xac, 0xe6, 0xb4, 0xe0, 0xca, 0x24, 0x38,
0x08, 0xb6, 0x4c, 0xfa, 0x79, 0xe4, 0x20, 0x78, 0x88, 0x9e, 0x35, 0xbf, 0x9d, 0x86, 0x3f, 0x61,
0x15, 0x97, 0x7f, 0x87, 0xe4, 0xac, 0xca, 0xc1, 0xfc, 0x76, 0x1b, 0xd5, 0x21, 0x91, 0xf9, 0x1d,
0xd6, 0xb0, 0x3e, 0xe0, 0xed, 0x94, 0xe1, 0x0d, 0xad, 0xf4, 0x38, 0x79, 0x35, 0x27, 0x59, 0xae,
0x46, 0xc3, 0x8f, 0x02, 0xb6, 0x11, 0x1d, 0xe4, 0x03, 0xde, 0x43, 0x75, 0xad, 0x4f, 0x9e, 0x87,
0x4b, 0x08, 0xce, 0xa5, 0x7b, 0xec, 0x23, 0xe7, 0xd2, 0xfd, 0x5a, 0x66, 0xbb, 0x68, 0x58, 0xc1,
0xad, 0x04, 0xb1, 0xc3, 0x52, 0x78, 0x48, 0x65, 0xd9, 0x04, 0x20, 0xb2, 0x5d, 0x0c, 0x2a, 0x98,
0xf5, 0xd5, 0x60, 0x7b, 0x59, 0x41, 0xf2, 0xec, 0x67, 0xf0, 0x86, 0xb3, 0x65, 0xa7, 0x25, 0x90,
0xf5, 0xd5, 0x4f, 0xfa, 0x5c, 0xed, 0x53, 0x3e, 0xcd, 0x9a, 0xd0, 0xff, 0x28, 0xd0, 0x6e, 0x82,
0xe8, 0x77, 0x65, 0x91, 0xd6, 0x47, 0x3a, 0x61, 0xb3, 0x6e, 0x97, 0xe5, 0xa4, 0x59, 0x9a, 0x4e,
0x69, 0x42, 0xb3, 0x92, 0x8f, 0x5f, 0x84, 0xdb, 0x0a, 0xe0, 0xc8, 0xd3, 0xfd, 0x01, 0x6a, 0xd6,
0x33, 0xe3, 0x26, 0x96, 0x4c, 0xe4, 0x1f, 0xe8, 0x3a, 0xab, 0x69, 0xa5, 0x56, 0xeb, 0x7d, 0xca,
0xc1, 0xec, 0xb4, 0xb8, 0xd8, 0x02, 0x9b, 0x8a, 0x22, 0xb3, 0x33, 0xac, 0x61, 0x4e, 0x98, 0x2c,
0xee, 0x94, 0xd6, 0x2c, 0x5f, 0x52, 0x71, 0xc9, 0x6d, 0x03, 0x35, 0x66, 0x51, 0xc8, 0x09, 0x13,
0x4e, 0x9b, 0x94, 0xa7, 0xeb, 0x76, 0xbb, 0x58, 0x1d, 0xc0, 0xe7, 0xf4, 0x1e, 0x4b, 0x02, 0x43,
0x52, 0x9e, 0x00, 0x6e, 0x9d, 0xc0, 0x56, 0x8c, 0xa4, 0x09, 0xa9, 0xf9, 0x09, 0x59, 0xe5, 0x8c,
0xa4, 0x62, 0x5d, 0x87, 0x27, 0xb0, 0x2d, 0x13, 0xdb, 0x10, 0x76, 0x02, 0x8b, 0xc1, 0x66, 0x77,
0xa9, 0xfe, 0xee, 0x98, 0xba, 0x40, 0x78, 0x0f, 0xa4, 0x49, 0xa2, 0xbc, 0xf0, 0xf2, 0xe0, 0xfd,
0x30, 0x64, 0x5e, 0x7c, 0x92, 0x22, 0x91, 0x86, 0xdc, 0xf1, 0xe9, 0x38, 0x09, 0xc8, 0xa7, 0x01,
0xc2, 0x7c, 0x0c, 0x41, 0xfe, 0xde, 0xfe, 0xe9, 0x0c, 0xae, 0x3e, 0x65, 0xbc, 0xe1, 0xd3, 0xb5,
0xa1, 0xd8, 0xfe, 0xc2, 0xd9, 0xe6, 0x40, 0xda, 0x6c, 0x1e, 0x77, 0x2e, 0x09, 0xdf, 0x4e, 0xd3,
0x23, 0x5a, 0x7b, 0xde, 0x62, 0x6e, 0x84, 0xb1, 0x91, 0x22, 0x9b, 0xc7, 0x2e, 0x65, 0x06, 0x7a,
0x23, 0x7b, 0x95, 0x66, 0x5c, 0xc9, 0xda, 0x6b, 0xb9, 0x1b, 0x5d, 0x03, 0x5d, 0x0a, 0xa9, 0x15,
0x4e, 0x9b, 0x58, 0xde, 0x30, 0x53, 0x36, 0x9b, 0xe5, 0x54, 0x41, 0xa7, 0x94, 0xc8, 0x2f, 0xb9,
0x6d, 0x75, 0x6d, 0x79, 0x41, 0x24, 0x96, 0x07, 0x15, 0x4c, 0x1a, 0xd9, 0x60, 0xf2, 0x39, 0x48,
0xdb, 0xb0, 0x6b, 0x5d, 0x33, 0x0e, 0x80, 0xa4, 0x91, 0x5e, 0xd0, 0xbc, 0x6c, 0xd5, 0x88, 0xf7,
0x69, 0xdb, 0x12, 0xf0, 0xbb, 0x37, 0x42, 0xd9, 0x12, 0x23, 0x2f, 0x5b, 0x79, 0x30, 0xb3, 0x4f,
0x00, 0x1e, 0x5e, 0xae, 0x0e, 0x52, 0xb8, 0x4f, 0x80, 0xfa, 0x82, 0x41, 0xf6, 0x09, 0x18, 0xeb,
0x76, 0x9d, 0xfe, 0xc8, 0xef, 0x21, 0xa9, 0x4d, 0xe5, 0x3c, 0x5d, 0xe7, 0x05, 0x43, 0x5d, 0x87,
0x29, 0xb8, 0x4d, 0x6a, 0x7f, 0x42, 0xd8, 0xd3, 0xa4, 0xbe, 0x4f, 0x07, 0x3f, 0xec, 0xc3, 0x4c,
0x5c, 0xd2, 0x9b, 0x32, 0x71, 0x4f, 0xc6, 0xff, 0x09, 0x77, 0x29, 0x44, 0xe2, 0x52, 0x07, 0x92,
0xb6, 0x5f, 0x7e, 0xfa, 0x5f, 0xdf, 0xdc, 0x1a, 0xfd, 0xe2, 0x9b, 0x5b, 0xa3, 0xff, 0xf9, 0xe6,
0xd6, 0xe8, 0xe7, 0xdf, 0xde, 0x7a, 0xef, 0x17, 0xdf, 0xde, 0x7a, 0xef, 0xbf, 0xbf, 0xbd, 0xf5,
0xde, 0xd7, 0xef, 0xab, 0xbf, 0x47, 0x79, 0xfe, 0xff, 0xc4, 0x5f, 0x95, 0x7c, 0xfe, 0x7f, 0x01,
0x00, 0x00, 0xff, 0xff, 0xe5, 0xb3, 0x13, 0x72, 0xb3, 0x72, 0x00, 0x00,
// 5189 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x9d, 0xdd, 0x6f, 0x1d, 0x49,
0x56, 0xc0, 0xc7, 0x2f, 0x0c, 0xf4, 0xb2, 0x03, 0xdc, 0x81, 0x61, 0x76, 0xd8, 0xcd, 0xd7, 0x24,
0x71, 0x12, 0xdb, 0xd7, 0x99, 0x64, 0x32, 0xb3, 0xda, 0x45, 0x42, 0x8e, 0x1d, 0x7b, 0xcc, 0xda,
0x8e, 0xf1, 0xb5, 0x13, 0x69, 0x24, 0x24, 0xca, 0xdd, 0xe5, 0xeb, 0xc6, 0x7d, 0xbb, 0x7a, 0xbb,
0xeb, 0x5e, 0xe7, 0x2e, 0x02, 0x81, 0x40, 0x20, 0x10, 0x88, 0x15, 0x5f, 0xaf, 0x48, 0xfc, 0x35,
0x3c, 0xee, 0x23, 0x8f, 0x68, 0x46, 0xfc, 0x1f, 0xa8, 0xeb, 0xbb, 0x4e, 0xd7, 0xa9, 0x6e, 0xef,
0x53, 0xa2, 0x7b, 0x7e, 0xe7, 0x9c, 0xfa, 0x3c, 0x75, 0xaa, 0xba, 0xba, 0x9d, 0xdc, 0xae, 0xce,
0x37, 0xab, 0x9a, 0x71, 0xd6, 0x6c, 0x36, 0xb4, 0x5e, 0xe4, 0x29, 0xd5, 0xff, 0x8e, 0xc5, 0xcf,
0xa3, 0xf7, 0x49, 0xb9, 0xe4, 0xcb, 0x8a, 0x7e, 0xf2, 0xb1, 0x25, 0x53, 0x36, 0x9b, 0x91, 0x32,
0x6b, 0x24, 0xf2, 0xc9, 0x47, 0x56, 0x42, 0x17, 0xb4, 0xe4, 0xea, 0xf7, 0x67, 0xdf, 0xfe, 0xdf,
0x4a, 0xf2, 0xc1, 0x76, 0x91, 0xd3, 0x92, 0x6f, 0x2b, 0x8d, 0xd1, 0xd7, 0xc9, 0x77, 0xb7, 0xaa,
0x6a, 0x8f, 0xf2, 0x37, 0xb4, 0x6e, 0x72, 0x56, 0x8e, 0x3e, 0x1d, 0x2b, 0x07, 0xe3, 0x93, 0x2a,
0x1d, 0x6f, 0x55, 0xd5, 0xd8, 0x0a, 0xc7, 0x27, 0xf4, 0xa7, 0x73, 0xda, 0xf0, 0x4f, 0xee, 0xc7,
0xa1, 0xa6, 0x62, 0x65, 0x43, 0x47, 0x17, 0xc9, 0x6f, 0x6d, 0x55, 0xd5, 0x84, 0xf2, 0x1d, 0xda,
0x56, 0x60, 0xc2, 0x09, 0xa7, 0xa3, 0xd5, 0x8e, 0xaa, 0x0f, 0x18, 0x1f, 0x8f, 0xfa, 0x41, 0xe5,
0xe7, 0x34, 0xf9, 0x4e, 0xeb, 0xe7, 0x72, 0xce, 0x33, 0x76, 0x5d, 0x8e, 0xee, 0x76, 0x15, 0x95,
0xc8, 0xd8, 0xbe, 0x17, 0x43, 0x94, 0xd5, 0xb7, 0xc9, 0xaf, 0xbf, 0x25, 0x45, 0x41, 0xf9, 0x76,
0x4d, 0xdb, 0x82, 0xfb, 0x3a, 0x52, 0x34, 0x96, 0x32, 0x63, 0xf7, 0xd3, 0x28, 0xa3, 0x0c, 0x7f,
0x9d, 0x7c, 0x57, 0x4a, 0x4e, 0x68, 0xca, 0x16, 0xb4, 0x1e, 0x05, 0xb5, 0x94, 0x10, 0x69, 0xf2,
0x0e, 0x04, 0x6d, 0x6f, 0xb3, 0x72, 0x41, 0x6b, 0x1e, 0xb6, 0xad, 0x84, 0x71, 0xdb, 0x16, 0x52,
0xb6, 0xff, 0x7e, 0x25, 0xf9, 0xfe, 0x56, 0x9a, 0xb2, 0x79, 0xc9, 0x0f, 0x58, 0x4a, 0x8a, 0x83,
0xbc, 0xbc, 0x3a, 0xa2, 0xd7, 0xdb, 0x97, 0x2d, 0x5f, 0x4e, 0xe9, 0xe8, 0xb9, 0xdf, 0xaa, 0x12,
0x1d, 0x1b, 0x76, 0xec, 0xc2, 0xc6, 0xf7, 0xe7, 0x37, 0x53, 0x52, 0x65, 0xf9, 0xe7, 0x95, 0xe4,
0x16, 0x2c, 0xcb, 0x84, 0x15, 0x0b, 0x6a, 0x4b, 0xf3, 0xa2, 0xc7, 0xb0, 0x8f, 0x9b, 0xf2, 0x7c,
0x71, 0x53, 0x35, 0x55, 0xa2, 0x22, 0xf9, 0xd0, 0x1d, 0x2e, 0x13, 0xda, 0x88, 0xe9, 0xf4, 0x18,
0x1f, 0x11, 0x0a, 0x31, 0x9e, 0x9f, 0x0c, 0x41, 0x95, 0xb7, 0x3c, 0x19, 0x29, 0x6f, 0x05, 0x6b,
0x8c, 0xb3, 0x47, 0x41, 0x0b, 0x0e, 0x61, 0x7c, 0x3d, 0x1e, 0x40, 0x2a, 0x57, 0x7f, 0x92, 0xfc,
0xc6, 0x5b, 0x56, 0x5f, 0x35, 0x15, 0x49, 0xa9, 0x9a, 0x0a, 0x0f, 0x7c, 0x6d, 0x2d, 0x85, 0xb3,
0xe1, 0x61, 0x1f, 0xe6, 0x0c, 0x5a, 0x2d, 0x7c, 0x5d, 0x51, 0x18, 0x83, 0xac, 0x62, 0x2b, 0xc4,
0x06, 0x2d, 0x84, 0x94, 0xed, 0xab, 0x64, 0x64, 0x6d, 0x9f, 0xff, 0x29, 0x4d, 0xf9, 0x56, 0x96,
0xc1, 0x5e, 0xb1, 0xba, 0x82, 0x18, 0x6f, 0x65, 0x19, 0xd6, 0x2b, 0x61, 0x54, 0x39, 0xbb, 0x4e,
0x3e, 0x02, 0xce, 0x0e, 0xf2, 0x46, 0x38, 0xdc, 0x88, 0x5b, 0x51, 0x98, 0x71, 0x3a, 0x1e, 0x8a,
0x2b, 0xc7, 0x7f, 0xb9, 0x92, 0x7c, 0x2f, 0xe0, 0xf9, 0x84, 0xce, 0xd8, 0x82, 0x8e, 0x9e, 0xf6,
0x5b, 0x93, 0xa4, 0xf1, 0xff, 0xd9, 0x0d, 0x34, 0x02, 0xc3, 0x64, 0x42, 0x0b, 0x9a, 0x72, 0x74,
0x98, 0x48, 0x71, 0xef, 0x30, 0x31, 0x98, 0x33, 0xc3, 0xb4, 0x70, 0x8f, 0xf2, 0xed, 0x79, 0x5d,
0xd3, 0x92, 0xa3, 0x7d, 0x69, 0x91, 0xde, 0xbe, 0xf4, 0xd0, 0x40, 0x7d, 0xf6, 0x28, 0xdf, 0x2a,
0x0a, 0xb4, 0x3e, 0x52, 0xdc, 0x5b, 0x1f, 0x83, 0x29, 0x0f, 0x69, 0xf2, 0x9b, 0x4e, 0x8b, 0xf1,
0xfd, 0xf2, 0x82, 0x8d, 0xf0, 0xb6, 0x10, 0x72, 0xe3, 0x63, 0xb5, 0x97, 0x0b, 0x54, 0xe3, 0xd5,
0xbb, 0x8a, 0xd5, 0x78, 0xb7, 0x48, 0x71, 0x6f, 0x35, 0x0c, 0xa6, 0x3c, 0xfc, 0x71, 0xf2, 0x81,
0x8a, 0x92, 0x7a, 0x3d, 0xbb, 0x1f, 0x0c, 0xa1, 0x70, 0x41, 0x7b, 0xd0, 0x43, 0xd9, 0xe0, 0xa0,
0x64, 0x2a, 0xf8, 0x7c, 0x1a, 0xd4, 0x03, 0xa1, 0xe7, 0x7e, 0x1c, 0xea, 0xd8, 0xde, 0xa1, 0x05,
0x45, 0x6d, 0x4b, 0x61, 0x8f, 0x6d, 0x03, 0x29, 0xdb, 0x75, 0xf2, 0x3b, 0xa6, 0x59, 0xda, 0x75,
0x54, 0xc8, 0xdb, 0x20, 0xbd, 0x86, 0xd4, 0xdb, 0x85, 0x8c, 0xaf, 0xf5, 0x61, 0x70, 0xa7, 0x3e,
0x6a, 0x06, 0x86, 0xeb, 0x03, 0xe6, 0xdf, 0xfd, 0x38, 0xa4, 0x6c, 0xff, 0xc3, 0x4a, 0xf2, 0x03,
0x25, 0x7b, 0x55, 0x92, 0xf3, 0x82, 0x8a, 0x25, 0xf1, 0x88, 0xf2, 0x6b, 0x56, 0x5f, 0x4d, 0x96,
0x65, 0x8a, 0x2c, 0xff, 0x61, 0xb8, 0x67, 0xf9, 0x47, 0x95, 0x9c, 0x8c, 0x4f, 0x55, 0x94, 0xb3,
0x0a, 0x66, 0x7c, 0xba, 0x06, 0x9c, 0x55, 0x58, 0xc6, 0xe7, 0x23, 0x1d, 0xab, 0x87, 0x6d, 0xd8,
0x0c, 0x5b, 0x3d, 0x74, 0xe3, 0xe4, 0xbd, 0x18, 0x62, 0xc3, 0x96, 0x1e, 0xc0, 0xac, 0xbc, 0xc8,
0xa7, 0x67, 0x55, 0xd6, 0x0e, 0xe3, 0xc7, 0xe1, 0x11, 0xea, 0x20, 0x48, 0xd8, 0x42, 0x50, 0xe5,
0xed, 0x9f, 0x6c, 0x62, 0xa4, 0xa6, 0xd2, 0x6e, 0xcd, 0x66, 0x07, 0x74, 0x4a, 0xd2, 0xa5, 0x9a,
0xff, 0x9f, 0xc7, 0x26, 0x1e, 0xa4, 0x4d, 0x21, 0x5e, 0xdc, 0x50, 0x4b, 0x95, 0xe7, 0x3f, 0x57,
0x92, 0xfb, 0xba, 0xfa, 0x97, 0xa4, 0x9c, 0x52, 0xd5, 0x9f, 0xb2, 0xf4, 0x5b, 0x65, 0x76, 0x42,
0x1b, 0x4e, 0x6a, 0x3e, 0xfa, 0x51, 0xb8, 0x92, 0x31, 0x1d, 0x53, 0xb6, 0x1f, 0xff, 0x52, 0xba,
0xb6, 0xd7, 0x27, 0x6d, 0x60, 0x53, 0x21, 0xc0, 0xef, 0x75, 0x21, 0x81, 0x01, 0xe0, 0x5e, 0x0c,
0xb1, 0xbd, 0x2e, 0x04, 0xfb, 0xe5, 0x22, 0xe7, 0x74, 0x8f, 0x96, 0xb4, 0xee, 0xf6, 0xba, 0x54,
0xf5, 0x11, 0xa4, 0xd7, 0x11, 0xd4, 0x06, 0x1b, 0xcf, 0x9b, 0x59, 0x1c, 0xd7, 0x22, 0x46, 0x3a,
0xcb, 0xe3, 0xfa, 0x30, 0xd8, 0xee, 0xee, 0x1c, 0x9f, 0x27, 0x74, 0xc1, 0xae, 0xe0, 0xee, 0xce,
0x35, 0x21, 0x01, 0x64, 0x77, 0x17, 0x04, 0xed, 0x0a, 0xe6, 0xf8, 0x79, 0x93, 0xd3, 0x6b, 0xb0,
0x82, 0xb9, 0xca, 0xad, 0x18, 0x59, 0xc1, 0x02, 0x98, 0xf2, 0x70, 0x94, 0xfc, 0x9a, 0x10, 0xfe,
0x21, 0xcb, 0xcb, 0xd1, 0xed, 0x80, 0x52, 0x2b, 0x30, 0x56, 0xef, 0xe0, 0x00, 0x28, 0x71, 0xfb,
0xeb, 0x36, 0x29, 0x53, 0x5a, 0x04, 0x4b, 0x6c, 0xc5, 0xd1, 0x12, 0x7b, 0x98, 0x4d, 0x1d, 0x84,
0xb0, 0x8d, 0x5f, 0x93, 0x4b, 0x52, 0xe7, 0xe5, 0x74, 0x14, 0xd2, 0x75, 0xe4, 0x48, 0xea, 0x10,
0xe2, 0xc0, 0x10, 0x56, 0x8a, 0x5b, 0x55, 0x55, 0xb7, 0x61, 0x31, 0x34, 0x84, 0x7d, 0x24, 0x3a,
0x84, 0x3b, 0x68, 0xd8, 0xdb, 0x0e, 0x4d, 0x8b, 0xbc, 0x8c, 0x7a, 0x53, 0xc8, 0x10, 0x6f, 0x16,
0x05, 0x83, 0xf7, 0x80, 0x92, 0x05, 0xd5, 0x35, 0x0b, 0xb5, 0x8c, 0x0b, 0x44, 0x07, 0x2f, 0x00,
0xed, 0x3e, 0x4d, 0x88, 0x0f, 0xc9, 0x15, 0x6d, 0x1b, 0x98, 0xb6, 0xeb, 0xda, 0x28, 0xa4, 0xef,
0x11, 0xc8, 0x3e, 0x2d, 0x4c, 0x2a, 0x57, 0xf3, 0xe4, 0x23, 0x21, 0x3f, 0x26, 0x35, 0xcf, 0xd3,
0xbc, 0x22, 0xa5, 0xce, 0xff, 0x43, 0xf3, 0xba, 0x43, 0x19, 0x97, 0x1b, 0x03, 0x69, 0xe5, 0xf6,
0x3f, 0x56, 0x92, 0xbb, 0xd0, 0xef, 0x31, 0xad, 0x67, 0xb9, 0xd8, 0x46, 0x36, 0x32, 0x08, 0x8f,
0xbe, 0x8c, 0x1b, 0xed, 0x28, 0x98, 0xd2, 0xfc, 0xf0, 0xe6, 0x8a, 0xaa, 0x60, 0x7f, 0x94, 0x24,
0x72, 0xbb, 0x22, 0xb6, 0x94, 0xfe, 0xac, 0x55, 0xfb, 0x18, 0x6f, 0x3f, 0x79, 0x37, 0x42, 0xd8,
0xa5, 0x42, 0xfe, 0x2e, 0x76, 0xca, 0xa3, 0xa0, 0x86, 0x10, 0x21, 0x4b, 0x05, 0x40, 0x60, 0x41,
0x27, 0x97, 0xec, 0x3a, 0x5c, 0xd0, 0x56, 0x12, 0x2f, 0xa8, 0x22, 0xec, 0xd9, 0x95, 0x2a, 0x68,
0xe8, 0xec, 0x4a, 0x17, 0x23, 0x76, 0x76, 0x05, 0x19, 0x65, 0x98, 0x25, 0xbf, 0xed, 0x1a, 0x7e,
0xc9, 0xd8, 0xd5, 0x8c, 0xd4, 0x57, 0xa3, 0x27, 0xb8, 0xb2, 0x66, 0x8c, 0xa3, 0xb5, 0x41, 0xac,
0x0d, 0x0b, 0xae, 0xc3, 0x36, 0xd1, 0x38, 0xab, 0x0b, 0x10, 0x16, 0x3c, 0x1b, 0x0a, 0x41, 0xc2,
0x02, 0x82, 0xda, 0xc8, 0xed, 0x7a, 0x9b, 0x50, 0xb8, 0x5b, 0xf2, 0xd4, 0x27, 0x14, 0xdb, 0x2d,
0x05, 0x30, 0x38, 0x84, 0xf6, 0x6a, 0x52, 0x5d, 0x86, 0x87, 0x90, 0x10, 0xc5, 0x87, 0x90, 0x46,
0x60, 0x7f, 0x4f, 0x28, 0xa9, 0xd3, 0xcb, 0x70, 0x7f, 0x4b, 0x59, 0xbc, 0xbf, 0x0d, 0x03, 0xfb,
0x5b, 0x0a, 0xde, 0xe6, 0xfc, 0xf2, 0x90, 0x72, 0x12, 0xee, 0x6f, 0x9f, 0x89, 0xf7, 0x77, 0x87,
0xb5, 0x99, 0x8c, 0xeb, 0x70, 0x32, 0x3f, 0x6f, 0xd2, 0x3a, 0x3f, 0xa7, 0xa3, 0x88, 0x15, 0x03,
0x21, 0x99, 0x0c, 0x0a, 0x2b, 0x9f, 0x3f, 0x5f, 0x49, 0x6e, 0xeb, 0x6e, 0x67, 0x4d, 0x23, 0x57,
0x56, 0xe0, 0xfe, 0x45, 0xb8, 0x7f, 0x11, 0x1c, 0x39, 0x4d, 0x1c, 0xa0, 0xe6, 0x44, 0xd5, 0x70,
0x91, 0xce, 0xca, 0xc6, 0x14, 0xea, 0xcb, 0x21, 0xd6, 0x1d, 0x05, 0x24, 0xaa, 0x0e, 0x52, 0xb4,
0x0b, 0x9a, 0xea, 0x1f, 0x2d, 0xdb, 0xcf, 0x1a, 0xb0, 0xa0, 0xe9, 0xf6, 0x76, 0x08, 0x64, 0x41,
0x0b, 0x93, 0x70, 0x28, 0xec, 0xd5, 0x6c, 0x5e, 0x35, 0x3d, 0x43, 0x01, 0x40, 0xf1, 0xa1, 0xd0,
0x85, 0x95, 0xcf, 0x77, 0xc9, 0xef, 0xba, 0xc3, 0xcf, 0x6d, 0xec, 0x0d, 0x7c, 0x4c, 0x85, 0x9a,
0x78, 0x3c, 0x14, 0xb7, 0x29, 0x9d, 0xf6, 0xcc, 0x77, 0x28, 0x27, 0x79, 0xd1, 0x8c, 0x1e, 0x86,
0x6d, 0x68, 0x39, 0x92, 0xd2, 0x85, 0x38, 0x18, 0xdf, 0x76, 0xe6, 0x55, 0x91, 0xa7, 0xdd, 0xb3,
0x5c, 0xa5, 0x6b, 0xc4, 0xf1, 0xf8, 0xe6, 0x62, 0x30, 0x5e, 0x4f, 0x28, 0x97, 0xff, 0x39, 0x5d,
0x56, 0x34, 0x1c, 0xaf, 0x3d, 0x24, 0x1e, 0xaf, 0x21, 0x0a, 0xeb, 0x33, 0xa1, 0xfc, 0x80, 0x2c,
0xd9, 0x1c, 0x89, 0xd7, 0x46, 0x1c, 0xaf, 0x8f, 0x8b, 0xd9, 0xac, 0xca, 0x78, 0xd8, 0x2f, 0x39,
0xad, 0x4b, 0x52, 0xec, 0x16, 0x64, 0xda, 0x8c, 0x90, 0x18, 0xe3, 0x53, 0x48, 0x56, 0x85, 0xd3,
0x81, 0x66, 0xdc, 0x6f, 0x76, 0xc9, 0x82, 0xd5, 0x39, 0xc7, 0x9b, 0xd1, 0x22, 0xbd, 0xcd, 0xe8,
0xa1, 0x41, 0x6f, 0x5b, 0x75, 0x7a, 0x99, 0x2f, 0x68, 0x16, 0xf1, 0xa6, 0x91, 0x01, 0xde, 0x1c,
0x34, 0xd0, 0x69, 0x13, 0x36, 0xaf, 0x53, 0x8a, 0x76, 0x9a, 0x14, 0xf7, 0x76, 0x9a, 0xc1, 0x94,
0x87, 0xbf, 0x59, 0x49, 0x7e, 0x4f, 0x4a, 0xdd, 0x03, 0xd6, 0x1d, 0xd2, 0x5c, 0x9e, 0x33, 0x52,
0x67, 0xa3, 0xcf, 0x42, 0x76, 0x82, 0xa8, 0x71, 0xfd, 0xec, 0x26, 0x2a, 0xb0, 0x59, 0x0f, 0xf2,
0xc6, 0x99, 0x71, 0xc1, 0x66, 0xf5, 0x90, 0x78, 0xb3, 0x42, 0x14, 0x06, 0x10, 0x21, 0x97, 0x87,
0x19, 0x0f, 0x51, 0x7d, 0xff, 0x44, 0x63, 0xb5, 0x97, 0x83, 0xf1, 0xb1, 0x15, 0xfa, 0xa3, 0x65,
0x03, 0xb3, 0x11, 0x1e, 0x31, 0xe3, 0xa1, 0x38, 0xea, 0xd9, 0xcc, 0x8a, 0xb8, 0xe7, 0xce, 0xcc,
0x18, 0x0f, 0xc5, 0x11, 0xcf, 0x4e, 0x58, 0x8b, 0x79, 0x0e, 0x84, 0xb6, 0xf1, 0x50, 0x1c, 0x66,
0x5f, 0x8a, 0xd1, 0xeb, 0xc2, 0x93, 0x88, 0x1d, 0xb8, 0x36, 0xac, 0x0d, 0x62, 0x95, 0xc3, 0xbf,
0x5b, 0x49, 0xbe, 0x6f, 0x3d, 0x1e, 0xb2, 0x2c, 0xbf, 0x58, 0x4a, 0xe8, 0x0d, 0x29, 0xe6, 0xb4,
0x19, 0x3d, 0xc3, 0xac, 0x75, 0x59, 0x53, 0x82, 0xe7, 0x37, 0xd2, 0x81, 0x73, 0x67, 0xab, 0xaa,
0x8a, 0xe5, 0x29, 0x9d, 0x55, 0x05, 0x3a, 0x77, 0x3c, 0x24, 0x3e, 0x77, 0x20, 0x0a, 0xb3, 0xf2,
0x53, 0xd6, 0xe6, 0xfc, 0xc1, 0xac, 0x5c, 0x88, 0xe2, 0x59, 0xb9, 0x46, 0x60, 0xae, 0x74, 0xca,
0xb6, 0x59, 0x51, 0xd0, 0x94, 0x77, 0x1f, 0xd2, 0x1a, 0x4d, 0x4b, 0xc4, 0x73, 0x25, 0x40, 0xda,
0xf3, 0x0c, 0xbd, 0x87, 0x24, 0x35, 0x7d, 0xb9, 0x3c, 0xc8, 0xcb, 0xab, 0x51, 0x38, 0x2d, 0xb0,
0x00, 0x72, 0x9e, 0x11, 0x04, 0xe1, 0x5e, 0xf5, 0xac, 0xcc, 0x58, 0x78, 0xaf, 0xda, 0x4a, 0xe2,
0x7b, 0x55, 0x45, 0x40, 0x93, 0x27, 0x14, 0x33, 0xd9, 0x4a, 0xe2, 0x26, 0x15, 0x11, 0x0a, 0x85,
0xea, 0xd4, 0x1b, 0x0d, 0x85, 0xe0, 0x9c, 0x7b, 0xb5, 0x97, 0x83, 0x23, 0x54, 0x6f, 0x5a, 0x77,
0x29, 0x4f, 0x2f, 0xc3, 0x23, 0xd4, 0x43, 0xe2, 0x23, 0x14, 0xa2, 0xb0, 0x4a, 0xa7, 0xcc, 0x6c,
0xba, 0x1f, 0x86, 0xc7, 0x47, 0x67, 0xc3, 0xbd, 0xda, 0xcb, 0xc1, 0x6d, 0xe4, 0xfe, 0x4c, 0xb4,
0x59, 0x70, 0x90, 0x4b, 0x59, 0x7c, 0x1b, 0x69, 0x18, 0x58, 0x7a, 0x29, 0x68, 0x9b, 0x33, 0x5c,
0x7a, 0x2b, 0x8f, 0x97, 0xde, 0xe3, 0x94, 0x93, 0x7f, 0x33, 0xdb, 0x38, 0x29, 0x3d, 0x62, 0xed,
0x1c, 0x79, 0x43, 0x8a, 0x3c, 0x23, 0x9c, 0x9e, 0xb2, 0x2b, 0x5a, 0x86, 0x77, 0x4c, 0xaa, 0xb4,
0x92, 0x1f, 0x7b, 0x0a, 0xf1, 0x1d, 0x53, 0x5c, 0x11, 0x8e, 0x13, 0x49, 0x9f, 0x35, 0x74, 0x9b,
0x34, 0x48, 0x24, 0xf3, 0x90, 0xf8, 0x38, 0x81, 0x28, 0xcc, 0x57, 0xa5, 0xfc, 0xd5, 0xbb, 0x8a,
0xd6, 0x39, 0x2d, 0x53, 0x1a, 0xce, 0x57, 0x21, 0x15, 0xcf, 0x57, 0x03, 0x74, 0xe7, 0x98, 0xc6,
0x04, 0xa7, 0xee, 0x3d, 0x0b, 0x48, 0x44, 0xee, 0x59, 0x20, 0x28, 0xac, 0xa4, 0x05, 0x82, 0x47,
0x9d, 0x1d, 0x2b, 0xd1, 0xa3, 0x4e, 0x9c, 0xee, 0x1c, 0x7e, 0x19, 0x66, 0xd2, 0x4e, 0x93, 0x9e,
0xa2, 0x4f, 0xdc, 0xe9, 0xb2, 0x36, 0x88, 0x0d, 0x9f, 0xb6, 0x9d, 0xd0, 0x82, 0x88, 0x25, 0x24,
0x72, 0xa4, 0xa5, 0x99, 0x21, 0xa7, 0x6d, 0x0e, 0xab, 0x1c, 0xfe, 0xd5, 0x4a, 0xf2, 0x49, 0xc8,
0xe3, 0xeb, 0x4a, 0xf8, 0x7d, 0xda, 0x6f, 0x4b, 0x92, 0xc8, 0x45, 0x92, 0xb8, 0x86, 0x2a, 0xc3,
0x9f, 0x25, 0x1f, 0x6b, 0x91, 0xbd, 0x67, 0xa2, 0x0a, 0xe0, 0x27, 0x50, 0xa6, 0xfc, 0x90, 0x33,
0xee, 0x37, 0x07, 0xf3, 0x76, 0x6f, 0xe2, 0x97, 0xab, 0x01, 0x7b, 0x13, 0x63, 0x43, 0x89, 0x91,
0xbd, 0x49, 0x00, 0xb3, 0xa7, 0x1a, 0x6e, 0xf5, 0xde, 0xe6, 0xfc, 0x52, 0xe4, 0x3e, 0xe0, 0x54,
0xc3, 0x2b, 0xab, 0x81, 0x90, 0x53, 0x0d, 0x14, 0x86, 0xd9, 0x81, 0x06, 0xdb, 0xb9, 0x19, 0x8a,
0xab, 0xc6, 0x90, 0x3b, 0x33, 0x1f, 0xf5, 0x83, 0x70, 0xbc, 0x6a, 0xb1, 0xda, 0x86, 0x3c, 0x89,
0x59, 0x00, 0x5b, 0x91, 0xb5, 0x41, 0xac, 0x72, 0xf8, 0x17, 0xc9, 0xf7, 0x3a, 0x15, 0xdb, 0xa5,
0x84, 0xcf, 0x6b, 0x9a, 0x8d, 0x36, 0x7b, 0xca, 0xad, 0x41, 0xe3, 0xfa, 0xe9, 0x70, 0x85, 0x4e,
0xbe, 0xac, 0x39, 0x39, 0xac, 0x4c, 0x19, 0x9e, 0xc5, 0x4c, 0xfa, 0x6c, 0x34, 0x5f, 0xc6, 0x75,
0x3a, 0x5b, 0x5e, 0x77, 0x74, 0x6d, 0x2d, 0x48, 0x5e, 0x88, 0x47, 0x4e, 0x9f, 0xc5, 0x8c, 0x7a,
0x68, 0x74, 0xcb, 0x8b, 0xaa, 0x74, 0x22, 0xb3, 0x98, 0xe3, 0xce, 0x56, 0x69, 0x1d, 0x8f, 0x04,
0x81, 0x9d, 0xd2, 0xc6, 0x40, 0x5a, 0xb9, 0xe5, 0xfa, 0xa8, 0xb0, 0xfd, 0xd9, 0x1d, 0xe4, 0x21,
0xaf, 0x4a, 0x35, 0x30, 0xd2, 0x37, 0x06, 0xd2, 0xca, 0xeb, 0x9f, 0x27, 0x1f, 0x77, 0xbd, 0xaa,
0x85, 0x68, 0xb3, 0xd7, 0x14, 0x58, 0x8b, 0x9e, 0x0e, 0x57, 0xb0, 0xdb, 0x8b, 0xaf, 0xf2, 0x86,
0xb3, 0x7a, 0x39, 0xb9, 0x64, 0xd7, 0xfa, 0xfe, 0xb6, 0x3f, 0x5b, 0x15, 0x30, 0x76, 0x08, 0x64,
0x7b, 0x11, 0x26, 0x3b, 0xae, 0xec, 0x3d, 0xef, 0x06, 0x71, 0xe5, 0x10, 0x3d, 0xae, 0x7c, 0xd2,
0xc6, 0x2a, 0x5d, 0x2b, 0x7b, 0x29, 0x7d, 0x35, 0x5c, 0xd4, 0xee, 0xc5, 0xf4, 0x47, 0xfd, 0xa0,
0xcd, 0x58, 0x94, 0x78, 0x27, 0xbf, 0xb8, 0x30, 0x75, 0x0a, 0x97, 0xd4, 0x45, 0x90, 0x8c, 0x05,
0x41, 0x6d, 0x02, 0xbc, 0x9b, 0x17, 0x54, 0x9c, 0xae, 0xbf, 0xbe, 0xb8, 0x28, 0x18, 0xc9, 0x40,
0x02, 0xdc, 0x8a, 0xc7, 0xae, 0x1c, 0x49, 0x80, 0x43, 0x9c, 0xbd, 0xfe, 0xd5, 0x4a, 0x4f, 0x68,
0xca, 0xca, 0x34, 0x2f, 0xe0, 0x75, 0x36, 0xa1, 0x69, 0x84, 0xc8, 0xf5, 0xaf, 0x0e, 0x64, 0x17,
0xc6, 0x56, 0xd4, 0x4e, 0x7b, 0x5d, 0xfe, 0x07, 0x5d, 0x45, 0x47, 0x8c, 0x2c, 0x8c, 0x01, 0xcc,
0xee, 0x03, 0x5b, 0xe1, 0x59, 0x25, 0x8c, 0xdf, 0xe9, 0x6a, 0x49, 0x09, 0xb2, 0x0f, 0xf4, 0x09,
0xbb, 0x9f, 0x69, 0x7f, 0xdf, 0x61, 0xd7, 0xa5, 0x30, 0x7a, 0xaf, 0xab, 0xa2, 0x65, 0xc8, 0x7e,
0x06, 0x32, 0xca, 0xf0, 0x4f, 0x92, 0x5f, 0x15, 0x86, 0x6b, 0x56, 0x8d, 0x6e, 0x05, 0x14, 0x6a,
0xe7, 0xe6, 0xd9, 0x6d, 0x54, 0x6e, 0x2f, 0x50, 0x9a, 0xb1, 0x71, 0xd6, 0x90, 0x29, 0x1d, 0xdd,
0x47, 0x7a, 0x5c, 0x48, 0x91, 0x0b, 0x94, 0x5d, 0xca, 0x1f, 0x15, 0x47, 0x2c, 0x53, 0xd6, 0x03,
0x35, 0x34, 0xc2, 0xd8, 0xa8, 0x70, 0x21, 0x9b, 0xcc, 0x1c, 0x91, 0x45, 0x3e, 0x35, 0x0b, 0x8e,
0x8c, 0x5b, 0x0d, 0x48, 0x66, 0x2c, 0x33, 0x76, 0x20, 0x24, 0x99, 0x41, 0x61, 0xe5, 0xf3, 0x5f,
0x57, 0x92, 0x3b, 0x96, 0xd9, 0xd3, 0x27, 0x67, 0xfb, 0xe5, 0x05, 0x6b, 0x53, 0x9f, 0x83, 0xbc,
0xbc, 0x6a, 0x46, 0x5f, 0x60, 0x26, 0xc3, 0xbc, 0x29, 0xca, 0x97, 0x37, 0xd6, 0xb3, 0x59, 0xab,
0x3e, 0x56, 0xb2, 0xcf, 0x96, 0xa5, 0x06, 0xc8, 0x5a, 0xcd, 0xe9, 0x13, 0xe4, 0x90, 0xac, 0x35,
0xc6, 0xdb, 0x2e, 0x36, 0xce, 0x0b, 0x56, 0xc2, 0x2e, 0xb6, 0x16, 0x5a, 0x21, 0xd2, 0xc5, 0x1d,
0xc8, 0xc6, 0x63, 0x2d, 0x92, 0x27, 0x20, 0x5b, 0x45, 0x01, 0xe2, 0xb1, 0x51, 0x35, 0x00, 0x12,
0x8f, 0x83, 0xa0, 0xf2, 0x73, 0x92, 0x7c, 0xa7, 0x6d, 0xd2, 0xe3, 0x9a, 0x2e, 0x72, 0x0a, 0xaf,
0x41, 0x38, 0x12, 0x64, 0xfe, 0xfb, 0x84, 0x9d, 0x59, 0x67, 0x65, 0x53, 0x15, 0xa4, 0xb9, 0x54,
0x0f, 0xc6, 0xfd, 0x3a, 0x6b, 0x21, 0x7c, 0x34, 0xfe, 0xa0, 0x87, 0xb2, 0x41, 0x5d, 0xcb, 0x4c,
0x88, 0x79, 0x18, 0x56, 0xed, 0x84, 0x99, 0xd5, 0x5e, 0xce, 0x9e, 0x3e, 0xef, 0x91, 0xa2, 0xa0,
0xf5, 0x52, 0xcb, 0x0e, 0x49, 0x99, 0x5f, 0xd0, 0x86, 0x83, 0xd3, 0x67, 0x45, 0x8d, 0x21, 0x86,
0x9c, 0x3e, 0x47, 0x70, 0x9b, 0xcd, 0x03, 0xcf, 0xfb, 0x65, 0x46, 0xdf, 0x81, 0x6c, 0x1e, 0xda,
0x11, 0x0c, 0x92, 0xcd, 0x63, 0xac, 0x3d, 0x85, 0x7d, 0x59, 0xb0, 0xf4, 0x4a, 0x2d, 0x01, 0x7e,
0x07, 0x0b, 0x09, 0x5c, 0x03, 0xee, 0xc5, 0x10, 0xbb, 0x08, 0x08, 0xc1, 0x09, 0xad, 0x0a, 0x92,
0xc2, 0xbb, 0x30, 0x52, 0x47, 0xc9, 0x90, 0x45, 0x00, 0x32, 0xa0, 0xb8, 0xea, 0x8e, 0x4d, 0xa8,
0xb8, 0xe0, 0x8a, 0xcd, 0xbd, 0x18, 0x62, 0x97, 0x41, 0x21, 0x98, 0x54, 0x45, 0xce, 0xc1, 0x34,
0x90, 0x1a, 0x42, 0x82, 0x4c, 0x03, 0x9f, 0x00, 0x26, 0x0f, 0x69, 0x3d, 0xa5, 0x41, 0x93, 0x42,
0x12, 0x35, 0xa9, 0x09, 0x7b, 0x65, 0x52, 0xd6, 0x9d, 0x55, 0x4b, 0x70, 0x65, 0x52, 0x55, 0x8b,
0x55, 0x4b, 0xe4, 0xca, 0xa4, 0x07, 0x80, 0x22, 0x1e, 0x93, 0x86, 0x87, 0x8b, 0x28, 0x24, 0xd1,
0x22, 0x6a, 0xc2, 0xae, 0xd1, 0xb2, 0x88, 0x73, 0x0e, 0xd6, 0x68, 0x55, 0x00, 0xe7, 0x69, 0xf0,
0x6d, 0x54, 0x6e, 0x23, 0x89, 0xec, 0x15, 0xca, 0x77, 0x73, 0x5a, 0x64, 0x0d, 0x88, 0x24, 0xaa,
0xdd, 0xb5, 0x14, 0x89, 0x24, 0x5d, 0x0a, 0x0c, 0x25, 0x75, 0x56, 0x1d, 0xaa, 0x1d, 0x38, 0xa6,
0xbe, 0x17, 0x43, 0x6c, 0x7c, 0xd2, 0x85, 0xde, 0x26, 0x75, 0x9d, 0xb7, 0x8b, 0xff, 0xc3, 0x70,
0x81, 0xb4, 0x1c, 0x89, 0x4f, 0x21, 0x0e, 0x4c, 0x2f, 0x1d, 0xb8, 0x43, 0x05, 0x83, 0xa1, 0xfb,
0xd3, 0x28, 0x63, 0x33, 0x4e, 0x21, 0x71, 0x1e, 0x67, 0x86, 0x5a, 0x33, 0xf0, 0x34, 0xf3, 0x61,
0x1f, 0xe6, 0xbc, 0xd2, 0x60, 0x5c, 0x1c, 0xb2, 0x05, 0x3d, 0x65, 0xaf, 0xde, 0xe5, 0x0d, 0xcf,
0xcb, 0xa9, 0x5a, 0xb9, 0x9f, 0x23, 0x96, 0x42, 0x30, 0xf2, 0x4a, 0x43, 0xaf, 0x92, 0x4d, 0x20,
0x40, 0x59, 0x8e, 0xe8, 0x75, 0x30, 0x81, 0x80, 0x16, 0x0d, 0x87, 0x24, 0x10, 0x31, 0xde, 0x9e,
0xa3, 0x18, 0xe7, 0xea, 0xbd, 0xcf, 0x53, 0xa6, 0x73, 0x39, 0xcc, 0x1a, 0x04, 0x91, 0xad, 0x6c,
0x54, 0xc1, 0xee, 0x2f, 0x8d, 0x7f, 0x3b, 0xc5, 0x1e, 0x21, 0x76, 0xba, 0xd3, 0xec, 0xf1, 0x00,
0x32, 0xe0, 0xca, 0x3e, 0x93, 0xc7, 0x5c, 0x75, 0x1f, 0xc9, 0x3f, 0x1e, 0x40, 0x3a, 0x67, 0x32,
0x6e, 0xb5, 0x5e, 0x92, 0xf4, 0x6a, 0x5a, 0xb3, 0x79, 0x99, 0x6d, 0xb3, 0x82, 0xd5, 0xe0, 0x4c,
0xc6, 0x2b, 0x35, 0x40, 0x91, 0x33, 0x99, 0x1e, 0x15, 0x9b, 0xc1, 0xb9, 0xa5, 0xd8, 0x2a, 0xf2,
0x29, 0xdc, 0x51, 0x7b, 0x86, 0x04, 0x80, 0x64, 0x70, 0x41, 0x30, 0x30, 0x88, 0xe4, 0x8e, 0x9b,
0xe7, 0x29, 0x29, 0xa4, 0xbf, 0x4d, 0xdc, 0x8c, 0x07, 0xf6, 0x0e, 0xa2, 0x80, 0x42, 0xa0, 0x9e,
0xa7, 0xf3, 0xba, 0xdc, 0x2f, 0x39, 0x43, 0xeb, 0xa9, 0x81, 0xde, 0x7a, 0x3a, 0x20, 0x08, 0xab,
0xa7, 0xf4, 0x5d, 0x5b, 0x9a, 0xf6, 0x9f, 0x50, 0x58, 0x6d, 0x7f, 0x1f, 0x2b, 0x79, 0x2c, 0xac,
0x02, 0x0e, 0x54, 0x46, 0x39, 0x91, 0x03, 0x26, 0xa2, 0xed, 0x0f, 0x93, 0x47, 0xfd, 0x60, 0xd8,
0xcf, 0x84, 0x2f, 0x0b, 0x1a, 0xf3, 0x23, 0x80, 0x21, 0x7e, 0x34, 0x68, 0x8f, 0x5b, 0xbc, 0xfa,
0x5c, 0xd2, 0xf4, 0xaa, 0x73, 0xc5, 0xc8, 0x2f, 0xa8, 0x44, 0x90, 0xe3, 0x16, 0x04, 0x0d, 0x77,
0xd1, 0x7e, 0xca, 0xca, 0x58, 0x17, 0xb5, 0xf2, 0x21, 0x5d, 0xa4, 0x38, 0xbb, 0xf9, 0x35, 0x52,
0x35, 0x32, 0x65, 0x37, 0xad, 0x21, 0x16, 0x5c, 0x08, 0xd9, 0xfc, 0xa2, 0xb0, 0xcd, 0xc9, 0xa1,
0xcf, 0xc3, 0xee, 0xfd, 0xeb, 0x8e, 0x95, 0x43, 0xfc, 0xfe, 0x35, 0xc6, 0xe2, 0x95, 0x94, 0x63,
0xa4, 0xc7, 0x8a, 0x3f, 0x4e, 0xd6, 0x87, 0xc1, 0x76, 0xcb, 0xe3, 0xf9, 0xdc, 0x2e, 0x28, 0xa9,
0xa5, 0xd7, 0x8d, 0x88, 0x21, 0x8b, 0x21, 0x5b, 0x9e, 0x08, 0x0e, 0x42, 0x98, 0xe7, 0x79, 0x9b,
0x95, 0x9c, 0x96, 0x3c, 0x14, 0xc2, 0x7c, 0x63, 0x0a, 0x8c, 0x85, 0x30, 0x4c, 0x01, 0x8c, 0x5b,
0x71, 0x1e, 0x44, 0xf9, 0x11, 0x99, 0x05, 0x33, 0x36, 0x79, 0xd6, 0x23, 0xe5, 0xb1, 0x71, 0x0b,
0x38, 0xe7, 0x21, 0x9f, 0xeb, 0xe5, 0x94, 0xd4, 0x53, 0x73, 0xba, 0x91, 0x8d, 0x9e, 0xe2, 0x76,
0x7c, 0x12, 0x79, 0xc8, 0x17, 0xd7, 0x00, 0x61, 0x67, 0x7f, 0x46, 0xa6, 0xa6, 0xa6, 0x81, 0x1a,
0x08, 0x79, 0xa7, 0xaa, 0x8f, 0xfa, 0x41, 0xe0, 0xe7, 0x4d, 0x9e, 0x51, 0x16, 0xf1, 0x23, 0xe4,
0x43, 0xfc, 0x40, 0x10, 0x64, 0x6f, 0x6d, 0xbd, 0xe5, 0x8e, 0x6e, 0xab, 0xcc, 0xd4, 0x3e, 0x76,
0x8c, 0x34, 0x0f, 0xe0, 0x62, 0xd9, 0x1b, 0xc2, 0x83, 0x39, 0xaa, 0x0f, 0x68, 0x63, 0x73, 0xd4,
0x9c, 0xbf, 0x0e, 0x99, 0xa3, 0x21, 0x58, 0xf9, 0xfc, 0x99, 0x9a, 0xa3, 0x3b, 0x84, 0x93, 0x36,
0x6f, 0x7f, 0x93, 0xd3, 0x6b, 0xb5, 0x11, 0x0e, 0xd4, 0x57, 0x53, 0x63, 0xf1, 0xe2, 0x1d, 0xd8,
0x15, 0x6f, 0x0e, 0xe6, 0x23, 0xbe, 0xd5, 0x0e, 0xa1, 0xd7, 0x37, 0xd8, 0x2a, 0x6c, 0x0e, 0xe6,
0x23, 0xbe, 0xd5, 0x1b, 0xbd, 0xbd, 0xbe, 0xc1, 0x6b, 0xbd, 0x9b, 0x83, 0x79, 0xe5, 0xfb, 0xaf,
0xf5, 0xc4, 0x75, 0x9d, 0xb7, 0x79, 0x58, 0xca, 0xf3, 0x05, 0x0d, 0xa5, 0x93, 0xbe, 0x3d, 0x83,
0xc6, 0xd2, 0x49, 0x5c, 0xc5, 0xf9, 0x0c, 0x4c, 0xa8, 0x14, 0xc7, 0xac, 0xc9, 0xc5, 0x43, 0xfa,
0xe7, 0x03, 0x8c, 0x6a, 0x38, 0xb6, 0x69, 0x8a, 0x29, 0xd9, 0xc7, 0x8d, 0x1e, 0x6a, 0x6f, 0x14,
0xaf, 0x47, 0xec, 0x75, 0x2f, 0x16, 0x6f, 0x0c, 0xa4, 0xed, 0x83, 0x3f, 0x8f, 0x71, 0x9f, 0x38,
0xc6, 0x7a, 0x35, 0xf8, 0xd0, 0xf1, 0xe9, 0x70, 0x05, 0xe5, 0xfe, 0x6f, 0xf5, 0xbe, 0x02, 0xfa,
0x57, 0x93, 0xe0, 0xd9, 0x10, 0x8b, 0x60, 0x22, 0x3c, 0xbf, 0x91, 0x8e, 0x2a, 0xc8, 0x3f, 0xea,
0x0d, 0xb4, 0x46, 0xc5, 0x7b, 0x15, 0xaf, 0xeb, 0x8c, 0xd6, 0x6a, 0x4e, 0xc4, 0xba, 0xd5, 0xc2,
0x70, 0x66, 0xbc, 0xb8, 0xa1, 0x96, 0xf3, 0x51, 0x20, 0x0f, 0x56, 0xef, 0xff, 0x39, 0xe5, 0x89,
0x59, 0x76, 0x68, 0x58, 0xa0, 0x2f, 0x6e, 0xaa, 0x86, 0xcd, 0x15, 0x07, 0x16, 0xdf, 0x18, 0x78,
0x3e, 0xd0, 0xb0, 0xf7, 0xd5, 0x81, 0xcf, 0x6f, 0xa6, 0xa4, 0xca, 0xf2, 0x5f, 0x2b, 0xc9, 0x03,
0x8f, 0xb5, 0xcf, 0x13, 0xc0, 0xa9, 0xc7, 0x8f, 0x23, 0xf6, 0x31, 0x25, 0x53, 0xb8, 0xdf, 0xff,
0xe5, 0x94, 0xed, 0x17, 0x74, 0x3c, 0x95, 0xdd, 0xbc, 0xe0, 0xb4, 0xee, 0x7e, 0x41, 0xc7, 0xb7,
0x2b, 0xa9, 0x31, 0xfe, 0x05, 0x9d, 0x08, 0xee, 0x7c, 0x41, 0x27, 0xe0, 0x39, 0xf8, 0x05, 0x9d,
0xa0, 0xb5, 0xe8, 0x17, 0x74, 0xe2, 0x1a, 0x58, 0x78, 0xd7, 0x45, 0x90, 0xe7, 0xd6, 0x83, 0x2c,
0xfa, 0xc7, 0xd8, 0xcf, 0x6e, 0xa2, 0x82, 0x2c, 0x70, 0x92, 0x13, 0xf7, 0xdc, 0x06, 0xb4, 0xa9,
0x77, 0xd7, 0x6d, 0x73, 0x30, 0xaf, 0x7c, 0xff, 0x54, 0xed, 0x6e, 0x4c, 0x38, 0x67, 0xb5, 0xf8,
0x7a, 0xd2, 0x5a, 0x2c, 0x3c, 0xb7, 0x16, 0xdc, 0x9e, 0x5f, 0x1f, 0x06, 0x23, 0xd5, 0x6d, 0x09,
0xd5, 0xe9, 0xe3, 0x3e, 0x43, 0xa0, 0xcb, 0x37, 0x07, 0xf3, 0xc8, 0x32, 0x22, 0x7d, 0xcb, 0xde,
0x1e, 0x60, 0xcc, 0xef, 0xeb, 0xa7, 0xc3, 0x15, 0x94, 0xfb, 0x85, 0x4a, 0x1b, 0x5d, 0xf7, 0xa2,
0x9f, 0x37, 0xfa, 0x4c, 0x4d, 0xbc, 0x6e, 0x1e, 0x0f, 0xc5, 0x63, 0x09, 0x84, 0xbb, 0x84, 0xf6,
0x25, 0x10, 0xc1, 0x65, 0xf4, 0xf3, 0x9b, 0x29, 0xa9, 0xb2, 0xfc, 0xcb, 0x4a, 0x72, 0x1b, 0x2d,
0x8b, 0x1a, 0x07, 0x5f, 0x0c, 0xb5, 0x0c, 0xc6, 0xc3, 0x97, 0x37, 0xd6, 0x53, 0x85, 0xfa, 0xf7,
0x95, 0xe4, 0x4e, 0xa4, 0x50, 0x72, 0x80, 0xdc, 0xc0, 0xba, 0x3f, 0x50, 0x7e, 0x78, 0x73, 0x45,
0x6c, 0xb9, 0x77, 0xf1, 0x49, 0xf7, 0xd3, 0x32, 0x11, 0xdb, 0x13, 0xfc, 0xd3, 0x32, 0xfd, 0x5a,
0xf0, 0x90, 0x87, 0x9c, 0xeb, 0x4d, 0x57, 0xf0, 0x90, 0x47, 0xdc, 0x50, 0x03, 0x7b, 0x8e, 0xd5,
0x5e, 0x2e, 0xe4, 0xe4, 0xd5, 0xbb, 0x8a, 0x94, 0x19, 0xee, 0x44, 0xca, 0xfb, 0x9d, 0x18, 0x0e,
0x1e, 0x8e, 0xb5, 0xd2, 0x13, 0xa6, 0x37, 0x52, 0x8f, 0x31, 0x7d, 0x83, 0x44, 0x0f, 0xc7, 0x3a,
0x28, 0xe2, 0x4d, 0x65, 0x8d, 0x31, 0x6f, 0x20, 0x59, 0x7c, 0x32, 0x04, 0x05, 0x29, 0xba, 0xf1,
0x66, 0xce, 0xdc, 0xd7, 0x63, 0x56, 0x3a, 0xe7, 0xee, 0x1b, 0x03, 0x69, 0xc4, 0xed, 0x84, 0xf2,
0xaf, 0x28, 0xc9, 0x68, 0x1d, 0x75, 0x6b, 0xa8, 0x41, 0x6e, 0x5d, 0x3a, 0xe4, 0x76, 0x9b, 0x15,
0xf3, 0x59, 0xa9, 0x3a, 0x13, 0x75, 0xeb, 0x52, 0xfd, 0x6e, 0x01, 0x0d, 0x8f, 0x05, 0xad, 0x5b,
0x91, 0x5e, 0x3e, 0x89, 0x9b, 0xf1, 0xb2, 0xca, 0xb5, 0x41, 0x2c, 0x5e, 0x4f, 0x35, 0x8c, 0x7a,
0xea, 0x09, 0x46, 0xd2, 0xc6, 0x40, 0x1a, 0x9e, 0xcf, 0x39, 0x6e, 0xcd, 0x78, 0xda, 0xec, 0xb1,
0xd5, 0x19, 0x52, 0x4f, 0x87, 0x2b, 0xc0, 0xd3, 0x50, 0x35, 0xaa, 0x0e, 0xf2, 0x86, 0xef, 0xe6,
0x45, 0x31, 0x5a, 0x8b, 0x0c, 0x13, 0x0d, 0x45, 0x4f, 0x43, 0x03, 0x30, 0x32, 0x92, 0xf5, 0xe9,
0x61, 0x39, 0xea, 0xb3, 0x23, 0xa8, 0x41, 0x23, 0xd9, 0xa5, 0xc1, 0x89, 0x96, 0xd3, 0xd4, 0xa6,
0xb6, 0xe3, 0x78, 0xc3, 0x75, 0x2a, 0xbc, 0x39, 0x98, 0x07, 0x8f, 0xdb, 0x05, 0x25, 0x56, 0x96,
0xfb, 0x98, 0x09, 0x6f, 0x25, 0x79, 0xd0, 0x43, 0x81, 0x53, 0x41, 0x39, 0x8d, 0xde, 0xe6, 0xd9,
0x94, 0xf2, 0xe0, 0x93, 0x22, 0x17, 0x88, 0x3e, 0x29, 0x02, 0x20, 0xe8, 0x3a, 0xf9, 0xbb, 0x39,
0x0e, 0xdd, 0xcf, 0x42, 0x5d, 0xa7, 0x94, 0x1d, 0x2a, 0xd6, 0x75, 0x41, 0x1a, 0x44, 0x03, 0xe3,
0x56, 0xbd, 0x1a, 0xff, 0x24, 0x66, 0x06, 0xbc, 0x1f, 0xbf, 0x36, 0x88, 0x05, 0x2b, 0x8a, 0x75,
0x98, 0xcf, 0x72, 0x1e, 0x5a, 0x51, 0x1c, 0x1b, 0x2d, 0x12, 0x5b, 0x51, 0xba, 0x28, 0x56, 0xbd,
0x36, 0x47, 0xd8, 0xcf, 0xe2, 0xd5, 0x93, 0xcc, 0xb0, 0xea, 0x19, 0xb6, 0xf3, 0x60, 0xb3, 0x34,
0x43, 0x86, 0x5f, 0xaa, 0xcd, 0x72, 0x60, 0x6c, 0x8b, 0x57, 0x26, 0x21, 0x18, 0x8b, 0x3a, 0x98,
0x02, 0x3c, 0xb0, 0x6f, 0x39, 0xfd, 0xec, 0xb5, 0xaa, 0x28, 0xa9, 0x49, 0x99, 0x06, 0x37, 0xa7,
0xc2, 0x60, 0x87, 0x8c, 0x6d, 0x4e, 0x51, 0x0d, 0xf0, 0xd8, 0xdc, 0x7f, 0xd9, 0x31, 0x30, 0x15,
0xcc, 0x5b, 0x85, 0xfe, 0xbb, 0x8e, 0x8f, 0x07, 0x90, 0xf0, 0xb1, 0xb9, 0x06, 0xcc, 0xc1, 0xb7,
0x74, 0xfa, 0x59, 0xc4, 0x94, 0x8f, 0xc6, 0x36, 0xc2, 0xb8, 0x0a, 0x18, 0xd4, 0x26, 0xc1, 0xa5,
0xfc, 0x27, 0x74, 0x19, 0x1a, 0xd4, 0x36, 0x3f, 0x15, 0x48, 0x6c, 0x50, 0x77, 0x51, 0x90, 0x67,
0xba, 0xfb, 0xa0, 0x87, 0x11, 0x7d, 0x77, 0xeb, 0xb3, 0xda, 0xcb, 0x81, 0x99, 0xb3, 0x93, 0x2f,
0xbc, 0xe7, 0x04, 0x81, 0x82, 0xee, 0xe4, 0x8b, 0xf0, 0x63, 0x82, 0xb5, 0x41, 0x2c, 0x7c, 0x24,
0x4f, 0x38, 0x7d, 0xa7, 0x9f, 0x95, 0x07, 0x8a, 0x2b, 0xe4, 0x9d, 0x87, 0xe5, 0x8f, 0xfa, 0x41,
0x7b, 0x01, 0xf6, 0xb8, 0x66, 0x29, 0x6d, 0x1a, 0xf5, 0xbd, 0x3d, 0xff, 0x86, 0x91, 0x92, 0x8d,
0xc1, 0xd7, 0xf6, 0xee, 0xc7, 0x21, 0x65, 0xfb, 0xab, 0xe4, 0xfd, 0x03, 0x36, 0x9d, 0xd0, 0x32,
0x1b, 0xfd, 0xc0, 0xbf, 0x72, 0xca, 0xa6, 0xe3, 0xf6, 0x67, 0x63, 0xef, 0x16, 0x26, 0xb6, 0x97,
0xe6, 0x76, 0xe8, 0xf9, 0x7c, 0x3a, 0xe1, 0x84, 0x83, 0x4b, 0x73, 0xe2, 0xf7, 0x71, 0x2b, 0x40,
0x2e, 0xcd, 0x79, 0x00, 0xb0, 0x77, 0x5a, 0x53, 0x1a, 0xb4, 0xd7, 0x0a, 0xa2, 0xf6, 0x14, 0x60,
0x57, 0x5d, 0x63, 0xaf, 0x4d, 0x6c, 0xe1, 0x25, 0x37, 0xab, 0x23, 0xa4, 0xc8, 0xaa, 0xdb, 0xa5,
0xec, 0x60, 0x90, 0xd5, 0x17, 0x5f, 0xcc, 0x98, 0xcf, 0x66, 0xa4, 0x5e, 0x82, 0xc1, 0xa0, 0x6a,
0xe9, 0x00, 0xc8, 0x60, 0x08, 0x82, 0x76, 0x94, 0xeb, 0x66, 0x4e, 0xaf, 0xf6, 0x58, 0xcd, 0xe6,
0x3c, 0x2f, 0x29, 0xfc, 0x6a, 0x82, 0x69, 0x50, 0x97, 0x41, 0x46, 0x39, 0xc6, 0xda, 0xac, 0x50,
0x10, 0xf2, 0xfe, 0x9d, 0xf8, 0x6a, 0x6d, 0xc3, 0x59, 0x0d, 0x9f, 0xbf, 0x49, 0x2b, 0x10, 0x42,
0xb2, 0x42, 0x14, 0x06, 0x7d, 0x7f, 0x9c, 0x97, 0xd3, 0x60, 0xdf, 0x1f, 0xbb, 0xdf, 0x7c, 0xbc,
0x83, 0x03, 0x36, 0xbe, 0xcb, 0x46, 0x93, 0x5f, 0x26, 0x52, 0xef, 0x3e, 0x06, 0x1b, 0xdd, 0x25,
0x90, 0xf8, 0x1e, 0x26, 0x81, 0xab, 0xd7, 0x15, 0x2d, 0x69, 0xa6, 0x6f, 0x99, 0x85, 0x5c, 0x79,
0x44, 0xd4, 0x15, 0x24, 0x6d, 0x54, 0x15, 0xf2, 0x93, 0x79, 0x79, 0x5c, 0xb3, 0x8b, 0xbc, 0xa0,
0x35, 0x88, 0xaa, 0x52, 0xdd, 0x91, 0x23, 0x51, 0x35, 0xc4, 0xd9, 0xeb, 0x0a, 0x42, 0xea, 0x7d,
0x7a, 0xf9, 0xb4, 0x26, 0x29, 0xbc, 0xae, 0x20, 0x6d, 0x74, 0x31, 0xe4, 0x24, 0x2d, 0x82, 0x3b,
0x89, 0x81, 0x74, 0x5d, 0x2e, 0xc5, 0xf8, 0x50, 0xef, 0xde, 0x89, 0x2f, 0x21, 0x36, 0x20, 0x31,
0x50, 0xe6, 0x42, 0x24, 0x92, 0x18, 0xc4, 0x35, 0x6c, 0xe8, 0x15, 0xdc, 0x91, 0xba, 0x86, 0x03,
0x42, 0xaf, 0xb4, 0xa1, 0x85, 0x48, 0xe8, 0xed, 0x40, 0x20, 0x20, 0xe9, 0x69, 0x30, 0x0d, 0x06,
0x24, 0x23, 0x8d, 0x06, 0x24, 0x97, 0xb2, 0x81, 0x62, 0xbf, 0xcc, 0x79, 0x4e, 0x8a, 0x09, 0xe5,
0xc7, 0xa4, 0x26, 0x33, 0xca, 0x69, 0x0d, 0x03, 0x85, 0x42, 0xc6, 0x1e, 0x83, 0x04, 0x0a, 0x8c,
0x55, 0x0e, 0xff, 0x20, 0xf9, 0xb0, 0x5d, 0x27, 0x69, 0xa9, 0xfe, 0xc8, 0xc2, 0x2b, 0xf1, 0xd7,
0x59, 0x46, 0x1f, 0x19, 0x1b, 0x13, 0x5e, 0x53, 0x32, 0xd3, 0xb6, 0x3f, 0x30, 0xbf, 0x0b, 0xf0,
0xe9, 0x4a, 0x3b, 0x9e, 0x8f, 0x18, 0xcf, 0x2f, 0xda, 0x6d, 0xa9, 0x7a, 0xe3, 0x06, 0x8c, 0x67,
0x57, 0x3c, 0x8e, 0x7c, 0x47, 0x21, 0xc4, 0xd9, 0x38, 0xed, 0x4a, 0x4f, 0x68, 0x55, 0xc0, 0x38,
0xed, 0x69, 0x0b, 0x00, 0x89, 0xd3, 0x41, 0xd0, 0x4e, 0x4e, 0x57, 0x7c, 0x4a, 0xe3, 0x95, 0x39,
0xa5, 0xc3, 0x2a, 0x73, 0xea, 0xbd, 0xc4, 0x50, 0x24, 0x1f, 0x1e, 0xd2, 0xd9, 0x39, 0xad, 0x9b,
0xcb, 0xbc, 0xda, 0x6b, 0x13, 0x14, 0xc2, 0xe7, 0xf0, 0x35, 0x3f, 0x4b, 0x8c, 0x0d, 0x82, 0x64,
0x71, 0x08, 0x6a, 0x57, 0x02, 0x0b, 0xec, 0x37, 0x47, 0x64, 0x46, 0xc5, 0x57, 0x21, 0xc0, 0x4a,
0xe0, 0x18, 0x71, 0x20, 0x64, 0x25, 0x40, 0x61, 0xe7, 0x7d, 0x28, 0xcb, 0x9c, 0xd0, 0x69, 0x3b,
0xc2, 0xea, 0x63, 0xb2, 0x9c, 0xd1, 0x92, 0x2b, 0x93, 0xe0, 0x0c, 0xdb, 0x31, 0x19, 0xe6, 0x91,
0x33, 0xec, 0x21, 0x7a, 0x4e, 0x68, 0xf2, 0x1a, 0xfe, 0x98, 0xd5, 0x5c, 0xfe, 0x09, 0x95, 0xb3,
0xba, 0x00, 0xa1, 0xc9, 0x6f, 0x54, 0x8f, 0x44, 0x42, 0x53, 0x5c, 0xc3, 0xf9, 0xf6, 0xb8, 0x57,
0x86, 0x37, 0xb4, 0x36, 0xe3, 0xe4, 0xd5, 0x8c, 0xe4, 0x85, 0x1a, 0x0d, 0x3f, 0x8a, 0xd8, 0x46,
0x74, 0x90, 0x6f, 0x8f, 0x0f, 0xd5, 0x75, 0xbe, 0xd6, 0x1e, 0x2f, 0x21, 0x38, 0x52, 0xef, 0xb1,
0x8f, 0x1c, 0xa9, 0xf7, 0x6b, 0xd9, 0x9d, 0xae, 0x65, 0x05, 0xb7, 0x14, 0xc4, 0x36, 0xcb, 0xe0,
0xf9, 0x9a, 0x63, 0x13, 0x80, 0xc8, 0x4e, 0x37, 0xaa, 0x60, 0x53, 0x03, 0x8b, 0xed, 0xe6, 0x25,
0x29, 0xf2, 0x9f, 0xc1, 0xcb, 0xd9, 0x8e, 0x1d, 0x4d, 0x20, 0xa9, 0x41, 0x98, 0x0c, 0xb9, 0xda,
0xa3, 0xfc, 0x34, 0x6f, 0x43, 0xff, 0xa3, 0x48, 0xbb, 0x09, 0xa2, 0xdf, 0x95, 0x43, 0x3a, 0xdf,
0x17, 0x85, 0xcd, 0xba, 0x55, 0x55, 0x93, 0x76, 0x55, 0x3d, 0xa1, 0x29, 0xcd, 0x2b, 0x3e, 0x7a,
0x11, 0x6f, 0x2b, 0x80, 0x23, 0x17, 0x13, 0x06, 0xa8, 0x39, 0x8f, 0xbb, 0xdb, 0x58, 0x32, 0x91,
0x7f, 0x5b, 0xec, 0xac, 0xa1, 0xb5, 0x4a, 0x34, 0xf6, 0x28, 0x07, 0xb3, 0xd3, 0xe1, 0xc6, 0x0e,
0xd8, 0x56, 0x14, 0x99, 0x9d, 0x71, 0x0d, 0x7b, 0x38, 0xe6, 0x70, 0x27, 0xb4, 0x61, 0xc5, 0x82,
0x8a, 0xfb, 0x79, 0xeb, 0xa8, 0x31, 0x87, 0x42, 0x0e, 0xc7, 0x70, 0xda, 0x66, 0x6b, 0x5d, 0xb7,
0x5b, 0xe5, 0x72, 0x1f, 0x5e, 0x31, 0x08, 0x58, 0x12, 0x18, 0x92, 0xad, 0x45, 0x70, 0xe7, 0xf0,
0xb8, 0x66, 0x24, 0x4b, 0x49, 0xc3, 0x8f, 0xc9, 0xb2, 0x60, 0x24, 0x13, 0xeb, 0x3a, 0x3c, 0x3c,
0xd6, 0xcc, 0xd8, 0x85, 0xb0, 0xc3, 0x63, 0x0c, 0x76, 0xb3, 0x33, 0xf1, 0x27, 0xd3, 0xd4, 0xdd,
0x47, 0x98, 0x9d, 0x89, 0xf2, 0xc2, 0x7b, 0x8f, 0xf7, 0xe3, 0x90, 0x7d, 0x67, 0x4b, 0x8a, 0x44,
0x1a, 0x72, 0x27, 0xa4, 0xe3, 0x25, 0x20, 0x77, 0x23, 0x84, 0xfd, 0x8e, 0x83, 0xfc, 0x5d, 0xff,
0xd5, 0x0f, 0xae, 0xbe, 0xc2, 0xbc, 0x1e, 0xd2, 0x75, 0xa1, 0xb1, 0xfb, 0x71, 0xb6, 0x8d, 0x81,
0xb4, 0x4d, 0x33, 0xb7, 0x2f, 0x09, 0xdf, 0xca, 0xb2, 0x43, 0xda, 0x04, 0x5e, 0xc0, 0x6e, 0x85,
0x63, 0x2b, 0x45, 0xd2, 0xcc, 0x2e, 0x65, 0x07, 0x7a, 0x2b, 0x7b, 0x95, 0xe5, 0x5c, 0xc9, 0xf4,
0x8d, 0xe2, 0xf5, 0xae, 0x81, 0x2e, 0x85, 0xd4, 0x0a, 0xa7, 0x6d, 0x2c, 0x6f, 0x99, 0x53, 0x36,
0x9d, 0x16, 0x54, 0x41, 0x27, 0x94, 0xc8, 0x8f, 0xd0, 0x6d, 0x76, 0x6d, 0x05, 0x41, 0x24, 0x96,
0x47, 0x15, 0x6c, 0x1a, 0xd9, 0x62, 0xf2, 0x11, 0x8e, 0x6e, 0xd8, 0xd5, 0xae, 0x19, 0x0f, 0x40,
0xd2, 0xc8, 0x20, 0x68, 0xdf, 0x13, 0x6b, 0xc5, 0x7b, 0x54, 0xb7, 0x04, 0xfc, 0x64, 0x8f, 0x50,
0x76, 0xc4, 0xc8, 0x7b, 0x62, 0x01, 0xcc, 0xee, 0x13, 0x80, 0x87, 0x97, 0xcb, 0xfd, 0x0c, 0xee,
0x13, 0xa0, 0xbe, 0x60, 0x90, 0x7d, 0x02, 0xc6, 0xfa, 0x5d, 0x67, 0xbe, 0x4f, 0x7c, 0x40, 0x1a,
0x5b, 0xb9, 0x40, 0xd7, 0x05, 0xc1, 0x58, 0xd7, 0x61, 0x0a, 0x7e, 0x93, 0xba, 0x5f, 0x3f, 0x0e,
0x34, 0x69, 0xe8, 0xab, 0xc7, 0x0f, 0xfb, 0x30, 0x1b, 0x97, 0xcc, 0x7e, 0x52, 0x5c, 0xf1, 0x09,
0x7f, 0x7d, 0x5e, 0x0a, 0x91, 0xb8, 0xd4, 0x81, 0xa4, 0xed, 0x97, 0x77, 0xff, 0xfb, 0x9b, 0x5b,
0x2b, 0xbf, 0xf8, 0xe6, 0xd6, 0xca, 0xff, 0x7e, 0x73, 0x6b, 0xe5, 0xe7, 0xdf, 0xde, 0x7a, 0xef,
0x17, 0xdf, 0xde, 0x7a, 0xef, 0x7f, 0xbe, 0xbd, 0xf5, 0xde, 0xd7, 0xef, 0xab, 0x3f, 0xa5, 0x79,
0xfe, 0x2b, 0xe2, 0x0f, 0x62, 0x3e, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xbb, 0xf9, 0xe5,
0xb2, 0x6e, 0x73, 0x00, 0x00,
}
// This is a compile-time assertion to ensure that this generated file
@ -630,7 +632,9 @@ type ClientCommandsHandler interface {
DebugRunProfiler(context.Context, *pb.RpcDebugRunProfilerRequest) *pb.RpcDebugRunProfilerResponse
DebugAccountSelectTrace(context.Context, *pb.RpcDebugAccountSelectTraceRequest) *pb.RpcDebugAccountSelectTraceResponse
DebugAnystoreObjectChanges(context.Context, *pb.RpcDebugAnystoreObjectChangesRequest) *pb.RpcDebugAnystoreObjectChangesResponse
MetricsSetParameters(context.Context, *pb.RpcMetricsSetParametersRequest) *pb.RpcMetricsSetParametersResponse
DebugNetCheck(context.Context, *pb.RpcDebugNetCheckRequest) *pb.RpcDebugNetCheckResponse
DebugExportLog(context.Context, *pb.RpcDebugExportLogRequest) *pb.RpcDebugExportLogResponse
InitialSetParameters(context.Context, *pb.RpcInitialSetParametersRequest) *pb.RpcInitialSetParametersResponse
// used only for lib-server via grpc
// Streams not supported ### ListenSessionEvents(context.Context, *pb.StreamRequest)
NotificationList(context.Context, *pb.RpcNotificationListRequest) *pb.RpcNotificationListResponse
@ -5328,23 +5332,63 @@ func DebugAnystoreObjectChanges(b []byte) (resp []byte) {
return resp
}
func MetricsSetParameters(b []byte) (resp []byte) {
func DebugNetCheck(b []byte) (resp []byte) {
defer func() {
if PanicHandler != nil {
if r := recover(); r != nil {
resp, _ = (&pb.RpcMetricsSetParametersResponse{Error: &pb.RpcMetricsSetParametersResponseError{Code: pb.RpcMetricsSetParametersResponseError_UNKNOWN_ERROR, Description: "panic recovered"}}).Marshal()
resp, _ = (&pb.RpcDebugNetCheckResponse{Error: &pb.RpcDebugNetCheckResponseError{Code: pb.RpcDebugNetCheckResponseError_UNKNOWN_ERROR, Description: "panic recovered"}}).Marshal()
PanicHandler(r)
}
}
}()
in := new(pb.RpcMetricsSetParametersRequest)
in := new(pb.RpcDebugNetCheckRequest)
if err := in.Unmarshal(b); err != nil {
resp, _ = (&pb.RpcMetricsSetParametersResponse{Error: &pb.RpcMetricsSetParametersResponseError{Code: pb.RpcMetricsSetParametersResponseError_BAD_INPUT, Description: err.Error()}}).Marshal()
resp, _ = (&pb.RpcDebugNetCheckResponse{Error: &pb.RpcDebugNetCheckResponseError{Code: pb.RpcDebugNetCheckResponseError_BAD_INPUT, Description: err.Error()}}).Marshal()
return resp
}
resp, _ = clientCommandsHandler.MetricsSetParameters(context.Background(), in).Marshal()
resp, _ = clientCommandsHandler.DebugNetCheck(context.Background(), in).Marshal()
return resp
}
func DebugExportLog(b []byte) (resp []byte) {
defer func() {
if PanicHandler != nil {
if r := recover(); r != nil {
resp, _ = (&pb.RpcDebugExportLogResponse{Error: &pb.RpcDebugExportLogResponseError{Code: pb.RpcDebugExportLogResponseError_UNKNOWN_ERROR, Description: "panic recovered"}}).Marshal()
PanicHandler(r)
}
}
}()
in := new(pb.RpcDebugExportLogRequest)
if err := in.Unmarshal(b); err != nil {
resp, _ = (&pb.RpcDebugExportLogResponse{Error: &pb.RpcDebugExportLogResponseError{Code: pb.RpcDebugExportLogResponseError_BAD_INPUT, Description: err.Error()}}).Marshal()
return resp
}
resp, _ = clientCommandsHandler.DebugExportLog(context.Background(), in).Marshal()
return resp
}
func InitialSetParameters(b []byte) (resp []byte) {
defer func() {
if PanicHandler != nil {
if r := recover(); r != nil {
resp, _ = (&pb.RpcInitialSetParametersResponse{Error: &pb.RpcInitialSetParametersResponseError{Code: pb.RpcInitialSetParametersResponseError_UNKNOWN_ERROR, Description: "panic recovered"}}).Marshal()
PanicHandler(r)
}
}
}()
in := new(pb.RpcInitialSetParametersRequest)
if err := in.Unmarshal(b); err != nil {
resp, _ = (&pb.RpcInitialSetParametersResponse{Error: &pb.RpcInitialSetParametersResponseError{Code: pb.RpcInitialSetParametersResponseError_BAD_INPUT, Description: err.Error()}}).Marshal()
return resp
}
resp, _ = clientCommandsHandler.InitialSetParameters(context.Background(), in).Marshal()
return resp
}
@ -6398,8 +6442,12 @@ func CommandAsync(cmd string, data []byte, callback func(data []byte)) {
cd = DebugAccountSelectTrace(data)
case "DebugAnystoreObjectChanges":
cd = DebugAnystoreObjectChanges(data)
case "MetricsSetParameters":
cd = MetricsSetParameters(data)
case "DebugNetCheck":
cd = DebugNetCheck(data)
case "DebugExportLog":
cd = DebugExportLog(data)
case "InitialSetParameters":
cd = InitialSetParameters(data)
case "NotificationList":
cd = NotificationList(data)
case "NotificationReply":
@ -9728,19 +9776,47 @@ func (h *ClientCommandsHandlerProxy) DebugAnystoreObjectChanges(ctx context.Cont
call, _ := actualCall(ctx, req)
return call.(*pb.RpcDebugAnystoreObjectChangesResponse)
}
func (h *ClientCommandsHandlerProxy) MetricsSetParameters(ctx context.Context, req *pb.RpcMetricsSetParametersRequest) *pb.RpcMetricsSetParametersResponse {
func (h *ClientCommandsHandlerProxy) DebugNetCheck(ctx context.Context, req *pb.RpcDebugNetCheckRequest) *pb.RpcDebugNetCheckResponse {
actualCall := func(ctx context.Context, req any) (any, error) {
return h.client.MetricsSetParameters(ctx, req.(*pb.RpcMetricsSetParametersRequest)), nil
return h.client.DebugNetCheck(ctx, req.(*pb.RpcDebugNetCheckRequest)), nil
}
for _, interceptor := range h.interceptors {
toCall := actualCall
currentInterceptor := interceptor
actualCall = func(ctx context.Context, req any) (any, error) {
return currentInterceptor(ctx, req, "MetricsSetParameters", toCall)
return currentInterceptor(ctx, req, "DebugNetCheck", toCall)
}
}
call, _ := actualCall(ctx, req)
return call.(*pb.RpcMetricsSetParametersResponse)
return call.(*pb.RpcDebugNetCheckResponse)
}
func (h *ClientCommandsHandlerProxy) DebugExportLog(ctx context.Context, req *pb.RpcDebugExportLogRequest) *pb.RpcDebugExportLogResponse {
actualCall := func(ctx context.Context, req any) (any, error) {
return h.client.DebugExportLog(ctx, req.(*pb.RpcDebugExportLogRequest)), nil
}
for _, interceptor := range h.interceptors {
toCall := actualCall
currentInterceptor := interceptor
actualCall = func(ctx context.Context, req any) (any, error) {
return currentInterceptor(ctx, req, "DebugExportLog", toCall)
}
}
call, _ := actualCall(ctx, req)
return call.(*pb.RpcDebugExportLogResponse)
}
func (h *ClientCommandsHandlerProxy) InitialSetParameters(ctx context.Context, req *pb.RpcInitialSetParametersRequest) *pb.RpcInitialSetParametersResponse {
actualCall := func(ctx context.Context, req any) (any, error) {
return h.client.InitialSetParameters(ctx, req.(*pb.RpcInitialSetParametersRequest)), nil
}
for _, interceptor := range h.interceptors {
toCall := actualCall
currentInterceptor := interceptor
actualCall = func(ctx context.Context, req any) (any, error) {
return currentInterceptor(ctx, req, "InitialSetParameters", toCall)
}
}
call, _ := actualCall(ctx, req)
return call.(*pb.RpcInitialSetParametersResponse)
}
func (h *ClientCommandsHandlerProxy) NotificationList(ctx context.Context, req *pb.RpcNotificationListRequest) *pb.RpcNotificationListResponse {
actualCall := func(ctx context.Context, req any) (any, error) {

View file

@ -3,6 +3,7 @@
package main
import (
"context"
"encoding/json"
"flag"
"fmt"
@ -142,8 +143,15 @@ func main() {
if err != nil {
log.Fatal("can't create temp file:", err)
}
g := graphviz.New()
g.Render(gvo, graphviz.SVG, tf)
ctx := context.Background()
g, err := graphviz.New(ctx)
if err != nil {
log.Fatal("can't open graphviz:", err)
}
err = g.Render(ctx, gvo, graphviz.SVG, tf)
if err != nil {
log.Fatal("can't render graphviz:", err)
}
fmt.Println("tree file:", tf.Name())
tf.Close()
open(tf.Name())

View file

@ -164,6 +164,7 @@ func (s *service) GetSpaceInfo(ctx context.Context, spaceId string) (*model.Acco
getInfo.AccountSpaceId = spaceId
getInfo.SpaceViewId = spaceViewId
getInfo.HomeObjectId = ids.Home
getInfo.WorkspaceObjectId = ids.Workspace
getInfo.WidgetsId = ids.Widgets
getInfo.ArchiveObjectId = ids.Archive
return getInfo, nil

View file

@ -19,6 +19,8 @@ import (
"github.com/anyproto/anytype-heart/util/debug"
)
var ErrNoFolder = fmt.Errorf("no folder provided")
func (s *Service) RunProfiler(ctx context.Context, seconds int) (string, error) {
// Start
inFlightTraceBuf, err := s.traceRecorder.stopAndGetInFlightTrace()
@ -115,6 +117,32 @@ func (s *Service) SaveLoginTrace(dir string) (string, error) {
return s.traceRecorder.save(dir)
}
// empty dir means use system temp dir
func (s *Service) SaveLog(srcPath, destDir string) (string, error) {
if srcPath == "" {
return "", ErrNoFolder
}
targetFile, err := os.CreateTemp(destDir, "anytype-log-*.zip")
if err != nil {
return "", fmt.Errorf("create temp file: %w", err)
}
file, err := os.Open(srcPath)
if err != nil {
return "", fmt.Errorf("failed to open source file: %w", err)
}
defer file.Close()
err = createZipArchive(targetFile, []zipFile{
{name: "anytype.log", data: file},
})
if err != nil {
return "", fmt.Errorf("failed to create zip archive: %w", err)
}
return targetFile.Name(), targetFile.Close()
}
// traceRecorder is a helper to start and stop flight trace recorder
type traceRecorder struct {
lock sync.Mutex

View file

@ -25,7 +25,11 @@ import (
"github.com/anyproto/anytype-heart/util/slice"
)
const CName = "backlinks-update-watcher"
const (
CName = "backlinks-update-watcher"
defaultAggregationInterval = time.Second * 5
)
var log = logging.Logger(CName)
@ -38,53 +42,69 @@ type backLinksUpdate struct {
removed []string
}
type UpdateWatcher struct {
type UpdateWatcher interface {
app.ComponentRunnable
FlushUpdates()
}
type watcher struct {
updater backlinksUpdater
store objectstore.ObjectStore
resolver idresolver.Resolver
spaceService space.Service
infoBatch *mb.MB
infoBatch *mb.MB
lock sync.Mutex
accumulatedBacklinks map[string]*backLinksUpdate
aggregationInterval time.Duration
}
func New() app.Component {
return &UpdateWatcher{}
func New() UpdateWatcher {
return &watcher{}
}
func (uw *UpdateWatcher) Name() string {
func (w *watcher) Name() string {
return CName
}
func (uw *UpdateWatcher) Init(a *app.App) error {
uw.updater = app.MustComponent[backlinksUpdater](a)
uw.store = app.MustComponent[objectstore.ObjectStore](a)
uw.resolver = app.MustComponent[idresolver.Resolver](a)
uw.spaceService = app.MustComponent[space.Service](a)
uw.infoBatch = mb.New(0)
func (w *watcher) Init(a *app.App) error {
w.updater = app.MustComponent[backlinksUpdater](a)
w.store = app.MustComponent[objectstore.ObjectStore](a)
w.resolver = app.MustComponent[idresolver.Resolver](a)
w.spaceService = app.MustComponent[space.Service](a)
w.infoBatch = mb.New(0)
w.accumulatedBacklinks = make(map[string]*backLinksUpdate)
w.aggregationInterval = defaultAggregationInterval
return nil
}
func (uw *UpdateWatcher) Close(context.Context) error {
if err := uw.infoBatch.Close(); err != nil {
func (w *watcher) Close(context.Context) error {
if err := w.infoBatch.Close(); err != nil {
log.Errorf("failed to close message batch: %v", err)
}
return nil
}
func (uw *UpdateWatcher) Run(context.Context) error {
uw.updater.SubscribeLinksUpdate(func(info spaceindex.LinksUpdateInfo) {
if err := uw.infoBatch.Add(info); err != nil {
func (w *watcher) Run(context.Context) error {
w.updater.SubscribeLinksUpdate(func(info spaceindex.LinksUpdateInfo) {
if err := w.infoBatch.Add(info); err != nil {
log.With("objectId", info.LinksFromId).Errorf("failed to add backlinks update info to message batch: %v", err)
}
})
go uw.backlinksUpdateHandler()
go w.backlinksUpdateHandler()
return nil
}
func (w *watcher) FlushUpdates() {
w.lock.Lock()
defer w.lock.Unlock()
w.updateAccumulatedBacklinks()
}
func applyUpdates(m map[string]*backLinksUpdate, update spaceindex.LinksUpdateInfo) {
if update.LinksFromId == "" {
return
@ -115,71 +135,69 @@ func applyUpdates(m map[string]*backLinksUpdate, update spaceindex.LinksUpdateIn
}
}
func (uw *UpdateWatcher) backlinksUpdateHandler() {
func (w *watcher) backlinksUpdateHandler() {
var (
accumulatedBacklinks = make(map[string]*backLinksUpdate)
l sync.Mutex
lastReceivedUpdates time.Time
closedCh = make(chan struct{})
aggregationInterval = time.Second * 5
lastReceivedUpdates time.Time
closedCh = make(chan struct{})
)
defer close(closedCh)
go func() {
process := func() {
log.Debugf("updating backlinks for %d objects", len(accumulatedBacklinks))
for id, updates := range accumulatedBacklinks {
uw.updateBackLinksInObject(id, updates)
}
accumulatedBacklinks = make(map[string]*backLinksUpdate)
}
for {
select {
case <-closedCh:
l.Lock()
process()
l.Unlock()
w.lock.Lock()
w.updateAccumulatedBacklinks()
w.lock.Unlock()
return
case <-time.After(aggregationInterval):
l.Lock()
if time.Since(lastReceivedUpdates) < aggregationInterval || len(accumulatedBacklinks) == 0 {
l.Unlock()
case <-time.After(w.aggregationInterval):
w.lock.Lock()
if time.Since(lastReceivedUpdates) < w.aggregationInterval || len(w.accumulatedBacklinks) == 0 {
w.lock.Unlock()
continue
}
process()
l.Unlock()
w.updateAccumulatedBacklinks()
w.lock.Unlock()
}
}
}()
for {
msgs := uw.infoBatch.Wait()
msgs := w.infoBatch.Wait()
if len(msgs) == 0 {
return
}
l.Lock()
w.lock.Lock()
for _, msg := range msgs {
info, ok := msg.(spaceindex.LinksUpdateInfo)
if !ok || hasSelfLinks(info) {
continue
}
applyUpdates(accumulatedBacklinks, info)
applyUpdates(w.accumulatedBacklinks, info)
}
lastReceivedUpdates = time.Now()
l.Unlock()
w.lock.Unlock()
}
}
func (uw *UpdateWatcher) updateBackLinksInObject(id string, backlinksUpdate *backLinksUpdate) {
spaceId, err := uw.resolver.ResolveSpaceID(id)
func (w *watcher) updateAccumulatedBacklinks() {
log.Debugf("updating backlinks for %d objects", len(w.accumulatedBacklinks))
for id, updates := range w.accumulatedBacklinks {
w.updateBackLinksInObject(id, updates)
}
w.accumulatedBacklinks = make(map[string]*backLinksUpdate)
}
func (w *watcher) updateBackLinksInObject(id string, backlinksUpdate *backLinksUpdate) {
spaceId, err := w.resolver.ResolveSpaceID(id)
if err != nil {
log.With("objectId", id).Errorf("failed to resolve space id for object: %v", err)
return
}
spc, err := uw.spaceService.Get(context.Background(), spaceId)
spc, err := w.spaceService.Get(context.Background(), spaceId)
if err != nil {
log.With("objectId", id, "spaceId", spaceId).Errorf("failed to get space: %v", err)
return
@ -206,7 +224,7 @@ func (uw *UpdateWatcher) updateBackLinksInObject(id string, backlinksUpdate *bac
}
err = spc.DoLockedIfNotExists(id, func() error {
return uw.store.SpaceIndex(spaceId).ModifyObjectDetails(id, func(details *domain.Details) (*domain.Details, bool, error) {
return w.store.SpaceIndex(spaceId).ModifyObjectDetails(id, func(details *domain.Details) (*domain.Details, bool, error) {
return updateBacklinks(details, backlinksUpdate)
})
})

View file

@ -0,0 +1,177 @@
package backlinks
import (
"testing"
"time"
"github.com/anyproto/any-sync/app/ocache"
"github.com/cheggaaa/mb"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/anyproto/anytype-heart/core/block/object/idresolver/mock_idresolver"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
"github.com/anyproto/anytype-heart/space/clientspace/mock_clientspace"
"github.com/anyproto/anytype-heart/space/mock_space"
"github.com/anyproto/anytype-heart/util/pbtypes"
)
const spaceId = "spc1"
type testUpdater struct {
callback func(info spaceindex.LinksUpdateInfo)
runFunc func(callback func(info spaceindex.LinksUpdateInfo))
}
func (u *testUpdater) SubscribeLinksUpdate(callback func(info spaceindex.LinksUpdateInfo)) {
u.callback = callback
}
func (u *testUpdater) start() {
go u.runFunc(u.callback)
}
type fixture struct {
store *objectstore.StoreFixture
resolver *mock_idresolver.MockResolver
spaceService *mock_space.MockService
updater *testUpdater
*watcher
}
func newFixture(t *testing.T, aggregationInterval time.Duration) *fixture {
updater := &testUpdater{}
store := objectstore.NewStoreFixture(t)
resolver := mock_idresolver.NewMockResolver(t)
spaceSvc := mock_space.NewMockService(t)
w := &watcher{
updater: updater,
store: store,
resolver: resolver,
spaceService: spaceSvc,
aggregationInterval: aggregationInterval,
infoBatch: mb.New(0),
accumulatedBacklinks: make(map[string]*backLinksUpdate),
}
return &fixture{
store: store,
resolver: resolver,
spaceService: spaceSvc,
updater: updater,
watcher: w,
}
}
func TestWatcher_Run(t *testing.T) {
t.Run("backlinks update asynchronously", func(t *testing.T) {
// given
interval := 500 * time.Millisecond
f := newFixture(t, interval)
f.resolver.EXPECT().ResolveSpaceID(mock.Anything).Return(spaceId, nil)
f.updater.runFunc = func(callback func(info spaceindex.LinksUpdateInfo)) {
callback(spaceindex.LinksUpdateInfo{
LinksFromId: "obj1",
Added: []string{"obj2", "obj3"},
Removed: nil,
})
time.Sleep(interval / 2)
callback(spaceindex.LinksUpdateInfo{
LinksFromId: "obj1",
Added: []string{"obj4", "obj5"},
Removed: []string{"obj2"},
})
time.Sleep(interval / 2)
callback(spaceindex.LinksUpdateInfo{
LinksFromId: "obj1",
Added: []string{"obj6"},
Removed: []string{"obj5"},
})
}
spc := mock_clientspace.NewMockSpace(t)
f.spaceService.EXPECT().Get(mock.Anything, spaceId).Return(spc, nil)
spc.EXPECT().DoLockedIfNotExists(mock.Anything, mock.Anything).RunAndReturn(func(id string, apply func() error) error {
if id == "obj2" {
return ocache.ErrExists
}
return nil
})
spc.EXPECT().Do(mock.Anything, mock.Anything).Return(nil)
// when
err := f.watcher.Run(nil)
require.NoError(t, err)
f.updater.start()
time.Sleep(4 * interval)
err = f.watcher.Close(nil)
// then
assert.NoError(t, err)
})
}
func TestWatcher_updateAccumulatedBacklinks(t *testing.T) {
t.Run("no errors", func(t *testing.T) {
// given
f := newFixture(t, time.Second)
f.resolver.EXPECT().ResolveSpaceID(mock.Anything).Return(spaceId, nil)
f.store.AddObjects(t, spaceId, []spaceindex.TestObject{{
bundle.RelationKeyId: pbtypes.String("obj1"),
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
bundle.RelationKeyBacklinks: pbtypes.StringList([]string{"obj4", "obj5", "obj6"}),
}, {
bundle.RelationKeyId: pbtypes.String("obj3"),
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
bundle.RelationKeyBacklinks: pbtypes.StringList([]string{"obj1", "obj2", "obj4"}),
}})
spc := mock_clientspace.NewMockSpace(t)
f.spaceService.EXPECT().Get(mock.Anything, spaceId).Return(spc, nil)
spc.EXPECT().DoLockedIfNotExists(mock.Anything, mock.Anything).RunAndReturn(func(id string, apply func() error) error {
if id == "obj2" {
return ocache.ErrExists
}
return apply()
})
spc.EXPECT().Do(mock.Anything, mock.Anything).Return(nil).Once()
f.watcher.accumulatedBacklinks = map[string]*backLinksUpdate{
"obj1": {
added: []string{"obj2", "obj3"},
removed: []string{"obj4", "obj5"},
},
"obj2": {
added: []string{"obj4", "obj5"},
},
"obj3": {
removed: []string{"obj1", "obj4"},
},
}
// when
f.watcher.updateAccumulatedBacklinks()
// then
details, err := f.store.SpaceIndex(spaceId).GetDetails("obj1")
require.NoError(t, err)
assert.Equal(t, []string{"obj6", "obj2", "obj3"}, pbtypes.GetStringList(details.Details, bundle.RelationKeyBacklinks.String()))
details, err = f.store.SpaceIndex(spaceId).GetDetails("obj3")
require.NoError(t, err)
assert.Equal(t, []string{"obj2"}, pbtypes.GetStringList(details.Details, bundle.RelationKeyBacklinks.String()))
})
}

View file

@ -6,6 +6,7 @@ import (
"github.com/anyproto/any-sync/app"
"github.com/samber/lo"
"github.com/anyproto/anytype-heart/core/block/backlinks"
"github.com/anyproto/anytype-heart/core/block/cache"
"github.com/anyproto/anytype-heart/core/block/editor/basic"
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
@ -26,10 +27,11 @@ import (
var log = logging.Logger("collection-service")
type Service struct {
lock *sync.RWMutex
collections map[string]map[string]chan []string
picker cache.ObjectGetter
objectStore objectstore.ObjectStore
lock *sync.RWMutex
collections map[string]map[string]chan []string
picker cache.ObjectGetter
objectStore objectstore.ObjectStore
backlinksUpdater backlinks.UpdateWatcher
}
func New() *Service {
@ -42,6 +44,7 @@ func New() *Service {
func (s *Service) Init(a *app.App) (err error) {
s.picker = app.MustComponent[cache.ObjectGetter](a)
s.objectStore = app.MustComponent[objectstore.ObjectStore](a)
s.backlinksUpdater = app.MustComponent[backlinks.UpdateWatcher](a)
return nil
}
@ -54,8 +57,9 @@ func (s *Service) CollectionType() string {
}
func (s *Service) Add(ctx session.Context, req *pb.RpcObjectCollectionAddRequest) error {
return s.updateCollection(ctx, req.ContextId, func(col []string) []string {
toAdd := slice.Difference(req.ObjectIds, col)
var toAdd []string
err := s.updateCollection(ctx, req.ContextId, func(col []string) []string {
toAdd = slice.Difference(req.ObjectIds, col)
pos := slice.FindPos(col, req.AfterId)
if pos >= 0 {
col = slice.Insert(col, pos+1, toAdd...)
@ -64,6 +68,16 @@ func (s *Service) Add(ctx session.Context, req *pb.RpcObjectCollectionAddRequest
}
return col
})
if err != nil {
return err
}
// we update backlinks of objects added to collection synchronously to avoid object rerender after backlinks accumulation interval
if len(toAdd) != 0 {
s.backlinksUpdater.FlushUpdates()
}
return nil
}
func (s *Service) Remove(ctx session.Context, req *pb.RpcObjectCollectionRemoveRequest) error {

View file

@ -2,6 +2,7 @@ package collection
import (
"context"
"fmt"
"sync"
"testing"
@ -15,27 +16,49 @@ import (
"github.com/anyproto/anytype-heart/core/block/editor/template"
"github.com/anyproto/anytype-heart/core/block/simple/dataview"
"github.com/anyproto/anytype-heart/core/domain"
"github.com/anyproto/anytype-heart/pb"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
)
const collectionID = "collectionID"
type testPicker struct {
sb smartblock.SmartBlock
sbMap map[string]smartblock.SmartBlock
}
func (t *testPicker) GetObject(ctx context.Context, id string) (sb smartblock.SmartBlock, err error) {
return t.sb, nil
func (t *testPicker) GetObject(ctx context.Context, id string) (smartblock.SmartBlock, error) {
if t.sbMap == nil {
return nil, fmt.Errorf("not found")
}
sb, found := t.sbMap[id]
if !found {
return nil, fmt.Errorf("not found")
}
return sb, nil
}
func (t *testPicker) GetObjectByFullID(ctx context.Context, id domain.FullID) (sb smartblock.SmartBlock, err error) {
return t.sb, nil
return t.GetObject(ctx, id.ObjectID)
}
func (t *testPicker) Init(a *app.App) error { return nil }
func (t *testPicker) Name() string { return "" }
func (t *testPicker) Name() string { return "test.picker" }
type testFlusher struct{}
func (tf *testFlusher) Name() string { return "test.flusher" }
func (tf *testFlusher) Init(*app.App) error { return nil }
func (tf *testFlusher) Run(context.Context) error { return nil }
func (tf *testFlusher) Close(context.Context) error { return nil }
func (tf *testFlusher) FlushUpdates() {}
type fixture struct {
picker *testPicker
@ -44,12 +67,14 @@ type fixture struct {
}
func newFixture(t *testing.T) *fixture {
picker := &testPicker{}
a := &app.App{}
picker := &testPicker{}
flusher := &testFlusher{}
objectStore := objectstore.NewStoreFixture(t)
a.Register(picker)
a.Register(objectStore)
a.Register(flusher)
s := New()
err := s.Init(a)
@ -58,11 +83,12 @@ func newFixture(t *testing.T) *fixture {
}
func TestBroadcast(t *testing.T) {
const collectionID = "collectionID"
sb := smarttest.New(collectionID)
s := newFixture(t)
s.picker.sb = sb
s.picker.sbMap = map[string]smartblock.SmartBlock{
collectionID: sb,
}
_, subCh1, err := s.SubscribeForCollection(collectionID, "sub1")
require.NoError(t, err)
@ -192,3 +218,29 @@ func TestSetObjectTypeToViews(t *testing.T) {
})
}
}
func TestService_Add(t *testing.T) {
t.Run("add new objects to collection", func(t *testing.T) {
// given
coll := smarttest.New(collectionID)
obj1 := smarttest.New("obj1")
obj2 := smarttest.New("obj2")
s := newFixture(t)
s.picker.sbMap = map[string]smartblock.SmartBlock{
collectionID: coll,
"obj1": obj1,
"obj2": obj2,
}
// when
err := s.Add(nil, &pb.RpcObjectCollectionAddRequest{
ContextId: collectionID,
ObjectIds: []string{"obj1", "obj2"},
})
// then
assert.NoError(t, err)
assert.Equal(t, []string{"obj1", "obj2"}, coll.NewState().GetStoreSlice(template.CollectionStoreKey))
})
}

View file

@ -131,7 +131,7 @@ func (s *Service) OnDelete(id domain.FullID, workspaceRemove func() error) error
b.ObjectCloseAllSessions()
st := b.NewState()
isFavorite := st.LocalDetails().GetBool(bundle.RelationKeyIsFavorite)
if err := s.detailsService.SetIsFavorite(id.ObjectID, isFavorite); err != nil {
if err := s.detailsService.SetIsFavorite(id.ObjectID, isFavorite, false); err != nil {
log.With("objectId", id).Errorf("failed to favorite object: %v", err)
}
b.SetIsDeleted()

View file

@ -568,17 +568,17 @@ func (_c *MockService_SetIsArchived_Call) RunAndReturn(run func(string, bool) er
return _c
}
// SetIsFavorite provides a mock function with given fields: objectId, isFavorite
func (_m *MockService) SetIsFavorite(objectId string, isFavorite bool) error {
ret := _m.Called(objectId, isFavorite)
// SetIsFavorite provides a mock function with given fields: objectId, isFavorite, createWidget
func (_m *MockService) SetIsFavorite(objectId string, isFavorite bool, createWidget bool) error {
ret := _m.Called(objectId, isFavorite, createWidget)
if len(ret) == 0 {
panic("no return value specified for SetIsFavorite")
}
var r0 error
if rf, ok := ret.Get(0).(func(string, bool) error); ok {
r0 = rf(objectId, isFavorite)
if rf, ok := ret.Get(0).(func(string, bool, bool) error); ok {
r0 = rf(objectId, isFavorite, createWidget)
} else {
r0 = ret.Error(0)
}
@ -594,13 +594,14 @@ type MockService_SetIsFavorite_Call struct {
// SetIsFavorite is a helper method to define mock.On call
// - objectId string
// - isFavorite bool
func (_e *MockService_Expecter) SetIsFavorite(objectId interface{}, isFavorite interface{}) *MockService_SetIsFavorite_Call {
return &MockService_SetIsFavorite_Call{Call: _e.mock.On("SetIsFavorite", objectId, isFavorite)}
// - createWidget bool
func (_e *MockService_Expecter) SetIsFavorite(objectId interface{}, isFavorite interface{}, createWidget interface{}) *MockService_SetIsFavorite_Call {
return &MockService_SetIsFavorite_Call{Call: _e.mock.On("SetIsFavorite", objectId, isFavorite, createWidget)}
}
func (_c *MockService_SetIsFavorite_Call) Run(run func(objectId string, isFavorite bool)) *MockService_SetIsFavorite_Call {
func (_c *MockService_SetIsFavorite_Call) Run(run func(objectId string, isFavorite bool, createWidget bool)) *MockService_SetIsFavorite_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(bool))
run(args[0].(string), args[1].(bool), args[2].(bool))
})
return _c
}
@ -610,7 +611,7 @@ func (_c *MockService_SetIsFavorite_Call) Return(_a0 error) *MockService_SetIsFa
return _c
}
func (_c *MockService_SetIsFavorite_Call) RunAndReturn(run func(string, bool) error) *MockService_SetIsFavorite_Call {
func (_c *MockService_SetIsFavorite_Call) RunAndReturn(run func(string, bool, bool) error) *MockService_SetIsFavorite_Call {
_c.Call.Return(run)
return _c
}

View file

@ -44,7 +44,7 @@ type Service interface {
SetSpaceInfo(spaceId string, details *domain.Details) error
SetWorkspaceDashboardId(ctx session.Context, workspaceId string, id string) (setId string, err error)
SetIsFavorite(objectId string, isFavorite bool) error
SetIsFavorite(objectId string, isFavorite, createWidget bool) error
SetIsArchived(objectId string, isArchived bool) error
SetListIsFavorite(objectIds []string, isFavorite bool) error
SetListIsArchived(objectIds []string, isArchived bool) error

View file

@ -324,19 +324,27 @@ func TestService_SetListIsFavorite(t *testing.T) {
{bundle.RelationKeyId: domain.String("obj2"), bundle.RelationKeySpaceId: domain.String(spaceId)},
{bundle.RelationKeyId: domain.String("obj3"), bundle.RelationKeySpaceId: domain.String(spaceId)},
}
homeId = "home"
homeId = "home"
widgetId = "widget"
)
t.Run("no error on favoriting", func(t *testing.T) {
// given
fx := newFixture(t)
sb := smarttest.New(homeId)
sb.AddBlock(simple.New(&model.Block{Id: homeId, ChildrenIds: []string{}}))
home := smarttest.New(homeId)
home.AddBlock(simple.New(&model.Block{Id: homeId, ChildrenIds: []string{}}))
widget := smarttest.New(widgetId)
widget.AddBlock(simple.New(&model.Block{Id: widgetId, ChildrenIds: []string{}}))
fx.store.AddObjects(t, spaceId, objects)
fx.space.EXPECT().DerivedIDs().Return(threads.DerivedSmartblockIds{Home: homeId})
fx.space.EXPECT().DerivedIDs().Return(threads.DerivedSmartblockIds{Home: homeId, Widgets: widgetId})
fx.getter.EXPECT().GetObject(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, objectId string) (smartblock.SmartBlock, error) {
require.Equal(t, homeId, objectId)
return editor.NewDashboard(sb, fx.store.SpaceIndex(spaceId), nil), nil
switch objectId {
case homeId:
return editor.NewDashboard(home, fx.store.SpaceIndex(spaceId), nil), nil
case widgetId:
return editor.NewWidgetObject(widget, fx.store.SpaceIndex(spaceId), nil), nil
}
return nil, fmt.Errorf("failed to get object")
})
// when
@ -344,22 +352,30 @@ func TestService_SetListIsFavorite(t *testing.T) {
// then
assert.NoError(t, err)
assert.Len(t, sb.Blocks(), 4)
assert.Len(t, home.Blocks(), 4)
assert.Len(t, widget.Blocks(), 3)
})
t.Run("no error on unfavoriting", func(t *testing.T) {
// given
fx := newFixture(t)
sb := smarttest.New(homeId)
sb.AddBlock(simple.New(&model.Block{Id: homeId, ChildrenIds: []string{"obj1", "obj2", "obj3"}}))
sb.AddBlock(simple.New(&model.Block{Id: "obj1", Content: &model.BlockContentOfLink{Link: &model.BlockContentLink{TargetBlockId: "obj1"}}}))
sb.AddBlock(simple.New(&model.Block{Id: "obj2", Content: &model.BlockContentOfLink{Link: &model.BlockContentLink{TargetBlockId: "obj2"}}}))
sb.AddBlock(simple.New(&model.Block{Id: "obj3", Content: &model.BlockContentOfLink{Link: &model.BlockContentLink{TargetBlockId: "obj3"}}}))
home := smarttest.New(homeId)
home.AddBlock(simple.New(&model.Block{Id: homeId, ChildrenIds: []string{"obj1", "obj2", "obj3"}}))
home.AddBlock(simple.New(&model.Block{Id: "obj1", Content: &model.BlockContentOfLink{Link: &model.BlockContentLink{TargetBlockId: "obj1"}}}))
home.AddBlock(simple.New(&model.Block{Id: "obj2", Content: &model.BlockContentOfLink{Link: &model.BlockContentLink{TargetBlockId: "obj2"}}}))
home.AddBlock(simple.New(&model.Block{Id: "obj3", Content: &model.BlockContentOfLink{Link: &model.BlockContentLink{TargetBlockId: "obj3"}}}))
widget := smarttest.New(widgetId)
widget.AddBlock(simple.New(&model.Block{Id: widgetId, ChildrenIds: []string{}}))
fx.store.AddObjects(t, spaceId, objects)
fx.space.EXPECT().DerivedIDs().Return(threads.DerivedSmartblockIds{Home: homeId})
fx.space.EXPECT().DerivedIDs().Return(threads.DerivedSmartblockIds{Home: homeId, Widgets: widgetId})
fx.getter.EXPECT().GetObject(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, objectId string) (smartblock.SmartBlock, error) {
require.Equal(t, homeId, objectId)
return editor.NewDashboard(sb, fx.store.SpaceIndex(spaceId), nil), nil
switch objectId {
case homeId:
return editor.NewDashboard(home, fx.store.SpaceIndex(spaceId), nil), nil
case widgetId:
return editor.NewWidgetObject(widget, fx.store.SpaceIndex(spaceId), nil), nil
}
return nil, fmt.Errorf("failed to get object")
})
// when
@ -367,24 +383,32 @@ func TestService_SetListIsFavorite(t *testing.T) {
// then
assert.NoError(t, err)
assert.Len(t, sb.Blocks(), 2)
assert.Len(t, home.Blocks(), 2)
assert.Len(t, widget.Blocks(), 1)
})
t.Run("some updates failed", func(t *testing.T) {
// given
fx := newFixture(t)
sb := smarttest.New(homeId)
sb.AddBlock(simple.New(&model.Block{Id: homeId, ChildrenIds: []string{}}))
home := smarttest.New(homeId)
home.AddBlock(simple.New(&model.Block{Id: homeId, ChildrenIds: []string{}}))
widget := smarttest.New(widgetId)
widget.AddBlock(simple.New(&model.Block{Id: widgetId, ChildrenIds: []string{}}))
fx.store.AddObjects(t, spaceId, objects)
fx.space.EXPECT().DerivedIDs().Return(threads.DerivedSmartblockIds{Home: homeId})
fx.space.EXPECT().DerivedIDs().Return(threads.DerivedSmartblockIds{Home: homeId, Widgets: widgetId})
flag := false
fx.getter.EXPECT().GetObject(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, objectId string) (smartblock.SmartBlock, error) {
require.Equal(t, homeId, objectId)
if flag {
return nil, fmt.Errorf("unexpected error")
switch objectId {
case homeId:
if flag {
return nil, fmt.Errorf("unexpected error")
}
flag = true
return editor.NewDashboard(home, fx.store.SpaceIndex(spaceId), nil), nil
case widgetId:
return editor.NewWidgetObject(widget, fx.store.SpaceIndex(spaceId), nil), nil
}
flag = true
return editor.NewDashboard(sb, fx.store.SpaceIndex(spaceId), nil), nil
return nil, fmt.Errorf("failed to get object")
})
// when
@ -392,14 +416,15 @@ func TestService_SetListIsFavorite(t *testing.T) {
// then
assert.NoError(t, err)
assert.Len(t, sb.Blocks(), 2)
assert.Len(t, home.Blocks(), 2)
assert.Len(t, widget.Blocks(), 3)
})
t.Run("all updates failed", func(t *testing.T) {
// given
fx := newFixture(t)
fx.store.AddObjects(t, spaceId, objects)
fx.space.EXPECT().DerivedIDs().Return(threads.DerivedSmartblockIds{Home: homeId})
fx.space.EXPECT().DerivedIDs().Return(threads.DerivedSmartblockIds{Home: homeId, Widgets: widgetId})
fx.getter.EXPECT().GetObject(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, objectId string) (smartblock.SmartBlock, error) {
require.Equal(t, homeId, objectId)
return nil, fmt.Errorf("unexpected error")

View file

@ -11,8 +11,11 @@ import (
"github.com/anyproto/anytype-heart/core/block/editor"
"github.com/anyproto/anytype-heart/core/block/editor/collection"
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
"github.com/anyproto/anytype-heart/core/domain"
"github.com/anyproto/anytype-heart/core/block/editor/state"
"github.com/anyproto/anytype-heart/core/block/editor/widget"
"github.com/anyproto/anytype-heart/core/block/simple"
"github.com/anyproto/anytype-heart/core/session"
"github.com/anyproto/anytype-heart/pb"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
@ -56,7 +59,7 @@ func (s *service) SetWorkspaceDashboardId(ctx session.Context, workspaceId strin
return id, err
}
func (s *service) SetIsFavorite(objectId string, isFavorite bool) error {
func (s *service) SetIsFavorite(objectId string, isFavorite, createWidget bool) error {
spaceID, err := s.resolver.ResolveSpaceID(objectId)
if err != nil {
return fmt.Errorf("resolve spaceID: %w", err)
@ -65,7 +68,18 @@ func (s *service) SetIsFavorite(objectId string, isFavorite bool) error {
if err != nil {
return fmt.Errorf("get space: %w", err)
}
return s.objectLinksCollectionModify(spc.DerivedIDs().Home, objectId, isFavorite)
if err = s.objectLinksCollectionModify(spc.DerivedIDs().Home, objectId, isFavorite); err != nil {
return err
}
if createWidget && isFavorite {
err = s.createFavoriteWidget(spc.DerivedIDs().Widgets)
if err != nil {
log.Error("failed to create favorite widget", zap.Error(err))
}
}
return nil
}
func (s *service) SetIsArchived(objectId string, isArchived bool) error {
@ -99,9 +113,9 @@ func (s *service) SetListIsFavorite(objectIds []string, isFavorite bool) error {
return err
}
for _, id := range ids {
for i, id := range ids {
// TODO Set list of ids at once
err := s.SetIsFavorite(id, isFavorite)
err := s.SetIsFavorite(id, isFavorite, i == 0)
if err != nil {
log.Error("failed to favorite object", zap.String("objectId", id), zap.Error(err))
resultError = errors.Join(resultError, err)
@ -228,3 +242,42 @@ func (s *service) modifyArchiveLinks(
}
return
}
func (s *service) createFavoriteWidget(widgetObjectId string) error {
return cache.DoState(s.objectGetter, widgetObjectId, func(st *state.State, w widget.Widget) (err error) {
var favoriteBlockFound bool
err = st.Iterate(func(b simple.Block) (isContinue bool) {
link := b.Model().GetLink()
if link == nil {
return true
}
if link.TargetBlockId == widget.DefaultWidgetFavorite {
favoriteBlockFound = true
return false
}
return true
})
if err != nil {
return err
}
if favoriteBlockFound {
log.Debug("favorite widget block is already presented")
return nil
}
_, err = w.CreateBlock(st, &pb.RpcBlockCreateWidgetRequest{
ContextId: widgetObjectId,
ObjectLimit: 6,
WidgetLayout: model.BlockContentWidget_List,
Position: model.Block_Bottom,
Block: &model.Block{
Content: &model.BlockContentOfLink{Link: &model.BlockContentLink{
TargetBlockId: widget.DefaultWidgetFavorite,
}},
},
})
return err
})
}

View file

@ -60,13 +60,17 @@ func (p *Archive) CreationStateMigration(ctx *smartblock.InitContext) migration.
template.WithNoObjectTypes(),
template.WithDetailName("Archive"),
template.WithDetailIconEmoji("🗑"),
template.WithForcedDetail(bundle.RelationKeyIsHidden, pbtypes.Bool(true)),
)
},
}
}
func (p *Archive) StateMigrations() migration.Migrations {
return migration.MakeMigrations(nil)
return migration.MakeMigrations([]migration.Migration{{
Version: 2,
Proc: template.WithForcedDetail(bundle.RelationKeyIsHidden, pbtypes.Bool(true)),
}})
}
func (p *Archive) Relations(_ *state.State) relationutils.Relations {

View file

@ -369,6 +369,10 @@ func (bs *basic) SetObjectTypesInState(s *state.State, objectTypeKeys []domain.T
if err = bs.Restrictions().Object.Check(model.Restrictions_TypeChange); errors.Is(err, restriction.ErrRestricted) {
return fmt.Errorf("objectType change is restricted for object '%s': %w", bs.Id(), err)
}
if objectTypeKeys[0] == bundle.TypeKeyTemplate {
return fmt.Errorf("changing object type to template is restricted")
}
}
s.SetObjectTypeKeys(objectTypeKeys)

View file

@ -4,9 +4,12 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/anyproto/anytype-heart/core/block/editor/converter"
"github.com/anyproto/anytype-heart/core/block/editor/lastused/mock_lastused"
"github.com/anyproto/anytype-heart/core/block/editor/smartblock/smarttest"
"github.com/anyproto/anytype-heart/core/block/restriction"
"github.com/anyproto/anytype-heart/core/domain"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
@ -14,10 +17,11 @@ import (
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
)
type duFixture struct {
sb *smarttest.SmartTest
store *spaceindex.StoreFixture
basic DetailsUpdatable
type basicFixture struct {
sb *smarttest.SmartTest
store *spaceindex.StoreFixture
lastUsed *mock_lastused.MockObjectUsageUpdater
basic CommonOperations
}
var (
@ -25,26 +29,28 @@ var (
spaceId = "space1"
)
func newDUFixture(t *testing.T) *duFixture {
func newBasicFixture(t *testing.T) *basicFixture {
sb := smarttest.New(objectId)
sb.SetDetails(nil, nil, false)
sb.SetSpaceId(spaceId)
store := spaceindex.NewStoreFixture(t)
lastUsed := mock_lastused.NewMockObjectUsageUpdater(t)
b := NewBasic(sb, store, converter.NewLayoutConverter(), nil, nil)
b := NewBasic(sb, store, converter.NewLayoutConverter(), nil, lastUsed)
return &duFixture{
sb: sb,
store: store,
basic: b,
return &basicFixture{
sb: sb,
store: store,
lastUsed: lastUsed,
basic: b,
}
}
func TestBasic_UpdateDetails(t *testing.T) {
t.Run("add new details", func(t *testing.T) {
// given
f := newDUFixture(t)
f := newBasicFixture(t)
f.store.AddObjects(t, []objectstore.TestObject{{
bundle.RelationKeyId: domain.String("rel-aperture"),
bundle.RelationKeySpaceId: domain.String(spaceId),
@ -84,7 +90,7 @@ func TestBasic_UpdateDetails(t *testing.T) {
t.Run("modify details", func(t *testing.T) {
// given
f := newDUFixture(t)
f := newBasicFixture(t)
err := f.sb.SetDetails(nil, []domain.Detail{{
Key: bundle.RelationKeySpaceDashboardId,
Value: domain.String("123"),
@ -115,7 +121,7 @@ func TestBasic_UpdateDetails(t *testing.T) {
t.Run("delete details", func(t *testing.T) {
// given
f := newDUFixture(t)
f := newBasicFixture(t)
err := f.sb.SetDetails(nil, []domain.Detail{{
Key: bundle.RelationKeyTargetObjectType,
Value: domain.String("ot-note"),
@ -137,3 +143,52 @@ func TestBasic_UpdateDetails(t *testing.T) {
assert.False(t, f.sb.HasRelation(f.sb.NewState(), bundle.RelationKeyTargetObjectType.String()))
})
}
func TestBasic_SetObjectTypesInState(t *testing.T) {
t.Run("no error", func(t *testing.T) {
// given
f := newBasicFixture(t)
f.lastUsed.EXPECT().UpdateLastUsedDate(mock.Anything, bundle.TypeKeyTask, mock.Anything).Return().Once()
f.store.AddObjects(t, []objectstore.TestObject{{
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
bundle.RelationKeyId: pbtypes.String("ot-task"),
bundle.RelationKeyUniqueKey: pbtypes.String("ot-task"),
bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_todo)),
}})
s := f.sb.NewState()
// when
err := f.basic.SetObjectTypesInState(s, []domain.TypeKey{bundle.TypeKeyTask}, false)
// then
assert.NoError(t, err)
assert.Equal(t, bundle.TypeKeyTask, s.ObjectTypeKey())
})
t.Run("type change is restricted", func(t *testing.T) {
// given
f := newBasicFixture(t)
f.sb.TestRestrictions = restriction.Restrictions{Object: []model.RestrictionsObjectRestriction{model.Restrictions_TypeChange}}
s := f.sb.NewState()
// when
err := f.basic.SetObjectTypesInState(s, []domain.TypeKey{bundle.TypeKeyTask}, false)
// then
assert.ErrorIs(t, err, restriction.ErrRestricted)
})
t.Run("changing to template type is restricted", func(t *testing.T) {
// given
f := newBasicFixture(t)
s := f.sb.NewState()
// when
err := f.basic.SetObjectTypesInState(s, []domain.TypeKey{bundle.TypeKeyTemplate}, false)
// then
assert.Error(t, err)
})
}

View file

@ -57,13 +57,17 @@ func (p *Dashboard) CreationStateMigration(ctx *smartblock.InitContext) migratio
template.WithDetailName("Home"),
template.WithDetailIconEmoji("🏠"),
template.WithNoDuplicateLinks(),
template.WithForcedDetail(bundle.RelationKeyIsHidden, pbtypes.Bool(true)),
)
},
}
}
func (p *Dashboard) StateMigrations() migration.Migrations {
return migration.MakeMigrations(nil)
return migration.MakeMigrations([]migration.Migration{{
Version: 2,
Proc: template.WithForcedDetail(bundle.RelationKeyIsHidden, pbtypes.Bool(true)),
}})
}
func (p *Dashboard) updateObjects(info smartblock.ApplyInfo) (err error) {

View file

@ -16,6 +16,7 @@ import (
"github.com/anyproto/anytype-heart/core/block/cache"
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
"github.com/anyproto/anytype-heart/core/block/editor/state"
"github.com/anyproto/anytype-heart/core/block/editor/template"
"github.com/anyproto/anytype-heart/core/block/process"
"github.com/anyproto/anytype-heart/core/block/simple"
"github.com/anyproto/anytype-heart/core/block/simple/file"
@ -221,8 +222,10 @@ func (sf *sfile) updateFile(ctx session.Context, id, groupId string, apply func(
}
func (sf *sfile) DropFiles(req pb.RpcFileDropRequest) (err error) {
if err = sf.Restrictions().Object.Check(model.Restrictions_Blocks); err != nil {
return err
if !isCollection(sf) {
if err = sf.Restrictions().Object.Check(model.Restrictions_Blocks); err != nil {
return err
}
}
proc := &dropFilesProcess{
spaceID: sf.SpaceID(),
@ -234,7 +237,7 @@ func (sf *sfile) DropFiles(req pb.RpcFileDropRequest) (err error) {
return
}
var ch = make(chan error)
go proc.Start(sf.RootId(), req.DropTargetId, req.Position, ch)
go proc.Start(sf, req.DropTargetId, req.Position, ch)
err = <-ch
return
}
@ -248,7 +251,6 @@ func (sf *sfile) dropFilesCreateStructure(groupId, targetId string, pos model.Bl
for _, entry := range entries {
var blockId, pageId string
if entry.isDir {
if err = sf.Apply(s); err != nil {
return
}
@ -304,6 +306,13 @@ func (sf *sfile) dropFilesSetInfo(info dropFileInfo) (err error) {
s.Unlink(info.blockId)
return sf.Apply(s)
}
if isCollection(sf) {
s := sf.NewState()
if !s.HasInStore([]string{info.file.TargetObjectId}) {
s.UpdateStoreSlice(template.CollectionStoreKey, append(s.GetStoreSlice(template.CollectionStoreKey), info.file.TargetObjectId))
}
return sf.Apply(s)
}
return sf.UpdateFile(info.blockId, info.groupId, func(f file.Block) error {
if info.err != nil || info.file == nil || info.file.State == model.BlockContentFile_Error {
if info.err != nil {
@ -451,7 +460,7 @@ func (dp *dropFilesProcess) readdir(entry *dropFileEntry, allowSymlinks bool) (o
return true, nil
}
func (dp *dropFilesProcess) Start(rootId, targetId string, pos model.BlockPosition, rootDone chan error) {
func (dp *dropFilesProcess) Start(file smartblock.SmartBlock, targetId string, pos model.BlockPosition, rootDone chan error) {
dp.id = uuid.New().String()
dp.doneCh = make(chan struct{})
dp.cancel = make(chan struct{})
@ -470,6 +479,46 @@ func (dp *dropFilesProcess) Start(rootId, targetId string, pos model.BlockPositi
go dp.addFilesWorker(wg, in)
}
if isCollection(file) {
dp.handleDragAndDropInCollection(file.RootId(), dp.root.child, rootDone, in)
} else {
dp.handleDragAndDropInDocument(file.RootId(), targetId, pos, rootDone, in)
}
wg.Wait()
}
func (dp *dropFilesProcess) handleDragAndDropInCollection(rootId string, droppedFiles []*dropFileEntry, rootDone chan error, in chan *dropFileInfo) {
close(rootDone)
filesToUpload := dp.getFilesToUploadFromDirs(droppedFiles)
for _, entry := range filesToUpload {
in <- &dropFileInfo{
pageId: rootId,
path: entry.path,
name: entry.name,
}
}
close(in)
}
func (dp *dropFilesProcess) getFilesToUploadFromDirs(droppedFiles []*dropFileEntry) []*dropFileEntry {
var (
stack []*dropFileEntry
totalFiles []*dropFileEntry
)
stack = append(stack, droppedFiles...)
for len(stack) > 0 {
entry := stack[len(stack)-1]
stack = stack[:len(stack)-1]
if entry.isDir {
stack = append(stack, entry.child...)
} else {
totalFiles = append(totalFiles, entry)
}
}
return totalFiles
}
func (dp *dropFilesProcess) handleDragAndDropInDocument(rootId, targetId string, pos model.BlockPosition, rootDone chan error, in chan *dropFileInfo) {
var flatEntries = [][]*dropFileEntry{dp.root.child}
var smartBlockIds = []string{rootId}
var handleLevel = func(idx int) (isContinue bool, err error) {
@ -534,8 +583,6 @@ func (dp *dropFilesProcess) Start(rootId, targetId string, pos model.BlockPositi
idx++
}
close(in)
wg.Wait()
return
}
func (dp *dropFilesProcess) addFilesWorker(wg *sync.WaitGroup, in chan *dropFileInfo) {
@ -591,3 +638,8 @@ func (dp *dropFilesProcess) apply(f *dropFileInfo) (err error) {
return sbHandler.dropFilesSetInfo(*f)
})
}
func isCollection(smartBlock smartblock.SmartBlock) bool {
layout, ok := smartBlock.Layout()
return ok && layout == model.ObjectType_collection
}

View file

@ -1,19 +1,42 @@
package file
import (
"context"
"errors"
"os"
"path/filepath"
"testing"
"github.com/anyproto/any-sync/accountservice/mock_accountservice"
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/commonfile/fileservice"
"github.com/gogo/protobuf/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
"github.com/anyproto/anytype-heart/core/anytype/config"
"github.com/anyproto/anytype-heart/core/block/cache/mock_cache"
"github.com/anyproto/anytype-heart/core/block/editor/smartblock/smarttest"
"github.com/anyproto/anytype-heart/core/block/editor/template"
"github.com/anyproto/anytype-heart/core/block/process"
"github.com/anyproto/anytype-heart/core/block/restriction"
"github.com/anyproto/anytype-heart/core/domain"
"github.com/anyproto/anytype-heart/core/event/mock_event"
"github.com/anyproto/anytype-heart/core/files"
"github.com/anyproto/anytype-heart/core/files/fileobject/mock_fileobject"
"github.com/anyproto/anytype-heart/core/files/fileuploader"
"github.com/anyproto/anytype-heart/core/filestorage"
"github.com/anyproto/anytype-heart/core/filestorage/filesync"
"github.com/anyproto/anytype-heart/core/filestorage/rpcstore"
wallet2 "github.com/anyproto/anytype-heart/core/wallet"
"github.com/anyproto/anytype-heart/core/wallet/mock_wallet"
"github.com/anyproto/anytype-heart/pb"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
"github.com/anyproto/anytype-heart/pkg/lib/core"
"github.com/anyproto/anytype-heart/pkg/lib/datastore"
"github.com/anyproto/anytype-heart/pkg/lib/localstore/filestore"
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
"github.com/anyproto/anytype-heart/tests/blockbuilder"
"github.com/anyproto/anytype-heart/tests/testutil"
@ -21,21 +44,31 @@ import (
type fileFixture struct {
sfile
pickerFx *mock_cache.MockObjectGetter
sb *smarttest.SmartTest
pickerFx *mock_cache.MockObjectGetter
sb *smarttest.SmartTest
mockSender *mock_event.MockSender
}
func newFixture(t *testing.T) *fileFixture {
picker := mock_cache.NewMockObjectGetter(t)
sb := smarttest.New("root")
mockSender := mock_event.NewMockSender(t)
fx := &fileFixture{
pickerFx: picker,
sb: sb,
pickerFx: picker,
sb: sb,
mockSender: mockSender,
}
a := &app.App{}
a.Register(testutil.PrepareMock(context.Background(), a, mockSender))
service := process.New()
err := service.Init(a)
assert.Nil(t, err)
fx.sfile = sfile{
SmartBlock: sb,
picker: picker,
SmartBlock: sb,
picker: picker,
processService: service,
}
return fx
}
@ -119,4 +152,167 @@ func TestDropFiles(t *testing.T) {
assert.Error(t, err)
assert.True(t, errors.Is(err, restriction.ErrRestricted))
})
t.Run("drop files in collection - no restriction error", func(t *testing.T) {
// given
dir := t.TempDir()
file, err := os.Create(filepath.Join(dir, "test"))
assert.Nil(t, err)
fx := newFixture(t)
st := fx.sb.Doc.NewState()
st.SetDetail(bundle.RelationKeyLayout.String(), pbtypes.Int64(int64(model.ObjectType_collection)))
fx.sb.Doc = st
fx.pickerFx.EXPECT().GetObject(context.Background(), "root").Return(fx, nil).Maybe()
fx.mockSender.EXPECT().Broadcast(mock.Anything).Return().Maybe()
mockService := mock_fileobject.NewMockService(t)
mockService.EXPECT().Create(mock.Anything, mock.Anything, mock.Anything).Return("fileObjectId", &types.Struct{Fields: map[string]*types.Value{}}, nil).Maybe()
fx.fileUploaderFactory = prepareFileService(t, fx.mockSender, mockService)
// when
err = fx.sfile.DropFiles(pb.RpcFileDropRequest{
ContextId: "root",
LocalFilePaths: []string{file.Name()},
})
// then
assert.Nil(t, err)
})
t.Run("drop dir in collection - no restriction error", func(t *testing.T) {
// given
dir := t.TempDir()
_, err := os.Create(filepath.Join(dir, "test"))
assert.Nil(t, err)
fx := newFixture(t)
st := fx.sb.Doc.NewState()
st.SetDetail(bundle.RelationKeyLayout.String(), pbtypes.Int64(int64(model.ObjectType_collection)))
fx.sb.Doc = st
fx.pickerFx.EXPECT().GetObject(context.Background(), "root").Return(fx, nil).Maybe()
fx.mockSender.EXPECT().Broadcast(mock.Anything).Return().Maybe()
mockService := mock_fileobject.NewMockService(t)
mockService.EXPECT().Create(mock.Anything, mock.Anything, mock.Anything).Return("fileObjectId", &types.Struct{Fields: map[string]*types.Value{}}, nil).Maybe()
fx.fileUploaderFactory = prepareFileService(t, fx.mockSender, mockService)
// when
err = fx.sfile.DropFiles(pb.RpcFileDropRequest{
ContextId: "root",
LocalFilePaths: []string{dir},
})
// then
assert.Nil(t, err)
})
t.Run("drop files in collection - success", func(t *testing.T) {
// given
dir := t.TempDir()
file, err := os.Create(filepath.Join(dir, "test"))
assert.Nil(t, err)
fx := newFixture(t)
st := fx.sb.Doc.NewState()
st.SetDetail(bundle.RelationKeyLayout.String(), pbtypes.Int64(int64(model.ObjectType_collection)))
fx.sb.Doc = st
fx.pickerFx.EXPECT().GetObject(context.Background(), "root").Return(fx, nil)
fx.mockSender.EXPECT().Broadcast(mock.Anything).Return()
mockService := mock_fileobject.NewMockService(t)
mockService.EXPECT().Create(context.Background(), "", mock.Anything).Return("fileObjectId", &types.Struct{Fields: map[string]*types.Value{}}, nil).Maybe()
fx.fileUploaderFactory = prepareFileService(t, fx.mockSender, mockService)
// when
proc := &dropFilesProcess{
spaceID: fx.SpaceID(),
processService: fx.processService,
picker: fx.picker,
fileUploaderFactory: fx.fileUploaderFactory,
}
err = proc.Init([]string{file.Name()})
assert.Nil(t, err)
var ch = make(chan error)
proc.Start(fx, "", model.Block_Bottom, ch)
err = <-ch
// then
assert.Nil(t, err)
storeSlice := fx.NewState().GetStoreSlice(template.CollectionStoreKey)
assert.Len(t, storeSlice, 1)
assert.Equal(t, "fileObjectId", storeSlice[0])
})
t.Run("drop dir with file in collection - success", func(t *testing.T) {
// given
dir := t.TempDir()
_, err := os.Create(filepath.Join(dir, "test"))
assert.Nil(t, err)
fx := newFixture(t)
st := fx.sb.Doc.NewState()
st.SetDetail(bundle.RelationKeyLayout.String(), pbtypes.Int64(int64(model.ObjectType_collection)))
fx.sb.Doc = st
fx.pickerFx.EXPECT().GetObject(context.Background(), "root").Return(fx, nil)
fx.mockSender.EXPECT().Broadcast(mock.Anything).Return()
mockService := mock_fileobject.NewMockService(t)
mockService.EXPECT().Create(context.Background(), "", mock.Anything).Return("fileObjectId", &types.Struct{Fields: map[string]*types.Value{}}, nil).Maybe()
fx.fileUploaderFactory = prepareFileService(t, fx.mockSender, mockService)
// when
proc := &dropFilesProcess{
spaceID: fx.SpaceID(),
processService: fx.processService,
picker: fx.picker,
fileUploaderFactory: fx.fileUploaderFactory,
}
err = proc.Init([]string{dir})
assert.Nil(t, err)
var ch = make(chan error)
proc.Start(fx, "", model.Block_Bottom, ch)
err = <-ch
// then
assert.Nil(t, err)
storeSlice := fx.NewState().GetStoreSlice(template.CollectionStoreKey)
assert.Len(t, storeSlice, 1)
assert.Equal(t, "fileObjectId", storeSlice[0])
})
}
func prepareFileService(t *testing.T, sender *mock_event.MockSender, fileObjectService *mock_fileobject.MockService) fileuploader.Service {
dataStoreProvider, err := datastore.NewInMemory()
assert.Nil(t, err)
blockStorage := filestorage.NewInMemory()
rpcStore := rpcstore.NewInMemoryStore(1024)
rpcStoreService := rpcstore.NewInMemoryService(rpcStore)
commonFileService := fileservice.New()
fileSyncService := filesync.New()
objectStore := objectstore.NewStoreFixture(t)
ctx := context.Background()
ctrl := gomock.NewController(t)
wallet := mock_wallet.NewMockWallet(t)
wallet.EXPECT().Name().Return(wallet2.CName)
wallet.EXPECT().RepoPath().Return("repo/path")
a := new(app.App)
a.Register(dataStoreProvider)
a.Register(filestore.New())
a.Register(commonFileService)
a.Register(fileSyncService)
a.Register(testutil.PrepareMock(ctx, a, sender))
a.Register(blockStorage)
a.Register(objectStore)
a.Register(rpcStoreService)
a.Register(testutil.PrepareMock(ctx, a, mock_accountservice.NewMockService(ctrl)))
a.Register(testutil.PrepareMock(ctx, a, wallet))
a.Register(testutil.PrepareMock(ctx, a, fileObjectService))
a.Register(&config.Config{DisableFileConfig: true, NetworkMode: pb.RpcAccount_DefaultConfig, PeferYamuxTransport: true})
a.Register(core.NewTempDirService())
a.Register(testutil.PrepareMock(ctx, a, mock_cache.NewMockObjectGetterComponent(t)))
a.Register(files.New())
err = a.Start(ctx)
assert.Nil(t, err)
service := fileuploader.New()
err = service.Init(a)
assert.Nil(t, err)
return service
}

View file

@ -52,6 +52,13 @@ func (p *participant) Init(ctx *smartblock.InitContext) (err error) {
ctx.State.SetDetailAndBundledRelation(bundle.RelationKeyLayout, domain.Int64(model.ObjectType_participant))
ctx.State.SetDetailAndBundledRelation(bundle.RelationKeyLayoutAlign, domain.Int64(model.Block_AlignCenter))
records, err := p.objectStore.QueryByIds([]string{p.Id()})
if err != nil {
return err
}
if len(records) > 0 {
ctx.State.SetDetails(records[0].Details)
}
template.InitTemplate(ctx.State,
template.WithEmpty,
template.WithTitle,
@ -60,15 +67,6 @@ func (p *participant) Init(ctx *smartblock.InitContext) (err error) {
template.WithAddedFeaturedRelation(bundle.RelationKeyType),
template.WithAddedFeaturedRelation(bundle.RelationKeyBacklinks),
)
records, err := p.objectStore.QueryByIds([]string{p.Id()})
if err != nil {
return err
}
if len(records) > 0 {
ctx.State.SetDetails(records[0].Details)
}
return nil
}

View file

@ -3,11 +3,13 @@ package editor
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/anyproto/anytype-heart/core/block/editor/basic"
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
"github.com/anyproto/anytype-heart/core/block/editor/smartblock/smarttest"
"github.com/anyproto/anytype-heart/core/block/editor/state"
"github.com/anyproto/anytype-heart/core/block/migration"
"github.com/anyproto/anytype-heart/core/domain"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
@ -107,6 +109,68 @@ func TestParticipant_ModifyIdentityDetails(t *testing.T) {
}
}
func TestParticipant_Init(t *testing.T) {
t.Run("title block not empty, because name detail is in store", func(t *testing.T) {
// given
sb := smarttest.New("root")
store := newStoreFixture(t)
store.AddObjects(t, []objectstore.TestObject{{
bundle.RelationKeySpaceId: pbtypes.String("spaceId"),
bundle.RelationKeyId: pbtypes.String("root"),
bundle.RelationKeyName: pbtypes.String("test"),
}})
basicComponent := basic.NewBasic(sb, store, nil, nil, nil)
p := &participant{
SmartBlock: sb,
DetailsUpdatable: basicComponent,
objectStore: store,
}
initCtx := &smartblock.InitContext{
IsNewObject: true,
}
// when
err := p.Init(initCtx)
assert.NoError(t, err)
migration.RunMigrations(p, initCtx)
err = p.Apply(initCtx.State)
assert.NoError(t, err)
// then
assert.NotNil(t, p.NewState().Get(state.TitleBlockID))
assert.Equal(t, "test", p.NewState().Get(state.TitleBlockID).Model().GetText().GetText())
})
t.Run("title block is empty", func(t *testing.T) {
// given
sb := smarttest.New("root")
store := newStoreFixture(t)
basicComponent := basic.NewBasic(sb, store, nil, nil, nil)
p := &participant{
SmartBlock: sb,
DetailsUpdatable: basicComponent,
objectStore: store,
}
initCtx := &smartblock.InitContext{
IsNewObject: true,
}
// when
err := p.Init(initCtx)
assert.NoError(t, err)
migration.RunMigrations(p, initCtx)
err = p.Apply(initCtx.State)
assert.NoError(t, err)
// then
assert.NotNil(t, p.NewState().Get(state.TitleBlockID))
assert.Equal(t, "", p.NewState().Get(state.TitleBlockID).Model().GetText().GetText())
})
}
func newStoreFixture(t *testing.T) *spaceindex.StoreFixture {
store := spaceindex.NewStoreFixture(t)

View file

@ -251,6 +251,7 @@ var workspaceKeysToCopy = []domain.RelationKey{
bundle.RelationKeyIconOption,
bundle.RelationKeySpaceDashboardId,
bundle.RelationKeyCreatedDate,
bundle.RelationKeyChatId,
}
func (s *SpaceView) GetSpaceDescription() (data spaceinfo.SpaceDescription) {

View file

@ -1307,8 +1307,9 @@ func (s *State) Copy() *State {
}
func (s *State) HasRelation(key string) bool {
for _, rel := range s.relationLinks {
if rel.Key == key {
links := s.GetRelationLinks()
for _, link := range links {
if link.Key == key {
return true
}
}

View file

@ -391,7 +391,7 @@ func (oc *ObjectCreator) resetState(newID string, st *state.State) *domain.Detai
func (oc *ObjectCreator) setFavorite(snapshot *common.StateSnapshot, newID string) {
isFavorite := snapshot.Details.GetBool(bundle.RelationKeyIsFavorite)
if isFavorite {
err := oc.detailsService.SetIsFavorite(newID, true)
err := oc.detailsService.SetIsFavorite(newID, true, false)
if err != nil {
log.With(zap.String("object id", newID)).Errorf("failed to set isFavorite when importing object: %s", err)
}

View file

@ -168,7 +168,7 @@ func (_c *MockCache_CreateTreeObject_Call) RunAndReturn(run func(context.Context
}
// CreateTreeObjectWithPayload provides a mock function with given fields: ctx, payload, initFunc
func (_m *MockCache) CreateTreeObjectWithPayload(ctx context.Context, payload treestorage.TreeStorageCreatePayload, initFunc func(string) *smartblock.InitContext) (smartblock.SmartBlock, error) {
func (_m *MockCache) CreateTreeObjectWithPayload(ctx context.Context, payload treestorage.TreeStorageCreatePayload, initFunc objectcache.InitFunc) (smartblock.SmartBlock, error) {
ret := _m.Called(ctx, payload, initFunc)
if len(ret) == 0 {
@ -177,10 +177,10 @@ func (_m *MockCache) CreateTreeObjectWithPayload(ctx context.Context, payload tr
var r0 smartblock.SmartBlock
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, treestorage.TreeStorageCreatePayload, func(string) *smartblock.InitContext) (smartblock.SmartBlock, error)); ok {
if rf, ok := ret.Get(0).(func(context.Context, treestorage.TreeStorageCreatePayload, objectcache.InitFunc) (smartblock.SmartBlock, error)); ok {
return rf(ctx, payload, initFunc)
}
if rf, ok := ret.Get(0).(func(context.Context, treestorage.TreeStorageCreatePayload, func(string) *smartblock.InitContext) smartblock.SmartBlock); ok {
if rf, ok := ret.Get(0).(func(context.Context, treestorage.TreeStorageCreatePayload, objectcache.InitFunc) smartblock.SmartBlock); ok {
r0 = rf(ctx, payload, initFunc)
} else {
if ret.Get(0) != nil {
@ -188,7 +188,7 @@ func (_m *MockCache) CreateTreeObjectWithPayload(ctx context.Context, payload tr
}
}
if rf, ok := ret.Get(1).(func(context.Context, treestorage.TreeStorageCreatePayload, func(string) *smartblock.InitContext) error); ok {
if rf, ok := ret.Get(1).(func(context.Context, treestorage.TreeStorageCreatePayload, objectcache.InitFunc) error); ok {
r1 = rf(ctx, payload, initFunc)
} else {
r1 = ret.Error(1)
@ -205,14 +205,14 @@ type MockCache_CreateTreeObjectWithPayload_Call struct {
// CreateTreeObjectWithPayload is a helper method to define mock.On call
// - ctx context.Context
// - payload treestorage.TreeStorageCreatePayload
// - initFunc func(string) *smartblock.InitContext
// - initFunc objectcache.InitFunc
func (_e *MockCache_Expecter) CreateTreeObjectWithPayload(ctx interface{}, payload interface{}, initFunc interface{}) *MockCache_CreateTreeObjectWithPayload_Call {
return &MockCache_CreateTreeObjectWithPayload_Call{Call: _e.mock.On("CreateTreeObjectWithPayload", ctx, payload, initFunc)}
}
func (_c *MockCache_CreateTreeObjectWithPayload_Call) Run(run func(ctx context.Context, payload treestorage.TreeStorageCreatePayload, initFunc func(string) *smartblock.InitContext)) *MockCache_CreateTreeObjectWithPayload_Call {
func (_c *MockCache_CreateTreeObjectWithPayload_Call) Run(run func(ctx context.Context, payload treestorage.TreeStorageCreatePayload, initFunc objectcache.InitFunc)) *MockCache_CreateTreeObjectWithPayload_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(treestorage.TreeStorageCreatePayload), args[2].(func(string) *smartblock.InitContext))
run(args[0].(context.Context), args[1].(treestorage.TreeStorageCreatePayload), args[2].(objectcache.InitFunc))
})
return _c
}
@ -222,7 +222,7 @@ func (_c *MockCache_CreateTreeObjectWithPayload_Call) Return(sb smartblock.Smart
return _c
}
func (_c *MockCache_CreateTreeObjectWithPayload_Call) RunAndReturn(run func(context.Context, treestorage.TreeStorageCreatePayload, func(string) *smartblock.InitContext) (smartblock.SmartBlock, error)) *MockCache_CreateTreeObjectWithPayload_Call {
func (_c *MockCache_CreateTreeObjectWithPayload_Call) RunAndReturn(run func(context.Context, treestorage.TreeStorageCreatePayload, objectcache.InitFunc) (smartblock.SmartBlock, error)) *MockCache_CreateTreeObjectWithPayload_Call {
_c.Call.Return(run)
return _c
}

View file

@ -3,10 +3,8 @@ package objectcreator
import (
"context"
"fmt"
"time"
"github.com/anyproto/anytype-heart/core/block/editor/state"
"github.com/anyproto/anytype-heart/core/block/object/payloadcreator"
"github.com/anyproto/anytype-heart/core/domain"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
"github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
@ -14,36 +12,11 @@ import (
"github.com/anyproto/anytype-heart/space/clientspace"
)
func (s *service) createChat(ctx context.Context, space clientspace.Space, details *domain.Details) (string, *domain.Details, error) {
payload, err := space.CreateTreePayload(ctx, payloadcreator.PayloadCreationParams{
Time: time.Now(),
SmartblockType: smartblock.SmartBlockTypeChatObject,
})
if err != nil {
return "", nil, fmt.Errorf("create tree payload: %w", err)
}
createState := state.NewDoc(payload.RootRawChange.Id, nil).(*state.State)
details.Set(bundle.RelationKeyLayout, domain.Int64(int64(model.ObjectType_chat)))
createState.SetDetails(details)
err = s.addChatDerivedObject(ctx, space, createState, payload.RootRawChange.Id)
if err != nil {
return "", nil, fmt.Errorf("add chat derived object: %w", err)
}
id, newDetails, err := s.CreateSmartBlockFromStateInSpaceWithOptions(ctx, space, []domain.TypeKey{bundle.TypeKeyChat}, createState, WithPayload(&payload))
if err != nil {
return "", nil, fmt.Errorf("create smartblock from state: %w", err)
}
return id, newDetails, nil
}
func (s *service) addChatDerivedObject(ctx context.Context, space clientspace.Space, st *state.State, chatObjectId string) error {
func (s *service) AddChatDerivedObject(ctx context.Context, space clientspace.Space, chatObjectId string) (chatId string, err error) {
chatDetails := domain.NewDetails()
chatUniqueKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeChatDerivedObject, chatObjectId)
if err != nil {
return fmt.Errorf("create payload: %w", err)
return "", fmt.Errorf("create payload: %w", err)
}
chatDetails.SetString(bundle.RelationKeyUniqueKey, chatUniqueKey.Marshal())
@ -52,14 +25,12 @@ func (s *service) addChatDerivedObject(ctx context.Context, space clientspace.Sp
Details: chatDetails,
}
chatId, _, err := s.createObjectInSpace(ctx, space, chatReq)
chatId, _, err = s.createObjectInSpace(ctx, space, chatReq)
if err != nil {
return fmt.Errorf("create object: %w", err)
return "", fmt.Errorf("create object: %w", err)
}
st.SetDetailAndBundledRelation(bundle.RelationKeyChatId, domain.String(chatId))
st.SetDetailAndBundledRelation(bundle.RelationKeyHasChat, domain.Bool(true))
return nil
return chatId, nil
}
func (s *service) createChatDerived(ctx context.Context, space clientspace.Space, details *domain.Details) (string, *domain.Details, error) {

View file

@ -46,6 +46,7 @@ type Service interface {
CreateSmartBlockFromState(ctx context.Context, spaceID string, objectTypeKeys []domain.TypeKey, createState *state.State) (id string, newDetails *domain.Details, err error)
CreateSmartBlockFromStateInSpace(ctx context.Context, space clientspace.Space, objectTypeKeys []domain.TypeKey, createState *state.State) (id string, newDetails *domain.Details, err error)
AddChatDerivedObject(ctx context.Context, space clientspace.Space, chatObjectId string) (chatId string, err error)
InstallBundledObjects(ctx context.Context, space clientspace.Space, sourceObjectIds []string, isNewSpace bool) (ids []string, objects []*domain.Details, err error)
app.Component
@ -146,12 +147,14 @@ func (s *service) createObjectInSpace(
return s.createRelation(ctx, space, details)
case bundle.TypeKeyRelationOption:
return s.createRelationOption(ctx, space, details)
case bundle.TypeKeyChat:
return s.createChat(ctx, space, details)
case bundle.TypeKeyChatDerived:
return s.createChatDerived(ctx, space, details)
case bundle.TypeKeyFile:
return "", nil, fmt.Errorf("files must be created via fileobject service")
case bundle.TypeKeyTemplate:
if pbtypes.GetString(details, bundle.RelationKeyTargetObjectType.String()) == "" {
return "", nil, fmt.Errorf("cannot create template without target object")
}
}
return s.createObjectFromTemplate(ctx, space, []domain.TypeKey{req.ObjectTypeKey}, details, req.TemplateId)

View file

@ -0,0 +1,106 @@
package objectcreator
import (
"context"
"testing"
"github.com/gogo/protobuf/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/anyproto/anytype-heart/core/block/editor/lastused/mock_lastused"
"github.com/anyproto/anytype-heart/core/block/editor/smartblock/smarttest"
"github.com/anyproto/anytype-heart/core/block/editor/state"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
"github.com/anyproto/anytype-heart/space/clientspace"
"github.com/anyproto/anytype-heart/space/clientspace/mock_clientspace"
"github.com/anyproto/anytype-heart/space/mock_space"
"github.com/anyproto/anytype-heart/util/pbtypes"
)
const spaceId = "spc1"
type fixture struct {
spaceService *mock_space.MockService
spc *mock_clientspace.MockSpace
templateService *testTemplateService
lastUsedService *mock_lastused.MockObjectUsageUpdater
service Service
}
func newFixture(t *testing.T) *fixture {
spaceService := mock_space.NewMockService(t)
spc := mock_clientspace.NewMockSpace(t)
templateSvc := &testTemplateService{}
lastUsedSvc := mock_lastused.NewMockObjectUsageUpdater(t)
s := &service{
spaceService: spaceService,
templateService: templateSvc,
lastUsedUpdater: lastUsedSvc,
}
return &fixture{
spaceService: spaceService,
spc: spc,
templateService: templateSvc,
lastUsedService: lastUsedSvc,
service: s,
}
}
type testTemplateService struct {
templates map[string]*state.State
}
func (tts *testTemplateService) CreateTemplateStateWithDetails(templateId string, details *types.Struct) (*state.State, error) {
if tts.templates != nil {
if st, found := tts.templates[templateId]; found {
return st, nil
}
}
return state.NewDoc(templateId, nil).NewState(), nil
}
func (tts *testTemplateService) TemplateCloneInSpace(space clientspace.Space, id string) (templateId string, err error) {
return "", nil
}
func TestService_CreateObject(t *testing.T) {
t.Run("template creation", func(t *testing.T) {
// given
sb := smarttest.New("test")
f := newFixture(t)
f.spaceService.EXPECT().Get(mock.Anything, mock.Anything).Return(f.spc, nil)
f.spc.EXPECT().CreateTreeObject(mock.Anything, mock.Anything).Return(sb, nil)
f.spc.EXPECT().Id().Return(spaceId)
f.lastUsedService.EXPECT().UpdateLastUsedDate(spaceId, bundle.TypeKeyTemplate, mock.Anything).Return()
// when
id, _, err := f.service.CreateObject(context.Background(), spaceId, CreateObjectRequest{
Details: &types.Struct{Fields: map[string]*types.Value{
bundle.RelationKeyTargetObjectType.String(): pbtypes.String(bundle.TypeKeyTask.URL()),
}},
ObjectTypeKey: bundle.TypeKeyTemplate,
})
// then
assert.NoError(t, err)
assert.Equal(t, "test", id)
})
t.Run("template creation - no target type", func(t *testing.T) {
// given
f := newFixture(t)
f.spaceService.EXPECT().Get(mock.Anything, mock.Anything).Return(f.spc, nil)
// when
_, _, err := f.service.CreateObject(context.Background(), spaceId, CreateObjectRequest{
ObjectTypeKey: bundle.TypeKeyTemplate,
})
// then
assert.Error(t, err)
})
}

View file

@ -11,9 +11,11 @@ import (
"github.com/anyproto/any-sync/commonspace/object/tree/synctree"
"github.com/anyproto/any-sync/commonspace/object/treemanager"
"github.com/anyproto/any-sync/commonspace/object/treesyncer"
"github.com/anyproto/any-sync/commonspace/spacestorage"
"github.com/anyproto/any-sync/net/peer"
"github.com/anyproto/any-sync/net/streampool"
"github.com/anyproto/any-sync/nodeconf"
"github.com/samber/lo"
"go.uber.org/zap"
)
@ -72,6 +74,7 @@ type treeSyncer struct {
requests int
spaceId string
timeout time.Duration
spaceSettingsId string
requestPools map[string]*executor
headPools map[string]*executor
treeManager treemanager.TreeManager
@ -97,6 +100,8 @@ func NewTreeSyncer(spaceId string) treesyncer.TreeSyncer {
func (t *treeSyncer) Init(a *app.App) (err error) {
t.isSyncing = true
spaceStorage := app.MustComponent[spacestorage.SpaceStorage](a)
t.spaceSettingsId = spaceStorage.SpaceSettingsId()
t.treeManager = app.MustComponent[treemanager.TreeManager](a)
t.nodeConf = app.MustComponent[nodeconf.NodeConf](a)
t.syncedTreeRemover = app.MustComponent[SyncedTreeRemover](a)
@ -157,7 +162,9 @@ func (t *treeSyncer) SyncAll(ctx context.Context, p peer.Peer, existing, missing
defer t.Unlock()
peerId := p.Id()
isResponsible := slices.Contains(t.nodeConf.NodeIds(t.spaceId), peerId)
t.sendSyncEvents(existing, missing, isResponsible)
t.sendSyncEvents(lo.Filter(existing, func(id string, index int) bool {
return id != t.spaceSettingsId
}), missing, isResponsible)
reqExec, exists := t.requestPools[peerId]
if !exists {
reqExec = newExecutor(t.requests, 0)

View file

@ -11,8 +11,11 @@ import (
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree/mock_objecttree"
"github.com/anyproto/any-sync/commonspace/object/tree/synctree/mock_synctree"
"github.com/anyproto/any-sync/commonspace/object/treemanager/mock_treemanager"
"github.com/anyproto/any-sync/commonspace/spacestorage/mock_spacestorage"
"github.com/anyproto/any-sync/net/peer"
"github.com/anyproto/any-sync/net/rpc/rpctest"
"github.com/anyproto/any-sync/nodeconf/mock_nodeconf"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
@ -40,9 +43,12 @@ func newFixture(t *testing.T, spaceId string) *fixture {
nodeConf.EXPECT().Name().Return("nodeConf").AnyTimes()
syncStatus := mock_treesyncer.NewMockSyncedTreeRemover(t)
syncDetailsUpdater := mock_treesyncer.NewMockSyncDetailsUpdater(t)
spaceStorage := mock_spacestorage.NewMockSpaceStorage(ctrl)
spaceStorage.EXPECT().SpaceSettingsId().Return("spaceSettingsId").AnyTimes()
a := new(app.App)
a.Register(testutil.PrepareMock(context.Background(), a, treeManager)).
Register(testutil.PrepareMock(context.Background(), a, spaceStorage)).
Register(testutil.PrepareMock(context.Background(), a, syncStatus)).
Register(testutil.PrepareMock(context.Background(), a, nodeConf)).
Register(testutil.PrepareMock(context.Background(), a, syncDetailsUpdater))
@ -62,7 +68,6 @@ func newFixture(t *testing.T, spaceId string) *fixture {
}
func TestTreeSyncer(t *testing.T) {
spaceId := "spaceId"
peerId := "peerId"
existingId := "existing"
@ -144,6 +149,27 @@ func TestTreeSyncer(t *testing.T) {
fx.Close(ctx)
})
t.Run("sync spaceSettingsId", func(t *testing.T) {
ctx := context.Background()
fx := newFixture(t, spaceId)
fx.nodeConf.EXPECT().NodeIds(spaceId).Return(nil)
fx.syncStatus.EXPECT().RemoveAllExcept(peerId, mock.Anything).RunAndReturn(func(s string, strings []string) {
require.Empty(t, strings)
})
ch := make(chan struct{})
fx.treeManager.EXPECT().GetTree(gomock.Any(), spaceId, "spaceSettingsId").Return(fx.existingMock, nil)
fx.existingMock.EXPECT().SyncWithPeer(gomock.Any(), pr).DoAndReturn(func(ctx context.Context, peer peer.Peer) error {
close(ch)
return nil
})
fx.StartSync()
err := fx.SyncAll(context.Background(), pr, []string{"spaceSettingsId"}, nil)
require.NoError(t, err)
<-ch
fx.Close(ctx)
})
t.Run("sync concurrent ids", func(t *testing.T) {
ctx := context.Background()
ch := make(chan struct{}, 2)
@ -185,9 +211,11 @@ func TestTreeSyncer(t *testing.T) {
mutex.Unlock()
return fx.missingMock, nil
})
fx.nodeConf.EXPECT().NodeIds(spaceId).Return([]string{})
fx.nodeConf.EXPECT().NodeIds(spaceId).Return(nil)
var existing []string
fx.syncStatus.EXPECT().RemoveAllExcept(peerId, existing).Return()
fx.syncStatus.EXPECT().RemoveAllExcept(peerId, mock.Anything).RunAndReturn(func(s string, strings []string) {
require.Empty(t, strings)
})
fx.StartSync()
err := fx.SyncAll(context.Background(), pr, existing, []string{missingId})

View file

@ -24,7 +24,7 @@ var (
model.Restrictions_Template,
model.Restrictions_Duplicate,
}
objFileRestrictions = ObjectRestrictions{
objRestrictEditAndDuplicate = ObjectRestrictions{
model.Restrictions_Blocks,
model.Restrictions_LayoutChange,
model.Restrictions_TypeChange,
@ -63,7 +63,7 @@ var (
model.ObjectType_collection: objRestrictEdit,
model.ObjectType_objectType: objRestrictEdit,
model.ObjectType_relation: objRestrictEdit,
model.ObjectType_file: objFileRestrictions,
model.ObjectType_file: objRestrictEditAndDuplicate,
model.ObjectType_dashboard: {
model.Restrictions_Details,
model.Restrictions_Relations,
@ -85,8 +85,8 @@ var (
model.Restrictions_Template,
},
model.ObjectType_participant: objRestrictAll,
model.ObjectType_chat: objRestrictEdit,
model.ObjectType_chatDerived: objRestrictEdit,
model.ObjectType_chat: objRestrictEditAndDuplicate,
model.ObjectType_chatDerived: objRestrictEditAndDuplicate,
model.ObjectType_tag: objRestrictEdit,
}
@ -117,7 +117,7 @@ var (
model.Restrictions_Template,
model.Restrictions_Duplicate,
},
smartblock.SmartBlockTypeFileObject: objFileRestrictions,
smartblock.SmartBlockTypeFileObject: objRestrictEditAndDuplicate,
smartblock.SmartBlockTypeArchive: objRestrictAll,
smartblock.SmartBlockTypeBundledRelation: objRestrictAll,
smartblock.SmartBlockTypeSubObject: objRestrictEdit,
@ -143,7 +143,9 @@ var (
smartblock.SmartBlockTypeAccountOld: {
model.Restrictions_Template,
},
smartblock.SmartBlockTypeParticipant: objRestrictAll,
smartblock.SmartBlockTypeParticipant: objRestrictAll,
smartblock.SmartBlockTypeChatObject: objRestrictEditAndDuplicate,
smartblock.SmartBlockTypeChatDerivedObject: objRestrictEditAndDuplicate,
}
)

View file

@ -92,6 +92,12 @@ func TestService_ObjectRestrictionsById(t *testing.T) {
bundledRelation := givenRestrictionHolder(coresb.SmartBlockTypeBundledRelation, bundle.TypeKeyRelation)
assert.ErrorIs(t, rs.GetRestrictions(bundledRelation).Object.Check(objRestrictAll...), ErrRestricted)
})
t.Run("chat should have edit and duplication restrictions", func(t *testing.T) {
assert.ErrorIs(t, rs.GetRestrictions(givenRestrictionHolder(coresb.SmartBlockTypeChatObject, bundle.TypeKeyChat)).Object.Check(
objRestrictEditAndDuplicate...,
), ErrRestricted)
})
}
func TestTemplateRestriction(t *testing.T) {

View file

@ -39,6 +39,7 @@ import (
"github.com/anyproto/anytype-heart/pb"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
"github.com/anyproto/anytype-heart/pkg/lib/core"
coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
"github.com/anyproto/anytype-heart/pkg/lib/database"
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
"github.com/anyproto/anytype-heart/pkg/lib/logging"
@ -300,6 +301,54 @@ func (s *Service) SpaceInstallBundledObjects(
return s.objectCreator.InstallBundledObjects(ctx, spc, sourceObjectIds, false)
}
func (s *Service) SpaceInitChat(ctx context.Context, spaceId string) error {
spc, err := s.spaceService.Get(ctx, spaceId)
if err != nil {
return fmt.Errorf("get space: %w", err)
}
if spc.IsReadOnly() {
return nil
}
if spc.IsPersonal() {
return nil
}
workspaceId := spc.DerivedIDs().Workspace
chatUk, err := domain.NewUniqueKey(coresb.SmartBlockTypeChatDerivedObject, workspaceId)
if err != nil {
return err
}
chatId, err := spc.DeriveObjectID(context.Background(), chatUk)
if err != nil {
return err
}
if spaceChatExists, err := spc.Storage().HasTree(chatId); err != nil {
return err
} else if !spaceChatExists {
_, err = s.objectCreator.AddChatDerivedObject(ctx, spc, workspaceId)
if err != nil {
if !errors.Is(err, treestorage.ErrTreeExists) {
return fmt.Errorf("add chat derived object: %w", err)
}
}
}
err = spc.DoCtx(ctx, workspaceId, func(b smartblock.SmartBlock) error {
st := b.NewState()
st.SetLocalDetail(bundle.RelationKeyChatId.String(), pbtypes.String(chatId))
st.SetDetail(bundle.RelationKeyHasChat.String(), pbtypes.Bool(true))
return b.Apply(st, smartblock.NoHistory, smartblock.NoEvent, smartblock.SkipIfNoChanges, smartblock.KeepInternalFlags, smartblock.IgnoreNoPermissions)
})
if err != nil {
return fmt.Errorf("apply chatId to workspace: %w", err)
}
return nil
}
func (s *Service) SelectWorkspace(req *pb.RpcWorkspaceSelectRequest) error {
panic("should be removed")
}

View file

@ -17,17 +17,18 @@ import (
"github.com/anyproto/anytype-heart/util/pbtypes"
)
func NewDate(space Space, id string) (s Source) {
func NewDate(space Space, id domain.FullID) (s Source) {
return &date{
id: id,
space: space,
id: id.ObjectID,
spaceId: id.SpaceID,
space: space,
}
}
type date struct {
space Space
id string
t time.Time
space Space
id, spaceId string
t time.Time
}
func (v *date) ListIds() ([]string, error) {
@ -43,10 +44,13 @@ func (v *date) Id() string {
}
func (v *date) SpaceID() string {
if v.space == nil {
return ""
if v.space != nil {
return v.space.Id()
}
return v.space.Id()
if v.spaceId != "" {
return v.spaceId
}
return ""
}
func (v *date) Type() smartblock.SmartBlockType {
@ -63,7 +67,7 @@ func (v *date) getDetails(ctx context.Context) (*domain.Details, error) {
return nil, fmt.Errorf("get date type id: %w", err)
}
det := domain.NewDetails()
det.SetString(bundle.RelationKeyName, v.t.Format("Mon Jan 2 2006"))
det.SetString(bundle.RelationKeyName, v.t.Format("02 Jan 2006"))
det.SetString(bundle.RelationKeyId, v.id)
det.SetBool(bundle.RelationKeyIsReadonly, true)
det.SetBool(bundle.RelationKeyIsArchived, false)
@ -82,7 +86,7 @@ func (v *date) DetailsFromId() (*domain.Details, error) {
return nil, err
}
det := domain.NewDetails()
det.SetString(bundle.RelationKeyName, v.t.Format("Mon Jan 2 2006"))
det.SetString(bundle.RelationKeyName, v.t.Format("02 Jan 2006"))
det.SetString(bundle.RelationKeyId, v.id)
det.SetBool(bundle.RelationKeyIsReadonly, true)
det.SetBool(bundle.RelationKeyIsArchived, false)
@ -179,10 +183,10 @@ func (v *date) Heads() []string {
return []string{v.id}
}
func (s *date) GetFileKeysSnapshot() []*pb.ChangeFileKeys {
func (v *date) GetFileKeysSnapshot() []*pb.ChangeFileKeys {
return nil
}
func (s *date) GetCreationInfo() (creatorObjectId string, createdDate int64, err error) {
func (v *date) GetCreationInfo() (creatorObjectId string, createdDate int64, err error) {
return addr.AnytypeProfileId, 0, nil
}

View file

@ -19,26 +19,26 @@ var text = "-- Еh bien, mon prince. Gênes et Lucques ne sont plus que des apan
func TestMarshallChange(t *testing.T) {
t.Run("marshall small change", func(t *testing.T) {
//given
// given
c := changeWithSmallTextUpdate()
//when
// when
data, dt, err := MarshalChange(c)
//then
// then
assert.NoError(t, err)
assert.NotZero(t, len(data))
assert.Empty(t, dt)
})
t.Run("marshall bigger change", func(t *testing.T) {
//given
// given
c := changeWithSetBigDetail(snappyLowerLimit)
//when
// when
data, dt, err := MarshalChange(c)
//then
// then
assert.NoError(t, err)
assert.NotEmpty(t, data)
assert.Equal(t, dataTypeSnappy, dt)
@ -49,97 +49,97 @@ func TestUnmarshallChange(t *testing.T) {
invalidDataType := "invalid"
t.Run("unmarshall small change", func(t *testing.T) {
//given
// given
c := changeWithSmallTextUpdate()
data, dt, err := MarshalChange(c)
require.NoError(t, err)
require.NotEmpty(t, data)
require.Empty(t, dt)
//when
// when
res, err := UnmarshalChange(&objecttree.Change{DataType: dt}, data)
//then
// then
assert.NoError(t, err)
assert.Equal(t, c, res)
})
t.Run("unmarshall bigger change", func(t *testing.T) {
//given
// given
c := changeWithSetBigDetail(snappyLowerLimit)
data, dt, err := MarshalChange(c)
require.NoError(t, err)
require.NotEmpty(t, data)
require.Equal(t, dataTypeSnappy, dt)
//when
// when
res, err := UnmarshalChange(&objecttree.Change{DataType: dt}, data)
//then
// then
assert.NoError(t, err)
assert.Equal(t, c, res)
})
t.Run("unmarshall plain change with invalid data type", func(t *testing.T) {
//given
// given
c := changeWithSmallTextUpdate()
data, dt, err := MarshalChange(c)
require.NoError(t, err)
require.NotEmpty(t, data)
require.Empty(t, dt)
//when
// when
res, err := UnmarshalChange(&objecttree.Change{DataType: invalidDataType}, data)
//then
// then
assert.NoError(t, err)
assert.Equal(t, c, res)
})
t.Run("unmarshall plain change with encoded data type", func(t *testing.T) {
//given
// given
c := changeWithSmallTextUpdate()
data, dt, err := MarshalChange(c)
require.NoError(t, err)
require.NotEmpty(t, data)
require.Empty(t, dt)
//when
// when
res, err := UnmarshalChange(&objecttree.Change{DataType: dataTypeSnappy}, data)
//then
// then
assert.NoError(t, err)
assert.Equal(t, c, res)
})
t.Run("unmarshall bigger change with empty data type", func(t *testing.T) {
//given
// given
c := changeWithSetBigDetail(snappyLowerLimit)
data, dt, err := MarshalChange(c)
require.NoError(t, err)
require.NotEmpty(t, data)
require.Equal(t, dataTypeSnappy, dt)
//when
// when
res, err := UnmarshalChange(&objecttree.Change{DataType: ""}, data)
//then
// then
assert.Error(t, err)
assert.Nil(t, res)
})
t.Run("unmarshall encoded change with invalid data type", func(t *testing.T) {
//given
// given
c := changeWithSetBigDetail(snappyLowerLimit)
data, dt, err := MarshalChange(c)
require.NoError(t, err)
require.NotEmpty(t, data)
require.Equal(t, dataTypeSnappy, dt)
//when
// when
res, err := UnmarshalChange(&objecttree.Change{DataType: invalidDataType}, data)
//then
// then
assert.Error(t, err)
assert.Nil(t, res)
})

View file

@ -14,6 +14,8 @@ import (
smartblock "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
source "github.com/anyproto/anytype-heart/core/block/source"
types "github.com/gogo/protobuf/types"
)
// MockService is an autogenerated mock type for the Service type
@ -30,27 +32,27 @@ func (_m *MockService) EXPECT() *MockService_Expecter {
}
// DetailsFromIdBasedSource provides a mock function with given fields: id
func (_m *MockService) DetailsFromIdBasedSource(id string) (*domain.GenericMap[domain.RelationKey], error) {
func (_m *MockService) DetailsFromIdBasedSource(id domain.FullID) (*types.Struct, error) {
ret := _m.Called(id)
if len(ret) == 0 {
panic("no return value specified for DetailsFromIdBasedSource")
}
var r0 *domain.GenericMap[domain.RelationKey]
var r0 *types.Struct
var r1 error
if rf, ok := ret.Get(0).(func(string) (*domain.GenericMap[domain.RelationKey], error)); ok {
if rf, ok := ret.Get(0).(func(domain.FullID) (*types.Struct, error)); ok {
return rf(id)
}
if rf, ok := ret.Get(0).(func(string) *domain.GenericMap[domain.RelationKey]); ok {
if rf, ok := ret.Get(0).(func(domain.FullID) *types.Struct); ok {
r0 = rf(id)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*domain.GenericMap[domain.RelationKey])
r0 = ret.Get(0).(*types.Struct)
}
}
if rf, ok := ret.Get(1).(func(string) error); ok {
if rf, ok := ret.Get(1).(func(domain.FullID) error); ok {
r1 = rf(id)
} else {
r1 = ret.Error(1)
@ -65,24 +67,24 @@ type MockService_DetailsFromIdBasedSource_Call struct {
}
// DetailsFromIdBasedSource is a helper method to define mock.On call
// - id string
// - id domain.FullID
func (_e *MockService_Expecter) DetailsFromIdBasedSource(id interface{}) *MockService_DetailsFromIdBasedSource_Call {
return &MockService_DetailsFromIdBasedSource_Call{Call: _e.mock.On("DetailsFromIdBasedSource", id)}
}
func (_c *MockService_DetailsFromIdBasedSource_Call) Run(run func(id string)) *MockService_DetailsFromIdBasedSource_Call {
func (_c *MockService_DetailsFromIdBasedSource_Call) Run(run func(id domain.FullID)) *MockService_DetailsFromIdBasedSource_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
run(args[0].(domain.FullID))
})
return _c
}
func (_c *MockService_DetailsFromIdBasedSource_Call) Return(_a0 *domain.GenericMap[domain.RelationKey], _a1 error) *MockService_DetailsFromIdBasedSource_Call {
func (_c *MockService_DetailsFromIdBasedSource_Call) Return(_a0 *types.Struct, _a1 error) *MockService_DetailsFromIdBasedSource_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockService_DetailsFromIdBasedSource_Call) RunAndReturn(run func(string) (*domain.GenericMap[domain.RelationKey], error)) *MockService_DetailsFromIdBasedSource_Call {
func (_c *MockService_DetailsFromIdBasedSource_Call) RunAndReturn(run func(domain.FullID) (*types.Struct, error)) *MockService_DetailsFromIdBasedSource_Call {
_c.Call.Return(run)
return _c
}

View file

@ -53,7 +53,7 @@ type Service interface {
RegisterStaticSource(s Source) error
NewStaticSource(params StaticSourceParams) SourceWithType
DetailsFromIdBasedSource(id string) (*domain.Details, error)
DetailsFromIdBasedSource(id domain.FullID) (*domain.Details, error)
IDsListerBySmartblockType(space Space, blockType smartblock.SmartBlockType) (IDsLister, error)
app.Component
}
@ -140,7 +140,10 @@ func (s *service) newSource(ctx context.Context, space Space, id string, buildOp
if err == nil {
switch st {
case smartblock.SmartBlockTypeDate:
return NewDate(space, id), nil
return NewDate(space, domain.FullID{
ObjectID: id,
SpaceID: space.Id(),
}), nil
case smartblock.SmartBlockTypeBundledObjectType:
return NewBundledObjectType(id), nil
case smartblock.SmartBlockTypeBundledRelation:
@ -201,11 +204,10 @@ func (s *service) IDsListerBySmartblockType(space Space, blockType smartblock.Sm
}
}
func (s *service) DetailsFromIdBasedSource(id string) (*domain.Details, error) {
if !strings.HasPrefix(id, addr.DatePrefix) {
func (s *service) DetailsFromIdBasedSource(id domain.FullID) (*domain.Details, error) {
if !strings.HasPrefix(id.ObjectID, addr.DatePrefix) {
return nil, fmt.Errorf("unsupported id")
}
// TODO Fix this, but how? It's broken by design, because no one pass spaceId here
ss := NewDate(nil, id)
defer ss.Close()
if v, ok := ss.(SourceIdEndodedDetails); ok {

View file

@ -5,6 +5,7 @@ package dot
import (
"bytes"
"context"
"fmt"
"io/ioutil"
@ -42,6 +43,7 @@ type linkInfo struct {
}
type dot struct {
ctx context.Context
graph *cgraph.Graph
graphviz *graphviz.Graphviz
knownDocs map[string]*domain.Details
@ -57,13 +59,18 @@ func NewMultiConverter(
format graphviz.Format,
sbtProvider typeprovider.SmartBlockTypeProvider,
) converter.MultiConverter {
g := graphviz.New()
ctx := context.Background()
g, err := graphviz.New(ctx)
if err != nil {
return nil
}
graph, err := g.Graph()
if err != nil {
return nil
}
return &dot{
ctx: ctx,
graph: graph,
graphviz: g,
exportFormat: format,
@ -87,7 +94,7 @@ func (d *dot) ImageHashes() []string {
}
func (d *dot) Add(space smartblock.Space, st *state.State) error {
n, e := d.graph.CreateNode(st.RootId())
n, e := d.graph.CreateNodeByName(st.RootId())
if e != nil {
return e
}
@ -158,7 +165,7 @@ func (d *dot) Convert(sbType model.SmartBlockType) []byte {
if !exists {
continue
}
e, err = d.graph.CreateEdge("", source, target)
e, err = d.graph.CreateEdgeByName("", source, target)
if err != nil {
return nil
}
@ -172,7 +179,7 @@ func (d *dot) Convert(sbType model.SmartBlockType) []byte {
}
var buf bytes.Buffer
if err = d.graphviz.Render(d.graph, d.exportFormat, &buf); err != nil {
if err = d.graphviz.Render(d.ctx, d.graph, d.exportFormat, &buf); err != nil {
return nil
}

View file

@ -3,10 +3,12 @@ package core
import (
"context"
"github.com/anyproto/anytype-heart/core/application"
"github.com/anyproto/anytype-heart/core/block"
"github.com/anyproto/anytype-heart/core/debug"
"github.com/anyproto/anytype-heart/core/subscription"
"github.com/anyproto/anytype-heart/pb"
"github.com/anyproto/anytype-heart/pkg/lib/environment"
)
func (mw *Middleware) DebugTree(cctx context.Context, req *pb.RpcDebugTreeRequest) *pb.RpcDebugTreeResponse {
@ -238,6 +240,21 @@ func (mw *Middleware) DebugAccountSelectTrace(cctx context.Context, req *pb.RpcD
}
}
func (mw *Middleware) DebugExportLog(cctx context.Context, req *pb.RpcDebugExportLogRequest) *pb.RpcDebugExportLogResponse {
path, err := mw.applicationService.SaveLog(environment.LOG_PATH, req.Dir)
code := mapErrorCode(err,
errToCode(application.ErrNoFolder, pb.RpcDebugExportLogResponseError_NO_FOLDER),
)
return &pb.RpcDebugExportLogResponse{
Path: path,
Error: &pb.RpcDebugExportLogResponseError{
Code: code,
Description: getErrorDescription(err),
},
}
}
func (mw *Middleware) DebugAnystoreObjectChanges(cctx context.Context, req *pb.RpcDebugAnystoreObjectChangesRequest) *pb.RpcDebugAnystoreObjectChangesResponse {
debugService := getService[debug.Debug](mw)
changes, wrongOrder, err := debugService.DebugAnystoreObjectChanges(cctx, req.ObjectId, req.OrderBy)
@ -255,3 +272,19 @@ func (mw *Middleware) DebugAnystoreObjectChanges(cctx context.Context, req *pb.R
WrongOrder: wrongOrder,
}
}
func (mw *Middleware) DebugNetCheck(cctx context.Context, req *pb.RpcDebugNetCheckRequest) *pb.RpcDebugNetCheckResponse {
res, err := getService[debug.Debug](mw).NetCheck(cctx, req.ClientYml)
if err != nil {
return &pb.RpcDebugNetCheckResponse{
Error: &pb.RpcDebugNetCheckResponseError{
Code: pb.RpcDebugNetCheckResponseError_UNKNOWN_ERROR,
Description: getErrorDescription(err),
},
}
}
return &pb.RpcDebugNetCheckResponse{
Result: res,
}
}

View file

@ -9,6 +9,7 @@
package debug
import (
"context"
"os"
"github.com/goccy/go-graphviz"
@ -28,6 +29,10 @@ func GraphvizSvg(gv, svgFilename string) (err error) {
}
defer f.Close()
g := graphviz.New()
return g.Render(gvo, graphviz.SVG, f)
ctx := context.Background()
g, err := graphviz.New(ctx)
if err != nil {
return err
}
return g.Render(ctx, gvo, graphviz.SVG, f)
}

317
core/debug/netcheck.go Normal file
View file

@ -0,0 +1,317 @@
package debug
import (
"context"
"fmt"
"net"
"os"
"strings"
"time"
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/coordinator/coordinatorproto"
"github.com/anyproto/any-sync/net/connutil"
"github.com/anyproto/any-sync/net/secureservice"
"github.com/anyproto/any-sync/net/secureservice/handshake"
"github.com/anyproto/any-sync/net/secureservice/handshake/handshakeproto"
"github.com/anyproto/any-sync/net/transport"
"github.com/anyproto/any-sync/net/transport/quic"
"github.com/anyproto/any-sync/net/transport/yamux"
"github.com/anyproto/any-sync/nodeconf"
"github.com/anyproto/any-sync/testutil/accounttest"
"github.com/anyproto/go-chash"
yamux2 "github.com/hashicorp/yamux"
"github.com/matishsiao/goInfo"
"gopkg.in/yaml.v3"
"storj.io/drpc/drpcconn"
)
func (d *debug) NetCheck(ctx context.Context, clientYml string) (string, error) {
var sb strings.Builder
var checkAddrs []string
if clientYml != "" {
file, err := os.ReadFile(clientYml)
if err != nil {
return "", err
}
var configFile nodeconf.Configuration
if err := yaml.Unmarshal(file, &configFile); err != nil {
return "", err
}
for _, node := range configFile.Nodes {
for _, t := range node.Types {
if t == "coordinator" {
for _, address := range node.Addresses {
if !strings.HasPrefix(address, "quic://") {
address = "yamux://" + address
}
checkAddrs = append(checkAddrs, address)
}
}
}
}
} else {
checkAddrs = strings.Split(defaultAddrs, ",")
}
info, err := goInfo.GetInfo()
if err != nil {
sb.WriteString(fmt.Sprintf("error getting system info: %s\n", err))
} else {
sb.WriteString(fmt.Sprintf("system info: %s\n", info.String()))
}
a := new(app.App)
bootstrap(a)
if err := a.Start(ctx); err != nil {
panic(err)
}
for _, addr := range checkAddrs {
addr = strings.TrimSpace(addr)
switch {
case strings.HasPrefix(addr, "yamux://"):
res, err := probeYamux(ctx, a, addr[8:])
if err != nil {
sb.WriteString(fmt.Sprintf("error probing yamux %s: %s\n", addr, err))
} else {
sb.WriteString(res)
}
case strings.HasPrefix(addr, "quic://"):
res, err := probeQuic(ctx, a, addr[7:])
if err != nil {
sb.WriteString(fmt.Sprintf("error probing yamux %s: %s\n", addr, err))
} else {
sb.WriteString(res)
}
default:
return "", fmt.Errorf("unexpected address scheme: %s", addr)
}
}
return sb.String(), err
}
func probeYamux(ctx context.Context, a *app.App, addr string) (string, error) {
var sb strings.Builder
ss := a.MustComponent(secureservice.CName).(secureservice.SecureService)
sb.WriteString(fmt.Sprintf("open TCP conn, addr: %s\n", addr))
st := time.Now()
conn, err := net.DialTimeout("tcp", addr, time.Second*60)
if err != nil {
return "", fmt.Errorf("open TCP conn error: %w, dur: %s", err, time.Since(st))
} else {
sb.WriteString(fmt.Sprintf("TCP conn established, ip:%s, dur: %s\n", conn.RemoteAddr().String(), time.Since(st)))
}
defer conn.Close()
sb.WriteString("start handshake\n")
hst := time.Now()
cctx, err := ss.SecureOutbound(ctx, conn)
if err != nil {
return "", fmt.Errorf("handshake error: %w, dur: %s", err, time.Since(hst))
} else {
sb.WriteString(fmt.Sprintf("handshake success, dur: %s, total: %s\n", time.Since(hst), time.Since(st)))
}
yst := time.Now()
sb.WriteString("open yamux session\n")
sess, err := yamux2.Client(conn, yamux2.DefaultConfig())
if err != nil {
return "", fmt.Errorf("yamux session error: %w, dur: %s", err, time.Since(yst))
} else {
sb.WriteString(fmt.Sprintf("yamux session success, dur: %s, total: %s\n", time.Since(yst), time.Since(st)))
}
mc := yamux.NewMultiConn(cctx, connutil.NewLastUsageConn(conn), conn.RemoteAddr().String(), sess)
sb.WriteString("open sub connection\n")
scst := time.Now()
sc, err := mc.Open(ctx)
if err != nil {
return "", fmt.Errorf("open sub connection error: %w, dur: %s", err, time.Since(scst))
} else {
sb.WriteString(fmt.Sprintf("open sub conn success, dur: %s, total: %s\n", time.Since(scst), time.Since(st)))
defer sc.Close()
}
sb.WriteString("start proto handshake\n")
phst := time.Now()
if err = handshake.OutgoingProtoHandshake(ctx, sc, handshakeproto.ProtoType_DRPC); err != nil {
return "", fmt.Errorf("proto handshake error: %w, dur: %s", err, time.Since(phst))
} else {
sb.WriteString(fmt.Sprintf("proto handshake success, dur: %s, total: %s\n", time.Since(phst), time.Since(st)))
}
sb.WriteString("start configuration request\n")
rst := time.Now()
resp, err := coordinatorproto.NewDRPCCoordinatorClient(drpcconn.New(sc)).NetworkConfiguration(ctx, &coordinatorproto.NetworkConfigurationRequest{})
if err != nil {
return "", fmt.Errorf("configuration request error: %w, dur: %s", err, time.Since(rst))
} else {
sb.WriteString(fmt.Sprintf("configuration request success, dur: %s, total: %s, nid: %s\n", time.Since(rst), time.Since(st), resp.GetNetworkId()))
}
sb.WriteString(fmt.Sprintf("success, dur: %s\n", time.Since(st)))
return sb.String(), nil
}
func probeQuic(ctx context.Context, a *app.App, addr string) (string, error) {
var sb strings.Builder
qs := a.MustComponent(quic.CName).(quic.Quic)
sb.WriteString(fmt.Sprintf("open QUIC conn, addr: %s\n", addr))
st := time.Now()
mc, err := qs.Dial(ctx, addr)
if err != nil {
return "", fmt.Errorf("open QUIC conn error: %w", err)
} else {
sb.WriteString(fmt.Sprintf("QUIC conn established, ip:%s, dur: %s\n", mc.Addr(), time.Since(st)))
}
defer mc.Close()
sb.WriteString("open sub connection\n")
scst := time.Now()
sc, err := mc.Open(ctx)
if err != nil {
return "", fmt.Errorf("open sub connection error: %w", err)
} else {
sb.WriteString(fmt.Sprintf("open sub conn success, dur: %s, total: %s\n", time.Since(scst), time.Since(st)))
defer sc.Close()
}
sb.WriteString("start proto handshake\n")
phst := time.Now()
if err = handshake.OutgoingProtoHandshake(ctx, sc, handshakeproto.ProtoType_DRPC); err != nil {
return "", fmt.Errorf("proto handshake error: %w", err)
} else {
sb.WriteString(fmt.Sprintf("proto handshake success, dur: %s, total: %s\n", time.Since(phst), time.Since(st)))
}
sb.WriteString("start configuration request\n")
rst := time.Now()
resp, err := coordinatorproto.NewDRPCCoordinatorClient(drpcconn.New(sc)).NetworkConfiguration(ctx, &coordinatorproto.NetworkConfigurationRequest{})
if err != nil {
return "", fmt.Errorf("configuration request error: %w", err)
} else {
sb.WriteString(fmt.Sprintf("configuration request success, dur: %s, total: %s, nid: %s\n", time.Since(rst), time.Since(st), resp.GetNetworkId()))
}
sb.WriteString(fmt.Sprintf("success, dur: %s\n", time.Since(st)))
return sb.String(), nil
}
func bootstrap(a *app.App) {
q := quic.New()
a.Register(&config{}).
Register(&nodeConf{}).
Register(q).
Register(&accounttest.AccountTestService{}).
Register(secureservice.New())
q.SetAccepter(new(accepter))
}
type config struct {
}
func (c config) Name() string { return "config" }
func (c config) Init(a *app.App) error { return nil }
func (c config) GetYamux() yamux.Config {
return yamux.Config{
WriteTimeoutSec: 60,
DialTimeoutSec: 60,
KeepAlivePeriodSec: 120,
}
}
func (c config) GetQuic() quic.Config {
return quic.Config{
WriteTimeoutSec: 60,
DialTimeoutSec: 60,
KeepAlivePeriodSec: 120,
}
}
type nodeConf struct {
}
func (n nodeConf) Id() string {
return "test"
}
func (n nodeConf) Configuration() nodeconf.Configuration {
return nodeconf.Configuration{
Id: "test",
NetworkId: "",
Nodes: nil,
CreationTime: time.Time{},
}
}
func (n nodeConf) NodeIds(spaceId string) []string {
return nil
}
func (n nodeConf) IsResponsible(spaceId string) bool {
return false
}
func (n nodeConf) FilePeers() []string {
return nil
}
func (n nodeConf) ConsensusPeers() []string {
return nil
}
func (n nodeConf) CoordinatorPeers() []string {
return nil
}
func (n nodeConf) NamingNodePeers() []string {
return nil
}
func (n nodeConf) PaymentProcessingNodePeers() []string {
return nil
}
func (n nodeConf) PeerAddresses(peerId string) (addrs []string, ok bool) {
return nil, false
}
func (n nodeConf) CHash() chash.CHash {
return nil
}
func (n nodeConf) Partition(spaceId string) (part int) {
return 0
}
func (n nodeConf) NodeTypes(nodeId string) []nodeconf.NodeType {
return []nodeconf.NodeType{nodeconf.NodeTypeCoordinator}
}
func (n nodeConf) NetworkCompatibilityStatus() nodeconf.NetworkCompatibilityStatus {
return 0
}
func (n nodeConf) Init(a *app.App) (err error) {
return nil
}
func (n nodeConf) Name() (name string) {
return nodeconf.CName
}
func (n nodeConf) Run(ctx context.Context) (err error) {
return nil
}
func (n nodeConf) Close(ctx context.Context) (err error) {
return nil
}
type accepter struct {
}
func (a accepter) Accept(mc transport.MultiConn) (err error) {
return nil
}

View file

@ -27,6 +27,7 @@ import (
"github.com/anyproto/anytype-heart/core/domain"
"github.com/anyproto/anytype-heart/pb"
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex"
"github.com/anyproto/anytype-heart/pkg/lib/logging"
"github.com/anyproto/anytype-heart/space"
)
@ -35,6 +36,16 @@ const CName = "debug"
var log = logging.Logger("anytype-debug")
const defaultAddrs = `
yamux://prod-any-sync-coordinator1.anyclub.org:443,
yamux://prod-any-sync-coordinator1.anyclub.org:1443,
yamux://prod-any-sync-coordinator1.toolpad.org:443,
yamux://prod-any-sync-coordinator1.toolpad.org:1443,
yamux://prod-any-sync-coordinator1.anytype.io:443,
yamux://prod-any-sync-coordinator1.anytype.io:1443,
quic://prod-any-sync-coordinator1.anyclub.org:5430
`
func New() Debug {
return new(debug)
}
@ -48,6 +59,7 @@ type Debug interface {
TreeHeads(ctx context.Context, id string) (info TreeInfo, err error)
DebugAnystoreObjectChanges(ctx context.Context, chatObjectId string, orderBy pb.RpcDebugAnystoreObjectChangesRequestOrderBy) ([]*pb.RpcDebugAnystoreObjectChangesResponseChange, bool, error)
NetCheck(ctx context.Context, clientYml string) (string, error)
}
type debug struct {
@ -237,13 +249,6 @@ func (d *debug) DumpTree(ctx context.Context, objectID string, path string, anon
}
func (d *debug) DumpLocalstore(ctx context.Context, spaceID string, objIds []string, path string) (filename string, err error) {
if len(objIds) == 0 {
objIds, err = d.store.ListIdsCrossSpace()
if err != nil {
return "", err
}
}
filename = filepath.Join(path, fmt.Sprintf("at.store.dbg.%s.zip", time.Now().Format("20060102.150405.99")))
f, err := os.Create(filename)
if err != nil {
@ -257,31 +262,38 @@ func (d *debug) DumpLocalstore(ctx context.Context, spaceID string, objIds []str
var wr io.Writer
m := jsonpb.Marshaler{Indent: " "}
store := d.store.SpaceIndex(spaceID)
for _, objId := range objIds {
doc, err := store.GetWithLinksInfoById(objId)
err = d.store.IterateSpaceIndex(func(store spaceindex.Store) error {
objIds, err = store.ListIds()
if err != nil {
var err2 error
wr, err2 = zw.Create(fmt.Sprintf("%s.txt", objId))
if err2 != nil {
return "", err
return err
}
for _, objId := range objIds {
doc, err := store.GetWithLinksInfoById(objId)
if err != nil {
var err2 error
wr, err2 = zw.Create(fmt.Sprintf("%s/%s.txt", store.SpaceId(), objId))
if err2 != nil {
return err
}
_, _ = wr.Write([]byte(err.Error()))
continue
}
wr, err = zw.Create(fmt.Sprintf("%s/%s.json", store.SpaceId(), objId))
if err != nil {
return err
}
wr.Write([]byte(err.Error()))
continue
}
wr, err = zw.Create(fmt.Sprintf("%s.json", objId))
if err != nil {
return "", err
err = m.Marshal(wr, doc)
if err != nil {
return err
}
}
return nil
})
err = m.Marshal(wr, doc)
if err != nil {
return "", err
}
}
return filename, nil
return filename, err
}
func (d *debug) DebugAnystoreObjectChanges(ctx context.Context, chatObjectId string, orderBy pb.RpcDebugAnystoreObjectChangesRequestOrderBy) ([]*pb.RpcDebugAnystoreObjectChangesResponseChange, bool, error) {

View file

@ -114,7 +114,7 @@ func (mw *Middleware) ObjectSetIsFavorite(_ context.Context, req *pb.RpcObjectSe
}
return m
}
err := getService[detailservice.Service](mw).SetIsFavorite(req.ContextId, req.IsFavorite)
err := getService[detailservice.Service](mw).SetIsFavorite(req.ContextId, req.IsFavorite, true)
if err != nil {
return response(pb.RpcObjectSetIsFavoriteResponseError_UNKNOWN_ERROR, err)
}

View file

@ -17,6 +17,10 @@ func (mw *Middleware) DeviceNetworkStateSet(cctx context.Context, req *pb.RpcDev
}
return m
}
app.MustComponent[device.NetworkState](mw.GetApp()).SetNetworkState(req.DeviceNetworkType)
mwApp := mw.GetApp()
if mwApp == nil {
return response(pb.RpcDeviceNetworkStateSetResponseError_INTERNAL_ERROR, ErrNotLoggedIn)
}
app.MustComponent[device.NetworkState](mwApp).SetNetworkState(req.DeviceNetworkType)
return response(pb.RpcDeviceNetworkStateSetResponseError_NULL, nil)
}

View file

@ -436,7 +436,7 @@ func TestGenericMap_ToProto(t *testing.T) {
"key-4": pbtypes.Bool(true),
"key-5": pbtypes.Bool(false),
"key-6": pbtypes.StringList([]string{"1", "2", "3"}),
"key-7": pbtypes.FloatList([]float64{1.1, 2.2, 3.3, 4.4}),
"key-7": pbtypes.Float64List([]float64{1.1, 2.2, 3.3, 4.4}),
"key-8": pbtypes.IntList(1, 2, 3),
"key-9": pbtypes.Struct(&types.Struct{
Fields: map[string]*types.Value{

View file

@ -425,7 +425,7 @@ func (v Value) ToProto() *types.Value {
case []string:
return pbtypes.StringList(v)
case []float64:
return pbtypes.FloatList(v)
return pbtypes.Float64List(v)
case ValueMap:
s := &types.Struct{Fields: make(map[string]*types.Value, v.Len())}
for k, val := range v.Iterate() {

View file

@ -149,5 +149,8 @@ func (f *fileStorage) NewLocalStoreGarbageCollector() LocalStoreGarbageCollector
}
func (f *fileStorage) Close(ctx context.Context) (err error) {
return f.proxy.Close()
if f.proxy != nil {
return f.proxy.Close()
}
return nil
}

View file

@ -315,6 +315,8 @@ func TestReindex_addSyncRelations(t *testing.T) {
fx.sourceFx.EXPECT().IDsListerBySmartblockType(space1, coresb.SmartBlockTypeObjectType).Return(idsLister{Ids: []string{}}, nil)
fx.sourceFx.EXPECT().IDsListerBySmartblockType(space1, coresb.SmartBlockTypeTemplate).Return(idsLister{Ids: []string{}}, nil)
fx.sourceFx.EXPECT().IDsListerBySmartblockType(space1, coresb.SmartBlockTypeProfilePage).Return(idsLister{Ids: []string{}}, nil)
fx.sourceFx.EXPECT().IDsListerBySmartblockType(space1, coresb.SmartBlockTypeChatDerivedObject).Return(idsLister{Ids: []string{}}, nil)
fx.sourceFx.EXPECT().IDsListerBySmartblockType(space1, coresb.SmartBlockTypeChatObject).Return(idsLister{Ids: []string{}}, nil)
space1.EXPECT().DoLockedIfNotExists("1", mock.AnythingOfType("func() error")).Return(nil)
space1.EXPECT().DoLockedIfNotExists("2", mock.AnythingOfType("func() error")).Return(nil)
@ -352,6 +354,8 @@ func TestReindex_addSyncRelations(t *testing.T) {
fx.sourceFx.EXPECT().IDsListerBySmartblockType(space1, coresb.SmartBlockTypeObjectType).Return(idsLister{Ids: []string{}}, nil)
fx.sourceFx.EXPECT().IDsListerBySmartblockType(space1, coresb.SmartBlockTypeTemplate).Return(idsLister{Ids: []string{}}, nil)
fx.sourceFx.EXPECT().IDsListerBySmartblockType(space1, coresb.SmartBlockTypeProfilePage).Return(idsLister{Ids: []string{}}, nil)
fx.sourceFx.EXPECT().IDsListerBySmartblockType(space1, coresb.SmartBlockTypeChatDerivedObject).Return(idsLister{Ids: []string{}}, nil)
fx.sourceFx.EXPECT().IDsListerBySmartblockType(space1, coresb.SmartBlockTypeChatObject).Return(idsLister{Ids: []string{}}, nil)
space1.EXPECT().DoLockedIfNotExists("1", mock.AnythingOfType("func() error")).Return(nil)
space1.EXPECT().DoLockedIfNotExists("2", mock.AnythingOfType("func() error")).Return(nil)

View file

@ -6,11 +6,12 @@ import (
"github.com/anyproto/anytype-heart/metrics"
"github.com/anyproto/anytype-heart/pb"
"github.com/anyproto/anytype-heart/pkg/lib/logging"
)
func (mw *Middleware) MetricsSetParameters(cctx context.Context, req *pb.RpcMetricsSetParametersRequest) *pb.RpcMetricsSetParametersResponse {
response := func(code pb.RpcMetricsSetParametersResponseErrorCode, err error) *pb.RpcMetricsSetParametersResponse {
m := &pb.RpcMetricsSetParametersResponse{Error: &pb.RpcMetricsSetParametersResponseError{Code: code}}
func (mw *Middleware) InitialSetParameters(cctx context.Context, req *pb.RpcInitialSetParametersRequest) *pb.RpcInitialSetParametersResponse {
response := func(code pb.RpcInitialSetParametersResponseErrorCode, err error) *pb.RpcInitialSetParametersResponse {
m := &pb.RpcInitialSetParametersResponse{Error: &pb.RpcInitialSetParametersResponseError{Code: code}}
if err != nil {
m.Error.Description = getErrorDescription(err)
}
@ -18,13 +19,15 @@ func (mw *Middleware) MetricsSetParameters(cctx context.Context, req *pb.RpcMetr
return m
}
if req.Version == "" {
return response(pb.RpcMetricsSetParametersResponseError_BAD_INPUT,
return response(pb.RpcInitialSetParametersResponseError_BAD_INPUT,
errors.New("version is empty. Version must be in format: 1.0.0-optional-commit-hash-for-dev-builds"))
}
mw.applicationService.SetClientVersion(req.Platform, req.Version)
metrics.Service.SetPlatform(req.Platform)
metrics.Service.SetStartVersion(req.Version)
metrics.Service.SetEnabled(!req.DoNotSendTelemetry)
logging.Init(req.Workdir, req.LogLevel, !req.DoNotSendLogs, !req.DoNotSaveLogs)
return response(pb.RpcMetricsSetParametersResponseError_NULL, nil)
return response(pb.RpcInitialSetParametersResponseError_NULL, nil)
}

View file

@ -288,7 +288,7 @@ func (mw *Middleware) makeSuggestedDateRecord(ctx context.Context, spaceID strin
}
d := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
bundle.RelationKeyId: domain.String(id),
bundle.RelationKeyName: domain.String(t.Format("Mon Jan 2 2006")),
bundle.RelationKeyName: domain.String(t.Format("02 Jan 2006")),
bundle.RelationKeyLayout: domain.Int64(model.ObjectType_date),
bundle.RelationKeyType: domain.String(typeId),
bundle.RelationKeyIconEmoji: domain.String("📅"),

View file

@ -381,17 +381,17 @@ func TestGetExpireTime(t *testing.T) {
for _, tc := range []struct {
name string
status *model.Membership
duration time.Duration
duration time.Time
}{
{"should return 10 minutes in case of nil", nil, cacheLifetimeDurOther},
{"should return 24 hours in case of Explorer", &model.Membership{Tier: 1}, cacheLifetimeDurExplorer},
{"should return 10 minutes in case of other", &model.Membership{Tier: 3}, cacheLifetimeDurOther},
{"should return 10 minutes in case of nil", nil, time.Now().UTC().Add(cacheLifetimeDurOther)},
{"should return 24 hours in case of Explorer", &model.Membership{Tier: 1}, time.Now().UTC().Add(cacheLifetimeDurExplorer)},
{"should return 10 minutes in case of other", &model.Membership{Tier: 3}, time.Now().UTC().Add(cacheLifetimeDurOther)},
{"should return dateEnds in case it is earlier than 10 minutes",
&model.Membership{Tier: 4, DateEnds: uint64(time.Now().UTC().Add(3 * time.Minute).Unix())}, 3 * time.Minute},
&model.Membership{Tier: 4, DateEnds: uint64(time.Now().UTC().Add(3 * time.Minute).Unix())}, time.Now().UTC().Add(3 * time.Minute)},
{"should return 10 minutes in case dateEnds is expired",
&model.Membership{Tier: 3, DateEnds: uint64(time.Now().UTC().Add(-10 * time.Hour).Unix())}, cacheLifetimeDurOther},
&model.Membership{Tier: 3, DateEnds: uint64(time.Now().UTC().Add(-10 * time.Hour).Unix())}, time.Now().UTC().Add(cacheLifetimeDurOther)},
{"should return 10 minutes in case dateEnds is 0",
&model.Membership{Tier: 3, DateEnds: uint64(time.Unix(0, 0).Unix())}, cacheLifetimeDurOther},
&model.Membership{Tier: 3, DateEnds: uint64(time.Unix(0, 0).Unix())}, time.Now().UTC().Add(cacheLifetimeDurOther)},
} {
t.Run(tc.name, func(t *testing.T) {
// given
@ -402,7 +402,7 @@ func TestGetExpireTime(t *testing.T) {
expire := getExpireTime(tc.status)
// then
assert.True(t, assertTimeNear(expire, time.Now().UTC().Add(tc.duration), delta))
assert.True(t, assertTimeNear(expire, tc.duration, delta))
})
}
}

View file

@ -14,6 +14,7 @@ import (
ppclient "github.com/anyproto/any-sync/paymentservice/paymentserviceclient"
proto "github.com/anyproto/any-sync/paymentservice/paymentserviceproto"
"github.com/anyproto/anytype-heart/core/anytype/config"
"github.com/anyproto/anytype-heart/core/event"
"github.com/anyproto/anytype-heart/core/filestorage/filesync"
"github.com/anyproto/anytype-heart/core/nameservice"
@ -123,6 +124,7 @@ func New() Service {
}
type service struct {
cfg *config.Config
cache cache.CacheService
ppclient ppclient.AnyPpClientService
wallet wallet.Wallet
@ -142,6 +144,7 @@ func (s *service) Name() (name string) {
}
func (s *service) Init(a *app.App) (err error) {
s.cfg = app.MustComponent[*config.Config](a)
s.cache = app.MustComponent[cache.CacheService](a)
s.ppclient = app.MustComponent[ppclient.AnyPpClientService](a)
s.wallet = app.MustComponent[wallet.Wallet](a)
@ -173,6 +176,12 @@ func (s *service) Close(_ context.Context) (err error) {
}
func (s *service) getPeriodicStatus(ctx context.Context) error {
// skip running loop if we are on a custom network or in local-only mode
if s.cfg.GetNetworkMode() != pb.RpcAccount_DefaultConfig {
// do not trace to log to prevent spamming
return nil
}
// get subscription status (from cache or from the PP node)
// if status has changed -> it will send events, etc
_, err := s.GetSubscriptionStatus(ctx, &pb.RpcMembershipGetStatusRequest{})

View file

@ -19,6 +19,7 @@ import (
mock_ppclient "github.com/anyproto/any-sync/paymentservice/paymentserviceclient/mock"
psp "github.com/anyproto/any-sync/paymentservice/paymentserviceproto"
"github.com/anyproto/anytype-heart/core/anytype/config"
"github.com/anyproto/anytype-heart/core/event/mock_event"
"github.com/anyproto/anytype-heart/core/filestorage/filesync/mock_filesync"
"github.com/anyproto/anytype-heart/core/nameservice/mock_nameservice"
@ -98,6 +99,7 @@ func newFixture(t *testing.T) *fixture {
fx.wallet.EXPECT().Account().Return(&ak).Maybe()
fx.wallet.EXPECT().GetAccountPrivkey().Return(decodedSignKey).Maybe()
fx.wallet.EXPECT().RepoPath().Return("repo/path")
fx.eventSender.EXPECT().Broadcast(mock.AnythingOfType("*pb.Event")).Maybe()
@ -111,9 +113,11 @@ func newFixture(t *testing.T) *fixture {
Register(fx.identitiesUpdater).
Register(testutil.PrepareMock(ctx, fx.a, fx.multiplayerLimitsUpdater)).
Register(testutil.PrepareMock(ctx, fx.a, fx.fileLimitsUpdater)).
Register(testutil.PrepareMock(ctx, fx.a, fx.ns))
Register(testutil.PrepareMock(ctx, fx.a, fx.ns)).
Register(&config.Config{DisableFileConfig: true, NetworkMode: pb.RpcAccount_DefaultConfig, PeferYamuxTransport: true})
require.NoError(t, fx.a.Start(ctx))
return fx
}

View file

@ -30,6 +30,7 @@ type collectionObserver struct {
objectStore spaceindex.Store
collectionService CollectionService
recBatch *mb.MB
recBatchMutex sync.Mutex
spaceSubscription *spaceSubscriptions
}
@ -97,9 +98,10 @@ func (c *collectionObserver) listEntries() []*entry {
return res
}
// updateIds updates the list of ids in the observer and updates the subscription
// IMPORTANT: this function is not thread-safe because of recBatch add is not under the lock and should be called only sequentially
func (c *collectionObserver) updateIds(ids []string) {
c.lock.Lock()
defer c.lock.Unlock()
removed, added := slice.DifferenceRemovedAdded(c.ids, ids)
for _, id := range removed {
@ -109,7 +111,7 @@ func (c *collectionObserver) updateIds(ids []string) {
c.idsSet[id] = struct{}{}
}
c.ids = ids
c.lock.Unlock()
entries := c.spaceSubscription.fetchEntriesLocked(append(removed, added...))
for _, e := range entries {
err := c.recBatch.Add(database.Record{

View file

@ -915,8 +915,10 @@ func (s *spaceSubscriptions) Close(ctx context.Context) (err error) {
s.m.Lock()
defer s.m.Unlock()
s.recBatch.Close()
s.iterateSubscriptions(func(sub subscription) {
for subId, sub := range s.subscriptions {
sub.close()
})
delete(s.subscriptions, subId)
}
s.subscriptionKeys = s.subscriptionKeys[:0]
return
}

View file

@ -34,5 +34,7 @@ func SyncRelationsSmartblockTypes() []smartblock.SmartBlockType {
smartblock.SmartBlockTypePage,
smartblock.SmartBlockTypeTemplate,
smartblock.SmartBlockTypeProfilePage,
smartblock.SmartBlockTypeChatDerivedObject,
smartblock.SmartBlockTypeChatObject,
}
}

View file

@ -231,10 +231,10 @@ func (u *syncStatusUpdater) setSyncDetails(sb smartblock.SmartBlock, status doma
if !slices.Contains(helper.SyncRelationsSmartblockTypes(), sb.Type()) {
return nil
}
st := sb.NewState()
if !u.isLayoutSuitableForSyncRelations(sb.Details()) {
return nil
}
st := sb.NewState()
if fileStatus, ok := st.Details().TryFloat64(bundle.RelationKeyFileBackupStatus); ok {
status, syncError = getSyncStatusForFile(status, syncError, filesyncstatus.Status(int(fileStatus)))
}
@ -261,6 +261,7 @@ var suitableLayouts = map[model.ObjectTypeLayout]struct{}{
model.ObjectType_audio: {},
model.ObjectType_video: {},
model.ObjectType_pdf: {},
model.ObjectType_chat: {},
}
func (u *syncStatusUpdater) isLayoutSuitableForSyncRelations(details *domain.Details) bool {

View file

@ -98,6 +98,7 @@ func TestSyncStatusUpdater_UpdateDetails(t *testing.T) {
sb := smarttest.New(objectId)
st := sb.Doc.(*state.State)
st.SetDetailAndBundledRelation(bundle.RelationKeyLayout, domain.Int64(int64(model.ObjectType_basic)))
st.SetDetailAndBundledRelation(bundle.RelationKeySpaceId, domain.String("spaceId"))
err := apply(sb)
require.NoError(t, err)
@ -164,6 +165,7 @@ func TestSyncStatusUpdater_UpdateDetails(t *testing.T) {
space.EXPECT().DoCtx(mock.Anything, mock.Anything, mock.Anything).Run(func(ctx context.Context, objectId string, apply func(smartblock.SmartBlock) error) {
sb := smarttest.New(objectId)
st := sb.Doc.(*state.State)
st.SetDetailAndBundledRelation(bundle.RelationKeySpaceId, pbtypes.String("spaceId"))
st.SetDetailAndBundledRelation(bundle.RelationKeyLayout, domain.Int64(int64(model.ObjectType_file)))
st.SetDetailAndBundledRelation(bundle.RelationKeyFileBackupStatus, domain.Int64(int64(filesyncstatus.Limited)))
err := apply(sb)
@ -193,6 +195,7 @@ func TestSyncStatusUpdater_UpdateDetails(t *testing.T) {
space.EXPECT().DoCtx(mock.Anything, mock.Anything, mock.Anything).Run(func(ctx context.Context, objectId string, apply func(smartblock.SmartBlock) error) {
sb := smarttest.New(objectId)
st := sb.Doc.(*state.State)
st.SetDetailAndBundledRelation(bundle.RelationKeySpaceId, pbtypes.String("spaceId"))
st.SetDetailAndBundledRelation(bundle.RelationKeyLayout, domain.Int64(int64(model.ObjectType_file)))
st.SetDetailAndBundledRelation(bundle.RelationKeyFileBackupStatus, domain.Int64(int64(filesyncstatus.Synced)))
err := apply(sb)
@ -244,6 +247,7 @@ func TestSyncStatusUpdater_UpdateSpaceDetails(t *testing.T) {
space.EXPECT().DoCtx(mock.Anything, objectId, mock.Anything).Run(func(ctx context.Context, objectId string, apply func(smartblock.SmartBlock) error) {
sb := smarttest.New(objectId)
st := sb.Doc.(*state.State)
st.SetDetailAndBundledRelation(bundle.RelationKeySpaceId, pbtypes.String("spaceId"))
st.SetDetailAndBundledRelation(bundle.RelationKeyLayout, domain.Int64(int64(model.ObjectType_basic)))
err := apply(sb)
require.NoError(t, err)
@ -277,7 +281,8 @@ func TestSyncStatusUpdater_setSyncDetails(t *testing.T) {
// given
fx := newFixture(t)
sb := smarttest.New("id")
st := sb.Doc.(*state.State)
st.SetDetailAndBundledRelation(bundle.RelationKeySpaceId, pbtypes.String("spaceId"))
// when
err := fx.setSyncDetails(sb, domain.ObjectSyncStatusError, domain.SyncErrorNetworkError)
assert.Nil(t, err)

View file

@ -42,11 +42,6 @@ func (s *syncingObjects) Run() error {
int64(domain.ObjectSyncStatusError),
}),
},
{
RelationKey: bundle.RelationKeySpaceId,
Condition: model.BlockContentDataviewFilter_Equal,
Value: domain.String(s.spaceId),
},
},
}
s.objectSubscription = objectsubscription.NewIdSubscription(s.service, objectReq)

View file

@ -6,12 +6,8 @@ import (
app "github.com/anyproto/any-sync/app"
accountdata "github.com/anyproto/any-sync/commonspace/object/accountdata"
common "github.com/ethereum/go-ethereum/common"
crypto "github.com/anyproto/any-sync/util/crypto"
ecdsa "crypto/ecdsa"
mock "github.com/stretchr/testify/mock"
wallet "github.com/anyproto/anytype-heart/core/wallet"
@ -78,19 +74,19 @@ func (_c *MockWallet_Account_Call) RunAndReturn(run func() *accountdata.AccountK
}
// GetAccountEthAddress provides a mock function with given fields:
func (_m *MockWallet) GetAccountEthAddress() common.Address {
func (_m *MockWallet) GetAccountEthAddress() wallet.EthAddress {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for GetAccountEthAddress")
}
var r0 common.Address
if rf, ok := ret.Get(0).(func() common.Address); ok {
var r0 wallet.EthAddress
if rf, ok := ret.Get(0).(func() wallet.EthAddress); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(common.Address)
r0 = ret.Get(0).(wallet.EthAddress)
}
}
@ -114,30 +110,30 @@ func (_c *MockWallet_GetAccountEthAddress_Call) Run(run func()) *MockWallet_GetA
return _c
}
func (_c *MockWallet_GetAccountEthAddress_Call) Return(_a0 common.Address) *MockWallet_GetAccountEthAddress_Call {
func (_c *MockWallet_GetAccountEthAddress_Call) Return(_a0 wallet.EthAddress) *MockWallet_GetAccountEthAddress_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockWallet_GetAccountEthAddress_Call) RunAndReturn(run func() common.Address) *MockWallet_GetAccountEthAddress_Call {
func (_c *MockWallet_GetAccountEthAddress_Call) RunAndReturn(run func() wallet.EthAddress) *MockWallet_GetAccountEthAddress_Call {
_c.Call.Return(run)
return _c
}
// GetAccountEthPrivkey provides a mock function with given fields:
func (_m *MockWallet) GetAccountEthPrivkey() *ecdsa.PrivateKey {
func (_m *MockWallet) GetAccountEthPrivkey() wallet.EthPrivateKey {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for GetAccountEthPrivkey")
}
var r0 *ecdsa.PrivateKey
if rf, ok := ret.Get(0).(func() *ecdsa.PrivateKey); ok {
var r0 wallet.EthPrivateKey
if rf, ok := ret.Get(0).(func() wallet.EthPrivateKey); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*ecdsa.PrivateKey)
r0 = ret.Get(0).(wallet.EthPrivateKey)
}
}
@ -161,12 +157,12 @@ func (_c *MockWallet_GetAccountEthPrivkey_Call) Run(run func()) *MockWallet_GetA
return _c
}
func (_c *MockWallet_GetAccountEthPrivkey_Call) Return(_a0 *ecdsa.PrivateKey) *MockWallet_GetAccountEthPrivkey_Call {
func (_c *MockWallet_GetAccountEthPrivkey_Call) Return(_a0 wallet.EthPrivateKey) *MockWallet_GetAccountEthPrivkey_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockWallet_GetAccountEthPrivkey_Call) RunAndReturn(run func() *ecdsa.PrivateKey) *MockWallet_GetAccountEthPrivkey_Call {
func (_c *MockWallet_GetAccountEthPrivkey_Call) RunAndReturn(run func() wallet.EthPrivateKey) *MockWallet_GetAccountEthPrivkey_Call {
_c.Call.Return(run)
return _c
}

View file

@ -16,8 +16,8 @@ import (
)
func (mw *Middleware) WorkspaceCreate(cctx context.Context, req *pb.RpcWorkspaceCreateRequest) *pb.RpcWorkspaceCreateResponse {
response := func(workspaceId string, code pb.RpcWorkspaceCreateResponseErrorCode, err error) *pb.RpcWorkspaceCreateResponse {
m := &pb.RpcWorkspaceCreateResponse{SpaceId: workspaceId, Error: &pb.RpcWorkspaceCreateResponseError{Code: code}}
response := func(spaceId string, code pb.RpcWorkspaceCreateResponseErrorCode, err error) *pb.RpcWorkspaceCreateResponse {
m := &pb.RpcWorkspaceCreateResponse{SpaceId: spaceId, Error: &pb.RpcWorkspaceCreateResponseError{Code: code}}
if err != nil {
m.Error.Description = getErrorDescription(err)
}
@ -25,16 +25,26 @@ func (mw *Middleware) WorkspaceCreate(cctx context.Context, req *pb.RpcWorkspace
return m
}
var workspaceId string
var spaceId string
err := mw.doBlockService(func(bs *block.Service) (err error) {
workspaceId, err = bs.CreateWorkspace(cctx, req)
spaceId, err = bs.CreateWorkspace(cctx, req)
if err != nil {
return
}
if req.WithChat {
// todo: as soon as it will be released for all users, we need to make it async inside the space init
err = bs.SpaceInitChat(cctx, spaceId)
if err != nil {
log.With("error", err).Warn("failed to init space level chat")
}
}
return
})
if err != nil {
return response("", pb.RpcWorkspaceCreateResponseError_UNKNOWN_ERROR, err)
}
return response(workspaceId, pb.RpcWorkspaceCreateResponseError_NULL, nil)
return response(spaceId, pb.RpcWorkspaceCreateResponseError_NULL, nil)
}
func (mw *Middleware) WorkspaceOpen(cctx context.Context, req *pb.RpcWorkspaceOpenRequest) *pb.RpcWorkspaceOpenResponse {
@ -54,10 +64,18 @@ func (mw *Middleware) WorkspaceOpen(cctx context.Context, req *pb.RpcWorkspaceOp
}
err = mw.doBlockService(func(bs *block.Service) error {
if req.WithChat {
// todo: as soon as it will be released for all users, we need to make it async inside the space init
err = bs.SpaceInitChat(cctx, req.SpaceId)
if err != nil {
log.With("error", err).Warn("failed to init space level chat")
}
}
return cache.Do[*editor.SpaceView](bs, info.SpaceViewId, func(sv *editor.SpaceView) error {
return sv.UpdateLastOpenedDate()
})
})
if err != nil {
return response(info, pb.RpcWorkspaceOpenResponseError_UNKNOWN_ERROR, err)
}

View file

@ -577,6 +577,14 @@
- [Rpc.Debug.ExportLocalstore.Request](#anytype-Rpc-Debug-ExportLocalstore-Request)
- [Rpc.Debug.ExportLocalstore.Response](#anytype-Rpc-Debug-ExportLocalstore-Response)
- [Rpc.Debug.ExportLocalstore.Response.Error](#anytype-Rpc-Debug-ExportLocalstore-Response-Error)
- [Rpc.Debug.ExportLog](#anytype-Rpc-Debug-ExportLog)
- [Rpc.Debug.ExportLog.Request](#anytype-Rpc-Debug-ExportLog-Request)
- [Rpc.Debug.ExportLog.Response](#anytype-Rpc-Debug-ExportLog-Response)
- [Rpc.Debug.ExportLog.Response.Error](#anytype-Rpc-Debug-ExportLog-Response-Error)
- [Rpc.Debug.NetCheck](#anytype-Rpc-Debug-NetCheck)
- [Rpc.Debug.NetCheck.Request](#anytype-Rpc-Debug-NetCheck-Request)
- [Rpc.Debug.NetCheck.Response](#anytype-Rpc-Debug-NetCheck-Response)
- [Rpc.Debug.NetCheck.Response.Error](#anytype-Rpc-Debug-NetCheck-Response-Error)
- [Rpc.Debug.OpenedObjects](#anytype-Rpc-Debug-OpenedObjects)
- [Rpc.Debug.OpenedObjects.Request](#anytype-Rpc-Debug-OpenedObjects-Request)
- [Rpc.Debug.OpenedObjects.Response](#anytype-Rpc-Debug-OpenedObjects-Response)
@ -698,6 +706,11 @@
- [Rpc.History.ShowVersion.Response](#anytype-Rpc-History-ShowVersion-Response)
- [Rpc.History.ShowVersion.Response.Error](#anytype-Rpc-History-ShowVersion-Response-Error)
- [Rpc.History.Version](#anytype-Rpc-History-Version)
- [Rpc.Initial](#anytype-Rpc-Initial)
- [Rpc.Initial.SetParameters](#anytype-Rpc-Initial-SetParameters)
- [Rpc.Initial.SetParameters.Request](#anytype-Rpc-Initial-SetParameters-Request)
- [Rpc.Initial.SetParameters.Response](#anytype-Rpc-Initial-SetParameters-Response)
- [Rpc.Initial.SetParameters.Response.Error](#anytype-Rpc-Initial-SetParameters-Response-Error)
- [Rpc.LinkPreview](#anytype-Rpc-LinkPreview)
- [Rpc.LinkPreview.Request](#anytype-Rpc-LinkPreview-Request)
- [Rpc.LinkPreview.Response](#anytype-Rpc-LinkPreview-Response)
@ -748,11 +761,6 @@
- [Rpc.Membership.VerifyEmailCode.Request](#anytype-Rpc-Membership-VerifyEmailCode-Request)
- [Rpc.Membership.VerifyEmailCode.Response](#anytype-Rpc-Membership-VerifyEmailCode-Response)
- [Rpc.Membership.VerifyEmailCode.Response.Error](#anytype-Rpc-Membership-VerifyEmailCode-Response-Error)
- [Rpc.Metrics](#anytype-Rpc-Metrics)
- [Rpc.Metrics.SetParameters](#anytype-Rpc-Metrics-SetParameters)
- [Rpc.Metrics.SetParameters.Request](#anytype-Rpc-Metrics-SetParameters-Request)
- [Rpc.Metrics.SetParameters.Response](#anytype-Rpc-Metrics-SetParameters-Response)
- [Rpc.Metrics.SetParameters.Response.Error](#anytype-Rpc-Metrics-SetParameters-Response-Error)
- [Rpc.NameService](#anytype-Rpc-NameService)
- [Rpc.NameService.ResolveAnyId](#anytype-Rpc-NameService-ResolveAnyId)
- [Rpc.NameService.ResolveAnyId.Request](#anytype-Rpc-NameService-ResolveAnyId-Request)
@ -1350,6 +1358,8 @@
- [Rpc.Debug.AnystoreObjectChanges.Request.OrderBy](#anytype-Rpc-Debug-AnystoreObjectChanges-Request-OrderBy)
- [Rpc.Debug.AnystoreObjectChanges.Response.Error.Code](#anytype-Rpc-Debug-AnystoreObjectChanges-Response-Error-Code)
- [Rpc.Debug.ExportLocalstore.Response.Error.Code](#anytype-Rpc-Debug-ExportLocalstore-Response-Error-Code)
- [Rpc.Debug.ExportLog.Response.Error.Code](#anytype-Rpc-Debug-ExportLog-Response-Error-Code)
- [Rpc.Debug.NetCheck.Response.Error.Code](#anytype-Rpc-Debug-NetCheck-Response-Error-Code)
- [Rpc.Debug.OpenedObjects.Response.Error.Code](#anytype-Rpc-Debug-OpenedObjects-Response-Error-Code)
- [Rpc.Debug.Ping.Response.Error.Code](#anytype-Rpc-Debug-Ping-Response-Error-Code)
- [Rpc.Debug.RunProfiler.Response.Error.Code](#anytype-Rpc-Debug-RunProfiler-Response-Error-Code)
@ -1378,6 +1388,7 @@
- [Rpc.History.GetVersions.Response.Error.Code](#anytype-Rpc-History-GetVersions-Response-Error-Code)
- [Rpc.History.SetVersion.Response.Error.Code](#anytype-Rpc-History-SetVersion-Response-Error-Code)
- [Rpc.History.ShowVersion.Response.Error.Code](#anytype-Rpc-History-ShowVersion-Response-Error-Code)
- [Rpc.Initial.SetParameters.Response.Error.Code](#anytype-Rpc-Initial-SetParameters-Response-Error-Code)
- [Rpc.LinkPreview.Response.Error.Code](#anytype-Rpc-LinkPreview-Response-Error-Code)
- [Rpc.Log.Send.Request.Level](#anytype-Rpc-Log-Send-Request-Level)
- [Rpc.Log.Send.Response.Error.Code](#anytype-Rpc-Log-Send-Response-Error-Code)
@ -1391,7 +1402,6 @@
- [Rpc.Membership.RegisterPaymentRequest.Response.Error.Code](#anytype-Rpc-Membership-RegisterPaymentRequest-Response-Error-Code)
- [Rpc.Membership.VerifyAppStoreReceipt.Response.Error.Code](#anytype-Rpc-Membership-VerifyAppStoreReceipt-Response-Error-Code)
- [Rpc.Membership.VerifyEmailCode.Response.Error.Code](#anytype-Rpc-Membership-VerifyEmailCode-Response-Error-Code)
- [Rpc.Metrics.SetParameters.Response.Error.Code](#anytype-Rpc-Metrics-SetParameters-Response-Error-Code)
- [Rpc.NameService.ResolveAnyId.Response.Error.Code](#anytype-Rpc-NameService-ResolveAnyId-Response-Error-Code)
- [Rpc.NameService.ResolveName.Response.Error.Code](#anytype-Rpc-NameService-ResolveName-Response-Error-Code)
- [Rpc.NameService.ResolveSpaceId.Response.Error.Code](#anytype-Rpc-NameService-ResolveSpaceId-Response-Error-Code)
@ -2153,7 +2163,9 @@
| DebugRunProfiler | [Rpc.Debug.RunProfiler.Request](#anytype-Rpc-Debug-RunProfiler-Request) | [Rpc.Debug.RunProfiler.Response](#anytype-Rpc-Debug-RunProfiler-Response) | |
| DebugAccountSelectTrace | [Rpc.Debug.AccountSelectTrace.Request](#anytype-Rpc-Debug-AccountSelectTrace-Request) | [Rpc.Debug.AccountSelectTrace.Response](#anytype-Rpc-Debug-AccountSelectTrace-Response) | |
| DebugAnystoreObjectChanges | [Rpc.Debug.AnystoreObjectChanges.Request](#anytype-Rpc-Debug-AnystoreObjectChanges-Request) | [Rpc.Debug.AnystoreObjectChanges.Response](#anytype-Rpc-Debug-AnystoreObjectChanges-Response) | |
| MetricsSetParameters | [Rpc.Metrics.SetParameters.Request](#anytype-Rpc-Metrics-SetParameters-Request) | [Rpc.Metrics.SetParameters.Response](#anytype-Rpc-Metrics-SetParameters-Response) | |
| DebugNetCheck | [Rpc.Debug.NetCheck.Request](#anytype-Rpc-Debug-NetCheck-Request) | [Rpc.Debug.NetCheck.Response](#anytype-Rpc-Debug-NetCheck-Response) | |
| DebugExportLog | [Rpc.Debug.ExportLog.Request](#anytype-Rpc-Debug-ExportLog-Request) | [Rpc.Debug.ExportLog.Response](#anytype-Rpc-Debug-ExportLog-Response) | |
| InitialSetParameters | [Rpc.Initial.SetParameters.Request](#anytype-Rpc-Initial-SetParameters-Request) | [Rpc.Initial.SetParameters.Response](#anytype-Rpc-Initial-SetParameters-Response) | |
| ListenSessionEvents | [StreamRequest](#anytype-StreamRequest) | [Event](#anytype-Event) stream | used only for lib-server via grpc |
| NotificationList | [Rpc.Notification.List.Request](#anytype-Rpc-Notification-List-Request) | [Rpc.Notification.List.Response](#anytype-Rpc-Notification-List-Response) | |
| NotificationReply | [Rpc.Notification.Reply.Request](#anytype-Rpc-Notification-Reply-Request) | [Rpc.Notification.Reply.Response](#anytype-Rpc-Notification-Reply-Response) | |
@ -10545,6 +10557,120 @@ Get marks list in the selected range in text block.
<a name="anytype-Rpc-Debug-ExportLog"></a>
### Rpc.Debug.ExportLog
<a name="anytype-Rpc-Debug-ExportLog-Request"></a>
### Rpc.Debug.ExportLog.Request
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| dir | [string](#string) | | empty means using OS-provided temp dir |
<a name="anytype-Rpc-Debug-ExportLog-Response"></a>
### Rpc.Debug.ExportLog.Response
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| error | [Rpc.Debug.ExportLog.Response.Error](#anytype-Rpc-Debug-ExportLog-Response-Error) | | |
| path | [string](#string) | | |
<a name="anytype-Rpc-Debug-ExportLog-Response-Error"></a>
### Rpc.Debug.ExportLog.Response.Error
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| code | [Rpc.Debug.ExportLog.Response.Error.Code](#anytype-Rpc-Debug-ExportLog-Response-Error-Code) | | |
| description | [string](#string) | | |
<a name="anytype-Rpc-Debug-NetCheck"></a>
### Rpc.Debug.NetCheck
<a name="anytype-Rpc-Debug-NetCheck-Request"></a>
### Rpc.Debug.NetCheck.Request
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| clientYml | [string](#string) | | |
<a name="anytype-Rpc-Debug-NetCheck-Response"></a>
### Rpc.Debug.NetCheck.Response
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| error | [Rpc.Debug.NetCheck.Response.Error](#anytype-Rpc-Debug-NetCheck-Response-Error) | | |
| result | [string](#string) | | |
<a name="anytype-Rpc-Debug-NetCheck-Response-Error"></a>
### Rpc.Debug.NetCheck.Response.Error
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| code | [Rpc.Debug.NetCheck.Response.Error.Code](#anytype-Rpc-Debug-NetCheck-Response-Error-Code) | | |
| description | [string](#string) | | |
<a name="anytype-Rpc-Debug-OpenedObjects"></a>
### Rpc.Debug.OpenedObjects
@ -12273,6 +12399,78 @@ returns blockShow event for given version
<a name="anytype-Rpc-Initial"></a>
### Rpc.Initial
<a name="anytype-Rpc-Initial-SetParameters"></a>
### Rpc.Initial.SetParameters
<a name="anytype-Rpc-Initial-SetParameters-Request"></a>
### Rpc.Initial.SetParameters.Request
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| platform | [string](#string) | | |
| version | [string](#string) | | |
| workdir | [string](#string) | | |
| logLevel | [string](#string) | | |
| doNotSendLogs | [bool](#bool) | | |
| doNotSaveLogs | [bool](#bool) | | |
| doNotSendTelemetry | [bool](#bool) | | |
<a name="anytype-Rpc-Initial-SetParameters-Response"></a>
### Rpc.Initial.SetParameters.Response
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| error | [Rpc.Initial.SetParameters.Response.Error](#anytype-Rpc-Initial-SetParameters-Response-Error) | | |
<a name="anytype-Rpc-Initial-SetParameters-Response-Error"></a>
### Rpc.Initial.SetParameters.Response.Error
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| code | [Rpc.Initial.SetParameters.Response.Error.Code](#anytype-Rpc-Initial-SetParameters-Response-Error-Code) | | |
| description | [string](#string) | | |
<a name="anytype-Rpc-LinkPreview"></a>
### Rpc.LinkPreview
@ -12987,73 +13185,6 @@ need a correct code that was sent to the user when calling GetVerificationEmail
<a name="anytype-Rpc-Metrics"></a>
### Rpc.Metrics
<a name="anytype-Rpc-Metrics-SetParameters"></a>
### Rpc.Metrics.SetParameters
<a name="anytype-Rpc-Metrics-SetParameters-Request"></a>
### Rpc.Metrics.SetParameters.Request
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| platform | [string](#string) | | |
| version | [string](#string) | | |
<a name="anytype-Rpc-Metrics-SetParameters-Response"></a>
### Rpc.Metrics.SetParameters.Response
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| error | [Rpc.Metrics.SetParameters.Response.Error](#anytype-Rpc-Metrics-SetParameters-Response-Error) | | |
<a name="anytype-Rpc-Metrics-SetParameters-Response-Error"></a>
### Rpc.Metrics.SetParameters.Response.Error
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| code | [Rpc.Metrics.SetParameters.Response.Error.Code](#anytype-Rpc-Metrics-SetParameters-Response-Error-Code) | | |
| description | [string](#string) | | |
<a name="anytype-Rpc-NameService"></a>
### Rpc.NameService
@ -19282,6 +19413,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er
| ----- | ---- | ----- | ----------- |
| details | [google.protobuf.Struct](#google-protobuf-Struct) | | object details |
| useCase | [Rpc.Object.ImportUseCase.Request.UseCase](#anytype-Rpc-Object-ImportUseCase-Request-UseCase) | | use case |
| withChat | [bool](#bool) | | create space-level chat; temporary solution, should be removed after chats released for all users |
@ -19686,6 +19818,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| spaceId | [string](#string) | | |
| withChat | [bool](#bool) | | create space-level chat if not exists; temporary solution, should be removed after chats released for all users |
@ -21594,6 +21727,33 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er
<a name="anytype-Rpc-Debug-ExportLog-Response-Error-Code"></a>
### Rpc.Debug.ExportLog.Response.Error.Code
| Name | Number | Description |
| ---- | ------ | ----------- |
| NULL | 0 | |
| UNKNOWN_ERROR | 1 | |
| BAD_INPUT | 2 | |
| NO_FOLDER | 3 | |
<a name="anytype-Rpc-Debug-NetCheck-Response-Error-Code"></a>
### Rpc.Debug.NetCheck.Response.Error.Code
| Name | Number | Description |
| ---- | ------ | ----------- |
| NULL | 0 | |
| UNKNOWN_ERROR | 1 | |
| BAD_INPUT | 2 | |
<a name="anytype-Rpc-Debug-OpenedObjects-Response-Error-Code"></a>
### Rpc.Debug.OpenedObjects.Response.Error.Code
@ -21964,6 +22124,19 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er
<a name="anytype-Rpc-Initial-SetParameters-Response-Error-Code"></a>
### Rpc.Initial.SetParameters.Response.Error.Code
| Name | Number | Description |
| ---- | ------ | ----------- |
| NULL | 0 | |
| UNKNOWN_ERROR | 1 | |
| BAD_INPUT | 2 | ... |
<a name="anytype-Rpc-LinkPreview-Response-Error-Code"></a>
### Rpc.LinkPreview.Response.Error.Code
@ -22205,19 +22378,6 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er
<a name="anytype-Rpc-Metrics-SetParameters-Response-Error-Code"></a>
### Rpc.Metrics.SetParameters.Response.Error.Code
| Name | Number | Description |
| ---- | ------ | ----------- |
| NULL | 0 | |
| UNKNOWN_ERROR | 1 | |
| BAD_INPUT | 2 | ... |
<a name="anytype-Rpc-NameService-ResolveAnyId-Response-Error-Code"></a>
### Rpc.NameService.ResolveAnyId.Response.Error.Code
@ -27475,6 +27635,7 @@ Contains basic information about a user account
| archiveObjectId | [string](#string) | | archive block id |
| profileObjectId | [string](#string) | | profile block id |
| marketplaceWorkspaceId | [string](#string) | | marketplace workspace id |
| workspaceObjectId | [string](#string) | | workspace object id. used for space-level chat |
| deviceId | [string](#string) | | |
| accountSpaceId | [string](#string) | | |
| widgetsId | [string](#string) | | |
@ -29877,7 +30038,7 @@ Look https://github.com/golang/protobuf/issues/1135 for more information.
| spaceView | 18 | |
| participant | 19 | |
| pdf | 20 | |
| chat | 21 | |
| chat | 21 | deprecated |
| chatDerived | 22 | |
| tag | 23 | |

22
go.mod
View file

@ -8,11 +8,12 @@ require (
github.com/VividCortex/ewma v1.2.0
github.com/adrium/goheif v0.0.0-20230113233934-ca402e77a786
github.com/anyproto/any-store v0.1.1
github.com/anyproto/any-sync v0.5.5
github.com/anyproto/any-sync v0.5.11
github.com/anyproto/go-chash v0.1.0
github.com/anyproto/go-naturaldate/v2 v2.0.2-0.20230524105841-9829cfd13438
github.com/anyproto/lexid v0.0.2
github.com/anyproto/protobuf v1.3.3-0.20240814124528-72b8c7e0e0f5
github.com/anyproto/tantivy-go v0.1.4
github.com/anyproto/tantivy-go v0.1.6-jieba
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
github.com/avast/retry-go/v4 v4.6.0
github.com/blevesearch/bleve/v2 v2.3.10
@ -31,7 +32,7 @@ require (
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8
github.com/go-chi/chi/v5 v5.0.13
github.com/go-shiori/go-readability v0.0.0-20220215145315-dd6828d2f09b
github.com/goccy/go-graphviz v0.1.3
github.com/goccy/go-graphviz v0.2.9
github.com/gogo/protobuf v1.3.2
github.com/gogo/status v1.1.1
github.com/golang-jwt/jwt v3.2.2+incompatible
@ -45,6 +46,7 @@ require (
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645
github.com/h2non/filetype v1.1.3
github.com/hashicorp/go-multierror v1.1.1
github.com/hashicorp/yamux v0.1.1
github.com/hbagdi/go-unsplash v0.0.0-20230414214043-474fc02c9119
github.com/huandu/skiplist v1.2.1
github.com/improbable-eng/grpc-web v0.15.0
@ -64,6 +66,7 @@ require (
github.com/libp2p/zeroconf/v2 v2.2.0
github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/magiconair/properties v1.8.7
github.com/matishsiao/goInfo v0.0.0-20240924010139-10388a85396f
github.com/mattn/go-sqlite3 v1.14.22
github.com/mb0/diff v0.0.0-20131118162322-d8d9a906c24d
github.com/microcosm-cc/bluemonday v1.0.25
@ -78,7 +81,7 @@ require (
github.com/otiai10/copy v1.14.0
github.com/otiai10/opengraph/v2 v2.1.0
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.20.4
github.com/prometheus/client_golang v1.20.5
github.com/pseudomuto/protoc-gen-doc v1.5.1
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd
github.com/samber/lo v1.47.0
@ -89,7 +92,7 @@ require (
github.com/stretchr/testify v1.9.0
github.com/uber/jaeger-client-go v2.30.0+incompatible
github.com/valyala/fastjson v1.6.4
github.com/vektra/mockery/v2 v2.42.2
github.com/vektra/mockery/v2 v2.46.3
github.com/xeipuuv/gojsonschema v1.2.0
github.com/yuin/goldmark v1.7.4
github.com/zeebo/blake3 v0.2.4
@ -99,12 +102,13 @@ require (
go.uber.org/zap v1.27.0
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c
golang.org/x/image v0.21.0
golang.org/x/mobile v0.0.0-20240806205939-81131f6468ab
golang.org/x/mobile v0.0.0-20241016134751-7ff83004ec2c
golang.org/x/net v0.30.0
golang.org/x/oauth2 v0.23.0
golang.org/x/text v0.19.0
google.golang.org/grpc v1.67.1
gopkg.in/Graylog2/go-gelf.v2 v2.0.0-20180125164251-1832d8546a9f
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/yaml.v3 v3.0.1
storj.io/drpc v0.0.34
zombiezen.com/go/sqlite v1.4.0
@ -121,7 +125,6 @@ require (
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect
github.com/andybalholm/cascadia v1.3.2 // indirect
github.com/anyproto/go-chash v0.1.0 // indirect
github.com/anyproto/go-slip10 v1.0.0 // indirect
github.com/anyproto/go-slip21 v1.0.0 // indirect
github.com/aymerick/douceur v0.2.0 // indirect
@ -161,6 +164,7 @@ require (
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
github.com/flopp/go-findfont v0.1.0 // indirect
github.com/fogleman/gg v1.3.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-errors/errors v1.4.2 // indirect
@ -186,7 +190,6 @@ require (
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/holiman/uint256 v1.2.4 // indirect
github.com/huandu/xstrings v1.4.0 // indirect
github.com/iancoleman/strcase v0.3.0 // indirect
@ -252,6 +255,7 @@ require (
github.com/spf13/viper v1.15.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
github.com/tetratelabs/wazero v1.8.1 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
@ -270,7 +274,7 @@ require (
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/term v0.25.0 // indirect
golang.org/x/time v0.6.0 // indirect
golang.org/x/time v0.7.0 // indirect
golang.org/x/tools v0.26.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect

44
go.sum
View file

@ -85,8 +85,8 @@ github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsVi
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
github.com/anyproto/any-store v0.1.1 h1:dZJt/ELKHzP0P6G3mT/Ch6CnX0pSHTAGpZYuBPCw2hA=
github.com/anyproto/any-store v0.1.1/go.mod h1:SDlN2AzysAfs8CDd28rrs6boUUtf5H/ydCvwmj+EbsE=
github.com/anyproto/any-sync v0.5.5 h1:StWApo7eE9dzWw/PtGkEayEsrO7dbFid0dDRsq3DVio=
github.com/anyproto/any-sync v0.5.5/go.mod h1:jXPhT2kjMVIPKEJZ/mW3NTP5j4Xsg4J5cp/ILGc/60A=
github.com/anyproto/any-sync v0.5.11 h1:dOGrNoC39/H+NHmz9/etkzxASTAXqJYdiKrKCzlzTTA=
github.com/anyproto/any-sync v0.5.11/go.mod h1:n9X9Hjq22aUHRPGrEbS1782SkEQXjKoFfExlZOFlqWA=
github.com/anyproto/badger/v4 v4.2.1-0.20240110160636-80743fa3d580 h1:Ba80IlCCxkZ9H1GF+7vFu/TSpPvbpDCxXJ5ogc4euYc=
github.com/anyproto/badger/v4 v4.2.1-0.20240110160636-80743fa3d580/go.mod h1:T/uWAYxrXdaXw64ihI++9RMbKTCpKd/yE9+saARew7k=
github.com/anyproto/go-chash v0.1.0 h1:I9meTPjXFRfXZHRJzjOHC/XF7Q5vzysKkiT/grsogXY=
@ -113,8 +113,8 @@ github.com/anyproto/protobuf v1.3.3-0.20240814124528-72b8c7e0e0f5 h1:aY7tBzQ+z8H
github.com/anyproto/protobuf v1.3.3-0.20240814124528-72b8c7e0e0f5/go.mod h1:5+PHE01DgsDPkralb8MYmGg2sPQahsqEJ9ue7ciDHKg=
github.com/anyproto/ristretto v0.1.2-0.20240221153107-2b23839cc50c h1:GicoaTUyB2mtCIl3YMrO0OzysqRT5GA4vuvDsqEkhSM=
github.com/anyproto/ristretto v0.1.2-0.20240221153107-2b23839cc50c/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA=
github.com/anyproto/tantivy-go v0.1.4 h1:Md3RZzkCB5Aw0FlvjvAQ3SQsUKZyQsUP3f33J8un7gA=
github.com/anyproto/tantivy-go v0.1.4/go.mod h1:Pl0zaeEX7dkVDTDKROzlLlGCVjbZHjyPrZloFuVEASc=
github.com/anyproto/tantivy-go v0.1.6-jieba h1:Adc1OA3pBzTktnDmO7KnEbzA0VkhIC4zqZB6EiDwOgg=
github.com/anyproto/tantivy-go v0.1.6-jieba/go.mod h1:MMLYW7e5SIzsHS3Q5CYiF1J7kJJaIRT+VVHGArU24IQ=
github.com/anyproto/zeroconf/v2 v2.2.1-0.20240228113933-f90a5cc4439d h1:5bj7nX/AS8sxGpTIrapE7PC4oPlhkHMwMqXlJbUHBlg=
github.com/anyproto/zeroconf/v2 v2.2.1-0.20240228113933-f90a5cc4439d/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
@ -234,8 +234,8 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/corona10/goimagehash v1.0.2 h1:pUfB0LnsJASMPGEZLj7tGY251vF+qLGqOgEP4rUs6kA=
github.com/corona10/goimagehash v1.0.2/go.mod h1:/l9umBhvcHQXVtQO1V6Gp1yD20STawkhRnnX0D1bvVI=
github.com/corona10/goimagehash v1.1.0 h1:teNMX/1e+Wn/AYSbLHX8mj+mF9r60R1kBeqE9MkoYwI=
github.com/corona10/goimagehash v1.1.0/go.mod h1:VkvE0mLn84L4aF8vCb6mafVajEb6QYMHl2ZJLn0mOGI=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
@ -320,6 +320,8 @@ github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9
github.com/ethereum/go-ethereum v1.13.15 h1:U7sSGYGo4SPjP6iNIifNoyIAiNjrmQkz6EwQG+/EZWo=
github.com/ethereum/go-ethereum v1.13.15/go.mod h1:TN8ZiHrdJwSe8Cb6x+p0hs5CxhJZPbqB7hHkaUXcmIU=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/flopp/go-findfont v0.1.0 h1:lPn0BymDUtJo+ZkV01VS3661HL6F4qFlkhcJN55u6mU=
github.com/flopp/go-findfont v0.1.0/go.mod h1:wKKxRDjD024Rh7VMwoU90i6ikQRCr+JTHB5n4Ejkqvw=
github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ=
github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg=
github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
@ -395,8 +397,8 @@ github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
github.com/goccy/go-graphviz v0.1.3 h1:Pkt8y4FBnBNI9tfSobpoN5qy1qMNqRXPQYvLhaSUasY=
github.com/goccy/go-graphviz v0.1.3/go.mod h1:pMYpbAqJT10V8dzV1JN/g/wUlG/0imKPzn3ZsrchGCI=
github.com/goccy/go-graphviz v0.2.9 h1:4yD2MIMpxNt+sOEARDh5jTE2S/jeAKi92w72B83mWGg=
github.com/goccy/go-graphviz v0.2.9/go.mod h1:hssjl/qbvUXGmloY81BwXt2nqoApKo7DFgDj5dLJGb8=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
@ -971,6 +973,8 @@ github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/matishsiao/goInfo v0.0.0-20240924010139-10388a85396f h1:XDrsC/9hdgiU9ecceSmYsS2E3fBtFiYc34dAMFgegnM=
github.com/matishsiao/goInfo v0.0.0-20240924010139-10388a85396f/go.mod h1:aEt7p9Rvh67BYApmZwNDPpgircTO2kgdmDUoF/1QmwA=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
@ -1109,8 +1113,8 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 h1:BvoENQQU+fZ9uukda/RzCAL/191HHwJA5b13R6diVlY=
github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
@ -1220,8 +1224,8 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI=
github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@ -1374,6 +1378,8 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/tetratelabs/wazero v1.8.1 h1:NrcgVbWfkWvVc4UtT4LRLDf91PsOzDzefMdwhLfA550=
github.com/tetratelabs/wazero v1.8.1/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs=
github.com/tj/assert v0.0.0-20190920132354-ee03d75cd160 h1:NSWpaDaurcAJY7PkL8Xt0PhZE7qpvbZl5ljd8r6U0bI=
github.com/tj/assert v0.0.0-20190920132354-ee03d75cd160/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
@ -1399,8 +1405,8 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX
github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ=
github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
github.com/vektra/mockery/v2 v2.42.2 h1:SSIvwnXBl9EynibBZhQ/hBXuV5TYPdZFIqkm4UkQHU4=
github.com/vektra/mockery/v2 v2.42.2/go.mod h1:XNTE9RIu3deGAGQRVjP1VZxGpQNm0YedZx4oDs3prr8=
github.com/vektra/mockery/v2 v2.46.3 h1:Aia4iShZeNTy6CZJcvweK4X97XOzXcqb+k9jm8IqBS0=
github.com/vektra/mockery/v2 v2.46.3/go.mod h1:dDivqi0ShM8A29mLgZn13yZ14MdXlTM4V360u8JDWCQ=
github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s=
github.com/warpfork/go-testmark v0.12.1/go.mod h1:kHwy7wfvGSPh1rQJYKayD4AbtNaeyZdcGi9tNJTaa5Y=
github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
@ -1561,8 +1567,8 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPI
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mobile v0.0.0-20240806205939-81131f6468ab h1:KONOFF8Uy3b60HEzOsGnNghORNhY4ImyOx0PGm73K9k=
golang.org/x/mobile v0.0.0-20240806205939-81131f6468ab/go.mod h1:udWezQGYjqrCxz5nV321pXQTx5oGbZx+khZvFjZNOPM=
golang.org/x/mobile v0.0.0-20241016134751-7ff83004ec2c h1:zuNS/LWsEpPTLfrmBkis6Xofw3nieAqB4hYLn8+uswk=
golang.org/x/mobile v0.0.0-20241016134751-7ff83004ec2c/go.mod h1:snk1Mn2ZpdKCt90JPEsDh4sL3ReK520U2t0d7RHBnSU=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
@ -1788,8 +1794,8 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -1988,6 +1994,8 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8=
gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE=

View file

@ -47,6 +47,7 @@ type MetricsService interface {
SetUserId(id string)
Send(ev anymetry.Event)
SendSampled(ev SamplableEvent)
SetEnabled(isEnabled bool)
Run()
Close()
@ -64,15 +65,23 @@ type service struct {
workingDir string
clients [1]*client
alreadyRunning bool
isEnabled bool
}
func (s *service) SendSampled(ev SamplableEvent) {
if !s.isEnabled {
return
}
if ev == nil {
return
}
s.getBackend(ev.GetBackend()).sendSampled(ev)
}
func (s *service) SetEnabled(isEnabled bool) {
s.isEnabled = isEnabled
}
func NewService() MetricsService {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
@ -173,6 +182,9 @@ func (s *service) GetStartVersion() string {
func (s *service) Run() {
s.lock.Lock()
defer s.lock.Unlock()
if !s.isEnabled {
return
}
if s.alreadyRunning {
return
}
@ -189,6 +201,9 @@ func (s *service) Run() {
func (s *service) Close() {
s.lock.Lock()
defer s.lock.Unlock()
if !s.isEnabled {
return
}
for _, c := range s.clients {
c.Close()
}
@ -196,6 +211,9 @@ func (s *service) Close() {
}
func (s *service) Send(ev anymetry.Event) {
if !s.isEnabled {
return
}
if ev == nil {
return
}

File diff suppressed because it is too large Load diff

View file

@ -1131,6 +1131,7 @@ message Rpc {
message Request {
google.protobuf.Struct details = 1; // object details
anytype.Rpc.Object.ImportUseCase.Request.UseCase useCase = 2; // use case
bool withChat = 3; // create space-level chat; temporary solution, should be removed after chats released for all users
}
message Response {
@ -1154,6 +1155,7 @@ message Rpc {
message Open {
message Request {
string spaceId = 1;
bool withChat = 2; // create space-level chat if not exists; temporary solution, should be removed after chats released for all users
}
message Response {
@ -6523,6 +6525,30 @@ message Rpc {
}
}
message ExportLog {
message Request {
option (no_auth) = true;
string dir = 1; // empty means using OS-provided temp dir
}
message Response {
Error error = 1;
string path = 2;
message Error {
Code code = 1;
string description = 2;
enum Code {
NULL = 0;
UNKNOWN_ERROR = 1;
BAD_INPUT = 2;
NO_FOLDER = 3;
}
}
}
}
message Ping {
message Request {
int32 index = 1;
@ -6581,14 +6607,41 @@ message Rpc {
}
}
}
message NetCheck {
message Request {
string clientYml = 1;
}
message Response {
Error error = 1;
string result = 2;
message Error {
Code code = 1;
string description = 2;
enum Code {
NULL = 0;
UNKNOWN_ERROR = 1;
BAD_INPUT = 2;
}
}
}
}
}
message Metrics {
message Initial {
message SetParameters {
message Request {
option (no_auth) = true;
string platform = 1;
string version = 2;
string workdir = 3;
string logLevel = 4;
bool doNotSendLogs = 5;
bool doNotSaveLogs = 6;
bool doNotSendTelemetry = 7;
}
message Response {

View file

@ -311,8 +311,10 @@ service ClientCommands {
rpc DebugRunProfiler (anytype.Rpc.Debug.RunProfiler.Request) returns (anytype.Rpc.Debug.RunProfiler.Response);
rpc DebugAccountSelectTrace (anytype.Rpc.Debug.AccountSelectTrace.Request) returns (anytype.Rpc.Debug.AccountSelectTrace.Response);
rpc DebugAnystoreObjectChanges (anytype.Rpc.Debug.AnystoreObjectChanges.Request) returns (anytype.Rpc.Debug.AnystoreObjectChanges.Response);
rpc DebugNetCheck (anytype.Rpc.Debug.NetCheck.Request) returns (anytype.Rpc.Debug.NetCheck.Response);
rpc DebugExportLog (anytype.Rpc.Debug.ExportLog.Request) returns (anytype.Rpc.Debug.ExportLog.Response);
rpc MetricsSetParameters (anytype.Rpc.Metrics.SetParameters.Request) returns (anytype.Rpc.Metrics.SetParameters.Response);
rpc InitialSetParameters (anytype.Rpc.Initial.SetParameters.Request) returns (anytype.Rpc.Initial.SetParameters.Response);
// used only for lib-server via grpc
rpc ListenSessionEvents (anytype.StreamRequest) returns (stream anytype.Event);

View file

@ -26,330 +26,332 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
func init() { proto.RegisterFile("pb/protos/service/service.proto", fileDescriptor_93a29dc403579097) }
var fileDescriptor_93a29dc403579097 = []byte{
// 5164 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x9d, 0x5b, 0x6f, 0x24, 0x49,
0x56, 0xf8, 0xa7, 0x5e, 0xfe, 0xf3, 0x27, 0x97, 0x1d, 0xa0, 0x06, 0x86, 0xd9, 0x61, 0xb7, 0xbb,
0xa7, 0x6f, 0xee, 0x6e, 0xdb, 0xe9, 0x9e, 0xee, 0xe9, 0x99, 0xd5, 0x2e, 0x12, 0x72, 0xdb, 0x6d,
0x8f, 0x59, 0xdb, 0x6d, 0x5c, 0xe5, 0x6e, 0x69, 0x24, 0x24, 0xc2, 0x99, 0xe1, 0x72, 0xe2, 0xac,
0x8c, 0xdc, 0xcc, 0xa8, 0x72, 0xd7, 0x22, 0x10, 0x08, 0x04, 0x02, 0x81, 0x58, 0x71, 0x7b, 0x45,
0xe2, 0x89, 0x8f, 0xc2, 0xe3, 0x3e, 0xf2, 0x88, 0x66, 0xf8, 0x20, 0x28, 0x23, 0x22, 0xe3, 0x72,
0x32, 0x4e, 0x64, 0x7a, 0x9f, 0xba, 0x55, 0xe7, 0x77, 0xce, 0x89, 0xeb, 0x89, 0x13, 0x91, 0x91,
0xe9, 0xe8, 0x76, 0x79, 0xbe, 0x55, 0x56, 0x8c, 0xb3, 0x7a, 0xab, 0xa6, 0xd5, 0x32, 0x4b, 0x68,
0xfb, 0x6f, 0x2c, 0x7e, 0x1e, 0xbf, 0x4f, 0x8a, 0x15, 0x5f, 0x95, 0xf4, 0x93, 0x8f, 0x0d, 0x99,
0xb0, 0xf9, 0x9c, 0x14, 0x69, 0x2d, 0x91, 0x4f, 0x3e, 0x32, 0x12, 0xba, 0xa4, 0x05, 0x57, 0xbf,
0x3f, 0xfb, 0xcf, 0xff, 0x1d, 0x45, 0x1f, 0xec, 0xe4, 0x19, 0x2d, 0xf8, 0x8e, 0xd2, 0x18, 0x7f,
0x1d, 0x7d, 0x77, 0xbb, 0x2c, 0xf7, 0x29, 0x7f, 0x43, 0xab, 0x3a, 0x63, 0xc5, 0xf8, 0x5e, 0xac,
0x1c, 0xc4, 0xa7, 0x65, 0x12, 0x6f, 0x97, 0x65, 0x6c, 0x84, 0xf1, 0x29, 0xfd, 0xe9, 0x82, 0xd6,
0xfc, 0x93, 0xfb, 0x61, 0xa8, 0x2e, 0x59, 0x51, 0xd3, 0xf1, 0x45, 0xf4, 0x1b, 0xdb, 0x65, 0x39,
0xa1, 0x7c, 0x97, 0x36, 0x15, 0x98, 0x70, 0xc2, 0xe9, 0x78, 0xad, 0xa3, 0xea, 0x02, 0xda, 0xc7,
0xa3, 0x7e, 0x50, 0xf9, 0x99, 0x46, 0xdf, 0x69, 0xfc, 0x5c, 0x2e, 0x78, 0xca, 0xae, 0x8b, 0xf1,
0xa7, 0x5d, 0x45, 0x25, 0xd2, 0xb6, 0xef, 0x86, 0x10, 0x65, 0xf5, 0x6d, 0xf4, 0xab, 0x6f, 0x49,
0x9e, 0x53, 0xbe, 0x53, 0xd1, 0xa6, 0xe0, 0xae, 0x8e, 0x14, 0xc5, 0x52, 0xa6, 0xed, 0xde, 0x0b,
0x32, 0xca, 0xf0, 0xd7, 0xd1, 0x77, 0xa5, 0xe4, 0x94, 0x26, 0x6c, 0x49, 0xab, 0xb1, 0x57, 0x4b,
0x09, 0x91, 0x26, 0xef, 0x40, 0xd0, 0xf6, 0x0e, 0x2b, 0x96, 0xb4, 0xe2, 0x7e, 0xdb, 0x4a, 0x18,
0xb6, 0x6d, 0x20, 0x65, 0xfb, 0x6f, 0x47, 0xd1, 0xf7, 0xb7, 0x93, 0x84, 0x2d, 0x0a, 0x7e, 0xc8,
0x12, 0x92, 0x1f, 0x66, 0xc5, 0xd5, 0x31, 0xbd, 0xde, 0xb9, 0x6c, 0xf8, 0x62, 0x46, 0xc7, 0xcf,
0xdd, 0x56, 0x95, 0x68, 0xac, 0xd9, 0xd8, 0x86, 0xb5, 0xef, 0xcf, 0x6f, 0xa6, 0xa4, 0xca, 0xf2,
0x8f, 0xa3, 0xe8, 0x16, 0x2c, 0xcb, 0x84, 0xe5, 0x4b, 0x6a, 0x4a, 0xf3, 0xa2, 0xc7, 0xb0, 0x8b,
0xeb, 0xf2, 0x7c, 0x71, 0x53, 0x35, 0x55, 0xa2, 0x3c, 0xfa, 0xd0, 0x1e, 0x2e, 0x13, 0x5a, 0x8b,
0xe9, 0xf4, 0x18, 0x1f, 0x11, 0x0a, 0xd1, 0x9e, 0x9f, 0x0c, 0x41, 0x95, 0xb7, 0x2c, 0x1a, 0x2b,
0x6f, 0x39, 0xab, 0xb5, 0xb3, 0x47, 0x5e, 0x0b, 0x16, 0xa1, 0x7d, 0x3d, 0x1e, 0x40, 0x2a, 0x57,
0x7f, 0x14, 0xfd, 0xda, 0x5b, 0x56, 0x5d, 0xd5, 0x25, 0x49, 0xa8, 0x9a, 0x0a, 0x0f, 0x5c, 0xed,
0x56, 0x0a, 0x67, 0xc3, 0xc3, 0x3e, 0xcc, 0x1a, 0xb4, 0xad, 0xf0, 0x75, 0x49, 0x61, 0x0c, 0x32,
0x8a, 0x8d, 0x10, 0x1b, 0xb4, 0x10, 0x52, 0xb6, 0xaf, 0xa2, 0xb1, 0xb1, 0x7d, 0xfe, 0xc7, 0x34,
0xe1, 0xdb, 0x69, 0x0a, 0x7b, 0xc5, 0xe8, 0x0a, 0x22, 0xde, 0x4e, 0x53, 0xac, 0x57, 0xfc, 0xa8,
0x72, 0x76, 0x1d, 0x7d, 0x04, 0x9c, 0x1d, 0x66, 0xb5, 0x70, 0xb8, 0x19, 0xb6, 0xa2, 0x30, 0xed,
0x34, 0x1e, 0x8a, 0x2b, 0xc7, 0x7f, 0x3e, 0x8a, 0xbe, 0xe7, 0xf1, 0x7c, 0x4a, 0xe7, 0x6c, 0x49,
0xc7, 0x4f, 0xfb, 0xad, 0x49, 0x52, 0xfb, 0xff, 0xec, 0x06, 0x1a, 0x9e, 0x61, 0x32, 0xa1, 0x39,
0x4d, 0x38, 0x3a, 0x4c, 0xa4, 0xb8, 0x77, 0x98, 0x68, 0xcc, 0x9a, 0x61, 0xad, 0x70, 0x9f, 0xf2,
0x9d, 0x45, 0x55, 0xd1, 0x82, 0xa3, 0x7d, 0x69, 0x90, 0xde, 0xbe, 0x74, 0x50, 0x4f, 0x7d, 0xf6,
0x29, 0xdf, 0xce, 0x73, 0xb4, 0x3e, 0x52, 0xdc, 0x5b, 0x1f, 0x8d, 0x29, 0x0f, 0x49, 0xf4, 0xeb,
0x56, 0x8b, 0xf1, 0x83, 0xe2, 0x82, 0x8d, 0xf1, 0xb6, 0x10, 0x72, 0xed, 0x63, 0xad, 0x97, 0xf3,
0x54, 0xe3, 0xd5, 0xbb, 0x92, 0x55, 0x78, 0xb7, 0x48, 0x71, 0x6f, 0x35, 0x34, 0xa6, 0x3c, 0xfc,
0x61, 0xf4, 0x81, 0x8a, 0x92, 0xed, 0x7a, 0x76, 0xdf, 0x1b, 0x42, 0xe1, 0x82, 0xf6, 0xa0, 0x87,
0x32, 0xc1, 0x41, 0xc9, 0x54, 0xf0, 0xb9, 0xe7, 0xd5, 0x03, 0xa1, 0xe7, 0x7e, 0x18, 0xea, 0xd8,
0xde, 0xa5, 0x39, 0x45, 0x6d, 0x4b, 0x61, 0x8f, 0x6d, 0x0d, 0x29, 0xdb, 0x55, 0xf4, 0x5b, 0xba,
0x59, 0x9a, 0x75, 0x54, 0xc8, 0x9b, 0x20, 0xbd, 0x8e, 0xd4, 0xdb, 0x86, 0xb4, 0xaf, 0x8d, 0x61,
0x70, 0xa7, 0x3e, 0x6a, 0x06, 0xfa, 0xeb, 0x03, 0xe6, 0xdf, 0xfd, 0x30, 0xa4, 0x6c, 0xff, 0xdd,
0x28, 0xfa, 0x81, 0x92, 0xbd, 0x2a, 0xc8, 0x79, 0x4e, 0xc5, 0x92, 0x78, 0x4c, 0xf9, 0x35, 0xab,
0xae, 0x26, 0xab, 0x22, 0x41, 0x96, 0x7f, 0x3f, 0xdc, 0xb3, 0xfc, 0xa3, 0x4a, 0x56, 0xc6, 0xa7,
0x2a, 0xca, 0x59, 0x09, 0x33, 0xbe, 0xb6, 0x06, 0x9c, 0x95, 0x58, 0xc6, 0xe7, 0x22, 0x1d, 0xab,
0x47, 0x4d, 0xd8, 0xf4, 0x5b, 0x3d, 0xb2, 0xe3, 0xe4, 0xdd, 0x10, 0x62, 0xc2, 0x56, 0x3b, 0x80,
0x59, 0x71, 0x91, 0xcd, 0xce, 0xca, 0xb4, 0x19, 0xc6, 0x8f, 0xfd, 0x23, 0xd4, 0x42, 0x90, 0xb0,
0x85, 0xa0, 0xca, 0xdb, 0x3f, 0x98, 0xc4, 0x48, 0x4d, 0xa5, 0xbd, 0x8a, 0xcd, 0x0f, 0xe9, 0x8c,
0x24, 0x2b, 0x35, 0xff, 0x3f, 0x0f, 0x4d, 0x3c, 0x48, 0xeb, 0x42, 0xbc, 0xb8, 0xa1, 0x96, 0x2a,
0xcf, 0xbf, 0x8f, 0xa2, 0xfb, 0x6d, 0xf5, 0x2f, 0x49, 0x31, 0xa3, 0xaa, 0x3f, 0x65, 0xe9, 0xb7,
0x8b, 0xf4, 0x94, 0xd6, 0x9c, 0x54, 0x7c, 0xfc, 0x23, 0x7f, 0x25, 0x43, 0x3a, 0xba, 0x6c, 0x3f,
0xfe, 0xa5, 0x74, 0x4d, 0xaf, 0x4f, 0x9a, 0xc0, 0xa6, 0x42, 0x80, 0xdb, 0xeb, 0x42, 0x02, 0x03,
0xc0, 0xdd, 0x10, 0x62, 0x7a, 0x5d, 0x08, 0x0e, 0x8a, 0x65, 0xc6, 0xe9, 0x3e, 0x2d, 0x68, 0xd5,
0xed, 0x75, 0xa9, 0xea, 0x22, 0x48, 0xaf, 0x23, 0xa8, 0x09, 0x36, 0x8e, 0x37, 0xbd, 0x38, 0xae,
0x07, 0x8c, 0x74, 0x96, 0xc7, 0x8d, 0x61, 0xb0, 0xd9, 0xdd, 0x59, 0x3e, 0x4f, 0xe9, 0x92, 0x5d,
0xc1, 0xdd, 0x9d, 0x6d, 0x42, 0x02, 0xc8, 0xee, 0xce, 0x0b, 0x9a, 0x15, 0xcc, 0xf2, 0xf3, 0x26,
0xa3, 0xd7, 0x60, 0x05, 0xb3, 0x95, 0x1b, 0x31, 0xb2, 0x82, 0x79, 0x30, 0xe5, 0xe1, 0x38, 0xfa,
0x15, 0x21, 0xfc, 0x7d, 0x96, 0x15, 0xe3, 0xdb, 0x1e, 0xa5, 0x46, 0xa0, 0xad, 0xde, 0xc1, 0x01,
0x50, 0xe2, 0xe6, 0xd7, 0x1d, 0x52, 0x24, 0x34, 0xf7, 0x96, 0xd8, 0x88, 0x83, 0x25, 0x76, 0x30,
0x93, 0x3a, 0x08, 0x61, 0x13, 0xbf, 0x26, 0x97, 0xa4, 0xca, 0x8a, 0xd9, 0xd8, 0xa7, 0x6b, 0xc9,
0x91, 0xd4, 0xc1, 0xc7, 0x81, 0x21, 0xac, 0x14, 0xb7, 0xcb, 0xb2, 0x6a, 0xc2, 0xa2, 0x6f, 0x08,
0xbb, 0x48, 0x70, 0x08, 0x77, 0x50, 0xbf, 0xb7, 0x5d, 0x9a, 0xe4, 0x59, 0x11, 0xf4, 0xa6, 0x90,
0x21, 0xde, 0x0c, 0x0a, 0x06, 0xef, 0x21, 0x25, 0x4b, 0xda, 0xd6, 0xcc, 0xd7, 0x32, 0x36, 0x10,
0x1c, 0xbc, 0x00, 0x34, 0xfb, 0x34, 0x21, 0x3e, 0x22, 0x57, 0xb4, 0x69, 0x60, 0xda, 0xac, 0x6b,
0x63, 0x9f, 0xbe, 0x43, 0x20, 0xfb, 0x34, 0x3f, 0xa9, 0x5c, 0x2d, 0xa2, 0x8f, 0x84, 0xfc, 0x84,
0x54, 0x3c, 0x4b, 0xb2, 0x92, 0x14, 0x6d, 0xfe, 0xef, 0x9b, 0xd7, 0x1d, 0x4a, 0xbb, 0xdc, 0x1c,
0x48, 0x2b, 0xb7, 0xff, 0x36, 0x8a, 0x3e, 0x85, 0x7e, 0x4f, 0x68, 0x35, 0xcf, 0xc4, 0x36, 0xb2,
0x96, 0x41, 0x78, 0xfc, 0x65, 0xd8, 0x68, 0x47, 0x41, 0x97, 0xe6, 0x87, 0x37, 0x57, 0x54, 0x05,
0xfb, 0x83, 0x28, 0x92, 0xdb, 0x15, 0xb1, 0xa5, 0x74, 0x67, 0xad, 0xda, 0xc7, 0x38, 0xfb, 0xc9,
0x4f, 0x03, 0x84, 0x59, 0x2a, 0xe4, 0xef, 0x62, 0xa7, 0x3c, 0xf6, 0x6a, 0x08, 0x11, 0xb2, 0x54,
0x00, 0x04, 0x16, 0x74, 0x72, 0xc9, 0xae, 0xfd, 0x05, 0x6d, 0x24, 0xe1, 0x82, 0x2a, 0xc2, 0x9c,
0x5d, 0xa9, 0x82, 0xfa, 0xce, 0xae, 0xda, 0x62, 0x84, 0xce, 0xae, 0x20, 0xa3, 0x0c, 0xb3, 0xe8,
0x37, 0x6d, 0xc3, 0x2f, 0x19, 0xbb, 0x9a, 0x93, 0xea, 0x6a, 0xfc, 0x04, 0x57, 0x6e, 0x19, 0xed,
0x68, 0x7d, 0x10, 0x6b, 0xc2, 0x82, 0xed, 0xb0, 0x49, 0x34, 0xce, 0xaa, 0x1c, 0x84, 0x05, 0xc7,
0x86, 0x42, 0x90, 0xb0, 0x80, 0xa0, 0x26, 0x72, 0xdb, 0xde, 0x26, 0x14, 0xee, 0x96, 0x1c, 0xf5,
0x09, 0xc5, 0x76, 0x4b, 0x1e, 0x0c, 0x0e, 0xa1, 0xfd, 0x8a, 0x94, 0x97, 0xfe, 0x21, 0x24, 0x44,
0xe1, 0x21, 0xd4, 0x22, 0xb0, 0xbf, 0x27, 0x94, 0x54, 0xc9, 0xa5, 0xbf, 0xbf, 0xa5, 0x2c, 0xdc,
0xdf, 0x9a, 0x81, 0xfd, 0x2d, 0x05, 0x6f, 0x33, 0x7e, 0x79, 0x44, 0x39, 0xf1, 0xf7, 0xb7, 0xcb,
0x84, 0xfb, 0xbb, 0xc3, 0x9a, 0x4c, 0xc6, 0x76, 0x38, 0x59, 0x9c, 0xd7, 0x49, 0x95, 0x9d, 0xd3,
0x71, 0xc0, 0x8a, 0x86, 0x90, 0x4c, 0x06, 0x85, 0x95, 0xcf, 0x9f, 0x8f, 0xa2, 0xdb, 0x6d, 0xb7,
0xb3, 0xba, 0x96, 0x2b, 0x2b, 0x70, 0xff, 0xc2, 0xdf, 0xbf, 0x08, 0x8e, 0x9c, 0x26, 0x0e, 0x50,
0xb3, 0xa2, 0xaa, 0xbf, 0x48, 0x67, 0x45, 0xad, 0x0b, 0xf5, 0xe5, 0x10, 0xeb, 0x96, 0x02, 0x12,
0x55, 0x07, 0x29, 0x9a, 0x05, 0x4d, 0xf5, 0x4f, 0x2b, 0x3b, 0x48, 0x6b, 0xb0, 0xa0, 0xb5, 0xed,
0x6d, 0x11, 0xc8, 0x82, 0xe6, 0x27, 0xe1, 0x50, 0xd8, 0xaf, 0xd8, 0xa2, 0xac, 0x7b, 0x86, 0x02,
0x80, 0xc2, 0x43, 0xa1, 0x0b, 0x2b, 0x9f, 0xef, 0xa2, 0xdf, 0xb6, 0x87, 0x9f, 0xdd, 0xd8, 0x9b,
0xf8, 0x98, 0xf2, 0x35, 0x71, 0x3c, 0x14, 0x37, 0x29, 0x5d, 0xeb, 0x99, 0xef, 0x52, 0x4e, 0xb2,
0xbc, 0x1e, 0x3f, 0xf4, 0xdb, 0x68, 0xe5, 0x48, 0x4a, 0xe7, 0xe3, 0x60, 0x7c, 0xdb, 0x5d, 0x94,
0x79, 0x96, 0x74, 0xcf, 0x72, 0x95, 0xae, 0x16, 0x87, 0xe3, 0x9b, 0x8d, 0xc1, 0x78, 0x3d, 0xa1,
0x5c, 0xfe, 0x67, 0xba, 0x2a, 0xa9, 0x3f, 0x5e, 0x3b, 0x48, 0x38, 0x5e, 0x43, 0x14, 0xd6, 0x67,
0x42, 0xf9, 0x21, 0x59, 0xb1, 0x05, 0x12, 0xaf, 0xb5, 0x38, 0x5c, 0x1f, 0x1b, 0x33, 0x59, 0x95,
0xf6, 0x70, 0x50, 0x70, 0x5a, 0x15, 0x24, 0xdf, 0xcb, 0xc9, 0xac, 0x1e, 0x23, 0x31, 0xc6, 0xa5,
0x90, 0xac, 0x0a, 0xa7, 0x3d, 0xcd, 0x78, 0x50, 0xef, 0x91, 0x25, 0xab, 0x32, 0x8e, 0x37, 0xa3,
0x41, 0x7a, 0x9b, 0xd1, 0x41, 0xbd, 0xde, 0xb6, 0xab, 0xe4, 0x32, 0x5b, 0xd2, 0x34, 0xe0, 0xad,
0x45, 0x06, 0x78, 0xb3, 0x50, 0x4f, 0xa7, 0x4d, 0xd8, 0xa2, 0x4a, 0x28, 0xda, 0x69, 0x52, 0xdc,
0xdb, 0x69, 0x1a, 0x53, 0x1e, 0xfe, 0x6a, 0x14, 0xfd, 0x8e, 0x94, 0xda, 0x07, 0xac, 0xbb, 0xa4,
0xbe, 0x3c, 0x67, 0xa4, 0x4a, 0xc7, 0x9f, 0xf9, 0xec, 0x78, 0x51, 0xed, 0xfa, 0xd9, 0x4d, 0x54,
0x60, 0xb3, 0x1e, 0x66, 0xb5, 0x35, 0xe3, 0xbc, 0xcd, 0xea, 0x20, 0xe1, 0x66, 0x85, 0x28, 0x0c,
0x20, 0x42, 0x2e, 0x0f, 0x33, 0x1e, 0xa2, 0xfa, 0xee, 0x89, 0xc6, 0x5a, 0x2f, 0x07, 0xe3, 0x63,
0x23, 0x74, 0x47, 0xcb, 0x26, 0x66, 0xc3, 0x3f, 0x62, 0xe2, 0xa1, 0x38, 0xea, 0x59, 0xcf, 0x8a,
0xb0, 0xe7, 0xce, 0xcc, 0x88, 0x87, 0xe2, 0x88, 0x67, 0x2b, 0xac, 0x85, 0x3c, 0x7b, 0x42, 0x5b,
0x3c, 0x14, 0x87, 0xd9, 0x97, 0x62, 0xda, 0x75, 0xe1, 0x49, 0xc0, 0x0e, 0x5c, 0x1b, 0xd6, 0x07,
0xb1, 0xca, 0xe1, 0xdf, 0x8c, 0xa2, 0xef, 0x1b, 0x8f, 0x47, 0x2c, 0xcd, 0x2e, 0x56, 0x12, 0x7a,
0x43, 0xf2, 0x05, 0xad, 0xc7, 0xcf, 0x30, 0x6b, 0x5d, 0x56, 0x97, 0xe0, 0xf9, 0x8d, 0x74, 0xe0,
0xdc, 0xd9, 0x2e, 0xcb, 0x7c, 0x35, 0xa5, 0xf3, 0x32, 0x47, 0xe7, 0x8e, 0x83, 0x84, 0xe7, 0x0e,
0x44, 0x61, 0x56, 0x3e, 0x65, 0x4d, 0xce, 0xef, 0xcd, 0xca, 0x85, 0x28, 0x9c, 0x95, 0xb7, 0x08,
0xcc, 0x95, 0xa6, 0x6c, 0x87, 0xe5, 0x39, 0x4d, 0x78, 0xf7, 0x21, 0xad, 0xd6, 0x34, 0x44, 0x38,
0x57, 0x02, 0xa4, 0x39, 0xcf, 0x68, 0xf7, 0x90, 0xa4, 0xa2, 0x2f, 0x57, 0x87, 0x59, 0x71, 0x35,
0xf6, 0xa7, 0x05, 0x06, 0x40, 0xce, 0x33, 0xbc, 0x20, 0xdc, 0xab, 0x9e, 0x15, 0x29, 0xf3, 0xef,
0x55, 0x1b, 0x49, 0x78, 0xaf, 0xaa, 0x08, 0x68, 0xf2, 0x94, 0x62, 0x26, 0x1b, 0x49, 0xd8, 0xa4,
0x22, 0x7c, 0xa1, 0x50, 0x9d, 0x7a, 0xa3, 0xa1, 0x10, 0x9c, 0x73, 0xaf, 0xf5, 0x72, 0x70, 0x84,
0xb6, 0x9b, 0xd6, 0x3d, 0xca, 0x93, 0x4b, 0xff, 0x08, 0x75, 0x90, 0xf0, 0x08, 0x85, 0x28, 0xac,
0xd2, 0x94, 0xe9, 0x4d, 0xf7, 0x43, 0xff, 0xf8, 0xe8, 0x6c, 0xb8, 0xd7, 0x7a, 0x39, 0xb8, 0x8d,
0x3c, 0x98, 0x8b, 0x36, 0xf3, 0x0e, 0x72, 0x29, 0x0b, 0x6f, 0x23, 0x35, 0x03, 0x4b, 0x2f, 0x05,
0x4d, 0x73, 0xfa, 0x4b, 0x6f, 0xe4, 0xe1, 0xd2, 0x3b, 0x9c, 0x72, 0xf2, 0x2f, 0x7a, 0x1b, 0x27,
0xa5, 0xc7, 0xac, 0x99, 0x23, 0x6f, 0x48, 0x9e, 0xa5, 0x84, 0xd3, 0x29, 0xbb, 0xa2, 0x85, 0x7f,
0xc7, 0xa4, 0x4a, 0x2b, 0xf9, 0xd8, 0x51, 0x08, 0xef, 0x98, 0xc2, 0x8a, 0x70, 0x9c, 0x48, 0xfa,
0xac, 0xa6, 0x3b, 0xa4, 0x46, 0x22, 0x99, 0x83, 0x84, 0xc7, 0x09, 0x44, 0x61, 0xbe, 0x2a, 0xe5,
0xaf, 0xde, 0x95, 0xb4, 0xca, 0x68, 0x91, 0x50, 0x7f, 0xbe, 0x0a, 0xa9, 0x70, 0xbe, 0xea, 0xa1,
0x3b, 0xc7, 0x34, 0x3a, 0x38, 0x75, 0xef, 0x59, 0x40, 0x22, 0x70, 0xcf, 0x02, 0x41, 0x61, 0x25,
0x0d, 0xe0, 0x3d, 0xea, 0xec, 0x58, 0x09, 0x1e, 0x75, 0xe2, 0x74, 0xe7, 0xf0, 0x4b, 0x33, 0x93,
0x66, 0x9a, 0xf4, 0x14, 0x7d, 0x62, 0x4f, 0x97, 0xf5, 0x41, 0xac, 0xff, 0xb4, 0xed, 0x94, 0xe6,
0x44, 0x2c, 0x21, 0x81, 0x23, 0xad, 0x96, 0x19, 0x72, 0xda, 0x66, 0xb1, 0xca, 0xe1, 0x5f, 0x8c,
0xa2, 0x4f, 0x7c, 0x1e, 0x5f, 0x97, 0xc2, 0xef, 0xd3, 0x7e, 0x5b, 0x92, 0x44, 0x2e, 0x92, 0x84,
0x35, 0x54, 0x19, 0xfe, 0x24, 0xfa, 0xb8, 0x15, 0x99, 0x7b, 0x26, 0xaa, 0x00, 0x6e, 0x02, 0xa5,
0xcb, 0x0f, 0x39, 0xed, 0x7e, 0x6b, 0x30, 0x6f, 0xf6, 0x26, 0x6e, 0xb9, 0x6a, 0xb0, 0x37, 0xd1,
0x36, 0x94, 0x18, 0xd9, 0x9b, 0x78, 0x30, 0x73, 0xaa, 0x61, 0x57, 0xef, 0x6d, 0xc6, 0x2f, 0x45,
0xee, 0x03, 0x4e, 0x35, 0x9c, 0xb2, 0x6a, 0x08, 0x39, 0xd5, 0x40, 0x61, 0x98, 0x1d, 0xb4, 0x60,
0x33, 0x37, 0x7d, 0x71, 0x55, 0x1b, 0xb2, 0x67, 0xe6, 0xa3, 0x7e, 0x10, 0x8e, 0xd7, 0x56, 0xac,
0xb6, 0x21, 0x4f, 0x42, 0x16, 0xc0, 0x56, 0x64, 0x7d, 0x10, 0xab, 0x1c, 0xfe, 0x59, 0xf4, 0xbd,
0x4e, 0xc5, 0xf6, 0x28, 0xe1, 0x8b, 0x8a, 0xa6, 0xe3, 0xad, 0x9e, 0x72, 0xb7, 0xa0, 0x76, 0xfd,
0x74, 0xb8, 0x42, 0x27, 0x5f, 0x6e, 0x39, 0x39, 0xac, 0x74, 0x19, 0x9e, 0x85, 0x4c, 0xba, 0x6c,
0x30, 0x5f, 0xc6, 0x75, 0x3a, 0x5b, 0x5e, 0x7b, 0x74, 0x6d, 0x2f, 0x49, 0x96, 0x8b, 0x47, 0x4e,
0x9f, 0x85, 0x8c, 0x3a, 0x68, 0x70, 0xcb, 0x8b, 0xaa, 0x74, 0x22, 0xb3, 0x98, 0xe3, 0xd6, 0x56,
0x69, 0x03, 0x8f, 0x04, 0x9e, 0x9d, 0xd2, 0xe6, 0x40, 0x5a, 0xb9, 0xe5, 0xed, 0x51, 0x61, 0xf3,
0xb3, 0x3d, 0xc8, 0x7d, 0x5e, 0x95, 0xaa, 0x67, 0xa4, 0x6f, 0x0e, 0xa4, 0x95, 0xd7, 0x3f, 0x8d,
0x3e, 0xee, 0x7a, 0x55, 0x0b, 0xd1, 0x56, 0xaf, 0x29, 0xb0, 0x16, 0x3d, 0x1d, 0xae, 0x60, 0xb6,
0x17, 0x5f, 0x65, 0x35, 0x67, 0xd5, 0x6a, 0x72, 0xc9, 0xae, 0xdb, 0xfb, 0xdb, 0xee, 0x6c, 0x55,
0x40, 0x6c, 0x11, 0xc8, 0xf6, 0xc2, 0x4f, 0x76, 0x5c, 0x99, 0x7b, 0xde, 0x35, 0xe2, 0xca, 0x22,
0x7a, 0x5c, 0xb9, 0xa4, 0x89, 0x55, 0x6d, 0xad, 0xcc, 0xa5, 0xf4, 0x35, 0x7f, 0x51, 0xbb, 0x17,
0xd3, 0x1f, 0xf5, 0x83, 0x26, 0x63, 0x51, 0xe2, 0xdd, 0xec, 0xe2, 0x42, 0xd7, 0xc9, 0x5f, 0x52,
0x1b, 0x41, 0x32, 0x16, 0x04, 0x35, 0x09, 0xf0, 0x5e, 0x96, 0x53, 0x71, 0xba, 0xfe, 0xfa, 0xe2,
0x22, 0x67, 0x24, 0x05, 0x09, 0x70, 0x23, 0x8e, 0x6d, 0x39, 0x92, 0x00, 0xfb, 0x38, 0x73, 0xfd,
0xab, 0x91, 0x9e, 0xd2, 0x84, 0x15, 0x49, 0x96, 0xc3, 0xeb, 0x6c, 0x42, 0x53, 0x0b, 0x91, 0xeb,
0x5f, 0x1d, 0xc8, 0x2c, 0x8c, 0x8d, 0xa8, 0x99, 0xf6, 0x6d, 0xf9, 0x1f, 0x74, 0x15, 0x2d, 0x31,
0xb2, 0x30, 0x7a, 0x30, 0xb3, 0x0f, 0x6c, 0x84, 0x67, 0xa5, 0x30, 0x7e, 0xa7, 0xab, 0x25, 0x25,
0xc8, 0x3e, 0xd0, 0x25, 0xcc, 0x7e, 0xa6, 0xf9, 0x7d, 0x97, 0x5d, 0x17, 0xc2, 0xe8, 0xdd, 0xae,
0x4a, 0x2b, 0x43, 0xf6, 0x33, 0x90, 0x51, 0x86, 0x7f, 0x12, 0xfd, 0x7f, 0x61, 0xb8, 0x62, 0xe5,
0xf8, 0x96, 0x47, 0xa1, 0xb2, 0x6e, 0x9e, 0xdd, 0x46, 0xe5, 0xe6, 0x02, 0xa5, 0x1e, 0x1b, 0x67,
0x35, 0x99, 0xd1, 0xf1, 0x7d, 0xa4, 0xc7, 0x85, 0x14, 0xb9, 0x40, 0xd9, 0xa5, 0xdc, 0x51, 0x71,
0xcc, 0x52, 0x65, 0xdd, 0x53, 0x43, 0x2d, 0x0c, 0x8d, 0x0a, 0x1b, 0x32, 0xc9, 0xcc, 0x31, 0x59,
0x66, 0x33, 0xbd, 0xe0, 0xc8, 0xb8, 0x55, 0x83, 0x64, 0xc6, 0x30, 0xb1, 0x05, 0x21, 0xc9, 0x0c,
0x0a, 0x2b, 0x9f, 0xff, 0x3c, 0x8a, 0xee, 0x18, 0x66, 0xbf, 0x3d, 0x39, 0x3b, 0x28, 0x2e, 0x58,
0x93, 0xfa, 0x1c, 0x66, 0xc5, 0x55, 0x3d, 0xfe, 0x02, 0x33, 0xe9, 0xe7, 0x75, 0x51, 0xbe, 0xbc,
0xb1, 0x9e, 0xc9, 0x5a, 0xdb, 0x63, 0x25, 0xf3, 0x6c, 0x59, 0x6a, 0x80, 0xac, 0x55, 0x9f, 0x3e,
0x41, 0x0e, 0xc9, 0x5a, 0x43, 0xbc, 0xe9, 0x62, 0xed, 0x3c, 0x67, 0x05, 0xec, 0x62, 0x63, 0xa1,
0x11, 0x22, 0x5d, 0xdc, 0x81, 0x4c, 0x3c, 0x6e, 0x45, 0xf2, 0x04, 0x64, 0x3b, 0xcf, 0x41, 0x3c,
0xd6, 0xaa, 0x1a, 0x40, 0xe2, 0xb1, 0x17, 0x54, 0x7e, 0x4e, 0xa3, 0xef, 0x34, 0x4d, 0x7a, 0x52,
0xd1, 0x65, 0x46, 0xe1, 0x35, 0x08, 0x4b, 0x82, 0xcc, 0x7f, 0x97, 0x30, 0x33, 0xeb, 0xac, 0xa8,
0xcb, 0x9c, 0xd4, 0x97, 0xea, 0xc1, 0xb8, 0x5b, 0xe7, 0x56, 0x08, 0x1f, 0x8d, 0x3f, 0xe8, 0xa1,
0x4c, 0x50, 0x6f, 0x65, 0x3a, 0xc4, 0x3c, 0xf4, 0xab, 0x76, 0xc2, 0xcc, 0x5a, 0x2f, 0x67, 0x4e,
0x9f, 0xf7, 0x49, 0x9e, 0xd3, 0x6a, 0xd5, 0xca, 0x8e, 0x48, 0x91, 0x5d, 0xd0, 0x9a, 0x83, 0xd3,
0x67, 0x45, 0xc5, 0x10, 0x43, 0x4e, 0x9f, 0x03, 0xb8, 0xc9, 0xe6, 0x81, 0xe7, 0x83, 0x22, 0xa5,
0xef, 0x40, 0x36, 0x0f, 0xed, 0x08, 0x06, 0xc9, 0xe6, 0x31, 0xd6, 0x9c, 0xc2, 0xbe, 0xcc, 0x59,
0x72, 0xa5, 0x96, 0x00, 0xb7, 0x83, 0x85, 0x04, 0xae, 0x01, 0x77, 0x43, 0x88, 0x59, 0x04, 0x84,
0xe0, 0x94, 0x96, 0x39, 0x49, 0xe0, 0x5d, 0x18, 0xa9, 0xa3, 0x64, 0xc8, 0x22, 0x00, 0x19, 0x50,
0x5c, 0x75, 0xc7, 0xc6, 0x57, 0x5c, 0x70, 0xc5, 0xe6, 0x6e, 0x08, 0x31, 0xcb, 0xa0, 0x10, 0x4c,
0xca, 0x3c, 0xe3, 0x60, 0x1a, 0x48, 0x0d, 0x21, 0x41, 0xa6, 0x81, 0x4b, 0x00, 0x93, 0x47, 0xb4,
0x9a, 0x51, 0xaf, 0x49, 0x21, 0x09, 0x9a, 0x6c, 0x09, 0x73, 0x65, 0x52, 0xd6, 0x9d, 0x95, 0x2b,
0x70, 0x65, 0x52, 0x55, 0x8b, 0x95, 0x2b, 0xe4, 0xca, 0xa4, 0x03, 0x80, 0x22, 0x9e, 0x90, 0x9a,
0xfb, 0x8b, 0x28, 0x24, 0xc1, 0x22, 0xb6, 0x84, 0x59, 0xa3, 0x65, 0x11, 0x17, 0x1c, 0xac, 0xd1,
0xaa, 0x00, 0xd6, 0xd3, 0xe0, 0xdb, 0xa8, 0xdc, 0x44, 0x12, 0xd9, 0x2b, 0x94, 0xef, 0x65, 0x34,
0x4f, 0x6b, 0x10, 0x49, 0x54, 0xbb, 0xb7, 0x52, 0x24, 0x92, 0x74, 0x29, 0x30, 0x94, 0xd4, 0x59,
0xb5, 0xaf, 0x76, 0xe0, 0x98, 0xfa, 0x6e, 0x08, 0x31, 0xf1, 0xa9, 0x2d, 0xf4, 0x0e, 0xa9, 0xaa,
0xac, 0x59, 0xfc, 0x1f, 0xfa, 0x0b, 0xd4, 0xca, 0x91, 0xf8, 0xe4, 0xe3, 0xc0, 0xf4, 0x6a, 0x03,
0xb7, 0xaf, 0x60, 0x30, 0x74, 0xdf, 0x0b, 0x32, 0x26, 0xe3, 0x14, 0x12, 0xeb, 0x71, 0xa6, 0xaf,
0x35, 0x3d, 0x4f, 0x33, 0x1f, 0xf6, 0x61, 0xd6, 0x2b, 0x0d, 0xda, 0xc5, 0x11, 0x5b, 0xd2, 0x29,
0x7b, 0xf5, 0x2e, 0xab, 0x79, 0x56, 0xcc, 0xd4, 0xca, 0xfd, 0x1c, 0xb1, 0xe4, 0x83, 0x91, 0x57,
0x1a, 0x7a, 0x95, 0x4c, 0x02, 0x01, 0xca, 0x72, 0x4c, 0xaf, 0xbd, 0x09, 0x04, 0xb4, 0xa8, 0x39,
0x24, 0x81, 0x08, 0xf1, 0xe6, 0x1c, 0x45, 0x3b, 0x57, 0xef, 0x7d, 0x4e, 0x59, 0x9b, 0xcb, 0x61,
0xd6, 0x20, 0x88, 0x6c, 0x65, 0x83, 0x0a, 0x66, 0x7f, 0xa9, 0xfd, 0x9b, 0x29, 0xf6, 0x08, 0xb1,
0xd3, 0x9d, 0x66, 0x8f, 0x07, 0x90, 0x1e, 0x57, 0xe6, 0x99, 0x3c, 0xe6, 0xaa, 0xfb, 0x48, 0xfe,
0xf1, 0x00, 0xd2, 0x3a, 0x93, 0xb1, 0xab, 0xf5, 0x92, 0x24, 0x57, 0xb3, 0x8a, 0x2d, 0x8a, 0x74,
0x87, 0xe5, 0xac, 0x02, 0x67, 0x32, 0x4e, 0xa9, 0x01, 0x8a, 0x9c, 0xc9, 0xf4, 0xa8, 0x98, 0x0c,
0xce, 0x2e, 0xc5, 0x76, 0x9e, 0xcd, 0xe0, 0x8e, 0xda, 0x31, 0x24, 0x00, 0x24, 0x83, 0xf3, 0x82,
0x9e, 0x41, 0x24, 0x77, 0xdc, 0x3c, 0x4b, 0x48, 0x2e, 0xfd, 0x6d, 0xe1, 0x66, 0x1c, 0xb0, 0x77,
0x10, 0x79, 0x14, 0x3c, 0xf5, 0x9c, 0x2e, 0xaa, 0xe2, 0xa0, 0xe0, 0x0c, 0xad, 0x67, 0x0b, 0xf4,
0xd6, 0xd3, 0x02, 0x41, 0x58, 0x9d, 0xd2, 0x77, 0x4d, 0x69, 0x9a, 0x7f, 0x7c, 0x61, 0xb5, 0xf9,
0x3d, 0x56, 0xf2, 0x50, 0x58, 0x05, 0x1c, 0xa8, 0x8c, 0x72, 0x22, 0x07, 0x4c, 0x40, 0xdb, 0x1d,
0x26, 0x8f, 0xfa, 0x41, 0xbf, 0x9f, 0x09, 0x5f, 0xe5, 0x34, 0xe4, 0x47, 0x00, 0x43, 0xfc, 0xb4,
0xa0, 0x39, 0x6e, 0x71, 0xea, 0x73, 0x49, 0x93, 0xab, 0xce, 0x15, 0x23, 0xb7, 0xa0, 0x12, 0x41,
0x8e, 0x5b, 0x10, 0xd4, 0xdf, 0x45, 0x07, 0x09, 0x2b, 0x42, 0x5d, 0xd4, 0xc8, 0x87, 0x74, 0x91,
0xe2, 0xcc, 0xe6, 0x57, 0x4b, 0xd5, 0xc8, 0x94, 0xdd, 0xb4, 0x8e, 0x58, 0xb0, 0x21, 0x64, 0xf3,
0x8b, 0xc2, 0x26, 0x27, 0x87, 0x3e, 0x8f, 0xba, 0xf7, 0xaf, 0x3b, 0x56, 0x8e, 0xf0, 0xfb, 0xd7,
0x18, 0x8b, 0x57, 0x52, 0x8e, 0x91, 0x1e, 0x2b, 0xee, 0x38, 0xd9, 0x18, 0x06, 0x9b, 0x2d, 0x8f,
0xe3, 0x73, 0x27, 0xa7, 0xa4, 0x92, 0x5e, 0x37, 0x03, 0x86, 0x0c, 0x86, 0x6c, 0x79, 0x02, 0x38,
0x08, 0x61, 0x8e, 0xe7, 0x1d, 0x56, 0x70, 0x5a, 0x70, 0x5f, 0x08, 0x73, 0x8d, 0x29, 0x30, 0x14,
0xc2, 0x30, 0x05, 0x30, 0x6e, 0xc5, 0x79, 0x10, 0xe5, 0xc7, 0x64, 0xee, 0xcd, 0xd8, 0xe4, 0x59,
0x8f, 0x94, 0x87, 0xc6, 0x2d, 0xe0, 0xac, 0x87, 0x7c, 0xb6, 0x97, 0x29, 0xa9, 0x66, 0xfa, 0x74,
0x23, 0x1d, 0x3f, 0xc5, 0xed, 0xb8, 0x24, 0xf2, 0x90, 0x2f, 0xac, 0x01, 0xc2, 0xce, 0xc1, 0x9c,
0xcc, 0x74, 0x4d, 0x3d, 0x35, 0x10, 0xf2, 0x4e, 0x55, 0x1f, 0xf5, 0x83, 0xc0, 0xcf, 0x9b, 0x2c,
0xa5, 0x2c, 0xe0, 0x47, 0xc8, 0x87, 0xf8, 0x81, 0x20, 0xc8, 0xde, 0x9a, 0x7a, 0xcb, 0x1d, 0xdd,
0x76, 0x91, 0xaa, 0x7d, 0x6c, 0x8c, 0x34, 0x0f, 0xe0, 0x42, 0xd9, 0x1b, 0xc2, 0x83, 0x39, 0xda,
0x1e, 0xd0, 0x86, 0xe6, 0xa8, 0x3e, 0x7f, 0x1d, 0x32, 0x47, 0x7d, 0xb0, 0xf2, 0xf9, 0x33, 0x35,
0x47, 0x77, 0x09, 0x27, 0x4d, 0xde, 0xfe, 0x26, 0xa3, 0xd7, 0x6a, 0x23, 0xec, 0xa9, 0x6f, 0x4b,
0xc5, 0xe2, 0xc5, 0x3b, 0xb0, 0x2b, 0xde, 0x1a, 0xcc, 0x07, 0x7c, 0xab, 0x1d, 0x42, 0xaf, 0x6f,
0xb0, 0x55, 0xd8, 0x1a, 0xcc, 0x07, 0x7c, 0xab, 0x37, 0x7a, 0x7b, 0x7d, 0x83, 0xd7, 0x7a, 0xb7,
0x06, 0xf3, 0xca, 0xf7, 0x5f, 0xb6, 0x13, 0xd7, 0x76, 0xde, 0xe4, 0x61, 0x09, 0xcf, 0x96, 0xd4,
0x97, 0x4e, 0xba, 0xf6, 0x34, 0x1a, 0x4a, 0x27, 0x71, 0x15, 0xeb, 0x33, 0x30, 0xbe, 0x52, 0x9c,
0xb0, 0x3a, 0x13, 0x0f, 0xe9, 0x9f, 0x0f, 0x30, 0xda, 0xc2, 0xa1, 0x4d, 0x53, 0x48, 0xc9, 0x3c,
0x6e, 0x74, 0x50, 0x73, 0xa3, 0x78, 0x23, 0x60, 0xaf, 0x7b, 0xb1, 0x78, 0x73, 0x20, 0x6d, 0x1e,
0xfc, 0x39, 0x8c, 0xfd, 0xc4, 0x31, 0xd4, 0xab, 0xde, 0x87, 0x8e, 0x4f, 0x87, 0x2b, 0x28, 0xf7,
0x7f, 0xdd, 0xee, 0x2b, 0xa0, 0x7f, 0x35, 0x09, 0x9e, 0x0d, 0xb1, 0x08, 0x26, 0xc2, 0xf3, 0x1b,
0xe9, 0xa8, 0x82, 0xfc, 0x7d, 0xbb, 0x81, 0x6e, 0x51, 0xf1, 0x5e, 0xc5, 0xeb, 0x2a, 0xa5, 0x95,
0x9a, 0x13, 0xa1, 0x6e, 0x35, 0x30, 0x9c, 0x19, 0x2f, 0x6e, 0xa8, 0x65, 0x7d, 0x14, 0xc8, 0x81,
0xd5, 0xfb, 0x7f, 0x56, 0x79, 0x42, 0x96, 0x2d, 0x1a, 0x16, 0xe8, 0x8b, 0x9b, 0xaa, 0x61, 0x73,
0xc5, 0x82, 0xc5, 0x37, 0x06, 0x9e, 0x0f, 0x34, 0xec, 0x7c, 0x75, 0xe0, 0xf3, 0x9b, 0x29, 0xa9,
0xb2, 0xfc, 0xc7, 0x28, 0x7a, 0xe0, 0xb0, 0xe6, 0x79, 0x02, 0x38, 0xf5, 0xf8, 0x71, 0xc0, 0x3e,
0xa6, 0xa4, 0x0b, 0xf7, 0xbb, 0xbf, 0x9c, 0xb2, 0xf9, 0x82, 0x8e, 0xa3, 0xb2, 0x97, 0xe5, 0x9c,
0x56, 0xdd, 0x2f, 0xe8, 0xb8, 0x76, 0x25, 0x15, 0xe3, 0x5f, 0xd0, 0x09, 0xe0, 0xd6, 0x17, 0x74,
0x3c, 0x9e, 0xbd, 0x5f, 0xd0, 0xf1, 0x5a, 0x0b, 0x7e, 0x41, 0x27, 0xac, 0x81, 0x85, 0xf7, 0xb6,
0x08, 0xf2, 0xdc, 0x7a, 0x90, 0x45, 0xf7, 0x18, 0xfb, 0xd9, 0x4d, 0x54, 0x90, 0x05, 0x4e, 0x72,
0xe2, 0x9e, 0xdb, 0x80, 0x36, 0x75, 0xee, 0xba, 0x6d, 0x0d, 0xe6, 0x95, 0xef, 0x9f, 0xaa, 0xdd,
0x8d, 0x0e, 0xe7, 0xac, 0x12, 0x5f, 0x4f, 0x5a, 0x0f, 0x85, 0xe7, 0xc6, 0x82, 0xdd, 0xf3, 0x1b,
0xc3, 0x60, 0xa4, 0xba, 0x0d, 0xa1, 0x3a, 0x3d, 0xee, 0x33, 0x04, 0xba, 0x7c, 0x6b, 0x30, 0x8f,
0x2c, 0x23, 0xd2, 0xb7, 0xec, 0xed, 0x01, 0xc6, 0xdc, 0xbe, 0x7e, 0x3a, 0x5c, 0x41, 0xb9, 0x5f,
0xaa, 0xb4, 0xd1, 0x76, 0x2f, 0xfa, 0x79, 0xb3, 0xcf, 0xd4, 0xc4, 0xe9, 0xe6, 0x78, 0x28, 0x1e,
0x4a, 0x20, 0xec, 0x25, 0xb4, 0x2f, 0x81, 0xf0, 0x2e, 0xa3, 0x9f, 0xdf, 0x4c, 0x49, 0x95, 0xe5,
0x9f, 0x46, 0xd1, 0x6d, 0xb4, 0x2c, 0x6a, 0x1c, 0x7c, 0x31, 0xd4, 0x32, 0x18, 0x0f, 0x5f, 0xde,
0x58, 0x4f, 0x15, 0xea, 0x5f, 0x47, 0xd1, 0x9d, 0x40, 0xa1, 0xe4, 0x00, 0xb9, 0x81, 0x75, 0x77,
0xa0, 0xfc, 0xf0, 0xe6, 0x8a, 0xd8, 0x72, 0x6f, 0xe3, 0x93, 0xee, 0xa7, 0x65, 0x02, 0xb6, 0x27,
0xf8, 0xa7, 0x65, 0xfa, 0xb5, 0xe0, 0x21, 0x0f, 0x39, 0x6f, 0x37, 0x5d, 0xde, 0x43, 0x1e, 0x71,
0x43, 0x0d, 0xec, 0x39, 0xd6, 0x7a, 0x39, 0x9f, 0x93, 0x57, 0xef, 0x4a, 0x52, 0xa4, 0xb8, 0x13,
0x29, 0xef, 0x77, 0xa2, 0x39, 0x78, 0x38, 0xd6, 0x48, 0x4f, 0x59, 0xbb, 0x91, 0x7a, 0x8c, 0xe9,
0x6b, 0x24, 0x78, 0x38, 0xd6, 0x41, 0x11, 0x6f, 0x2a, 0x6b, 0x0c, 0x79, 0x03, 0xc9, 0xe2, 0x93,
0x21, 0x28, 0x48, 0xd1, 0xb5, 0x37, 0x7d, 0xe6, 0xbe, 0x11, 0xb2, 0xd2, 0x39, 0x77, 0xdf, 0x1c,
0x48, 0x23, 0x6e, 0x27, 0x94, 0x7f, 0x45, 0x49, 0x4a, 0xab, 0xa0, 0x5b, 0x4d, 0x0d, 0x72, 0x6b,
0xd3, 0x3e, 0xb7, 0x3b, 0x2c, 0x5f, 0xcc, 0x0b, 0xd5, 0x99, 0xa8, 0x5b, 0x9b, 0xea, 0x77, 0x0b,
0x68, 0x78, 0x2c, 0x68, 0xdc, 0x8a, 0xf4, 0xf2, 0x49, 0xd8, 0x8c, 0x93, 0x55, 0xae, 0x0f, 0x62,
0xf1, 0x7a, 0xaa, 0x61, 0xd4, 0x53, 0x4f, 0x30, 0x92, 0x36, 0x07, 0xd2, 0xf0, 0x7c, 0xce, 0x72,
0xab, 0xc7, 0xd3, 0x56, 0x8f, 0xad, 0xce, 0x90, 0x7a, 0x3a, 0x5c, 0x01, 0x9e, 0x86, 0xaa, 0x51,
0x75, 0x98, 0xd5, 0x7c, 0x2f, 0xcb, 0xf3, 0xf1, 0x7a, 0x60, 0x98, 0xb4, 0x50, 0xf0, 0x34, 0xd4,
0x03, 0x23, 0x23, 0xb9, 0x3d, 0x3d, 0x2c, 0xc6, 0x7d, 0x76, 0x04, 0x35, 0x68, 0x24, 0xdb, 0x34,
0x38, 0xd1, 0xb2, 0x9a, 0x5a, 0xd7, 0x36, 0x0e, 0x37, 0x5c, 0xa7, 0xc2, 0x5b, 0x83, 0x79, 0xf0,
0xb8, 0x5d, 0x50, 0x62, 0x65, 0xb9, 0x8f, 0x99, 0x70, 0x56, 0x92, 0x07, 0x3d, 0x14, 0x38, 0x15,
0x94, 0xd3, 0xe8, 0x6d, 0x96, 0xce, 0x28, 0xf7, 0x3e, 0x29, 0xb2, 0x81, 0xe0, 0x93, 0x22, 0x00,
0x82, 0xae, 0x93, 0xbf, 0xeb, 0xe3, 0xd0, 0x83, 0xd4, 0xd7, 0x75, 0x4a, 0xd9, 0xa2, 0x42, 0x5d,
0xe7, 0xa5, 0x41, 0x34, 0xd0, 0x6e, 0xd5, 0xab, 0xf1, 0x4f, 0x42, 0x66, 0xc0, 0xfb, 0xf1, 0xeb,
0x83, 0x58, 0xb0, 0xa2, 0x18, 0x87, 0xd9, 0x3c, 0xe3, 0xbe, 0x15, 0xc5, 0xb2, 0xd1, 0x20, 0xa1,
0x15, 0xa5, 0x8b, 0x62, 0xd5, 0x6b, 0x72, 0x84, 0x83, 0x34, 0x5c, 0x3d, 0xc9, 0x0c, 0xab, 0x9e,
0x66, 0x3b, 0x0f, 0x36, 0x0b, 0x3d, 0x64, 0xf8, 0xa5, 0xda, 0x2c, 0x7b, 0xc6, 0xb6, 0x78, 0x65,
0x12, 0x82, 0xa1, 0xa8, 0x83, 0x29, 0xc0, 0x03, 0xfb, 0x86, 0x6b, 0x9f, 0xbd, 0x96, 0x25, 0x25,
0x15, 0x29, 0x12, 0xef, 0xe6, 0x54, 0x18, 0xec, 0x90, 0xa1, 0xcd, 0x29, 0xaa, 0x01, 0x1e, 0x9b,
0xbb, 0x2f, 0x3b, 0x7a, 0xa6, 0x82, 0x7e, 0xab, 0xd0, 0x7d, 0xd7, 0xf1, 0xf1, 0x00, 0x12, 0x3e,
0x36, 0x6f, 0x01, 0x7d, 0xf0, 0x2d, 0x9d, 0x7e, 0x16, 0x30, 0xe5, 0xa2, 0xa1, 0x8d, 0x30, 0xae,
0x02, 0x06, 0xb5, 0x4e, 0x70, 0x29, 0xff, 0x09, 0x5d, 0xf9, 0x06, 0xb5, 0xc9, 0x4f, 0x05, 0x12,
0x1a, 0xd4, 0x5d, 0x14, 0xe4, 0x99, 0xf6, 0x3e, 0xe8, 0x61, 0x40, 0xdf, 0xde, 0xfa, 0xac, 0xf5,
0x72, 0x60, 0xe6, 0xec, 0x66, 0x4b, 0xe7, 0x39, 0x81, 0xa7, 0xa0, 0xbb, 0xd9, 0xd2, 0xff, 0x98,
0x60, 0x7d, 0x10, 0x0b, 0x1f, 0xc9, 0x13, 0x4e, 0xdf, 0xb5, 0xcf, 0xca, 0x3d, 0xc5, 0x15, 0xf2,
0xce, 0xc3, 0xf2, 0x47, 0xfd, 0xa0, 0xb9, 0x00, 0x7b, 0x52, 0xb1, 0x84, 0xd6, 0xb5, 0xfa, 0xde,
0x9e, 0x7b, 0xc3, 0x48, 0xc9, 0x62, 0xf0, 0xb5, 0xbd, 0xfb, 0x61, 0x48, 0xd9, 0xfe, 0x2a, 0x7a,
0xff, 0x90, 0xcd, 0x26, 0xb4, 0x48, 0xc7, 0x3f, 0x70, 0xaf, 0x9c, 0xb2, 0x59, 0xdc, 0xfc, 0xac,
0xed, 0xdd, 0xc2, 0xc4, 0xe6, 0xd2, 0xdc, 0x2e, 0x3d, 0x5f, 0xcc, 0x26, 0x9c, 0x70, 0x70, 0x69,
0x4e, 0xfc, 0x1e, 0x37, 0x02, 0xe4, 0xd2, 0x9c, 0x03, 0x00, 0x7b, 0xd3, 0x8a, 0x52, 0xaf, 0xbd,
0x46, 0x10, 0xb4, 0xa7, 0x00, 0xb3, 0xea, 0x6a, 0x7b, 0x4d, 0x62, 0x0b, 0x2f, 0xb9, 0x19, 0x1d,
0x21, 0x45, 0x56, 0xdd, 0x2e, 0x65, 0x06, 0x83, 0xac, 0xbe, 0xf8, 0x62, 0xc6, 0x62, 0x3e, 0x27,
0xd5, 0x0a, 0x0c, 0x06, 0x55, 0x4b, 0x0b, 0x40, 0x06, 0x83, 0x17, 0x34, 0xa3, 0xbc, 0x6d, 0xe6,
0xe4, 0x6a, 0x9f, 0x55, 0x6c, 0xc1, 0xb3, 0x82, 0xc2, 0xaf, 0x26, 0xe8, 0x06, 0xb5, 0x19, 0x64,
0x94, 0x63, 0xac, 0xc9, 0x0a, 0x05, 0x21, 0xef, 0xdf, 0x89, 0xaf, 0xd6, 0xd6, 0x9c, 0x55, 0xf0,
0xf9, 0x9b, 0xb4, 0x02, 0x21, 0x24, 0x2b, 0x44, 0x61, 0xd0, 0xf7, 0x27, 0x59, 0x31, 0xf3, 0xf6,
0xfd, 0x89, 0xfd, 0xcd, 0xc7, 0x3b, 0x38, 0x60, 0xe2, 0xbb, 0x6c, 0x34, 0xf9, 0x65, 0x22, 0xf5,
0xee, 0xa3, 0xb7, 0xd1, 0x6d, 0x02, 0x89, 0xef, 0x7e, 0x12, 0xb8, 0x7a, 0x5d, 0xd2, 0x82, 0xa6,
0xed, 0x2d, 0x33, 0x9f, 0x2b, 0x87, 0x08, 0xba, 0x82, 0xa4, 0x89, 0xaa, 0x42, 0x7e, 0xba, 0x28,
0x4e, 0x2a, 0x76, 0x91, 0xe5, 0xb4, 0x02, 0x51, 0x55, 0xaa, 0x5b, 0x72, 0x24, 0xaa, 0xfa, 0x38,
0x73, 0x5d, 0x41, 0x48, 0x9d, 0x4f, 0x2f, 0x4f, 0x2b, 0x92, 0xc0, 0xeb, 0x0a, 0xd2, 0x46, 0x17,
0x43, 0x4e, 0xd2, 0x02, 0xb8, 0x95, 0x18, 0x48, 0xd7, 0xc5, 0x4a, 0x8c, 0x0f, 0xf5, 0xee, 0x9d,
0xf8, 0x12, 0x62, 0x0d, 0x12, 0x03, 0x65, 0xce, 0x47, 0x22, 0x89, 0x41, 0x58, 0xc3, 0xcc, 0xb6,
0x23, 0xca, 0xab, 0x2c, 0xa9, 0x27, 0x94, 0x9f, 0x90, 0x8a, 0xcc, 0x29, 0xa7, 0x15, 0x9c, 0x6d,
0x0a, 0x89, 0x1d, 0x06, 0x99, 0x6d, 0x18, 0xab, 0x1c, 0xfe, 0x5e, 0xf4, 0x61, 0xb3, 0xd8, 0xd0,
0x42, 0xfd, 0xa5, 0x82, 0x57, 0xe2, 0x4f, 0x9c, 0x8c, 0x3f, 0xd2, 0x36, 0x26, 0xbc, 0xa2, 0x64,
0xde, 0xda, 0xfe, 0x40, 0xff, 0x2e, 0xc0, 0xa7, 0xa3, 0x66, 0x50, 0x1c, 0x33, 0x9e, 0x5d, 0x34,
0x7b, 0x3b, 0xf5, 0xda, 0x0a, 0x18, 0x14, 0xb6, 0x38, 0x0e, 0x7c, 0x8c, 0xc0, 0xc7, 0x99, 0x60,
0x67, 0x4b, 0x4f, 0x69, 0x99, 0xc3, 0x60, 0xe7, 0x68, 0x0b, 0x00, 0x09, 0x76, 0x5e, 0xd0, 0x8c,
0x70, 0x5b, 0x3c, 0xa5, 0xe1, 0xca, 0x4c, 0xe9, 0xb0, 0xca, 0x4c, 0x9d, 0x37, 0x01, 0xf2, 0xe8,
0xc3, 0x23, 0x3a, 0x3f, 0xa7, 0x55, 0x7d, 0x99, 0x95, 0xfb, 0xcd, 0x2a, 0x4f, 0xf8, 0x02, 0xbe,
0x2b, 0x67, 0x88, 0x58, 0x23, 0x48, 0x2a, 0x84, 0xa0, 0x26, 0x9c, 0x1a, 0xe0, 0xa0, 0x3e, 0x26,
0x73, 0x2a, 0x3e, 0xad, 0x30, 0x5e, 0xc7, 0x8c, 0x58, 0x10, 0x12, 0x4e, 0x51, 0xd8, 0x7a, 0xa9,
0xc8, 0x30, 0xa7, 0x74, 0xd6, 0x8c, 0xb0, 0xea, 0x84, 0xac, 0xe6, 0xb4, 0xe0, 0xca, 0x24, 0x38,
0x08, 0xb6, 0x4c, 0xfa, 0x79, 0xe4, 0x20, 0x78, 0x88, 0x9e, 0x35, 0xbf, 0x9d, 0x86, 0x3f, 0x61,
0x15, 0x97, 0x7f, 0x87, 0xe4, 0xac, 0xca, 0xc1, 0xfc, 0x76, 0x1b, 0xd5, 0x21, 0x91, 0xf9, 0x1d,
0xd6, 0xb0, 0x3e, 0xe0, 0xed, 0x94, 0xe1, 0x0d, 0xad, 0xf4, 0x38, 0x79, 0x35, 0x27, 0x59, 0xae,
0x46, 0xc3, 0x8f, 0x02, 0xb6, 0x11, 0x1d, 0xe4, 0x03, 0xde, 0x43, 0x75, 0xad, 0x4f, 0x9e, 0x87,
0x4b, 0x08, 0xce, 0xa5, 0x7b, 0xec, 0x23, 0xe7, 0xd2, 0xfd, 0x5a, 0x66, 0xbb, 0x68, 0x58, 0xc1,
0xad, 0x04, 0xb1, 0xc3, 0x52, 0x78, 0x48, 0x65, 0xd9, 0x04, 0x20, 0xb2, 0x5d, 0x0c, 0x2a, 0x98,
0xf5, 0xd5, 0x60, 0x7b, 0x59, 0x41, 0xf2, 0xec, 0x67, 0xf0, 0x86, 0xb3, 0x65, 0xa7, 0x25, 0x90,
0xf5, 0xd5, 0x4f, 0xfa, 0x5c, 0xed, 0x53, 0x3e, 0xcd, 0x9a, 0xd0, 0xff, 0x28, 0xd0, 0x6e, 0x82,
0xe8, 0x77, 0x65, 0x91, 0xd6, 0x47, 0x3a, 0x61, 0xb3, 0x6e, 0x97, 0xe5, 0xa4, 0x59, 0x9a, 0x4e,
0x69, 0x42, 0xb3, 0x92, 0x8f, 0x5f, 0x84, 0xdb, 0x0a, 0xe0, 0xc8, 0xd3, 0xfd, 0x01, 0x6a, 0xd6,
0x33, 0xe3, 0x26, 0x96, 0x4c, 0xe4, 0x1f, 0xe8, 0x3a, 0xab, 0x69, 0xa5, 0x56, 0xeb, 0x7d, 0xca,
0xc1, 0xec, 0xb4, 0xb8, 0xd8, 0x02, 0x9b, 0x8a, 0x22, 0xb3, 0x33, 0xac, 0x61, 0x4e, 0x98, 0x2c,
0xee, 0x94, 0xd6, 0x2c, 0x5f, 0x52, 0x71, 0xc9, 0x6d, 0x03, 0x35, 0x66, 0x51, 0xc8, 0x09, 0x13,
0x4e, 0x9b, 0x94, 0xa7, 0xeb, 0x76, 0xbb, 0x58, 0x1d, 0xc0, 0xe7, 0xf4, 0x1e, 0x4b, 0x02, 0x43,
0x52, 0x9e, 0x00, 0x6e, 0x9d, 0xc0, 0x56, 0x8c, 0xa4, 0x09, 0xa9, 0xf9, 0x09, 0x59, 0xe5, 0x8c,
0xa4, 0x62, 0x5d, 0x87, 0x27, 0xb0, 0x2d, 0x13, 0xdb, 0x10, 0x76, 0x02, 0x8b, 0xc1, 0x66, 0x77,
0xa9, 0xfe, 0xee, 0x98, 0xba, 0x40, 0x78, 0x0f, 0xa4, 0x49, 0xa2, 0xbc, 0xf0, 0xf2, 0xe0, 0xfd,
0x30, 0x64, 0x5e, 0x7c, 0x92, 0x22, 0x91, 0x86, 0xdc, 0xf1, 0xe9, 0x38, 0x09, 0xc8, 0xa7, 0x01,
0xc2, 0x7c, 0x0c, 0x41, 0xfe, 0xde, 0xfe, 0xe9, 0x0c, 0xae, 0x3e, 0x65, 0xbc, 0xe1, 0xd3, 0xb5,
0xa1, 0xd8, 0xfe, 0xc2, 0xd9, 0xe6, 0x40, 0xda, 0x6c, 0x1e, 0x77, 0x2e, 0x09, 0xdf, 0x4e, 0xd3,
0x23, 0x5a, 0x7b, 0xde, 0x62, 0x6e, 0x84, 0xb1, 0x91, 0x22, 0x9b, 0xc7, 0x2e, 0x65, 0x06, 0x7a,
0x23, 0x7b, 0x95, 0x66, 0x5c, 0xc9, 0xda, 0x6b, 0xb9, 0x1b, 0x5d, 0x03, 0x5d, 0x0a, 0xa9, 0x15,
0x4e, 0x9b, 0x58, 0xde, 0x30, 0x53, 0x36, 0x9b, 0xe5, 0x54, 0x41, 0xa7, 0x94, 0xc8, 0x2f, 0xb9,
0x6d, 0x75, 0x6d, 0x79, 0x41, 0x24, 0x96, 0x07, 0x15, 0x4c, 0x1a, 0xd9, 0x60, 0xf2, 0x39, 0x48,
0xdb, 0xb0, 0x6b, 0x5d, 0x33, 0x0e, 0x80, 0xa4, 0x91, 0x5e, 0xd0, 0xbc, 0x6c, 0xd5, 0x88, 0xf7,
0x69, 0xdb, 0x12, 0xf0, 0xbb, 0x37, 0x42, 0xd9, 0x12, 0x23, 0x2f, 0x5b, 0x79, 0x30, 0xb3, 0x4f,
0x00, 0x1e, 0x5e, 0xae, 0x0e, 0x52, 0xb8, 0x4f, 0x80, 0xfa, 0x82, 0x41, 0xf6, 0x09, 0x18, 0xeb,
0x76, 0x9d, 0xfe, 0xc8, 0xef, 0x21, 0xa9, 0x4d, 0xe5, 0x3c, 0x5d, 0xe7, 0x05, 0x43, 0x5d, 0x87,
0x29, 0xb8, 0x4d, 0x6a, 0x7f, 0x42, 0xd8, 0xd3, 0xa4, 0xbe, 0x4f, 0x07, 0x3f, 0xec, 0xc3, 0x4c,
0x5c, 0xd2, 0x9b, 0x32, 0x71, 0x4f, 0xc6, 0xff, 0x09, 0x77, 0x29, 0x44, 0xe2, 0x52, 0x07, 0x92,
0xb6, 0x5f, 0x7e, 0xfa, 0x5f, 0xdf, 0xdc, 0x1a, 0xfd, 0xe2, 0x9b, 0x5b, 0xa3, 0xff, 0xf9, 0xe6,
0xd6, 0xe8, 0xe7, 0xdf, 0xde, 0x7a, 0xef, 0x17, 0xdf, 0xde, 0x7a, 0xef, 0xbf, 0xbf, 0xbd, 0xf5,
0xde, 0xd7, 0xef, 0xab, 0xbf, 0x47, 0x79, 0xfe, 0xff, 0xc4, 0x5f, 0x95, 0x7c, 0xfe, 0x7f, 0x01,
0x00, 0x00, 0xff, 0xff, 0xe5, 0xb3, 0x13, 0x72, 0xb3, 0x72, 0x00, 0x00,
// 5189 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x9d, 0xdd, 0x6f, 0x1d, 0x49,
0x56, 0xc0, 0xc7, 0x2f, 0x0c, 0xf4, 0xb2, 0x03, 0xdc, 0x81, 0x61, 0x76, 0xd8, 0xcd, 0xd7, 0x24,
0x71, 0x12, 0xdb, 0xd7, 0x99, 0x64, 0x32, 0xb3, 0xda, 0x45, 0x42, 0x8e, 0x1d, 0x7b, 0xcc, 0xda,
0x8e, 0xf1, 0xb5, 0x13, 0x69, 0x24, 0x24, 0xca, 0xdd, 0xe5, 0xeb, 0xc6, 0x7d, 0xbb, 0x7a, 0xbb,
0xeb, 0x5e, 0xe7, 0x2e, 0x02, 0x81, 0x40, 0x20, 0x10, 0x88, 0x15, 0x5f, 0xaf, 0x48, 0xfc, 0x35,
0x3c, 0xee, 0x23, 0x8f, 0x68, 0x46, 0xfc, 0x1f, 0xa8, 0xeb, 0xbb, 0x4e, 0xd7, 0xa9, 0x6e, 0xef,
0x53, 0xa2, 0x7b, 0x7e, 0xe7, 0x9c, 0xfa, 0x3c, 0x75, 0xaa, 0xba, 0xba, 0x9d, 0xdc, 0xae, 0xce,
0x37, 0xab, 0x9a, 0x71, 0xd6, 0x6c, 0x36, 0xb4, 0x5e, 0xe4, 0x29, 0xd5, 0xff, 0x8e, 0xc5, 0xcf,
0xa3, 0xf7, 0x49, 0xb9, 0xe4, 0xcb, 0x8a, 0x7e, 0xf2, 0xb1, 0x25, 0x53, 0x36, 0x9b, 0x91, 0x32,
0x6b, 0x24, 0xf2, 0xc9, 0x47, 0x56, 0x42, 0x17, 0xb4, 0xe4, 0xea, 0xf7, 0x67, 0xdf, 0xfe, 0xdf,
0x4a, 0xf2, 0xc1, 0x76, 0x91, 0xd3, 0x92, 0x6f, 0x2b, 0x8d, 0xd1, 0xd7, 0xc9, 0x77, 0xb7, 0xaa,
0x6a, 0x8f, 0xf2, 0x37, 0xb4, 0x6e, 0x72, 0x56, 0x8e, 0x3e, 0x1d, 0x2b, 0x07, 0xe3, 0x93, 0x2a,
0x1d, 0x6f, 0x55, 0xd5, 0xd8, 0x0a, 0xc7, 0x27, 0xf4, 0xa7, 0x73, 0xda, 0xf0, 0x4f, 0xee, 0xc7,
0xa1, 0xa6, 0x62, 0x65, 0x43, 0x47, 0x17, 0xc9, 0x6f, 0x6d, 0x55, 0xd5, 0x84, 0xf2, 0x1d, 0xda,
0x56, 0x60, 0xc2, 0x09, 0xa7, 0xa3, 0xd5, 0x8e, 0xaa, 0x0f, 0x18, 0x1f, 0x8f, 0xfa, 0x41, 0xe5,
0xe7, 0x34, 0xf9, 0x4e, 0xeb, 0xe7, 0x72, 0xce, 0x33, 0x76, 0x5d, 0x8e, 0xee, 0x76, 0x15, 0x95,
0xc8, 0xd8, 0xbe, 0x17, 0x43, 0x94, 0xd5, 0xb7, 0xc9, 0xaf, 0xbf, 0x25, 0x45, 0x41, 0xf9, 0x76,
0x4d, 0xdb, 0x82, 0xfb, 0x3a, 0x52, 0x34, 0x96, 0x32, 0x63, 0xf7, 0xd3, 0x28, 0xa3, 0x0c, 0x7f,
0x9d, 0x7c, 0x57, 0x4a, 0x4e, 0x68, 0xca, 0x16, 0xb4, 0x1e, 0x05, 0xb5, 0x94, 0x10, 0x69, 0xf2,
0x0e, 0x04, 0x6d, 0x6f, 0xb3, 0x72, 0x41, 0x6b, 0x1e, 0xb6, 0xad, 0x84, 0x71, 0xdb, 0x16, 0x52,
0xb6, 0xff, 0x7e, 0x25, 0xf9, 0xfe, 0x56, 0x9a, 0xb2, 0x79, 0xc9, 0x0f, 0x58, 0x4a, 0x8a, 0x83,
0xbc, 0xbc, 0x3a, 0xa2, 0xd7, 0xdb, 0x97, 0x2d, 0x5f, 0x4e, 0xe9, 0xe8, 0xb9, 0xdf, 0xaa, 0x12,
0x1d, 0x1b, 0x76, 0xec, 0xc2, 0xc6, 0xf7, 0xe7, 0x37, 0x53, 0x52, 0x65, 0xf9, 0xe7, 0x95, 0xe4,
0x16, 0x2c, 0xcb, 0x84, 0x15, 0x0b, 0x6a, 0x4b, 0xf3, 0xa2, 0xc7, 0xb0, 0x8f, 0x9b, 0xf2, 0x7c,
0x71, 0x53, 0x35, 0x55, 0xa2, 0x22, 0xf9, 0xd0, 0x1d, 0x2e, 0x13, 0xda, 0x88, 0xe9, 0xf4, 0x18,
0x1f, 0x11, 0x0a, 0x31, 0x9e, 0x9f, 0x0c, 0x41, 0x95, 0xb7, 0x3c, 0x19, 0x29, 0x6f, 0x05, 0x6b,
0x8c, 0xb3, 0x47, 0x41, 0x0b, 0x0e, 0x61, 0x7c, 0x3d, 0x1e, 0x40, 0x2a, 0x57, 0x7f, 0x92, 0xfc,
0xc6, 0x5b, 0x56, 0x5f, 0x35, 0x15, 0x49, 0xa9, 0x9a, 0x0a, 0x0f, 0x7c, 0x6d, 0x2d, 0x85, 0xb3,
0xe1, 0x61, 0x1f, 0xe6, 0x0c, 0x5a, 0x2d, 0x7c, 0x5d, 0x51, 0x18, 0x83, 0xac, 0x62, 0x2b, 0xc4,
0x06, 0x2d, 0x84, 0x94, 0xed, 0xab, 0x64, 0x64, 0x6d, 0x9f, 0xff, 0x29, 0x4d, 0xf9, 0x56, 0x96,
0xc1, 0x5e, 0xb1, 0xba, 0x82, 0x18, 0x6f, 0x65, 0x19, 0xd6, 0x2b, 0x61, 0x54, 0x39, 0xbb, 0x4e,
0x3e, 0x02, 0xce, 0x0e, 0xf2, 0x46, 0x38, 0xdc, 0x88, 0x5b, 0x51, 0x98, 0x71, 0x3a, 0x1e, 0x8a,
0x2b, 0xc7, 0x7f, 0xb9, 0x92, 0x7c, 0x2f, 0xe0, 0xf9, 0x84, 0xce, 0xd8, 0x82, 0x8e, 0x9e, 0xf6,
0x5b, 0x93, 0xa4, 0xf1, 0xff, 0xd9, 0x0d, 0x34, 0x02, 0xc3, 0x64, 0x42, 0x0b, 0x9a, 0x72, 0x74,
0x98, 0x48, 0x71, 0xef, 0x30, 0x31, 0x98, 0x33, 0xc3, 0xb4, 0x70, 0x8f, 0xf2, 0xed, 0x79, 0x5d,
0xd3, 0x92, 0xa3, 0x7d, 0x69, 0x91, 0xde, 0xbe, 0xf4, 0xd0, 0x40, 0x7d, 0xf6, 0x28, 0xdf, 0x2a,
0x0a, 0xb4, 0x3e, 0x52, 0xdc, 0x5b, 0x1f, 0x83, 0x29, 0x0f, 0x69, 0xf2, 0x9b, 0x4e, 0x8b, 0xf1,
0xfd, 0xf2, 0x82, 0x8d, 0xf0, 0xb6, 0x10, 0x72, 0xe3, 0x63, 0xb5, 0x97, 0x0b, 0x54, 0xe3, 0xd5,
0xbb, 0x8a, 0xd5, 0x78, 0xb7, 0x48, 0x71, 0x6f, 0x35, 0x0c, 0xa6, 0x3c, 0xfc, 0x71, 0xf2, 0x81,
0x8a, 0x92, 0x7a, 0x3d, 0xbb, 0x1f, 0x0c, 0xa1, 0x70, 0x41, 0x7b, 0xd0, 0x43, 0xd9, 0xe0, 0xa0,
0x64, 0x2a, 0xf8, 0x7c, 0x1a, 0xd4, 0x03, 0xa1, 0xe7, 0x7e, 0x1c, 0xea, 0xd8, 0xde, 0xa1, 0x05,
0x45, 0x6d, 0x4b, 0x61, 0x8f, 0x6d, 0x03, 0x29, 0xdb, 0x75, 0xf2, 0x3b, 0xa6, 0x59, 0xda, 0x75,
0x54, 0xc8, 0xdb, 0x20, 0xbd, 0x86, 0xd4, 0xdb, 0x85, 0x8c, 0xaf, 0xf5, 0x61, 0x70, 0xa7, 0x3e,
0x6a, 0x06, 0x86, 0xeb, 0x03, 0xe6, 0xdf, 0xfd, 0x38, 0xa4, 0x6c, 0xff, 0xc3, 0x4a, 0xf2, 0x03,
0x25, 0x7b, 0x55, 0x92, 0xf3, 0x82, 0x8a, 0x25, 0xf1, 0x88, 0xf2, 0x6b, 0x56, 0x5f, 0x4d, 0x96,
0x65, 0x8a, 0x2c, 0xff, 0x61, 0xb8, 0x67, 0xf9, 0x47, 0x95, 0x9c, 0x8c, 0x4f, 0x55, 0x94, 0xb3,
0x0a, 0x66, 0x7c, 0xba, 0x06, 0x9c, 0x55, 0x58, 0xc6, 0xe7, 0x23, 0x1d, 0xab, 0x87, 0x6d, 0xd8,
0x0c, 0x5b, 0x3d, 0x74, 0xe3, 0xe4, 0xbd, 0x18, 0x62, 0xc3, 0x96, 0x1e, 0xc0, 0xac, 0xbc, 0xc8,
0xa7, 0x67, 0x55, 0xd6, 0x0e, 0xe3, 0xc7, 0xe1, 0x11, 0xea, 0x20, 0x48, 0xd8, 0x42, 0x50, 0xe5,
0xed, 0x9f, 0x6c, 0x62, 0xa4, 0xa6, 0xd2, 0x6e, 0xcd, 0x66, 0x07, 0x74, 0x4a, 0xd2, 0xa5, 0x9a,
0xff, 0x9f, 0xc7, 0x26, 0x1e, 0xa4, 0x4d, 0x21, 0x5e, 0xdc, 0x50, 0x4b, 0x95, 0xe7, 0x3f, 0x57,
0x92, 0xfb, 0xba, 0xfa, 0x97, 0xa4, 0x9c, 0x52, 0xd5, 0x9f, 0xb2, 0xf4, 0x5b, 0x65, 0x76, 0x42,
0x1b, 0x4e, 0x6a, 0x3e, 0xfa, 0x51, 0xb8, 0x92, 0x31, 0x1d, 0x53, 0xb6, 0x1f, 0xff, 0x52, 0xba,
0xb6, 0xd7, 0x27, 0x6d, 0x60, 0x53, 0x21, 0xc0, 0xef, 0x75, 0x21, 0x81, 0x01, 0xe0, 0x5e, 0x0c,
0xb1, 0xbd, 0x2e, 0x04, 0xfb, 0xe5, 0x22, 0xe7, 0x74, 0x8f, 0x96, 0xb4, 0xee, 0xf6, 0xba, 0x54,
0xf5, 0x11, 0xa4, 0xd7, 0x11, 0xd4, 0x06, 0x1b, 0xcf, 0x9b, 0x59, 0x1c, 0xd7, 0x22, 0x46, 0x3a,
0xcb, 0xe3, 0xfa, 0x30, 0xd8, 0xee, 0xee, 0x1c, 0x9f, 0x27, 0x74, 0xc1, 0xae, 0xe0, 0xee, 0xce,
0x35, 0x21, 0x01, 0x64, 0x77, 0x17, 0x04, 0xed, 0x0a, 0xe6, 0xf8, 0x79, 0x93, 0xd3, 0x6b, 0xb0,
0x82, 0xb9, 0xca, 0xad, 0x18, 0x59, 0xc1, 0x02, 0x98, 0xf2, 0x70, 0x94, 0xfc, 0x9a, 0x10, 0xfe,
0x21, 0xcb, 0xcb, 0xd1, 0xed, 0x80, 0x52, 0x2b, 0x30, 0x56, 0xef, 0xe0, 0x00, 0x28, 0x71, 0xfb,
0xeb, 0x36, 0x29, 0x53, 0x5a, 0x04, 0x4b, 0x6c, 0xc5, 0xd1, 0x12, 0x7b, 0x98, 0x4d, 0x1d, 0x84,
0xb0, 0x8d, 0x5f, 0x93, 0x4b, 0x52, 0xe7, 0xe5, 0x74, 0x14, 0xd2, 0x75, 0xe4, 0x48, 0xea, 0x10,
0xe2, 0xc0, 0x10, 0x56, 0x8a, 0x5b, 0x55, 0x55, 0xb7, 0x61, 0x31, 0x34, 0x84, 0x7d, 0x24, 0x3a,
0x84, 0x3b, 0x68, 0xd8, 0xdb, 0x0e, 0x4d, 0x8b, 0xbc, 0x8c, 0x7a, 0x53, 0xc8, 0x10, 0x6f, 0x16,
0x05, 0x83, 0xf7, 0x80, 0x92, 0x05, 0xd5, 0x35, 0x0b, 0xb5, 0x8c, 0x0b, 0x44, 0x07, 0x2f, 0x00,
0xed, 0x3e, 0x4d, 0x88, 0x0f, 0xc9, 0x15, 0x6d, 0x1b, 0x98, 0xb6, 0xeb, 0xda, 0x28, 0xa4, 0xef,
0x11, 0xc8, 0x3e, 0x2d, 0x4c, 0x2a, 0x57, 0xf3, 0xe4, 0x23, 0x21, 0x3f, 0x26, 0x35, 0xcf, 0xd3,
0xbc, 0x22, 0xa5, 0xce, 0xff, 0x43, 0xf3, 0xba, 0x43, 0x19, 0x97, 0x1b, 0x03, 0x69, 0xe5, 0xf6,
0x3f, 0x56, 0x92, 0xbb, 0xd0, 0xef, 0x31, 0xad, 0x67, 0xb9, 0xd8, 0x46, 0x36, 0x32, 0x08, 0x8f,
0xbe, 0x8c, 0x1b, 0xed, 0x28, 0x98, 0xd2, 0xfc, 0xf0, 0xe6, 0x8a, 0xaa, 0x60, 0x7f, 0x94, 0x24,
0x72, 0xbb, 0x22, 0xb6, 0x94, 0xfe, 0xac, 0x55, 0xfb, 0x18, 0x6f, 0x3f, 0x79, 0x37, 0x42, 0xd8,
0xa5, 0x42, 0xfe, 0x2e, 0x76, 0xca, 0xa3, 0xa0, 0x86, 0x10, 0x21, 0x4b, 0x05, 0x40, 0x60, 0x41,
0x27, 0x97, 0xec, 0x3a, 0x5c, 0xd0, 0x56, 0x12, 0x2f, 0xa8, 0x22, 0xec, 0xd9, 0x95, 0x2a, 0x68,
0xe8, 0xec, 0x4a, 0x17, 0x23, 0x76, 0x76, 0x05, 0x19, 0x65, 0x98, 0x25, 0xbf, 0xed, 0x1a, 0x7e,
0xc9, 0xd8, 0xd5, 0x8c, 0xd4, 0x57, 0xa3, 0x27, 0xb8, 0xb2, 0x66, 0x8c, 0xa3, 0xb5, 0x41, 0xac,
0x0d, 0x0b, 0xae, 0xc3, 0x36, 0xd1, 0x38, 0xab, 0x0b, 0x10, 0x16, 0x3c, 0x1b, 0x0a, 0x41, 0xc2,
0x02, 0x82, 0xda, 0xc8, 0xed, 0x7a, 0x9b, 0x50, 0xb8, 0x5b, 0xf2, 0xd4, 0x27, 0x14, 0xdb, 0x2d,
0x05, 0x30, 0x38, 0x84, 0xf6, 0x6a, 0x52, 0x5d, 0x86, 0x87, 0x90, 0x10, 0xc5, 0x87, 0x90, 0x46,
0x60, 0x7f, 0x4f, 0x28, 0xa9, 0xd3, 0xcb, 0x70, 0x7f, 0x4b, 0x59, 0xbc, 0xbf, 0x0d, 0x03, 0xfb,
0x5b, 0x0a, 0xde, 0xe6, 0xfc, 0xf2, 0x90, 0x72, 0x12, 0xee, 0x6f, 0x9f, 0x89, 0xf7, 0x77, 0x87,
0xb5, 0x99, 0x8c, 0xeb, 0x70, 0x32, 0x3f, 0x6f, 0xd2, 0x3a, 0x3f, 0xa7, 0xa3, 0x88, 0x15, 0x03,
0x21, 0x99, 0x0c, 0x0a, 0x2b, 0x9f, 0x3f, 0x5f, 0x49, 0x6e, 0xeb, 0x6e, 0x67, 0x4d, 0x23, 0x57,
0x56, 0xe0, 0xfe, 0x45, 0xb8, 0x7f, 0x11, 0x1c, 0x39, 0x4d, 0x1c, 0xa0, 0xe6, 0x44, 0xd5, 0x70,
0x91, 0xce, 0xca, 0xc6, 0x14, 0xea, 0xcb, 0x21, 0xd6, 0x1d, 0x05, 0x24, 0xaa, 0x0e, 0x52, 0xb4,
0x0b, 0x9a, 0xea, 0x1f, 0x2d, 0xdb, 0xcf, 0x1a, 0xb0, 0xa0, 0xe9, 0xf6, 0x76, 0x08, 0x64, 0x41,
0x0b, 0x93, 0x70, 0x28, 0xec, 0xd5, 0x6c, 0x5e, 0x35, 0x3d, 0x43, 0x01, 0x40, 0xf1, 0xa1, 0xd0,
0x85, 0x95, 0xcf, 0x77, 0xc9, 0xef, 0xba, 0xc3, 0xcf, 0x6d, 0xec, 0x0d, 0x7c, 0x4c, 0x85, 0x9a,
0x78, 0x3c, 0x14, 0xb7, 0x29, 0x9d, 0xf6, 0xcc, 0x77, 0x28, 0x27, 0x79, 0xd1, 0x8c, 0x1e, 0x86,
0x6d, 0x68, 0x39, 0x92, 0xd2, 0x85, 0x38, 0x18, 0xdf, 0x76, 0xe6, 0x55, 0x91, 0xa7, 0xdd, 0xb3,
0x5c, 0xa5, 0x6b, 0xc4, 0xf1, 0xf8, 0xe6, 0x62, 0x30, 0x5e, 0x4f, 0x28, 0x97, 0xff, 0x39, 0x5d,
0x56, 0x34, 0x1c, 0xaf, 0x3d, 0x24, 0x1e, 0xaf, 0x21, 0x0a, 0xeb, 0x33, 0xa1, 0xfc, 0x80, 0x2c,
0xd9, 0x1c, 0x89, 0xd7, 0x46, 0x1c, 0xaf, 0x8f, 0x8b, 0xd9, 0xac, 0xca, 0x78, 0xd8, 0x2f, 0x39,
0xad, 0x4b, 0x52, 0xec, 0x16, 0x64, 0xda, 0x8c, 0x90, 0x18, 0xe3, 0x53, 0x48, 0x56, 0x85, 0xd3,
0x81, 0x66, 0xdc, 0x6f, 0x76, 0xc9, 0x82, 0xd5, 0x39, 0xc7, 0x9b, 0xd1, 0x22, 0xbd, 0xcd, 0xe8,
0xa1, 0x41, 0x6f, 0x5b, 0x75, 0x7a, 0x99, 0x2f, 0x68, 0x16, 0xf1, 0xa6, 0x91, 0x01, 0xde, 0x1c,
0x34, 0xd0, 0x69, 0x13, 0x36, 0xaf, 0x53, 0x8a, 0x76, 0x9a, 0x14, 0xf7, 0x76, 0x9a, 0xc1, 0x94,
0x87, 0xbf, 0x59, 0x49, 0x7e, 0x4f, 0x4a, 0xdd, 0x03, 0xd6, 0x1d, 0xd2, 0x5c, 0x9e, 0x33, 0x52,
0x67, 0xa3, 0xcf, 0x42, 0x76, 0x82, 0xa8, 0x71, 0xfd, 0xec, 0x26, 0x2a, 0xb0, 0x59, 0x0f, 0xf2,
0xc6, 0x99, 0x71, 0xc1, 0x66, 0xf5, 0x90, 0x78, 0xb3, 0x42, 0x14, 0x06, 0x10, 0x21, 0x97, 0x87,
0x19, 0x0f, 0x51, 0x7d, 0xff, 0x44, 0x63, 0xb5, 0x97, 0x83, 0xf1, 0xb1, 0x15, 0xfa, 0xa3, 0x65,
0x03, 0xb3, 0x11, 0x1e, 0x31, 0xe3, 0xa1, 0x38, 0xea, 0xd9, 0xcc, 0x8a, 0xb8, 0xe7, 0xce, 0xcc,
0x18, 0x0f, 0xc5, 0x11, 0xcf, 0x4e, 0x58, 0x8b, 0x79, 0x0e, 0x84, 0xb6, 0xf1, 0x50, 0x1c, 0x66,
0x5f, 0x8a, 0xd1, 0xeb, 0xc2, 0x93, 0x88, 0x1d, 0xb8, 0x36, 0xac, 0x0d, 0x62, 0x95, 0xc3, 0xbf,
0x5b, 0x49, 0xbe, 0x6f, 0x3d, 0x1e, 0xb2, 0x2c, 0xbf, 0x58, 0x4a, 0xe8, 0x0d, 0x29, 0xe6, 0xb4,
0x19, 0x3d, 0xc3, 0xac, 0x75, 0x59, 0x53, 0x82, 0xe7, 0x37, 0xd2, 0x81, 0x73, 0x67, 0xab, 0xaa,
0x8a, 0xe5, 0x29, 0x9d, 0x55, 0x05, 0x3a, 0x77, 0x3c, 0x24, 0x3e, 0x77, 0x20, 0x0a, 0xb3, 0xf2,
0x53, 0xd6, 0xe6, 0xfc, 0xc1, 0xac, 0x5c, 0x88, 0xe2, 0x59, 0xb9, 0x46, 0x60, 0xae, 0x74, 0xca,
0xb6, 0x59, 0x51, 0xd0, 0x94, 0x77, 0x1f, 0xd2, 0x1a, 0x4d, 0x4b, 0xc4, 0x73, 0x25, 0x40, 0xda,
0xf3, 0x0c, 0xbd, 0x87, 0x24, 0x35, 0x7d, 0xb9, 0x3c, 0xc8, 0xcb, 0xab, 0x51, 0x38, 0x2d, 0xb0,
0x00, 0x72, 0x9e, 0x11, 0x04, 0xe1, 0x5e, 0xf5, 0xac, 0xcc, 0x58, 0x78, 0xaf, 0xda, 0x4a, 0xe2,
0x7b, 0x55, 0x45, 0x40, 0x93, 0x27, 0x14, 0x33, 0xd9, 0x4a, 0xe2, 0x26, 0x15, 0x11, 0x0a, 0x85,
0xea, 0xd4, 0x1b, 0x0d, 0x85, 0xe0, 0x9c, 0x7b, 0xb5, 0x97, 0x83, 0x23, 0x54, 0x6f, 0x5a, 0x77,
0x29, 0x4f, 0x2f, 0xc3, 0x23, 0xd4, 0x43, 0xe2, 0x23, 0x14, 0xa2, 0xb0, 0x4a, 0xa7, 0xcc, 0x6c,
0xba, 0x1f, 0x86, 0xc7, 0x47, 0x67, 0xc3, 0xbd, 0xda, 0xcb, 0xc1, 0x6d, 0xe4, 0xfe, 0x4c, 0xb4,
0x59, 0x70, 0x90, 0x4b, 0x59, 0x7c, 0x1b, 0x69, 0x18, 0x58, 0x7a, 0x29, 0x68, 0x9b, 0x33, 0x5c,
0x7a, 0x2b, 0x8f, 0x97, 0xde, 0xe3, 0x94, 0x93, 0x7f, 0x33, 0xdb, 0x38, 0x29, 0x3d, 0x62, 0xed,
0x1c, 0x79, 0x43, 0x8a, 0x3c, 0x23, 0x9c, 0x9e, 0xb2, 0x2b, 0x5a, 0x86, 0x77, 0x4c, 0xaa, 0xb4,
0x92, 0x1f, 0x7b, 0x0a, 0xf1, 0x1d, 0x53, 0x5c, 0x11, 0x8e, 0x13, 0x49, 0x9f, 0x35, 0x74, 0x9b,
0x34, 0x48, 0x24, 0xf3, 0x90, 0xf8, 0x38, 0x81, 0x28, 0xcc, 0x57, 0xa5, 0xfc, 0xd5, 0xbb, 0x8a,
0xd6, 0x39, 0x2d, 0x53, 0x1a, 0xce, 0x57, 0x21, 0x15, 0xcf, 0x57, 0x03, 0x74, 0xe7, 0x98, 0xc6,
0x04, 0xa7, 0xee, 0x3d, 0x0b, 0x48, 0x44, 0xee, 0x59, 0x20, 0x28, 0xac, 0xa4, 0x05, 0x82, 0x47,
0x9d, 0x1d, 0x2b, 0xd1, 0xa3, 0x4e, 0x9c, 0xee, 0x1c, 0x7e, 0x19, 0x66, 0xd2, 0x4e, 0x93, 0x9e,
0xa2, 0x4f, 0xdc, 0xe9, 0xb2, 0x36, 0x88, 0x0d, 0x9f, 0xb6, 0x9d, 0xd0, 0x82, 0x88, 0x25, 0x24,
0x72, 0xa4, 0xa5, 0x99, 0x21, 0xa7, 0x6d, 0x0e, 0xab, 0x1c, 0xfe, 0xd5, 0x4a, 0xf2, 0x49, 0xc8,
0xe3, 0xeb, 0x4a, 0xf8, 0x7d, 0xda, 0x6f, 0x4b, 0x92, 0xc8, 0x45, 0x92, 0xb8, 0x86, 0x2a, 0xc3,
0x9f, 0x25, 0x1f, 0x6b, 0x91, 0xbd, 0x67, 0xa2, 0x0a, 0xe0, 0x27, 0x50, 0xa6, 0xfc, 0x90, 0x33,
0xee, 0x37, 0x07, 0xf3, 0x76, 0x6f, 0xe2, 0x97, 0xab, 0x01, 0x7b, 0x13, 0x63, 0x43, 0x89, 0x91,
0xbd, 0x49, 0x00, 0xb3, 0xa7, 0x1a, 0x6e, 0xf5, 0xde, 0xe6, 0xfc, 0x52, 0xe4, 0x3e, 0xe0, 0x54,
0xc3, 0x2b, 0xab, 0x81, 0x90, 0x53, 0x0d, 0x14, 0x86, 0xd9, 0x81, 0x06, 0xdb, 0xb9, 0x19, 0x8a,
0xab, 0xc6, 0x90, 0x3b, 0x33, 0x1f, 0xf5, 0x83, 0x70, 0xbc, 0x6a, 0xb1, 0xda, 0x86, 0x3c, 0x89,
0x59, 0x00, 0x5b, 0x91, 0xb5, 0x41, 0xac, 0x72, 0xf8, 0x17, 0xc9, 0xf7, 0x3a, 0x15, 0xdb, 0xa5,
0x84, 0xcf, 0x6b, 0x9a, 0x8d, 0x36, 0x7b, 0xca, 0xad, 0x41, 0xe3, 0xfa, 0xe9, 0x70, 0x85, 0x4e,
0xbe, 0xac, 0x39, 0x39, 0xac, 0x4c, 0x19, 0x9e, 0xc5, 0x4c, 0xfa, 0x6c, 0x34, 0x5f, 0xc6, 0x75,
0x3a, 0x5b, 0x5e, 0x77, 0x74, 0x6d, 0x2d, 0x48, 0x5e, 0x88, 0x47, 0x4e, 0x9f, 0xc5, 0x8c, 0x7a,
0x68, 0x74, 0xcb, 0x8b, 0xaa, 0x74, 0x22, 0xb3, 0x98, 0xe3, 0xce, 0x56, 0x69, 0x1d, 0x8f, 0x04,
0x81, 0x9d, 0xd2, 0xc6, 0x40, 0x5a, 0xb9, 0xe5, 0xfa, 0xa8, 0xb0, 0xfd, 0xd9, 0x1d, 0xe4, 0x21,
0xaf, 0x4a, 0x35, 0x30, 0xd2, 0x37, 0x06, 0xd2, 0xca, 0xeb, 0x9f, 0x27, 0x1f, 0x77, 0xbd, 0xaa,
0x85, 0x68, 0xb3, 0xd7, 0x14, 0x58, 0x8b, 0x9e, 0x0e, 0x57, 0xb0, 0xdb, 0x8b, 0xaf, 0xf2, 0x86,
0xb3, 0x7a, 0x39, 0xb9, 0x64, 0xd7, 0xfa, 0xfe, 0xb6, 0x3f, 0x5b, 0x15, 0x30, 0x76, 0x08, 0x64,
0x7b, 0x11, 0x26, 0x3b, 0xae, 0xec, 0x3d, 0xef, 0x06, 0x71, 0xe5, 0x10, 0x3d, 0xae, 0x7c, 0xd2,
0xc6, 0x2a, 0x5d, 0x2b, 0x7b, 0x29, 0x7d, 0x35, 0x5c, 0xd4, 0xee, 0xc5, 0xf4, 0x47, 0xfd, 0xa0,
0xcd, 0x58, 0x94, 0x78, 0x27, 0xbf, 0xb8, 0x30, 0x75, 0x0a, 0x97, 0xd4, 0x45, 0x90, 0x8c, 0x05,
0x41, 0x6d, 0x02, 0xbc, 0x9b, 0x17, 0x54, 0x9c, 0xae, 0xbf, 0xbe, 0xb8, 0x28, 0x18, 0xc9, 0x40,
0x02, 0xdc, 0x8a, 0xc7, 0xae, 0x1c, 0x49, 0x80, 0x43, 0x9c, 0xbd, 0xfe, 0xd5, 0x4a, 0x4f, 0x68,
0xca, 0xca, 0x34, 0x2f, 0xe0, 0x75, 0x36, 0xa1, 0x69, 0x84, 0xc8, 0xf5, 0xaf, 0x0e, 0x64, 0x17,
0xc6, 0x56, 0xd4, 0x4e, 0x7b, 0x5d, 0xfe, 0x07, 0x5d, 0x45, 0x47, 0x8c, 0x2c, 0x8c, 0x01, 0xcc,
0xee, 0x03, 0x5b, 0xe1, 0x59, 0x25, 0x8c, 0xdf, 0xe9, 0x6a, 0x49, 0x09, 0xb2, 0x0f, 0xf4, 0x09,
0xbb, 0x9f, 0x69, 0x7f, 0xdf, 0x61, 0xd7, 0xa5, 0x30, 0x7a, 0xaf, 0xab, 0xa2, 0x65, 0xc8, 0x7e,
0x06, 0x32, 0xca, 0xf0, 0x4f, 0x92, 0x5f, 0x15, 0x86, 0x6b, 0x56, 0x8d, 0x6e, 0x05, 0x14, 0x6a,
0xe7, 0xe6, 0xd9, 0x6d, 0x54, 0x6e, 0x2f, 0x50, 0x9a, 0xb1, 0x71, 0xd6, 0x90, 0x29, 0x1d, 0xdd,
0x47, 0x7a, 0x5c, 0x48, 0x91, 0x0b, 0x94, 0x5d, 0xca, 0x1f, 0x15, 0x47, 0x2c, 0x53, 0xd6, 0x03,
0x35, 0x34, 0xc2, 0xd8, 0xa8, 0x70, 0x21, 0x9b, 0xcc, 0x1c, 0x91, 0x45, 0x3e, 0x35, 0x0b, 0x8e,
0x8c, 0x5b, 0x0d, 0x48, 0x66, 0x2c, 0x33, 0x76, 0x20, 0x24, 0x99, 0x41, 0x61, 0xe5, 0xf3, 0x5f,
0x57, 0x92, 0x3b, 0x96, 0xd9, 0xd3, 0x27, 0x67, 0xfb, 0xe5, 0x05, 0x6b, 0x53, 0x9f, 0x83, 0xbc,
0xbc, 0x6a, 0x46, 0x5f, 0x60, 0x26, 0xc3, 0xbc, 0x29, 0xca, 0x97, 0x37, 0xd6, 0xb3, 0x59, 0xab,
0x3e, 0x56, 0xb2, 0xcf, 0x96, 0xa5, 0x06, 0xc8, 0x5a, 0xcd, 0xe9, 0x13, 0xe4, 0x90, 0xac, 0x35,
0xc6, 0xdb, 0x2e, 0x36, 0xce, 0x0b, 0x56, 0xc2, 0x2e, 0xb6, 0x16, 0x5a, 0x21, 0xd2, 0xc5, 0x1d,
0xc8, 0xc6, 0x63, 0x2d, 0x92, 0x27, 0x20, 0x5b, 0x45, 0x01, 0xe2, 0xb1, 0x51, 0x35, 0x00, 0x12,
0x8f, 0x83, 0xa0, 0xf2, 0x73, 0x92, 0x7c, 0xa7, 0x6d, 0xd2, 0xe3, 0x9a, 0x2e, 0x72, 0x0a, 0xaf,
0x41, 0x38, 0x12, 0x64, 0xfe, 0xfb, 0x84, 0x9d, 0x59, 0x67, 0x65, 0x53, 0x15, 0xa4, 0xb9, 0x54,
0x0f, 0xc6, 0xfd, 0x3a, 0x6b, 0x21, 0x7c, 0x34, 0xfe, 0xa0, 0x87, 0xb2, 0x41, 0x5d, 0xcb, 0x4c,
0x88, 0x79, 0x18, 0x56, 0xed, 0x84, 0x99, 0xd5, 0x5e, 0xce, 0x9e, 0x3e, 0xef, 0x91, 0xa2, 0xa0,
0xf5, 0x52, 0xcb, 0x0e, 0x49, 0x99, 0x5f, 0xd0, 0x86, 0x83, 0xd3, 0x67, 0x45, 0x8d, 0x21, 0x86,
0x9c, 0x3e, 0x47, 0x70, 0x9b, 0xcd, 0x03, 0xcf, 0xfb, 0x65, 0x46, 0xdf, 0x81, 0x6c, 0x1e, 0xda,
0x11, 0x0c, 0x92, 0xcd, 0x63, 0xac, 0x3d, 0x85, 0x7d, 0x59, 0xb0, 0xf4, 0x4a, 0x2d, 0x01, 0x7e,
0x07, 0x0b, 0x09, 0x5c, 0x03, 0xee, 0xc5, 0x10, 0xbb, 0x08, 0x08, 0xc1, 0x09, 0xad, 0x0a, 0x92,
0xc2, 0xbb, 0x30, 0x52, 0x47, 0xc9, 0x90, 0x45, 0x00, 0x32, 0xa0, 0xb8, 0xea, 0x8e, 0x4d, 0xa8,
0xb8, 0xe0, 0x8a, 0xcd, 0xbd, 0x18, 0x62, 0x97, 0x41, 0x21, 0x98, 0x54, 0x45, 0xce, 0xc1, 0x34,
0x90, 0x1a, 0x42, 0x82, 0x4c, 0x03, 0x9f, 0x00, 0x26, 0x0f, 0x69, 0x3d, 0xa5, 0x41, 0x93, 0x42,
0x12, 0x35, 0xa9, 0x09, 0x7b, 0x65, 0x52, 0xd6, 0x9d, 0x55, 0x4b, 0x70, 0x65, 0x52, 0x55, 0x8b,
0x55, 0x4b, 0xe4, 0xca, 0xa4, 0x07, 0x80, 0x22, 0x1e, 0x93, 0x86, 0x87, 0x8b, 0x28, 0x24, 0xd1,
0x22, 0x6a, 0xc2, 0xae, 0xd1, 0xb2, 0x88, 0x73, 0x0e, 0xd6, 0x68, 0x55, 0x00, 0xe7, 0x69, 0xf0,
0x6d, 0x54, 0x6e, 0x23, 0x89, 0xec, 0x15, 0xca, 0x77, 0x73, 0x5a, 0x64, 0x0d, 0x88, 0x24, 0xaa,
0xdd, 0xb5, 0x14, 0x89, 0x24, 0x5d, 0x0a, 0x0c, 0x25, 0x75, 0x56, 0x1d, 0xaa, 0x1d, 0x38, 0xa6,
0xbe, 0x17, 0x43, 0x6c, 0x7c, 0xd2, 0x85, 0xde, 0x26, 0x75, 0x9d, 0xb7, 0x8b, 0xff, 0xc3, 0x70,
0x81, 0xb4, 0x1c, 0x89, 0x4f, 0x21, 0x0e, 0x4c, 0x2f, 0x1d, 0xb8, 0x43, 0x05, 0x83, 0xa1, 0xfb,
0xd3, 0x28, 0x63, 0x33, 0x4e, 0x21, 0x71, 0x1e, 0x67, 0x86, 0x5a, 0x33, 0xf0, 0x34, 0xf3, 0x61,
0x1f, 0xe6, 0xbc, 0xd2, 0x60, 0x5c, 0x1c, 0xb2, 0x05, 0x3d, 0x65, 0xaf, 0xde, 0xe5, 0x0d, 0xcf,
0xcb, 0xa9, 0x5a, 0xb9, 0x9f, 0x23, 0x96, 0x42, 0x30, 0xf2, 0x4a, 0x43, 0xaf, 0x92, 0x4d, 0x20,
0x40, 0x59, 0x8e, 0xe8, 0x75, 0x30, 0x81, 0x80, 0x16, 0x0d, 0x87, 0x24, 0x10, 0x31, 0xde, 0x9e,
0xa3, 0x18, 0xe7, 0xea, 0xbd, 0xcf, 0x53, 0xa6, 0x73, 0x39, 0xcc, 0x1a, 0x04, 0x91, 0xad, 0x6c,
0x54, 0xc1, 0xee, 0x2f, 0x8d, 0x7f, 0x3b, 0xc5, 0x1e, 0x21, 0x76, 0xba, 0xd3, 0xec, 0xf1, 0x00,
0x32, 0xe0, 0xca, 0x3e, 0x93, 0xc7, 0x5c, 0x75, 0x1f, 0xc9, 0x3f, 0x1e, 0x40, 0x3a, 0x67, 0x32,
0x6e, 0xb5, 0x5e, 0x92, 0xf4, 0x6a, 0x5a, 0xb3, 0x79, 0x99, 0x6d, 0xb3, 0x82, 0xd5, 0xe0, 0x4c,
0xc6, 0x2b, 0x35, 0x40, 0x91, 0x33, 0x99, 0x1e, 0x15, 0x9b, 0xc1, 0xb9, 0xa5, 0xd8, 0x2a, 0xf2,
0x29, 0xdc, 0x51, 0x7b, 0x86, 0x04, 0x80, 0x64, 0x70, 0x41, 0x30, 0x30, 0x88, 0xe4, 0x8e, 0x9b,
0xe7, 0x29, 0x29, 0xa4, 0xbf, 0x4d, 0xdc, 0x8c, 0x07, 0xf6, 0x0e, 0xa2, 0x80, 0x42, 0xa0, 0x9e,
0xa7, 0xf3, 0xba, 0xdc, 0x2f, 0x39, 0x43, 0xeb, 0xa9, 0x81, 0xde, 0x7a, 0x3a, 0x20, 0x08, 0xab,
0xa7, 0xf4, 0x5d, 0x5b, 0x9a, 0xf6, 0x9f, 0x50, 0x58, 0x6d, 0x7f, 0x1f, 0x2b, 0x79, 0x2c, 0xac,
0x02, 0x0e, 0x54, 0x46, 0x39, 0x91, 0x03, 0x26, 0xa2, 0xed, 0x0f, 0x93, 0x47, 0xfd, 0x60, 0xd8,
0xcf, 0x84, 0x2f, 0x0b, 0x1a, 0xf3, 0x23, 0x80, 0x21, 0x7e, 0x34, 0x68, 0x8f, 0x5b, 0xbc, 0xfa,
0x5c, 0xd2, 0xf4, 0xaa, 0x73, 0xc5, 0xc8, 0x2f, 0xa8, 0x44, 0x90, 0xe3, 0x16, 0x04, 0x0d, 0x77,
0xd1, 0x7e, 0xca, 0xca, 0x58, 0x17, 0xb5, 0xf2, 0x21, 0x5d, 0xa4, 0x38, 0xbb, 0xf9, 0x35, 0x52,
0x35, 0x32, 0x65, 0x37, 0xad, 0x21, 0x16, 0x5c, 0x08, 0xd9, 0xfc, 0xa2, 0xb0, 0xcd, 0xc9, 0xa1,
0xcf, 0xc3, 0xee, 0xfd, 0xeb, 0x8e, 0x95, 0x43, 0xfc, 0xfe, 0x35, 0xc6, 0xe2, 0x95, 0x94, 0x63,
0xa4, 0xc7, 0x8a, 0x3f, 0x4e, 0xd6, 0x87, 0xc1, 0x76, 0xcb, 0xe3, 0xf9, 0xdc, 0x2e, 0x28, 0xa9,
0xa5, 0xd7, 0x8d, 0x88, 0x21, 0x8b, 0x21, 0x5b, 0x9e, 0x08, 0x0e, 0x42, 0x98, 0xe7, 0x79, 0x9b,
0x95, 0x9c, 0x96, 0x3c, 0x14, 0xc2, 0x7c, 0x63, 0x0a, 0x8c, 0x85, 0x30, 0x4c, 0x01, 0x8c, 0x5b,
0x71, 0x1e, 0x44, 0xf9, 0x11, 0x99, 0x05, 0x33, 0x36, 0x79, 0xd6, 0x23, 0xe5, 0xb1, 0x71, 0x0b,
0x38, 0xe7, 0x21, 0x9f, 0xeb, 0xe5, 0x94, 0xd4, 0x53, 0x73, 0xba, 0x91, 0x8d, 0x9e, 0xe2, 0x76,
0x7c, 0x12, 0x79, 0xc8, 0x17, 0xd7, 0x00, 0x61, 0x67, 0x7f, 0x46, 0xa6, 0xa6, 0xa6, 0x81, 0x1a,
0x08, 0x79, 0xa7, 0xaa, 0x8f, 0xfa, 0x41, 0xe0, 0xe7, 0x4d, 0x9e, 0x51, 0x16, 0xf1, 0x23, 0xe4,
0x43, 0xfc, 0x40, 0x10, 0x64, 0x6f, 0x6d, 0xbd, 0xe5, 0x8e, 0x6e, 0xab, 0xcc, 0xd4, 0x3e, 0x76,
0x8c, 0x34, 0x0f, 0xe0, 0x62, 0xd9, 0x1b, 0xc2, 0x83, 0x39, 0xaa, 0x0f, 0x68, 0x63, 0x73, 0xd4,
0x9c, 0xbf, 0x0e, 0x99, 0xa3, 0x21, 0x58, 0xf9, 0xfc, 0x99, 0x9a, 0xa3, 0x3b, 0x84, 0x93, 0x36,
0x6f, 0x7f, 0x93, 0xd3, 0x6b, 0xb5, 0x11, 0x0e, 0xd4, 0x57, 0x53, 0x63, 0xf1, 0xe2, 0x1d, 0xd8,
0x15, 0x6f, 0x0e, 0xe6, 0x23, 0xbe, 0xd5, 0x0e, 0xa1, 0xd7, 0x37, 0xd8, 0x2a, 0x6c, 0x0e, 0xe6,
0x23, 0xbe, 0xd5, 0x1b, 0xbd, 0xbd, 0xbe, 0xc1, 0x6b, 0xbd, 0x9b, 0x83, 0x79, 0xe5, 0xfb, 0xaf,
0xf5, 0xc4, 0x75, 0x9d, 0xb7, 0x79, 0x58, 0xca, 0xf3, 0x05, 0x0d, 0xa5, 0x93, 0xbe, 0x3d, 0x83,
0xc6, 0xd2, 0x49, 0x5c, 0xc5, 0xf9, 0x0c, 0x4c, 0xa8, 0x14, 0xc7, 0xac, 0xc9, 0xc5, 0x43, 0xfa,
0xe7, 0x03, 0x8c, 0x6a, 0x38, 0xb6, 0x69, 0x8a, 0x29, 0xd9, 0xc7, 0x8d, 0x1e, 0x6a, 0x6f, 0x14,
0xaf, 0x47, 0xec, 0x75, 0x2f, 0x16, 0x6f, 0x0c, 0xa4, 0xed, 0x83, 0x3f, 0x8f, 0x71, 0x9f, 0x38,
0xc6, 0x7a, 0x35, 0xf8, 0xd0, 0xf1, 0xe9, 0x70, 0x05, 0xe5, 0xfe, 0x6f, 0xf5, 0xbe, 0x02, 0xfa,
0x57, 0x93, 0xe0, 0xd9, 0x10, 0x8b, 0x60, 0x22, 0x3c, 0xbf, 0x91, 0x8e, 0x2a, 0xc8, 0x3f, 0xea,
0x0d, 0xb4, 0x46, 0xc5, 0x7b, 0x15, 0xaf, 0xeb, 0x8c, 0xd6, 0x6a, 0x4e, 0xc4, 0xba, 0xd5, 0xc2,
0x70, 0x66, 0xbc, 0xb8, 0xa1, 0x96, 0xf3, 0x51, 0x20, 0x0f, 0x56, 0xef, 0xff, 0x39, 0xe5, 0x89,
0x59, 0x76, 0x68, 0x58, 0xa0, 0x2f, 0x6e, 0xaa, 0x86, 0xcd, 0x15, 0x07, 0x16, 0xdf, 0x18, 0x78,
0x3e, 0xd0, 0xb0, 0xf7, 0xd5, 0x81, 0xcf, 0x6f, 0xa6, 0xa4, 0xca, 0xf2, 0x5f, 0x2b, 0xc9, 0x03,
0x8f, 0xb5, 0xcf, 0x13, 0xc0, 0xa9, 0xc7, 0x8f, 0x23, 0xf6, 0x31, 0x25, 0x53, 0xb8, 0xdf, 0xff,
0xe5, 0x94, 0xed, 0x17, 0x74, 0x3c, 0x95, 0xdd, 0xbc, 0xe0, 0xb4, 0xee, 0x7e, 0x41, 0xc7, 0xb7,
0x2b, 0xa9, 0x31, 0xfe, 0x05, 0x9d, 0x08, 0xee, 0x7c, 0x41, 0x27, 0xe0, 0x39, 0xf8, 0x05, 0x9d,
0xa0, 0xb5, 0xe8, 0x17, 0x74, 0xe2, 0x1a, 0x58, 0x78, 0xd7, 0x45, 0x90, 0xe7, 0xd6, 0x83, 0x2c,
0xfa, 0xc7, 0xd8, 0xcf, 0x6e, 0xa2, 0x82, 0x2c, 0x70, 0x92, 0x13, 0xf7, 0xdc, 0x06, 0xb4, 0xa9,
0x77, 0xd7, 0x6d, 0x73, 0x30, 0xaf, 0x7c, 0xff, 0x54, 0xed, 0x6e, 0x4c, 0x38, 0x67, 0xb5, 0xf8,
0x7a, 0xd2, 0x5a, 0x2c, 0x3c, 0xb7, 0x16, 0xdc, 0x9e, 0x5f, 0x1f, 0x06, 0x23, 0xd5, 0x6d, 0x09,
0xd5, 0xe9, 0xe3, 0x3e, 0x43, 0xa0, 0xcb, 0x37, 0x07, 0xf3, 0xc8, 0x32, 0x22, 0x7d, 0xcb, 0xde,
0x1e, 0x60, 0xcc, 0xef, 0xeb, 0xa7, 0xc3, 0x15, 0x94, 0xfb, 0x85, 0x4a, 0x1b, 0x5d, 0xf7, 0xa2,
0x9f, 0x37, 0xfa, 0x4c, 0x4d, 0xbc, 0x6e, 0x1e, 0x0f, 0xc5, 0x63, 0x09, 0x84, 0xbb, 0x84, 0xf6,
0x25, 0x10, 0xc1, 0x65, 0xf4, 0xf3, 0x9b, 0x29, 0xa9, 0xb2, 0xfc, 0xcb, 0x4a, 0x72, 0x1b, 0x2d,
0x8b, 0x1a, 0x07, 0x5f, 0x0c, 0xb5, 0x0c, 0xc6, 0xc3, 0x97, 0x37, 0xd6, 0x53, 0x85, 0xfa, 0xf7,
0x95, 0xe4, 0x4e, 0xa4, 0x50, 0x72, 0x80, 0xdc, 0xc0, 0xba, 0x3f, 0x50, 0x7e, 0x78, 0x73, 0x45,
0x6c, 0xb9, 0x77, 0xf1, 0x49, 0xf7, 0xd3, 0x32, 0x11, 0xdb, 0x13, 0xfc, 0xd3, 0x32, 0xfd, 0x5a,
0xf0, 0x90, 0x87, 0x9c, 0xeb, 0x4d, 0x57, 0xf0, 0x90, 0x47, 0xdc, 0x50, 0x03, 0x7b, 0x8e, 0xd5,
0x5e, 0x2e, 0xe4, 0xe4, 0xd5, 0xbb, 0x8a, 0x94, 0x19, 0xee, 0x44, 0xca, 0xfb, 0x9d, 0x18, 0x0e,
0x1e, 0x8e, 0xb5, 0xd2, 0x13, 0xa6, 0x37, 0x52, 0x8f, 0x31, 0x7d, 0x83, 0x44, 0x0f, 0xc7, 0x3a,
0x28, 0xe2, 0x4d, 0x65, 0x8d, 0x31, 0x6f, 0x20, 0x59, 0x7c, 0x32, 0x04, 0x05, 0x29, 0xba, 0xf1,
0x66, 0xce, 0xdc, 0xd7, 0x63, 0x56, 0x3a, 0xe7, 0xee, 0x1b, 0x03, 0x69, 0xc4, 0xed, 0x84, 0xf2,
0xaf, 0x28, 0xc9, 0x68, 0x1d, 0x75, 0x6b, 0xa8, 0x41, 0x6e, 0x5d, 0x3a, 0xe4, 0x76, 0x9b, 0x15,
0xf3, 0x59, 0xa9, 0x3a, 0x13, 0x75, 0xeb, 0x52, 0xfd, 0x6e, 0x01, 0x0d, 0x8f, 0x05, 0xad, 0x5b,
0x91, 0x5e, 0x3e, 0x89, 0x9b, 0xf1, 0xb2, 0xca, 0xb5, 0x41, 0x2c, 0x5e, 0x4f, 0x35, 0x8c, 0x7a,
0xea, 0x09, 0x46, 0xd2, 0xc6, 0x40, 0x1a, 0x9e, 0xcf, 0x39, 0x6e, 0xcd, 0x78, 0xda, 0xec, 0xb1,
0xd5, 0x19, 0x52, 0x4f, 0x87, 0x2b, 0xc0, 0xd3, 0x50, 0x35, 0xaa, 0x0e, 0xf2, 0x86, 0xef, 0xe6,
0x45, 0x31, 0x5a, 0x8b, 0x0c, 0x13, 0x0d, 0x45, 0x4f, 0x43, 0x03, 0x30, 0x32, 0x92, 0xf5, 0xe9,
0x61, 0x39, 0xea, 0xb3, 0x23, 0xa8, 0x41, 0x23, 0xd9, 0xa5, 0xc1, 0x89, 0x96, 0xd3, 0xd4, 0xa6,
0xb6, 0xe3, 0x78, 0xc3, 0x75, 0x2a, 0xbc, 0x39, 0x98, 0x07, 0x8f, 0xdb, 0x05, 0x25, 0x56, 0x96,
0xfb, 0x98, 0x09, 0x6f, 0x25, 0x79, 0xd0, 0x43, 0x81, 0x53, 0x41, 0x39, 0x8d, 0xde, 0xe6, 0xd9,
0x94, 0xf2, 0xe0, 0x93, 0x22, 0x17, 0x88, 0x3e, 0x29, 0x02, 0x20, 0xe8, 0x3a, 0xf9, 0xbb, 0x39,
0x0e, 0xdd, 0xcf, 0x42, 0x5d, 0xa7, 0x94, 0x1d, 0x2a, 0xd6, 0x75, 0x41, 0x1a, 0x44, 0x03, 0xe3,
0x56, 0xbd, 0x1a, 0xff, 0x24, 0x66, 0x06, 0xbc, 0x1f, 0xbf, 0x36, 0x88, 0x05, 0x2b, 0x8a, 0x75,
0x98, 0xcf, 0x72, 0x1e, 0x5a, 0x51, 0x1c, 0x1b, 0x2d, 0x12, 0x5b, 0x51, 0xba, 0x28, 0x56, 0xbd,
0x36, 0x47, 0xd8, 0xcf, 0xe2, 0xd5, 0x93, 0xcc, 0xb0, 0xea, 0x19, 0xb6, 0xf3, 0x60, 0xb3, 0x34,
0x43, 0x86, 0x5f, 0xaa, 0xcd, 0x72, 0x60, 0x6c, 0x8b, 0x57, 0x26, 0x21, 0x18, 0x8b, 0x3a, 0x98,
0x02, 0x3c, 0xb0, 0x6f, 0x39, 0xfd, 0xec, 0xb5, 0xaa, 0x28, 0xa9, 0x49, 0x99, 0x06, 0x37, 0xa7,
0xc2, 0x60, 0x87, 0x8c, 0x6d, 0x4e, 0x51, 0x0d, 0xf0, 0xd8, 0xdc, 0x7f, 0xd9, 0x31, 0x30, 0x15,
0xcc, 0x5b, 0x85, 0xfe, 0xbb, 0x8e, 0x8f, 0x07, 0x90, 0xf0, 0xb1, 0xb9, 0x06, 0xcc, 0xc1, 0xb7,
0x74, 0xfa, 0x59, 0xc4, 0x94, 0x8f, 0xc6, 0x36, 0xc2, 0xb8, 0x0a, 0x18, 0xd4, 0x26, 0xc1, 0xa5,
0xfc, 0x27, 0x74, 0x19, 0x1a, 0xd4, 0x36, 0x3f, 0x15, 0x48, 0x6c, 0x50, 0x77, 0x51, 0x90, 0x67,
0xba, 0xfb, 0xa0, 0x87, 0x11, 0x7d, 0x77, 0xeb, 0xb3, 0xda, 0xcb, 0x81, 0x99, 0xb3, 0x93, 0x2f,
0xbc, 0xe7, 0x04, 0x81, 0x82, 0xee, 0xe4, 0x8b, 0xf0, 0x63, 0x82, 0xb5, 0x41, 0x2c, 0x7c, 0x24,
0x4f, 0x38, 0x7d, 0xa7, 0x9f, 0x95, 0x07, 0x8a, 0x2b, 0xe4, 0x9d, 0x87, 0xe5, 0x8f, 0xfa, 0x41,
0x7b, 0x01, 0xf6, 0xb8, 0x66, 0x29, 0x6d, 0x1a, 0xf5, 0xbd, 0x3d, 0xff, 0x86, 0x91, 0x92, 0x8d,
0xc1, 0xd7, 0xf6, 0xee, 0xc7, 0x21, 0x65, 0xfb, 0xab, 0xe4, 0xfd, 0x03, 0x36, 0x9d, 0xd0, 0x32,
0x1b, 0xfd, 0xc0, 0xbf, 0x72, 0xca, 0xa6, 0xe3, 0xf6, 0x67, 0x63, 0xef, 0x16, 0x26, 0xb6, 0x97,
0xe6, 0x76, 0xe8, 0xf9, 0x7c, 0x3a, 0xe1, 0x84, 0x83, 0x4b, 0x73, 0xe2, 0xf7, 0x71, 0x2b, 0x40,
0x2e, 0xcd, 0x79, 0x00, 0xb0, 0x77, 0x5a, 0x53, 0x1a, 0xb4, 0xd7, 0x0a, 0xa2, 0xf6, 0x14, 0x60,
0x57, 0x5d, 0x63, 0xaf, 0x4d, 0x6c, 0xe1, 0x25, 0x37, 0xab, 0x23, 0xa4, 0xc8, 0xaa, 0xdb, 0xa5,
0xec, 0x60, 0x90, 0xd5, 0x17, 0x5f, 0xcc, 0x98, 0xcf, 0x66, 0xa4, 0x5e, 0x82, 0xc1, 0xa0, 0x6a,
0xe9, 0x00, 0xc8, 0x60, 0x08, 0x82, 0x76, 0x94, 0xeb, 0x66, 0x4e, 0xaf, 0xf6, 0x58, 0xcd, 0xe6,
0x3c, 0x2f, 0x29, 0xfc, 0x6a, 0x82, 0x69, 0x50, 0x97, 0x41, 0x46, 0x39, 0xc6, 0xda, 0xac, 0x50,
0x10, 0xf2, 0xfe, 0x9d, 0xf8, 0x6a, 0x6d, 0xc3, 0x59, 0x0d, 0x9f, 0xbf, 0x49, 0x2b, 0x10, 0x42,
0xb2, 0x42, 0x14, 0x06, 0x7d, 0x7f, 0x9c, 0x97, 0xd3, 0x60, 0xdf, 0x1f, 0xbb, 0xdf, 0x7c, 0xbc,
0x83, 0x03, 0x36, 0xbe, 0xcb, 0x46, 0x93, 0x5f, 0x26, 0x52, 0xef, 0x3e, 0x06, 0x1b, 0xdd, 0x25,
0x90, 0xf8, 0x1e, 0x26, 0x81, 0xab, 0xd7, 0x15, 0x2d, 0x69, 0xa6, 0x6f, 0x99, 0x85, 0x5c, 0x79,
0x44, 0xd4, 0x15, 0x24, 0x6d, 0x54, 0x15, 0xf2, 0x93, 0x79, 0x79, 0x5c, 0xb3, 0x8b, 0xbc, 0xa0,
0x35, 0x88, 0xaa, 0x52, 0xdd, 0x91, 0x23, 0x51, 0x35, 0xc4, 0xd9, 0xeb, 0x0a, 0x42, 0xea, 0x7d,
0x7a, 0xf9, 0xb4, 0x26, 0x29, 0xbc, 0xae, 0x20, 0x6d, 0x74, 0x31, 0xe4, 0x24, 0x2d, 0x82, 0x3b,
0x89, 0x81, 0x74, 0x5d, 0x2e, 0xc5, 0xf8, 0x50, 0xef, 0xde, 0x89, 0x2f, 0x21, 0x36, 0x20, 0x31,
0x50, 0xe6, 0x42, 0x24, 0x92, 0x18, 0xc4, 0x35, 0x6c, 0xe8, 0x15, 0xdc, 0x91, 0xba, 0x86, 0x03,
0x42, 0xaf, 0xb4, 0xa1, 0x85, 0x48, 0xe8, 0xed, 0x40, 0x20, 0x20, 0xe9, 0x69, 0x30, 0x0d, 0x06,
0x24, 0x23, 0x8d, 0x06, 0x24, 0x97, 0xb2, 0x81, 0x62, 0xbf, 0xcc, 0x79, 0x4e, 0x8a, 0x09, 0xe5,
0xc7, 0xa4, 0x26, 0x33, 0xca, 0x69, 0x0d, 0x03, 0x85, 0x42, 0xc6, 0x1e, 0x83, 0x04, 0x0a, 0x8c,
0x55, 0x0e, 0xff, 0x20, 0xf9, 0xb0, 0x5d, 0x27, 0x69, 0xa9, 0xfe, 0xc8, 0xc2, 0x2b, 0xf1, 0xd7,
0x59, 0x46, 0x1f, 0x19, 0x1b, 0x13, 0x5e, 0x53, 0x32, 0xd3, 0xb6, 0x3f, 0x30, 0xbf, 0x0b, 0xf0,
0xe9, 0x4a, 0x3b, 0x9e, 0x8f, 0x18, 0xcf, 0x2f, 0xda, 0x6d, 0xa9, 0x7a, 0xe3, 0x06, 0x8c, 0x67,
0x57, 0x3c, 0x8e, 0x7c, 0x47, 0x21, 0xc4, 0xd9, 0x38, 0xed, 0x4a, 0x4f, 0x68, 0x55, 0xc0, 0x38,
0xed, 0x69, 0x0b, 0x00, 0x89, 0xd3, 0x41, 0xd0, 0x4e, 0x4e, 0x57, 0x7c, 0x4a, 0xe3, 0x95, 0x39,
0xa5, 0xc3, 0x2a, 0x73, 0xea, 0xbd, 0xc4, 0x50, 0x24, 0x1f, 0x1e, 0xd2, 0xd9, 0x39, 0xad, 0x9b,
0xcb, 0xbc, 0xda, 0x6b, 0x13, 0x14, 0xc2, 0xe7, 0xf0, 0x35, 0x3f, 0x4b, 0x8c, 0x0d, 0x82, 0x64,
0x71, 0x08, 0x6a, 0x57, 0x02, 0x0b, 0xec, 0x37, 0x47, 0x64, 0x46, 0xc5, 0x57, 0x21, 0xc0, 0x4a,
0xe0, 0x18, 0x71, 0x20, 0x64, 0x25, 0x40, 0x61, 0xe7, 0x7d, 0x28, 0xcb, 0x9c, 0xd0, 0x69, 0x3b,
0xc2, 0xea, 0x63, 0xb2, 0x9c, 0xd1, 0x92, 0x2b, 0x93, 0xe0, 0x0c, 0xdb, 0x31, 0x19, 0xe6, 0x91,
0x33, 0xec, 0x21, 0x7a, 0x4e, 0x68, 0xf2, 0x1a, 0xfe, 0x98, 0xd5, 0x5c, 0xfe, 0x09, 0x95, 0xb3,
0xba, 0x00, 0xa1, 0xc9, 0x6f, 0x54, 0x8f, 0x44, 0x42, 0x53, 0x5c, 0xc3, 0xf9, 0xf6, 0xb8, 0x57,
0x86, 0x37, 0xb4, 0x36, 0xe3, 0xe4, 0xd5, 0x8c, 0xe4, 0x85, 0x1a, 0x0d, 0x3f, 0x8a, 0xd8, 0x46,
0x74, 0x90, 0x6f, 0x8f, 0x0f, 0xd5, 0x75, 0xbe, 0xd6, 0x1e, 0x2f, 0x21, 0x38, 0x52, 0xef, 0xb1,
0x8f, 0x1c, 0xa9, 0xf7, 0x6b, 0xd9, 0x9d, 0xae, 0x65, 0x05, 0xb7, 0x14, 0xc4, 0x36, 0xcb, 0xe0,
0xf9, 0x9a, 0x63, 0x13, 0x80, 0xc8, 0x4e, 0x37, 0xaa, 0x60, 0x53, 0x03, 0x8b, 0xed, 0xe6, 0x25,
0x29, 0xf2, 0x9f, 0xc1, 0xcb, 0xd9, 0x8e, 0x1d, 0x4d, 0x20, 0xa9, 0x41, 0x98, 0x0c, 0xb9, 0xda,
0xa3, 0xfc, 0x34, 0x6f, 0x43, 0xff, 0xa3, 0x48, 0xbb, 0x09, 0xa2, 0xdf, 0x95, 0x43, 0x3a, 0xdf,
0x17, 0x85, 0xcd, 0xba, 0x55, 0x55, 0x93, 0x76, 0x55, 0x3d, 0xa1, 0x29, 0xcd, 0x2b, 0x3e, 0x7a,
0x11, 0x6f, 0x2b, 0x80, 0x23, 0x17, 0x13, 0x06, 0xa8, 0x39, 0x8f, 0xbb, 0xdb, 0x58, 0x32, 0x91,
0x7f, 0x5b, 0xec, 0xac, 0xa1, 0xb5, 0x4a, 0x34, 0xf6, 0x28, 0x07, 0xb3, 0xd3, 0xe1, 0xc6, 0x0e,
0xd8, 0x56, 0x14, 0x99, 0x9d, 0x71, 0x0d, 0x7b, 0x38, 0xe6, 0x70, 0x27, 0xb4, 0x61, 0xc5, 0x82,
0x8a, 0xfb, 0x79, 0xeb, 0xa8, 0x31, 0x87, 0x42, 0x0e, 0xc7, 0x70, 0xda, 0x66, 0x6b, 0x5d, 0xb7,
0x5b, 0xe5, 0x72, 0x1f, 0x5e, 0x31, 0x08, 0x58, 0x12, 0x18, 0x92, 0xad, 0x45, 0x70, 0xe7, 0xf0,
0xb8, 0x66, 0x24, 0x4b, 0x49, 0xc3, 0x8f, 0xc9, 0xb2, 0x60, 0x24, 0x13, 0xeb, 0x3a, 0x3c, 0x3c,
0xd6, 0xcc, 0xd8, 0x85, 0xb0, 0xc3, 0x63, 0x0c, 0x76, 0xb3, 0x33, 0xf1, 0x27, 0xd3, 0xd4, 0xdd,
0x47, 0x98, 0x9d, 0x89, 0xf2, 0xc2, 0x7b, 0x8f, 0xf7, 0xe3, 0x90, 0x7d, 0x67, 0x4b, 0x8a, 0x44,
0x1a, 0x72, 0x27, 0xa4, 0xe3, 0x25, 0x20, 0x77, 0x23, 0x84, 0xfd, 0x8e, 0x83, 0xfc, 0x5d, 0xff,
0xd5, 0x0f, 0xae, 0xbe, 0xc2, 0xbc, 0x1e, 0xd2, 0x75, 0xa1, 0xb1, 0xfb, 0x71, 0xb6, 0x8d, 0x81,
0xb4, 0x4d, 0x33, 0xb7, 0x2f, 0x09, 0xdf, 0xca, 0xb2, 0x43, 0xda, 0x04, 0x5e, 0xc0, 0x6e, 0x85,
0x63, 0x2b, 0x45, 0xd2, 0xcc, 0x2e, 0x65, 0x07, 0x7a, 0x2b, 0x7b, 0x95, 0xe5, 0x5c, 0xc9, 0xf4,
0x8d, 0xe2, 0xf5, 0xae, 0x81, 0x2e, 0x85, 0xd4, 0x0a, 0xa7, 0x6d, 0x2c, 0x6f, 0x99, 0x53, 0x36,
0x9d, 0x16, 0x54, 0x41, 0x27, 0x94, 0xc8, 0x8f, 0xd0, 0x6d, 0x76, 0x6d, 0x05, 0x41, 0x24, 0x96,
0x47, 0x15, 0x6c, 0x1a, 0xd9, 0x62, 0xf2, 0x11, 0x8e, 0x6e, 0xd8, 0xd5, 0xae, 0x19, 0x0f, 0x40,
0xd2, 0xc8, 0x20, 0x68, 0xdf, 0x13, 0x6b, 0xc5, 0x7b, 0x54, 0xb7, 0x04, 0xfc, 0x64, 0x8f, 0x50,
0x76, 0xc4, 0xc8, 0x7b, 0x62, 0x01, 0xcc, 0xee, 0x13, 0x80, 0x87, 0x97, 0xcb, 0xfd, 0x0c, 0xee,
0x13, 0xa0, 0xbe, 0x60, 0x90, 0x7d, 0x02, 0xc6, 0xfa, 0x5d, 0x67, 0xbe, 0x4f, 0x7c, 0x40, 0x1a,
0x5b, 0xb9, 0x40, 0xd7, 0x05, 0xc1, 0x58, 0xd7, 0x61, 0x0a, 0x7e, 0x93, 0xba, 0x5f, 0x3f, 0x0e,
0x34, 0x69, 0xe8, 0xab, 0xc7, 0x0f, 0xfb, 0x30, 0x1b, 0x97, 0xcc, 0x7e, 0x52, 0x5c, 0xf1, 0x09,
0x7f, 0x7d, 0x5e, 0x0a, 0x91, 0xb8, 0xd4, 0x81, 0xa4, 0xed, 0x97, 0x77, 0xff, 0xfb, 0x9b, 0x5b,
0x2b, 0xbf, 0xf8, 0xe6, 0xd6, 0xca, 0xff, 0x7e, 0x73, 0x6b, 0xe5, 0xe7, 0xdf, 0xde, 0x7a, 0xef,
0x17, 0xdf, 0xde, 0x7a, 0xef, 0x7f, 0xbe, 0xbd, 0xf5, 0xde, 0xd7, 0xef, 0xab, 0x3f, 0xa5, 0x79,
0xfe, 0x2b, 0xe2, 0x0f, 0x62, 0x3e, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xbb, 0xf9, 0xe5,
0xb2, 0x6e, 0x73, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@ -636,7 +638,9 @@ type ClientCommandsClient interface {
DebugRunProfiler(ctx context.Context, in *pb.RpcDebugRunProfilerRequest, opts ...grpc.CallOption) (*pb.RpcDebugRunProfilerResponse, error)
DebugAccountSelectTrace(ctx context.Context, in *pb.RpcDebugAccountSelectTraceRequest, opts ...grpc.CallOption) (*pb.RpcDebugAccountSelectTraceResponse, error)
DebugAnystoreObjectChanges(ctx context.Context, in *pb.RpcDebugAnystoreObjectChangesRequest, opts ...grpc.CallOption) (*pb.RpcDebugAnystoreObjectChangesResponse, error)
MetricsSetParameters(ctx context.Context, in *pb.RpcMetricsSetParametersRequest, opts ...grpc.CallOption) (*pb.RpcMetricsSetParametersResponse, error)
DebugNetCheck(ctx context.Context, in *pb.RpcDebugNetCheckRequest, opts ...grpc.CallOption) (*pb.RpcDebugNetCheckResponse, error)
DebugExportLog(ctx context.Context, in *pb.RpcDebugExportLogRequest, opts ...grpc.CallOption) (*pb.RpcDebugExportLogResponse, error)
InitialSetParameters(ctx context.Context, in *pb.RpcInitialSetParametersRequest, opts ...grpc.CallOption) (*pb.RpcInitialSetParametersResponse, error)
// used only for lib-server via grpc
ListenSessionEvents(ctx context.Context, in *pb.StreamRequest, opts ...grpc.CallOption) (ClientCommands_ListenSessionEventsClient, error)
NotificationList(ctx context.Context, in *pb.RpcNotificationListRequest, opts ...grpc.CallOption) (*pb.RpcNotificationListResponse, error)
@ -2786,9 +2790,27 @@ func (c *clientCommandsClient) DebugAnystoreObjectChanges(ctx context.Context, i
return out, nil
}
func (c *clientCommandsClient) MetricsSetParameters(ctx context.Context, in *pb.RpcMetricsSetParametersRequest, opts ...grpc.CallOption) (*pb.RpcMetricsSetParametersResponse, error) {
out := new(pb.RpcMetricsSetParametersResponse)
err := c.cc.Invoke(ctx, "/anytype.ClientCommands/MetricsSetParameters", in, out, opts...)
func (c *clientCommandsClient) DebugNetCheck(ctx context.Context, in *pb.RpcDebugNetCheckRequest, opts ...grpc.CallOption) (*pb.RpcDebugNetCheckResponse, error) {
out := new(pb.RpcDebugNetCheckResponse)
err := c.cc.Invoke(ctx, "/anytype.ClientCommands/DebugNetCheck", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *clientCommandsClient) DebugExportLog(ctx context.Context, in *pb.RpcDebugExportLogRequest, opts ...grpc.CallOption) (*pb.RpcDebugExportLogResponse, error) {
out := new(pb.RpcDebugExportLogResponse)
err := c.cc.Invoke(ctx, "/anytype.ClientCommands/DebugExportLog", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *clientCommandsClient) InitialSetParameters(ctx context.Context, in *pb.RpcInitialSetParametersRequest, opts ...grpc.CallOption) (*pb.RpcInitialSetParametersResponse, error) {
out := new(pb.RpcInitialSetParametersResponse)
err := c.cc.Invoke(ctx, "/anytype.ClientCommands/InitialSetParameters", in, out, opts...)
if err != nil {
return nil, err
}
@ -3362,7 +3384,9 @@ type ClientCommandsServer interface {
DebugRunProfiler(context.Context, *pb.RpcDebugRunProfilerRequest) *pb.RpcDebugRunProfilerResponse
DebugAccountSelectTrace(context.Context, *pb.RpcDebugAccountSelectTraceRequest) *pb.RpcDebugAccountSelectTraceResponse
DebugAnystoreObjectChanges(context.Context, *pb.RpcDebugAnystoreObjectChangesRequest) *pb.RpcDebugAnystoreObjectChangesResponse
MetricsSetParameters(context.Context, *pb.RpcMetricsSetParametersRequest) *pb.RpcMetricsSetParametersResponse
DebugNetCheck(context.Context, *pb.RpcDebugNetCheckRequest) *pb.RpcDebugNetCheckResponse
DebugExportLog(context.Context, *pb.RpcDebugExportLogRequest) *pb.RpcDebugExportLogResponse
InitialSetParameters(context.Context, *pb.RpcInitialSetParametersRequest) *pb.RpcInitialSetParametersResponse
// used only for lib-server via grpc
ListenSessionEvents(*pb.StreamRequest, ClientCommands_ListenSessionEventsServer)
NotificationList(context.Context, *pb.RpcNotificationListRequest) *pb.RpcNotificationListResponse
@ -4116,7 +4140,13 @@ func (*UnimplementedClientCommandsServer) DebugAccountSelectTrace(ctx context.Co
func (*UnimplementedClientCommandsServer) DebugAnystoreObjectChanges(ctx context.Context, req *pb.RpcDebugAnystoreObjectChangesRequest) *pb.RpcDebugAnystoreObjectChangesResponse {
return nil
}
func (*UnimplementedClientCommandsServer) MetricsSetParameters(ctx context.Context, req *pb.RpcMetricsSetParametersRequest) *pb.RpcMetricsSetParametersResponse {
func (*UnimplementedClientCommandsServer) DebugNetCheck(ctx context.Context, req *pb.RpcDebugNetCheckRequest) *pb.RpcDebugNetCheckResponse {
return nil
}
func (*UnimplementedClientCommandsServer) DebugExportLog(ctx context.Context, req *pb.RpcDebugExportLogRequest) *pb.RpcDebugExportLogResponse {
return nil
}
func (*UnimplementedClientCommandsServer) InitialSetParameters(ctx context.Context, req *pb.RpcInitialSetParametersRequest) *pb.RpcInitialSetParametersResponse {
return nil
}
func (*UnimplementedClientCommandsServer) ListenSessionEvents(req *pb.StreamRequest, srv ClientCommands_ListenSessionEventsServer) {
@ -8390,20 +8420,56 @@ func _ClientCommands_DebugAnystoreObjectChanges_Handler(srv interface{}, ctx con
return interceptor(ctx, in, info, handler)
}
func _ClientCommands_MetricsSetParameters_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(pb.RpcMetricsSetParametersRequest)
func _ClientCommands_DebugNetCheck_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(pb.RpcDebugNetCheckRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ClientCommandsServer).MetricsSetParameters(ctx, in), nil
return srv.(ClientCommandsServer).DebugNetCheck(ctx, in), nil
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/anytype.ClientCommands/MetricsSetParameters",
FullMethod: "/anytype.ClientCommands/DebugNetCheck",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ClientCommandsServer).MetricsSetParameters(ctx, req.(*pb.RpcMetricsSetParametersRequest)), nil
return srv.(ClientCommandsServer).DebugNetCheck(ctx, req.(*pb.RpcDebugNetCheckRequest)), nil
}
return interceptor(ctx, in, info, handler)
}
func _ClientCommands_DebugExportLog_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(pb.RpcDebugExportLogRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ClientCommandsServer).DebugExportLog(ctx, in), nil
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/anytype.ClientCommands/DebugExportLog",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ClientCommandsServer).DebugExportLog(ctx, req.(*pb.RpcDebugExportLogRequest)), nil
}
return interceptor(ctx, in, info, handler)
}
func _ClientCommands_InitialSetParameters_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(pb.RpcInitialSetParametersRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ClientCommandsServer).InitialSetParameters(ctx, in), nil
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/anytype.ClientCommands/InitialSetParameters",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ClientCommandsServer).InitialSetParameters(ctx, req.(*pb.RpcInitialSetParametersRequest)), nil
}
return interceptor(ctx, in, info, handler)
}
@ -9885,8 +9951,16 @@ var _ClientCommands_serviceDesc = grpc.ServiceDesc{
Handler: _ClientCommands_DebugAnystoreObjectChanges_Handler,
},
{
MethodName: "MetricsSetParameters",
Handler: _ClientCommands_MetricsSetParameters_Handler,
MethodName: "DebugNetCheck",
Handler: _ClientCommands_DebugNetCheck_Handler,
},
{
MethodName: "DebugExportLog",
Handler: _ClientCommands_DebugExportLog_Handler,
},
{
MethodName: "InitialSetParameters",
Handler: _ClientCommands_InitialSetParameters_Handler,
},
{
MethodName: "NotificationList",

View file

@ -6,7 +6,7 @@ package bundle
import domain "github.com/anyproto/anytype-heart/core/domain"
const SystemTypesChecksum = "e68b37f73baf858d7101257403a3a0605e09090dbe11432919e1e7a6d4668b67"
const SystemTypesChecksum = "bf5fb329802ba479e21c98306b1bda3226c17c6cae83b280ede6954d9c012185"
// SystemTypes contains types that have some special biz logic depends on them in some objects
// they shouldn't be removed or edited in any way
@ -17,6 +17,5 @@ var SystemTypes = append(InternalTypes, []domain.TypeKey{
TypeKeyCollection,
TypeKeySet,
TypeKeyBookmark,
TypeKeyChat,
TypeKeyChatDerived,
}...)

View file

@ -18,6 +18,5 @@
"collection",
"set",
"bookmark",
"chat",
"chatDerived"
]

View file

@ -9,7 +9,7 @@ import (
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
)
const TypeChecksum = "f3ae9931142aa23ec9696ccb60fe1a68b4fdafcc345e307e0a26d4fb98a0686c"
const TypeChecksum = "5458717a4167a70b8a8e3148147e192263a645484359ec155b6856a8996e8ec8"
const (
TypePrefix = "_ot"
)
@ -84,10 +84,11 @@ var (
},
TypeKeyChat: {
Description: "A chat",
Description: "A chat [deprecated]",
Hidden: true,
IconEmoji: "💬",
Layout: model.ObjectType_chat,
Name: "Chat",
Name: "Chat [deprecated]",
Readonly: true,
RelationLinks: []*model.RelationLink{MustGetRelationLink(RelationKeyTag), MustGetRelationLink(RelationKeyDescription)},
Types: []model.SmartBlockType{model.SmartBlockType_ChatObject},
@ -143,7 +144,7 @@ var (
Description: "Gregorian calendar date",
Hidden: true,
IconEmoji: "📅",
Layout: model.ObjectType_basic,
Layout: model.ObjectType_date,
Name: "Date",
Readonly: true,
RelationLinks: []*model.RelationLink{MustGetRelationLink(RelationKeyTag)},

View file

@ -70,7 +70,7 @@
],
"emoji": "📅",
"hidden": true,
"layout": "basic",
"layout": "date",
"relations": [
"tag"
],
@ -459,18 +459,18 @@
},
{
"id": "chat",
"name": "Chat",
"name": "Chat [deprecated]",
"types": [
"ChatObject"
],
"emoji": "💬",
"hidden": false,
"hidden": true,
"layout": "chat",
"relations": [
"tag",
"description"
],
"description": "A chat"
"description": "A chat [deprecated]"
},
{
"id": "chatDerived",

View file

@ -27,7 +27,7 @@ const (
SmartBlockTypeAnytypeProfile = SmartBlockType(model.SmartBlockType_AnytypeProfile)
SmartBlockTypeDate = SmartBlockType(model.SmartBlockType_Date)
SmartBlockTypeIdentity = SmartBlockType(model.SmartBlockType_Identity)
SmartBlockTypeChatObject = SmartBlockType(model.SmartBlockType_ChatObject) // Container for any-store based chats
SmartBlockTypeChatObject = SmartBlockType(model.SmartBlockType_ChatObject) // deprecated. Container for any-store based chats
SmartBlockTypeChatDerivedObject = SmartBlockType(model.SmartBlockType_ChatDerivedObject) // Any-store based object for chat
SmartBlockTypeAccountObject = SmartBlockType(model.SmartBlockType_AccountObject)
@ -72,10 +72,9 @@ func (sbt SmartBlockType) IsOneOf(sbts ...SmartBlockType) bool {
// Indexable determines if the object of specific type need to be proceeded by the indexer in order to appear in sets
func (sbt SmartBlockType) Indexable() (details, outgoingLinks bool) {
switch sbt {
case SmartBlockTypeDate, SmartBlockTypeAccountOld, SmartBlockTypeArchive,
SmartBlockTypeHome, SmartBlockTypeNotificationObject, SmartBlockTypeDevicesObject:
case SmartBlockTypeDate, SmartBlockTypeAccountOld, SmartBlockTypeNotificationObject, SmartBlockTypeDevicesObject:
return false, false
case SmartBlockTypeWidget:
case SmartBlockTypeWidget, SmartBlockTypeArchive, SmartBlockTypeHome:
return true, false
default:
return true, true

View file

@ -0,0 +1,4 @@
package environment
var ROOT_PATH = ""
var LOG_PATH = ""

View file

@ -2,6 +2,7 @@ package ftsearch
import (
"fmt"
"sync"
tantivy "github.com/anyproto/tantivy-go"
"github.com/blevesearch/bleve/v2/search"
@ -12,6 +13,7 @@ const docLimit = 10000
func (f *ftSearchTantivy) NewAutoBatcher(maxDocs int, maxSizeBytes uint64) AutoBatcher {
return &ftIndexBatcherTantivy{
index: f.index,
mu: &f.mu,
}
}
@ -37,10 +39,12 @@ func (f *ftSearchTantivy) Iterate(objectId string, fields []string, shouldContin
dm.Fields = make(map[string]any)
dm.Fields[fieldSpace] = string(value.GetStringBytes(fieldSpace))
dm.Fields[fieldText] = string(value.GetStringBytes(fieldText))
dm.Fields[fieldTextZh] = string(value.GetStringBytes(fieldTextZh))
dm.Fields[fieldTitle] = string(value.GetStringBytes(fieldTitle))
dm.Fields[fieldTitleZh] = string(value.GetStringBytes(fieldTitleZh))
return dm, nil
},
fieldId, fieldSpace, fieldTitle, fieldText,
fieldId, fieldSpace, fieldTitle, fieldTitleZh, fieldText, fieldTextZh,
)
if err != nil {
return err
@ -49,9 +53,15 @@ func (f *ftSearchTantivy) Iterate(objectId string, fields []string, shouldContin
var text, title, spaceId string
for _, hit := range searchResult {
if hit.Fields != nil {
if hit.Fields[fieldTextZh] != nil {
text, _ = hit.Fields[fieldTextZh].(string)
}
if hit.Fields[fieldText] != nil {
text, _ = hit.Fields[fieldText].(string)
}
if hit.Fields[fieldTitleZh] != nil {
title, _ = hit.Fields[fieldTitleZh].(string)
}
if hit.Fields[fieldTitle] != nil {
title, _ = hit.Fields[fieldTitle].(string)
}
@ -76,6 +86,7 @@ type ftIndexBatcherTantivy struct {
index *tantivy.TantivyContext
deleteIds []string
updateDocs []*tantivy.Document
mu *sync.Mutex // original mutex, temporary solution
}
// Add adds a update operation to the batcher. If the batch is reaching the size limit, it will be indexed and reset.
@ -109,11 +120,21 @@ func (f *ftIndexBatcherTantivy) UpdateDoc(searchDoc SearchDoc) error {
return err
}
err = doc.AddField(fieldTitleZh, searchDoc.Title, f.index)
if err != nil {
return err
}
err = doc.AddField(fieldText, searchDoc.Text, f.index)
if err != nil {
return err
}
err = doc.AddField(fieldTextZh, searchDoc.Text, f.index)
if err != nil {
return err
}
f.updateDocs = append(f.updateDocs, doc)
if len(f.updateDocs) >= docLimit {
@ -124,6 +145,8 @@ func (f *ftIndexBatcherTantivy) UpdateDoc(searchDoc SearchDoc) error {
// Finish indexes the remaining documents in the batch.
func (f *ftIndexBatcherTantivy) Finish() error {
f.mu.Lock()
defer f.mu.Unlock()
err := f.index.DeleteDocuments(fieldIdRaw, f.deleteIds...)
if err != nil {
return err

View file

@ -28,10 +28,12 @@ import (
const (
CName = "fts"
ftsDir = "fts"
ftsVer = "6"
ftsVer = "7"
fieldTitle = "Title"
fieldTitleZh = "TitleZh"
fieldText = "Text"
fieldTextZh = "TextZh"
fieldSpace = "SpaceID"
fieldTitleNoTerms = "TitleNoTerms"
fieldTextNoTerms = "TextNoTerms"

View file

@ -19,6 +19,7 @@ import (
"os"
"path/filepath"
"strings"
"sync"
"time"
"github.com/anyproto/any-sync/app"
@ -49,12 +50,15 @@ type ftSearchTantivy struct {
index *tantivy.TantivyContext
schema *tantivy.Schema
parserPool *fastjson.ParserPool
mu sync.Mutex
}
func (f *ftSearchTantivy) BatchDeleteObjects(ids []string) error {
if len(ids) == 0 {
return nil
}
f.mu.Lock()
defer f.mu.Unlock()
start := time.Now()
defer func() {
spentMs := time.Since(start).Milliseconds()
@ -74,6 +78,8 @@ func (f *ftSearchTantivy) BatchDeleteObjects(ids []string) error {
}
func (f *ftSearchTantivy) DeleteObject(objectId string) error {
f.mu.Lock()
defer f.mu.Unlock()
return f.index.DeleteDocuments(fieldIdRaw, objectId)
}
@ -146,6 +152,15 @@ func (f *ftSearchTantivy) Run(context.Context) error {
tantivy.TokenizerNgram,
)
err = builder.AddTextField(
fieldTitleZh,
true,
true,
false,
tantivy.IndexRecordOptionWithFreqsAndPositions,
tantivy.TokenizerJieba,
)
err = builder.AddTextField(
fieldText,
true,
@ -155,6 +170,15 @@ func (f *ftSearchTantivy) Run(context.Context) error {
tantivy.TokenizerSimple,
)
err = builder.AddTextField(
fieldTextZh,
true,
true,
false,
tantivy.IndexRecordOptionWithFreqsAndPositions,
tantivy.TokenizerJieba,
)
schema, err := builder.BuildSchema()
if err != nil {
return err
@ -175,6 +199,11 @@ func (f *ftSearchTantivy) Run(context.Context) error {
return err
}
err = index.RegisterTextAnalyzerJieba(tantivy.TokenizerJieba, 40)
if err != nil {
return err
}
err = index.RegisterTextAnalyzerSimple(tokenizerId, 1000, tantivy.English)
if err != nil {
return err
@ -206,6 +235,8 @@ func (f *ftSearchTantivy) tryToBuildSchema(schema *tantivy.Schema) (*tantivy.Tan
}
func (f *ftSearchTantivy) Index(doc SearchDoc) error {
f.mu.Lock()
defer f.mu.Unlock()
metrics.ObjectFTUpdatedCounter.Inc()
tantivyDoc, err := f.convertDoc(doc)
if err != nil {
@ -234,10 +265,18 @@ func (f *ftSearchTantivy) convertDoc(doc SearchDoc) (*tantivy.Document, error) {
if err != nil {
return nil, err
}
err = document.AddField(fieldTitleZh, doc.Title, f.index)
if err != nil {
return nil, err
}
err = document.AddField(fieldText, doc.Text, f.index)
if err != nil {
return nil, err
}
err = document.AddField(fieldTextZh, doc.Text, f.index)
if err != nil {
return nil, err
}
return document, nil
}
@ -256,7 +295,9 @@ func (f *ftSearchTantivy) BatchIndex(ctx context.Context, docs []SearchDoc, dele
l.Debugf("ft index done")
}
}()
f.mu.Lock()
err = f.index.DeleteDocuments(fieldIdRaw, deletedDocs...)
f.mu.Unlock()
if err != nil {
return err
}
@ -268,6 +309,8 @@ func (f *ftSearchTantivy) BatchIndex(ctx context.Context, docs []SearchDoc, dele
}
tantivyDocs = append(tantivyDocs, tantivyDoc)
}
f.mu.Lock()
defer f.mu.Unlock()
return f.index.AddAndConsumeDocuments(tantivyDocs...)
}
@ -280,7 +323,9 @@ func (f *ftSearchTantivy) Search(spaceIds []string, highlightFormatter Highlight
if spaceIdsQuery != "" {
query = fmt.Sprintf("%s AND %s", spaceIdsQuery, query)
}
result, err := f.index.Search(query, 100, true, fieldId, fieldSpace, fieldTitle, fieldText)
result, err := f.index.Search(query, 100, true,
fieldId, fieldSpace, fieldTitle, fieldTitleZh, fieldText, fieldTextZh,
)
if err != nil {
return nil, wrapError(err)
}
@ -301,9 +346,9 @@ func (f *ftSearchTantivy) Search(spaceIds []string, highlightFormatter Highlight
for _, val := range highlights {
object := val.GetObject()
fieldName := string(object.Get("field_name").GetStringBytes())
if fieldName == fieldTitle {
if fieldName == fieldTitle || fieldName == fieldTitleZh {
// fragments[fieldTitle] = append(fragments[fieldTitle], string(object.Get("fragment").MarshalTo(nil)))
} else if fieldName == fieldText {
} else if fieldName == fieldText || fieldName == fieldTextZh {
fragments[fieldText] = append(fragments[fieldText], string(object.Get("fragment").MarshalTo(nil)))
}
}

View file

@ -117,6 +117,9 @@ func TestNewFTSearch(t *testing.T) {
{
name: "assertFoundCaseSensitivePartsOfTheWords",
tester: assertFoundCaseSensitivePartsOfTheWords,
}, {
name: "assertChineseFound",
tester: assertChineseFound,
},
{
name: "assertMultiSpace",
@ -176,27 +179,21 @@ func assertChineseFound(t *testing.T, tmpDir string) {
require.NoError(t, ft.Index(SearchDoc{
Id: "1",
Title: "",
Text: "你好",
Text: "张华考上了北京大学;李萍进了中等技术学校;我在百货公司当售货员:我们都有光明的前途",
}))
require.NoError(t, ft.Index(SearchDoc{
Id: "2",
Title: "",
Text: "交代",
}))
require.NoError(t, ft.Index(SearchDoc{
Id: "3",
Title: "",
Text: "长江大桥",
Title: "张华考上了北京大学;李萍进了中等技术学校;我在百货公司当售货员:我们都有光明的前途",
Text: "",
}))
queries := []string{
"你好世界",
"亲口交代",
"长江",
"售货员",
}
for _, qry := range queries {
validateSearch(t, ft, "", qry, 1)
validateSearch(t, ft, "", qry, 2)
}
_ = ft.Close(nil)
@ -388,7 +385,7 @@ func assertMultiSpace(t *testing.T, tmpDir string) {
validateSearch(t, ft, "", "Advanced", 1)
validateSearch(t, ft, "", "dash", 2)
validateSearch(t, ft, "", "space", 4)
validateSearch(t, ft, "", "of", 0)
validateSearch(t, ft, "", "of", 4)
_ = ft.Close(nil)
}

View file

@ -30,7 +30,7 @@ func (fx *StoreFixture) TechSpaceId() string {
type detailsFromId struct {
}
func (d *detailsFromId) DetailsFromIdBasedSource(id string) (*domain.Details, error) {
func (d *detailsFromId) DetailsFromIdBasedSource(id domain.FullID) (*domain.Details, error) {
return nil, fmt.Errorf("not found")
}

View file

@ -47,6 +47,7 @@ type CrossSpace interface {
type ObjectStore interface {
app.ComponentRunnable
IterateSpaceIndex(func(store spaceindex.Store) error) error
SpaceIndex(spaceId string) spaceindex.Store
GetCrdtDb(spaceId string) anystore.DB
@ -116,6 +117,21 @@ type dsObjectStore struct {
componentCtxCancel context.CancelFunc
}
func (s *dsObjectStore) IterateSpaceIndex(f func(store spaceindex.Store) error) error {
s.Lock()
spaceIndexes := make([]spaceindex.Store, 0, len(s.spaceIndexes))
for _, store := range s.spaceIndexes {
spaceIndexes = append(spaceIndexes, store)
}
s.Unlock()
for _, store := range s.spaceIndexes {
if err := f(store); err != nil {
return err
}
}
return nil
}
func New() ObjectStore {
ctx, cancel := context.WithCancel(context.Background())
return &dsObjectStore{

View file

@ -32,7 +32,7 @@ const spaceName = "space1"
type detailsFromId struct {
}
func (d *detailsFromId) DetailsFromIdBasedSource(id string) (*domain.Details, error) {
func (d *detailsFromId) DetailsFromIdBasedSource(id domain.FullID) (*domain.Details, error) {
return nil, fmt.Errorf("not found")
}

View file

@ -78,7 +78,10 @@ func (s *dsObjectStore) GetInfosByIds(ids []string) ([]*database.ObjectInfo, err
}
func (s *dsObjectStore) getObjectInfo(ctx context.Context, id string) (*database.ObjectInfo, error) {
details, err := s.sourceService.DetailsFromIdBasedSource(id)
details, err := s.sourceService.DetailsFromIdBasedSource(domain.FullID{
ObjectID: id,
SpaceID: s.SpaceId(),
})
if err == nil {
details.SetString(bundle.RelationKeyId, id)
return &database.ObjectInfo{

View file

@ -178,7 +178,10 @@ func (s *dsObjectStore) QueryFromFulltext(results []database.FulltextResult, par
// Don't use spaceID because expected objects are virtual
if sbt, err := typeprovider.SmartblockTypeFromID(res.Path.ObjectId); err == nil {
if indexDetails, _ := sbt.Indexable(); !indexDetails && s.sourceService != nil {
details, err := s.sourceService.DetailsFromIdBasedSource(res.Path.ObjectId)
details, err := s.sourceService.DetailsFromIdBasedSource(domain.FullID{
ObjectID: res.Path.ObjectId,
SpaceID: s.SpaceId(),
})
if err != nil {
log.Errorf("QueryByIds failed to GetDetailsFromIdBasedSource id: %s", res.Path.ObjectId)
continue
@ -443,7 +446,10 @@ func (s *dsObjectStore) QueryByIds(ids []string) (records []database.Record, err
// Don't use spaceID because expected objects are virtual
if sbt, err := typeprovider.SmartblockTypeFromID(id); err == nil {
if indexDetails, _ := sbt.Indexable(); !indexDetails && s.sourceService != nil {
details, err := s.sourceService.DetailsFromIdBasedSource(id)
details, err := s.sourceService.DetailsFromIdBasedSource(domain.FullID{
ObjectID: id,
SpaceID: s.SpaceId(),
})
if err != nil {
log.Errorf("QueryByIds failed to GetDetailsFromIdBasedSource id: %s", id)
continue

View file

@ -1036,7 +1036,7 @@ type dummySourceService struct {
objectToReturn TestObject
}
func (s dummySourceService) DetailsFromIdBasedSource(id string) (*domain.Details, error) {
func (s dummySourceService) DetailsFromIdBasedSource(id domain.FullID) (*domain.Details, error) {
return makeDetails(s.objectToReturn), nil
}

View file

@ -90,7 +90,7 @@ type Store interface {
}
type SourceDetailsFromID interface {
DetailsFromIdBasedSource(id string) (*domain.Details, error)
DetailsFromIdBasedSource(id domain.FullID) (*domain.Details, error)
}
type FulltextQueue interface {
@ -100,8 +100,6 @@ type FulltextQueue interface {
}
type dsObjectStore struct {
initErr error
spaceId string
db anystore.DB
objects anystore.Collection
@ -157,8 +155,7 @@ func New(componentCtx context.Context, spaceId string, deps Deps) Store {
var err error
err = s.openDatabase(componentCtx, deps.DbPath)
if err != nil {
s.initErr = err
return s
return NewInvalidStore(err)
}
return s

View file

@ -0,0 +1,18 @@
package spaceindex
import (
"context"
"testing"
"github.com/stretchr/testify/require"
)
func TestNewWithError(t *testing.T) {
spaceIndex := New(context.Background(), "space1", Deps{
// Crazy path to force an error
DbPath: "....\\\\\\....///////****",
})
_, err := spaceIndex.ListIds()
require.Error(t, err)
}

View file

@ -2,16 +2,21 @@ package logging
import (
"fmt"
"net/url"
"os"
"path/filepath"
"strings"
"github.com/anyproto/any-sync/app/logger"
"go.uber.org/zap"
"gopkg.in/natefinch/lumberjack.v2"
"github.com/anyproto/anytype-heart/pkg/lib/environment"
"github.com/anyproto/anytype-heart/util/vcs"
)
const DefaultLogLevels = "common.commonspace.headsync=INFO;core.block.editor.spaceview=INFO;*=WARN"
const lumberjackScheme = "lumberjack"
var DefaultCfg = logger.Config{
Production: false,
@ -69,18 +74,70 @@ func SetLogLevels(levels string) {
cfg.ApplyGlobal()
}
func init() {
if os.Getenv("ANYTYPE_LOG_NOGELF") == "1" {
DefaultCfg.Format = logger.ColorizedOutput
type lumberjackSink struct {
*lumberjack.Logger
}
func (s *lumberjackSink) Sync() error {
return nil
}
func newLumberjackSink(u *url.URL) (zap.Sink, error) {
return &lumberjackSink{
Logger: &lumberjack.Logger{
Filename: u.Path,
MaxSize: 1,
MaxAge: 28,
},
}, nil
}
func Init(root string, logLevels string, sendLogs bool, saveLogs bool) {
if root != "" {
environment.ROOT_PATH = filepath.Join(root, "common")
err := os.Mkdir(environment.ROOT_PATH, 0755)
if err != nil {
fmt.Println("failed to create global dir", err)
}
}
if os.Getenv("ANYTYPE_LOG_NOGELF") == "1" || !sendLogs {
if !saveLogs {
DefaultCfg.Format = logger.ColorizedOutput
}
} else {
registerGelfSink(&DefaultCfg)
info := vcs.GetVCSInfo()
SetVersion(info.Version())
}
logLevels := os.Getenv("ANYTYPE_LOG_LEVEL")
if saveLogs {
registerLumberjackSink(environment.ROOT_PATH, &DefaultCfg)
}
envLogLevels := os.Getenv("ANYTYPE_LOG_LEVEL")
if logLevels == "" {
logLevels = envLogLevels
}
if logLevels == "" {
logLevels = DefaultLogLevels
}
SetLogLevels(logLevels)
}
func registerLumberjackSink(globalRoot string, config *logger.Config) {
if globalRoot == "" {
fmt.Println("globalRoot dir is not set")
return
}
err := zap.RegisterSink(lumberjackScheme, newLumberjackSink)
if err != nil {
fmt.Println("failed to register lumberjack sink", err)
}
logsDir := filepath.Join(globalRoot, "logs")
err = os.Mkdir(logsDir, 0755)
if err != nil {
fmt.Println("failed to create globalRoot dir", err)
}
environment.LOG_PATH = filepath.Join(logsDir, "anytype.log")
config.AddOutputPaths = append(config.AddOutputPaths, lumberjackScheme+":"+environment.LOG_PATH)
}

File diff suppressed because it is too large Load diff

View file

@ -639,6 +639,7 @@ message Account {
string archiveObjectId = 3; // archive block id
string profileObjectId = 4; // profile block id
string marketplaceWorkspaceId = 11; // marketplace workspace id
string workspaceObjectId = 15; // workspace object id. used for space-level chat
string deviceId = 8;
string accountSpaceId = 9;
@ -762,7 +763,7 @@ message ObjectType {
participant = 19;
pdf = 20;
chat = 21;
chat = 21; // deprecated
chatDerived = 22;
tag = 23;
}

View file

@ -273,7 +273,7 @@ func (_c *MockSpace_CreateTreeObject_Call) RunAndReturn(run func(context.Context
}
// CreateTreeObjectWithPayload provides a mock function with given fields: ctx, payload, initFunc
func (_m *MockSpace) CreateTreeObjectWithPayload(ctx context.Context, payload treestorage.TreeStorageCreatePayload, initFunc func(string) *smartblock.InitContext) (smartblock.SmartBlock, error) {
func (_m *MockSpace) CreateTreeObjectWithPayload(ctx context.Context, payload treestorage.TreeStorageCreatePayload, initFunc objectcache.InitFunc) (smartblock.SmartBlock, error) {
ret := _m.Called(ctx, payload, initFunc)
if len(ret) == 0 {
@ -282,10 +282,10 @@ func (_m *MockSpace) CreateTreeObjectWithPayload(ctx context.Context, payload tr
var r0 smartblock.SmartBlock
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, treestorage.TreeStorageCreatePayload, func(string) *smartblock.InitContext) (smartblock.SmartBlock, error)); ok {
if rf, ok := ret.Get(0).(func(context.Context, treestorage.TreeStorageCreatePayload, objectcache.InitFunc) (smartblock.SmartBlock, error)); ok {
return rf(ctx, payload, initFunc)
}
if rf, ok := ret.Get(0).(func(context.Context, treestorage.TreeStorageCreatePayload, func(string) *smartblock.InitContext) smartblock.SmartBlock); ok {
if rf, ok := ret.Get(0).(func(context.Context, treestorage.TreeStorageCreatePayload, objectcache.InitFunc) smartblock.SmartBlock); ok {
r0 = rf(ctx, payload, initFunc)
} else {
if ret.Get(0) != nil {
@ -293,7 +293,7 @@ func (_m *MockSpace) CreateTreeObjectWithPayload(ctx context.Context, payload tr
}
}
if rf, ok := ret.Get(1).(func(context.Context, treestorage.TreeStorageCreatePayload, func(string) *smartblock.InitContext) error); ok {
if rf, ok := ret.Get(1).(func(context.Context, treestorage.TreeStorageCreatePayload, objectcache.InitFunc) error); ok {
r1 = rf(ctx, payload, initFunc)
} else {
r1 = ret.Error(1)
@ -310,14 +310,14 @@ type MockSpace_CreateTreeObjectWithPayload_Call struct {
// CreateTreeObjectWithPayload is a helper method to define mock.On call
// - ctx context.Context
// - payload treestorage.TreeStorageCreatePayload
// - initFunc func(string) *smartblock.InitContext
// - initFunc objectcache.InitFunc
func (_e *MockSpace_Expecter) CreateTreeObjectWithPayload(ctx interface{}, payload interface{}, initFunc interface{}) *MockSpace_CreateTreeObjectWithPayload_Call {
return &MockSpace_CreateTreeObjectWithPayload_Call{Call: _e.mock.On("CreateTreeObjectWithPayload", ctx, payload, initFunc)}
}
func (_c *MockSpace_CreateTreeObjectWithPayload_Call) Run(run func(ctx context.Context, payload treestorage.TreeStorageCreatePayload, initFunc func(string) *smartblock.InitContext)) *MockSpace_CreateTreeObjectWithPayload_Call {
func (_c *MockSpace_CreateTreeObjectWithPayload_Call) Run(run func(ctx context.Context, payload treestorage.TreeStorageCreatePayload, initFunc objectcache.InitFunc)) *MockSpace_CreateTreeObjectWithPayload_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(treestorage.TreeStorageCreatePayload), args[2].(func(string) *smartblock.InitContext))
run(args[0].(context.Context), args[1].(treestorage.TreeStorageCreatePayload), args[2].(objectcache.InitFunc))
})
return _c
}
@ -327,7 +327,7 @@ func (_c *MockSpace_CreateTreeObjectWithPayload_Call) Return(sb smartblock.Smart
return _c
}
func (_c *MockSpace_CreateTreeObjectWithPayload_Call) RunAndReturn(run func(context.Context, treestorage.TreeStorageCreatePayload, func(string) *smartblock.InitContext) (smartblock.SmartBlock, error)) *MockSpace_CreateTreeObjectWithPayload_Call {
func (_c *MockSpace_CreateTreeObjectWithPayload_Call) RunAndReturn(run func(context.Context, treestorage.TreeStorageCreatePayload, objectcache.InitFunc) (smartblock.SmartBlock, error)) *MockSpace_CreateTreeObjectWithPayload_Call {
_c.Call.Return(run)
return _c
}

View file

@ -71,19 +71,19 @@ func (_c *MockSpaceController_Close_Call) RunAndReturn(run func(context.Context)
}
// Current provides a mock function with given fields:
func (_m *MockSpaceController) Current() interface{} {
func (_m *MockSpaceController) Current() any {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for Current")
}
var r0 interface{}
if rf, ok := ret.Get(0).(func() interface{}); ok {
var r0 any
if rf, ok := ret.Get(0).(func() any); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(interface{})
r0 = ret.Get(0).(any)
}
}
@ -107,12 +107,12 @@ func (_c *MockSpaceController_Current_Call) Run(run func()) *MockSpaceController
return _c
}
func (_c *MockSpaceController_Current_Call) Return(_a0 interface{}) *MockSpaceController_Current_Call {
func (_c *MockSpaceController_Current_Call) Return(_a0 any) *MockSpaceController_Current_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockSpaceController_Current_Call) RunAndReturn(run func() interface{}) *MockSpaceController_Current_Call {
func (_c *MockSpaceController_Current_Call) RunAndReturn(run func() any) *MockSpaceController_Current_Call {
_c.Call.Return(run)
return _c
}

View file

@ -1,11 +1,11 @@
a05bdf7ce60a330211418df7bfdabd865aedd892d46d9f143de1e00f79935d55 deps/libs/android-386.tar.gz
f196e7f219cbb4d1b1a040de89bf6d9a7bb9c1ad2754386f680c2df368e2907a deps/libs/android-amd64.tar.gz
19e522f5562399ea5e182e30b06ad6df6d131cdf1b4d9289b5e5e9c9856ba0f4 deps/libs/android-arm.tar.gz
99ad41537a4c3c539c161c3cb2348c4c4890cff67515a06879f2b5ebdead0a84 deps/libs/android-arm64.tar.gz
72c95ba004dfc3af2682f789b3065af42c7fbc2a0a58296477249682fa071838 deps/libs/darwin-amd64.tar.gz
c1ae66952d6849a3061126993824eb8d1dae8af695f2cff6a62bb417ba1e5c22 deps/libs/darwin-arm64.tar.gz
a8601bcf050a4133f694942b4dc5dcd19a54b5559708450a0173e2e7ee72f9e2 deps/libs/ios-amd64.tar.gz
7342b454aacc13ca4b0245be94e1572d22dc2bd5987890d1ae0da9be4e13ee21 deps/libs/ios-arm64.tar.gz
3e54c74d47dd8486155dc10eb22f414224aefd104c10572456e213cfa7613851 deps/libs/ios-arm64-sim.tar.gz
f3216e5ef28c474d3200df560d2188a7456a10da39616bcbf09d3d14ab713932 deps/libs/linux-amd64-musl.tar.gz
66309ec91b9f03d2c1f9becff01cc40e6a81b3b082b975f90fd8341e3ad78949 deps/libs/windows-amd64.tar.gz
51756cec01c0d1867464d6fedf19df2e5e1859f7fc1784f35b4750dcf53ebb54 deps/libs/android-386.tar.gz
bce360c33af6559cf978539a546ce07cdf32b212b73ce93d655b8ba78ad923a6 deps/libs/android-amd64.tar.gz
7881478a39ff6b85e37ad4339aed3756a82d8cbf11bf56efe9c9530c6b4ed602 deps/libs/android-arm.tar.gz
0b129c76883a33700195ce971ad073b7855dc69e90418769b80259ec3125e2e0 deps/libs/android-arm64.tar.gz
71331b6b034a2f81ad4feed195d18cd0c039719cab4f015cfa5bb6eac298b7a7 deps/libs/darwin-amd64.tar.gz
96ab3f803b781bd6489e1d7172dfa2e13d251280db22d686b545baf5a99c7da3 deps/libs/darwin-arm64.tar.gz
3ce3f3933202dee68e106215772a102a5742b7915a6773d7a8aecddc66d2be10 deps/libs/ios-amd64.tar.gz
1ab4b2fdb6bf229bd63ce74bae7a25c4bd8ae895db192a096058035c7057b6ad deps/libs/ios-arm64.tar.gz
b38b025ef58c44240265f01b75a469b5003c63cbae78b9337ce6b9c48aa2e5ef deps/libs/ios-arm64-sim.tar.gz
2b8c84cb0e2a7309b7d130bc64217a3abcd086428403cc5343dad2534bbd7e7d deps/libs/linux-amd64-musl.tar.gz
99b8d647de1783f5362e603a1e5187895c49ae453895b17e132876c6eb4c66f1 deps/libs/windows-amd64.tar.gz

View file

@ -65,7 +65,7 @@ func IntList(ints ...int) *types.Value {
}
}
func FloatList(floats []float64) *types.Value {
func Float64List(floats []float64) *types.Value {
var vals = make([]*types.Value, 0, len(floats))
for _, f := range floats {
vals = append(vals, Float64(f))