github.com/janelia-flyem/dvid@v1.0.0/datatype/labelmap/mutate_test.go (about) 1 package labelmap 2 3 import ( 4 "bytes" 5 "compress/gzip" 6 "encoding/binary" 7 "encoding/json" 8 "fmt" 9 "io" 10 "math/rand" 11 "net/http" 12 "reflect" 13 "runtime" 14 "strings" 15 "sync" 16 "testing" 17 "time" 18 19 pb "google.golang.org/protobuf/proto" 20 21 "github.com/janelia-flyem/dvid/datastore" 22 "github.com/janelia-flyem/dvid/datatype/common/downres" 23 "github.com/janelia-flyem/dvid/datatype/common/labels" 24 "github.com/janelia-flyem/dvid/datatype/common/proto" 25 "github.com/janelia-flyem/dvid/dvid" 26 "github.com/janelia-flyem/dvid/server" 27 28 lz4 "github.com/janelia-flyem/go/golz4-updated" 29 ) 30 31 func checkSparsevolsCoarse(t *testing.T, encoding []byte) { 32 length := len(encoding) 33 var i int 34 for label := uint64(1); label <= 3; label++ { 35 if i+28 >= length { 36 t.Fatalf("Expected label %d but only %d bytes remain in encoding\n", label, len(encoding[i:])) 37 } 38 gotLabel := binary.LittleEndian.Uint64(encoding[i : i+8]) 39 if gotLabel != label { 40 t.Errorf("Expected label %d, got label %d in returned coarse sparsevols\n", label, gotLabel) 41 } 42 i += 8 43 var spans dvid.Spans 44 if err := spans.UnmarshalBinary(encoding[i:]); err != nil { 45 t.Errorf("Error in decoding coarse sparse volume: %v\n", err) 46 return 47 } 48 i += 4 + len(spans)*16 49 b := bodies[label-1] 50 if !reflect.DeepEqual(spans, b.blockSpans) { 51 _, fn, line, _ := runtime.Caller(1) 52 t.Errorf("Expected coarse spans for label %d:\n%s\nGot spans [%s:%d]:\n%s\n", b.label, b.blockSpans, fn, line, spans) 53 } 54 } 55 } 56 57 func checkNoSparsevol(t *testing.T, uuid dvid.UUID, label uint64) { 58 headReq := fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, label) 59 resp := server.TestHTTPResponse(t, "HEAD", headReq, nil) 60 if resp.Code != http.StatusNoContent { 61 _, fn, line, _ := runtime.Caller(1) 62 t.Fatalf("HEAD on %s did not return 204 (No Content). Status = %d [%s:%d]\n", headReq, resp.Code, fn, line) 63 } 64 } 65 66 func checkSparsevolAPIs(t *testing.T, uuid dvid.UUID) { 67 for _, label := range []uint64{1, 2, 3, 4} { 68 bodies[label-1].checkSparsevolAPIs(t, uuid, label) 69 } 70 71 reqStr := fmt.Sprintf("%snode/%s/labels/sparsevols-coarse/1/3", server.WebAPIPath, uuid) 72 encoding := server.TestHTTP(t, "GET", reqStr, nil) 73 checkSparsevolsCoarse(t, encoding) 74 75 reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol-size/1", server.WebAPIPath, uuid) 76 sizeResp := server.TestHTTP(t, "GET", reqStr, nil) 77 if string(sizeResp) != `{"voxels": 32000, "numblocks": 3, "minvoxel": [0, 32, 0], "maxvoxel": [31, 63, 95]}` { 78 t.Errorf("bad response to sparsevol-size endpoint: %s\n", string(sizeResp)) 79 } 80 81 // Make sure non-existent bodies return proper HEAD responses. 82 headReq := fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, 10) 83 resp := server.TestHTTPResponse(t, "HEAD", headReq, nil) 84 if resp.Code != http.StatusNoContent { 85 t.Errorf("HEAD on %s did not return 204 (No Content). Status = %d\n", headReq, resp.Code) 86 } 87 } 88 89 func ingestIndex(t *testing.T, uuid dvid.UUID, idx *labels.Index) { 90 serialization, err := pb.Marshal(idx) 91 if err != nil { 92 t.Fatal(err) 93 } 94 ingestReq := fmt.Sprintf("%snode/%s/labels/index/%d", server.WebAPIPath, uuid, idx.Label) 95 server.TestHTTP(t, "POST", ingestReq, bytes.NewBuffer(serialization)) 96 } 97 98 type testBody struct { 99 label uint64 100 offset, size dvid.Point3d // these are just to give ROI of voxelSpans 101 blockSpans dvid.Spans 102 voxelSpans dvid.Spans // in DVID coordinates, not relative coordinates 103 } 104 105 var emptyBody = testBody{ 106 label: 0, 107 offset: dvid.Point3d{}, 108 size: dvid.Point3d{}, 109 blockSpans: dvid.Spans{}, 110 voxelSpans: dvid.Spans{}, 111 } 112 113 func (b testBody) add(b2 testBody) (merged testBody) { 114 blockSpans := make(dvid.Spans, len(b.blockSpans)+len(b2.blockSpans)) 115 i := 0 116 for _, span := range b.blockSpans { 117 blockSpans[i] = span 118 i++ 119 } 120 for _, span := range b2.blockSpans { 121 blockSpans[i] = span 122 i++ 123 } 124 125 voxelSpans := make(dvid.Spans, len(b.voxelSpans)+len(b2.voxelSpans)) 126 i = 0 127 for _, span := range b.voxelSpans { 128 voxelSpans[i] = span 129 i++ 130 } 131 for _, span := range b2.voxelSpans { 132 voxelSpans[i] = span 133 i++ 134 } 135 offset, size := voxelSpans.Extents() 136 merged = testBody{ 137 label: b.label, 138 offset: offset, 139 size: size, 140 blockSpans: blockSpans.Normalize(), 141 voxelSpans: voxelSpans.Normalize(), 142 } 143 return 144 } 145 146 func (b testBody) checkSparsevolAPIs(t *testing.T, uuid dvid.UUID, label uint64) { 147 // Check coarse sparsevol 148 reqStr := fmt.Sprintf("%snode/%s/labels/sparsevol-coarse/%d", server.WebAPIPath, uuid, label) 149 encoding := server.TestHTTP(t, "GET", reqStr, nil) 150 b.checkCoarse(t, encoding) 151 152 // Check fast HEAD requests 153 reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, label) 154 resp := server.TestHTTPResponse(t, "HEAD", reqStr, nil) 155 if resp.Code != http.StatusOK { 156 t.Errorf("HEAD on %s did not return OK. Status = %d\n", reqStr, resp.Code) 157 } 158 159 // Check full sparse volumes 160 encoding = server.TestHTTP(t, "GET", reqStr, nil) 161 lenEncoding := len(encoding) 162 b.checkSparseVol(t, encoding, dvid.OptionalBounds{}) 163 164 // check one downres 165 encoding = server.TestHTTP(t, "GET", reqStr+"?scale=1", nil) 166 b.checkScaledSparseVol(t, encoding, 1, dvid.OptionalBounds{}) 167 168 // check two downres 169 encoding = server.TestHTTP(t, "GET", reqStr+"?scale=2", nil) 170 b.checkScaledSparseVol(t, encoding, 2, dvid.OptionalBounds{}) 171 172 // Check with lz4 compression 173 uncompressed := make([]byte, lenEncoding) 174 compressed := server.TestHTTP(t, "GET", reqStr+"?compression=lz4", nil) 175 if err := lz4.Uncompress(compressed, uncompressed); err != nil { 176 t.Fatalf("error uncompressing lz4 for sparsevol %d GET: %v\n", label, err) 177 } 178 b.checkSparseVol(t, uncompressed, dvid.OptionalBounds{}) 179 180 // Check with gzip compression 181 compressed = server.TestHTTP(t, "GET", reqStr+"?compression=gzip", nil) 182 buf := bytes.NewBuffer(compressed) 183 var err error 184 r, err := gzip.NewReader(buf) 185 if err != nil { 186 t.Fatalf("error creating gzip reader: %v\n", err) 187 } 188 var buffer bytes.Buffer 189 _, err = io.Copy(&buffer, r) 190 if err != nil { 191 t.Fatalf("error copying gzip data: %v\n", err) 192 } 193 err = r.Close() 194 if err != nil { 195 t.Fatalf("error closing gzip: %v\n", err) 196 } 197 encoding = buffer.Bytes() 198 b.checkSparseVol(t, encoding, dvid.OptionalBounds{}) 199 200 // Check Y/Z restriction 201 miny := int32(30) 202 maxy := int32(50) 203 minz := int32(20) 204 maxz := int32(40) 205 for scale := uint8(0); scale < 3; scale++ { 206 reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/%d?scale=%d&miny=%d&maxy=%d&minz=%d&maxz=%d", 207 server.WebAPIPath, uuid, label, scale, miny, maxy, minz, maxz) 208 if label != 4 { 209 encoding = server.TestHTTP(t, "GET", reqStr, nil) 210 var bound dvid.OptionalBounds 211 bound.SetMinY(miny) 212 bound.SetMaxY(maxy) 213 bound.SetMinZ(minz) 214 bound.SetMaxZ(maxz) 215 b.checkScaledSparseVol(t, encoding, scale, bound) 216 } else { 217 encoding = server.TestHTTP(t, "GET", reqStr, nil) // Should be 200 with no bytes 218 if len(encoding) != 0 { 219 t.Fatalf("expected 0 bytes, got %d for %s\n", len(encoding), reqStr) 220 } 221 } 222 miny >>= 1 223 maxy >>= 1 224 minz >>= 1 225 maxz >>= 1 226 } 227 228 // Check X restriction 229 minx := int32(20) 230 maxx := int32(47) 231 reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/%d?minx=%d&maxx=%d", server.WebAPIPath, uuid, label, minx, maxx) 232 if label != 4 { 233 encoding = server.TestHTTP(t, "GET", reqStr, nil) 234 checkSpans(t, encoding, minx, maxx) 235 } else { 236 server.TestBadHTTP(t, "GET", reqStr, nil) // Should be not found 237 } 238 } 239 240 func (b testBody) getIndex(t *testing.T) *labels.Index { 241 idx := new(labels.Index) 242 idx.Label = b.label 243 idx.Blocks = make(map[uint64]*proto.SVCount) 244 voxelCounts := b.voxelSpans.VoxelCounts(dvid.Point3d{32, 32, 32}) 245 for izyxStr, count := range voxelCounts { 246 zyx, err := labels.IZYXStringToBlockIndex(izyxStr) 247 if err != nil { 248 t.Fatal(err) 249 } 250 svc := new(proto.SVCount) 251 svc.Counts = map[uint64]uint32{b.label: count} 252 idx.Blocks[zyx] = svc 253 } 254 return idx 255 } 256 257 func (b testBody) postIndex(t *testing.T, uuid dvid.UUID) { 258 idx := b.getIndex(t) 259 serialization, err := pb.Marshal(idx) 260 if err != nil { 261 t.Fatal(err) 262 } 263 indexReq := fmt.Sprintf("%snode/%s/labels/index/%d", server.WebAPIPath, uuid, b.label) 264 server.TestHTTP(t, "POST", indexReq, bytes.NewBuffer(serialization)) 265 } 266 267 // Makes sure the coarse sparse volume encoding matches the body. 268 func (b testBody) checkCoarse(t *testing.T, encoding []byte) { 269 // Get to the # spans and RLE in encoding 270 spansEncoding := encoding[8:] 271 var spans dvid.Spans 272 if err := spans.UnmarshalBinary(spansEncoding); err != nil { 273 t.Errorf("Error in decoding coarse sparse volume: %v\n", err) 274 return 275 } 276 277 // Check those spans match the body voxels. 278 if !reflect.DeepEqual(spans, b.blockSpans) { 279 _, fn, line, _ := runtime.Caller(1) 280 t.Errorf("Expected coarse spans for label %d:\n%s\nGot spans [%s:%d]:\n%s\n", b.label, b.blockSpans, fn, line, spans) 281 } 282 } 283 284 // Makes sure the sparse volume encoding matches the actual body voxels. 285 func (b testBody) checkSparseVol(t *testing.T, encoding []byte, bounds dvid.OptionalBounds) { 286 if len(encoding) < 12 { 287 t.Fatalf("Bad encoded sparsevol received. Only %d bytes\n", len(encoding)) 288 } 289 290 // Get to the # spans and RLE in encoding 291 spansEncoding := encoding[8:] 292 var spans dvid.Spans 293 if err := spans.UnmarshalBinary(spansEncoding); err != nil { 294 t.Fatalf("Error in decoding sparse volume: %v\n", err) 295 } 296 297 // Create potentially bounded spans 298 expected := dvid.Spans{} 299 if bounds.IsSet() { 300 for _, span := range b.voxelSpans { 301 if bounds.OutsideY(span[1]) || bounds.OutsideZ(span[0]) { 302 continue 303 } 304 expected = append(expected, span) 305 } 306 } else { 307 expected = b.voxelSpans 308 } 309 310 // Check those spans match the body voxels. 311 gotNorm := spans.Normalize() 312 expectNorm := expected.Normalize() 313 if !reflect.DeepEqual(gotNorm, expectNorm) { 314 for _, got := range gotNorm { 315 bad := true 316 for _, expect := range expectNorm { 317 if reflect.DeepEqual(got, expect) { 318 bad = false 319 } 320 } 321 if bad { 322 fmt.Printf("Got unexpected span: %s\n", got) 323 } 324 } 325 for _, expect := range expectNorm { 326 bad := true 327 for _, got := range gotNorm { 328 if reflect.DeepEqual(got, expect) { 329 bad = false 330 } 331 } 332 if bad { 333 fmt.Printf("Never got expected span: %s\n", expect) 334 } 335 } 336 _, fn, line, _ := runtime.Caller(1) 337 t.Fatalf("Expected %d fine spans for label %d [%s:%d]:\n%s\nGot %d spans:\n%s\nAfter Norm:%s\n", len(expectNorm), b.label, fn, line, expectNorm, len(spans), spans, gotNorm) 338 } 339 } 340 341 // Makes sure the sparse volume encoding matches a downres of actual body voxels. 342 func (b testBody) checkScaledSparseVol(t *testing.T, encoding []byte, scale uint8, bounds dvid.OptionalBounds) { 343 if scale == 0 { 344 b.checkSparseVol(t, encoding, bounds) 345 return 346 } 347 // Make down-res volume of body 348 vol := newTestVolume(128, 128, 128) 349 vol.addBody(b, 1) 350 vol.downres(scale) 351 352 if len(encoding) < 12 { 353 if vol.containsLabel(1) { 354 t.Fatalf("Bad encoded sparsevol received at scale %d. Only %d bytes when label 1 found\n", scale, len(encoding)) 355 } 356 return 357 } 358 359 // Get to the # spans and RLE in encoding 360 spansEncoding := encoding[8:] 361 var spans dvid.Spans 362 if err := spans.UnmarshalBinary(spansEncoding); err != nil { 363 t.Fatalf("Error in decoding sparse volume: %v\n", err) 364 } 365 366 // Check those spans are within the body voxels. 367 for _, span := range spans { 368 z, y, x0, x1 := span.Unpack() 369 if x1 >= vol.size[0] || y >= vol.size[1] || z >= vol.size[2] { 370 t.Fatalf("Span %s is outside bound of scale %d volume of size %s\n", span, scale, vol.size) 371 } 372 pos := z*vol.size[0]*vol.size[1] + y*vol.size[0] + x0 373 for x := x0; x <= x1; x++ { 374 label := binary.LittleEndian.Uint64(vol.data[pos*8 : pos*8+8]) 375 if label != 1 { 376 t.Fatalf("Received body at scale %d has voxel at (%d,%d,%d) but that voxel is label %d, not in body %d\n", scale, x, y, z, label, b.label) 377 return 378 } 379 pos++ 380 } 381 } 382 } 383 384 // checks use of binary blocks format 385 func (b testBody) checkBinarySparseVol(t *testing.T, r io.Reader) { 386 binBlocks, err := labels.ReceiveBinaryBlocks(r) 387 if err != nil { 388 _, fn, line, _ := runtime.Caller(1) 389 t.Fatalf("Error trying to decode binary blocks for body %d [%s:%d]: %v\n", b.label, fn, line, err) 390 } 391 392 expected := newTestVolume(128, 128, 128) 393 expected.addBody(b, 1) 394 395 got := newTestVolume(128, 128, 128) 396 got.addBlocks(t, binBlocks, 1) 397 398 if err := expected.equals(got); err != nil { 399 _, fn, line, _ := runtime.Caller(1) 400 t.Fatalf("error getting binary blocks for body %d [%s:%d]: %v\n", b.label, fn, line, err) 401 } 402 } 403 404 // checks use of binary blocks format + scaling 405 func (b testBody) checkScaledBinarySparseVol(t *testing.T, r io.Reader, scale uint8) { 406 binBlocks, err := labels.ReceiveBinaryBlocks(r) 407 if err != nil { 408 t.Fatalf("Error trying to decode binary blocks for body %d: %v\n", b.label, err) 409 } 410 411 expected := newTestVolume(128, 128, 128) 412 expected.addBody(b, 1) 413 expected.downres(scale) 414 415 n := int32(128 >> scale) 416 got := newTestVolume(n, n, n) 417 got.addBlocks(t, binBlocks, 1) 418 419 if err := expected.equals(got); err != nil { 420 _, fn, line, _ := runtime.Caller(1) 421 t.Fatalf("error getting binary blocks for body %d, scale %d [%s:%d]: %v\n", b.label, scale, fn, line, err) 422 } 423 } 424 425 // Sees if the given block span has any of this test body label in it. 426 func (b testBody) isDeleted(t *testing.T, encoding []byte, bspan dvid.Span) bool { 427 // Get to the # spans and RLE in encoding 428 spansEncoding := encoding[8:] 429 var spans dvid.Spans 430 if err := spans.UnmarshalBinary(spansEncoding); err != nil { 431 t.Fatalf("Error in decoding sparse volume: %v\n", err) 432 return false 433 } 434 435 // Iterate true spans to see if any are in the blocks given. 436 for _, span := range spans { 437 bx0 := span[2] / 32 438 bx1 := span[3] / 32 439 by := span[1] / 32 440 bz := span[0] / 32 441 442 withinX := (bx0 >= bspan[2] && bx0 <= bspan[3]) || (bx1 >= bspan[2] && bx1 <= bspan[3]) 443 if bz == bspan[0] && by == bspan[1] && withinX { 444 return false 445 } 446 } 447 return true 448 } 449 450 func checkSpans(t *testing.T, encoding []byte, minx, maxx int32) { 451 // Get to the # spans and RLE in encoding 452 spansEncoding := encoding[8:] 453 var spans dvid.Spans 454 if err := spans.UnmarshalBinary(spansEncoding); err != nil { 455 t.Errorf("Error in decoding coarse sparse volume: %v\n", err) 456 return 457 } 458 for _, span := range spans { 459 if span[2] < minx { 460 t.Errorf("Found span violating min x %d: %s\n", minx, span) 461 return 462 } 463 if span[3] > maxx { 464 t.Errorf("Found span violating max x %d: %s\n", maxx, span) 465 } 466 } 467 } 468 469 // Sets voxels in body to given label. 470 func (v *testVolume) addBody(body testBody, label uint64) { 471 nx := v.size[0] 472 nxy := nx * v.size[1] 473 for _, span := range body.voxelSpans { 474 z, y, x0, x1 := span.Unpack() 475 p := (z*nxy + y*nx) * 8 476 for i := p + x0*8; i <= p+x1*8; i += 8 { 477 binary.LittleEndian.PutUint64(v.data[i:i+8], label) 478 } 479 } 480 } 481 482 // Returns true if all voxels in test volume for given body has label. 483 func (v *testVolume) isLabel(label uint64, body *testBody) bool { 484 nx := v.size[0] 485 nxy := nx * v.size[1] 486 for _, span := range body.voxelSpans { 487 z, y, x0, x1 := span.Unpack() 488 p := (z*nxy + y*nx) * 8 489 for i := p + x0*8; i <= p+x1*8; i += 8 { 490 curLabel := binary.LittleEndian.Uint64(v.data[i : i+8]) 491 if curLabel != label { 492 return false 493 } 494 } 495 } 496 return true 497 } 498 499 // Returns true if any voxel in test volume has given label. 500 func (v *testVolume) hasLabel(label uint64, body *testBody) bool { 501 nx := v.size[0] 502 nxy := nx * v.size[1] 503 for _, span := range body.voxelSpans { 504 z, y, x0, x1 := span.Unpack() 505 p := (z*nxy + y*nx) * 8 506 for i := p + x0*8; i <= p+x1*8; i += 8 { 507 curLabel := binary.LittleEndian.Uint64(v.data[i : i+8]) 508 if curLabel == label { 509 return true 510 } 511 } 512 } 513 return false 514 } 515 516 func createLabelTestVolume(t *testing.T, uuid dvid.UUID, name string) *testVolume { 517 // Setup test label blocks that are non-intersecting. 518 volume := newTestVolume(128, 128, 128) 519 volume.addBody(body1, 1) 520 volume.addBody(body2, 2) 521 volume.addBody(body3, 3) 522 volume.addBody(body4, 4) 523 524 // Send data over HTTP to populate a data instance 525 volume.put(t, uuid, name) 526 return volume 527 } 528 529 func createLabelTest2Volume(t *testing.T, uuid dvid.UUID, name string) *testVolume { 530 // Setup test label blocks that are non-intersecting. 531 volume := newTestVolume(128, 128, 128) 532 volume.addBody(body6, 6) 533 volume.addBody(body7, 7) 534 535 // Send data over HTTP to populate a data instance using mutable flag 536 volume.putMutable(t, uuid, name) 537 return volume 538 } 539 540 func TestSparseVolumes(t *testing.T) { 541 if err := server.OpenTest(); err != nil { 542 t.Fatalf("can't open test server: %v\n", err) 543 } 544 defer server.CloseTest() 545 546 // Create testbed volume and data instances 547 uuid, _ := initTestRepo() 548 var config dvid.Config 549 config.Set("MaxDownresLevel", "2") 550 config.Set("BlockSize", "32,32,32") // Previous test data was on 32^3 blocks 551 server.CreateTestInstance(t, uuid, "labelmap", "labels", config) 552 labelVol := createLabelTestVolume(t, uuid, "labels") 553 554 gotVol := newTestVolume(128, 128, 128) 555 gotVol.get(t, uuid, "labels", false) 556 if err := gotVol.equals(labelVol); err != nil { 557 t.Fatalf("Couldn't get back simple 128x128x128 label volume that was written: %v\n", err) 558 } 559 560 if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil { 561 t.Fatalf("Error blocking on labels updating: %v\n", err) 562 } 563 if err := downres.BlockOnUpdating(uuid, "labels"); err != nil { 564 t.Fatalf("Error blocking on update for labels: %v\n", err) 565 } 566 time.Sleep(1 * time.Second) 567 568 dataservice, err := datastore.GetDataByUUIDName(uuid, "labels") 569 if err != nil { 570 t.Fatalf("couldn't get labels data instance from datastore: %v\n", err) 571 } 572 labels, ok := dataservice.(*Data) 573 if !ok { 574 t.Fatalf("Returned data instance for 'labels' instance was not labelmap.Data!\n") 575 } 576 if labels.MaxRepoLabel != 4 { 577 t.Errorf("Expected max repo label to be 4, got %d\n", labels.MaxRepoLabel) 578 } 579 v, err := datastore.VersionFromUUID(uuid) 580 if err != nil { 581 t.Errorf("couldn't get version id from uuid %s: %v\n", uuid, err) 582 } 583 if len(labels.MaxLabel) != 1 || labels.MaxLabel[v] != 4 { 584 t.Errorf("bad MaxLabels: %v\n", labels.MaxLabel) 585 } 586 maxLabelResp := server.TestHTTP(t, "GET", fmt.Sprintf("%snode/%s/labels/maxlabel", server.WebAPIPath, uuid), nil) 587 if string(maxLabelResp) != `{"maxlabel": 4}` { 588 t.Errorf("bad response to maxlabel endpoint: %s\n", string(maxLabelResp)) 589 } 590 591 server.TestHTTP(t, "POST", fmt.Sprintf("%snode/%s/labels/maxlabel/8", server.WebAPIPath, uuid), nil) 592 maxLabelResp = server.TestHTTP(t, "GET", fmt.Sprintf("%snode/%s/labels/maxlabel", server.WebAPIPath, uuid), nil) 593 if string(maxLabelResp) != `{"maxlabel": 8}` { 594 t.Errorf("bad response to maxlabel endpoint: %s\n", string(maxLabelResp)) 595 } 596 597 nextLabelResp := server.TestHTTP(t, "GET", fmt.Sprintf("%snode/%s/labels/nextlabel", server.WebAPIPath, uuid), nil) 598 if string(nextLabelResp) != `{"nextlabel": 9}` { 599 t.Errorf("bad response to nextlabel endpoint: %s\n", string(nextLabelResp)) 600 } 601 nextLabelResp = server.TestHTTP(t, "POST", fmt.Sprintf("%snode/%s/labels/nextlabel/5", server.WebAPIPath, uuid), nil) 602 if string(nextLabelResp) != `{"start": 9, "end": 13}` { 603 t.Errorf("bad response to POST /nextlabel: %s\n", string(maxLabelResp)) 604 } 605 maxLabelResp = server.TestHTTP(t, "GET", fmt.Sprintf("%snode/%s/labels/maxlabel", server.WebAPIPath, uuid), nil) 606 if string(maxLabelResp) != `{"maxlabel": 13}` { 607 t.Errorf("bad response to maxlabel endpoint: %s\n", string(maxLabelResp)) 608 } 609 nextLabelResp = server.TestHTTP(t, "GET", fmt.Sprintf("%snode/%s/labels/nextlabel", server.WebAPIPath, uuid), nil) 610 if string(nextLabelResp) != `{"nextlabel": 14}` { 611 t.Errorf("bad response to nextlabel endpoint: %s\n", string(nextLabelResp)) 612 } 613 614 badReqStr := fmt.Sprintf("%snode/%s/labels/sparsevol/0", server.WebAPIPath, uuid) 615 server.TestBadHTTP(t, "GET", badReqStr, nil) 616 617 checkSparsevolAPIs(t, uuid) 618 } 619 620 func Test16x16x16SparseVolumes(t *testing.T) { 621 if err := server.OpenTest(); err != nil { 622 t.Fatalf("can't open test server: %v\n", err) 623 } 624 defer server.CloseTest() 625 626 // Create testbed volume and data instances 627 uuid, _ := initTestRepo() 628 var config dvid.Config 629 config.Set("BlockSize", "16,16,16") // Since RLE encoding spans blocks now, should work for smaller block size. 630 server.CreateTestInstance(t, uuid, "labelmap", "labels", config) 631 labelVol := createLabelTestVolume(t, uuid, "labels") 632 633 gotVol := newTestVolume(128, 128, 128) 634 gotVol.get(t, uuid, "labels", false) 635 if err := gotVol.equals(labelVol); err != nil { 636 t.Fatalf("Couldn't get back simple 128x128x128 label volume that was written: %v\n", err) 637 } 638 639 if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil { 640 t.Fatalf("Error blocking on labels updating: %v\n", err) 641 } 642 time.Sleep(1 * time.Second) 643 644 for _, label := range []uint64{1, 2, 3, 4} { 645 // Check fast HEAD requests 646 reqStr := fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, label) 647 resp := server.TestHTTPResponse(t, "HEAD", reqStr, nil) 648 if resp.Code != http.StatusOK { 649 t.Errorf("HEAD on %s did not return OK. Status = %d\n", reqStr, resp.Code) 650 } 651 652 // Check full sparse volumes 653 encoding := server.TestHTTP(t, "GET", reqStr, nil) 654 fmt.Printf("Got %d bytes back from %s\n", len(encoding), reqStr) 655 bodies[label-1].checkSparseVol(t, encoding, dvid.OptionalBounds{}) 656 657 // Check with lz4 compression 658 compressed := server.TestHTTP(t, "GET", reqStr+"?compression=lz4", nil) 659 if err := lz4.Uncompress(compressed, encoding); err != nil { 660 t.Fatalf("error uncompressing lz4: %v\n", err) 661 } 662 bodies[label-1].checkSparseVol(t, encoding, dvid.OptionalBounds{}) 663 664 // Check with gzip compression 665 compressed = server.TestHTTP(t, "GET", reqStr+"?compression=gzip", nil) 666 b := bytes.NewBuffer(compressed) 667 var err error 668 r, err := gzip.NewReader(b) 669 if err != nil { 670 t.Fatalf("error creating gzip reader: %v\n", err) 671 } 672 var buffer bytes.Buffer 673 _, err = io.Copy(&buffer, r) 674 if err != nil { 675 t.Fatalf("error copying gzip data: %v\n", err) 676 } 677 err = r.Close() 678 if err != nil { 679 t.Fatalf("error closing gzip: %v\n", err) 680 } 681 encoding = buffer.Bytes() 682 bodies[label-1].checkSparseVol(t, encoding, dvid.OptionalBounds{}) 683 684 // Check Y/Z restriction 685 reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/%d?miny=30&maxy=50&minz=20&maxz=40", server.WebAPIPath, uuid, label) 686 if label != 4 { 687 encoding = server.TestHTTP(t, "GET", reqStr, nil) 688 var bound dvid.OptionalBounds 689 bound.SetMinY(30) 690 bound.SetMaxY(50) 691 bound.SetMinZ(20) 692 bound.SetMaxZ(40) 693 bodies[label-1].checkSparseVol(t, encoding, bound) 694 } else { 695 server.TestBadHTTP(t, "GET", reqStr, nil) // Should be not found 696 } 697 698 // Check X restriction 699 minx := int32(20) 700 maxx := int32(47) 701 reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/%d?minx=%d&maxx=%d", server.WebAPIPath, uuid, label, minx, maxx) 702 if label != 4 { 703 encoding = server.TestHTTP(t, "GET", reqStr, nil) 704 checkSpans(t, encoding, minx, maxx) 705 } else { 706 server.TestBadHTTP(t, "GET", reqStr, nil) // Should be not found 707 } 708 } 709 710 // Make sure non-existent bodies return proper HEAD responses. 711 headReq := fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, 10) 712 resp := server.TestHTTPResponse(t, "HEAD", headReq, nil) 713 if resp.Code != http.StatusNoContent { 714 t.Errorf("HEAD on %s did not return 204 (No Content). Status = %d\n", headReq, resp.Code) 715 } 716 } 717 718 // func TestMergeLog(t *testing.T) { 719 // if err := server.OpenTest(); err != nil { 720 // t.Fatalf("can't open test server: %v\n", err) 721 // } 722 // defer server.CloseTest() 723 724 // // Create testbed volume and data instances 725 // uuid, _ := initTestRepo() 726 // var config dvid.Config 727 // server.CreateTestInstance(t, uuid, "labelmap", "labels", config) 728 729 // data, err := GetByUUIDName(uuid, "labels") 730 // if err != nil { 731 // t.Fatalf("can't get labels instance of labelmap: %v\n", err) 732 // } 733 // } 734 735 func TestMergeLabels(t *testing.T) { 736 if err := server.OpenTest(); err != nil { 737 t.Fatalf("can't open test server: %v\n", err) 738 } 739 defer server.CloseTest() 740 741 // Create testbed volume and data instances 742 uuid, _ := initTestRepo() 743 var config dvid.Config 744 server.CreateTestInstance(t, uuid, "labelmap", "labels", config) 745 746 expected := createLabelTestVolume(t, uuid, "labels") 747 expected.addBody(body3, 2) 748 749 if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil { 750 t.Fatalf("Error blocking on sync of labels: %v\n", err) 751 } 752 753 // Make sure max label is consistent 754 reqStr := fmt.Sprintf("%snode/%s/labels/maxlabel", server.WebAPIPath, uuid) 755 r := server.TestHTTP(t, "GET", reqStr, nil) 756 jsonVal := make(map[string]uint64) 757 if err := json.Unmarshal(r, &jsonVal); err != nil { 758 t.Errorf("Unable to get maxlabel from server. Instead got: %v\n", jsonVal) 759 } 760 maxlabel, ok := jsonVal["maxlabel"] 761 if !ok { 762 t.Errorf("The maxlabel query did not yield max label. Instead got: %v\n", jsonVal) 763 } 764 if maxlabel != 4 { 765 t.Errorf("Expected max label to be 4, instead got %d\n", maxlabel) 766 } 767 768 // Check /supervoxels 769 reqStr = fmt.Sprintf("%snode/%s/labels/supervoxels/2", server.WebAPIPath, uuid) 770 r = server.TestHTTP(t, "GET", reqStr, nil) 771 var supervoxels []uint64 772 if err := json.Unmarshal(r, &supervoxels); err != nil { 773 t.Errorf("Unable to parse supervoxels from server. Got: %v\n", supervoxels) 774 } 775 if len(supervoxels) != 1 || supervoxels[0] != 2 { 776 t.Errorf("expected [2] for supervoxels in body 2, got %v\n", supervoxels) 777 } 778 779 // Check /supervoxel-sizes 780 reqStr = fmt.Sprintf("%snode/%s/labels/supervoxel-sizes/2", server.WebAPIPath, uuid) 781 r = server.TestHTTP(t, "GET", reqStr, nil) 782 svsizes := struct { 783 Supervoxels []uint64 784 Sizes []uint64 785 }{} 786 if err := json.Unmarshal(r, &svsizes); err != nil { 787 t.Errorf("Unable to parse supervoxel-sizes from server. Got: %s\n", string(r)) 788 } 789 if len(svsizes.Supervoxels) != 1 || svsizes.Supervoxels[0] != 2 { 790 t.Errorf("expected [2] for supervoxels in body 2, got %v\n", svsizes.Supervoxels) 791 } 792 if len(svsizes.Sizes) != 1 || svsizes.Sizes[0] != 50000 { 793 t.Errorf("expected [2] for supervoxel sizes in body 2, got %v\n", svsizes.Sizes) 794 } 795 796 // Make sure /label and /labels endpoints work. 797 apiStr := fmt.Sprintf("%snode/%s/%s/label/94_58_89", server.WebAPIPath, uuid, "labels") 798 jsonResp := server.TestHTTP(t, "GET", apiStr, nil) 799 var jsonVal2 struct { 800 Label uint64 801 } 802 if err := json.Unmarshal(jsonResp, &jsonVal2); err != nil { 803 t.Errorf("Unable to parse 'label' endpoint response: %s\n", jsonResp) 804 } 805 if jsonVal2.Label != 4 { 806 t.Errorf("Expected label 4, got label %d\n", jsonVal2.Label) 807 } 808 apiStr = fmt.Sprintf("%snode/%s/%s/labels", server.WebAPIPath, uuid, "labels") 809 payload := `[[20,46,39],[30,25,50],[48,56,39],[80,55,60]]` 810 jsonResp = server.TestHTTP(t, "GET", apiStr, bytes.NewBufferString(payload)) 811 var labels [4]uint64 812 if err := json.Unmarshal(jsonResp, &labels); err != nil { 813 t.Fatalf("Unable to parse 'labels' endpoint response: %s\n", jsonResp) 814 } 815 if labels[0] != 1 { 816 t.Errorf("Expected label 1, got label %d\n", labels[0]) 817 } 818 if labels[1] != 2 { 819 t.Errorf("Expected label 2, got label %d\n", labels[1]) 820 } 821 if labels[2] != 3 { 822 t.Errorf("Expected label 3, got label %d\n", labels[2]) 823 } 824 if labels[3] != 4 { 825 t.Errorf("Expected label 4, got label %d\n", labels[3]) 826 } 827 828 // Test merge of 3 into 2 829 testMerge := mergeJSON(`[2, 3]`) 830 testMerge.send(t, uuid, "labels") 831 832 // Make sure label 3 sparsevol has been removed. 833 reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, 3) 834 server.TestBadHTTP(t, "GET", reqStr, nil) 835 836 // Check /supervoxels 837 reqStr = fmt.Sprintf("%snode/%s/labels/supervoxels/2", server.WebAPIPath, uuid) 838 r = server.TestHTTP(t, "GET", reqStr, nil) 839 if err := json.Unmarshal(r, &supervoxels); err != nil { 840 t.Errorf("Unable to parse supervoxels from server. Got: %v\n", supervoxels) 841 } 842 if len(supervoxels) != 2 { 843 t.Errorf("expected [2,3] for supervoxels in body 2, got %v\n", supervoxels) 844 } 845 sv := make(map[uint64]struct{}, 2) 846 for _, supervoxel := range supervoxels { 847 sv[supervoxel] = struct{}{} 848 } 849 if _, found := sv[2]; !found { 850 t.Errorf("expected supervoxel 2 within body 2 but didn't find it\n") 851 } 852 if _, found := sv[3]; !found { 853 t.Errorf("expected supervoxel 3 within body 3 but didn't find it\n") 854 } 855 856 reqStr = fmt.Sprintf("%snode/%s/labels/supervoxel-sizes/2", server.WebAPIPath, uuid) 857 r = server.TestHTTP(t, "GET", reqStr, nil) 858 if err := json.Unmarshal(r, &svsizes); err != nil { 859 t.Errorf("Unable to parse supervoxel-sizes from server. Got: %s\n", string(r)) 860 } 861 expectedSizes := map[uint64]uint64{ 862 2: 50000, 863 3: 12000, 864 } 865 if len(svsizes.Supervoxels) != 2 { 866 t.Fatalf("expected 2 sv return from supervoxel-sizes, got %d\n", len(svsizes.Supervoxels)) 867 } 868 if len(svsizes.Sizes) != 2 { 869 t.Fatalf("expected 2 sv size return from supervoxel-sizes, got %d\n", len(svsizes.Sizes)) 870 } 871 for i := 0; i < 2; i++ { 872 svlabel := svsizes.Supervoxels[i] 873 expectedSize, found := expectedSizes[svlabel] 874 if !found { 875 t.Fatalf("bad /supervoxel-sizes return. Got unexpected supervoxel %d\n", svlabel) 876 } 877 if expectedSize != svsizes.Sizes[i] { 878 t.Fatalf("bad /supervoxel-sizes return. Got unexpected size %d for supervoxel %d, expected %d\n", 879 svsizes.Sizes[i], svlabel, expectedSize) 880 } 881 } 882 883 // Make sure the index metadata is correct 884 indexURL := fmt.Sprintf("%snode/%s/labels/index/2?metadata-only=true", server.WebAPIPath, uuid) 885 respData := server.TestHTTP(t, "GET", indexURL, nil) 886 respJSON := struct { 887 NumVoxels uint64 `json:"num_voxels"` 888 LastMutID uint64 `json:"last_mutid"` 889 LastModTime string `json:"last_mod_time"` 890 LastModUser string `json:"last_mod_user"` 891 LastModApp string `json:"last_mod_app"` 892 }{} 893 if err := json.Unmarshal(respData, &respJSON); err != nil { 894 t.Errorf("Expected JSON response. Got %s\n", string(respData)) 895 } 896 if respJSON.NumVoxels != 62000 { 897 t.Errorf("Expected num voxels %d, got %d\n", 50000, respJSON.NumVoxels) 898 } 899 if respJSON.LastModUser != "tester" { 900 t.Errorf("Expected LastModUser 'tester', got %v\n", respJSON) 901 } 902 903 // Make sure label changes are correct after completion 904 apiStr = fmt.Sprintf("%snode/%s/%s/labels", server.WebAPIPath, uuid, "labels") 905 jsonResp = server.TestHTTP(t, "GET", apiStr, bytes.NewBufferString(payload)) 906 if err := json.Unmarshal(jsonResp, &labels); err != nil { 907 t.Fatalf("Unable to parse 'labels' endpoint response: %s\n", jsonResp) 908 } 909 if labels[0] != 1 { 910 t.Errorf("Expected label 1, got label %d\n", labels[0]) 911 } 912 if labels[1] != 2 { 913 t.Errorf("Expected label 2, got label %d\n", labels[1]) 914 } 915 if labels[2] != 2 { 916 t.Errorf("Expected label 2, got label %d\n", labels[2]) 917 } 918 if labels[3] != 4 { 919 t.Errorf("Expected label 4, got label %d\n", labels[3]) 920 } 921 922 apiStr = fmt.Sprintf("%snode/%s/%s/label/59_56_20", server.WebAPIPath, uuid, "labels") 923 jsonResp = server.TestHTTP(t, "GET", apiStr, nil) 924 if err := json.Unmarshal(jsonResp, &jsonVal2); err != nil { 925 t.Errorf("Unable to parse 'label' endpoint response: %s\n", jsonResp) 926 } 927 if jsonVal2.Label != 2 { 928 t.Errorf("Expected label 2, got label %d\n", jsonVal2.Label) 929 } 930 931 retrieved := newTestVolume(128, 128, 128) 932 retrieved.get(t, uuid, "labels", false) 933 if len(retrieved.data) != 8*128*128*128 { 934 t.Errorf("Retrieved labelvol volume is incorrect size\n") 935 } 936 if !retrieved.isLabel(2, &body2) { 937 t.Errorf("Expected label 2 original voxels to remain. Instead some were removed.\n") 938 } 939 if retrieved.hasLabel(3, &body3) { 940 t.Errorf("Found label 3 when all label 3 should have been merged into label 2!\n") 941 } 942 if !retrieved.isLabel(2, &body3) { 943 t.Errorf("Incomplete merging. Label 2 should have taken over full extent of label 3\n") 944 } 945 if err := retrieved.equals(expected); err != nil { 946 t.Errorf("Merged label volume: %v\n", err) 947 } 948 } 949 950 func TestSplitLabel(t *testing.T) { 951 if err := server.OpenTest(); err != nil { 952 t.Fatalf("can't open test server: %v\n", err) 953 } 954 defer server.CloseTest() 955 956 // Create testbed volume and data instances 957 uuid, _ := initTestRepo() 958 var config dvid.Config 959 config.Set("MaxDownresLevel", "2") 960 config.Set("BlockSize", "32,32,32") // Previous test data was on 32^3 blocks 961 server.CreateTestInstance(t, uuid, "labelmap", "labels", config) 962 963 // Post label volume and setup expected volume after split. 964 expected := createLabelTestVolume(t, uuid, "labels") 965 expected.addBody(bodysplit, 5) 966 967 if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil { 968 t.Fatalf("Error blocking on sync of labels: %v\n", err) 969 } 970 971 // Make sure sparsevol for original body 4 is correct 972 reqStr := fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, 4) 973 encoding := server.TestHTTP(t, "GET", reqStr, nil) 974 fmt.Printf("Checking original body 4 is correct\n") 975 body4.checkSparseVol(t, encoding, dvid.OptionalBounds{}) 976 977 // Create the sparsevol encoding for split area 978 numspans := len(bodysplit.voxelSpans) 979 rles := make(dvid.RLEs, numspans, numspans) 980 for i, span := range bodysplit.voxelSpans { 981 start := dvid.Point3d{span[2], span[1], span[0]} 982 length := span[3] - span[2] + 1 983 rles[i] = dvid.NewRLE(start, length) 984 } 985 986 // Create the split sparse volume binary 987 buf := new(bytes.Buffer) 988 buf.WriteByte(dvid.EncodingBinary) 989 binary.Write(buf, binary.LittleEndian, uint8(3)) // # of dimensions 990 binary.Write(buf, binary.LittleEndian, byte(0)) // dimension of run (X = 0) 991 buf.WriteByte(byte(0)) // reserved for later 992 binary.Write(buf, binary.LittleEndian, uint32(0)) // Placeholder for # voxels 993 binary.Write(buf, binary.LittleEndian, uint32(numspans)) // Placeholder for # spans 994 rleBytes, err := rles.MarshalBinary() 995 if err != nil { 996 t.Errorf("Unable to serialize RLEs: %v\n", err) 997 } 998 buf.Write(rleBytes) 999 1000 // Verify the max label is 4 1001 reqStr = fmt.Sprintf("%snode/%s/labels/maxlabel", server.WebAPIPath, uuid) 1002 jsonStr := server.TestHTTP(t, "GET", reqStr, nil) 1003 expectedJSON := `{"maxlabel": 4}` 1004 if string(jsonStr) != expectedJSON { 1005 t.Errorf("Expected this JSON returned from maxlabel:\n%s\nGot:\n%s\n", expectedJSON, string(jsonStr)) 1006 } 1007 1008 // Submit the split sparsevol for body 4 using RLES "bodysplit" 1009 reqStr = fmt.Sprintf("%snode/%s/labels/split/%d", server.WebAPIPath, uuid, 4) 1010 r := server.TestHTTP(t, "POST", reqStr, buf) 1011 jsonVal := make(map[string]uint64) 1012 if err := json.Unmarshal(r, &jsonVal); err != nil { 1013 t.Errorf("Unable to get new label from split. Instead got: %v\n", jsonVal) 1014 } 1015 newlabel, ok := jsonVal["label"] 1016 if !ok { 1017 t.Errorf("The split request did not yield label value. Instead got: %v\n", jsonVal) 1018 } 1019 if newlabel != 5 { 1020 t.Errorf("Expected split label to be 5, instead got %d\n", newlabel) 1021 } 1022 1023 if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil { 1024 t.Fatalf("Error blocking on sync of labels: %v\n", err) 1025 } 1026 1027 retrieved := newTestVolume(128, 128, 128) 1028 retrieved.get(t, uuid, "labels", false) 1029 if len(retrieved.data) != 8*128*128*128 { 1030 t.Errorf("Retrieved post-split volume is incorrect size\n") 1031 } 1032 if err := retrieved.equals(expected); err != nil { 1033 t.Errorf("Split label volume not equal to expected volume: %v\n", err) 1034 } 1035 downres1 := newTestVolume(64, 64, 64) 1036 downres1.getScale(t, uuid, "labels", 1, false) 1037 if err := downres1.equalsDownres(expected); err != nil { 1038 t.Errorf("Split label volume failed level 1 down-scale: %v\n", err) 1039 } 1040 downres2 := newTestVolume(32, 32, 32) 1041 downres2.getScale(t, uuid, "labels", 2, false) 1042 if err := downres2.equalsDownres(downres1); err != nil { 1043 t.Errorf("Split label volume failed level 2 down-scale: %v\n", err) 1044 } 1045 1046 retrieved.get(t, uuid, "labels", true) 1047 downres1.getScale(t, uuid, "labels", 1, true) 1048 if err := downres1.equalsDownres(retrieved); err != nil { 1049 t.Errorf("Split label supervoxel volume failed level 1 down-scale: %v\n", err) 1050 } 1051 downres2.getScale(t, uuid, "labels", 2, true) 1052 if err := downres2.equalsDownres(downres1); err != nil { 1053 t.Errorf("Split label supervoxel volume failed level 2 down-scale: %v\n", err) 1054 } 1055 1056 // Check split body 5 usine legacy RLEs 1057 reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, 5) 1058 encoding = server.TestHTTP(t, "GET", reqStr, nil) 1059 bodysplit.checkSparseVol(t, encoding, dvid.OptionalBounds{}) 1060 1061 reqStr = fmt.Sprintf("%snode/%s/labels/size/5", server.WebAPIPath, uuid) 1062 r = server.TestHTTP(t, "GET", reqStr, nil) 1063 var jsonVal2 struct { 1064 Voxels uint64 `json:"voxels"` 1065 } 1066 if err := json.Unmarshal(r, &jsonVal2); err != nil { 1067 t.Fatalf("unable to get size: %v", err) 1068 } 1069 voxelsIn4 := body4.voxelSpans.Count() 1070 expectedVoxels := bodysplit.voxelSpans.Count() 1071 if jsonVal2.Voxels != expectedVoxels { 1072 t.Errorf("thought split body would have %d voxels, got %d\n", expectedVoxels, jsonVal2.Voxels) 1073 } 1074 dvid.Infof("body split had %d voxels\n", expectedVoxels) 1075 1076 reqStr = fmt.Sprintf("%snode/%s/labels/size/4?supervoxels=true", server.WebAPIPath, uuid) 1077 server.TestBadHTTP(t, "GET", reqStr, nil) 1078 1079 reqStr = fmt.Sprintf("%snode/%s/labels/size/6?supervoxels=true", server.WebAPIPath, uuid) 1080 r = server.TestHTTP(t, "GET", reqStr, nil) 1081 if err := json.Unmarshal(r, &jsonVal2); err != nil { 1082 t.Fatalf("unable to get size for supervoxel 6: %v", err) 1083 } 1084 if jsonVal2.Voxels != expectedVoxels { 1085 t.Errorf("expected split supervoxel to be %d voxels, got %d voxels\n", expectedVoxels, jsonVal2.Voxels) 1086 } 1087 reqStr = fmt.Sprintf("%snode/%s/labels/sizes?supervoxels=true", server.WebAPIPath, uuid) 1088 bodystr := "[4, 6]" 1089 r = server.TestHTTP(t, "GET", reqStr, bytes.NewBufferString(bodystr)) 1090 if string(r) != fmt.Sprintf("[%d,%d]", 0, expectedVoxels) { 1091 t.Errorf("bad batch sizes result. got: %s\n", string(r)) 1092 } 1093 1094 reqStr = fmt.Sprintf("%snode/%s/labels/size/7?supervoxels=true", server.WebAPIPath, uuid) 1095 r = server.TestHTTP(t, "GET", reqStr, nil) 1096 if err := json.Unmarshal(r, &jsonVal2); err != nil { 1097 t.Fatalf("unable to get size for supervoxel 7: %v", err) 1098 } 1099 if jsonVal2.Voxels != voxelsIn4-expectedVoxels { 1100 t.Errorf("thought remnant supervoxel 7 would have %d voxels remaining, got %d\n", voxelsIn4-expectedVoxels, jsonVal2.Voxels) 1101 } 1102 1103 reqStr = fmt.Sprintf("%snode/%s/labels/supervoxel-splits", server.WebAPIPath, uuid) 1104 r = server.TestHTTP(t, "GET", reqStr, nil) 1105 if string(r) != fmt.Sprintf(`["%s",[[%d,4,7,6]]]`, uuid, datastore.InitialMutationID+1) { 1106 t.Fatalf("bad supervoxel-splits JSON return: %s\n", string(r)) 1107 } 1108 1109 // Make sure sparsevol for original body 4 is correct 1110 reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, 4) 1111 encoding = server.TestHTTP(t, "GET", reqStr, nil) 1112 bodyleft.checkSparseVol(t, encoding, dvid.OptionalBounds{}) 1113 1114 // make sure we verified supervoxel list works in /mapping. 1115 reqStr = fmt.Sprintf("%snode/%s/labels/mapping", server.WebAPIPath, uuid) 1116 svlist := "[1, 2, 3, 4, 5, 6, 7, 8, 1000]" 1117 r = server.TestHTTP(t, "GET", reqStr, bytes.NewBufferString(svlist)) 1118 if string(r) != "[1,2,3,0,0,5,4,0,0]" { 1119 t.Errorf("bad verified /mapping result after split. got: %s\n", string(r)) 1120 } 1121 1122 // Do a merge of two after the split 1123 testMerge := mergeJSON(`[4, 5]`) 1124 testMerge.send(t, uuid, "labels") 1125 1126 // Make sure we wind up with original body 4 1127 reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/4", server.WebAPIPath, uuid) 1128 encoding = server.TestHTTP(t, "GET", reqStr, nil) 1129 body4.checkSparseVol(t, encoding, dvid.OptionalBounds{}) 1130 1131 // make sure we verified supervoxel list works in /mapping. 1132 reqStr = fmt.Sprintf("%snode/%s/labels/mapping", server.WebAPIPath, uuid) 1133 r = server.TestHTTP(t, "GET", reqStr, bytes.NewBufferString(svlist)) 1134 if string(r) != "[1,2,3,0,0,4,4,0,0]" { 1135 t.Errorf("bad verified /mapping result after split and merge. got: %s\n", string(r)) 1136 } 1137 } 1138 1139 func getSVMapping(t *testing.T, uuid dvid.UUID, name string, supervoxel uint64) (mappedSV uint64) { 1140 url := fmt.Sprintf("%snode/%s/%s/mapping", server.WebAPIPath, uuid, name) 1141 svlist := fmt.Sprintf("[%d]", supervoxel) 1142 r := server.TestHTTP(t, "GET", url, bytes.NewBufferString(svlist)) 1143 mapResp := []uint64{} 1144 if err := json.Unmarshal(r, &mapResp); err != nil { 1145 t.Fatalf("Unable to get mapping. Instead got: %v, err: %v\n", mapResp, err) 1146 } 1147 if len(mapResp) != 1 { 1148 t.Fatalf("Expected 1 uint64 response from /mapping, got: %v\n", mapResp) 1149 } 1150 return mapResp[0] 1151 } 1152 1153 func getIndex(t *testing.T, uuid dvid.UUID, name string, label uint64) *labels.Index { 1154 url := fmt.Sprintf("http://%snode/%s/%s/index/%d", server.WebAPIPath, uuid, name, label) 1155 data := server.TestHTTP(t, "GET", url, nil) 1156 if len(data) == 0 { 1157 t.Fatalf("Read label index %d returned no bytes\n", label) 1158 } 1159 idx := new(labels.Index) 1160 if err := pb.Unmarshal(data, idx); err != nil { 1161 t.Fatalf("couldn't unmarshal index: %v\n", err) 1162 } 1163 return idx 1164 } 1165 1166 type blockCounts struct { 1167 bcoord dvid.ChunkPoint3d 1168 counts map[uint64]uint32 1169 } 1170 1171 func checkIndex(t *testing.T, desc string, idx *labels.Index, blocks []blockCounts) { 1172 if len(idx.Blocks) != len(blocks) { 1173 t.Fatalf("Expected %d blocks for index %d (%s), got %d blocks: %s\n", len(blocks), idx.Label, desc, len(idx.Blocks), idx.StringDump(false)) 1174 } 1175 seen := make(map[uint64]struct{}) 1176 for _, block := range blocks { 1177 zyx, err := labels.IZYXStringToBlockIndex(block.bcoord.ToIZYXString()) 1178 if err != nil { 1179 t.Fatalf("bad block coord (%s): %s\n", desc, block.bcoord) 1180 } 1181 seen[zyx] = struct{}{} 1182 svc, found := idx.Blocks[zyx] 1183 if !found { 1184 t.Fatalf("expected %s block %s to be in index %d but found none\n", desc, block.bcoord, idx.Label) 1185 } 1186 if len(svc.Counts) != len(block.counts) { 1187 t.Fatalf("expected %s block %s counts %v and got this instead: %v\n", desc, block.bcoord, block.counts, svc.Counts) 1188 } 1189 for supervoxel, count := range block.counts { 1190 actual, found := svc.Counts[supervoxel] 1191 if !found { 1192 t.Fatalf("expected label %d (%s) to have %d voxels, but label not in the retrieved index for block %s\n", supervoxel, desc, count, block.bcoord) 1193 } 1194 if actual != count { 1195 t.Fatalf("expected label %d (%s) to have %d voxels in block %s, but got %d voxels\n", supervoxel, desc, count, block.bcoord, actual) 1196 } 1197 } 1198 } 1199 } 1200 1201 func TestArbitrarySplit(t *testing.T) { 1202 if err := server.OpenTest(); err != nil { 1203 t.Fatalf("can't open test server: %v\n", err) 1204 } 1205 defer server.CloseTest() 1206 1207 uuid, _ := datastore.NewTestRepo() 1208 server.CreateTestInstance(t, uuid, "labelmap", "labels", dvid.Config{}) 1209 1210 labelA := uint64(1000) 1211 labelB := uint64(2000) 1212 1213 data := make([]byte, 128*128*128*8) 1214 var x, y, z int32 1215 for z = 32; z < 96; z++ { 1216 for y = 32; y < 96; y++ { 1217 for x = 32; x < 96; x++ { 1218 i := (z*128*128 + y*128 + x) * 8 1219 binary.LittleEndian.PutUint64(data[i:i+8], labelA) 1220 } 1221 } 1222 } 1223 for z = 32; z < 96; z++ { 1224 for y = 96; y < 112; y++ { 1225 for x = 32; x < 112; x++ { 1226 i := (z*128*128 + y*128 + x) * 8 1227 binary.LittleEndian.PutUint64(data[i:i+8], labelB) 1228 } 1229 } 1230 } 1231 for z = 32; z < 96; z++ { 1232 for y = 32; y < 96; y++ { 1233 for x = 96; x < 112; x++ { 1234 i := (z*128*128 + y*128 + x) * 8 1235 binary.LittleEndian.PutUint64(data[i:i+8], labelB) 1236 } 1237 } 1238 } 1239 1240 apiStr := fmt.Sprintf("%snode/%s/labels/raw/0_1_2/128_128_128/0_0_0", server.WebAPIPath, uuid) 1241 server.TestHTTP(t, "POST", apiStr, bytes.NewBuffer(data)) 1242 if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil { 1243 t.Fatalf("Error blocking on sync of labels: %v\n", err) 1244 } 1245 1246 // Get the original body indices 1247 origIndexA := getIndex(t, uuid, "labels", labelA) 1248 blocksA := []blockCounts{ 1249 { 1250 bcoord: dvid.ChunkPoint3d{0, 0, 0}, 1251 counts: map[uint64]uint32{labelA: 32768}, 1252 }, 1253 { 1254 bcoord: dvid.ChunkPoint3d{1, 0, 0}, 1255 counts: map[uint64]uint32{labelA: 32768}, 1256 }, 1257 { 1258 bcoord: dvid.ChunkPoint3d{0, 1, 0}, 1259 counts: map[uint64]uint32{labelA: 32768}, 1260 }, 1261 { 1262 bcoord: dvid.ChunkPoint3d{1, 1, 0}, 1263 counts: map[uint64]uint32{labelA: 32768}, 1264 }, 1265 { 1266 bcoord: dvid.ChunkPoint3d{0, 0, 1}, 1267 counts: map[uint64]uint32{labelA: 32768}, 1268 }, 1269 { 1270 bcoord: dvid.ChunkPoint3d{1, 0, 1}, 1271 counts: map[uint64]uint32{labelA: 32768}, 1272 }, 1273 { 1274 bcoord: dvid.ChunkPoint3d{0, 1, 1}, 1275 counts: map[uint64]uint32{labelA: 32768}, 1276 }, 1277 { 1278 bcoord: dvid.ChunkPoint3d{1, 1, 1}, 1279 counts: map[uint64]uint32{labelA: 32768}, 1280 }, 1281 } 1282 checkIndex(t, "original index A", origIndexA, blocksA) 1283 1284 origIndexB := getIndex(t, uuid, "labels", labelB) 1285 blocksB := []blockCounts{ 1286 { 1287 bcoord: dvid.ChunkPoint3d{1, 0, 0}, 1288 counts: map[uint64]uint32{labelB: 16384}, 1289 }, 1290 { 1291 bcoord: dvid.ChunkPoint3d{0, 1, 0}, 1292 counts: map[uint64]uint32{labelB: 16384}, 1293 }, 1294 { 1295 bcoord: dvid.ChunkPoint3d{1, 1, 0}, 1296 counts: map[uint64]uint32{labelB: 16384 + 24576}, 1297 }, 1298 { 1299 bcoord: dvid.ChunkPoint3d{1, 0, 1}, 1300 counts: map[uint64]uint32{labelB: 16384}, 1301 }, 1302 { 1303 bcoord: dvid.ChunkPoint3d{0, 1, 1}, 1304 counts: map[uint64]uint32{labelB: 16384}, 1305 }, 1306 { 1307 bcoord: dvid.ChunkPoint3d{1, 1, 1}, 1308 counts: map[uint64]uint32{labelB: 16384 + 24576}, 1309 }, 1310 } 1311 checkIndex(t, "original index B", origIndexB, blocksB) 1312 1313 // merge the two supervoxels into one body 1314 mergeJSON := fmt.Sprintf("[%d,%d]", labelA, labelB) 1315 apiStr = fmt.Sprintf("%snode/%s/labels/merge", server.WebAPIPath, uuid) 1316 server.TestHTTP(t, "POST", apiStr, bytes.NewBufferString(mergeJSON)) 1317 1318 mergeIndex := getIndex(t, uuid, "labels", labelA) 1319 blocksAB := []blockCounts{ 1320 { 1321 bcoord: dvid.ChunkPoint3d{0, 0, 0}, 1322 counts: map[uint64]uint32{labelA: 32768}, 1323 }, 1324 { 1325 bcoord: dvid.ChunkPoint3d{1, 0, 0}, 1326 counts: map[uint64]uint32{labelA: 32768, labelB: 16384}, 1327 }, 1328 { 1329 bcoord: dvid.ChunkPoint3d{0, 1, 0}, 1330 counts: map[uint64]uint32{labelA: 32768, labelB: 16384}, 1331 }, 1332 { 1333 bcoord: dvid.ChunkPoint3d{1, 1, 0}, 1334 counts: map[uint64]uint32{labelA: 32768, labelB: 16384 + 24576}, 1335 }, 1336 { 1337 bcoord: dvid.ChunkPoint3d{0, 0, 1}, 1338 counts: map[uint64]uint32{labelA: 32768}, 1339 }, 1340 { 1341 bcoord: dvid.ChunkPoint3d{1, 0, 1}, 1342 counts: map[uint64]uint32{labelA: 32768, labelB: 16384}, 1343 }, 1344 { 1345 bcoord: dvid.ChunkPoint3d{0, 1, 1}, 1346 counts: map[uint64]uint32{labelA: 32768, labelB: 16384}, 1347 }, 1348 { 1349 bcoord: dvid.ChunkPoint3d{1, 1, 1}, 1350 counts: map[uint64]uint32{labelA: 32768, labelB: 16384 + 24576}, 1351 }, 1352 } 1353 checkIndex(t, "merged index", mergeIndex, blocksAB) 1354 1355 // do a split 1356 var split dvid.RLEs 1357 x = 56 1358 for z = 32; z < 96; z++ { 1359 for y = 32; y < 64; y++ { 1360 split = append(split, dvid.NewRLE(dvid.Point3d{x, y, z}, 40)) 1361 } 1362 } 1363 x = 50 // 10 x 10 x 10 notch in (0, 1, 0) block just in LabelA area 1364 for z = 32; z < 42; z++ { 1365 for y = 64; y < 74; y++ { 1366 split = append(split, dvid.NewRLE(dvid.Point3d{x, y, z}, 10)) 1367 } 1368 } 1369 x = 80 1370 for z = 32; z < 48; z++ { 1371 for y = 64; y < 100; y++ { 1372 split = append(split, dvid.NewRLE(dvid.Point3d{x, y, z}, 8)) 1373 } 1374 } 1375 splitVoxels, splitRuns := split.Stats() 1376 dvid.Infof("split has %d voxels, %d runs\n", splitVoxels, splitRuns) 1377 1378 buf := new(bytes.Buffer) 1379 buf.WriteByte(dvid.EncodingBinary) 1380 binary.Write(buf, binary.LittleEndian, uint8(3)) // # of dimensions 1381 binary.Write(buf, binary.LittleEndian, byte(0)) // dimension of run (X = 0) 1382 buf.WriteByte(byte(0)) // reserved for later 1383 binary.Write(buf, binary.LittleEndian, uint32(0)) // Placeholder for # voxels 1384 binary.Write(buf, binary.LittleEndian, uint32(splitRuns)) // Placeholder for # spans 1385 splitBytes, err := split.MarshalBinary() 1386 if err != nil { 1387 t.Errorf("Unable to serialize RLEs: %v\n", err) 1388 } 1389 buf.Write(splitBytes) 1390 1391 apiStr = fmt.Sprintf("%snode/%s/labels/split/%d", server.WebAPIPath, uuid, labelA) 1392 r := server.TestHTTP(t, "POST", apiStr, buf) 1393 var splitResp struct { 1394 Label uint64 `json:"label"` 1395 } 1396 if err := json.Unmarshal(r, &splitResp); err != nil { 1397 t.Errorf("Unable to get new label from split. Instead got: %v\n", splitResp) 1398 } 1399 dvid.Infof("Test split produced new label %d\n", splitResp.Label) 1400 1401 splitIndex := getIndex(t, uuid, "labels", splitResp.Label) 1402 remainIndex := getIndex(t, uuid, "labels", labelA) 1403 1404 zyx110, _ := labels.IZYXStringToBlockIndex(dvid.ChunkPoint3d{1, 1, 0}.ToIZYXString()) 1405 svc, found := splitIndex.Blocks[zyx110] 1406 if !found { 1407 t.Fatalf("expected split index block (1,1,0) but not found\n") 1408 } 1409 if len(svc.Counts) != 2 { 1410 t.Fatalf("expected two supervoxels in split block (1,1,0), got: %v\n", svc.Counts) 1411 } 1412 var labelSplitA, labelSplitB, labelRemainA, labelRemainB uint64 1413 for label, count := range svc.Counts { 1414 switch count { 1415 case 512: 1416 labelSplitB = label 1417 case 4096: 1418 labelSplitA = label 1419 default: 1420 t.Fatalf("bad split block (1,1,0): %v\n", svc.Counts) 1421 } 1422 } 1423 svc, found = remainIndex.Blocks[zyx110] 1424 if !found { 1425 t.Fatalf("expected remain index block (1,1,0) but not found\n") 1426 } 1427 if len(svc.Counts) != 2 { 1428 t.Fatalf("expected two supervoxels in remain block (1,1,0), got: %v\n", svc.Counts) 1429 } 1430 for label, count := range svc.Counts { 1431 switch count { 1432 case 16384 + 24576 - 512: 1433 labelRemainB = label 1434 case 32768 - 4096: 1435 labelRemainA = label 1436 default: 1437 t.Fatalf("bad remain block (1,1,0): %v\n", svc.Counts) 1438 } 1439 } 1440 dvid.Infof("Supervoxel %d -> split %d, remain %d\n", labelA, labelSplitA, labelRemainA) 1441 dvid.Infof("Supervoxel %d -> split %d, remain %d\n", labelB, labelSplitB, labelRemainB) 1442 1443 blocksSplit := []blockCounts{ 1444 { 1445 bcoord: dvid.ChunkPoint3d{0, 0, 0}, 1446 counts: map[uint64]uint32{labelSplitA: 8192}, 1447 }, 1448 { 1449 bcoord: dvid.ChunkPoint3d{1, 0, 0}, 1450 counts: map[uint64]uint32{labelSplitA: 32768}, 1451 }, 1452 { 1453 bcoord: dvid.ChunkPoint3d{0, 1, 0}, 1454 counts: map[uint64]uint32{labelSplitA: 1000}, 1455 }, 1456 { 1457 bcoord: dvid.ChunkPoint3d{1, 1, 0}, 1458 counts: map[uint64]uint32{labelSplitA: 4096, labelSplitB: 512}, 1459 }, 1460 { 1461 bcoord: dvid.ChunkPoint3d{0, 0, 1}, 1462 counts: map[uint64]uint32{labelSplitA: 8192}, 1463 }, 1464 { 1465 bcoord: dvid.ChunkPoint3d{1, 0, 1}, 1466 counts: map[uint64]uint32{labelSplitA: 32768}, 1467 }, 1468 } 1469 checkIndex(t, "split index", splitIndex, blocksSplit) 1470 1471 blocksRemain := []blockCounts{ 1472 { 1473 bcoord: dvid.ChunkPoint3d{0, 0, 0}, 1474 counts: map[uint64]uint32{labelRemainA: 32768 - 8192}, 1475 }, 1476 { 1477 bcoord: dvid.ChunkPoint3d{1, 0, 0}, 1478 counts: map[uint64]uint32{labelRemainB: 16384}, 1479 }, 1480 { 1481 bcoord: dvid.ChunkPoint3d{0, 1, 0}, 1482 counts: map[uint64]uint32{labelRemainA: 31768, labelRemainB: 16384}, 1483 }, 1484 { 1485 bcoord: dvid.ChunkPoint3d{1, 1, 0}, 1486 counts: map[uint64]uint32{labelRemainA: 32768 - 4096, labelRemainB: 16384 + 24576 - 512}, 1487 }, 1488 { 1489 bcoord: dvid.ChunkPoint3d{0, 0, 1}, 1490 counts: map[uint64]uint32{labelRemainA: 32768 - 8192}, 1491 }, 1492 { 1493 bcoord: dvid.ChunkPoint3d{1, 0, 1}, 1494 counts: map[uint64]uint32{labelRemainB: 16384}, 1495 }, 1496 { 1497 bcoord: dvid.ChunkPoint3d{0, 1, 1}, 1498 counts: map[uint64]uint32{labelRemainA: 32768, labelRemainB: 16384}, 1499 }, 1500 { 1501 bcoord: dvid.ChunkPoint3d{1, 1, 1}, 1502 counts: map[uint64]uint32{labelRemainA: 32768, labelRemainB: 16384 + 24576}, 1503 }, 1504 } 1505 checkIndex(t, "remain index", remainIndex, blocksRemain) 1506 1507 blocks := testGetVolumeBlocks(t, uuid, "labels", true, dvid.Point3d{128, 128, 128}, dvid.Point3d{0, 0, 0}) 1508 checkVoxels(t, blocks, blocksSplit, blocksRemain) 1509 } 1510 1511 func checkVoxels(t *testing.T, blocks []labels.PositionedBlock, blocksSplit, blocksRemain []blockCounts) { 1512 expected := make(map[uint64]map[uint64]int32) 1513 for _, blockSplit := range blocksSplit { 1514 zyx, _ := labels.IZYXStringToBlockIndex(blockSplit.bcoord.ToIZYXString()) 1515 counts, found := expected[zyx] 1516 if !found { 1517 counts = make(map[uint64]int32) 1518 } 1519 for sv, count := range blockSplit.counts { 1520 counts[sv] = int32(count) 1521 } 1522 expected[zyx] = counts 1523 } 1524 for _, blockRemain := range blocksRemain { 1525 zyx, _ := labels.IZYXStringToBlockIndex(blockRemain.bcoord.ToIZYXString()) 1526 counts, found := expected[zyx] 1527 if !found { 1528 counts = make(map[uint64]int32) 1529 } 1530 for sv, count := range blockRemain.counts { 1531 counts[sv] = int32(count) 1532 } 1533 expected[zyx] = counts 1534 } 1535 actual := make(map[uint64]map[uint64]int32) 1536 for _, block := range blocks { 1537 zyx, _ := labels.IZYXStringToBlockIndex(block.BCoord) 1538 got := block.CalcNumLabels(nil) 1539 actual[zyx] = got 1540 want, found := expected[zyx] 1541 if !found { 1542 t.Fatalf("Received block %s but wasn't expected block\n", block.BCoord) 1543 } 1544 for sv, count := range got { 1545 wantcount, found := want[sv] 1546 if !found { 1547 t.Fatalf("got supervoxel %d in block %s but not expected\n", sv, block.BCoord) 1548 } 1549 if wantcount != count { 1550 t.Fatalf("expected supervoxel %d to have %d voxels in block %s, got %d\n", sv, wantcount, block.BCoord, count) 1551 } 1552 } 1553 } 1554 for zyx, counts := range expected { 1555 bcoord := labels.BlockIndexToIZYXString(zyx) 1556 got, found := actual[zyx] 1557 if !found { 1558 t.Fatalf("Expected to get block %s but not found\n", bcoord) 1559 } 1560 for sv, count := range counts { 1561 gotcount, found := got[sv] 1562 if !found { 1563 t.Fatalf("expected supervoxel %d in block %s but not received\n", sv, bcoord) 1564 } 1565 if gotcount != count { 1566 t.Fatalf("expected supervoxel %d to have %d voxels in block %s, got %d\n", sv, count, bcoord, gotcount) 1567 } 1568 } 1569 } 1570 } 1571 1572 func TestSupervoxelSplit2(t *testing.T) { 1573 if err := server.OpenTest(); err != nil { 1574 t.Fatalf("can't open test server: %v\n", err) 1575 } 1576 defer server.CloseTest() 1577 1578 uuid, _ := datastore.NewTestRepo() 1579 server.CreateTestInstance(t, uuid, "labelmap", "labels", dvid.Config{}) 1580 1581 labelA := uint64(1000) 1582 labelB := uint64(2000) 1583 1584 data := make([]byte, 128*128*128*8) 1585 var x, y, z int32 1586 for z = 32; z < 96; z++ { 1587 for y = 32; y < 96; y++ { 1588 for x = 32; x < 96; x++ { 1589 i := (z*128*128 + y*128 + x) * 8 1590 binary.LittleEndian.PutUint64(data[i:i+8], labelA) 1591 } 1592 } 1593 } 1594 for z = 32; z < 96; z++ { 1595 for y = 96; y < 112; y++ { 1596 for x = 32; x < 112; x++ { 1597 i := (z*128*128 + y*128 + x) * 8 1598 binary.LittleEndian.PutUint64(data[i:i+8], labelB) 1599 } 1600 } 1601 } 1602 for z = 32; z < 96; z++ { 1603 for y = 32; y < 96; y++ { 1604 for x = 96; x < 112; x++ { 1605 i := (z*128*128 + y*128 + x) * 8 1606 binary.LittleEndian.PutUint64(data[i:i+8], labelB) 1607 } 1608 } 1609 } 1610 origdata := make([]byte, 128*128*128*8) 1611 copy(origdata, data) 1612 1613 apiStr := fmt.Sprintf("%snode/%s/labels/raw/0_1_2/128_128_128/0_0_0", server.WebAPIPath, uuid) 1614 server.TestHTTP(t, "POST", apiStr, bytes.NewBuffer(data)) 1615 if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil { 1616 t.Fatalf("Error blocking on sync of labels: %v\n", err) 1617 } 1618 1619 // Get the original body indices 1620 origIndexB := getIndex(t, uuid, "labels", labelB) 1621 blocksB := []blockCounts{ 1622 { 1623 bcoord: dvid.ChunkPoint3d{1, 0, 0}, 1624 counts: map[uint64]uint32{labelB: 16384}, 1625 }, 1626 { 1627 bcoord: dvid.ChunkPoint3d{0, 1, 0}, 1628 counts: map[uint64]uint32{labelB: 16384}, 1629 }, 1630 { 1631 bcoord: dvid.ChunkPoint3d{1, 1, 0}, 1632 counts: map[uint64]uint32{labelB: 16384 + 24576}, 1633 }, 1634 { 1635 bcoord: dvid.ChunkPoint3d{1, 0, 1}, 1636 counts: map[uint64]uint32{labelB: 16384}, 1637 }, 1638 { 1639 bcoord: dvid.ChunkPoint3d{0, 1, 1}, 1640 counts: map[uint64]uint32{labelB: 16384}, 1641 }, 1642 { 1643 bcoord: dvid.ChunkPoint3d{1, 1, 1}, 1644 counts: map[uint64]uint32{labelB: 16384 + 24576}, 1645 }, 1646 } 1647 checkIndex(t, "original index B", origIndexB, blocksB) 1648 1649 // do a bad split 1650 var split dvid.RLEs 1651 x = 56 1652 for z = 32; z < 96; z++ { 1653 for y = 32; y < 64; y++ { 1654 split = append(split, dvid.NewRLE(dvid.Point3d{x, y, z}, 40)) 1655 } 1656 } 1657 x = 80 1658 for z = 32; z < 48; z++ { 1659 for y = 64; y < 100; y++ { 1660 split = append(split, dvid.NewRLE(dvid.Point3d{x, y, z}, 8)) 1661 } 1662 } 1663 _, splitRuns := split.Stats() 1664 1665 buf := new(bytes.Buffer) 1666 buf.WriteByte(dvid.EncodingBinary) 1667 binary.Write(buf, binary.LittleEndian, uint8(3)) // # of dimensions 1668 binary.Write(buf, binary.LittleEndian, byte(0)) // dimension of run (X = 0) 1669 buf.WriteByte(byte(0)) // reserved for later 1670 binary.Write(buf, binary.LittleEndian, uint32(0)) // Placeholder for # voxels 1671 binary.Write(buf, binary.LittleEndian, uint32(splitRuns)) // Placeholder for # spans 1672 splitBytes, err := split.MarshalBinary() 1673 if err != nil { 1674 t.Errorf("Unable to serialize RLEs: %v\n", err) 1675 } 1676 buf.Write(splitBytes) 1677 1678 apiStr = fmt.Sprintf("%snode/%s/labels/split-supervoxel/%d?split=189417&remain=8506273", server.WebAPIPath, uuid, labelB) 1679 server.TestBadHTTP(t, "POST", apiStr, buf) 1680 1681 // make sure indices and volume is not changed 1682 afterBadSplit := getIndex(t, uuid, "labels", labelB) 1683 checkIndex(t, "label B after bad split", afterBadSplit, blocksB) 1684 1685 postvol := newTestVolume(128, 128, 128) 1686 postvol.get(t, uuid, "labels", true) 1687 oldvol := testVolume{ 1688 data: origdata, 1689 size: dvid.Point3d{128, 128, 128}, 1690 } 1691 if err := oldvol.equals(postvol); err != nil { 1692 t.Fatalf("bad supervoxel volume get after aborted supervoxel split: %v\n", err) 1693 } 1694 postvol.get(t, uuid, "labels", false) 1695 if err := oldvol.equals(postvol); err != nil { 1696 t.Fatalf("bad label volume get after aborted supervoxel split: %v\n", err) 1697 } 1698 1699 // run valid split 1700 split = nil 1701 x = 96 1702 for z = 32; z < 96; z++ { 1703 for y = 32; y < 96; y++ { 1704 split = append(split, dvid.NewRLE(dvid.Point3d{x, y, z}, 16)) 1705 } 1706 } 1707 _, splitRuns = split.Stats() 1708 1709 buf = new(bytes.Buffer) 1710 buf.WriteByte(dvid.EncodingBinary) 1711 binary.Write(buf, binary.LittleEndian, uint8(3)) // # of dimensions 1712 binary.Write(buf, binary.LittleEndian, byte(0)) // dimension of run (X = 0) 1713 buf.WriteByte(byte(0)) // reserved for later 1714 binary.Write(buf, binary.LittleEndian, uint32(0)) // Placeholder for # voxels 1715 binary.Write(buf, binary.LittleEndian, uint32(splitRuns)) // Placeholder for # spans 1716 splitBytes, err = split.MarshalBinary() 1717 if err != nil { 1718 t.Errorf("Unable to serialize RLEs: %v\n", err) 1719 } 1720 buf.Write(splitBytes) 1721 1722 r := server.TestHTTP(t, "POST", apiStr, buf) 1723 var resp struct { 1724 Split uint64 `json:"SplitSupervoxel"` 1725 Remain uint64 `json:"RemainSupervoxel"` 1726 } 1727 if err := json.Unmarshal(r, &resp); err != nil { 1728 t.Errorf("Unable to get new labels from supervoxel split. Instead got: %v\n", resp) 1729 } 1730 dvid.Infof("supervoxel split %d -> split %d, remain %d\n", labelB, resp.Split, resp.Remain) 1731 if resp.Split != 189417 || resp.Remain != 8506273 { 1732 t.Errorf("bad split/remain supervoxel labels: %v\n", resp) 1733 } 1734 1735 // label B index shouldn't have changed 1736 splitIndexB := getIndex(t, uuid, "labels", labelB) 1737 blocksSplitB := []blockCounts{ 1738 { 1739 bcoord: dvid.ChunkPoint3d{1, 0, 0}, 1740 counts: map[uint64]uint32{resp.Split: 16384}, 1741 }, 1742 { 1743 bcoord: dvid.ChunkPoint3d{0, 1, 0}, 1744 counts: map[uint64]uint32{resp.Remain: 16384}, 1745 }, 1746 { 1747 bcoord: dvid.ChunkPoint3d{1, 1, 0}, 1748 counts: map[uint64]uint32{resp.Split: 16384, resp.Remain: 24576}, 1749 }, 1750 { 1751 bcoord: dvid.ChunkPoint3d{1, 0, 1}, 1752 counts: map[uint64]uint32{resp.Split: 16384}, 1753 }, 1754 { 1755 bcoord: dvid.ChunkPoint3d{0, 1, 1}, 1756 counts: map[uint64]uint32{resp.Remain: 16384}, 1757 }, 1758 { 1759 bcoord: dvid.ChunkPoint3d{1, 1, 1}, 1760 counts: map[uint64]uint32{resp.Split: 16384, resp.Remain: 24576}, 1761 }, 1762 } 1763 checkIndex(t, "split index B", splitIndexB, blocksSplitB) 1764 1765 // supervoxels should have changed 1766 blocksA := []blockCounts{ 1767 { 1768 bcoord: dvid.ChunkPoint3d{0, 0, 0}, 1769 counts: map[uint64]uint32{labelA: 32768}, 1770 }, 1771 { 1772 bcoord: dvid.ChunkPoint3d{1, 0, 0}, 1773 counts: map[uint64]uint32{labelA: 32768}, 1774 }, 1775 { 1776 bcoord: dvid.ChunkPoint3d{0, 1, 0}, 1777 counts: map[uint64]uint32{labelA: 32768}, 1778 }, 1779 { 1780 bcoord: dvid.ChunkPoint3d{1, 1, 0}, 1781 counts: map[uint64]uint32{labelA: 32768}, 1782 }, 1783 { 1784 bcoord: dvid.ChunkPoint3d{0, 0, 1}, 1785 counts: map[uint64]uint32{labelA: 32768}, 1786 }, 1787 { 1788 bcoord: dvid.ChunkPoint3d{1, 0, 1}, 1789 counts: map[uint64]uint32{labelA: 32768}, 1790 }, 1791 { 1792 bcoord: dvid.ChunkPoint3d{0, 1, 1}, 1793 counts: map[uint64]uint32{labelA: 32768}, 1794 }, 1795 { 1796 bcoord: dvid.ChunkPoint3d{1, 1, 1}, 1797 counts: map[uint64]uint32{labelA: 32768}, 1798 }, 1799 } 1800 blocks := testGetVolumeBlocks(t, uuid, "labels", true, dvid.Point3d{128, 128, 128}, dvid.Point3d{0, 0, 0}) 1801 checkVoxels(t, blocks, blocksSplitB, blocksA) 1802 } 1803 1804 func testSplitSupervoxel(t *testing.T, testEnclosing bool) { 1805 if err := server.OpenTest(); err != nil { 1806 t.Fatalf("can't open test server: %v\n", err) 1807 } 1808 defer server.CloseTest() 1809 1810 // Create testbed volume and data instances 1811 uuid, _ := initTestRepo() 1812 var config dvid.Config 1813 config.Set("MaxDownresLevel", "2") 1814 config.Set("BlockSize", "32,32,32") // Previous test data was on 32^3 blocks 1815 server.CreateTestInstance(t, uuid, "labelmap", "labels", config) 1816 1817 // Post supervoxel volume 1818 original := createLabelTestVolume(t, uuid, "labels") 1819 if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil { 1820 t.Fatalf("Error blocking on sync of labels: %v\n", err) 1821 } 1822 1823 reqStr := fmt.Sprintf("%snode/%s/labels/sparsevol/4", server.WebAPIPath, uuid) 1824 encoding := server.TestHTTP(t, "GET", reqStr, nil) 1825 body4.checkSparseVol(t, encoding, dvid.OptionalBounds{}) 1826 1827 if testEnclosing { 1828 testMerge := mergeJSON(`[3, 4]`) 1829 testMerge.send(t, uuid, "labels") 1830 1831 reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/3", server.WebAPIPath, uuid) 1832 encoding = server.TestHTTP(t, "GET", reqStr, nil) 1833 } 1834 1835 // Create the sparsevol encoding for split area 1836 numspans := len(bodysplit.voxelSpans) 1837 rles := make(dvid.RLEs, numspans, numspans) 1838 for i, span := range bodysplit.voxelSpans { 1839 start := dvid.Point3d{span[2], span[1], span[0]} 1840 length := span[3] - span[2] + 1 1841 rles[i] = dvid.NewRLE(start, length) 1842 } 1843 1844 // Create the split sparse volume binary 1845 buf := new(bytes.Buffer) 1846 buf.WriteByte(dvid.EncodingBinary) 1847 binary.Write(buf, binary.LittleEndian, uint8(3)) // # of dimensions 1848 binary.Write(buf, binary.LittleEndian, byte(0)) // dimension of run (X = 0) 1849 buf.WriteByte(byte(0)) // reserved for later 1850 binary.Write(buf, binary.LittleEndian, uint32(0)) // Placeholder for # voxels 1851 binary.Write(buf, binary.LittleEndian, uint32(numspans)) // Placeholder for # spans 1852 rleBytes, err := rles.MarshalBinary() 1853 if err != nil { 1854 t.Errorf("Unable to serialize RLEs: %v\n", err) 1855 } 1856 buf.Write(rleBytes) 1857 1858 // Verify the max label is 4 1859 reqStr = fmt.Sprintf("%snode/%s/labels/maxlabel", server.WebAPIPath, uuid) 1860 jsonStr := server.TestHTTP(t, "GET", reqStr, nil) 1861 expectedJSON := `{"maxlabel": 4}` 1862 if string(jsonStr) != expectedJSON { 1863 t.Errorf("Expected this JSON returned from maxlabel:\n%s\nGot:\n%s\n", expectedJSON, string(jsonStr)) 1864 } 1865 1866 // Submit the split sparsevol for supervoxel 4 using RLES "bodysplit" 1867 reqStr = fmt.Sprintf("%snode/%s/labels/split-supervoxel/4", server.WebAPIPath, uuid) 1868 r := server.TestHTTP(t, "POST", reqStr, buf) 1869 var jsonVal struct { 1870 SplitSupervoxel uint64 1871 RemainSupervoxel uint64 1872 } 1873 if err := json.Unmarshal(r, &jsonVal); err != nil { 1874 t.Errorf("Unable to get new label from split. Instead got: %v\n", jsonVal) 1875 } 1876 if jsonVal.SplitSupervoxel != 5 { 1877 t.Errorf("Expected split label to be 5, instead got %d\n", jsonVal.SplitSupervoxel) 1878 } 1879 if jsonVal.RemainSupervoxel != 6 { 1880 t.Errorf("Expected remain label to be 6, instead got %d\n", jsonVal.RemainSupervoxel) 1881 } 1882 reqStr = fmt.Sprintf("%snode/%s/labels/maxlabel", server.WebAPIPath, uuid) 1883 jsonStr = server.TestHTTP(t, "GET", reqStr, nil) 1884 expectedJSON = `{"maxlabel": 6}` 1885 if string(jsonStr) != expectedJSON { 1886 t.Errorf("Expected this JSON returned from maxlabel:\n%s\nGot:\n%s\n", expectedJSON, string(jsonStr)) 1887 } 1888 1889 if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil { 1890 t.Fatalf("Error blocking on sync of labels: %v\n", err) 1891 } 1892 1893 // Make sure retrieved body voxels are same as original 1894 retrieved := newTestVolume(128, 128, 128) 1895 retrieved.get(t, uuid, "labels", false) 1896 if len(retrieved.data) != 8*128*128*128 { 1897 t.Errorf("Retrieved post-split volume is incorrect size\n") 1898 } 1899 if testEnclosing { 1900 original.addBody(body4, 3) 1901 } 1902 if err := original.equals(retrieved); err != nil { 1903 t.Errorf("Post-supervoxel split label volume not equal to expected volume: %v\n", err) 1904 } 1905 downres1 := newTestVolume(64, 64, 64) 1906 downres1.getScale(t, uuid, "labels", 1, false) 1907 if err := downres1.equalsDownres(original); err != nil { 1908 t.Errorf("split supervoxel volume failed level 1 down-scale: %v\n", err) 1909 } 1910 downres2 := newTestVolume(32, 32, 32) 1911 downres2.getScale(t, uuid, "labels", 2, false) 1912 if err := downres2.equalsDownres(downres1); err != nil { 1913 t.Errorf("split supervoxel volume failed level 2 down-scale: %v\n", err) 1914 } 1915 1916 // Make sure retrieved supervoxels are correct 1917 retrieved.get(t, uuid, "labels", true) 1918 if testEnclosing { 1919 original.addBody(body4, 4) 1920 } 1921 original.addBody(bodysplit, 5) 1922 original.addBody(bodyleft, 6) 1923 if err := original.equals(retrieved); err != nil { 1924 t.Errorf("Post-supervoxel split supervoxel volume not equal to expected supervoxels: %v\n", err) 1925 } 1926 1927 // Check split body hasn't changed usine legacy RLEs 1928 if testEnclosing { 1929 reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/3", server.WebAPIPath, uuid) 1930 } else { 1931 reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/4", server.WebAPIPath, uuid) 1932 } 1933 splitBody := server.TestHTTP(t, "GET", reqStr, nil) 1934 if !bytes.Equal(splitBody, encoding) { 1935 t.Errorf("split body after supervoxel split has changed incorrectly!\n") 1936 } 1937 } 1938 1939 func TestSplitSupervoxel(t *testing.T) { 1940 dvid.Infof("Testing non-agglomerated supervoxel...\n") 1941 testSplitSupervoxel(t, false) 1942 dvid.Infof("Testing agglomerated supervoxel...\n") 1943 testSplitSupervoxel(t, true) 1944 } 1945 1946 func TestCompleteSplitSupervoxel(t *testing.T) { 1947 if err := server.OpenTest(); err != nil { 1948 t.Fatalf("can't open test server: %v\n", err) 1949 } 1950 defer server.CloseTest() 1951 1952 // Create testbed volume and data instances 1953 uuid, _ := initTestRepo() 1954 var config dvid.Config 1955 config.Set("BlockSize", "32,32,32") // Previous test data was on 32^3 blocks 1956 server.CreateTestInstance(t, uuid, "labelmap", "labels", config) 1957 1958 // Post supervoxel volume 1959 original := createLabelTestVolume(t, uuid, "labels") 1960 if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil { 1961 t.Fatalf("Error blocking on sync of labels: %v\n", err) 1962 } 1963 1964 reqStr := fmt.Sprintf("%snode/%s/labels/sparsevol/4", server.WebAPIPath, uuid) 1965 encoding := server.TestHTTP(t, "GET", reqStr, nil) 1966 body4.checkSparseVol(t, encoding, dvid.OptionalBounds{}) 1967 1968 // Create the sparsevol encoding for split area 1969 numspans := len(body4.voxelSpans) 1970 rles := make(dvid.RLEs, numspans, numspans) 1971 for i, span := range body4.voxelSpans { 1972 start := dvid.Point3d{span[2], span[1], span[0]} 1973 length := span[3] - span[2] + 1 1974 rles[i] = dvid.NewRLE(start, length) 1975 } 1976 1977 // Create the split sparse volume binary 1978 buf := new(bytes.Buffer) 1979 buf.WriteByte(dvid.EncodingBinary) 1980 binary.Write(buf, binary.LittleEndian, uint8(3)) // # of dimensions 1981 binary.Write(buf, binary.LittleEndian, byte(0)) // dimension of run (X = 0) 1982 buf.WriteByte(byte(0)) // reserved for later 1983 binary.Write(buf, binary.LittleEndian, uint32(0)) // Placeholder for # voxels 1984 binary.Write(buf, binary.LittleEndian, uint32(numspans)) // Placeholder for # spans 1985 rleBytes, err := rles.MarshalBinary() 1986 if err != nil { 1987 t.Errorf("Unable to serialize RLEs: %v\n", err) 1988 } 1989 buf.Write(rleBytes) 1990 1991 // Before split, the supervoxel should be mapped to itself. 1992 mappedSV := getSVMapping(t, uuid, "labels", 4) 1993 if mappedSV != 4 { 1994 t.Fatalf("Expected supervoxel 4 to be mapped to itself before split. Got %d instead.\n", mappedSV) 1995 } 1996 1997 // Submit the split sparsevol for supervoxel 4 using its entire body 1998 reqStr = fmt.Sprintf("%snode/%s/labels/split-supervoxel/4", server.WebAPIPath, uuid) 1999 r := server.TestHTTP(t, "POST", reqStr, buf) 2000 var jsonVal struct { 2001 SplitSupervoxel uint64 2002 RemainSupervoxel uint64 2003 } 2004 if err := json.Unmarshal(r, &jsonVal); err != nil { 2005 t.Errorf("Unable to get new label from split. Instead got: %v\n", jsonVal) 2006 } 2007 if jsonVal.SplitSupervoxel != 5 { 2008 t.Errorf("Expected split label to be 5, instead got %d\n", jsonVal.SplitSupervoxel) 2009 } 2010 if jsonVal.RemainSupervoxel != 6 { 2011 t.Errorf("Expected remain label to be 6, instead got %d\n", jsonVal.RemainSupervoxel) 2012 } 2013 if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil { 2014 t.Fatalf("Error blocking on sync of labels: %v\n", err) 2015 } 2016 2017 // Make sure the split supervoxel is now mapped to 0. 2018 mappedSV = getSVMapping(t, uuid, "labels", 4) 2019 if mappedSV != 0 { 2020 t.Fatalf("Expected supervoxel 4 to map to 0 after split. Got %d instead.\n", mappedSV) 2021 } 2022 2023 // Make sure retrieved body voxels are same as original 2024 retrieved := newTestVolume(128, 128, 128) 2025 retrieved.get(t, uuid, "labels", false) 2026 if len(retrieved.data) != 8*128*128*128 { 2027 t.Errorf("Retrieved post-split volume is incorrect size\n") 2028 } 2029 if err := original.equals(retrieved); err != nil { 2030 t.Errorf("Post-supervoxel split label volume not equal to expected volume: %v\n", err) 2031 } 2032 2033 // Submit the split sparsevol for supervoxel 4 using no RLEs 2034 buf = new(bytes.Buffer) 2035 buf.WriteByte(dvid.EncodingBinary) 2036 binary.Write(buf, binary.LittleEndian, uint8(3)) // # of dimensions 2037 binary.Write(buf, binary.LittleEndian, byte(0)) // dimension of run (X = 0) 2038 buf.WriteByte(byte(0)) // reserved for later 2039 binary.Write(buf, binary.LittleEndian, uint32(0)) // Placeholder for # voxels 2040 binary.Write(buf, binary.LittleEndian, uint32(0)) // Placeholder for # spans 2041 2042 reqStr = fmt.Sprintf("%snode/%s/labels/split-supervoxel/5", server.WebAPIPath, uuid) 2043 r = server.TestHTTP(t, "POST", reqStr, buf) 2044 if err := json.Unmarshal(r, &jsonVal); err != nil { 2045 t.Errorf("Unable to get new label from split. Instead got: %v\n", jsonVal) 2046 } 2047 if jsonVal.SplitSupervoxel != 7 { 2048 t.Errorf("Expected split label to be 5, instead got %d\n", jsonVal.SplitSupervoxel) 2049 } 2050 if jsonVal.RemainSupervoxel != 8 { 2051 t.Errorf("Expected remain label to be 6, instead got %d\n", jsonVal.RemainSupervoxel) 2052 } 2053 if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil { 2054 t.Fatalf("Error blocking on sync of labels: %v\n", err) 2055 } 2056 2057 // Make sure retrieved body voxels are same as original 2058 retrieved = newTestVolume(128, 128, 128) 2059 retrieved.get(t, uuid, "labels", false) 2060 if len(retrieved.data) != 8*128*128*128 { 2061 t.Errorf("Retrieved post-split volume is incorrect size\n") 2062 } 2063 if err := original.equals(retrieved); err != nil { 2064 t.Errorf("Post-supervoxel split label volume not equal to expected volume: %v\n", err) 2065 } 2066 } 2067 2068 type labelType interface { 2069 GetLabelPoints(dvid.VersionID, []dvid.Point3d, uint8, bool) ([]uint64, error) 2070 GetPointsInSupervoxels(dvid.VersionID, []dvid.Point3d, []uint64) ([]bool, error) 2071 } 2072 2073 func TestMergeCleave(t *testing.T) { 2074 if err := server.OpenTest(); err != nil { 2075 t.Fatalf("can't open test server: %v\n", err) 2076 } 2077 defer server.CloseTest() 2078 2079 // Create testbed volume and data instances 2080 uuid, _ := initTestRepo() 2081 var config dvid.Config 2082 config.Set("BlockSize", "32,32,32") // Previous test data was on 32^3 blocks 2083 server.CreateTestInstance(t, uuid, "labelmap", "labels", config) 2084 2085 // Post standard label 1-4 volume 2086 expected := createLabelTestVolume(t, uuid, "labels") 2087 2088 if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil { 2089 t.Fatalf("Error blocking on sync of labels: %v\n", err) 2090 } 2091 2092 reqStr := fmt.Sprintf("%snode/%s/labels/sparsevol/4", server.WebAPIPath, uuid) 2093 sv4encoding := server.TestHTTP(t, "GET", reqStr, nil) 2094 body4.checkSparseVol(t, sv4encoding, dvid.OptionalBounds{}) 2095 2096 // Check direct label queries for points 2097 pts := []dvid.Point3d{ 2098 {25, 40, 15}, // body 1 2099 {15, 57, 34}, 2100 {30, 27, 57}, // body 2 2101 {63, 39, 45}, 2102 {59, 56, 39}, // body 3 2103 {75, 40, 73}, // body 4 2104 } 2105 d, err := datastore.GetDataByUUIDName(uuid, "labels") 2106 if err != nil { 2107 t.Fatalf("Can't get labels instance from test db: %v\n", err) 2108 } 2109 labeldata, ok := d.(labelType) 2110 if !ok { 2111 t.Fatalf("Didn't get labels data that conforms to expected functions.\n") 2112 } 2113 v, err := datastore.VersionFromUUID(uuid) 2114 if err != nil { 2115 t.Fatalf("couldn't get version from UUID\n") 2116 } 2117 mapped, err := labeldata.GetLabelPoints(v, pts, 0, false) 2118 if err != nil { 2119 t.Errorf("bad response to GetLabelsPoints: %v\n", err) 2120 } 2121 if len(mapped) != 6 || !reflect.DeepEqual(mapped, []uint64{1, 1, 2, 2, 3, 4}) { 2122 t.Fatalf("bad return from GetLabelPoints: %v\n", mapped) 2123 } 2124 inSupervoxels, err := labeldata.GetPointsInSupervoxels(v, pts, []uint64{1}) 2125 if err != nil { 2126 t.Errorf("bad response to GetPointsInSupervoxels: %v\n", err) 2127 } 2128 if len(inSupervoxels) != 6 || !reflect.DeepEqual(inSupervoxels, []bool{true, true, false, false, false, false}) { 2129 t.Fatalf("bad return from GetPointsInSupervoxels: %v\n", inSupervoxels) 2130 } 2131 inSupervoxels, err = labeldata.GetPointsInSupervoxels(v, pts, []uint64{3}) 2132 if err != nil { 2133 t.Errorf("bad response to GetPointsInSupervoxels: %v\n", err) 2134 } 2135 if len(inSupervoxels) != 6 || !reflect.DeepEqual(inSupervoxels, []bool{false, false, false, false, true, false}) { 2136 t.Fatalf("bad return from GetPointsInSupervoxels: %v\n", inSupervoxels) 2137 } 2138 2139 // Merge of 3 into 4 2140 testMerge := mergeJSON(`[4, 3]`) 2141 testMerge.send(t, uuid, "labels") 2142 2143 reqStr = fmt.Sprintf("%snode/%s/labels/lastmod/4", server.WebAPIPath, uuid) 2144 r := server.TestHTTP(t, "GET", reqStr, nil) 2145 var infoVal struct { 2146 MutID uint64 `json:"mutation id"` 2147 User string `json:"last mod user"` 2148 App string `json:"last mod app"` 2149 Time string `json:"last mod time"` 2150 } 2151 if err := json.Unmarshal(r, &infoVal); err != nil { 2152 t.Fatalf("unable to get mod info for label 4: %v", err) 2153 } 2154 if infoVal.MutID != datastore.InitialMutationID+1 { 2155 t.Errorf("expected mutation id %d, got %d\n", datastore.InitialMutationID+1, infoVal.MutID) 2156 } 2157 2158 // Check direct label queries for points after merge 2159 mapped, err = labeldata.GetLabelPoints(v, pts, 0, false) 2160 if err != nil { 2161 t.Errorf("bad response to GetLabelsPoints: %v\n", err) 2162 } 2163 if len(mapped) != 6 || !reflect.DeepEqual(mapped, []uint64{1, 1, 2, 2, 4, 4}) { 2164 t.Fatalf("bad return from GetLabelPoints: %v\n", mapped) 2165 } 2166 inSupervoxels, err = labeldata.GetPointsInSupervoxels(v, pts, []uint64{3}) 2167 if err != nil { 2168 t.Errorf("bad response to GetPointsInSupervoxels: %v\n", err) 2169 } 2170 if len(inSupervoxels) != 6 || !reflect.DeepEqual(inSupervoxels, []bool{false, false, false, false, true, false}) { 2171 t.Fatalf("bad return from GetPointsInSupervoxels: %v\n", inSupervoxels) 2172 } 2173 inSupervoxels, err = labeldata.GetPointsInSupervoxels(v, pts, []uint64{4}) 2174 if err != nil { 2175 t.Errorf("bad response to GetPointsInSupervoxels: %v\n", err) 2176 } 2177 if len(inSupervoxels) != 6 || !reflect.DeepEqual(inSupervoxels, []bool{false, false, false, false, false, true}) { 2178 t.Fatalf("bad return from GetPointsInSupervoxels: %v\n", inSupervoxels) 2179 } 2180 inSupervoxels, err = labeldata.GetPointsInSupervoxels(v, pts, []uint64{3, 4}) 2181 if err != nil { 2182 t.Errorf("bad response to GetPointsInSupervoxels: %v\n", err) 2183 } 2184 if len(inSupervoxels) != 6 || !reflect.DeepEqual(inSupervoxels, []bool{false, false, false, false, true, true}) { 2185 t.Fatalf("bad return from GetPointsInSupervoxels: %v\n", inSupervoxels) 2186 } 2187 2188 // Check sizes 2189 reqStr = fmt.Sprintf("%snode/%s/labels/size/4", server.WebAPIPath, uuid) 2190 r = server.TestHTTP(t, "GET", reqStr, nil) 2191 var jsonVal struct { 2192 Voxels uint64 `json:"voxels"` 2193 } 2194 if err := json.Unmarshal(r, &jsonVal); err != nil { 2195 t.Fatalf("unable to get size for label 4: %v", err) 2196 } 2197 voxelsIn3 := body3.voxelSpans.Count() 2198 voxelsIn4 := body4.voxelSpans.Count() 2199 if jsonVal.Voxels != voxelsIn3+voxelsIn4 { 2200 t.Errorf("thought label 4 would have %d voxels, got %d\n", voxelsIn3+voxelsIn4, jsonVal.Voxels) 2201 } 2202 reqStr = fmt.Sprintf("%snode/%s/labels/size/4?supervoxels=true", server.WebAPIPath, uuid) 2203 r = server.TestHTTP(t, "GET", reqStr, nil) 2204 if err := json.Unmarshal(r, &jsonVal); err != nil { 2205 t.Fatalf("unable to get size for supervoxel 4: %v", err) 2206 } 2207 if jsonVal.Voxels != voxelsIn4 { 2208 t.Errorf("thought supervoxel 4 would have %d voxels, got %d\n", voxelsIn4, jsonVal.Voxels) 2209 } 2210 2211 // Make sure label 3 sparsevol has been removed. 2212 reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, 3) 2213 server.TestBadHTTP(t, "GET", reqStr, nil) 2214 2215 retrieved := newTestVolume(128, 128, 128) 2216 retrieved.get(t, uuid, "labels", false) 2217 if len(retrieved.data) != 8*128*128*128 { 2218 t.Errorf("Retrieved label volume is incorrect size\n") 2219 } 2220 if !retrieved.isLabel(2, &body2) { 2221 t.Errorf("Expected label 2 original voxels to remain. Instead some were removed.\n") 2222 } 2223 if retrieved.hasLabel(3, &body3) { 2224 t.Errorf("Found label 3 when all label 3 should have been merged into label 4!\n") 2225 } 2226 if !retrieved.isLabel(4, &body3) { 2227 t.Errorf("Incomplete merging. Label 4 should have taken over full extent of label 3\n") 2228 } 2229 expected.addBody(body3, 4) 2230 if err := retrieved.equals(expected); err != nil { 2231 t.Errorf("Merged label volume not equal to expected merged volume: %v\n", err) 2232 } 2233 2234 retrieved.get(t, uuid, "labels", true) // check supervoxels 2235 if len(retrieved.data) != 8*128*128*128 { 2236 t.Errorf("Retrieved supervoxel volume is incorrect size\n") 2237 } 2238 if !retrieved.isLabel(1, &body1) { 2239 t.Errorf("Expected supervoxel 1 original voxels to remain. Instead some were removed.\n") 2240 } 2241 if !retrieved.isLabel(2, &body2) { 2242 t.Errorf("Expected supervoxel 2 original voxels to remain. Instead some were removed.\n") 2243 } 2244 if !retrieved.hasLabel(3, &body3) { 2245 t.Errorf("Expected supervoxel 3 original voxels to remain. Instead some were removed.\n") 2246 } 2247 if !retrieved.isLabel(4, &body4) { 2248 t.Errorf("Expected supervoxel 4 original voxels to remain. Instead some were removed.\n") 2249 } 2250 2251 // Cleave supervoxel 3 out of label 4. 2252 reqStr = fmt.Sprintf("%snode/%s/labels/cleave/4?u=mrsmith&app=myapp", server.WebAPIPath, uuid) 2253 r = server.TestHTTP(t, "POST", reqStr, bytes.NewBufferString("[3]")) 2254 var jsonVal2 struct { 2255 CleavedLabel uint64 2256 } 2257 if err := json.Unmarshal(r, &jsonVal2); err != nil { 2258 t.Errorf("Unable to get new label from cleave. Instead got: %v\n", jsonVal2) 2259 } 2260 2261 reqStr = fmt.Sprintf("%snode/%s/labels/lastmod/4", server.WebAPIPath, uuid) 2262 r = server.TestHTTP(t, "GET", reqStr, nil) 2263 if err := json.Unmarshal(r, &infoVal); err != nil { 2264 t.Fatalf("unable to get mod info for label 4: %v", err) 2265 } 2266 if infoVal.MutID != datastore.InitialMutationID+2 || infoVal.App != "myapp" || infoVal.User != "mrsmith" { 2267 t.Errorf("unexpected last mod info: %v\n", infoVal) 2268 } 2269 2270 reqStr = fmt.Sprintf("%snode/%s/labels/maxlabel", server.WebAPIPath, uuid) 2271 jsonStr := server.TestHTTP(t, "GET", reqStr, nil) 2272 expectedJSON := `{"maxlabel": 5}` 2273 if string(jsonStr) != expectedJSON { 2274 t.Errorf("Expected this JSON returned from maxlabel:\n%s\nGot:\n%s\n", expectedJSON, string(jsonStr)) 2275 } 2276 2277 retrieved.get(t, uuid, "labels", false) 2278 if len(retrieved.data) != 8*128*128*128 { 2279 t.Fatalf("Retrieved label volume is incorrect size\n") 2280 } 2281 expected.addBody(body3, 5) 2282 if err := expected.equals(retrieved); err != nil { 2283 t.Fatalf("Post-cleave label volume not equal to expected volume: %v\n", err) 2284 } 2285 2286 retrieved.get(t, uuid, "labels", true) 2287 if len(retrieved.data) != 8*128*128*128 { 2288 t.Fatalf("Retrieved supervoxel volume is incorrect size\n") 2289 } 2290 expected.addBody(body3, 3) 2291 if err := expected.equals(retrieved); err != nil { 2292 t.Fatalf("Post-cleave supervoxel volume not equal to expected volume: %v\n", err) 2293 } 2294 2295 // supervoxel 3 (original body 3) should now be label 5 2296 reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/5", server.WebAPIPath, uuid) 2297 encoding := server.TestHTTP(t, "GET", reqStr, nil) 2298 body3.checkSparseVol(t, encoding, dvid.OptionalBounds{}) 2299 2300 // make sure you can't cleave all supervoxels from a label 2301 reqStr = fmt.Sprintf("%snode/%s/labels/cleave/4", server.WebAPIPath, uuid) 2302 server.TestBadHTTP(t, "POST", reqStr, bytes.NewBufferString("[4]")) 2303 2304 // Check direct label queries for points after cleave 2305 mapped, err = labeldata.GetLabelPoints(v, pts, 0, false) 2306 if err != nil { 2307 t.Errorf("bad response to GetLabelsPoints: %v\n", err) 2308 } 2309 if len(mapped) != 6 || !reflect.DeepEqual(mapped, []uint64{1, 1, 2, 2, 5, 4}) { 2310 t.Fatalf("bad return from GetLabelPoints: %v\n", mapped) 2311 } 2312 inSupervoxels, err = labeldata.GetPointsInSupervoxels(v, pts, []uint64{3}) 2313 if err != nil { 2314 t.Errorf("bad response to GetPointsInSupervoxels: %v\n", err) 2315 } 2316 if len(inSupervoxels) != 6 || !reflect.DeepEqual(inSupervoxels, []bool{false, false, false, false, true, false}) { 2317 t.Fatalf("bad return from GetPointsInSupervoxels: %v\n", inSupervoxels) 2318 } 2319 inSupervoxels, err = labeldata.GetPointsInSupervoxels(v, pts, []uint64{4}) 2320 if err != nil { 2321 t.Errorf("bad response to GetPointsInSupervoxels: %v\n", err) 2322 } 2323 if len(inSupervoxels) != 6 || !reflect.DeepEqual(inSupervoxels, []bool{false, false, false, false, false, true}) { 2324 t.Fatalf("bad return from GetPointsInSupervoxels: %v\n", inSupervoxels) 2325 } 2326 inSupervoxels, err = labeldata.GetPointsInSupervoxels(v, pts, []uint64{4}) 2327 if err != nil { 2328 t.Fatalf("bad response to GetPointsInSupervoxels: %v\n", err) 2329 } 2330 if len(inSupervoxels) != 6 || !reflect.DeepEqual(inSupervoxels, []bool{false, false, false, false, false, true}) { 2331 t.Fatalf("bad return from GetPointsInSupervoxels: %v\n", inSupervoxels) 2332 } 2333 inSupervoxels, err = labeldata.GetPointsInSupervoxels(v, pts, []uint64{3}) 2334 if err != nil { 2335 t.Errorf("bad response to GetPointsInSupervoxels: %v\n", err) 2336 } 2337 if len(inSupervoxels) != 6 || !reflect.DeepEqual(inSupervoxels, []bool{false, false, false, false, true, false}) { 2338 t.Fatalf("bad return from GetPointsInSupervoxels: %v\n", inSupervoxels) 2339 } 2340 2341 // Check storage stats 2342 stats, err := datastore.GetStorageDetails() 2343 if err != nil { 2344 t.Fatalf("error getting storage details: %v\n", err) 2345 } 2346 dvid.Infof("storage details: %s\n", stats) 2347 } 2348 2349 func TestMultiscaleMergeCleave(t *testing.T) { 2350 testConfig := server.TestConfig{CacheSize: map[string]int{"labelmap": 10}} 2351 // var testConfig server.TestConfig 2352 if err := server.OpenTest(testConfig); err != nil { 2353 t.Fatalf("can't open test server: %v\n", err) 2354 } 2355 defer server.CloseTest() 2356 2357 // Create testbed volume 2358 uuid, _ := initTestRepo() 2359 var config dvid.Config 2360 config.Set("MaxDownresLevel", "2") 2361 server.CreateTestInstance(t, uuid, "labelmap", "labels", config) 2362 2363 // Create an easily interpreted label volume with a couple of labels. 2364 volume := newTestVolume(128, 128, 128) 2365 volume.addSubvol(dvid.Point3d{40, 40, 40}, dvid.Point3d{40, 40, 40}, 1) 2366 volume.addSubvol(dvid.Point3d{40, 40, 80}, dvid.Point3d{40, 40, 40}, 2) 2367 volume.addSubvol(dvid.Point3d{80, 40, 40}, dvid.Point3d{40, 40, 40}, 13) 2368 volume.addSubvol(dvid.Point3d{40, 80, 40}, dvid.Point3d{40, 40, 40}, 209) 2369 volume.addSubvol(dvid.Point3d{80, 80, 40}, dvid.Point3d{40, 40, 40}, 311) 2370 volume.put(t, uuid, "labels") 2371 2372 // Verify initial ingest for hi-res 2373 if err := downres.BlockOnUpdating(uuid, "labels"); err != nil { 2374 t.Fatalf("Error blocking on update for labels: %v\n", err) 2375 } 2376 2377 sizeReq := fmt.Sprintf("%snode/%s/labels/sparsevol-size/1", server.WebAPIPath, uuid) 2378 sizeResp := server.TestHTTP(t, "GET", sizeReq, nil) 2379 if string(sizeResp) != `{"voxels": 64000, "numblocks": 8, "minvoxel": [0, 0, 0], "maxvoxel": [127, 127, 127]}` { 2380 t.Errorf("bad response to sparsevol-size endpoint: %s\n", string(sizeResp)) 2381 } 2382 2383 testPoints0 := map[uint64][3]int32{ 2384 0: {18, 18, 18}, 2385 1: {45, 45, 45}, 2386 2: {50, 50, 100}, 2387 13: {100, 60, 60}, 2388 209: {55, 100, 55}, 2389 311: {81, 81, 41}, 2390 } 2391 testPoints1 := map[uint64][3]int32{ 2392 0: {35, 34, 2}, 2393 1: {30, 30, 30}, 2394 2: {21, 21, 45}, 2395 13: {45, 21, 36}, 2396 209: {21, 50, 35}, 2397 311: {45, 55, 35}, 2398 } 2399 testPoints2 := map[uint64][3]int32{ 2400 0: {15, 16, 2}, 2401 1: {15, 15, 15}, 2402 2: {11, 11, 23}, 2403 13: {23, 11, 18}, 2404 209: {11, 25, 18}, 2405 311: {23, 28, 18}, 2406 } 2407 2408 hires := newTestVolume(128, 128, 128) 2409 hires.get(t, uuid, "labels", false) 2410 2411 strarray := make([]string, len(testPoints0)) 2412 var sentLabels []uint64 2413 i := 0 2414 for label, pt := range testPoints0 { 2415 hires.verifyLabel(t, label, pt[0], pt[1], pt[2]) 2416 sentLabels = append(sentLabels, label) 2417 strarray[i] = fmt.Sprintf("[%d,%d,%d]", pt[0], pt[1], pt[2]) 2418 i++ 2419 } 2420 coordsStr := "[" + strings.Join(strarray, ",") + "]" 2421 reqStr := fmt.Sprintf("%snode/%s/labels/labels", server.WebAPIPath, uuid) 2422 r := server.TestHTTP(t, "GET", reqStr, bytes.NewBufferString(coordsStr)) 2423 var gotLabels []uint64 2424 if err := json.Unmarshal(r, &gotLabels); err != nil { 2425 t.Errorf("Unable to get label array from GET /labels. Instead got: %v\n", string(r)) 2426 } 2427 for i, sent := range sentLabels { 2428 if sent != gotLabels[i] { 2429 t.Errorf("expected GET /labels to return label %d in position %d, got %d back\n", sent, i, gotLabels[i]) 2430 } 2431 } 2432 2433 // Check the first downres: 64^3 2434 downres1 := newTestVolume(64, 64, 64) 2435 downres1.getScale(t, uuid, "labels", 1, false) 2436 sentLabels = []uint64{} 2437 i = 0 2438 for label, pt := range testPoints1 { 2439 downres1.verifyLabel(t, label, pt[0], pt[1], pt[2]) 2440 sentLabels = append(sentLabels, label) 2441 strarray[i] = fmt.Sprintf("[%d,%d,%d]", pt[0], pt[1], pt[2]) 2442 i++ 2443 } 2444 coordsStr = "[" + strings.Join(strarray, ",") + "]" 2445 reqStr = fmt.Sprintf("%snode/%s/labels/labels?scale=1", server.WebAPIPath, uuid) 2446 r = server.TestHTTP(t, "GET", reqStr, bytes.NewBufferString(coordsStr)) 2447 gotLabels = []uint64{} 2448 if err := json.Unmarshal(r, &gotLabels); err != nil { 2449 t.Errorf("Unable to get label array from GET /labels. Instead got: %v\n", string(r)) 2450 } 2451 for i, sent := range sentLabels { 2452 if sent != gotLabels[i] { 2453 t.Errorf("expected GET /labels to return label %d in position %d, got %d back\n", sent, i, gotLabels[i]) 2454 } 2455 } 2456 expected1 := newTestVolume(64, 64, 64) 2457 expected1.addSubvol(dvid.Point3d{20, 20, 20}, dvid.Point3d{20, 20, 20}, 1) 2458 expected1.addSubvol(dvid.Point3d{20, 20, 40}, dvid.Point3d{20, 20, 20}, 2) 2459 expected1.addSubvol(dvid.Point3d{40, 20, 20}, dvid.Point3d{20, 20, 20}, 13) 2460 expected1.addSubvol(dvid.Point3d{20, 40, 20}, dvid.Point3d{20, 20, 20}, 209) 2461 expected1.addSubvol(dvid.Point3d{40, 40, 20}, dvid.Point3d{20, 20, 20}, 311) 2462 if err := expected1.equals(downres1); err != nil { 2463 t.Errorf("1st downres isn't what is expected: %v\n", err) 2464 } 2465 2466 // Check the second downres to voxel: 32^3 2467 downres2 := newTestVolume(32, 32, 32) 2468 downres2.getScale(t, uuid, "labels", 2, false) 2469 for label, pt := range testPoints2 { 2470 downres2.verifyLabel(t, label, pt[0], pt[1], pt[2]) 2471 } 2472 expected2 := newTestVolume(32, 32, 32) 2473 expected2.addSubvol(dvid.Point3d{10, 10, 10}, dvid.Point3d{10, 10, 10}, 1) 2474 expected2.addSubvol(dvid.Point3d{10, 10, 20}, dvid.Point3d{10, 10, 10}, 2) 2475 expected2.addSubvol(dvid.Point3d{20, 10, 10}, dvid.Point3d{10, 10, 10}, 13) 2476 expected2.addSubvol(dvid.Point3d{10, 20, 10}, dvid.Point3d{10, 10, 10}, 209) 2477 expected2.addSubvol(dvid.Point3d{20, 20, 10}, dvid.Point3d{10, 10, 10}, 311) 2478 if err := expected2.equals(downres2); err != nil { 2479 t.Errorf("2nd downres isn't what is expected: %v\n", err) 2480 } 2481 2482 var labelJSON struct { 2483 Label uint64 2484 } 2485 for i := 0; i < 100; i++ { 2486 for label, pt := range testPoints0 { 2487 labelReq := fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d", server.WebAPIPath, uuid, pt[0], pt[1], pt[2]) 2488 labelResp := server.TestHTTP(t, "GET", labelReq, nil) 2489 if err := json.Unmarshal(labelResp, &labelJSON); err != nil { 2490 t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err) 2491 } 2492 if labelJSON.Label != label { 2493 t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp)) 2494 } 2495 } 2496 } 2497 for label, pt := range testPoints1 { 2498 labelReq := fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?scale=1", server.WebAPIPath, uuid, pt[0], pt[1], pt[2]) 2499 labelResp := server.TestHTTP(t, "GET", labelReq, nil) 2500 if err := json.Unmarshal(labelResp, &labelJSON); err != nil { 2501 t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err) 2502 } 2503 if labelJSON.Label != label { 2504 t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp)) 2505 } 2506 } 2507 for label, pt := range testPoints2 { 2508 labelReq := fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?scale=2", server.WebAPIPath, uuid, pt[0], pt[1], pt[2]) 2509 labelResp := server.TestHTTP(t, "GET", labelReq, nil) 2510 if err := json.Unmarshal(labelResp, &labelJSON); err != nil { 2511 t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err) 2512 } 2513 if labelJSON.Label != label { 2514 t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp)) 2515 } 2516 } 2517 2518 // Test merge of 2 and 13 into 1 2519 testMerge := mergeJSON(`[1, 2, 13]`) 2520 testMerge.send(t, uuid, "labels") 2521 2522 sizeReq = fmt.Sprintf("%snode/%s/labels/sparsevol-size/1", server.WebAPIPath, uuid) 2523 sizeResp = server.TestHTTP(t, "GET", sizeReq, nil) 2524 if string(sizeResp) != `{"voxels": 192000, "numblocks": 8, "minvoxel": [0, 0, 0], "maxvoxel": [127, 127, 127]}` { 2525 t.Errorf("bad response to sparsevol-size endpoint: %s\n", string(sizeResp)) 2526 } 2527 sizeReq = fmt.Sprintf("%snode/%s/labels/sparsevol-size/2?supervoxels=true", server.WebAPIPath, uuid) 2528 sizeResp = server.TestHTTP(t, "GET", sizeReq, nil) 2529 if string(sizeResp) != `{"voxels": 64000, "numblocks": 4, "minvoxel": [0, 0, 64], "maxvoxel": [127, 127, 127]}` { 2530 t.Errorf("bad response to sparsevol-size endpoint: %s\n", string(sizeResp)) 2531 } 2532 headReq := fmt.Sprintf("%snode/%s/labels/sparsevol/2?supervoxels=true", server.WebAPIPath, uuid) 2533 headResp := server.TestHTTPResponse(t, "HEAD", headReq, nil) 2534 if headResp.Code != http.StatusOK { 2535 t.Errorf("HEAD on %s did not return OK. Status = %d\n", headReq, headResp.Code) 2536 } 2537 2538 mapping := map[uint64]uint64{ 2539 1: 1, 2540 2: 1, 2541 13: 1, 2542 209: 209, 2543 311: 311, 2544 } 2545 sentLabels = []uint64{} 2546 i = 0 2547 for label, pt := range testPoints0 { 2548 labelReq := fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d", server.WebAPIPath, uuid, pt[0], pt[1], pt[2]) 2549 labelResp := server.TestHTTP(t, "GET", labelReq, nil) 2550 if err := json.Unmarshal(labelResp, &labelJSON); err != nil { 2551 t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err) 2552 } 2553 if labelJSON.Label != mapping[label] { 2554 t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp)) 2555 } 2556 labelReq = fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?supervoxels=true", server.WebAPIPath, uuid, pt[0], pt[1], pt[2]) 2557 labelResp = server.TestHTTP(t, "GET", labelReq, nil) 2558 if err := json.Unmarshal(labelResp, &labelJSON); err != nil { 2559 t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err) 2560 } 2561 if labelJSON.Label != label { 2562 t.Errorf("expected label %d to query on (%d, %d, %d): %s\n", label, pt[0], pt[1], pt[2], string(labelResp)) 2563 } 2564 sentLabels = append(sentLabels, label) 2565 strarray[i] = fmt.Sprintf("%d", label) 2566 i++ 2567 } 2568 supervoxelsStr := "[" + strings.Join(strarray, ",") + "]" 2569 reqStr = fmt.Sprintf("%snode/%s/labels/mapping", server.WebAPIPath, uuid) 2570 r = server.TestHTTP(t, "GET", reqStr, bytes.NewBufferString(supervoxelsStr)) 2571 gotLabels = []uint64{} 2572 if err := json.Unmarshal(r, &gotLabels); err != nil { 2573 t.Errorf("Unable to get label array from GET /mapping. Instead got: %v\n", string(r)) 2574 } 2575 for i, sent := range sentLabels { 2576 if mapping[sent] != gotLabels[i] { 2577 t.Fatalf("expected GET /mapping to return label %d in position %d, got %d back\n", mapping[sent], i, gotLabels[i]) 2578 } 2579 } 2580 2581 for label, pt := range testPoints1 { 2582 labelReq := fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?scale=1", server.WebAPIPath, uuid, pt[0], pt[1], pt[2]) 2583 labelResp := server.TestHTTP(t, "GET", labelReq, nil) 2584 if err := json.Unmarshal(labelResp, &labelJSON); err != nil { 2585 t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err) 2586 } 2587 if labelJSON.Label != mapping[label] { 2588 t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp)) 2589 } 2590 labelReq = fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?scale=1&supervoxels=true", server.WebAPIPath, uuid, pt[0], pt[1], pt[2]) 2591 labelResp = server.TestHTTP(t, "GET", labelReq, nil) 2592 if err := json.Unmarshal(labelResp, &labelJSON); err != nil { 2593 t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err) 2594 } 2595 if labelJSON.Label != label { 2596 t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp)) 2597 } 2598 } 2599 for label, pt := range testPoints2 { 2600 labelReq := fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?scale=2", server.WebAPIPath, uuid, pt[0], pt[1], pt[2]) 2601 labelResp := server.TestHTTP(t, "GET", labelReq, nil) 2602 if err := json.Unmarshal(labelResp, &labelJSON); err != nil { 2603 t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err) 2604 } 2605 if labelJSON.Label != mapping[label] { 2606 t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp)) 2607 } 2608 labelReq = fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?scale=2&supervoxels=true", server.WebAPIPath, uuid, pt[0], pt[1], pt[2]) 2609 labelResp = server.TestHTTP(t, "GET", labelReq, nil) 2610 if err := json.Unmarshal(labelResp, &labelJSON); err != nil { 2611 t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err) 2612 } 2613 if labelJSON.Label != label { 2614 t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp)) 2615 } 2616 } 2617 2618 // Make sure labels 2 and 13 sparsevol has been removed. 2619 reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/2", server.WebAPIPath, uuid) 2620 server.TestBadHTTP(t, "GET", reqStr, nil) 2621 2622 reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/13", server.WebAPIPath, uuid) 2623 server.TestBadHTTP(t, "GET", reqStr, nil) 2624 2625 // Make sure label changes are correct after completion of merge 2626 if err := downres.BlockOnUpdating(uuid, "labels"); err != nil { 2627 t.Fatalf("Error blocking on update for labels: %v\n", err) 2628 } 2629 retrieved := newTestVolume(128, 128, 128) 2630 retrieved.get(t, uuid, "labels", false) 2631 merged := newTestVolume(128, 128, 128) 2632 merged.addSubvol(dvid.Point3d{40, 40, 40}, dvid.Point3d{40, 40, 40}, 1) 2633 merged.addSubvol(dvid.Point3d{40, 40, 80}, dvid.Point3d{40, 40, 40}, 1) 2634 merged.addSubvol(dvid.Point3d{80, 40, 40}, dvid.Point3d{40, 40, 40}, 1) 2635 merged.addSubvol(dvid.Point3d{40, 80, 40}, dvid.Point3d{40, 40, 40}, 209) 2636 merged.addSubvol(dvid.Point3d{80, 80, 40}, dvid.Point3d{40, 40, 40}, 311) 2637 if err := merged.equals(retrieved); err != nil { 2638 t.Errorf("Merged label volume not equal to expected label volume: %v\n", err) 2639 } 2640 2641 retrieved.get(t, uuid, "labels", true) // check supervoxels 2642 if err := hires.equals(retrieved); err != nil { 2643 t.Errorf("Merged supervoxel volume not equal to original supervoxel volume: %v\n", err) 2644 } 2645 2646 retrieved1 := newTestVolume(64, 64, 64) 2647 retrieved1.getScale(t, uuid, "labels", 1, false) 2648 retrieved1.verifyLabel(t, 0, 35, 34, 2) 2649 merged1 := newTestVolume(64, 64, 64) 2650 merged1.addSubvol(dvid.Point3d{20, 20, 20}, dvid.Point3d{20, 20, 20}, 1) 2651 merged1.addSubvol(dvid.Point3d{20, 20, 40}, dvid.Point3d{20, 20, 20}, 1) 2652 merged1.addSubvol(dvid.Point3d{40, 20, 20}, dvid.Point3d{20, 20, 20}, 1) 2653 merged1.addSubvol(dvid.Point3d{20, 40, 20}, dvid.Point3d{20, 20, 20}, 209) 2654 merged1.addSubvol(dvid.Point3d{40, 40, 20}, dvid.Point3d{20, 20, 20}, 311) 2655 if err := retrieved1.equals(merged1); err != nil { 2656 t.Errorf("Merged label volume downres #1 not equal to expected merged volume: %v\n", err) 2657 } 2658 2659 retrieved1.getScale(t, uuid, "labels", 1, true) // check supervoxels 2660 if err := downres1.equals(retrieved1); err != nil { 2661 t.Errorf("Merged supervoxel volume @ downres #1 not equal to original supervoxel volume: %v\n", err) 2662 } 2663 2664 retrieved2 := newTestVolume(32, 32, 32) 2665 retrieved2.getScale(t, uuid, "labels", 2, false) 2666 merged2 := newTestVolume(32, 32, 32) 2667 merged2.addSubvol(dvid.Point3d{10, 10, 10}, dvid.Point3d{10, 10, 10}, 1) 2668 merged2.addSubvol(dvid.Point3d{10, 10, 20}, dvid.Point3d{10, 10, 10}, 1) 2669 merged2.addSubvol(dvid.Point3d{20, 10, 10}, dvid.Point3d{10, 10, 10}, 1) 2670 merged2.addSubvol(dvid.Point3d{10, 20, 10}, dvid.Point3d{10, 10, 10}, 209) 2671 merged2.addSubvol(dvid.Point3d{20, 20, 10}, dvid.Point3d{10, 10, 10}, 311) 2672 if err := retrieved2.equals(merged2); err != nil { 2673 t.Errorf("Merged label volume downres #2 not equal to expected merged volume: %v\n", err) 2674 } 2675 2676 retrieved2.getScale(t, uuid, "labels", 2, true) // check supervoxels 2677 if err := downres2.equals(retrieved2); err != nil { 2678 t.Errorf("Merged supervoxel volume @ downres #2 not equal to original supervoxel volume: %v\n", err) 2679 } 2680 2681 // Cleave supervoxel 2 and 13 back out of merge label 1, should be 312. 2682 reqStr = fmt.Sprintf("%snode/%s/labels/cleave/1", server.WebAPIPath, uuid) 2683 r = server.TestHTTP(t, "POST", reqStr, bytes.NewBufferString("[2, 13]")) 2684 var jsonVal struct { 2685 CleavedLabel uint64 2686 MutationID uint64 2687 } 2688 if err := json.Unmarshal(r, &jsonVal); err != nil { 2689 t.Errorf("Unable to get new label from cleave. Instead got: %v\n", jsonVal) 2690 } 2691 if jsonVal.MutationID == 0 { 2692 t.Errorf("expected Mutation ID from cleave but got zero: %v\n", jsonVal) 2693 } 2694 2695 reqStr = fmt.Sprintf("%snode/%s/labels/maxlabel", server.WebAPIPath, uuid) 2696 jsonStr := server.TestHTTP(t, "GET", reqStr, nil) 2697 expectedJSON := `{"maxlabel": 312}` 2698 if string(jsonStr) != expectedJSON { 2699 t.Errorf("Expected this JSON returned from maxlabel:\n%s\nGot:\n%s\n", expectedJSON, string(jsonStr)) 2700 } 2701 2702 mapping = map[uint64]uint64{ 2703 1: 1, 2704 2: 312, 2705 13: 312, 2706 209: 209, 2707 311: 311, 2708 } 2709 for label, pt := range testPoints0 { 2710 labelReq := fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d", server.WebAPIPath, uuid, pt[0], pt[1], pt[2]) 2711 labelResp := server.TestHTTP(t, "GET", labelReq, nil) 2712 if err := json.Unmarshal(labelResp, &labelJSON); err != nil { 2713 t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err) 2714 } 2715 if labelJSON.Label != mapping[label] { 2716 t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp)) 2717 } 2718 labelReq = fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?supervoxels=true", server.WebAPIPath, uuid, pt[0], pt[1], pt[2]) 2719 labelResp = server.TestHTTP(t, "GET", labelReq, nil) 2720 if err := json.Unmarshal(labelResp, &labelJSON); err != nil { 2721 t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err) 2722 } 2723 if labelJSON.Label != label { 2724 t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp)) 2725 } 2726 } 2727 for label, pt := range testPoints1 { 2728 labelReq := fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?scale=1", server.WebAPIPath, uuid, pt[0], pt[1], pt[2]) 2729 labelResp := server.TestHTTP(t, "GET", labelReq, nil) 2730 if err := json.Unmarshal(labelResp, &labelJSON); err != nil { 2731 t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err) 2732 } 2733 if labelJSON.Label != mapping[label] { 2734 t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp)) 2735 } 2736 labelReq = fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?scale=1&supervoxels=true", server.WebAPIPath, uuid, pt[0], pt[1], pt[2]) 2737 labelResp = server.TestHTTP(t, "GET", labelReq, nil) 2738 if err := json.Unmarshal(labelResp, &labelJSON); err != nil { 2739 t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err) 2740 } 2741 if labelJSON.Label != label { 2742 t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp)) 2743 } 2744 } 2745 for label, pt := range testPoints2 { 2746 labelReq := fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?scale=2", server.WebAPIPath, uuid, pt[0], pt[1], pt[2]) 2747 labelResp := server.TestHTTP(t, "GET", labelReq, nil) 2748 if err := json.Unmarshal(labelResp, &labelJSON); err != nil { 2749 t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err) 2750 } 2751 if labelJSON.Label != mapping[label] { 2752 t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp)) 2753 } 2754 labelReq = fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?scale=2&supervoxels=true", server.WebAPIPath, uuid, pt[0], pt[1], pt[2]) 2755 labelResp = server.TestHTTP(t, "GET", labelReq, nil) 2756 if err := json.Unmarshal(labelResp, &labelJSON); err != nil { 2757 t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err) 2758 } 2759 if labelJSON.Label != label { 2760 t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp)) 2761 } 2762 } 2763 2764 retrieved.get(t, uuid, "labels", false) 2765 cleaved0 := newTestVolume(128, 128, 128) 2766 cleaved0.addSubvol(dvid.Point3d{40, 40, 40}, dvid.Point3d{40, 40, 40}, 1) 2767 cleaved0.addSubvol(dvid.Point3d{40, 40, 80}, dvid.Point3d{40, 40, 40}, 312) 2768 cleaved0.addSubvol(dvid.Point3d{80, 40, 40}, dvid.Point3d{40, 40, 40}, 312) 2769 cleaved0.addSubvol(dvid.Point3d{40, 80, 40}, dvid.Point3d{40, 40, 40}, 209) 2770 cleaved0.addSubvol(dvid.Point3d{80, 80, 40}, dvid.Point3d{40, 40, 40}, 311) 2771 if err := cleaved0.equals(retrieved); err != nil { 2772 t.Errorf("Cleaved label volume not equal to expected label volume: %v\n", err) 2773 } 2774 2775 retrieved.get(t, uuid, "labels", true) // check supervoxels 2776 if err := hires.equals(retrieved); err != nil { 2777 t.Errorf("Cleaved supervoxel volume not equal to original supervoxel volume: %v\n", err) 2778 } 2779 2780 retrieved1.getScale(t, uuid, "labels", 1, false) 2781 cleaved1 := newTestVolume(64, 64, 64) 2782 cleaved1.addSubvol(dvid.Point3d{20, 20, 20}, dvid.Point3d{20, 20, 20}, 1) 2783 cleaved1.addSubvol(dvid.Point3d{20, 20, 40}, dvid.Point3d{20, 20, 20}, 312) 2784 cleaved1.addSubvol(dvid.Point3d{40, 20, 20}, dvid.Point3d{20, 20, 20}, 312) 2785 cleaved1.addSubvol(dvid.Point3d{20, 40, 20}, dvid.Point3d{20, 20, 20}, 209) 2786 cleaved1.addSubvol(dvid.Point3d{40, 40, 20}, dvid.Point3d{20, 20, 20}, 311) 2787 if err := retrieved1.equals(cleaved1); err != nil { 2788 t.Errorf("Cleaved label volume downres #1 not equal to expected merged volume: %v\n", err) 2789 } 2790 2791 retrieved1.getScale(t, uuid, "labels", 1, true) // check supervoxels 2792 if err := downres1.equals(retrieved1); err != nil { 2793 t.Errorf("Cleaved supervoxel volume @ downres #1 not equal to original supervoxel volume: %v\n", err) 2794 } 2795 2796 retrieved2.getScale(t, uuid, "labels", 2, false) 2797 cleaved2 := newTestVolume(32, 32, 32) 2798 cleaved2.addSubvol(dvid.Point3d{10, 10, 10}, dvid.Point3d{10, 10, 10}, 1) 2799 cleaved2.addSubvol(dvid.Point3d{10, 10, 20}, dvid.Point3d{10, 10, 10}, 312) 2800 cleaved2.addSubvol(dvid.Point3d{20, 10, 10}, dvid.Point3d{10, 10, 10}, 312) 2801 cleaved2.addSubvol(dvid.Point3d{10, 20, 10}, dvid.Point3d{10, 10, 10}, 209) 2802 cleaved2.addSubvol(dvid.Point3d{20, 20, 10}, dvid.Point3d{10, 10, 10}, 311) 2803 if err := retrieved2.equals(cleaved2); err != nil { 2804 t.Errorf("Cleaved label volume downres #2 not equal to expected merged volume: %v\n", err) 2805 } 2806 2807 retrieved2.getScale(t, uuid, "labels", 2, true) // check supervoxels 2808 if err := downres2.equals(retrieved2); err != nil { 2809 t.Errorf("Cleaved supervoxel volume @ downres #2 not equal to original supervoxel volume: %v\n", err) 2810 } 2811 2812 } 2813 2814 // Test that mutable labelmap POST will accurately remove prior bodies if we overwrite 2815 // supervoxels entirely. 2816 func TestMutableLabelblkPOST(t *testing.T) { 2817 testConfig := server.TestConfig{CacheSize: map[string]int{"labelmap": 10}} 2818 // var testConfig server.TestConfig 2819 if err := server.OpenTest(testConfig); err != nil { 2820 t.Fatalf("can't open test server: %v\n", err) 2821 } 2822 defer server.CloseTest() 2823 2824 // Create testbed volume and data instances 2825 uuid, _ := initTestRepo() 2826 var config dvid.Config 2827 server.CreateTestInstance(t, uuid, "labelmap", "labels", config) 2828 2829 // Post labels 1-4 2830 createLabelTestVolume(t, uuid, "labels") 2831 2832 if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil { 2833 t.Fatalf("Error blocking on sync of labels: %v\n", err) 2834 } 2835 2836 // Make sure we have labels 1-4 sparsevol 2837 for _, label := range []uint64{1, 2, 3, 4} { 2838 // Check fast HEAD requests 2839 reqStr := fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, label) 2840 resp := server.TestHTTPResponse(t, "HEAD", reqStr, nil) 2841 if resp.Code != http.StatusOK { 2842 t.Errorf("HEAD on %s did not return OK. Status = %d\n", reqStr, resp.Code) 2843 } 2844 2845 // Check full sparse volumes 2846 encoding := server.TestHTTP(t, "GET", reqStr, nil) 2847 bodies[label-1].checkSparseVol(t, encoding, dvid.OptionalBounds{}) 2848 } 2849 2850 // Post labels 6-7 that overwrite all labels 1-4. 2851 createLabelTest2Volume(t, uuid, "labels") 2852 2853 if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil { 2854 t.Fatalf("Error blocking on sync of labels: %v\n", err) 2855 } 2856 2857 // Make sure that labels 1-4 have no more sparse vol. 2858 for _, label := range []uint64{1, 2, 3, 4} { 2859 // Check full sparse volumes aren't retrievable anymore 2860 reqStr := fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, label) 2861 server.TestBadHTTP(t, "GET", reqStr, nil) 2862 2863 // Make sure non-existent bodies return proper HEAD responses. 2864 resp := server.TestHTTPResponse(t, "HEAD", reqStr, nil) 2865 if resp.Code != http.StatusNoContent { 2866 t.Errorf("HEAD on %s did not return 204 (No Content). Status = %d\n", reqStr, resp.Code) 2867 } 2868 } 2869 2870 // Make sure labels 6-7 are available as sparse vol. 2871 for _, label := range []uint64{6, 7} { 2872 // Check fast HEAD requests 2873 reqStr := fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, label) 2874 resp := server.TestHTTPResponse(t, "HEAD", reqStr, nil) 2875 if resp.Code != http.StatusOK { 2876 t.Errorf("HEAD on %s did not return OK. Status = %d\n", reqStr, resp.Code) 2877 } 2878 2879 // Check full sparse volumes 2880 encoding := server.TestHTTP(t, "GET", reqStr, nil) 2881 bodies[label-1].checkSparseVol(t, encoding, dvid.OptionalBounds{}) 2882 } 2883 } 2884 2885 func TestConcurrentMutations(t *testing.T) { 2886 testConfig := server.TestConfig{CacheSize: map[string]int{"labelmap": 10}} 2887 // var testConfig server.TestConfig 2888 if err := server.OpenTest(testConfig); err != nil { 2889 t.Fatalf("can't open test server: %v\n", err) 2890 } 2891 defer server.CloseTest() 2892 2893 // Create testbed volume and data instances 2894 uuid, _ := initTestRepo() 2895 var config dvid.Config // use native 64^3 blocks 2896 server.CreateTestInstance(t, uuid, "labelmap", "labels", config) 2897 2898 // Make 12 parallel bodies and do merge/split on 3 groups. 2899 tbodies := make([]testBody, 12) 2900 for i := 0; i < 12; i++ { 2901 z := int32(32 + 4*i) 2902 blockz := z / 64 2903 tbodies[i] = testBody{ // 72 x 4 x 4 horizontal bar 2904 label: uint64(i + 1), 2905 offset: dvid.Point3d{9, 68, z}, 2906 size: dvid.Point3d{72, 4, 4}, 2907 blockSpans: []dvid.Span{ 2908 {blockz, 1, 0, 1}, 2909 }, 2910 voxelSpans: []dvid.Span{ 2911 {z, 68, 9, 80}, 2912 {z, 69, 9, 80}, 2913 {z, 70, 9, 80}, 2914 {z, 71, 9, 80}, 2915 {z + 1, 68, 9, 80}, 2916 {z + 1, 69, 9, 80}, 2917 {z + 1, 70, 9, 80}, 2918 {z + 1, 71, 9, 80}, 2919 {z + 2, 68, 9, 80}, 2920 {z + 2, 69, 9, 80}, 2921 {z + 2, 70, 9, 80}, 2922 {z + 2, 71, 9, 80}, 2923 {z + 3, 68, 9, 80}, 2924 {z + 3, 69, 9, 80}, 2925 {z + 3, 70, 9, 80}, 2926 {z + 3, 71, 9, 80}, 2927 }, 2928 } 2929 } 2930 2931 tvol := newTestVolume(192, 128, 128) 2932 for i := 0; i < 12; i++ { 2933 tvol.addBody(tbodies[i], uint64(i+1)) 2934 } 2935 tvol.put(t, uuid, "labels") 2936 2937 if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil { 2938 t.Fatalf("Error blocking on sync of labels: %v\n", err) 2939 } 2940 2941 retrieved := newTestVolume(192, 128, 128) 2942 retrieved.get(t, uuid, "labels", false) 2943 if len(retrieved.data) != 8*192*128*128 { 2944 t.Errorf("Retrieved labelvol volume is incorrect size\n") 2945 } 2946 if err := retrieved.equals(tvol); err != nil { 2947 t.Errorf("Initial put not working: %v\n", err) 2948 } 2949 2950 // Run concurrent cleave/merge ops on labels 1-4, 5-8, and 9-12. 2951 expectedMapping1 := make(map[uint64]uint64) 2952 expectedMapping2 := make(map[uint64]uint64) 2953 expectedMapping3 := make(map[uint64]uint64) 2954 wg := new(sync.WaitGroup) 2955 wg.Add(3) 2956 go func() { 2957 var err error 2958 for n := 0; n < 50; n++ { 2959 if err = mergeCleave(t, uuid, "labels", tbodies[0:4], 1, expectedMapping1); err != nil { 2960 break 2961 } 2962 } 2963 wg.Done() 2964 if err != nil { 2965 t.Error(err) 2966 } 2967 }() 2968 go func() { 2969 var err error 2970 for n := 0; n < 50; n++ { 2971 if err = mergeCleave(t, uuid, "labels", tbodies[4:8], 2, expectedMapping2); err != nil { 2972 break 2973 } 2974 } 2975 wg.Done() 2976 if err != nil { 2977 t.Error(err) 2978 } 2979 }() 2980 go func() { 2981 var err error 2982 for n := 0; n < 50; n++ { 2983 if err = mergeCleave(t, uuid, "labels", tbodies[8:12], 3, expectedMapping3); err != nil { 2984 break 2985 } 2986 } 2987 wg.Done() 2988 if err != nil { 2989 t.Error(err) 2990 } 2991 }() 2992 wg.Wait() 2993 2994 retrieved2 := newTestVolume(192, 128, 128) 2995 retrieved2.get(t, uuid, "labels", false) 2996 if len(retrieved2.data) != 8*192*128*128 { 2997 t.Errorf("Retrieved labelvol volume is incorrect size\n") 2998 } 2999 for i := 0; i < 4; i++ { 3000 tvol.addBody(tbodies[i], expectedMapping1[uint64(i+1)]) 3001 } 3002 for i := 4; i < 8; i++ { 3003 tvol.addBody(tbodies[i], expectedMapping2[uint64(i+1)]) 3004 } 3005 for i := 8; i < 12; i++ { 3006 tvol.addBody(tbodies[i], expectedMapping3[uint64(i+1)]) 3007 } 3008 if err := retrieved2.equals(tvol); err != nil { 3009 t.Errorf("Concurrent split/merge producing bad result: %v\n", err) 3010 } 3011 3012 // get reverse mapping of new bodies to supervoxel: should be 1 to 1 since cleaves are last ops. 3013 reverse := make(map[uint64]uint64, 12) 3014 for i := uint64(1); i <= 4; i++ { 3015 label, found := expectedMapping1[i] 3016 if !found { 3017 t.Errorf("unlikely that no mapping found for supervoxel %d!\n", i) 3018 label = i 3019 } 3020 reverse[label] = i 3021 } 3022 for i := uint64(5); i <= 8; i++ { 3023 label, found := expectedMapping2[i] 3024 if !found { 3025 t.Errorf("unlikely that no mapping found for supervoxel %d!\n", i) 3026 label = i 3027 } 3028 reverse[label] = i 3029 } 3030 for i := uint64(9); i <= 12; i++ { 3031 label, found := expectedMapping3[i] 3032 if !found { 3033 t.Errorf("unlikely that no mapping found for supervoxel %d!\n", i) 3034 label = i 3035 } 3036 reverse[label] = i 3037 } 3038 3039 reqStr := fmt.Sprintf("%snode/%s/labels/sparsevols-coarse/1/3000", server.WebAPIPath, uuid) 3040 encoding := server.TestHTTP(t, "GET", reqStr, nil) 3041 var i int 3042 for labelNum := 1; labelNum <= 12; labelNum++ { 3043 if i+28 > len(encoding) { 3044 t.Fatalf("Expected label #%d but only %d bytes remain in encoding\n", labelNum, len(encoding[i:])) 3045 } 3046 label := binary.LittleEndian.Uint64(encoding[i : i+8]) 3047 i += 8 3048 var spans dvid.Spans 3049 if err := spans.UnmarshalBinary(encoding[i:]); err != nil { 3050 t.Errorf("Error in decoding coarse sparse volume: %v\n", err) 3051 return 3052 } 3053 i += 4 + len(spans)*16 3054 supervoxel, found := reverse[label] 3055 if !found { 3056 t.Fatalf("Got sparsevol for label %d, yet none of the supervoxels were mapped to it!\n", label) 3057 } 3058 b := tbodies[supervoxel-1] 3059 if !reflect.DeepEqual(spans, b.blockSpans) { 3060 t.Errorf("Expected coarse spans for supervoxel %d:\n%s\nGot spans:\n%s\n", b.label, b.blockSpans, spans) 3061 } 3062 } 3063 } 3064 3065 // merge a subset of bodies, then cleave each of them back out. 3066 func mergeCleave(t *testing.T, uuid dvid.UUID, name dvid.InstanceName, tbodies []testBody, thread int, mapping map[uint64]uint64) error { 3067 label1 := tbodies[0].label 3068 label4 := tbodies[3].label 3069 target := label1 + uint64(rand.Int()%4) 3070 3071 labelset := make(labels.Set) 3072 for i := label1; i <= label4; i++ { 3073 if i != target { 3074 labelset[i] = struct{}{} 3075 } 3076 } 3077 3078 mapped, found := mapping[target] 3079 if found { 3080 target = mapped 3081 } 3082 var s []string 3083 for label := range labelset { 3084 mapped, found = mapping[label] 3085 if found { 3086 label = mapped 3087 } 3088 s = append(s, fmt.Sprintf("%d", label)) 3089 } 3090 mergeStr := "[" + fmt.Sprintf("%d", target) + ", " + strings.Join(s, ",") + "]" 3091 testMerge := mergeJSON(mergeStr) 3092 if err := testMerge.sendErr(t, uuid, "labels"); err != nil { 3093 return err 3094 } 3095 3096 for label := range labelset { 3097 reqStr := fmt.Sprintf("%snode/%s/labels/cleave/%d", server.WebAPIPath, uuid, target) 3098 cleaveStr := fmt.Sprintf("[%d]", label) 3099 r, err := server.TestHTTPError(t, "POST", reqStr, bytes.NewBufferString(cleaveStr)) 3100 if err != nil { 3101 return err 3102 } 3103 var jsonVal struct { 3104 CleavedLabel uint64 3105 } 3106 if err := json.Unmarshal(r, &jsonVal); err != nil { 3107 return fmt.Errorf("unable to get new label from cleave. Instead got: %v", jsonVal) 3108 } 3109 mapping[label] = jsonVal.CleavedLabel 3110 3111 // make sure old label doesn't have these supervoxels anymore. 3112 reqStr = fmt.Sprintf("%snode/%s/labels/supervoxels/%d", server.WebAPIPath, uuid, target) 3113 r, err = server.TestHTTPError(t, "GET", reqStr, nil) 3114 if err != nil { 3115 return err 3116 } 3117 var supervoxels []uint64 3118 if err := json.Unmarshal(r, &supervoxels); err != nil { 3119 return fmt.Errorf("unable to get supervoxels after cleave: %v", err) 3120 } 3121 for _, supervoxel := range supervoxels { 3122 if supervoxel == label { 3123 return fmt.Errorf("supervoxel %d was supposedly cleaved but still remains in label %d index", label, target) 3124 } 3125 } 3126 3127 // make sure cleaved body has just this supervoxel. 3128 reqStr = fmt.Sprintf("%snode/%s/labels/supervoxels/%d", server.WebAPIPath, uuid, jsonVal.CleavedLabel) 3129 r, err = server.TestHTTPError(t, "GET", reqStr, nil) 3130 if err != nil { 3131 return err 3132 } 3133 if err := json.Unmarshal(r, &supervoxels); err != nil { 3134 return fmt.Errorf("unable to get supervoxels for cleaved body %d after cleave: %v", jsonVal.CleavedLabel, err) 3135 } 3136 if len(supervoxels) != 1 { 3137 return fmt.Errorf("expected only 1 supervoxel (%d) to remain from cleave of %d into %d. have: %v", label, target, jsonVal.CleavedLabel, supervoxels) 3138 } 3139 if supervoxels[0] != label { 3140 return fmt.Errorf("expected only supervoxel in cleaved body %d to be %d, got %d", jsonVal.CleavedLabel, label, supervoxels[0]) 3141 } 3142 } 3143 return nil 3144 } 3145 3146 // Test concurrent POST blocks and then extents that should have data-wide mutex so no 3147 // overwriting of extents. 3148 func TestPostBlocksExtents(t *testing.T) { 3149 numTests := 3 3150 for i := 0; i < numTests; i++ { 3151 runTestBlocksExtents(t, i) 3152 } 3153 } 3154 3155 func runTestBlocksExtents(t *testing.T, run int) { 3156 if err := server.OpenTest(); err != nil { 3157 t.Fatalf("can't open test server: %v\n", err) 3158 } 3159 defer server.CloseTest() 3160 3161 uuid, _ := datastore.NewTestRepo() 3162 if len(uuid) < 5 { 3163 t.Fatalf("Bad root UUID for new repo: %s\n", uuid) 3164 } 3165 server.CreateTestInstance(t, uuid, "labelmap", "labels", dvid.Config{}) 3166 3167 data := loadTestData(t, testFiles[0]) 3168 gzippedData, err := data.b.CompressGZIP() 3169 if err != nil { 3170 t.Fatalf("unable to gzip compress block: %v\n", err) 3171 } 3172 3173 apiStr := fmt.Sprintf("%snode/%s/labels/blocks", server.WebAPIPath, uuid) 3174 sz := 128 3175 span := int32(sz / 64) 3176 wg := new(sync.WaitGroup) 3177 wg.Add(int(span * span * span)) 3178 for z := int32(0); z < span; z++ { 3179 for y := int32(0); y < span; y++ { 3180 for x := int32(0); x < span; x++ { 3181 go writeConcurrentBlock(t, wg, apiStr, x, y, z, gzippedData) 3182 } 3183 } 3184 } 3185 wg.Wait() 3186 if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil { 3187 t.Fatalf("Error blocking on sync of labels: %v\n", err) 3188 } 3189 3190 // check extents... 3191 apiStr = fmt.Sprintf("%snode/%s/labels/info", server.WebAPIPath, uuid) 3192 r := server.TestHTTP(t, "GET", apiStr, nil) 3193 jsonResp := make(map[string]map[string]interface{}) 3194 if err := json.Unmarshal(r, &jsonResp); err != nil { 3195 t.Fatalf("Unable to unmarshal labels/info response: %v\n", r) 3196 } 3197 extJSON, found := jsonResp["Extended"] 3198 if !found { 3199 t.Fatalf("No Extended property in labels/info response: %v\n", jsonResp) 3200 } 3201 val, found := extJSON["MinPoint"] 3202 if !found { 3203 t.Fatalf("No MinPoint property in labels/info response: %v\n", extJSON) 3204 } 3205 minPoint := val.([]interface{}) 3206 for i, pt := range minPoint { 3207 coord := pt.(float64) 3208 if coord != 0 { 3209 t.Fatalf("Bad min coord at position %d in run %d: %v\n", i, run, val) 3210 } 3211 } 3212 val, found = extJSON["MaxPoint"] 3213 if !found { 3214 t.Fatalf("No MaxPoint property in labels/info response: %v\n", extJSON) 3215 } 3216 maxPoint := val.([]interface{}) 3217 for i, pt := range maxPoint { 3218 coord := pt.(float64) 3219 if coord != 127 { 3220 t.Fatalf("Bad max coord at position %d in run %d: %v\n", i, run, val) 3221 } 3222 } 3223 } 3224 3225 func writeConcurrentBlock(t *testing.T, wg *sync.WaitGroup, apiStr string, x, y, z int32, gzippedData []byte) { 3226 if x == 0 && y == 0 && z == 0 { // randomly pause this block to see if extents correct 3227 t := time.Duration(rand.Int63() % 100) 3228 time.Sleep(t * time.Millisecond) 3229 } 3230 var buf bytes.Buffer 3231 writeTestInt32(t, &buf, x) 3232 writeTestInt32(t, &buf, y) 3233 writeTestInt32(t, &buf, z) 3234 writeTestInt32(t, &buf, int32(len(gzippedData))) 3235 n, err := buf.Write(gzippedData) 3236 if err != nil { 3237 t.Fatalf("unable to write gzip block: %v\n", err) 3238 } 3239 if n != len(gzippedData) { 3240 t.Fatalf("unable to write %d bytes to buffer, only wrote %d bytes\n", len(gzippedData), n) 3241 } 3242 server.TestHTTP(t, "POST", apiStr, &buf) 3243 wg.Done() 3244 } 3245 3246 var ( 3247 body1 = testBody{ 3248 label: 1, 3249 offset: dvid.Point3d{10, 40, 10}, 3250 size: dvid.Point3d{20, 20, 80}, 3251 blockSpans: []dvid.Span{ 3252 {0, 1, 0, 0}, 3253 {1, 1, 0, 0}, 3254 {2, 1, 0, 0}, 3255 }, 3256 voxelSpans: []dvid.Span{ 3257 {10, 40, 10, 29}, {10, 41, 10, 29}, {10, 42, 10, 29}, {10, 43, 10, 29}, {10, 44, 10, 29}, 3258 {10, 45, 10, 29}, {10, 46, 10, 29}, {10, 47, 10, 29}, {10, 48, 10, 29}, {10, 49, 10, 29}, 3259 {10, 50, 10, 29}, {10, 51, 10, 29}, {10, 52, 10, 29}, {10, 53, 10, 29}, {10, 54, 10, 29}, 3260 {10, 55, 10, 29}, {10, 56, 10, 29}, {10, 57, 10, 29}, {10, 58, 10, 29}, {10, 59, 10, 29}, 3261 {11, 40, 10, 29}, {11, 41, 10, 29}, {11, 42, 10, 29}, {11, 43, 10, 29}, {11, 44, 10, 29}, 3262 {11, 45, 10, 29}, {11, 46, 10, 29}, {11, 47, 10, 29}, {11, 48, 10, 29}, {11, 49, 10, 29}, 3263 {11, 50, 10, 29}, {11, 51, 10, 29}, {11, 52, 10, 29}, {11, 53, 10, 29}, {11, 54, 10, 29}, 3264 {11, 55, 10, 29}, {11, 56, 10, 29}, {11, 57, 10, 29}, {11, 58, 10, 29}, {11, 59, 10, 29}, 3265 {12, 40, 10, 29}, {12, 41, 10, 29}, {12, 42, 10, 29}, {12, 43, 10, 29}, {12, 44, 10, 29}, 3266 {12, 45, 10, 29}, {12, 46, 10, 29}, {12, 47, 10, 29}, {12, 48, 10, 29}, {12, 49, 10, 29}, 3267 {12, 50, 10, 29}, {12, 51, 10, 29}, {12, 52, 10, 29}, {12, 53, 10, 29}, {12, 54, 10, 29}, 3268 {12, 55, 10, 29}, {12, 56, 10, 29}, {12, 57, 10, 29}, {12, 58, 10, 29}, {12, 59, 10, 29}, 3269 {13, 40, 10, 29}, {13, 41, 10, 29}, {13, 42, 10, 29}, {13, 43, 10, 29}, {13, 44, 10, 29}, 3270 {13, 45, 10, 29}, {13, 46, 10, 29}, {13, 47, 10, 29}, {13, 48, 10, 29}, {13, 49, 10, 29}, 3271 {13, 50, 10, 29}, {13, 51, 10, 29}, {13, 52, 10, 29}, {13, 53, 10, 29}, {13, 54, 10, 29}, 3272 {13, 55, 10, 29}, {13, 56, 10, 29}, {13, 57, 10, 29}, {13, 58, 10, 29}, {13, 59, 10, 29}, 3273 {14, 40, 10, 29}, {14, 41, 10, 29}, {14, 42, 10, 29}, {14, 43, 10, 29}, {14, 44, 10, 29}, 3274 {14, 45, 10, 29}, {14, 46, 10, 29}, {14, 47, 10, 29}, {14, 48, 10, 29}, {14, 49, 10, 29}, 3275 {14, 50, 10, 29}, {14, 51, 10, 29}, {14, 52, 10, 29}, {14, 53, 10, 29}, {14, 54, 10, 29}, 3276 {14, 55, 10, 29}, {14, 56, 10, 29}, {14, 57, 10, 29}, {14, 58, 10, 29}, {14, 59, 10, 29}, 3277 {15, 40, 10, 29}, {15, 41, 10, 29}, {15, 42, 10, 29}, {15, 43, 10, 29}, {15, 44, 10, 29}, 3278 {15, 45, 10, 29}, {15, 46, 10, 29}, {15, 47, 10, 29}, {15, 48, 10, 29}, {15, 49, 10, 29}, 3279 {15, 50, 10, 29}, {15, 51, 10, 29}, {15, 52, 10, 29}, {15, 53, 10, 29}, {15, 54, 10, 29}, 3280 {15, 55, 10, 29}, {15, 56, 10, 29}, {15, 57, 10, 29}, {15, 58, 10, 29}, {15, 59, 10, 29}, 3281 {16, 40, 10, 29}, {16, 41, 10, 29}, {16, 42, 10, 29}, {16, 43, 10, 29}, {16, 44, 10, 29}, 3282 {16, 45, 10, 29}, {16, 46, 10, 29}, {16, 47, 10, 29}, {16, 48, 10, 29}, {16, 49, 10, 29}, 3283 {16, 50, 10, 29}, {16, 51, 10, 29}, {16, 52, 10, 29}, {16, 53, 10, 29}, {16, 54, 10, 29}, 3284 {16, 55, 10, 29}, {16, 56, 10, 29}, {16, 57, 10, 29}, {16, 58, 10, 29}, {16, 59, 10, 29}, 3285 {17, 40, 10, 29}, {17, 41, 10, 29}, {17, 42, 10, 29}, {17, 43, 10, 29}, {17, 44, 10, 29}, 3286 {17, 45, 10, 29}, {17, 46, 10, 29}, {17, 47, 10, 29}, {17, 48, 10, 29}, {17, 49, 10, 29}, 3287 {17, 50, 10, 29}, {17, 51, 10, 29}, {17, 52, 10, 29}, {17, 53, 10, 29}, {17, 54, 10, 29}, 3288 {17, 55, 10, 29}, {17, 56, 10, 29}, {17, 57, 10, 29}, {17, 58, 10, 29}, {17, 59, 10, 29}, 3289 {18, 40, 10, 29}, {18, 41, 10, 29}, {18, 42, 10, 29}, {18, 43, 10, 29}, {18, 44, 10, 29}, 3290 {18, 45, 10, 29}, {18, 46, 10, 29}, {18, 47, 10, 29}, {18, 48, 10, 29}, {18, 49, 10, 29}, 3291 {18, 50, 10, 29}, {18, 51, 10, 29}, {18, 52, 10, 29}, {18, 53, 10, 29}, {18, 54, 10, 29}, 3292 {18, 55, 10, 29}, {18, 56, 10, 29}, {18, 57, 10, 29}, {18, 58, 10, 29}, {18, 59, 10, 29}, 3293 {19, 40, 10, 29}, {19, 41, 10, 29}, {19, 42, 10, 29}, {19, 43, 10, 29}, {19, 44, 10, 29}, 3294 {19, 45, 10, 29}, {19, 46, 10, 29}, {19, 47, 10, 29}, {19, 48, 10, 29}, {19, 49, 10, 29}, 3295 {19, 50, 10, 29}, {19, 51, 10, 29}, {19, 52, 10, 29}, {19, 53, 10, 29}, {19, 54, 10, 29}, 3296 {19, 55, 10, 29}, {19, 56, 10, 29}, {19, 57, 10, 29}, {19, 58, 10, 29}, {19, 59, 10, 29}, 3297 {20, 40, 10, 29}, {20, 41, 10, 29}, {20, 42, 10, 29}, {20, 43, 10, 29}, {20, 44, 10, 29}, 3298 {20, 45, 10, 29}, {20, 46, 10, 29}, {20, 47, 10, 29}, {20, 48, 10, 29}, {20, 49, 10, 29}, 3299 {20, 50, 10, 29}, {20, 51, 10, 29}, {20, 52, 10, 29}, {20, 53, 10, 29}, {20, 54, 10, 29}, 3300 {20, 55, 10, 29}, {20, 56, 10, 29}, {20, 57, 10, 29}, {20, 58, 10, 29}, {20, 59, 10, 29}, 3301 {21, 40, 10, 29}, {21, 41, 10, 29}, {21, 42, 10, 29}, {21, 43, 10, 29}, {21, 44, 10, 29}, 3302 {21, 45, 10, 29}, {21, 46, 10, 29}, {21, 47, 10, 29}, {21, 48, 10, 29}, {21, 49, 10, 29}, 3303 {21, 50, 10, 29}, {21, 51, 10, 29}, {21, 52, 10, 29}, {21, 53, 10, 29}, {21, 54, 10, 29}, 3304 {21, 55, 10, 29}, {21, 56, 10, 29}, {21, 57, 10, 29}, {21, 58, 10, 29}, {21, 59, 10, 29}, 3305 {22, 40, 10, 29}, {22, 41, 10, 29}, {22, 42, 10, 29}, {22, 43, 10, 29}, {22, 44, 10, 29}, 3306 {22, 45, 10, 29}, {22, 46, 10, 29}, {22, 47, 10, 29}, {22, 48, 10, 29}, {22, 49, 10, 29}, 3307 {22, 50, 10, 29}, {22, 51, 10, 29}, {22, 52, 10, 29}, {22, 53, 10, 29}, {22, 54, 10, 29}, 3308 {22, 55, 10, 29}, {22, 56, 10, 29}, {22, 57, 10, 29}, {22, 58, 10, 29}, {22, 59, 10, 29}, 3309 {23, 40, 10, 29}, {23, 41, 10, 29}, {23, 42, 10, 29}, {23, 43, 10, 29}, {23, 44, 10, 29}, 3310 {23, 45, 10, 29}, {23, 46, 10, 29}, {23, 47, 10, 29}, {23, 48, 10, 29}, {23, 49, 10, 29}, 3311 {23, 50, 10, 29}, {23, 51, 10, 29}, {23, 52, 10, 29}, {23, 53, 10, 29}, {23, 54, 10, 29}, 3312 {23, 55, 10, 29}, {23, 56, 10, 29}, {23, 57, 10, 29}, {23, 58, 10, 29}, {23, 59, 10, 29}, 3313 {24, 40, 10, 29}, {24, 41, 10, 29}, {24, 42, 10, 29}, {24, 43, 10, 29}, {24, 44, 10, 29}, 3314 {24, 45, 10, 29}, {24, 46, 10, 29}, {24, 47, 10, 29}, {24, 48, 10, 29}, {24, 49, 10, 29}, 3315 {24, 50, 10, 29}, {24, 51, 10, 29}, {24, 52, 10, 29}, {24, 53, 10, 29}, {24, 54, 10, 29}, 3316 {24, 55, 10, 29}, {24, 56, 10, 29}, {24, 57, 10, 29}, {24, 58, 10, 29}, {24, 59, 10, 29}, 3317 {25, 40, 10, 29}, {25, 41, 10, 29}, {25, 42, 10, 29}, {25, 43, 10, 29}, {25, 44, 10, 29}, 3318 {25, 45, 10, 29}, {25, 46, 10, 29}, {25, 47, 10, 29}, {25, 48, 10, 29}, {25, 49, 10, 29}, 3319 {25, 50, 10, 29}, {25, 51, 10, 29}, {25, 52, 10, 29}, {25, 53, 10, 29}, {25, 54, 10, 29}, 3320 {25, 55, 10, 29}, {25, 56, 10, 29}, {25, 57, 10, 29}, {25, 58, 10, 29}, {25, 59, 10, 29}, 3321 {26, 40, 10, 29}, {26, 41, 10, 29}, {26, 42, 10, 29}, {26, 43, 10, 29}, {26, 44, 10, 29}, 3322 {26, 45, 10, 29}, {26, 46, 10, 29}, {26, 47, 10, 29}, {26, 48, 10, 29}, {26, 49, 10, 29}, 3323 {26, 50, 10, 29}, {26, 51, 10, 29}, {26, 52, 10, 29}, {26, 53, 10, 29}, {26, 54, 10, 29}, 3324 {26, 55, 10, 29}, {26, 56, 10, 29}, {26, 57, 10, 29}, {26, 58, 10, 29}, {26, 59, 10, 29}, 3325 {27, 40, 10, 29}, {27, 41, 10, 29}, {27, 42, 10, 29}, {27, 43, 10, 29}, {27, 44, 10, 29}, 3326 {27, 45, 10, 29}, {27, 46, 10, 29}, {27, 47, 10, 29}, {27, 48, 10, 29}, {27, 49, 10, 29}, 3327 {27, 50, 10, 29}, {27, 51, 10, 29}, {27, 52, 10, 29}, {27, 53, 10, 29}, {27, 54, 10, 29}, 3328 {27, 55, 10, 29}, {27, 56, 10, 29}, {27, 57, 10, 29}, {27, 58, 10, 29}, {27, 59, 10, 29}, 3329 {28, 40, 10, 29}, {28, 41, 10, 29}, {28, 42, 10, 29}, {28, 43, 10, 29}, {28, 44, 10, 29}, 3330 {28, 45, 10, 29}, {28, 46, 10, 29}, {28, 47, 10, 29}, {28, 48, 10, 29}, {28, 49, 10, 29}, 3331 {28, 50, 10, 29}, {28, 51, 10, 29}, {28, 52, 10, 29}, {28, 53, 10, 29}, {28, 54, 10, 29}, 3332 {28, 55, 10, 29}, {28, 56, 10, 29}, {28, 57, 10, 29}, {28, 58, 10, 29}, {28, 59, 10, 29}, 3333 {29, 40, 10, 29}, {29, 41, 10, 29}, {29, 42, 10, 29}, {29, 43, 10, 29}, {29, 44, 10, 29}, 3334 {29, 45, 10, 29}, {29, 46, 10, 29}, {29, 47, 10, 29}, {29, 48, 10, 29}, {29, 49, 10, 29}, 3335 {29, 50, 10, 29}, {29, 51, 10, 29}, {29, 52, 10, 29}, {29, 53, 10, 29}, {29, 54, 10, 29}, 3336 {29, 55, 10, 29}, {29, 56, 10, 29}, {29, 57, 10, 29}, {29, 58, 10, 29}, {29, 59, 10, 29}, 3337 {30, 40, 10, 29}, {30, 41, 10, 29}, {30, 42, 10, 29}, {30, 43, 10, 29}, {30, 44, 10, 29}, 3338 {30, 45, 10, 29}, {30, 46, 10, 29}, {30, 47, 10, 29}, {30, 48, 10, 29}, {30, 49, 10, 29}, 3339 {30, 50, 10, 29}, {30, 51, 10, 29}, {30, 52, 10, 29}, {30, 53, 10, 29}, {30, 54, 10, 29}, 3340 {30, 55, 10, 29}, {30, 56, 10, 29}, {30, 57, 10, 29}, {30, 58, 10, 29}, {30, 59, 10, 29}, 3341 {31, 40, 10, 29}, {31, 41, 10, 29}, {31, 42, 10, 29}, {31, 43, 10, 29}, {31, 44, 10, 29}, 3342 {31, 45, 10, 29}, {31, 46, 10, 29}, {31, 47, 10, 29}, {31, 48, 10, 29}, {31, 49, 10, 29}, 3343 {31, 50, 10, 29}, {31, 51, 10, 29}, {31, 52, 10, 29}, {31, 53, 10, 29}, {31, 54, 10, 29}, 3344 {31, 55, 10, 29}, {31, 56, 10, 29}, {31, 57, 10, 29}, {31, 58, 10, 29}, {31, 59, 10, 29}, 3345 {32, 40, 10, 29}, {32, 41, 10, 29}, {32, 42, 10, 29}, {32, 43, 10, 29}, {32, 44, 10, 29}, 3346 {32, 45, 10, 29}, {32, 46, 10, 29}, {32, 47, 10, 29}, {32, 48, 10, 29}, {32, 49, 10, 29}, 3347 {32, 50, 10, 29}, {32, 51, 10, 29}, {32, 52, 10, 29}, {32, 53, 10, 29}, {32, 54, 10, 29}, 3348 {32, 55, 10, 29}, {32, 56, 10, 29}, {32, 57, 10, 29}, {32, 58, 10, 29}, {32, 59, 10, 29}, 3349 {33, 40, 10, 29}, {33, 41, 10, 29}, {33, 42, 10, 29}, {33, 43, 10, 29}, {33, 44, 10, 29}, 3350 {33, 45, 10, 29}, {33, 46, 10, 29}, {33, 47, 10, 29}, {33, 48, 10, 29}, {33, 49, 10, 29}, 3351 {33, 50, 10, 29}, {33, 51, 10, 29}, {33, 52, 10, 29}, {33, 53, 10, 29}, {33, 54, 10, 29}, 3352 {33, 55, 10, 29}, {33, 56, 10, 29}, {33, 57, 10, 29}, {33, 58, 10, 29}, {33, 59, 10, 29}, 3353 {34, 40, 10, 29}, {34, 41, 10, 29}, {34, 42, 10, 29}, {34, 43, 10, 29}, {34, 44, 10, 29}, 3354 {34, 45, 10, 29}, {34, 46, 10, 29}, {34, 47, 10, 29}, {34, 48, 10, 29}, {34, 49, 10, 29}, 3355 {34, 50, 10, 29}, {34, 51, 10, 29}, {34, 52, 10, 29}, {34, 53, 10, 29}, {34, 54, 10, 29}, 3356 {34, 55, 10, 29}, {34, 56, 10, 29}, {34, 57, 10, 29}, {34, 58, 10, 29}, {34, 59, 10, 29}, 3357 {35, 40, 10, 29}, {35, 41, 10, 29}, {35, 42, 10, 29}, {35, 43, 10, 29}, {35, 44, 10, 29}, 3358 {35, 45, 10, 29}, {35, 46, 10, 29}, {35, 47, 10, 29}, {35, 48, 10, 29}, {35, 49, 10, 29}, 3359 {35, 50, 10, 29}, {35, 51, 10, 29}, {35, 52, 10, 29}, {35, 53, 10, 29}, {35, 54, 10, 29}, 3360 {35, 55, 10, 29}, {35, 56, 10, 29}, {35, 57, 10, 29}, {35, 58, 10, 29}, {35, 59, 10, 29}, 3361 {36, 40, 10, 29}, {36, 41, 10, 29}, {36, 42, 10, 29}, {36, 43, 10, 29}, {36, 44, 10, 29}, 3362 {36, 45, 10, 29}, {36, 46, 10, 29}, {36, 47, 10, 29}, {36, 48, 10, 29}, {36, 49, 10, 29}, 3363 {36, 50, 10, 29}, {36, 51, 10, 29}, {36, 52, 10, 29}, {36, 53, 10, 29}, {36, 54, 10, 29}, 3364 {36, 55, 10, 29}, {36, 56, 10, 29}, {36, 57, 10, 29}, {36, 58, 10, 29}, {36, 59, 10, 29}, 3365 {37, 40, 10, 29}, {37, 41, 10, 29}, {37, 42, 10, 29}, {37, 43, 10, 29}, {37, 44, 10, 29}, 3366 {37, 45, 10, 29}, {37, 46, 10, 29}, {37, 47, 10, 29}, {37, 48, 10, 29}, {37, 49, 10, 29}, 3367 {37, 50, 10, 29}, {37, 51, 10, 29}, {37, 52, 10, 29}, {37, 53, 10, 29}, {37, 54, 10, 29}, 3368 {37, 55, 10, 29}, {37, 56, 10, 29}, {37, 57, 10, 29}, {37, 58, 10, 29}, {37, 59, 10, 29}, 3369 {38, 40, 10, 29}, {38, 41, 10, 29}, {38, 42, 10, 29}, {38, 43, 10, 29}, {38, 44, 10, 29}, 3370 {38, 45, 10, 29}, {38, 46, 10, 29}, {38, 47, 10, 29}, {38, 48, 10, 29}, {38, 49, 10, 29}, 3371 {38, 50, 10, 29}, {38, 51, 10, 29}, {38, 52, 10, 29}, {38, 53, 10, 29}, {38, 54, 10, 29}, 3372 {38, 55, 10, 29}, {38, 56, 10, 29}, {38, 57, 10, 29}, {38, 58, 10, 29}, {38, 59, 10, 29}, 3373 {39, 40, 10, 29}, {39, 41, 10, 29}, {39, 42, 10, 29}, {39, 43, 10, 29}, {39, 44, 10, 29}, 3374 {39, 45, 10, 29}, {39, 46, 10, 29}, {39, 47, 10, 29}, {39, 48, 10, 29}, {39, 49, 10, 29}, 3375 {39, 50, 10, 29}, {39, 51, 10, 29}, {39, 52, 10, 29}, {39, 53, 10, 29}, {39, 54, 10, 29}, 3376 {39, 55, 10, 29}, {39, 56, 10, 29}, {39, 57, 10, 29}, {39, 58, 10, 29}, {39, 59, 10, 29}, 3377 {40, 40, 10, 29}, {40, 41, 10, 29}, {40, 42, 10, 29}, {40, 43, 10, 29}, {40, 44, 10, 29}, 3378 {40, 45, 10, 29}, {40, 46, 10, 29}, {40, 47, 10, 29}, {40, 48, 10, 29}, {40, 49, 10, 29}, 3379 {40, 50, 10, 29}, {40, 51, 10, 29}, {40, 52, 10, 29}, {40, 53, 10, 29}, {40, 54, 10, 29}, 3380 {40, 55, 10, 29}, {40, 56, 10, 29}, {40, 57, 10, 29}, {40, 58, 10, 29}, {40, 59, 10, 29}, 3381 {41, 40, 10, 29}, {41, 41, 10, 29}, {41, 42, 10, 29}, {41, 43, 10, 29}, {41, 44, 10, 29}, 3382 {41, 45, 10, 29}, {41, 46, 10, 29}, {41, 47, 10, 29}, {41, 48, 10, 29}, {41, 49, 10, 29}, 3383 {41, 50, 10, 29}, {41, 51, 10, 29}, {41, 52, 10, 29}, {41, 53, 10, 29}, {41, 54, 10, 29}, 3384 {41, 55, 10, 29}, {41, 56, 10, 29}, {41, 57, 10, 29}, {41, 58, 10, 29}, {41, 59, 10, 29}, 3385 {42, 40, 10, 29}, {42, 41, 10, 29}, {42, 42, 10, 29}, {42, 43, 10, 29}, {42, 44, 10, 29}, 3386 {42, 45, 10, 29}, {42, 46, 10, 29}, {42, 47, 10, 29}, {42, 48, 10, 29}, {42, 49, 10, 29}, 3387 {42, 50, 10, 29}, {42, 51, 10, 29}, {42, 52, 10, 29}, {42, 53, 10, 29}, {42, 54, 10, 29}, 3388 {42, 55, 10, 29}, {42, 56, 10, 29}, {42, 57, 10, 29}, {42, 58, 10, 29}, {42, 59, 10, 29}, 3389 {43, 40, 10, 29}, {43, 41, 10, 29}, {43, 42, 10, 29}, {43, 43, 10, 29}, {43, 44, 10, 29}, 3390 {43, 45, 10, 29}, {43, 46, 10, 29}, {43, 47, 10, 29}, {43, 48, 10, 29}, {43, 49, 10, 29}, 3391 {43, 50, 10, 29}, {43, 51, 10, 29}, {43, 52, 10, 29}, {43, 53, 10, 29}, {43, 54, 10, 29}, 3392 {43, 55, 10, 29}, {43, 56, 10, 29}, {43, 57, 10, 29}, {43, 58, 10, 29}, {43, 59, 10, 29}, 3393 {44, 40, 10, 29}, {44, 41, 10, 29}, {44, 42, 10, 29}, {44, 43, 10, 29}, {44, 44, 10, 29}, 3394 {44, 45, 10, 29}, {44, 46, 10, 29}, {44, 47, 10, 29}, {44, 48, 10, 29}, {44, 49, 10, 29}, 3395 {44, 50, 10, 29}, {44, 51, 10, 29}, {44, 52, 10, 29}, {44, 53, 10, 29}, {44, 54, 10, 29}, 3396 {44, 55, 10, 29}, {44, 56, 10, 29}, {44, 57, 10, 29}, {44, 58, 10, 29}, {44, 59, 10, 29}, 3397 {45, 40, 10, 29}, {45, 41, 10, 29}, {45, 42, 10, 29}, {45, 43, 10, 29}, {45, 44, 10, 29}, 3398 {45, 45, 10, 29}, {45, 46, 10, 29}, {45, 47, 10, 29}, {45, 48, 10, 29}, {45, 49, 10, 29}, 3399 {45, 50, 10, 29}, {45, 51, 10, 29}, {45, 52, 10, 29}, {45, 53, 10, 29}, {45, 54, 10, 29}, 3400 {45, 55, 10, 29}, {45, 56, 10, 29}, {45, 57, 10, 29}, {45, 58, 10, 29}, {45, 59, 10, 29}, 3401 {46, 40, 10, 29}, {46, 41, 10, 29}, {46, 42, 10, 29}, {46, 43, 10, 29}, {46, 44, 10, 29}, 3402 {46, 45, 10, 29}, {46, 46, 10, 29}, {46, 47, 10, 29}, {46, 48, 10, 29}, {46, 49, 10, 29}, 3403 {46, 50, 10, 29}, {46, 51, 10, 29}, {46, 52, 10, 29}, {46, 53, 10, 29}, {46, 54, 10, 29}, 3404 {46, 55, 10, 29}, {46, 56, 10, 29}, {46, 57, 10, 29}, {46, 58, 10, 29}, {46, 59, 10, 29}, 3405 {47, 40, 10, 29}, {47, 41, 10, 29}, {47, 42, 10, 29}, {47, 43, 10, 29}, {47, 44, 10, 29}, 3406 {47, 45, 10, 29}, {47, 46, 10, 29}, {47, 47, 10, 29}, {47, 48, 10, 29}, {47, 49, 10, 29}, 3407 {47, 50, 10, 29}, {47, 51, 10, 29}, {47, 52, 10, 29}, {47, 53, 10, 29}, {47, 54, 10, 29}, 3408 {47, 55, 10, 29}, {47, 56, 10, 29}, {47, 57, 10, 29}, {47, 58, 10, 29}, {47, 59, 10, 29}, 3409 {48, 40, 10, 29}, {48, 41, 10, 29}, {48, 42, 10, 29}, {48, 43, 10, 29}, {48, 44, 10, 29}, 3410 {48, 45, 10, 29}, {48, 46, 10, 29}, {48, 47, 10, 29}, {48, 48, 10, 29}, {48, 49, 10, 29}, 3411 {48, 50, 10, 29}, {48, 51, 10, 29}, {48, 52, 10, 29}, {48, 53, 10, 29}, {48, 54, 10, 29}, 3412 {48, 55, 10, 29}, {48, 56, 10, 29}, {48, 57, 10, 29}, {48, 58, 10, 29}, {48, 59, 10, 29}, 3413 {49, 40, 10, 29}, {49, 41, 10, 29}, {49, 42, 10, 29}, {49, 43, 10, 29}, {49, 44, 10, 29}, 3414 {49, 45, 10, 29}, {49, 46, 10, 29}, {49, 47, 10, 29}, {49, 48, 10, 29}, {49, 49, 10, 29}, 3415 {49, 50, 10, 29}, {49, 51, 10, 29}, {49, 52, 10, 29}, {49, 53, 10, 29}, {49, 54, 10, 29}, 3416 {49, 55, 10, 29}, {49, 56, 10, 29}, {49, 57, 10, 29}, {49, 58, 10, 29}, {49, 59, 10, 29}, 3417 {50, 40, 10, 29}, {50, 41, 10, 29}, {50, 42, 10, 29}, {50, 43, 10, 29}, {50, 44, 10, 29}, 3418 {50, 45, 10, 29}, {50, 46, 10, 29}, {50, 47, 10, 29}, {50, 48, 10, 29}, {50, 49, 10, 29}, 3419 {50, 50, 10, 29}, {50, 51, 10, 29}, {50, 52, 10, 29}, {50, 53, 10, 29}, {50, 54, 10, 29}, 3420 {50, 55, 10, 29}, {50, 56, 10, 29}, {50, 57, 10, 29}, {50, 58, 10, 29}, {50, 59, 10, 29}, 3421 {51, 40, 10, 29}, {51, 41, 10, 29}, {51, 42, 10, 29}, {51, 43, 10, 29}, {51, 44, 10, 29}, 3422 {51, 45, 10, 29}, {51, 46, 10, 29}, {51, 47, 10, 29}, {51, 48, 10, 29}, {51, 49, 10, 29}, 3423 {51, 50, 10, 29}, {51, 51, 10, 29}, {51, 52, 10, 29}, {51, 53, 10, 29}, {51, 54, 10, 29}, 3424 {51, 55, 10, 29}, {51, 56, 10, 29}, {51, 57, 10, 29}, {51, 58, 10, 29}, {51, 59, 10, 29}, 3425 {52, 40, 10, 29}, {52, 41, 10, 29}, {52, 42, 10, 29}, {52, 43, 10, 29}, {52, 44, 10, 29}, 3426 {52, 45, 10, 29}, {52, 46, 10, 29}, {52, 47, 10, 29}, {52, 48, 10, 29}, {52, 49, 10, 29}, 3427 {52, 50, 10, 29}, {52, 51, 10, 29}, {52, 52, 10, 29}, {52, 53, 10, 29}, {52, 54, 10, 29}, 3428 {52, 55, 10, 29}, {52, 56, 10, 29}, {52, 57, 10, 29}, {52, 58, 10, 29}, {52, 59, 10, 29}, 3429 {53, 40, 10, 29}, {53, 41, 10, 29}, {53, 42, 10, 29}, {53, 43, 10, 29}, {53, 44, 10, 29}, 3430 {53, 45, 10, 29}, {53, 46, 10, 29}, {53, 47, 10, 29}, {53, 48, 10, 29}, {53, 49, 10, 29}, 3431 {53, 50, 10, 29}, {53, 51, 10, 29}, {53, 52, 10, 29}, {53, 53, 10, 29}, {53, 54, 10, 29}, 3432 {53, 55, 10, 29}, {53, 56, 10, 29}, {53, 57, 10, 29}, {53, 58, 10, 29}, {53, 59, 10, 29}, 3433 {54, 40, 10, 29}, {54, 41, 10, 29}, {54, 42, 10, 29}, {54, 43, 10, 29}, {54, 44, 10, 29}, 3434 {54, 45, 10, 29}, {54, 46, 10, 29}, {54, 47, 10, 29}, {54, 48, 10, 29}, {54, 49, 10, 29}, 3435 {54, 50, 10, 29}, {54, 51, 10, 29}, {54, 52, 10, 29}, {54, 53, 10, 29}, {54, 54, 10, 29}, 3436 {54, 55, 10, 29}, {54, 56, 10, 29}, {54, 57, 10, 29}, {54, 58, 10, 29}, {54, 59, 10, 29}, 3437 {55, 40, 10, 29}, {55, 41, 10, 29}, {55, 42, 10, 29}, {55, 43, 10, 29}, {55, 44, 10, 29}, 3438 {55, 45, 10, 29}, {55, 46, 10, 29}, {55, 47, 10, 29}, {55, 48, 10, 29}, {55, 49, 10, 29}, 3439 {55, 50, 10, 29}, {55, 51, 10, 29}, {55, 52, 10, 29}, {55, 53, 10, 29}, {55, 54, 10, 29}, 3440 {55, 55, 10, 29}, {55, 56, 10, 29}, {55, 57, 10, 29}, {55, 58, 10, 29}, {55, 59, 10, 29}, 3441 {56, 40, 10, 29}, {56, 41, 10, 29}, {56, 42, 10, 29}, {56, 43, 10, 29}, {56, 44, 10, 29}, 3442 {56, 45, 10, 29}, {56, 46, 10, 29}, {56, 47, 10, 29}, {56, 48, 10, 29}, {56, 49, 10, 29}, 3443 {56, 50, 10, 29}, {56, 51, 10, 29}, {56, 52, 10, 29}, {56, 53, 10, 29}, {56, 54, 10, 29}, 3444 {56, 55, 10, 29}, {56, 56, 10, 29}, {56, 57, 10, 29}, {56, 58, 10, 29}, {56, 59, 10, 29}, 3445 {57, 40, 10, 29}, {57, 41, 10, 29}, {57, 42, 10, 29}, {57, 43, 10, 29}, {57, 44, 10, 29}, 3446 {57, 45, 10, 29}, {57, 46, 10, 29}, {57, 47, 10, 29}, {57, 48, 10, 29}, {57, 49, 10, 29}, 3447 {57, 50, 10, 29}, {57, 51, 10, 29}, {57, 52, 10, 29}, {57, 53, 10, 29}, {57, 54, 10, 29}, 3448 {57, 55, 10, 29}, {57, 56, 10, 29}, {57, 57, 10, 29}, {57, 58, 10, 29}, {57, 59, 10, 29}, 3449 {58, 40, 10, 29}, {58, 41, 10, 29}, {58, 42, 10, 29}, {58, 43, 10, 29}, {58, 44, 10, 29}, 3450 {58, 45, 10, 29}, {58, 46, 10, 29}, {58, 47, 10, 29}, {58, 48, 10, 29}, {58, 49, 10, 29}, 3451 {58, 50, 10, 29}, {58, 51, 10, 29}, {58, 52, 10, 29}, {58, 53, 10, 29}, {58, 54, 10, 29}, 3452 {58, 55, 10, 29}, {58, 56, 10, 29}, {58, 57, 10, 29}, {58, 58, 10, 29}, {58, 59, 10, 29}, 3453 {59, 40, 10, 29}, {59, 41, 10, 29}, {59, 42, 10, 29}, {59, 43, 10, 29}, {59, 44, 10, 29}, 3454 {59, 45, 10, 29}, {59, 46, 10, 29}, {59, 47, 10, 29}, {59, 48, 10, 29}, {59, 49, 10, 29}, 3455 {59, 50, 10, 29}, {59, 51, 10, 29}, {59, 52, 10, 29}, {59, 53, 10, 29}, {59, 54, 10, 29}, 3456 {59, 55, 10, 29}, {59, 56, 10, 29}, {59, 57, 10, 29}, {59, 58, 10, 29}, {59, 59, 10, 29}, 3457 {60, 40, 10, 29}, {60, 41, 10, 29}, {60, 42, 10, 29}, {60, 43, 10, 29}, {60, 44, 10, 29}, 3458 {60, 45, 10, 29}, {60, 46, 10, 29}, {60, 47, 10, 29}, {60, 48, 10, 29}, {60, 49, 10, 29}, 3459 {60, 50, 10, 29}, {60, 51, 10, 29}, {60, 52, 10, 29}, {60, 53, 10, 29}, {60, 54, 10, 29}, 3460 {60, 55, 10, 29}, {60, 56, 10, 29}, {60, 57, 10, 29}, {60, 58, 10, 29}, {60, 59, 10, 29}, 3461 {61, 40, 10, 29}, {61, 41, 10, 29}, {61, 42, 10, 29}, {61, 43, 10, 29}, {61, 44, 10, 29}, 3462 {61, 45, 10, 29}, {61, 46, 10, 29}, {61, 47, 10, 29}, {61, 48, 10, 29}, {61, 49, 10, 29}, 3463 {61, 50, 10, 29}, {61, 51, 10, 29}, {61, 52, 10, 29}, {61, 53, 10, 29}, {61, 54, 10, 29}, 3464 {61, 55, 10, 29}, {61, 56, 10, 29}, {61, 57, 10, 29}, {61, 58, 10, 29}, {61, 59, 10, 29}, 3465 {62, 40, 10, 29}, {62, 41, 10, 29}, {62, 42, 10, 29}, {62, 43, 10, 29}, {62, 44, 10, 29}, 3466 {62, 45, 10, 29}, {62, 46, 10, 29}, {62, 47, 10, 29}, {62, 48, 10, 29}, {62, 49, 10, 29}, 3467 {62, 50, 10, 29}, {62, 51, 10, 29}, {62, 52, 10, 29}, {62, 53, 10, 29}, {62, 54, 10, 29}, 3468 {62, 55, 10, 29}, {62, 56, 10, 29}, {62, 57, 10, 29}, {62, 58, 10, 29}, {62, 59, 10, 29}, 3469 {63, 40, 10, 29}, {63, 41, 10, 29}, {63, 42, 10, 29}, {63, 43, 10, 29}, {63, 44, 10, 29}, 3470 {63, 45, 10, 29}, {63, 46, 10, 29}, {63, 47, 10, 29}, {63, 48, 10, 29}, {63, 49, 10, 29}, 3471 {63, 50, 10, 29}, {63, 51, 10, 29}, {63, 52, 10, 29}, {63, 53, 10, 29}, {63, 54, 10, 29}, 3472 {63, 55, 10, 29}, {63, 56, 10, 29}, {63, 57, 10, 29}, {63, 58, 10, 29}, {63, 59, 10, 29}, 3473 {64, 40, 10, 29}, {64, 41, 10, 29}, {64, 42, 10, 29}, {64, 43, 10, 29}, {64, 44, 10, 29}, 3474 {64, 45, 10, 29}, {64, 46, 10, 29}, {64, 47, 10, 29}, {64, 48, 10, 29}, {64, 49, 10, 29}, 3475 {64, 50, 10, 29}, {64, 51, 10, 29}, {64, 52, 10, 29}, {64, 53, 10, 29}, {64, 54, 10, 29}, 3476 {64, 55, 10, 29}, {64, 56, 10, 29}, {64, 57, 10, 29}, {64, 58, 10, 29}, {64, 59, 10, 29}, 3477 {65, 40, 10, 29}, {65, 41, 10, 29}, {65, 42, 10, 29}, {65, 43, 10, 29}, {65, 44, 10, 29}, 3478 {65, 45, 10, 29}, {65, 46, 10, 29}, {65, 47, 10, 29}, {65, 48, 10, 29}, {65, 49, 10, 29}, 3479 {65, 50, 10, 29}, {65, 51, 10, 29}, {65, 52, 10, 29}, {65, 53, 10, 29}, {65, 54, 10, 29}, 3480 {65, 55, 10, 29}, {65, 56, 10, 29}, {65, 57, 10, 29}, {65, 58, 10, 29}, {65, 59, 10, 29}, 3481 {66, 40, 10, 29}, {66, 41, 10, 29}, {66, 42, 10, 29}, {66, 43, 10, 29}, {66, 44, 10, 29}, 3482 {66, 45, 10, 29}, {66, 46, 10, 29}, {66, 47, 10, 29}, {66, 48, 10, 29}, {66, 49, 10, 29}, 3483 {66, 50, 10, 29}, {66, 51, 10, 29}, {66, 52, 10, 29}, {66, 53, 10, 29}, {66, 54, 10, 29}, 3484 {66, 55, 10, 29}, {66, 56, 10, 29}, {66, 57, 10, 29}, {66, 58, 10, 29}, {66, 59, 10, 29}, 3485 {67, 40, 10, 29}, {67, 41, 10, 29}, {67, 42, 10, 29}, {67, 43, 10, 29}, {67, 44, 10, 29}, 3486 {67, 45, 10, 29}, {67, 46, 10, 29}, {67, 47, 10, 29}, {67, 48, 10, 29}, {67, 49, 10, 29}, 3487 {67, 50, 10, 29}, {67, 51, 10, 29}, {67, 52, 10, 29}, {67, 53, 10, 29}, {67, 54, 10, 29}, 3488 {67, 55, 10, 29}, {67, 56, 10, 29}, {67, 57, 10, 29}, {67, 58, 10, 29}, {67, 59, 10, 29}, 3489 {68, 40, 10, 29}, {68, 41, 10, 29}, {68, 42, 10, 29}, {68, 43, 10, 29}, {68, 44, 10, 29}, 3490 {68, 45, 10, 29}, {68, 46, 10, 29}, {68, 47, 10, 29}, {68, 48, 10, 29}, {68, 49, 10, 29}, 3491 {68, 50, 10, 29}, {68, 51, 10, 29}, {68, 52, 10, 29}, {68, 53, 10, 29}, {68, 54, 10, 29}, 3492 {68, 55, 10, 29}, {68, 56, 10, 29}, {68, 57, 10, 29}, {68, 58, 10, 29}, {68, 59, 10, 29}, 3493 {69, 40, 10, 29}, {69, 41, 10, 29}, {69, 42, 10, 29}, {69, 43, 10, 29}, {69, 44, 10, 29}, 3494 {69, 45, 10, 29}, {69, 46, 10, 29}, {69, 47, 10, 29}, {69, 48, 10, 29}, {69, 49, 10, 29}, 3495 {69, 50, 10, 29}, {69, 51, 10, 29}, {69, 52, 10, 29}, {69, 53, 10, 29}, {69, 54, 10, 29}, 3496 {69, 55, 10, 29}, {69, 56, 10, 29}, {69, 57, 10, 29}, {69, 58, 10, 29}, {69, 59, 10, 29}, 3497 {70, 40, 10, 29}, {70, 41, 10, 29}, {70, 42, 10, 29}, {70, 43, 10, 29}, {70, 44, 10, 29}, 3498 {70, 45, 10, 29}, {70, 46, 10, 29}, {70, 47, 10, 29}, {70, 48, 10, 29}, {70, 49, 10, 29}, 3499 {70, 50, 10, 29}, {70, 51, 10, 29}, {70, 52, 10, 29}, {70, 53, 10, 29}, {70, 54, 10, 29}, 3500 {70, 55, 10, 29}, {70, 56, 10, 29}, {70, 57, 10, 29}, {70, 58, 10, 29}, {70, 59, 10, 29}, 3501 {71, 40, 10, 29}, {71, 41, 10, 29}, {71, 42, 10, 29}, {71, 43, 10, 29}, {71, 44, 10, 29}, 3502 {71, 45, 10, 29}, {71, 46, 10, 29}, {71, 47, 10, 29}, {71, 48, 10, 29}, {71, 49, 10, 29}, 3503 {71, 50, 10, 29}, {71, 51, 10, 29}, {71, 52, 10, 29}, {71, 53, 10, 29}, {71, 54, 10, 29}, 3504 {71, 55, 10, 29}, {71, 56, 10, 29}, {71, 57, 10, 29}, {71, 58, 10, 29}, {71, 59, 10, 29}, 3505 {72, 40, 10, 29}, {72, 41, 10, 29}, {72, 42, 10, 29}, {72, 43, 10, 29}, {72, 44, 10, 29}, 3506 {72, 45, 10, 29}, {72, 46, 10, 29}, {72, 47, 10, 29}, {72, 48, 10, 29}, {72, 49, 10, 29}, 3507 {72, 50, 10, 29}, {72, 51, 10, 29}, {72, 52, 10, 29}, {72, 53, 10, 29}, {72, 54, 10, 29}, 3508 {72, 55, 10, 29}, {72, 56, 10, 29}, {72, 57, 10, 29}, {72, 58, 10, 29}, {72, 59, 10, 29}, 3509 {73, 40, 10, 29}, {73, 41, 10, 29}, {73, 42, 10, 29}, {73, 43, 10, 29}, {73, 44, 10, 29}, 3510 {73, 45, 10, 29}, {73, 46, 10, 29}, {73, 47, 10, 29}, {73, 48, 10, 29}, {73, 49, 10, 29}, 3511 {73, 50, 10, 29}, {73, 51, 10, 29}, {73, 52, 10, 29}, {73, 53, 10, 29}, {73, 54, 10, 29}, 3512 {73, 55, 10, 29}, {73, 56, 10, 29}, {73, 57, 10, 29}, {73, 58, 10, 29}, {73, 59, 10, 29}, 3513 {74, 40, 10, 29}, {74, 41, 10, 29}, {74, 42, 10, 29}, {74, 43, 10, 29}, {74, 44, 10, 29}, 3514 {74, 45, 10, 29}, {74, 46, 10, 29}, {74, 47, 10, 29}, {74, 48, 10, 29}, {74, 49, 10, 29}, 3515 {74, 50, 10, 29}, {74, 51, 10, 29}, {74, 52, 10, 29}, {74, 53, 10, 29}, {74, 54, 10, 29}, 3516 {74, 55, 10, 29}, {74, 56, 10, 29}, {74, 57, 10, 29}, {74, 58, 10, 29}, {74, 59, 10, 29}, 3517 {75, 40, 10, 29}, {75, 41, 10, 29}, {75, 42, 10, 29}, {75, 43, 10, 29}, {75, 44, 10, 29}, 3518 {75, 45, 10, 29}, {75, 46, 10, 29}, {75, 47, 10, 29}, {75, 48, 10, 29}, {75, 49, 10, 29}, 3519 {75, 50, 10, 29}, {75, 51, 10, 29}, {75, 52, 10, 29}, {75, 53, 10, 29}, {75, 54, 10, 29}, 3520 {75, 55, 10, 29}, {75, 56, 10, 29}, {75, 57, 10, 29}, {75, 58, 10, 29}, {75, 59, 10, 29}, 3521 {76, 40, 10, 29}, {76, 41, 10, 29}, {76, 42, 10, 29}, {76, 43, 10, 29}, {76, 44, 10, 29}, 3522 {76, 45, 10, 29}, {76, 46, 10, 29}, {76, 47, 10, 29}, {76, 48, 10, 29}, {76, 49, 10, 29}, 3523 {76, 50, 10, 29}, {76, 51, 10, 29}, {76, 52, 10, 29}, {76, 53, 10, 29}, {76, 54, 10, 29}, 3524 {76, 55, 10, 29}, {76, 56, 10, 29}, {76, 57, 10, 29}, {76, 58, 10, 29}, {76, 59, 10, 29}, 3525 {77, 40, 10, 29}, {77, 41, 10, 29}, {77, 42, 10, 29}, {77, 43, 10, 29}, {77, 44, 10, 29}, 3526 {77, 45, 10, 29}, {77, 46, 10, 29}, {77, 47, 10, 29}, {77, 48, 10, 29}, {77, 49, 10, 29}, 3527 {77, 50, 10, 29}, {77, 51, 10, 29}, {77, 52, 10, 29}, {77, 53, 10, 29}, {77, 54, 10, 29}, 3528 {77, 55, 10, 29}, {77, 56, 10, 29}, {77, 57, 10, 29}, {77, 58, 10, 29}, {77, 59, 10, 29}, 3529 {78, 40, 10, 29}, {78, 41, 10, 29}, {78, 42, 10, 29}, {78, 43, 10, 29}, {78, 44, 10, 29}, 3530 {78, 45, 10, 29}, {78, 46, 10, 29}, {78, 47, 10, 29}, {78, 48, 10, 29}, {78, 49, 10, 29}, 3531 {78, 50, 10, 29}, {78, 51, 10, 29}, {78, 52, 10, 29}, {78, 53, 10, 29}, {78, 54, 10, 29}, 3532 {78, 55, 10, 29}, {78, 56, 10, 29}, {78, 57, 10, 29}, {78, 58, 10, 29}, {78, 59, 10, 29}, 3533 {79, 40, 10, 29}, {79, 41, 10, 29}, {79, 42, 10, 29}, {79, 43, 10, 29}, {79, 44, 10, 29}, 3534 {79, 45, 10, 29}, {79, 46, 10, 29}, {79, 47, 10, 29}, {79, 48, 10, 29}, {79, 49, 10, 29}, 3535 {79, 50, 10, 29}, {79, 51, 10, 29}, {79, 52, 10, 29}, {79, 53, 10, 29}, {79, 54, 10, 29}, 3536 {79, 55, 10, 29}, {79, 56, 10, 29}, {79, 57, 10, 29}, {79, 58, 10, 29}, {79, 59, 10, 29}, 3537 {80, 40, 10, 29}, {80, 41, 10, 29}, {80, 42, 10, 29}, {80, 43, 10, 29}, {80, 44, 10, 29}, 3538 {80, 45, 10, 29}, {80, 46, 10, 29}, {80, 47, 10, 29}, {80, 48, 10, 29}, {80, 49, 10, 29}, 3539 {80, 50, 10, 29}, {80, 51, 10, 29}, {80, 52, 10, 29}, {80, 53, 10, 29}, {80, 54, 10, 29}, 3540 {80, 55, 10, 29}, {80, 56, 10, 29}, {80, 57, 10, 29}, {80, 58, 10, 29}, {80, 59, 10, 29}, 3541 {81, 40, 10, 29}, {81, 41, 10, 29}, {81, 42, 10, 29}, {81, 43, 10, 29}, {81, 44, 10, 29}, 3542 {81, 45, 10, 29}, {81, 46, 10, 29}, {81, 47, 10, 29}, {81, 48, 10, 29}, {81, 49, 10, 29}, 3543 {81, 50, 10, 29}, {81, 51, 10, 29}, {81, 52, 10, 29}, {81, 53, 10, 29}, {81, 54, 10, 29}, 3544 {81, 55, 10, 29}, {81, 56, 10, 29}, {81, 57, 10, 29}, {81, 58, 10, 29}, {81, 59, 10, 29}, 3545 {82, 40, 10, 29}, {82, 41, 10, 29}, {82, 42, 10, 29}, {82, 43, 10, 29}, {82, 44, 10, 29}, 3546 {82, 45, 10, 29}, {82, 46, 10, 29}, {82, 47, 10, 29}, {82, 48, 10, 29}, {82, 49, 10, 29}, 3547 {82, 50, 10, 29}, {82, 51, 10, 29}, {82, 52, 10, 29}, {82, 53, 10, 29}, {82, 54, 10, 29}, 3548 {82, 55, 10, 29}, {82, 56, 10, 29}, {82, 57, 10, 29}, {82, 58, 10, 29}, {82, 59, 10, 29}, 3549 {83, 40, 10, 29}, {83, 41, 10, 29}, {83, 42, 10, 29}, {83, 43, 10, 29}, {83, 44, 10, 29}, 3550 {83, 45, 10, 29}, {83, 46, 10, 29}, {83, 47, 10, 29}, {83, 48, 10, 29}, {83, 49, 10, 29}, 3551 {83, 50, 10, 29}, {83, 51, 10, 29}, {83, 52, 10, 29}, {83, 53, 10, 29}, {83, 54, 10, 29}, 3552 {83, 55, 10, 29}, {83, 56, 10, 29}, {83, 57, 10, 29}, {83, 58, 10, 29}, {83, 59, 10, 29}, 3553 {84, 40, 10, 29}, {84, 41, 10, 29}, {84, 42, 10, 29}, {84, 43, 10, 29}, {84, 44, 10, 29}, 3554 {84, 45, 10, 29}, {84, 46, 10, 29}, {84, 47, 10, 29}, {84, 48, 10, 29}, {84, 49, 10, 29}, 3555 {84, 50, 10, 29}, {84, 51, 10, 29}, {84, 52, 10, 29}, {84, 53, 10, 29}, {84, 54, 10, 29}, 3556 {84, 55, 10, 29}, {84, 56, 10, 29}, {84, 57, 10, 29}, {84, 58, 10, 29}, {84, 59, 10, 29}, 3557 {85, 40, 10, 29}, {85, 41, 10, 29}, {85, 42, 10, 29}, {85, 43, 10, 29}, {85, 44, 10, 29}, 3558 {85, 45, 10, 29}, {85, 46, 10, 29}, {85, 47, 10, 29}, {85, 48, 10, 29}, {85, 49, 10, 29}, 3559 {85, 50, 10, 29}, {85, 51, 10, 29}, {85, 52, 10, 29}, {85, 53, 10, 29}, {85, 54, 10, 29}, 3560 {85, 55, 10, 29}, {85, 56, 10, 29}, {85, 57, 10, 29}, {85, 58, 10, 29}, {85, 59, 10, 29}, 3561 {86, 40, 10, 29}, {86, 41, 10, 29}, {86, 42, 10, 29}, {86, 43, 10, 29}, {86, 44, 10, 29}, 3562 {86, 45, 10, 29}, {86, 46, 10, 29}, {86, 47, 10, 29}, {86, 48, 10, 29}, {86, 49, 10, 29}, 3563 {86, 50, 10, 29}, {86, 51, 10, 29}, {86, 52, 10, 29}, {86, 53, 10, 29}, {86, 54, 10, 29}, 3564 {86, 55, 10, 29}, {86, 56, 10, 29}, {86, 57, 10, 29}, {86, 58, 10, 29}, {86, 59, 10, 29}, 3565 {87, 40, 10, 29}, {87, 41, 10, 29}, {87, 42, 10, 29}, {87, 43, 10, 29}, {87, 44, 10, 29}, 3566 {87, 45, 10, 29}, {87, 46, 10, 29}, {87, 47, 10, 29}, {87, 48, 10, 29}, {87, 49, 10, 29}, 3567 {87, 50, 10, 29}, {87, 51, 10, 29}, {87, 52, 10, 29}, {87, 53, 10, 29}, {87, 54, 10, 29}, 3568 {87, 55, 10, 29}, {87, 56, 10, 29}, {87, 57, 10, 29}, {87, 58, 10, 29}, {87, 59, 10, 29}, 3569 {88, 40, 10, 29}, {88, 41, 10, 29}, {88, 42, 10, 29}, {88, 43, 10, 29}, {88, 44, 10, 29}, 3570 {88, 45, 10, 29}, {88, 46, 10, 29}, {88, 47, 10, 29}, {88, 48, 10, 29}, {88, 49, 10, 29}, 3571 {88, 50, 10, 29}, {88, 51, 10, 29}, {88, 52, 10, 29}, {88, 53, 10, 29}, {88, 54, 10, 29}, 3572 {88, 55, 10, 29}, {88, 56, 10, 29}, {88, 57, 10, 29}, {88, 58, 10, 29}, {88, 59, 10, 29}, 3573 {89, 40, 10, 29}, {89, 41, 10, 29}, {89, 42, 10, 29}, {89, 43, 10, 29}, {89, 44, 10, 29}, 3574 {89, 45, 10, 29}, {89, 46, 10, 29}, {89, 47, 10, 29}, {89, 48, 10, 29}, {89, 49, 10, 29}, 3575 {89, 50, 10, 29}, {89, 51, 10, 29}, {89, 52, 10, 29}, {89, 53, 10, 29}, {89, 54, 10, 29}, 3576 {89, 55, 10, 29}, {89, 56, 10, 29}, {89, 57, 10, 29}, {89, 58, 10, 29}, {89, 59, 10, 29}, 3577 }, 3578 } 3579 body2 = testBody{ 3580 label: 2, 3581 offset: dvid.Point3d{30, 20, 40}, 3582 size: dvid.Point3d{50, 50, 20}, 3583 blockSpans: []dvid.Span{ 3584 {1, 0, 0, 2}, 3585 {1, 1, 0, 2}, 3586 {1, 2, 0, 2}, 3587 }, 3588 voxelSpans: []dvid.Span{ 3589 {40, 20, 30, 31}, {40, 21, 30, 31}, {40, 22, 30, 31}, {40, 23, 30, 31}, {40, 24, 30, 31}, 3590 {40, 25, 30, 31}, {40, 26, 30, 31}, {40, 27, 30, 31}, {40, 28, 30, 31}, {40, 29, 30, 31}, 3591 {40, 30, 30, 31}, {40, 31, 30, 31}, {41, 20, 30, 31}, {41, 21, 30, 31}, {41, 22, 30, 31}, 3592 {41, 23, 30, 31}, {41, 24, 30, 31}, {41, 25, 30, 31}, {41, 26, 30, 31}, {41, 27, 30, 31}, 3593 {41, 28, 30, 31}, {41, 29, 30, 31}, {41, 30, 30, 31}, {41, 31, 30, 31}, {42, 20, 30, 31}, 3594 {42, 21, 30, 31}, {42, 22, 30, 31}, {42, 23, 30, 31}, {42, 24, 30, 31}, {42, 25, 30, 31}, 3595 {42, 26, 30, 31}, {42, 27, 30, 31}, {42, 28, 30, 31}, {42, 29, 30, 31}, {42, 30, 30, 31}, 3596 {42, 31, 30, 31}, {43, 20, 30, 31}, {43, 21, 30, 31}, {43, 22, 30, 31}, {43, 23, 30, 31}, 3597 {43, 24, 30, 31}, {43, 25, 30, 31}, {43, 26, 30, 31}, {43, 27, 30, 31}, {43, 28, 30, 31}, 3598 {43, 29, 30, 31}, {43, 30, 30, 31}, {43, 31, 30, 31}, {44, 20, 30, 31}, {44, 21, 30, 31}, 3599 {44, 22, 30, 31}, {44, 23, 30, 31}, {44, 24, 30, 31}, {44, 25, 30, 31}, {44, 26, 30, 31}, 3600 {44, 27, 30, 31}, {44, 28, 30, 31}, {44, 29, 30, 31}, {44, 30, 30, 31}, {44, 31, 30, 31}, 3601 {45, 20, 30, 31}, {45, 21, 30, 31}, {45, 22, 30, 31}, {45, 23, 30, 31}, {45, 24, 30, 31}, 3602 {45, 25, 30, 31}, {45, 26, 30, 31}, {45, 27, 30, 31}, {45, 28, 30, 31}, {45, 29, 30, 31}, 3603 {45, 30, 30, 31}, {45, 31, 30, 31}, {46, 20, 30, 31}, {46, 21, 30, 31}, {46, 22, 30, 31}, 3604 {46, 23, 30, 31}, {46, 24, 30, 31}, {46, 25, 30, 31}, {46, 26, 30, 31}, {46, 27, 30, 31}, 3605 {46, 28, 30, 31}, {46, 29, 30, 31}, {46, 30, 30, 31}, {46, 31, 30, 31}, {47, 20, 30, 31}, 3606 {47, 21, 30, 31}, {47, 22, 30, 31}, {47, 23, 30, 31}, {47, 24, 30, 31}, {47, 25, 30, 31}, 3607 {47, 26, 30, 31}, {47, 27, 30, 31}, {47, 28, 30, 31}, {47, 29, 30, 31}, {47, 30, 30, 31}, 3608 {47, 31, 30, 31}, {48, 20, 30, 31}, {48, 21, 30, 31}, {48, 22, 30, 31}, {48, 23, 30, 31}, 3609 {48, 24, 30, 31}, {48, 25, 30, 31}, {48, 26, 30, 31}, {48, 27, 30, 31}, {48, 28, 30, 31}, 3610 {48, 29, 30, 31}, {48, 30, 30, 31}, {48, 31, 30, 31}, {49, 20, 30, 31}, {49, 21, 30, 31}, 3611 {49, 22, 30, 31}, {49, 23, 30, 31}, {49, 24, 30, 31}, {49, 25, 30, 31}, {49, 26, 30, 31}, 3612 {49, 27, 30, 31}, {49, 28, 30, 31}, {49, 29, 30, 31}, {49, 30, 30, 31}, {49, 31, 30, 31}, 3613 {50, 20, 30, 31}, {50, 21, 30, 31}, {50, 22, 30, 31}, {50, 23, 30, 31}, {50, 24, 30, 31}, 3614 {50, 25, 30, 31}, {50, 26, 30, 31}, {50, 27, 30, 31}, {50, 28, 30, 31}, {50, 29, 30, 31}, 3615 {50, 30, 30, 31}, {50, 31, 30, 31}, {51, 20, 30, 31}, {51, 21, 30, 31}, {51, 22, 30, 31}, 3616 {51, 23, 30, 31}, {51, 24, 30, 31}, {51, 25, 30, 31}, {51, 26, 30, 31}, {51, 27, 30, 31}, 3617 {51, 28, 30, 31}, {51, 29, 30, 31}, {51, 30, 30, 31}, {51, 31, 30, 31}, {52, 20, 30, 31}, 3618 {52, 21, 30, 31}, {52, 22, 30, 31}, {52, 23, 30, 31}, {52, 24, 30, 31}, {52, 25, 30, 31}, 3619 {52, 26, 30, 31}, {52, 27, 30, 31}, {52, 28, 30, 31}, {52, 29, 30, 31}, {52, 30, 30, 31}, 3620 {52, 31, 30, 31}, {53, 20, 30, 31}, {53, 21, 30, 31}, {53, 22, 30, 31}, {53, 23, 30, 31}, 3621 {53, 24, 30, 31}, {53, 25, 30, 31}, {53, 26, 30, 31}, {53, 27, 30, 31}, {53, 28, 30, 31}, 3622 {53, 29, 30, 31}, {53, 30, 30, 31}, {53, 31, 30, 31}, {54, 20, 30, 31}, {54, 21, 30, 31}, 3623 {54, 22, 30, 31}, {54, 23, 30, 31}, {54, 24, 30, 31}, {54, 25, 30, 31}, {54, 26, 30, 31}, 3624 {54, 27, 30, 31}, {54, 28, 30, 31}, {54, 29, 30, 31}, {54, 30, 30, 31}, {54, 31, 30, 31}, 3625 {55, 20, 30, 31}, {55, 21, 30, 31}, {55, 22, 30, 31}, {55, 23, 30, 31}, {55, 24, 30, 31}, 3626 {55, 25, 30, 31}, {55, 26, 30, 31}, {55, 27, 30, 31}, {55, 28, 30, 31}, {55, 29, 30, 31}, 3627 {55, 30, 30, 31}, {55, 31, 30, 31}, {56, 20, 30, 31}, {56, 21, 30, 31}, {56, 22, 30, 31}, 3628 {56, 23, 30, 31}, {56, 24, 30, 31}, {56, 25, 30, 31}, {56, 26, 30, 31}, {56, 27, 30, 31}, 3629 {56, 28, 30, 31}, {56, 29, 30, 31}, {56, 30, 30, 31}, {56, 31, 30, 31}, {57, 20, 30, 31}, 3630 {57, 21, 30, 31}, {57, 22, 30, 31}, {57, 23, 30, 31}, {57, 24, 30, 31}, {57, 25, 30, 31}, 3631 {57, 26, 30, 31}, {57, 27, 30, 31}, {57, 28, 30, 31}, {57, 29, 30, 31}, {57, 30, 30, 31}, 3632 {57, 31, 30, 31}, {58, 20, 30, 31}, {58, 21, 30, 31}, {58, 22, 30, 31}, {58, 23, 30, 31}, 3633 {58, 24, 30, 31}, {58, 25, 30, 31}, {58, 26, 30, 31}, {58, 27, 30, 31}, {58, 28, 30, 31}, 3634 {58, 29, 30, 31}, {58, 30, 30, 31}, {58, 31, 30, 31}, {59, 20, 30, 31}, {59, 21, 30, 31}, 3635 {59, 22, 30, 31}, {59, 23, 30, 31}, {59, 24, 30, 31}, {59, 25, 30, 31}, {59, 26, 30, 31}, 3636 {59, 27, 30, 31}, {59, 28, 30, 31}, {59, 29, 30, 31}, {59, 30, 30, 31}, {59, 31, 30, 31}, 3637 {40, 20, 32, 63}, {40, 21, 32, 63}, {40, 22, 32, 63}, {40, 23, 32, 63}, {40, 24, 32, 63}, 3638 {40, 25, 32, 63}, {40, 26, 32, 63}, {40, 27, 32, 63}, {40, 28, 32, 63}, {40, 29, 32, 63}, 3639 {40, 30, 32, 63}, {40, 31, 32, 63}, {41, 20, 32, 63}, {41, 21, 32, 63}, {41, 22, 32, 63}, 3640 {41, 23, 32, 63}, {41, 24, 32, 63}, {41, 25, 32, 63}, {41, 26, 32, 63}, {41, 27, 32, 63}, 3641 {41, 28, 32, 63}, {41, 29, 32, 63}, {41, 30, 32, 63}, {41, 31, 32, 63}, {42, 20, 32, 63}, 3642 {42, 21, 32, 63}, {42, 22, 32, 63}, {42, 23, 32, 63}, {42, 24, 32, 63}, {42, 25, 32, 63}, 3643 {42, 26, 32, 63}, {42, 27, 32, 63}, {42, 28, 32, 63}, {42, 29, 32, 63}, {42, 30, 32, 63}, 3644 {42, 31, 32, 63}, {43, 20, 32, 63}, {43, 21, 32, 63}, {43, 22, 32, 63}, {43, 23, 32, 63}, 3645 {43, 24, 32, 63}, {43, 25, 32, 63}, {43, 26, 32, 63}, {43, 27, 32, 63}, {43, 28, 32, 63}, 3646 {43, 29, 32, 63}, {43, 30, 32, 63}, {43, 31, 32, 63}, {44, 20, 32, 63}, {44, 21, 32, 63}, 3647 {44, 22, 32, 63}, {44, 23, 32, 63}, {44, 24, 32, 63}, {44, 25, 32, 63}, {44, 26, 32, 63}, 3648 {44, 27, 32, 63}, {44, 28, 32, 63}, {44, 29, 32, 63}, {44, 30, 32, 63}, {44, 31, 32, 63}, 3649 {45, 20, 32, 63}, {45, 21, 32, 63}, {45, 22, 32, 63}, {45, 23, 32, 63}, {45, 24, 32, 63}, 3650 {45, 25, 32, 63}, {45, 26, 32, 63}, {45, 27, 32, 63}, {45, 28, 32, 63}, {45, 29, 32, 63}, 3651 {45, 30, 32, 63}, {45, 31, 32, 63}, {46, 20, 32, 63}, {46, 21, 32, 63}, {46, 22, 32, 63}, 3652 {46, 23, 32, 63}, {46, 24, 32, 63}, {46, 25, 32, 63}, {46, 26, 32, 63}, {46, 27, 32, 63}, 3653 {46, 28, 32, 63}, {46, 29, 32, 63}, {46, 30, 32, 63}, {46, 31, 32, 63}, {47, 20, 32, 63}, 3654 {47, 21, 32, 63}, {47, 22, 32, 63}, {47, 23, 32, 63}, {47, 24, 32, 63}, {47, 25, 32, 63}, 3655 {47, 26, 32, 63}, {47, 27, 32, 63}, {47, 28, 32, 63}, {47, 29, 32, 63}, {47, 30, 32, 63}, 3656 {47, 31, 32, 63}, {48, 20, 32, 63}, {48, 21, 32, 63}, {48, 22, 32, 63}, {48, 23, 32, 63}, 3657 {48, 24, 32, 63}, {48, 25, 32, 63}, {48, 26, 32, 63}, {48, 27, 32, 63}, {48, 28, 32, 63}, 3658 {48, 29, 32, 63}, {48, 30, 32, 63}, {48, 31, 32, 63}, {49, 20, 32, 63}, {49, 21, 32, 63}, 3659 {49, 22, 32, 63}, {49, 23, 32, 63}, {49, 24, 32, 63}, {49, 25, 32, 63}, {49, 26, 32, 63}, 3660 {49, 27, 32, 63}, {49, 28, 32, 63}, {49, 29, 32, 63}, {49, 30, 32, 63}, {49, 31, 32, 63}, 3661 {50, 20, 32, 63}, {50, 21, 32, 63}, {50, 22, 32, 63}, {50, 23, 32, 63}, {50, 24, 32, 63}, 3662 {50, 25, 32, 63}, {50, 26, 32, 63}, {50, 27, 32, 63}, {50, 28, 32, 63}, {50, 29, 32, 63}, 3663 {50, 30, 32, 63}, {50, 31, 32, 63}, {51, 20, 32, 63}, {51, 21, 32, 63}, {51, 22, 32, 63}, 3664 {51, 23, 32, 63}, {51, 24, 32, 63}, {51, 25, 32, 63}, {51, 26, 32, 63}, {51, 27, 32, 63}, 3665 {51, 28, 32, 63}, {51, 29, 32, 63}, {51, 30, 32, 63}, {51, 31, 32, 63}, {52, 20, 32, 63}, 3666 {52, 21, 32, 63}, {52, 22, 32, 63}, {52, 23, 32, 63}, {52, 24, 32, 63}, {52, 25, 32, 63}, 3667 {52, 26, 32, 63}, {52, 27, 32, 63}, {52, 28, 32, 63}, {52, 29, 32, 63}, {52, 30, 32, 63}, 3668 {52, 31, 32, 63}, {53, 20, 32, 63}, {53, 21, 32, 63}, {53, 22, 32, 63}, {53, 23, 32, 63}, 3669 {53, 24, 32, 63}, {53, 25, 32, 63}, {53, 26, 32, 63}, {53, 27, 32, 63}, {53, 28, 32, 63}, 3670 {53, 29, 32, 63}, {53, 30, 32, 63}, {53, 31, 32, 63}, {54, 20, 32, 63}, {54, 21, 32, 63}, 3671 {54, 22, 32, 63}, {54, 23, 32, 63}, {54, 24, 32, 63}, {54, 25, 32, 63}, {54, 26, 32, 63}, 3672 {54, 27, 32, 63}, {54, 28, 32, 63}, {54, 29, 32, 63}, {54, 30, 32, 63}, {54, 31, 32, 63}, 3673 {55, 20, 32, 63}, {55, 21, 32, 63}, {55, 22, 32, 63}, {55, 23, 32, 63}, {55, 24, 32, 63}, 3674 {55, 25, 32, 63}, {55, 26, 32, 63}, {55, 27, 32, 63}, {55, 28, 32, 63}, {55, 29, 32, 63}, 3675 {55, 30, 32, 63}, {55, 31, 32, 63}, {56, 20, 32, 63}, {56, 21, 32, 63}, {56, 22, 32, 63}, 3676 {56, 23, 32, 63}, {56, 24, 32, 63}, {56, 25, 32, 63}, {56, 26, 32, 63}, {56, 27, 32, 63}, 3677 {56, 28, 32, 63}, {56, 29, 32, 63}, {56, 30, 32, 63}, {56, 31, 32, 63}, {57, 20, 32, 63}, 3678 {57, 21, 32, 63}, {57, 22, 32, 63}, {57, 23, 32, 63}, {57, 24, 32, 63}, {57, 25, 32, 63}, 3679 {57, 26, 32, 63}, {57, 27, 32, 63}, {57, 28, 32, 63}, {57, 29, 32, 63}, {57, 30, 32, 63}, 3680 {57, 31, 32, 63}, {58, 20, 32, 63}, {58, 21, 32, 63}, {58, 22, 32, 63}, {58, 23, 32, 63}, 3681 {58, 24, 32, 63}, {58, 25, 32, 63}, {58, 26, 32, 63}, {58, 27, 32, 63}, {58, 28, 32, 63}, 3682 {58, 29, 32, 63}, {58, 30, 32, 63}, {58, 31, 32, 63}, {59, 20, 32, 63}, {59, 21, 32, 63}, 3683 {59, 22, 32, 63}, {59, 23, 32, 63}, {59, 24, 32, 63}, {59, 25, 32, 63}, {59, 26, 32, 63}, 3684 {59, 27, 32, 63}, {59, 28, 32, 63}, {59, 29, 32, 63}, {59, 30, 32, 63}, {59, 31, 32, 63}, 3685 {40, 20, 64, 79}, {40, 21, 64, 79}, {40, 22, 64, 79}, {40, 23, 64, 79}, {40, 24, 64, 79}, 3686 {40, 25, 64, 79}, {40, 26, 64, 79}, {40, 27, 64, 79}, {40, 28, 64, 79}, {40, 29, 64, 79}, 3687 {40, 30, 64, 79}, {40, 31, 64, 79}, {41, 20, 64, 79}, {41, 21, 64, 79}, {41, 22, 64, 79}, 3688 {41, 23, 64, 79}, {41, 24, 64, 79}, {41, 25, 64, 79}, {41, 26, 64, 79}, {41, 27, 64, 79}, 3689 {41, 28, 64, 79}, {41, 29, 64, 79}, {41, 30, 64, 79}, {41, 31, 64, 79}, {42, 20, 64, 79}, 3690 {42, 21, 64, 79}, {42, 22, 64, 79}, {42, 23, 64, 79}, {42, 24, 64, 79}, {42, 25, 64, 79}, 3691 {42, 26, 64, 79}, {42, 27, 64, 79}, {42, 28, 64, 79}, {42, 29, 64, 79}, {42, 30, 64, 79}, 3692 {42, 31, 64, 79}, {43, 20, 64, 79}, {43, 21, 64, 79}, {43, 22, 64, 79}, {43, 23, 64, 79}, 3693 {43, 24, 64, 79}, {43, 25, 64, 79}, {43, 26, 64, 79}, {43, 27, 64, 79}, {43, 28, 64, 79}, 3694 {43, 29, 64, 79}, {43, 30, 64, 79}, {43, 31, 64, 79}, {44, 20, 64, 79}, {44, 21, 64, 79}, 3695 {44, 22, 64, 79}, {44, 23, 64, 79}, {44, 24, 64, 79}, {44, 25, 64, 79}, {44, 26, 64, 79}, 3696 {44, 27, 64, 79}, {44, 28, 64, 79}, {44, 29, 64, 79}, {44, 30, 64, 79}, {44, 31, 64, 79}, 3697 {45, 20, 64, 79}, {45, 21, 64, 79}, {45, 22, 64, 79}, {45, 23, 64, 79}, {45, 24, 64, 79}, 3698 {45, 25, 64, 79}, {45, 26, 64, 79}, {45, 27, 64, 79}, {45, 28, 64, 79}, {45, 29, 64, 79}, 3699 {45, 30, 64, 79}, {45, 31, 64, 79}, {46, 20, 64, 79}, {46, 21, 64, 79}, {46, 22, 64, 79}, 3700 {46, 23, 64, 79}, {46, 24, 64, 79}, {46, 25, 64, 79}, {46, 26, 64, 79}, {46, 27, 64, 79}, 3701 {46, 28, 64, 79}, {46, 29, 64, 79}, {46, 30, 64, 79}, {46, 31, 64, 79}, {47, 20, 64, 79}, 3702 {47, 21, 64, 79}, {47, 22, 64, 79}, {47, 23, 64, 79}, {47, 24, 64, 79}, {47, 25, 64, 79}, 3703 {47, 26, 64, 79}, {47, 27, 64, 79}, {47, 28, 64, 79}, {47, 29, 64, 79}, {47, 30, 64, 79}, 3704 {47, 31, 64, 79}, {48, 20, 64, 79}, {48, 21, 64, 79}, {48, 22, 64, 79}, {48, 23, 64, 79}, 3705 {48, 24, 64, 79}, {48, 25, 64, 79}, {48, 26, 64, 79}, {48, 27, 64, 79}, {48, 28, 64, 79}, 3706 {48, 29, 64, 79}, {48, 30, 64, 79}, {48, 31, 64, 79}, {49, 20, 64, 79}, {49, 21, 64, 79}, 3707 {49, 22, 64, 79}, {49, 23, 64, 79}, {49, 24, 64, 79}, {49, 25, 64, 79}, {49, 26, 64, 79}, 3708 {49, 27, 64, 79}, {49, 28, 64, 79}, {49, 29, 64, 79}, {49, 30, 64, 79}, {49, 31, 64, 79}, 3709 {50, 20, 64, 79}, {50, 21, 64, 79}, {50, 22, 64, 79}, {50, 23, 64, 79}, {50, 24, 64, 79}, 3710 {50, 25, 64, 79}, {50, 26, 64, 79}, {50, 27, 64, 79}, {50, 28, 64, 79}, {50, 29, 64, 79}, 3711 {50, 30, 64, 79}, {50, 31, 64, 79}, {51, 20, 64, 79}, {51, 21, 64, 79}, {51, 22, 64, 79}, 3712 {51, 23, 64, 79}, {51, 24, 64, 79}, {51, 25, 64, 79}, {51, 26, 64, 79}, {51, 27, 64, 79}, 3713 {51, 28, 64, 79}, {51, 29, 64, 79}, {51, 30, 64, 79}, {51, 31, 64, 79}, {52, 20, 64, 79}, 3714 {52, 21, 64, 79}, {52, 22, 64, 79}, {52, 23, 64, 79}, {52, 24, 64, 79}, {52, 25, 64, 79}, 3715 {52, 26, 64, 79}, {52, 27, 64, 79}, {52, 28, 64, 79}, {52, 29, 64, 79}, {52, 30, 64, 79}, 3716 {52, 31, 64, 79}, {53, 20, 64, 79}, {53, 21, 64, 79}, {53, 22, 64, 79}, {53, 23, 64, 79}, 3717 {53, 24, 64, 79}, {53, 25, 64, 79}, {53, 26, 64, 79}, {53, 27, 64, 79}, {53, 28, 64, 79}, 3718 {53, 29, 64, 79}, {53, 30, 64, 79}, {53, 31, 64, 79}, {54, 20, 64, 79}, {54, 21, 64, 79}, 3719 {54, 22, 64, 79}, {54, 23, 64, 79}, {54, 24, 64, 79}, {54, 25, 64, 79}, {54, 26, 64, 79}, 3720 {54, 27, 64, 79}, {54, 28, 64, 79}, {54, 29, 64, 79}, {54, 30, 64, 79}, {54, 31, 64, 79}, 3721 {55, 20, 64, 79}, {55, 21, 64, 79}, {55, 22, 64, 79}, {55, 23, 64, 79}, {55, 24, 64, 79}, 3722 {55, 25, 64, 79}, {55, 26, 64, 79}, {55, 27, 64, 79}, {55, 28, 64, 79}, {55, 29, 64, 79}, 3723 {55, 30, 64, 79}, {55, 31, 64, 79}, {56, 20, 64, 79}, {56, 21, 64, 79}, {56, 22, 64, 79}, 3724 {56, 23, 64, 79}, {56, 24, 64, 79}, {56, 25, 64, 79}, {56, 26, 64, 79}, {56, 27, 64, 79}, 3725 {56, 28, 64, 79}, {56, 29, 64, 79}, {56, 30, 64, 79}, {56, 31, 64, 79}, {57, 20, 64, 79}, 3726 {57, 21, 64, 79}, {57, 22, 64, 79}, {57, 23, 64, 79}, {57, 24, 64, 79}, {57, 25, 64, 79}, 3727 {57, 26, 64, 79}, {57, 27, 64, 79}, {57, 28, 64, 79}, {57, 29, 64, 79}, {57, 30, 64, 79}, 3728 {57, 31, 64, 79}, {58, 20, 64, 79}, {58, 21, 64, 79}, {58, 22, 64, 79}, {58, 23, 64, 79}, 3729 {58, 24, 64, 79}, {58, 25, 64, 79}, {58, 26, 64, 79}, {58, 27, 64, 79}, {58, 28, 64, 79}, 3730 {58, 29, 64, 79}, {58, 30, 64, 79}, {58, 31, 64, 79}, {59, 20, 64, 79}, {59, 21, 64, 79}, 3731 {59, 22, 64, 79}, {59, 23, 64, 79}, {59, 24, 64, 79}, {59, 25, 64, 79}, {59, 26, 64, 79}, 3732 {59, 27, 64, 79}, {59, 28, 64, 79}, {59, 29, 64, 79}, {59, 30, 64, 79}, {59, 31, 64, 79}, 3733 {40, 32, 30, 31}, {40, 33, 30, 31}, {40, 34, 30, 31}, {40, 35, 30, 31}, {40, 36, 30, 31}, 3734 {40, 37, 30, 31}, {40, 38, 30, 31}, {40, 39, 30, 31}, {40, 40, 30, 31}, {40, 41, 30, 31}, 3735 {40, 42, 30, 31}, {40, 43, 30, 31}, {40, 44, 30, 31}, {40, 45, 30, 31}, {40, 46, 30, 31}, 3736 {40, 47, 30, 31}, {40, 48, 30, 31}, {40, 49, 30, 31}, {40, 50, 30, 31}, {40, 51, 30, 31}, 3737 {40, 52, 30, 31}, {40, 53, 30, 31}, {40, 54, 30, 31}, {40, 55, 30, 31}, {40, 56, 30, 31}, 3738 {40, 57, 30, 31}, {40, 58, 30, 31}, {40, 59, 30, 31}, {40, 60, 30, 31}, {40, 61, 30, 31}, 3739 {40, 62, 30, 31}, {40, 63, 30, 31}, {41, 32, 30, 31}, {41, 33, 30, 31}, {41, 34, 30, 31}, 3740 {41, 35, 30, 31}, {41, 36, 30, 31}, {41, 37, 30, 31}, {41, 38, 30, 31}, {41, 39, 30, 31}, 3741 {41, 40, 30, 31}, {41, 41, 30, 31}, {41, 42, 30, 31}, {41, 43, 30, 31}, {41, 44, 30, 31}, 3742 {41, 45, 30, 31}, {41, 46, 30, 31}, {41, 47, 30, 31}, {41, 48, 30, 31}, {41, 49, 30, 31}, 3743 {41, 50, 30, 31}, {41, 51, 30, 31}, {41, 52, 30, 31}, {41, 53, 30, 31}, {41, 54, 30, 31}, 3744 {41, 55, 30, 31}, {41, 56, 30, 31}, {41, 57, 30, 31}, {41, 58, 30, 31}, {41, 59, 30, 31}, 3745 {41, 60, 30, 31}, {41, 61, 30, 31}, {41, 62, 30, 31}, {41, 63, 30, 31}, {42, 32, 30, 31}, 3746 {42, 33, 30, 31}, {42, 34, 30, 31}, {42, 35, 30, 31}, {42, 36, 30, 31}, {42, 37, 30, 31}, 3747 {42, 38, 30, 31}, {42, 39, 30, 31}, {42, 40, 30, 31}, {42, 41, 30, 31}, {42, 42, 30, 31}, 3748 {42, 43, 30, 31}, {42, 44, 30, 31}, {42, 45, 30, 31}, {42, 46, 30, 31}, {42, 47, 30, 31}, 3749 {42, 48, 30, 31}, {42, 49, 30, 31}, {42, 50, 30, 31}, {42, 51, 30, 31}, {42, 52, 30, 31}, 3750 {42, 53, 30, 31}, {42, 54, 30, 31}, {42, 55, 30, 31}, {42, 56, 30, 31}, {42, 57, 30, 31}, 3751 {42, 58, 30, 31}, {42, 59, 30, 31}, {42, 60, 30, 31}, {42, 61, 30, 31}, {42, 62, 30, 31}, 3752 {42, 63, 30, 31}, {43, 32, 30, 31}, {43, 33, 30, 31}, {43, 34, 30, 31}, {43, 35, 30, 31}, 3753 {43, 36, 30, 31}, {43, 37, 30, 31}, {43, 38, 30, 31}, {43, 39, 30, 31}, {43, 40, 30, 31}, 3754 {43, 41, 30, 31}, {43, 42, 30, 31}, {43, 43, 30, 31}, {43, 44, 30, 31}, {43, 45, 30, 31}, 3755 {43, 46, 30, 31}, {43, 47, 30, 31}, {43, 48, 30, 31}, {43, 49, 30, 31}, {43, 50, 30, 31}, 3756 {43, 51, 30, 31}, {43, 52, 30, 31}, {43, 53, 30, 31}, {43, 54, 30, 31}, {43, 55, 30, 31}, 3757 {43, 56, 30, 31}, {43, 57, 30, 31}, {43, 58, 30, 31}, {43, 59, 30, 31}, {43, 60, 30, 31}, 3758 {43, 61, 30, 31}, {43, 62, 30, 31}, {43, 63, 30, 31}, {44, 32, 30, 31}, {44, 33, 30, 31}, 3759 {44, 34, 30, 31}, {44, 35, 30, 31}, {44, 36, 30, 31}, {44, 37, 30, 31}, {44, 38, 30, 31}, 3760 {44, 39, 30, 31}, {44, 40, 30, 31}, {44, 41, 30, 31}, {44, 42, 30, 31}, {44, 43, 30, 31}, 3761 {44, 44, 30, 31}, {44, 45, 30, 31}, {44, 46, 30, 31}, {44, 47, 30, 31}, {44, 48, 30, 31}, 3762 {44, 49, 30, 31}, {44, 50, 30, 31}, {44, 51, 30, 31}, {44, 52, 30, 31}, {44, 53, 30, 31}, 3763 {44, 54, 30, 31}, {44, 55, 30, 31}, {44, 56, 30, 31}, {44, 57, 30, 31}, {44, 58, 30, 31}, 3764 {44, 59, 30, 31}, {44, 60, 30, 31}, {44, 61, 30, 31}, {44, 62, 30, 31}, {44, 63, 30, 31}, 3765 {45, 32, 30, 31}, {45, 33, 30, 31}, {45, 34, 30, 31}, {45, 35, 30, 31}, {45, 36, 30, 31}, 3766 {45, 37, 30, 31}, {45, 38, 30, 31}, {45, 39, 30, 31}, {45, 40, 30, 31}, {45, 41, 30, 31}, 3767 {45, 42, 30, 31}, {45, 43, 30, 31}, {45, 44, 30, 31}, {45, 45, 30, 31}, {45, 46, 30, 31}, 3768 {45, 47, 30, 31}, {45, 48, 30, 31}, {45, 49, 30, 31}, {45, 50, 30, 31}, {45, 51, 30, 31}, 3769 {45, 52, 30, 31}, {45, 53, 30, 31}, {45, 54, 30, 31}, {45, 55, 30, 31}, {45, 56, 30, 31}, 3770 {45, 57, 30, 31}, {45, 58, 30, 31}, {45, 59, 30, 31}, {45, 60, 30, 31}, {45, 61, 30, 31}, 3771 {45, 62, 30, 31}, {45, 63, 30, 31}, {46, 32, 30, 31}, {46, 33, 30, 31}, {46, 34, 30, 31}, 3772 {46, 35, 30, 31}, {46, 36, 30, 31}, {46, 37, 30, 31}, {46, 38, 30, 31}, {46, 39, 30, 31}, 3773 {46, 40, 30, 31}, {46, 41, 30, 31}, {46, 42, 30, 31}, {46, 43, 30, 31}, {46, 44, 30, 31}, 3774 {46, 45, 30, 31}, {46, 46, 30, 31}, {46, 47, 30, 31}, {46, 48, 30, 31}, {46, 49, 30, 31}, 3775 {46, 50, 30, 31}, {46, 51, 30, 31}, {46, 52, 30, 31}, {46, 53, 30, 31}, {46, 54, 30, 31}, 3776 {46, 55, 30, 31}, {46, 56, 30, 31}, {46, 57, 30, 31}, {46, 58, 30, 31}, {46, 59, 30, 31}, 3777 {46, 60, 30, 31}, {46, 61, 30, 31}, {46, 62, 30, 31}, {46, 63, 30, 31}, {47, 32, 30, 31}, 3778 {47, 33, 30, 31}, {47, 34, 30, 31}, {47, 35, 30, 31}, {47, 36, 30, 31}, {47, 37, 30, 31}, 3779 {47, 38, 30, 31}, {47, 39, 30, 31}, {47, 40, 30, 31}, {47, 41, 30, 31}, {47, 42, 30, 31}, 3780 {47, 43, 30, 31}, {47, 44, 30, 31}, {47, 45, 30, 31}, {47, 46, 30, 31}, {47, 47, 30, 31}, 3781 {47, 48, 30, 31}, {47, 49, 30, 31}, {47, 50, 30, 31}, {47, 51, 30, 31}, {47, 52, 30, 31}, 3782 {47, 53, 30, 31}, {47, 54, 30, 31}, {47, 55, 30, 31}, {47, 56, 30, 31}, {47, 57, 30, 31}, 3783 {47, 58, 30, 31}, {47, 59, 30, 31}, {47, 60, 30, 31}, {47, 61, 30, 31}, {47, 62, 30, 31}, 3784 {47, 63, 30, 31}, {48, 32, 30, 31}, {48, 33, 30, 31}, {48, 34, 30, 31}, {48, 35, 30, 31}, 3785 {48, 36, 30, 31}, {48, 37, 30, 31}, {48, 38, 30, 31}, {48, 39, 30, 31}, {48, 40, 30, 31}, 3786 {48, 41, 30, 31}, {48, 42, 30, 31}, {48, 43, 30, 31}, {48, 44, 30, 31}, {48, 45, 30, 31}, 3787 {48, 46, 30, 31}, {48, 47, 30, 31}, {48, 48, 30, 31}, {48, 49, 30, 31}, {48, 50, 30, 31}, 3788 {48, 51, 30, 31}, {48, 52, 30, 31}, {48, 53, 30, 31}, {48, 54, 30, 31}, {48, 55, 30, 31}, 3789 {48, 56, 30, 31}, {48, 57, 30, 31}, {48, 58, 30, 31}, {48, 59, 30, 31}, {48, 60, 30, 31}, 3790 {48, 61, 30, 31}, {48, 62, 30, 31}, {48, 63, 30, 31}, {49, 32, 30, 31}, {49, 33, 30, 31}, 3791 {49, 34, 30, 31}, {49, 35, 30, 31}, {49, 36, 30, 31}, {49, 37, 30, 31}, {49, 38, 30, 31}, 3792 {49, 39, 30, 31}, {49, 40, 30, 31}, {49, 41, 30, 31}, {49, 42, 30, 31}, {49, 43, 30, 31}, 3793 {49, 44, 30, 31}, {49, 45, 30, 31}, {49, 46, 30, 31}, {49, 47, 30, 31}, {49, 48, 30, 31}, 3794 {49, 49, 30, 31}, {49, 50, 30, 31}, {49, 51, 30, 31}, {49, 52, 30, 31}, {49, 53, 30, 31}, 3795 {49, 54, 30, 31}, {49, 55, 30, 31}, {49, 56, 30, 31}, {49, 57, 30, 31}, {49, 58, 30, 31}, 3796 {49, 59, 30, 31}, {49, 60, 30, 31}, {49, 61, 30, 31}, {49, 62, 30, 31}, {49, 63, 30, 31}, 3797 {50, 32, 30, 31}, {50, 33, 30, 31}, {50, 34, 30, 31}, {50, 35, 30, 31}, {50, 36, 30, 31}, 3798 {50, 37, 30, 31}, {50, 38, 30, 31}, {50, 39, 30, 31}, {50, 40, 30, 31}, {50, 41, 30, 31}, 3799 {50, 42, 30, 31}, {50, 43, 30, 31}, {50, 44, 30, 31}, {50, 45, 30, 31}, {50, 46, 30, 31}, 3800 {50, 47, 30, 31}, {50, 48, 30, 31}, {50, 49, 30, 31}, {50, 50, 30, 31}, {50, 51, 30, 31}, 3801 {50, 52, 30, 31}, {50, 53, 30, 31}, {50, 54, 30, 31}, {50, 55, 30, 31}, {50, 56, 30, 31}, 3802 {50, 57, 30, 31}, {50, 58, 30, 31}, {50, 59, 30, 31}, {50, 60, 30, 31}, {50, 61, 30, 31}, 3803 {50, 62, 30, 31}, {50, 63, 30, 31}, {51, 32, 30, 31}, {51, 33, 30, 31}, {51, 34, 30, 31}, 3804 {51, 35, 30, 31}, {51, 36, 30, 31}, {51, 37, 30, 31}, {51, 38, 30, 31}, {51, 39, 30, 31}, 3805 {51, 40, 30, 31}, {51, 41, 30, 31}, {51, 42, 30, 31}, {51, 43, 30, 31}, {51, 44, 30, 31}, 3806 {51, 45, 30, 31}, {51, 46, 30, 31}, {51, 47, 30, 31}, {51, 48, 30, 31}, {51, 49, 30, 31}, 3807 {51, 50, 30, 31}, {51, 51, 30, 31}, {51, 52, 30, 31}, {51, 53, 30, 31}, {51, 54, 30, 31}, 3808 {51, 55, 30, 31}, {51, 56, 30, 31}, {51, 57, 30, 31}, {51, 58, 30, 31}, {51, 59, 30, 31}, 3809 {51, 60, 30, 31}, {51, 61, 30, 31}, {51, 62, 30, 31}, {51, 63, 30, 31}, {52, 32, 30, 31}, 3810 {52, 33, 30, 31}, {52, 34, 30, 31}, {52, 35, 30, 31}, {52, 36, 30, 31}, {52, 37, 30, 31}, 3811 {52, 38, 30, 31}, {52, 39, 30, 31}, {52, 40, 30, 31}, {52, 41, 30, 31}, {52, 42, 30, 31}, 3812 {52, 43, 30, 31}, {52, 44, 30, 31}, {52, 45, 30, 31}, {52, 46, 30, 31}, {52, 47, 30, 31}, 3813 {52, 48, 30, 31}, {52, 49, 30, 31}, {52, 50, 30, 31}, {52, 51, 30, 31}, {52, 52, 30, 31}, 3814 {52, 53, 30, 31}, {52, 54, 30, 31}, {52, 55, 30, 31}, {52, 56, 30, 31}, {52, 57, 30, 31}, 3815 {52, 58, 30, 31}, {52, 59, 30, 31}, {52, 60, 30, 31}, {52, 61, 30, 31}, {52, 62, 30, 31}, 3816 {52, 63, 30, 31}, {53, 32, 30, 31}, {53, 33, 30, 31}, {53, 34, 30, 31}, {53, 35, 30, 31}, 3817 {53, 36, 30, 31}, {53, 37, 30, 31}, {53, 38, 30, 31}, {53, 39, 30, 31}, {53, 40, 30, 31}, 3818 {53, 41, 30, 31}, {53, 42, 30, 31}, {53, 43, 30, 31}, {53, 44, 30, 31}, {53, 45, 30, 31}, 3819 {53, 46, 30, 31}, {53, 47, 30, 31}, {53, 48, 30, 31}, {53, 49, 30, 31}, {53, 50, 30, 31}, 3820 {53, 51, 30, 31}, {53, 52, 30, 31}, {53, 53, 30, 31}, {53, 54, 30, 31}, {53, 55, 30, 31}, 3821 {53, 56, 30, 31}, {53, 57, 30, 31}, {53, 58, 30, 31}, {53, 59, 30, 31}, {53, 60, 30, 31}, 3822 {53, 61, 30, 31}, {53, 62, 30, 31}, {53, 63, 30, 31}, {54, 32, 30, 31}, {54, 33, 30, 31}, 3823 {54, 34, 30, 31}, {54, 35, 30, 31}, {54, 36, 30, 31}, {54, 37, 30, 31}, {54, 38, 30, 31}, 3824 {54, 39, 30, 31}, {54, 40, 30, 31}, {54, 41, 30, 31}, {54, 42, 30, 31}, {54, 43, 30, 31}, 3825 {54, 44, 30, 31}, {54, 45, 30, 31}, {54, 46, 30, 31}, {54, 47, 30, 31}, {54, 48, 30, 31}, 3826 {54, 49, 30, 31}, {54, 50, 30, 31}, {54, 51, 30, 31}, {54, 52, 30, 31}, {54, 53, 30, 31}, 3827 {54, 54, 30, 31}, {54, 55, 30, 31}, {54, 56, 30, 31}, {54, 57, 30, 31}, {54, 58, 30, 31}, 3828 {54, 59, 30, 31}, {54, 60, 30, 31}, {54, 61, 30, 31}, {54, 62, 30, 31}, {54, 63, 30, 31}, 3829 {55, 32, 30, 31}, {55, 33, 30, 31}, {55, 34, 30, 31}, {55, 35, 30, 31}, {55, 36, 30, 31}, 3830 {55, 37, 30, 31}, {55, 38, 30, 31}, {55, 39, 30, 31}, {55, 40, 30, 31}, {55, 41, 30, 31}, 3831 {55, 42, 30, 31}, {55, 43, 30, 31}, {55, 44, 30, 31}, {55, 45, 30, 31}, {55, 46, 30, 31}, 3832 {55, 47, 30, 31}, {55, 48, 30, 31}, {55, 49, 30, 31}, {55, 50, 30, 31}, {55, 51, 30, 31}, 3833 {55, 52, 30, 31}, {55, 53, 30, 31}, {55, 54, 30, 31}, {55, 55, 30, 31}, {55, 56, 30, 31}, 3834 {55, 57, 30, 31}, {55, 58, 30, 31}, {55, 59, 30, 31}, {55, 60, 30, 31}, {55, 61, 30, 31}, 3835 {55, 62, 30, 31}, {55, 63, 30, 31}, {56, 32, 30, 31}, {56, 33, 30, 31}, {56, 34, 30, 31}, 3836 {56, 35, 30, 31}, {56, 36, 30, 31}, {56, 37, 30, 31}, {56, 38, 30, 31}, {56, 39, 30, 31}, 3837 {56, 40, 30, 31}, {56, 41, 30, 31}, {56, 42, 30, 31}, {56, 43, 30, 31}, {56, 44, 30, 31}, 3838 {56, 45, 30, 31}, {56, 46, 30, 31}, {56, 47, 30, 31}, {56, 48, 30, 31}, {56, 49, 30, 31}, 3839 {56, 50, 30, 31}, {56, 51, 30, 31}, {56, 52, 30, 31}, {56, 53, 30, 31}, {56, 54, 30, 31}, 3840 {56, 55, 30, 31}, {56, 56, 30, 31}, {56, 57, 30, 31}, {56, 58, 30, 31}, {56, 59, 30, 31}, 3841 {56, 60, 30, 31}, {56, 61, 30, 31}, {56, 62, 30, 31}, {56, 63, 30, 31}, {57, 32, 30, 31}, 3842 {57, 33, 30, 31}, {57, 34, 30, 31}, {57, 35, 30, 31}, {57, 36, 30, 31}, {57, 37, 30, 31}, 3843 {57, 38, 30, 31}, {57, 39, 30, 31}, {57, 40, 30, 31}, {57, 41, 30, 31}, {57, 42, 30, 31}, 3844 {57, 43, 30, 31}, {57, 44, 30, 31}, {57, 45, 30, 31}, {57, 46, 30, 31}, {57, 47, 30, 31}, 3845 {57, 48, 30, 31}, {57, 49, 30, 31}, {57, 50, 30, 31}, {57, 51, 30, 31}, {57, 52, 30, 31}, 3846 {57, 53, 30, 31}, {57, 54, 30, 31}, {57, 55, 30, 31}, {57, 56, 30, 31}, {57, 57, 30, 31}, 3847 {57, 58, 30, 31}, {57, 59, 30, 31}, {57, 60, 30, 31}, {57, 61, 30, 31}, {57, 62, 30, 31}, 3848 {57, 63, 30, 31}, {58, 32, 30, 31}, {58, 33, 30, 31}, {58, 34, 30, 31}, {58, 35, 30, 31}, 3849 {58, 36, 30, 31}, {58, 37, 30, 31}, {58, 38, 30, 31}, {58, 39, 30, 31}, {58, 40, 30, 31}, 3850 {58, 41, 30, 31}, {58, 42, 30, 31}, {58, 43, 30, 31}, {58, 44, 30, 31}, {58, 45, 30, 31}, 3851 {58, 46, 30, 31}, {58, 47, 30, 31}, {58, 48, 30, 31}, {58, 49, 30, 31}, {58, 50, 30, 31}, 3852 {58, 51, 30, 31}, {58, 52, 30, 31}, {58, 53, 30, 31}, {58, 54, 30, 31}, {58, 55, 30, 31}, 3853 {58, 56, 30, 31}, {58, 57, 30, 31}, {58, 58, 30, 31}, {58, 59, 30, 31}, {58, 60, 30, 31}, 3854 {58, 61, 30, 31}, {58, 62, 30, 31}, {58, 63, 30, 31}, {59, 32, 30, 31}, {59, 33, 30, 31}, 3855 {59, 34, 30, 31}, {59, 35, 30, 31}, {59, 36, 30, 31}, {59, 37, 30, 31}, {59, 38, 30, 31}, 3856 {59, 39, 30, 31}, {59, 40, 30, 31}, {59, 41, 30, 31}, {59, 42, 30, 31}, {59, 43, 30, 31}, 3857 {59, 44, 30, 31}, {59, 45, 30, 31}, {59, 46, 30, 31}, {59, 47, 30, 31}, {59, 48, 30, 31}, 3858 {59, 49, 30, 31}, {59, 50, 30, 31}, {59, 51, 30, 31}, {59, 52, 30, 31}, {59, 53, 30, 31}, 3859 {59, 54, 30, 31}, {59, 55, 30, 31}, {59, 56, 30, 31}, {59, 57, 30, 31}, {59, 58, 30, 31}, 3860 {59, 59, 30, 31}, {59, 60, 30, 31}, {59, 61, 30, 31}, {59, 62, 30, 31}, {59, 63, 30, 31}, 3861 {40, 32, 32, 63}, {40, 33, 32, 63}, {40, 34, 32, 63}, {40, 35, 32, 63}, {40, 36, 32, 63}, 3862 {40, 37, 32, 63}, {40, 38, 32, 63}, {40, 39, 32, 63}, {40, 40, 32, 63}, {40, 41, 32, 63}, 3863 {40, 42, 32, 63}, {40, 43, 32, 63}, {40, 44, 32, 63}, {40, 45, 32, 63}, {40, 46, 32, 63}, 3864 {40, 47, 32, 63}, {40, 48, 32, 63}, {40, 49, 32, 63}, {40, 50, 32, 63}, {40, 51, 32, 63}, 3865 {40, 52, 32, 63}, {40, 53, 32, 63}, {40, 54, 32, 63}, {40, 55, 32, 63}, {40, 56, 32, 63}, 3866 {40, 57, 32, 63}, {40, 58, 32, 63}, {40, 59, 32, 63}, {40, 60, 32, 63}, {40, 61, 32, 63}, 3867 {40, 62, 32, 63}, {40, 63, 32, 63}, {41, 32, 32, 63}, {41, 33, 32, 63}, {41, 34, 32, 63}, 3868 {41, 35, 32, 63}, {41, 36, 32, 63}, {41, 37, 32, 63}, {41, 38, 32, 63}, {41, 39, 32, 63}, 3869 {41, 40, 32, 63}, {41, 41, 32, 63}, {41, 42, 32, 63}, {41, 43, 32, 63}, {41, 44, 32, 63}, 3870 {41, 45, 32, 63}, {41, 46, 32, 63}, {41, 47, 32, 63}, {41, 48, 32, 63}, {41, 49, 32, 63}, 3871 {41, 50, 32, 63}, {41, 51, 32, 63}, {41, 52, 32, 63}, {41, 53, 32, 63}, {41, 54, 32, 63}, 3872 {41, 55, 32, 63}, {41, 56, 32, 63}, {41, 57, 32, 63}, {41, 58, 32, 63}, {41, 59, 32, 63}, 3873 {41, 60, 32, 63}, {41, 61, 32, 63}, {41, 62, 32, 63}, {41, 63, 32, 63}, {42, 32, 32, 63}, 3874 {42, 33, 32, 63}, {42, 34, 32, 63}, {42, 35, 32, 63}, {42, 36, 32, 63}, {42, 37, 32, 63}, 3875 {42, 38, 32, 63}, {42, 39, 32, 63}, {42, 40, 32, 63}, {42, 41, 32, 63}, {42, 42, 32, 63}, 3876 {42, 43, 32, 63}, {42, 44, 32, 63}, {42, 45, 32, 63}, {42, 46, 32, 63}, {42, 47, 32, 63}, 3877 {42, 48, 32, 63}, {42, 49, 32, 63}, {42, 50, 32, 63}, {42, 51, 32, 63}, {42, 52, 32, 63}, 3878 {42, 53, 32, 63}, {42, 54, 32, 63}, {42, 55, 32, 63}, {42, 56, 32, 63}, {42, 57, 32, 63}, 3879 {42, 58, 32, 63}, {42, 59, 32, 63}, {42, 60, 32, 63}, {42, 61, 32, 63}, {42, 62, 32, 63}, 3880 {42, 63, 32, 63}, {43, 32, 32, 63}, {43, 33, 32, 63}, {43, 34, 32, 63}, {43, 35, 32, 63}, 3881 {43, 36, 32, 63}, {43, 37, 32, 63}, {43, 38, 32, 63}, {43, 39, 32, 63}, {43, 40, 32, 63}, 3882 {43, 41, 32, 63}, {43, 42, 32, 63}, {43, 43, 32, 63}, {43, 44, 32, 63}, {43, 45, 32, 63}, 3883 {43, 46, 32, 63}, {43, 47, 32, 63}, {43, 48, 32, 63}, {43, 49, 32, 63}, {43, 50, 32, 63}, 3884 {43, 51, 32, 63}, {43, 52, 32, 63}, {43, 53, 32, 63}, {43, 54, 32, 63}, {43, 55, 32, 63}, 3885 {43, 56, 32, 63}, {43, 57, 32, 63}, {43, 58, 32, 63}, {43, 59, 32, 63}, {43, 60, 32, 63}, 3886 {43, 61, 32, 63}, {43, 62, 32, 63}, {43, 63, 32, 63}, {44, 32, 32, 63}, {44, 33, 32, 63}, 3887 {44, 34, 32, 63}, {44, 35, 32, 63}, {44, 36, 32, 63}, {44, 37, 32, 63}, {44, 38, 32, 63}, 3888 {44, 39, 32, 63}, {44, 40, 32, 63}, {44, 41, 32, 63}, {44, 42, 32, 63}, {44, 43, 32, 63}, 3889 {44, 44, 32, 63}, {44, 45, 32, 63}, {44, 46, 32, 63}, {44, 47, 32, 63}, {44, 48, 32, 63}, 3890 {44, 49, 32, 63}, {44, 50, 32, 63}, {44, 51, 32, 63}, {44, 52, 32, 63}, {44, 53, 32, 63}, 3891 {44, 54, 32, 63}, {44, 55, 32, 63}, {44, 56, 32, 63}, {44, 57, 32, 63}, {44, 58, 32, 63}, 3892 {44, 59, 32, 63}, {44, 60, 32, 63}, {44, 61, 32, 63}, {44, 62, 32, 63}, {44, 63, 32, 63}, 3893 {45, 32, 32, 63}, {45, 33, 32, 63}, {45, 34, 32, 63}, {45, 35, 32, 63}, {45, 36, 32, 63}, 3894 {45, 37, 32, 63}, {45, 38, 32, 63}, {45, 39, 32, 63}, {45, 40, 32, 63}, {45, 41, 32, 63}, 3895 {45, 42, 32, 63}, {45, 43, 32, 63}, {45, 44, 32, 63}, {45, 45, 32, 63}, {45, 46, 32, 63}, 3896 {45, 47, 32, 63}, {45, 48, 32, 63}, {45, 49, 32, 63}, {45, 50, 32, 63}, {45, 51, 32, 63}, 3897 {45, 52, 32, 63}, {45, 53, 32, 63}, {45, 54, 32, 63}, {45, 55, 32, 63}, {45, 56, 32, 63}, 3898 {45, 57, 32, 63}, {45, 58, 32, 63}, {45, 59, 32, 63}, {45, 60, 32, 63}, {45, 61, 32, 63}, 3899 {45, 62, 32, 63}, {45, 63, 32, 63}, {46, 32, 32, 63}, {46, 33, 32, 63}, {46, 34, 32, 63}, 3900 {46, 35, 32, 63}, {46, 36, 32, 63}, {46, 37, 32, 63}, {46, 38, 32, 63}, {46, 39, 32, 63}, 3901 {46, 40, 32, 63}, {46, 41, 32, 63}, {46, 42, 32, 63}, {46, 43, 32, 63}, {46, 44, 32, 63}, 3902 {46, 45, 32, 63}, {46, 46, 32, 63}, {46, 47, 32, 63}, {46, 48, 32, 63}, {46, 49, 32, 63}, 3903 {46, 50, 32, 63}, {46, 51, 32, 63}, {46, 52, 32, 63}, {46, 53, 32, 63}, {46, 54, 32, 63}, 3904 {46, 55, 32, 63}, {46, 56, 32, 63}, {46, 57, 32, 63}, {46, 58, 32, 63}, {46, 59, 32, 63}, 3905 {46, 60, 32, 63}, {46, 61, 32, 63}, {46, 62, 32, 63}, {46, 63, 32, 63}, {47, 32, 32, 63}, 3906 {47, 33, 32, 63}, {47, 34, 32, 63}, {47, 35, 32, 63}, {47, 36, 32, 63}, {47, 37, 32, 63}, 3907 {47, 38, 32, 63}, {47, 39, 32, 63}, {47, 40, 32, 63}, {47, 41, 32, 63}, {47, 42, 32, 63}, 3908 {47, 43, 32, 63}, {47, 44, 32, 63}, {47, 45, 32, 63}, {47, 46, 32, 63}, {47, 47, 32, 63}, 3909 {47, 48, 32, 63}, {47, 49, 32, 63}, {47, 50, 32, 63}, {47, 51, 32, 63}, {47, 52, 32, 63}, 3910 {47, 53, 32, 63}, {47, 54, 32, 63}, {47, 55, 32, 63}, {47, 56, 32, 63}, {47, 57, 32, 63}, 3911 {47, 58, 32, 63}, {47, 59, 32, 63}, {47, 60, 32, 63}, {47, 61, 32, 63}, {47, 62, 32, 63}, 3912 {47, 63, 32, 63}, {48, 32, 32, 63}, {48, 33, 32, 63}, {48, 34, 32, 63}, {48, 35, 32, 63}, 3913 {48, 36, 32, 63}, {48, 37, 32, 63}, {48, 38, 32, 63}, {48, 39, 32, 63}, {48, 40, 32, 63}, 3914 {48, 41, 32, 63}, {48, 42, 32, 63}, {48, 43, 32, 63}, {48, 44, 32, 63}, {48, 45, 32, 63}, 3915 {48, 46, 32, 63}, {48, 47, 32, 63}, {48, 48, 32, 63}, {48, 49, 32, 63}, {48, 50, 32, 63}, 3916 {48, 51, 32, 63}, {48, 52, 32, 63}, {48, 53, 32, 63}, {48, 54, 32, 63}, {48, 55, 32, 63}, 3917 {48, 56, 32, 63}, {48, 57, 32, 63}, {48, 58, 32, 63}, {48, 59, 32, 63}, {48, 60, 32, 63}, 3918 {48, 61, 32, 63}, {48, 62, 32, 63}, {48, 63, 32, 63}, {49, 32, 32, 63}, {49, 33, 32, 63}, 3919 {49, 34, 32, 63}, {49, 35, 32, 63}, {49, 36, 32, 63}, {49, 37, 32, 63}, {49, 38, 32, 63}, 3920 {49, 39, 32, 63}, {49, 40, 32, 63}, {49, 41, 32, 63}, {49, 42, 32, 63}, {49, 43, 32, 63}, 3921 {49, 44, 32, 63}, {49, 45, 32, 63}, {49, 46, 32, 63}, {49, 47, 32, 63}, {49, 48, 32, 63}, 3922 {49, 49, 32, 63}, {49, 50, 32, 63}, {49, 51, 32, 63}, {49, 52, 32, 63}, {49, 53, 32, 63}, 3923 {49, 54, 32, 63}, {49, 55, 32, 63}, {49, 56, 32, 63}, {49, 57, 32, 63}, {49, 58, 32, 63}, 3924 {49, 59, 32, 63}, {49, 60, 32, 63}, {49, 61, 32, 63}, {49, 62, 32, 63}, {49, 63, 32, 63}, 3925 {50, 32, 32, 63}, {50, 33, 32, 63}, {50, 34, 32, 63}, {50, 35, 32, 63}, {50, 36, 32, 63}, 3926 {50, 37, 32, 63}, {50, 38, 32, 63}, {50, 39, 32, 63}, {50, 40, 32, 63}, {50, 41, 32, 63}, 3927 {50, 42, 32, 63}, {50, 43, 32, 63}, {50, 44, 32, 63}, {50, 45, 32, 63}, {50, 46, 32, 63}, 3928 {50, 47, 32, 63}, {50, 48, 32, 63}, {50, 49, 32, 63}, {50, 50, 32, 63}, {50, 51, 32, 63}, 3929 {50, 52, 32, 63}, {50, 53, 32, 63}, {50, 54, 32, 63}, {50, 55, 32, 63}, {50, 56, 32, 63}, 3930 {50, 57, 32, 63}, {50, 58, 32, 63}, {50, 59, 32, 63}, {50, 60, 32, 63}, {50, 61, 32, 63}, 3931 {50, 62, 32, 63}, {50, 63, 32, 63}, {51, 32, 32, 63}, {51, 33, 32, 63}, {51, 34, 32, 63}, 3932 {51, 35, 32, 63}, {51, 36, 32, 63}, {51, 37, 32, 63}, {51, 38, 32, 63}, {51, 39, 32, 63}, 3933 {51, 40, 32, 63}, {51, 41, 32, 63}, {51, 42, 32, 63}, {51, 43, 32, 63}, {51, 44, 32, 63}, 3934 {51, 45, 32, 63}, {51, 46, 32, 63}, {51, 47, 32, 63}, {51, 48, 32, 63}, {51, 49, 32, 63}, 3935 {51, 50, 32, 63}, {51, 51, 32, 63}, {51, 52, 32, 63}, {51, 53, 32, 63}, {51, 54, 32, 63}, 3936 {51, 55, 32, 63}, {51, 56, 32, 63}, {51, 57, 32, 63}, {51, 58, 32, 63}, {51, 59, 32, 63}, 3937 {51, 60, 32, 63}, {51, 61, 32, 63}, {51, 62, 32, 63}, {51, 63, 32, 63}, {52, 32, 32, 63}, 3938 {52, 33, 32, 63}, {52, 34, 32, 63}, {52, 35, 32, 63}, {52, 36, 32, 63}, {52, 37, 32, 63}, 3939 {52, 38, 32, 63}, {52, 39, 32, 63}, {52, 40, 32, 63}, {52, 41, 32, 63}, {52, 42, 32, 63}, 3940 {52, 43, 32, 63}, {52, 44, 32, 63}, {52, 45, 32, 63}, {52, 46, 32, 63}, {52, 47, 32, 63}, 3941 {52, 48, 32, 63}, {52, 49, 32, 63}, {52, 50, 32, 63}, {52, 51, 32, 63}, {52, 52, 32, 63}, 3942 {52, 53, 32, 63}, {52, 54, 32, 63}, {52, 55, 32, 63}, {52, 56, 32, 63}, {52, 57, 32, 63}, 3943 {52, 58, 32, 63}, {52, 59, 32, 63}, {52, 60, 32, 63}, {52, 61, 32, 63}, {52, 62, 32, 63}, 3944 {52, 63, 32, 63}, {53, 32, 32, 63}, {53, 33, 32, 63}, {53, 34, 32, 63}, {53, 35, 32, 63}, 3945 {53, 36, 32, 63}, {53, 37, 32, 63}, {53, 38, 32, 63}, {53, 39, 32, 63}, {53, 40, 32, 63}, 3946 {53, 41, 32, 63}, {53, 42, 32, 63}, {53, 43, 32, 63}, {53, 44, 32, 63}, {53, 45, 32, 63}, 3947 {53, 46, 32, 63}, {53, 47, 32, 63}, {53, 48, 32, 63}, {53, 49, 32, 63}, {53, 50, 32, 63}, 3948 {53, 51, 32, 63}, {53, 52, 32, 63}, {53, 53, 32, 63}, {53, 54, 32, 63}, {53, 55, 32, 63}, 3949 {53, 56, 32, 63}, {53, 57, 32, 63}, {53, 58, 32, 63}, {53, 59, 32, 63}, {53, 60, 32, 63}, 3950 {53, 61, 32, 63}, {53, 62, 32, 63}, {53, 63, 32, 63}, {54, 32, 32, 63}, {54, 33, 32, 63}, 3951 {54, 34, 32, 63}, {54, 35, 32, 63}, {54, 36, 32, 63}, {54, 37, 32, 63}, {54, 38, 32, 63}, 3952 {54, 39, 32, 63}, {54, 40, 32, 63}, {54, 41, 32, 63}, {54, 42, 32, 63}, {54, 43, 32, 63}, 3953 {54, 44, 32, 63}, {54, 45, 32, 63}, {54, 46, 32, 63}, {54, 47, 32, 63}, {54, 48, 32, 63}, 3954 {54, 49, 32, 63}, {54, 50, 32, 63}, {54, 51, 32, 63}, {54, 52, 32, 63}, {54, 53, 32, 63}, 3955 {54, 54, 32, 63}, {54, 55, 32, 63}, {54, 56, 32, 63}, {54, 57, 32, 63}, {54, 58, 32, 63}, 3956 {54, 59, 32, 63}, {54, 60, 32, 63}, {54, 61, 32, 63}, {54, 62, 32, 63}, {54, 63, 32, 63}, 3957 {55, 32, 32, 63}, {55, 33, 32, 63}, {55, 34, 32, 63}, {55, 35, 32, 63}, {55, 36, 32, 63}, 3958 {55, 37, 32, 63}, {55, 38, 32, 63}, {55, 39, 32, 63}, {55, 40, 32, 63}, {55, 41, 32, 63}, 3959 {55, 42, 32, 63}, {55, 43, 32, 63}, {55, 44, 32, 63}, {55, 45, 32, 63}, {55, 46, 32, 63}, 3960 {55, 47, 32, 63}, {55, 48, 32, 63}, {55, 49, 32, 63}, {55, 50, 32, 63}, {55, 51, 32, 63}, 3961 {55, 52, 32, 63}, {55, 53, 32, 63}, {55, 54, 32, 63}, {55, 55, 32, 63}, {55, 56, 32, 63}, 3962 {55, 57, 32, 63}, {55, 58, 32, 63}, {55, 59, 32, 63}, {55, 60, 32, 63}, {55, 61, 32, 63}, 3963 {55, 62, 32, 63}, {55, 63, 32, 63}, {56, 32, 32, 63}, {56, 33, 32, 63}, {56, 34, 32, 63}, 3964 {56, 35, 32, 63}, {56, 36, 32, 63}, {56, 37, 32, 63}, {56, 38, 32, 63}, {56, 39, 32, 63}, 3965 {56, 40, 32, 63}, {56, 41, 32, 63}, {56, 42, 32, 63}, {56, 43, 32, 63}, {56, 44, 32, 63}, 3966 {56, 45, 32, 63}, {56, 46, 32, 63}, {56, 47, 32, 63}, {56, 48, 32, 63}, {56, 49, 32, 63}, 3967 {56, 50, 32, 63}, {56, 51, 32, 63}, {56, 52, 32, 63}, {56, 53, 32, 63}, {56, 54, 32, 63}, 3968 {56, 55, 32, 63}, {56, 56, 32, 63}, {56, 57, 32, 63}, {56, 58, 32, 63}, {56, 59, 32, 63}, 3969 {56, 60, 32, 63}, {56, 61, 32, 63}, {56, 62, 32, 63}, {56, 63, 32, 63}, {57, 32, 32, 63}, 3970 {57, 33, 32, 63}, {57, 34, 32, 63}, {57, 35, 32, 63}, {57, 36, 32, 63}, {57, 37, 32, 63}, 3971 {57, 38, 32, 63}, {57, 39, 32, 63}, {57, 40, 32, 63}, {57, 41, 32, 63}, {57, 42, 32, 63}, 3972 {57, 43, 32, 63}, {57, 44, 32, 63}, {57, 45, 32, 63}, {57, 46, 32, 63}, {57, 47, 32, 63}, 3973 {57, 48, 32, 63}, {57, 49, 32, 63}, {57, 50, 32, 63}, {57, 51, 32, 63}, {57, 52, 32, 63}, 3974 {57, 53, 32, 63}, {57, 54, 32, 63}, {57, 55, 32, 63}, {57, 56, 32, 63}, {57, 57, 32, 63}, 3975 {57, 58, 32, 63}, {57, 59, 32, 63}, {57, 60, 32, 63}, {57, 61, 32, 63}, {57, 62, 32, 63}, 3976 {57, 63, 32, 63}, {58, 32, 32, 63}, {58, 33, 32, 63}, {58, 34, 32, 63}, {58, 35, 32, 63}, 3977 {58, 36, 32, 63}, {58, 37, 32, 63}, {58, 38, 32, 63}, {58, 39, 32, 63}, {58, 40, 32, 63}, 3978 {58, 41, 32, 63}, {58, 42, 32, 63}, {58, 43, 32, 63}, {58, 44, 32, 63}, {58, 45, 32, 63}, 3979 {58, 46, 32, 63}, {58, 47, 32, 63}, {58, 48, 32, 63}, {58, 49, 32, 63}, {58, 50, 32, 63}, 3980 {58, 51, 32, 63}, {58, 52, 32, 63}, {58, 53, 32, 63}, {58, 54, 32, 63}, {58, 55, 32, 63}, 3981 {58, 56, 32, 63}, {58, 57, 32, 63}, {58, 58, 32, 63}, {58, 59, 32, 63}, {58, 60, 32, 63}, 3982 {58, 61, 32, 63}, {58, 62, 32, 63}, {58, 63, 32, 63}, {59, 32, 32, 63}, {59, 33, 32, 63}, 3983 {59, 34, 32, 63}, {59, 35, 32, 63}, {59, 36, 32, 63}, {59, 37, 32, 63}, {59, 38, 32, 63}, 3984 {59, 39, 32, 63}, {59, 40, 32, 63}, {59, 41, 32, 63}, {59, 42, 32, 63}, {59, 43, 32, 63}, 3985 {59, 44, 32, 63}, {59, 45, 32, 63}, {59, 46, 32, 63}, {59, 47, 32, 63}, {59, 48, 32, 63}, 3986 {59, 49, 32, 63}, {59, 50, 32, 63}, {59, 51, 32, 63}, {59, 52, 32, 63}, {59, 53, 32, 63}, 3987 {59, 54, 32, 63}, {59, 55, 32, 63}, {59, 56, 32, 63}, {59, 57, 32, 63}, {59, 58, 32, 63}, 3988 {59, 59, 32, 63}, {59, 60, 32, 63}, {59, 61, 32, 63}, {59, 62, 32, 63}, {59, 63, 32, 63}, 3989 {40, 32, 64, 79}, {40, 33, 64, 79}, {40, 34, 64, 79}, {40, 35, 64, 79}, {40, 36, 64, 79}, 3990 {40, 37, 64, 79}, {40, 38, 64, 79}, {40, 39, 64, 79}, {40, 40, 64, 79}, {40, 41, 64, 79}, 3991 {40, 42, 64, 79}, {40, 43, 64, 79}, {40, 44, 64, 79}, {40, 45, 64, 79}, {40, 46, 64, 79}, 3992 {40, 47, 64, 79}, {40, 48, 64, 79}, {40, 49, 64, 79}, {40, 50, 64, 79}, {40, 51, 64, 79}, 3993 {40, 52, 64, 79}, {40, 53, 64, 79}, {40, 54, 64, 79}, {40, 55, 64, 79}, {40, 56, 64, 79}, 3994 {40, 57, 64, 79}, {40, 58, 64, 79}, {40, 59, 64, 79}, {40, 60, 64, 79}, {40, 61, 64, 79}, 3995 {40, 62, 64, 79}, {40, 63, 64, 79}, {41, 32, 64, 79}, {41, 33, 64, 79}, {41, 34, 64, 79}, 3996 {41, 35, 64, 79}, {41, 36, 64, 79}, {41, 37, 64, 79}, {41, 38, 64, 79}, {41, 39, 64, 79}, 3997 {41, 40, 64, 79}, {41, 41, 64, 79}, {41, 42, 64, 79}, {41, 43, 64, 79}, {41, 44, 64, 79}, 3998 {41, 45, 64, 79}, {41, 46, 64, 79}, {41, 47, 64, 79}, {41, 48, 64, 79}, {41, 49, 64, 79}, 3999 {41, 50, 64, 79}, {41, 51, 64, 79}, {41, 52, 64, 79}, {41, 53, 64, 79}, {41, 54, 64, 79}, 4000 {41, 55, 64, 79}, {41, 56, 64, 79}, {41, 57, 64, 79}, {41, 58, 64, 79}, {41, 59, 64, 79}, 4001 {41, 60, 64, 79}, {41, 61, 64, 79}, {41, 62, 64, 79}, {41, 63, 64, 79}, {42, 32, 64, 79}, 4002 {42, 33, 64, 79}, {42, 34, 64, 79}, {42, 35, 64, 79}, {42, 36, 64, 79}, {42, 37, 64, 79}, 4003 {42, 38, 64, 79}, {42, 39, 64, 79}, {42, 40, 64, 79}, {42, 41, 64, 79}, {42, 42, 64, 79}, 4004 {42, 43, 64, 79}, {42, 44, 64, 79}, {42, 45, 64, 79}, {42, 46, 64, 79}, {42, 47, 64, 79}, 4005 {42, 48, 64, 79}, {42, 49, 64, 79}, {42, 50, 64, 79}, {42, 51, 64, 79}, {42, 52, 64, 79}, 4006 {42, 53, 64, 79}, {42, 54, 64, 79}, {42, 55, 64, 79}, {42, 56, 64, 79}, {42, 57, 64, 79}, 4007 {42, 58, 64, 79}, {42, 59, 64, 79}, {42, 60, 64, 79}, {42, 61, 64, 79}, {42, 62, 64, 79}, 4008 {42, 63, 64, 79}, {43, 32, 64, 79}, {43, 33, 64, 79}, {43, 34, 64, 79}, {43, 35, 64, 79}, 4009 {43, 36, 64, 79}, {43, 37, 64, 79}, {43, 38, 64, 79}, {43, 39, 64, 79}, {43, 40, 64, 79}, 4010 {43, 41, 64, 79}, {43, 42, 64, 79}, {43, 43, 64, 79}, {43, 44, 64, 79}, {43, 45, 64, 79}, 4011 {43, 46, 64, 79}, {43, 47, 64, 79}, {43, 48, 64, 79}, {43, 49, 64, 79}, {43, 50, 64, 79}, 4012 {43, 51, 64, 79}, {43, 52, 64, 79}, {43, 53, 64, 79}, {43, 54, 64, 79}, {43, 55, 64, 79}, 4013 {43, 56, 64, 79}, {43, 57, 64, 79}, {43, 58, 64, 79}, {43, 59, 64, 79}, {43, 60, 64, 79}, 4014 {43, 61, 64, 79}, {43, 62, 64, 79}, {43, 63, 64, 79}, {44, 32, 64, 79}, {44, 33, 64, 79}, 4015 {44, 34, 64, 79}, {44, 35, 64, 79}, {44, 36, 64, 79}, {44, 37, 64, 79}, {44, 38, 64, 79}, 4016 {44, 39, 64, 79}, {44, 40, 64, 79}, {44, 41, 64, 79}, {44, 42, 64, 79}, {44, 43, 64, 79}, 4017 {44, 44, 64, 79}, {44, 45, 64, 79}, {44, 46, 64, 79}, {44, 47, 64, 79}, {44, 48, 64, 79}, 4018 {44, 49, 64, 79}, {44, 50, 64, 79}, {44, 51, 64, 79}, {44, 52, 64, 79}, {44, 53, 64, 79}, 4019 {44, 54, 64, 79}, {44, 55, 64, 79}, {44, 56, 64, 79}, {44, 57, 64, 79}, {44, 58, 64, 79}, 4020 {44, 59, 64, 79}, {44, 60, 64, 79}, {44, 61, 64, 79}, {44, 62, 64, 79}, {44, 63, 64, 79}, 4021 {45, 32, 64, 79}, {45, 33, 64, 79}, {45, 34, 64, 79}, {45, 35, 64, 79}, {45, 36, 64, 79}, 4022 {45, 37, 64, 79}, {45, 38, 64, 79}, {45, 39, 64, 79}, {45, 40, 64, 79}, {45, 41, 64, 79}, 4023 {45, 42, 64, 79}, {45, 43, 64, 79}, {45, 44, 64, 79}, {45, 45, 64, 79}, {45, 46, 64, 79}, 4024 {45, 47, 64, 79}, {45, 48, 64, 79}, {45, 49, 64, 79}, {45, 50, 64, 79}, {45, 51, 64, 79}, 4025 {45, 52, 64, 79}, {45, 53, 64, 79}, {45, 54, 64, 79}, {45, 55, 64, 79}, {45, 56, 64, 79}, 4026 {45, 57, 64, 79}, {45, 58, 64, 79}, {45, 59, 64, 79}, {45, 60, 64, 79}, {45, 61, 64, 79}, 4027 {45, 62, 64, 79}, {45, 63, 64, 79}, {46, 32, 64, 79}, {46, 33, 64, 79}, {46, 34, 64, 79}, 4028 {46, 35, 64, 79}, {46, 36, 64, 79}, {46, 37, 64, 79}, {46, 38, 64, 79}, {46, 39, 64, 79}, 4029 {46, 40, 64, 79}, {46, 41, 64, 79}, {46, 42, 64, 79}, {46, 43, 64, 79}, {46, 44, 64, 79}, 4030 {46, 45, 64, 79}, {46, 46, 64, 79}, {46, 47, 64, 79}, {46, 48, 64, 79}, {46, 49, 64, 79}, 4031 {46, 50, 64, 79}, {46, 51, 64, 79}, {46, 52, 64, 79}, {46, 53, 64, 79}, {46, 54, 64, 79}, 4032 {46, 55, 64, 79}, {46, 56, 64, 79}, {46, 57, 64, 79}, {46, 58, 64, 79}, {46, 59, 64, 79}, 4033 {46, 60, 64, 79}, {46, 61, 64, 79}, {46, 62, 64, 79}, {46, 63, 64, 79}, {47, 32, 64, 79}, 4034 {47, 33, 64, 79}, {47, 34, 64, 79}, {47, 35, 64, 79}, {47, 36, 64, 79}, {47, 37, 64, 79}, 4035 {47, 38, 64, 79}, {47, 39, 64, 79}, {47, 40, 64, 79}, {47, 41, 64, 79}, {47, 42, 64, 79}, 4036 {47, 43, 64, 79}, {47, 44, 64, 79}, {47, 45, 64, 79}, {47, 46, 64, 79}, {47, 47, 64, 79}, 4037 {47, 48, 64, 79}, {47, 49, 64, 79}, {47, 50, 64, 79}, {47, 51, 64, 79}, {47, 52, 64, 79}, 4038 {47, 53, 64, 79}, {47, 54, 64, 79}, {47, 55, 64, 79}, {47, 56, 64, 79}, {47, 57, 64, 79}, 4039 {47, 58, 64, 79}, {47, 59, 64, 79}, {47, 60, 64, 79}, {47, 61, 64, 79}, {47, 62, 64, 79}, 4040 {47, 63, 64, 79}, {48, 32, 64, 79}, {48, 33, 64, 79}, {48, 34, 64, 79}, {48, 35, 64, 79}, 4041 {48, 36, 64, 79}, {48, 37, 64, 79}, {48, 38, 64, 79}, {48, 39, 64, 79}, {48, 40, 64, 79}, 4042 {48, 41, 64, 79}, {48, 42, 64, 79}, {48, 43, 64, 79}, {48, 44, 64, 79}, {48, 45, 64, 79}, 4043 {48, 46, 64, 79}, {48, 47, 64, 79}, {48, 48, 64, 79}, {48, 49, 64, 79}, {48, 50, 64, 79}, 4044 {48, 51, 64, 79}, {48, 52, 64, 79}, {48, 53, 64, 79}, {48, 54, 64, 79}, {48, 55, 64, 79}, 4045 {48, 56, 64, 79}, {48, 57, 64, 79}, {48, 58, 64, 79}, {48, 59, 64, 79}, {48, 60, 64, 79}, 4046 {48, 61, 64, 79}, {48, 62, 64, 79}, {48, 63, 64, 79}, {49, 32, 64, 79}, {49, 33, 64, 79}, 4047 {49, 34, 64, 79}, {49, 35, 64, 79}, {49, 36, 64, 79}, {49, 37, 64, 79}, {49, 38, 64, 79}, 4048 {49, 39, 64, 79}, {49, 40, 64, 79}, {49, 41, 64, 79}, {49, 42, 64, 79}, {49, 43, 64, 79}, 4049 {49, 44, 64, 79}, {49, 45, 64, 79}, {49, 46, 64, 79}, {49, 47, 64, 79}, {49, 48, 64, 79}, 4050 {49, 49, 64, 79}, {49, 50, 64, 79}, {49, 51, 64, 79}, {49, 52, 64, 79}, {49, 53, 64, 79}, 4051 {49, 54, 64, 79}, {49, 55, 64, 79}, {49, 56, 64, 79}, {49, 57, 64, 79}, {49, 58, 64, 79}, 4052 {49, 59, 64, 79}, {49, 60, 64, 79}, {49, 61, 64, 79}, {49, 62, 64, 79}, {49, 63, 64, 79}, 4053 {50, 32, 64, 79}, {50, 33, 64, 79}, {50, 34, 64, 79}, {50, 35, 64, 79}, {50, 36, 64, 79}, 4054 {50, 37, 64, 79}, {50, 38, 64, 79}, {50, 39, 64, 79}, {50, 40, 64, 79}, {50, 41, 64, 79}, 4055 {50, 42, 64, 79}, {50, 43, 64, 79}, {50, 44, 64, 79}, {50, 45, 64, 79}, {50, 46, 64, 79}, 4056 {50, 47, 64, 79}, {50, 48, 64, 79}, {50, 49, 64, 79}, {50, 50, 64, 79}, {50, 51, 64, 79}, 4057 {50, 52, 64, 79}, {50, 53, 64, 79}, {50, 54, 64, 79}, {50, 55, 64, 79}, {50, 56, 64, 79}, 4058 {50, 57, 64, 79}, {50, 58, 64, 79}, {50, 59, 64, 79}, {50, 60, 64, 79}, {50, 61, 64, 79}, 4059 {50, 62, 64, 79}, {50, 63, 64, 79}, {51, 32, 64, 79}, {51, 33, 64, 79}, {51, 34, 64, 79}, 4060 {51, 35, 64, 79}, {51, 36, 64, 79}, {51, 37, 64, 79}, {51, 38, 64, 79}, {51, 39, 64, 79}, 4061 {51, 40, 64, 79}, {51, 41, 64, 79}, {51, 42, 64, 79}, {51, 43, 64, 79}, {51, 44, 64, 79}, 4062 {51, 45, 64, 79}, {51, 46, 64, 79}, {51, 47, 64, 79}, {51, 48, 64, 79}, {51, 49, 64, 79}, 4063 {51, 50, 64, 79}, {51, 51, 64, 79}, {51, 52, 64, 79}, {51, 53, 64, 79}, {51, 54, 64, 79}, 4064 {51, 55, 64, 79}, {51, 56, 64, 79}, {51, 57, 64, 79}, {51, 58, 64, 79}, {51, 59, 64, 79}, 4065 {51, 60, 64, 79}, {51, 61, 64, 79}, {51, 62, 64, 79}, {51, 63, 64, 79}, {52, 32, 64, 79}, 4066 {52, 33, 64, 79}, {52, 34, 64, 79}, {52, 35, 64, 79}, {52, 36, 64, 79}, {52, 37, 64, 79}, 4067 {52, 38, 64, 79}, {52, 39, 64, 79}, {52, 40, 64, 79}, {52, 41, 64, 79}, {52, 42, 64, 79}, 4068 {52, 43, 64, 79}, {52, 44, 64, 79}, {52, 45, 64, 79}, {52, 46, 64, 79}, {52, 47, 64, 79}, 4069 {52, 48, 64, 79}, {52, 49, 64, 79}, {52, 50, 64, 79}, {52, 51, 64, 79}, {52, 52, 64, 79}, 4070 {52, 53, 64, 79}, {52, 54, 64, 79}, {52, 55, 64, 79}, {52, 56, 64, 79}, {52, 57, 64, 79}, 4071 {52, 58, 64, 79}, {52, 59, 64, 79}, {52, 60, 64, 79}, {52, 61, 64, 79}, {52, 62, 64, 79}, 4072 {52, 63, 64, 79}, {53, 32, 64, 79}, {53, 33, 64, 79}, {53, 34, 64, 79}, {53, 35, 64, 79}, 4073 {53, 36, 64, 79}, {53, 37, 64, 79}, {53, 38, 64, 79}, {53, 39, 64, 79}, {53, 40, 64, 79}, 4074 {53, 41, 64, 79}, {53, 42, 64, 79}, {53, 43, 64, 79}, {53, 44, 64, 79}, {53, 45, 64, 79}, 4075 {53, 46, 64, 79}, {53, 47, 64, 79}, {53, 48, 64, 79}, {53, 49, 64, 79}, {53, 50, 64, 79}, 4076 {53, 51, 64, 79}, {53, 52, 64, 79}, {53, 53, 64, 79}, {53, 54, 64, 79}, {53, 55, 64, 79}, 4077 {53, 56, 64, 79}, {53, 57, 64, 79}, {53, 58, 64, 79}, {53, 59, 64, 79}, {53, 60, 64, 79}, 4078 {53, 61, 64, 79}, {53, 62, 64, 79}, {53, 63, 64, 79}, {54, 32, 64, 79}, {54, 33, 64, 79}, 4079 {54, 34, 64, 79}, {54, 35, 64, 79}, {54, 36, 64, 79}, {54, 37, 64, 79}, {54, 38, 64, 79}, 4080 {54, 39, 64, 79}, {54, 40, 64, 79}, {54, 41, 64, 79}, {54, 42, 64, 79}, {54, 43, 64, 79}, 4081 {54, 44, 64, 79}, {54, 45, 64, 79}, {54, 46, 64, 79}, {54, 47, 64, 79}, {54, 48, 64, 79}, 4082 {54, 49, 64, 79}, {54, 50, 64, 79}, {54, 51, 64, 79}, {54, 52, 64, 79}, {54, 53, 64, 79}, 4083 {54, 54, 64, 79}, {54, 55, 64, 79}, {54, 56, 64, 79}, {54, 57, 64, 79}, {54, 58, 64, 79}, 4084 {54, 59, 64, 79}, {54, 60, 64, 79}, {54, 61, 64, 79}, {54, 62, 64, 79}, {54, 63, 64, 79}, 4085 {55, 32, 64, 79}, {55, 33, 64, 79}, {55, 34, 64, 79}, {55, 35, 64, 79}, {55, 36, 64, 79}, 4086 {55, 37, 64, 79}, {55, 38, 64, 79}, {55, 39, 64, 79}, {55, 40, 64, 79}, {55, 41, 64, 79}, 4087 {55, 42, 64, 79}, {55, 43, 64, 79}, {55, 44, 64, 79}, {55, 45, 64, 79}, {55, 46, 64, 79}, 4088 {55, 47, 64, 79}, {55, 48, 64, 79}, {55, 49, 64, 79}, {55, 50, 64, 79}, {55, 51, 64, 79}, 4089 {55, 52, 64, 79}, {55, 53, 64, 79}, {55, 54, 64, 79}, {55, 55, 64, 79}, {55, 56, 64, 79}, 4090 {55, 57, 64, 79}, {55, 58, 64, 79}, {55, 59, 64, 79}, {55, 60, 64, 79}, {55, 61, 64, 79}, 4091 {55, 62, 64, 79}, {55, 63, 64, 79}, {56, 32, 64, 79}, {56, 33, 64, 79}, {56, 34, 64, 79}, 4092 {56, 35, 64, 79}, {56, 36, 64, 79}, {56, 37, 64, 79}, {56, 38, 64, 79}, {56, 39, 64, 79}, 4093 {56, 40, 64, 79}, {56, 41, 64, 79}, {56, 42, 64, 79}, {56, 43, 64, 79}, {56, 44, 64, 79}, 4094 {56, 45, 64, 79}, {56, 46, 64, 79}, {56, 47, 64, 79}, {56, 48, 64, 79}, {56, 49, 64, 79}, 4095 {56, 50, 64, 79}, {56, 51, 64, 79}, {56, 52, 64, 79}, {56, 53, 64, 79}, {56, 54, 64, 79}, 4096 {56, 55, 64, 79}, {56, 56, 64, 79}, {56, 57, 64, 79}, {56, 58, 64, 79}, {56, 59, 64, 79}, 4097 {56, 60, 64, 79}, {56, 61, 64, 79}, {56, 62, 64, 79}, {56, 63, 64, 79}, {57, 32, 64, 79}, 4098 {57, 33, 64, 79}, {57, 34, 64, 79}, {57, 35, 64, 79}, {57, 36, 64, 79}, {57, 37, 64, 79}, 4099 {57, 38, 64, 79}, {57, 39, 64, 79}, {57, 40, 64, 79}, {57, 41, 64, 79}, {57, 42, 64, 79}, 4100 {57, 43, 64, 79}, {57, 44, 64, 79}, {57, 45, 64, 79}, {57, 46, 64, 79}, {57, 47, 64, 79}, 4101 {57, 48, 64, 79}, {57, 49, 64, 79}, {57, 50, 64, 79}, {57, 51, 64, 79}, {57, 52, 64, 79}, 4102 {57, 53, 64, 79}, {57, 54, 64, 79}, {57, 55, 64, 79}, {57, 56, 64, 79}, {57, 57, 64, 79}, 4103 {57, 58, 64, 79}, {57, 59, 64, 79}, {57, 60, 64, 79}, {57, 61, 64, 79}, {57, 62, 64, 79}, 4104 {57, 63, 64, 79}, {58, 32, 64, 79}, {58, 33, 64, 79}, {58, 34, 64, 79}, {58, 35, 64, 79}, 4105 {58, 36, 64, 79}, {58, 37, 64, 79}, {58, 38, 64, 79}, {58, 39, 64, 79}, {58, 40, 64, 79}, 4106 {58, 41, 64, 79}, {58, 42, 64, 79}, {58, 43, 64, 79}, {58, 44, 64, 79}, {58, 45, 64, 79}, 4107 {58, 46, 64, 79}, {58, 47, 64, 79}, {58, 48, 64, 79}, {58, 49, 64, 79}, {58, 50, 64, 79}, 4108 {58, 51, 64, 79}, {58, 52, 64, 79}, {58, 53, 64, 79}, {58, 54, 64, 79}, {58, 55, 64, 79}, 4109 {58, 56, 64, 79}, {58, 57, 64, 79}, {58, 58, 64, 79}, {58, 59, 64, 79}, {58, 60, 64, 79}, 4110 {58, 61, 64, 79}, {58, 62, 64, 79}, {58, 63, 64, 79}, {59, 32, 64, 79}, {59, 33, 64, 79}, 4111 {59, 34, 64, 79}, {59, 35, 64, 79}, {59, 36, 64, 79}, {59, 37, 64, 79}, {59, 38, 64, 79}, 4112 {59, 39, 64, 79}, {59, 40, 64, 79}, {59, 41, 64, 79}, {59, 42, 64, 79}, {59, 43, 64, 79}, 4113 {59, 44, 64, 79}, {59, 45, 64, 79}, {59, 46, 64, 79}, {59, 47, 64, 79}, {59, 48, 64, 79}, 4114 {59, 49, 64, 79}, {59, 50, 64, 79}, {59, 51, 64, 79}, {59, 52, 64, 79}, {59, 53, 64, 79}, 4115 {59, 54, 64, 79}, {59, 55, 64, 79}, {59, 56, 64, 79}, {59, 57, 64, 79}, {59, 58, 64, 79}, 4116 {59, 59, 64, 79}, {59, 60, 64, 79}, {59, 61, 64, 79}, {59, 62, 64, 79}, {59, 63, 64, 79}, 4117 {40, 64, 30, 31}, {40, 65, 30, 31}, {40, 66, 30, 31}, {40, 67, 30, 31}, {40, 68, 30, 31}, 4118 {40, 69, 30, 31}, {41, 64, 30, 31}, {41, 65, 30, 31}, {41, 66, 30, 31}, {41, 67, 30, 31}, 4119 {41, 68, 30, 31}, {41, 69, 30, 31}, {42, 64, 30, 31}, {42, 65, 30, 31}, {42, 66, 30, 31}, 4120 {42, 67, 30, 31}, {42, 68, 30, 31}, {42, 69, 30, 31}, {43, 64, 30, 31}, {43, 65, 30, 31}, 4121 {43, 66, 30, 31}, {43, 67, 30, 31}, {43, 68, 30, 31}, {43, 69, 30, 31}, {44, 64, 30, 31}, 4122 {44, 65, 30, 31}, {44, 66, 30, 31}, {44, 67, 30, 31}, {44, 68, 30, 31}, {44, 69, 30, 31}, 4123 {45, 64, 30, 31}, {45, 65, 30, 31}, {45, 66, 30, 31}, {45, 67, 30, 31}, {45, 68, 30, 31}, 4124 {45, 69, 30, 31}, {46, 64, 30, 31}, {46, 65, 30, 31}, {46, 66, 30, 31}, {46, 67, 30, 31}, 4125 {46, 68, 30, 31}, {46, 69, 30, 31}, {47, 64, 30, 31}, {47, 65, 30, 31}, {47, 66, 30, 31}, 4126 {47, 67, 30, 31}, {47, 68, 30, 31}, {47, 69, 30, 31}, {48, 64, 30, 31}, {48, 65, 30, 31}, 4127 {48, 66, 30, 31}, {48, 67, 30, 31}, {48, 68, 30, 31}, {48, 69, 30, 31}, {49, 64, 30, 31}, 4128 {49, 65, 30, 31}, {49, 66, 30, 31}, {49, 67, 30, 31}, {49, 68, 30, 31}, {49, 69, 30, 31}, 4129 {50, 64, 30, 31}, {50, 65, 30, 31}, {50, 66, 30, 31}, {50, 67, 30, 31}, {50, 68, 30, 31}, 4130 {50, 69, 30, 31}, {51, 64, 30, 31}, {51, 65, 30, 31}, {51, 66, 30, 31}, {51, 67, 30, 31}, 4131 {51, 68, 30, 31}, {51, 69, 30, 31}, {52, 64, 30, 31}, {52, 65, 30, 31}, {52, 66, 30, 31}, 4132 {52, 67, 30, 31}, {52, 68, 30, 31}, {52, 69, 30, 31}, {53, 64, 30, 31}, {53, 65, 30, 31}, 4133 {53, 66, 30, 31}, {53, 67, 30, 31}, {53, 68, 30, 31}, {53, 69, 30, 31}, {54, 64, 30, 31}, 4134 {54, 65, 30, 31}, {54, 66, 30, 31}, {54, 67, 30, 31}, {54, 68, 30, 31}, {54, 69, 30, 31}, 4135 {55, 64, 30, 31}, {55, 65, 30, 31}, {55, 66, 30, 31}, {55, 67, 30, 31}, {55, 68, 30, 31}, 4136 {55, 69, 30, 31}, {56, 64, 30, 31}, {56, 65, 30, 31}, {56, 66, 30, 31}, {56, 67, 30, 31}, 4137 {56, 68, 30, 31}, {56, 69, 30, 31}, {57, 64, 30, 31}, {57, 65, 30, 31}, {57, 66, 30, 31}, 4138 {57, 67, 30, 31}, {57, 68, 30, 31}, {57, 69, 30, 31}, {58, 64, 30, 31}, {58, 65, 30, 31}, 4139 {58, 66, 30, 31}, {58, 67, 30, 31}, {58, 68, 30, 31}, {58, 69, 30, 31}, {59, 64, 30, 31}, 4140 {59, 65, 30, 31}, {59, 66, 30, 31}, {59, 67, 30, 31}, {59, 68, 30, 31}, {59, 69, 30, 31}, 4141 {40, 64, 32, 63}, {40, 65, 32, 63}, {40, 66, 32, 63}, {40, 67, 32, 63}, {40, 68, 32, 63}, 4142 {40, 69, 32, 63}, {41, 64, 32, 63}, {41, 65, 32, 63}, {41, 66, 32, 63}, {41, 67, 32, 63}, 4143 {41, 68, 32, 63}, {41, 69, 32, 63}, {42, 64, 32, 63}, {42, 65, 32, 63}, {42, 66, 32, 63}, 4144 {42, 67, 32, 63}, {42, 68, 32, 63}, {42, 69, 32, 63}, {43, 64, 32, 63}, {43, 65, 32, 63}, 4145 {43, 66, 32, 63}, {43, 67, 32, 63}, {43, 68, 32, 63}, {43, 69, 32, 63}, {44, 64, 32, 63}, 4146 {44, 65, 32, 63}, {44, 66, 32, 63}, {44, 67, 32, 63}, {44, 68, 32, 63}, {44, 69, 32, 63}, 4147 {45, 64, 32, 63}, {45, 65, 32, 63}, {45, 66, 32, 63}, {45, 67, 32, 63}, {45, 68, 32, 63}, 4148 {45, 69, 32, 63}, {46, 64, 32, 63}, {46, 65, 32, 63}, {46, 66, 32, 63}, {46, 67, 32, 63}, 4149 {46, 68, 32, 63}, {46, 69, 32, 63}, {47, 64, 32, 63}, {47, 65, 32, 63}, {47, 66, 32, 63}, 4150 {47, 67, 32, 63}, {47, 68, 32, 63}, {47, 69, 32, 63}, {48, 64, 32, 63}, {48, 65, 32, 63}, 4151 {48, 66, 32, 63}, {48, 67, 32, 63}, {48, 68, 32, 63}, {48, 69, 32, 63}, {49, 64, 32, 63}, 4152 {49, 65, 32, 63}, {49, 66, 32, 63}, {49, 67, 32, 63}, {49, 68, 32, 63}, {49, 69, 32, 63}, 4153 {50, 64, 32, 63}, {50, 65, 32, 63}, {50, 66, 32, 63}, {50, 67, 32, 63}, {50, 68, 32, 63}, 4154 {50, 69, 32, 63}, {51, 64, 32, 63}, {51, 65, 32, 63}, {51, 66, 32, 63}, {51, 67, 32, 63}, 4155 {51, 68, 32, 63}, {51, 69, 32, 63}, {52, 64, 32, 63}, {52, 65, 32, 63}, {52, 66, 32, 63}, 4156 {52, 67, 32, 63}, {52, 68, 32, 63}, {52, 69, 32, 63}, {53, 64, 32, 63}, {53, 65, 32, 63}, 4157 {53, 66, 32, 63}, {53, 67, 32, 63}, {53, 68, 32, 63}, {53, 69, 32, 63}, {54, 64, 32, 63}, 4158 {54, 65, 32, 63}, {54, 66, 32, 63}, {54, 67, 32, 63}, {54, 68, 32, 63}, {54, 69, 32, 63}, 4159 {55, 64, 32, 63}, {55, 65, 32, 63}, {55, 66, 32, 63}, {55, 67, 32, 63}, {55, 68, 32, 63}, 4160 {55, 69, 32, 63}, {56, 64, 32, 63}, {56, 65, 32, 63}, {56, 66, 32, 63}, {56, 67, 32, 63}, 4161 {56, 68, 32, 63}, {56, 69, 32, 63}, {57, 64, 32, 63}, {57, 65, 32, 63}, {57, 66, 32, 63}, 4162 {57, 67, 32, 63}, {57, 68, 32, 63}, {57, 69, 32, 63}, {58, 64, 32, 63}, {58, 65, 32, 63}, 4163 {58, 66, 32, 63}, {58, 67, 32, 63}, {58, 68, 32, 63}, {58, 69, 32, 63}, {59, 64, 32, 63}, 4164 {59, 65, 32, 63}, {59, 66, 32, 63}, {59, 67, 32, 63}, {59, 68, 32, 63}, {59, 69, 32, 63}, 4165 {40, 64, 64, 79}, {40, 65, 64, 79}, {40, 66, 64, 79}, {40, 67, 64, 79}, {40, 68, 64, 79}, 4166 {40, 69, 64, 79}, {41, 64, 64, 79}, {41, 65, 64, 79}, {41, 66, 64, 79}, {41, 67, 64, 79}, 4167 {41, 68, 64, 79}, {41, 69, 64, 79}, {42, 64, 64, 79}, {42, 65, 64, 79}, {42, 66, 64, 79}, 4168 {42, 67, 64, 79}, {42, 68, 64, 79}, {42, 69, 64, 79}, {43, 64, 64, 79}, {43, 65, 64, 79}, 4169 {43, 66, 64, 79}, {43, 67, 64, 79}, {43, 68, 64, 79}, {43, 69, 64, 79}, {44, 64, 64, 79}, 4170 {44, 65, 64, 79}, {44, 66, 64, 79}, {44, 67, 64, 79}, {44, 68, 64, 79}, {44, 69, 64, 79}, 4171 {45, 64, 64, 79}, {45, 65, 64, 79}, {45, 66, 64, 79}, {45, 67, 64, 79}, {45, 68, 64, 79}, 4172 {45, 69, 64, 79}, {46, 64, 64, 79}, {46, 65, 64, 79}, {46, 66, 64, 79}, {46, 67, 64, 79}, 4173 {46, 68, 64, 79}, {46, 69, 64, 79}, {47, 64, 64, 79}, {47, 65, 64, 79}, {47, 66, 64, 79}, 4174 {47, 67, 64, 79}, {47, 68, 64, 79}, {47, 69, 64, 79}, {48, 64, 64, 79}, {48, 65, 64, 79}, 4175 {48, 66, 64, 79}, {48, 67, 64, 79}, {48, 68, 64, 79}, {48, 69, 64, 79}, {49, 64, 64, 79}, 4176 {49, 65, 64, 79}, {49, 66, 64, 79}, {49, 67, 64, 79}, {49, 68, 64, 79}, {49, 69, 64, 79}, 4177 {50, 64, 64, 79}, {50, 65, 64, 79}, {50, 66, 64, 79}, {50, 67, 64, 79}, {50, 68, 64, 79}, 4178 {50, 69, 64, 79}, {51, 64, 64, 79}, {51, 65, 64, 79}, {51, 66, 64, 79}, {51, 67, 64, 79}, 4179 {51, 68, 64, 79}, {51, 69, 64, 79}, {52, 64, 64, 79}, {52, 65, 64, 79}, {52, 66, 64, 79}, 4180 {52, 67, 64, 79}, {52, 68, 64, 79}, {52, 69, 64, 79}, {53, 64, 64, 79}, {53, 65, 64, 79}, 4181 {53, 66, 64, 79}, {53, 67, 64, 79}, {53, 68, 64, 79}, {53, 69, 64, 79}, {54, 64, 64, 79}, 4182 {54, 65, 64, 79}, {54, 66, 64, 79}, {54, 67, 64, 79}, {54, 68, 64, 79}, {54, 69, 64, 79}, 4183 {55, 64, 64, 79}, {55, 65, 64, 79}, {55, 66, 64, 79}, {55, 67, 64, 79}, {55, 68, 64, 79}, 4184 {55, 69, 64, 79}, {56, 64, 64, 79}, {56, 65, 64, 79}, {56, 66, 64, 79}, {56, 67, 64, 79}, 4185 {56, 68, 64, 79}, {56, 69, 64, 79}, {57, 64, 64, 79}, {57, 65, 64, 79}, {57, 66, 64, 79}, 4186 {57, 67, 64, 79}, {57, 68, 64, 79}, {57, 69, 64, 79}, {58, 64, 64, 79}, {58, 65, 64, 79}, 4187 {58, 66, 64, 79}, {58, 67, 64, 79}, {58, 68, 64, 79}, {58, 69, 64, 79}, {59, 64, 64, 79}, 4188 {59, 65, 64, 79}, {59, 66, 64, 79}, {59, 67, 64, 79}, {59, 68, 64, 79}, {59, 69, 64, 79}, 4189 }, 4190 } 4191 body3 = testBody{ 4192 label: 3, 4193 offset: dvid.Point3d{40, 40, 10}, 4194 size: dvid.Point3d{20, 20, 30}, 4195 blockSpans: []dvid.Span{ 4196 {0, 1, 1, 1}, 4197 {1, 1, 1, 1}, 4198 }, 4199 voxelSpans: []dvid.Span{ 4200 {10, 40, 40, 59}, {10, 41, 40, 59}, {10, 42, 40, 59}, {10, 43, 40, 59}, {10, 44, 40, 59}, 4201 {10, 45, 40, 59}, {10, 46, 40, 59}, {10, 47, 40, 59}, {10, 48, 40, 59}, {10, 49, 40, 59}, 4202 {10, 50, 40, 59}, {10, 51, 40, 59}, {10, 52, 40, 59}, {10, 53, 40, 59}, {10, 54, 40, 59}, 4203 {10, 55, 40, 59}, {10, 56, 40, 59}, {10, 57, 40, 59}, {10, 58, 40, 59}, {10, 59, 40, 59}, 4204 {11, 40, 40, 59}, {11, 41, 40, 59}, {11, 42, 40, 59}, {11, 43, 40, 59}, {11, 44, 40, 59}, 4205 {11, 45, 40, 59}, {11, 46, 40, 59}, {11, 47, 40, 59}, {11, 48, 40, 59}, {11, 49, 40, 59}, 4206 {11, 50, 40, 59}, {11, 51, 40, 59}, {11, 52, 40, 59}, {11, 53, 40, 59}, {11, 54, 40, 59}, 4207 {11, 55, 40, 59}, {11, 56, 40, 59}, {11, 57, 40, 59}, {11, 58, 40, 59}, {11, 59, 40, 59}, 4208 {12, 40, 40, 59}, {12, 41, 40, 59}, {12, 42, 40, 59}, {12, 43, 40, 59}, {12, 44, 40, 59}, 4209 {12, 45, 40, 59}, {12, 46, 40, 59}, {12, 47, 40, 59}, {12, 48, 40, 59}, {12, 49, 40, 59}, 4210 {12, 50, 40, 59}, {12, 51, 40, 59}, {12, 52, 40, 59}, {12, 53, 40, 59}, {12, 54, 40, 59}, 4211 {12, 55, 40, 59}, {12, 56, 40, 59}, {12, 57, 40, 59}, {12, 58, 40, 59}, {12, 59, 40, 59}, 4212 {13, 40, 40, 59}, {13, 41, 40, 59}, {13, 42, 40, 59}, {13, 43, 40, 59}, {13, 44, 40, 59}, 4213 {13, 45, 40, 59}, {13, 46, 40, 59}, {13, 47, 40, 59}, {13, 48, 40, 59}, {13, 49, 40, 59}, 4214 {13, 50, 40, 59}, {13, 51, 40, 59}, {13, 52, 40, 59}, {13, 53, 40, 59}, {13, 54, 40, 59}, 4215 {13, 55, 40, 59}, {13, 56, 40, 59}, {13, 57, 40, 59}, {13, 58, 40, 59}, {13, 59, 40, 59}, 4216 {14, 40, 40, 59}, {14, 41, 40, 59}, {14, 42, 40, 59}, {14, 43, 40, 59}, {14, 44, 40, 59}, 4217 {14, 45, 40, 59}, {14, 46, 40, 59}, {14, 47, 40, 59}, {14, 48, 40, 59}, {14, 49, 40, 59}, 4218 {14, 50, 40, 59}, {14, 51, 40, 59}, {14, 52, 40, 59}, {14, 53, 40, 59}, {14, 54, 40, 59}, 4219 {14, 55, 40, 59}, {14, 56, 40, 59}, {14, 57, 40, 59}, {14, 58, 40, 59}, {14, 59, 40, 59}, 4220 {15, 40, 40, 59}, {15, 41, 40, 59}, {15, 42, 40, 59}, {15, 43, 40, 59}, {15, 44, 40, 59}, 4221 {15, 45, 40, 59}, {15, 46, 40, 59}, {15, 47, 40, 59}, {15, 48, 40, 59}, {15, 49, 40, 59}, 4222 {15, 50, 40, 59}, {15, 51, 40, 59}, {15, 52, 40, 59}, {15, 53, 40, 59}, {15, 54, 40, 59}, 4223 {15, 55, 40, 59}, {15, 56, 40, 59}, {15, 57, 40, 59}, {15, 58, 40, 59}, {15, 59, 40, 59}, 4224 {16, 40, 40, 59}, {16, 41, 40, 59}, {16, 42, 40, 59}, {16, 43, 40, 59}, {16, 44, 40, 59}, 4225 {16, 45, 40, 59}, {16, 46, 40, 59}, {16, 47, 40, 59}, {16, 48, 40, 59}, {16, 49, 40, 59}, 4226 {16, 50, 40, 59}, {16, 51, 40, 59}, {16, 52, 40, 59}, {16, 53, 40, 59}, {16, 54, 40, 59}, 4227 {16, 55, 40, 59}, {16, 56, 40, 59}, {16, 57, 40, 59}, {16, 58, 40, 59}, {16, 59, 40, 59}, 4228 {17, 40, 40, 59}, {17, 41, 40, 59}, {17, 42, 40, 59}, {17, 43, 40, 59}, {17, 44, 40, 59}, 4229 {17, 45, 40, 59}, {17, 46, 40, 59}, {17, 47, 40, 59}, {17, 48, 40, 59}, {17, 49, 40, 59}, 4230 {17, 50, 40, 59}, {17, 51, 40, 59}, {17, 52, 40, 59}, {17, 53, 40, 59}, {17, 54, 40, 59}, 4231 {17, 55, 40, 59}, {17, 56, 40, 59}, {17, 57, 40, 59}, {17, 58, 40, 59}, {17, 59, 40, 59}, 4232 {18, 40, 40, 59}, {18, 41, 40, 59}, {18, 42, 40, 59}, {18, 43, 40, 59}, {18, 44, 40, 59}, 4233 {18, 45, 40, 59}, {18, 46, 40, 59}, {18, 47, 40, 59}, {18, 48, 40, 59}, {18, 49, 40, 59}, 4234 {18, 50, 40, 59}, {18, 51, 40, 59}, {18, 52, 40, 59}, {18, 53, 40, 59}, {18, 54, 40, 59}, 4235 {18, 55, 40, 59}, {18, 56, 40, 59}, {18, 57, 40, 59}, {18, 58, 40, 59}, {18, 59, 40, 59}, 4236 {19, 40, 40, 59}, {19, 41, 40, 59}, {19, 42, 40, 59}, {19, 43, 40, 59}, {19, 44, 40, 59}, 4237 {19, 45, 40, 59}, {19, 46, 40, 59}, {19, 47, 40, 59}, {19, 48, 40, 59}, {19, 49, 40, 59}, 4238 {19, 50, 40, 59}, {19, 51, 40, 59}, {19, 52, 40, 59}, {19, 53, 40, 59}, {19, 54, 40, 59}, 4239 {19, 55, 40, 59}, {19, 56, 40, 59}, {19, 57, 40, 59}, {19, 58, 40, 59}, {19, 59, 40, 59}, 4240 {20, 40, 40, 59}, {20, 41, 40, 59}, {20, 42, 40, 59}, {20, 43, 40, 59}, {20, 44, 40, 59}, 4241 {20, 45, 40, 59}, {20, 46, 40, 59}, {20, 47, 40, 59}, {20, 48, 40, 59}, {20, 49, 40, 59}, 4242 {20, 50, 40, 59}, {20, 51, 40, 59}, {20, 52, 40, 59}, {20, 53, 40, 59}, {20, 54, 40, 59}, 4243 {20, 55, 40, 59}, {20, 56, 40, 59}, {20, 57, 40, 59}, {20, 58, 40, 59}, {20, 59, 40, 59}, 4244 {21, 40, 40, 59}, {21, 41, 40, 59}, {21, 42, 40, 59}, {21, 43, 40, 59}, {21, 44, 40, 59}, 4245 {21, 45, 40, 59}, {21, 46, 40, 59}, {21, 47, 40, 59}, {21, 48, 40, 59}, {21, 49, 40, 59}, 4246 {21, 50, 40, 59}, {21, 51, 40, 59}, {21, 52, 40, 59}, {21, 53, 40, 59}, {21, 54, 40, 59}, 4247 {21, 55, 40, 59}, {21, 56, 40, 59}, {21, 57, 40, 59}, {21, 58, 40, 59}, {21, 59, 40, 59}, 4248 {22, 40, 40, 59}, {22, 41, 40, 59}, {22, 42, 40, 59}, {22, 43, 40, 59}, {22, 44, 40, 59}, 4249 {22, 45, 40, 59}, {22, 46, 40, 59}, {22, 47, 40, 59}, {22, 48, 40, 59}, {22, 49, 40, 59}, 4250 {22, 50, 40, 59}, {22, 51, 40, 59}, {22, 52, 40, 59}, {22, 53, 40, 59}, {22, 54, 40, 59}, 4251 {22, 55, 40, 59}, {22, 56, 40, 59}, {22, 57, 40, 59}, {22, 58, 40, 59}, {22, 59, 40, 59}, 4252 {23, 40, 40, 59}, {23, 41, 40, 59}, {23, 42, 40, 59}, {23, 43, 40, 59}, {23, 44, 40, 59}, 4253 {23, 45, 40, 59}, {23, 46, 40, 59}, {23, 47, 40, 59}, {23, 48, 40, 59}, {23, 49, 40, 59}, 4254 {23, 50, 40, 59}, {23, 51, 40, 59}, {23, 52, 40, 59}, {23, 53, 40, 59}, {23, 54, 40, 59}, 4255 {23, 55, 40, 59}, {23, 56, 40, 59}, {23, 57, 40, 59}, {23, 58, 40, 59}, {23, 59, 40, 59}, 4256 {24, 40, 40, 59}, {24, 41, 40, 59}, {24, 42, 40, 59}, {24, 43, 40, 59}, {24, 44, 40, 59}, 4257 {24, 45, 40, 59}, {24, 46, 40, 59}, {24, 47, 40, 59}, {24, 48, 40, 59}, {24, 49, 40, 59}, 4258 {24, 50, 40, 59}, {24, 51, 40, 59}, {24, 52, 40, 59}, {24, 53, 40, 59}, {24, 54, 40, 59}, 4259 {24, 55, 40, 59}, {24, 56, 40, 59}, {24, 57, 40, 59}, {24, 58, 40, 59}, {24, 59, 40, 59}, 4260 {25, 40, 40, 59}, {25, 41, 40, 59}, {25, 42, 40, 59}, {25, 43, 40, 59}, {25, 44, 40, 59}, 4261 {25, 45, 40, 59}, {25, 46, 40, 59}, {25, 47, 40, 59}, {25, 48, 40, 59}, {25, 49, 40, 59}, 4262 {25, 50, 40, 59}, {25, 51, 40, 59}, {25, 52, 40, 59}, {25, 53, 40, 59}, {25, 54, 40, 59}, 4263 {25, 55, 40, 59}, {25, 56, 40, 59}, {25, 57, 40, 59}, {25, 58, 40, 59}, {25, 59, 40, 59}, 4264 {26, 40, 40, 59}, {26, 41, 40, 59}, {26, 42, 40, 59}, {26, 43, 40, 59}, {26, 44, 40, 59}, 4265 {26, 45, 40, 59}, {26, 46, 40, 59}, {26, 47, 40, 59}, {26, 48, 40, 59}, {26, 49, 40, 59}, 4266 {26, 50, 40, 59}, {26, 51, 40, 59}, {26, 52, 40, 59}, {26, 53, 40, 59}, {26, 54, 40, 59}, 4267 {26, 55, 40, 59}, {26, 56, 40, 59}, {26, 57, 40, 59}, {26, 58, 40, 59}, {26, 59, 40, 59}, 4268 {27, 40, 40, 59}, {27, 41, 40, 59}, {27, 42, 40, 59}, {27, 43, 40, 59}, {27, 44, 40, 59}, 4269 {27, 45, 40, 59}, {27, 46, 40, 59}, {27, 47, 40, 59}, {27, 48, 40, 59}, {27, 49, 40, 59}, 4270 {27, 50, 40, 59}, {27, 51, 40, 59}, {27, 52, 40, 59}, {27, 53, 40, 59}, {27, 54, 40, 59}, 4271 {27, 55, 40, 59}, {27, 56, 40, 59}, {27, 57, 40, 59}, {27, 58, 40, 59}, {27, 59, 40, 59}, 4272 {28, 40, 40, 59}, {28, 41, 40, 59}, {28, 42, 40, 59}, {28, 43, 40, 59}, {28, 44, 40, 59}, 4273 {28, 45, 40, 59}, {28, 46, 40, 59}, {28, 47, 40, 59}, {28, 48, 40, 59}, {28, 49, 40, 59}, 4274 {28, 50, 40, 59}, {28, 51, 40, 59}, {28, 52, 40, 59}, {28, 53, 40, 59}, {28, 54, 40, 59}, 4275 {28, 55, 40, 59}, {28, 56, 40, 59}, {28, 57, 40, 59}, {28, 58, 40, 59}, {28, 59, 40, 59}, 4276 {29, 40, 40, 59}, {29, 41, 40, 59}, {29, 42, 40, 59}, {29, 43, 40, 59}, {29, 44, 40, 59}, 4277 {29, 45, 40, 59}, {29, 46, 40, 59}, {29, 47, 40, 59}, {29, 48, 40, 59}, {29, 49, 40, 59}, 4278 {29, 50, 40, 59}, {29, 51, 40, 59}, {29, 52, 40, 59}, {29, 53, 40, 59}, {29, 54, 40, 59}, 4279 {29, 55, 40, 59}, {29, 56, 40, 59}, {29, 57, 40, 59}, {29, 58, 40, 59}, {29, 59, 40, 59}, 4280 {30, 40, 40, 59}, {30, 41, 40, 59}, {30, 42, 40, 59}, {30, 43, 40, 59}, {30, 44, 40, 59}, 4281 {30, 45, 40, 59}, {30, 46, 40, 59}, {30, 47, 40, 59}, {30, 48, 40, 59}, {30, 49, 40, 59}, 4282 {30, 50, 40, 59}, {30, 51, 40, 59}, {30, 52, 40, 59}, {30, 53, 40, 59}, {30, 54, 40, 59}, 4283 {30, 55, 40, 59}, {30, 56, 40, 59}, {30, 57, 40, 59}, {30, 58, 40, 59}, {30, 59, 40, 59}, 4284 {31, 40, 40, 59}, {31, 41, 40, 59}, {31, 42, 40, 59}, {31, 43, 40, 59}, {31, 44, 40, 59}, 4285 {31, 45, 40, 59}, {31, 46, 40, 59}, {31, 47, 40, 59}, {31, 48, 40, 59}, {31, 49, 40, 59}, 4286 {31, 50, 40, 59}, {31, 51, 40, 59}, {31, 52, 40, 59}, {31, 53, 40, 59}, {31, 54, 40, 59}, 4287 {31, 55, 40, 59}, {31, 56, 40, 59}, {31, 57, 40, 59}, {31, 58, 40, 59}, {31, 59, 40, 59}, 4288 {32, 40, 40, 59}, {32, 41, 40, 59}, {32, 42, 40, 59}, {32, 43, 40, 59}, {32, 44, 40, 59}, 4289 {32, 45, 40, 59}, {32, 46, 40, 59}, {32, 47, 40, 59}, {32, 48, 40, 59}, {32, 49, 40, 59}, 4290 {32, 50, 40, 59}, {32, 51, 40, 59}, {32, 52, 40, 59}, {32, 53, 40, 59}, {32, 54, 40, 59}, 4291 {32, 55, 40, 59}, {32, 56, 40, 59}, {32, 57, 40, 59}, {32, 58, 40, 59}, {32, 59, 40, 59}, 4292 {33, 40, 40, 59}, {33, 41, 40, 59}, {33, 42, 40, 59}, {33, 43, 40, 59}, {33, 44, 40, 59}, 4293 {33, 45, 40, 59}, {33, 46, 40, 59}, {33, 47, 40, 59}, {33, 48, 40, 59}, {33, 49, 40, 59}, 4294 {33, 50, 40, 59}, {33, 51, 40, 59}, {33, 52, 40, 59}, {33, 53, 40, 59}, {33, 54, 40, 59}, 4295 {33, 55, 40, 59}, {33, 56, 40, 59}, {33, 57, 40, 59}, {33, 58, 40, 59}, {33, 59, 40, 59}, 4296 {34, 40, 40, 59}, {34, 41, 40, 59}, {34, 42, 40, 59}, {34, 43, 40, 59}, {34, 44, 40, 59}, 4297 {34, 45, 40, 59}, {34, 46, 40, 59}, {34, 47, 40, 59}, {34, 48, 40, 59}, {34, 49, 40, 59}, 4298 {34, 50, 40, 59}, {34, 51, 40, 59}, {34, 52, 40, 59}, {34, 53, 40, 59}, {34, 54, 40, 59}, 4299 {34, 55, 40, 59}, {34, 56, 40, 59}, {34, 57, 40, 59}, {34, 58, 40, 59}, {34, 59, 40, 59}, 4300 {35, 40, 40, 59}, {35, 41, 40, 59}, {35, 42, 40, 59}, {35, 43, 40, 59}, {35, 44, 40, 59}, 4301 {35, 45, 40, 59}, {35, 46, 40, 59}, {35, 47, 40, 59}, {35, 48, 40, 59}, {35, 49, 40, 59}, 4302 {35, 50, 40, 59}, {35, 51, 40, 59}, {35, 52, 40, 59}, {35, 53, 40, 59}, {35, 54, 40, 59}, 4303 {35, 55, 40, 59}, {35, 56, 40, 59}, {35, 57, 40, 59}, {35, 58, 40, 59}, {35, 59, 40, 59}, 4304 {36, 40, 40, 59}, {36, 41, 40, 59}, {36, 42, 40, 59}, {36, 43, 40, 59}, {36, 44, 40, 59}, 4305 {36, 45, 40, 59}, {36, 46, 40, 59}, {36, 47, 40, 59}, {36, 48, 40, 59}, {36, 49, 40, 59}, 4306 {36, 50, 40, 59}, {36, 51, 40, 59}, {36, 52, 40, 59}, {36, 53, 40, 59}, {36, 54, 40, 59}, 4307 {36, 55, 40, 59}, {36, 56, 40, 59}, {36, 57, 40, 59}, {36, 58, 40, 59}, {36, 59, 40, 59}, 4308 {37, 40, 40, 59}, {37, 41, 40, 59}, {37, 42, 40, 59}, {37, 43, 40, 59}, {37, 44, 40, 59}, 4309 {37, 45, 40, 59}, {37, 46, 40, 59}, {37, 47, 40, 59}, {37, 48, 40, 59}, {37, 49, 40, 59}, 4310 {37, 50, 40, 59}, {37, 51, 40, 59}, {37, 52, 40, 59}, {37, 53, 40, 59}, {37, 54, 40, 59}, 4311 {37, 55, 40, 59}, {37, 56, 40, 59}, {37, 57, 40, 59}, {37, 58, 40, 59}, {37, 59, 40, 59}, 4312 {38, 40, 40, 59}, {38, 41, 40, 59}, {38, 42, 40, 59}, {38, 43, 40, 59}, {38, 44, 40, 59}, 4313 {38, 45, 40, 59}, {38, 46, 40, 59}, {38, 47, 40, 59}, {38, 48, 40, 59}, {38, 49, 40, 59}, 4314 {38, 50, 40, 59}, {38, 51, 40, 59}, {38, 52, 40, 59}, {38, 53, 40, 59}, {38, 54, 40, 59}, 4315 {38, 55, 40, 59}, {38, 56, 40, 59}, {38, 57, 40, 59}, {38, 58, 40, 59}, {38, 59, 40, 59}, 4316 {39, 40, 40, 59}, {39, 41, 40, 59}, {39, 42, 40, 59}, {39, 43, 40, 59}, {39, 44, 40, 59}, 4317 {39, 45, 40, 59}, {39, 46, 40, 59}, {39, 47, 40, 59}, {39, 48, 40, 59}, {39, 49, 40, 59}, 4318 {39, 50, 40, 59}, {39, 51, 40, 59}, {39, 52, 40, 59}, {39, 53, 40, 59}, {39, 54, 40, 59}, 4319 {39, 55, 40, 59}, {39, 56, 40, 59}, {39, 57, 40, 59}, {39, 58, 40, 59}, {39, 59, 40, 59}, 4320 }, 4321 } 4322 body4 = testBody{ 4323 label: 4, 4324 offset: dvid.Point3d{75, 40, 60}, 4325 size: dvid.Point3d{20, 20, 30}, 4326 blockSpans: []dvid.Span{ 4327 {1, 1, 2, 2}, 4328 {2, 1, 2, 2}, 4329 }, 4330 voxelSpans: []dvid.Span{ 4331 {60, 40, 75, 94}, {60, 41, 75, 94}, {60, 42, 75, 94}, {60, 43, 75, 94}, {60, 44, 75, 94}, 4332 {60, 45, 75, 94}, {60, 46, 75, 94}, {60, 47, 75, 94}, {60, 48, 75, 94}, {60, 49, 75, 94}, 4333 {60, 50, 75, 94}, {60, 51, 75, 94}, {60, 52, 75, 94}, {60, 53, 75, 94}, {60, 54, 75, 94}, 4334 {60, 55, 75, 94}, {60, 56, 75, 94}, {60, 57, 75, 94}, {60, 58, 75, 94}, {60, 59, 75, 94}, 4335 {61, 40, 75, 94}, {61, 41, 75, 94}, {61, 42, 75, 94}, {61, 43, 75, 94}, {61, 44, 75, 94}, 4336 {61, 45, 75, 94}, {61, 46, 75, 94}, {61, 47, 75, 94}, {61, 48, 75, 94}, {61, 49, 75, 94}, 4337 {61, 50, 75, 94}, {61, 51, 75, 94}, {61, 52, 75, 94}, {61, 53, 75, 94}, {61, 54, 75, 94}, 4338 {61, 55, 75, 94}, {61, 56, 75, 94}, {61, 57, 75, 94}, {61, 58, 75, 94}, {61, 59, 75, 94}, 4339 {62, 40, 75, 94}, {62, 41, 75, 94}, {62, 42, 75, 94}, {62, 43, 75, 94}, {62, 44, 75, 94}, 4340 {62, 45, 75, 94}, {62, 46, 75, 94}, {62, 47, 75, 94}, {62, 48, 75, 94}, {62, 49, 75, 94}, 4341 {62, 50, 75, 94}, {62, 51, 75, 94}, {62, 52, 75, 94}, {62, 53, 75, 94}, {62, 54, 75, 94}, 4342 {62, 55, 75, 94}, {62, 56, 75, 94}, {62, 57, 75, 94}, {62, 58, 75, 94}, {62, 59, 75, 94}, 4343 {63, 40, 75, 94}, {63, 41, 75, 94}, {63, 42, 75, 94}, {63, 43, 75, 94}, {63, 44, 75, 94}, 4344 {63, 45, 75, 94}, {63, 46, 75, 94}, {63, 47, 75, 94}, {63, 48, 75, 94}, {63, 49, 75, 94}, 4345 {63, 50, 75, 94}, {63, 51, 75, 94}, {63, 52, 75, 94}, {63, 53, 75, 94}, {63, 54, 75, 94}, 4346 {63, 55, 75, 94}, {63, 56, 75, 94}, {63, 57, 75, 94}, {63, 58, 75, 94}, {63, 59, 75, 94}, 4347 {64, 40, 75, 94}, {64, 41, 75, 94}, {64, 42, 75, 94}, {64, 43, 75, 94}, {64, 44, 75, 94}, 4348 {64, 45, 75, 94}, {64, 46, 75, 94}, {64, 47, 75, 94}, {64, 48, 75, 94}, {64, 49, 75, 94}, 4349 {64, 50, 75, 94}, {64, 51, 75, 94}, {64, 52, 75, 94}, {64, 53, 75, 94}, {64, 54, 75, 94}, 4350 {64, 55, 75, 94}, {64, 56, 75, 94}, {64, 57, 75, 94}, {64, 58, 75, 94}, {64, 59, 75, 94}, 4351 {65, 40, 75, 94}, {65, 41, 75, 94}, {65, 42, 75, 94}, {65, 43, 75, 94}, {65, 44, 75, 94}, 4352 {65, 45, 75, 94}, {65, 46, 75, 94}, {65, 47, 75, 94}, {65, 48, 75, 94}, {65, 49, 75, 94}, 4353 {65, 50, 75, 94}, {65, 51, 75, 94}, {65, 52, 75, 94}, {65, 53, 75, 94}, {65, 54, 75, 94}, 4354 {65, 55, 75, 94}, {65, 56, 75, 94}, {65, 57, 75, 94}, {65, 58, 75, 94}, {65, 59, 75, 94}, 4355 {66, 40, 75, 94}, {66, 41, 75, 94}, {66, 42, 75, 94}, {66, 43, 75, 94}, {66, 44, 75, 94}, 4356 {66, 45, 75, 94}, {66, 46, 75, 94}, {66, 47, 75, 94}, {66, 48, 75, 94}, {66, 49, 75, 94}, 4357 {66, 50, 75, 94}, {66, 51, 75, 94}, {66, 52, 75, 94}, {66, 53, 75, 94}, {66, 54, 75, 94}, 4358 {66, 55, 75, 94}, {66, 56, 75, 94}, {66, 57, 75, 94}, {66, 58, 75, 94}, {66, 59, 75, 94}, 4359 {67, 40, 75, 94}, {67, 41, 75, 94}, {67, 42, 75, 94}, {67, 43, 75, 94}, {67, 44, 75, 94}, 4360 {67, 45, 75, 94}, {67, 46, 75, 94}, {67, 47, 75, 94}, {67, 48, 75, 94}, {67, 49, 75, 94}, 4361 {67, 50, 75, 94}, {67, 51, 75, 94}, {67, 52, 75, 94}, {67, 53, 75, 94}, {67, 54, 75, 94}, 4362 {67, 55, 75, 94}, {67, 56, 75, 94}, {67, 57, 75, 94}, {67, 58, 75, 94}, {67, 59, 75, 94}, 4363 {68, 40, 75, 94}, {68, 41, 75, 94}, {68, 42, 75, 94}, {68, 43, 75, 94}, {68, 44, 75, 94}, 4364 {68, 45, 75, 94}, {68, 46, 75, 94}, {68, 47, 75, 94}, {68, 48, 75, 94}, {68, 49, 75, 94}, 4365 {68, 50, 75, 94}, {68, 51, 75, 94}, {68, 52, 75, 94}, {68, 53, 75, 94}, {68, 54, 75, 94}, 4366 {68, 55, 75, 94}, {68, 56, 75, 94}, {68, 57, 75, 94}, {68, 58, 75, 94}, {68, 59, 75, 94}, 4367 {69, 40, 75, 94}, {69, 41, 75, 94}, {69, 42, 75, 94}, {69, 43, 75, 94}, {69, 44, 75, 94}, 4368 {69, 45, 75, 94}, {69, 46, 75, 94}, {69, 47, 75, 94}, {69, 48, 75, 94}, {69, 49, 75, 94}, 4369 {69, 50, 75, 94}, {69, 51, 75, 94}, {69, 52, 75, 94}, {69, 53, 75, 94}, {69, 54, 75, 94}, 4370 {69, 55, 75, 94}, {69, 56, 75, 94}, {69, 57, 75, 94}, {69, 58, 75, 94}, {69, 59, 75, 94}, 4371 {70, 40, 75, 94}, {70, 41, 75, 94}, {70, 42, 75, 94}, {70, 43, 75, 94}, {70, 44, 75, 94}, 4372 {70, 45, 75, 94}, {70, 46, 75, 94}, {70, 47, 75, 94}, {70, 48, 75, 94}, {70, 49, 75, 94}, 4373 {70, 50, 75, 94}, {70, 51, 75, 94}, {70, 52, 75, 94}, {70, 53, 75, 94}, {70, 54, 75, 94}, 4374 {70, 55, 75, 94}, {70, 56, 75, 94}, {70, 57, 75, 94}, {70, 58, 75, 94}, {70, 59, 75, 94}, 4375 {71, 40, 75, 94}, {71, 41, 75, 94}, {71, 42, 75, 94}, {71, 43, 75, 94}, {71, 44, 75, 94}, 4376 {71, 45, 75, 94}, {71, 46, 75, 94}, {71, 47, 75, 94}, {71, 48, 75, 94}, {71, 49, 75, 94}, 4377 {71, 50, 75, 94}, {71, 51, 75, 94}, {71, 52, 75, 94}, {71, 53, 75, 94}, {71, 54, 75, 94}, 4378 {71, 55, 75, 94}, {71, 56, 75, 94}, {71, 57, 75, 94}, {71, 58, 75, 94}, {71, 59, 75, 94}, 4379 {72, 40, 75, 94}, {72, 41, 75, 94}, {72, 42, 75, 94}, {72, 43, 75, 94}, {72, 44, 75, 94}, 4380 {72, 45, 75, 94}, {72, 46, 75, 94}, {72, 47, 75, 94}, {72, 48, 75, 94}, {72, 49, 75, 94}, 4381 {72, 50, 75, 94}, {72, 51, 75, 94}, {72, 52, 75, 94}, {72, 53, 75, 94}, {72, 54, 75, 94}, 4382 {72, 55, 75, 94}, {72, 56, 75, 94}, {72, 57, 75, 94}, {72, 58, 75, 94}, {72, 59, 75, 94}, 4383 {73, 40, 75, 94}, {73, 41, 75, 94}, {73, 42, 75, 94}, {73, 43, 75, 94}, {73, 44, 75, 94}, 4384 {73, 45, 75, 94}, {73, 46, 75, 94}, {73, 47, 75, 94}, {73, 48, 75, 94}, {73, 49, 75, 94}, 4385 {73, 50, 75, 94}, {73, 51, 75, 94}, {73, 52, 75, 94}, {73, 53, 75, 94}, {73, 54, 75, 94}, 4386 {73, 55, 75, 94}, {73, 56, 75, 94}, {73, 57, 75, 94}, {73, 58, 75, 94}, {73, 59, 75, 94}, 4387 {74, 40, 75, 94}, {74, 41, 75, 94}, {74, 42, 75, 94}, {74, 43, 75, 94}, {74, 44, 75, 94}, 4388 {74, 45, 75, 94}, {74, 46, 75, 94}, {74, 47, 75, 94}, {74, 48, 75, 94}, {74, 49, 75, 94}, 4389 {74, 50, 75, 94}, {74, 51, 75, 94}, {74, 52, 75, 94}, {74, 53, 75, 94}, {74, 54, 75, 94}, 4390 {74, 55, 75, 94}, {74, 56, 75, 94}, {74, 57, 75, 94}, {74, 58, 75, 94}, {74, 59, 75, 94}, 4391 {75, 40, 75, 94}, {75, 41, 75, 94}, {75, 42, 75, 94}, {75, 43, 75, 94}, {75, 44, 75, 94}, 4392 {75, 45, 75, 94}, {75, 46, 75, 94}, {75, 47, 75, 94}, {75, 48, 75, 94}, {75, 49, 75, 94}, 4393 {75, 50, 75, 94}, {75, 51, 75, 94}, {75, 52, 75, 94}, {75, 53, 75, 94}, {75, 54, 75, 94}, 4394 {75, 55, 75, 94}, {75, 56, 75, 94}, {75, 57, 75, 94}, {75, 58, 75, 94}, {75, 59, 75, 94}, 4395 {76, 40, 75, 94}, {76, 41, 75, 94}, {76, 42, 75, 94}, {76, 43, 75, 94}, {76, 44, 75, 94}, 4396 {76, 45, 75, 94}, {76, 46, 75, 94}, {76, 47, 75, 94}, {76, 48, 75, 94}, {76, 49, 75, 94}, 4397 {76, 50, 75, 94}, {76, 51, 75, 94}, {76, 52, 75, 94}, {76, 53, 75, 94}, {76, 54, 75, 94}, 4398 {76, 55, 75, 94}, {76, 56, 75, 94}, {76, 57, 75, 94}, {76, 58, 75, 94}, {76, 59, 75, 94}, 4399 {77, 40, 75, 94}, {77, 41, 75, 94}, {77, 42, 75, 94}, {77, 43, 75, 94}, {77, 44, 75, 94}, 4400 {77, 45, 75, 94}, {77, 46, 75, 94}, {77, 47, 75, 94}, {77, 48, 75, 94}, {77, 49, 75, 94}, 4401 {77, 50, 75, 94}, {77, 51, 75, 94}, {77, 52, 75, 94}, {77, 53, 75, 94}, {77, 54, 75, 94}, 4402 {77, 55, 75, 94}, {77, 56, 75, 94}, {77, 57, 75, 94}, {77, 58, 75, 94}, {77, 59, 75, 94}, 4403 {78, 40, 75, 94}, {78, 41, 75, 94}, {78, 42, 75, 94}, {78, 43, 75, 94}, {78, 44, 75, 94}, 4404 {78, 45, 75, 94}, {78, 46, 75, 94}, {78, 47, 75, 94}, {78, 48, 75, 94}, {78, 49, 75, 94}, 4405 {78, 50, 75, 94}, {78, 51, 75, 94}, {78, 52, 75, 94}, {78, 53, 75, 94}, {78, 54, 75, 94}, 4406 {78, 55, 75, 94}, {78, 56, 75, 94}, {78, 57, 75, 94}, {78, 58, 75, 94}, {78, 59, 75, 94}, 4407 {79, 40, 75, 94}, {79, 41, 75, 94}, {79, 42, 75, 94}, {79, 43, 75, 94}, {79, 44, 75, 94}, 4408 {79, 45, 75, 94}, {79, 46, 75, 94}, {79, 47, 75, 94}, {79, 48, 75, 94}, {79, 49, 75, 94}, 4409 {79, 50, 75, 94}, {79, 51, 75, 94}, {79, 52, 75, 94}, {79, 53, 75, 94}, {79, 54, 75, 94}, 4410 {79, 55, 75, 94}, {79, 56, 75, 94}, {79, 57, 75, 94}, {79, 58, 75, 94}, {79, 59, 75, 94}, 4411 {80, 40, 75, 94}, {80, 41, 75, 94}, {80, 42, 75, 94}, {80, 43, 75, 94}, {80, 44, 75, 94}, 4412 {80, 45, 75, 94}, {80, 46, 75, 94}, {80, 47, 75, 94}, {80, 48, 75, 94}, {80, 49, 75, 94}, 4413 {80, 50, 75, 94}, {80, 51, 75, 94}, {80, 52, 75, 94}, {80, 53, 75, 94}, {80, 54, 75, 94}, 4414 {80, 55, 75, 94}, {80, 56, 75, 94}, {80, 57, 75, 94}, {80, 58, 75, 94}, {80, 59, 75, 94}, 4415 {81, 40, 75, 94}, {81, 41, 75, 94}, {81, 42, 75, 94}, {81, 43, 75, 94}, {81, 44, 75, 94}, 4416 {81, 45, 75, 94}, {81, 46, 75, 94}, {81, 47, 75, 94}, {81, 48, 75, 94}, {81, 49, 75, 94}, 4417 {81, 50, 75, 94}, {81, 51, 75, 94}, {81, 52, 75, 94}, {81, 53, 75, 94}, {81, 54, 75, 94}, 4418 {81, 55, 75, 94}, {81, 56, 75, 94}, {81, 57, 75, 94}, {81, 58, 75, 94}, {81, 59, 75, 94}, 4419 {82, 40, 75, 94}, {82, 41, 75, 94}, {82, 42, 75, 94}, {82, 43, 75, 94}, {82, 44, 75, 94}, 4420 {82, 45, 75, 94}, {82, 46, 75, 94}, {82, 47, 75, 94}, {82, 48, 75, 94}, {82, 49, 75, 94}, 4421 {82, 50, 75, 94}, {82, 51, 75, 94}, {82, 52, 75, 94}, {82, 53, 75, 94}, {82, 54, 75, 94}, 4422 {82, 55, 75, 94}, {82, 56, 75, 94}, {82, 57, 75, 94}, {82, 58, 75, 94}, {82, 59, 75, 94}, 4423 {83, 40, 75, 94}, {83, 41, 75, 94}, {83, 42, 75, 94}, {83, 43, 75, 94}, {83, 44, 75, 94}, 4424 {83, 45, 75, 94}, {83, 46, 75, 94}, {83, 47, 75, 94}, {83, 48, 75, 94}, {83, 49, 75, 94}, 4425 {83, 50, 75, 94}, {83, 51, 75, 94}, {83, 52, 75, 94}, {83, 53, 75, 94}, {83, 54, 75, 94}, 4426 {83, 55, 75, 94}, {83, 56, 75, 94}, {83, 57, 75, 94}, {83, 58, 75, 94}, {83, 59, 75, 94}, 4427 {84, 40, 75, 94}, {84, 41, 75, 94}, {84, 42, 75, 94}, {84, 43, 75, 94}, {84, 44, 75, 94}, 4428 {84, 45, 75, 94}, {84, 46, 75, 94}, {84, 47, 75, 94}, {84, 48, 75, 94}, {84, 49, 75, 94}, 4429 {84, 50, 75, 94}, {84, 51, 75, 94}, {84, 52, 75, 94}, {84, 53, 75, 94}, {84, 54, 75, 94}, 4430 {84, 55, 75, 94}, {84, 56, 75, 94}, {84, 57, 75, 94}, {84, 58, 75, 94}, {84, 59, 75, 94}, 4431 {85, 40, 75, 94}, {85, 41, 75, 94}, {85, 42, 75, 94}, {85, 43, 75, 94}, {85, 44, 75, 94}, 4432 {85, 45, 75, 94}, {85, 46, 75, 94}, {85, 47, 75, 94}, {85, 48, 75, 94}, {85, 49, 75, 94}, 4433 {85, 50, 75, 94}, {85, 51, 75, 94}, {85, 52, 75, 94}, {85, 53, 75, 94}, {85, 54, 75, 94}, 4434 {85, 55, 75, 94}, {85, 56, 75, 94}, {85, 57, 75, 94}, {85, 58, 75, 94}, {85, 59, 75, 94}, 4435 {86, 40, 75, 94}, {86, 41, 75, 94}, {86, 42, 75, 94}, {86, 43, 75, 94}, {86, 44, 75, 94}, 4436 {86, 45, 75, 94}, {86, 46, 75, 94}, {86, 47, 75, 94}, {86, 48, 75, 94}, {86, 49, 75, 94}, 4437 {86, 50, 75, 94}, {86, 51, 75, 94}, {86, 52, 75, 94}, {86, 53, 75, 94}, {86, 54, 75, 94}, 4438 {86, 55, 75, 94}, {86, 56, 75, 94}, {86, 57, 75, 94}, {86, 58, 75, 94}, {86, 59, 75, 94}, 4439 {87, 40, 75, 94}, {87, 41, 75, 94}, {87, 42, 75, 94}, {87, 43, 75, 94}, {87, 44, 75, 94}, 4440 {87, 45, 75, 94}, {87, 46, 75, 94}, {87, 47, 75, 94}, {87, 48, 75, 94}, {87, 49, 75, 94}, 4441 {87, 50, 75, 94}, {87, 51, 75, 94}, {87, 52, 75, 94}, {87, 53, 75, 94}, {87, 54, 75, 94}, 4442 {87, 55, 75, 94}, {87, 56, 75, 94}, {87, 57, 75, 94}, {87, 58, 75, 94}, {87, 59, 75, 94}, 4443 {88, 40, 75, 94}, {88, 41, 75, 94}, {88, 42, 75, 94}, {88, 43, 75, 94}, {88, 44, 75, 94}, 4444 {88, 45, 75, 94}, {88, 46, 75, 94}, {88, 47, 75, 94}, {88, 48, 75, 94}, {88, 49, 75, 94}, 4445 {88, 50, 75, 94}, {88, 51, 75, 94}, {88, 52, 75, 94}, {88, 53, 75, 94}, {88, 54, 75, 94}, 4446 {88, 55, 75, 94}, {88, 56, 75, 94}, {88, 57, 75, 94}, {88, 58, 75, 94}, {88, 59, 75, 94}, 4447 {89, 40, 75, 94}, {89, 41, 75, 94}, {89, 42, 75, 94}, {89, 43, 75, 94}, {89, 44, 75, 94}, 4448 {89, 45, 75, 94}, {89, 46, 75, 94}, {89, 47, 75, 94}, {89, 48, 75, 94}, {89, 49, 75, 94}, 4449 {89, 50, 75, 94}, {89, 51, 75, 94}, {89, 52, 75, 94}, {89, 53, 75, 94}, {89, 54, 75, 94}, 4450 {89, 55, 75, 94}, {89, 56, 75, 94}, {89, 57, 75, 94}, {89, 58, 75, 94}, {89, 59, 75, 94}, 4451 }, 4452 } 4453 bodyleft = testBody{ 4454 label: 6, 4455 offset: dvid.Point3d{75, 40, 60}, 4456 size: dvid.Point3d{20, 20, 21}, 4457 blockSpans: []dvid.Span{ 4458 {1, 1, 2, 2}, 4459 {2, 1, 2, 2}, 4460 }, 4461 voxelSpans: []dvid.Span{ 4462 {60, 40, 75, 94}, {60, 41, 75, 94}, {60, 42, 75, 94}, {60, 43, 75, 94}, {60, 44, 75, 94}, 4463 {60, 45, 75, 94}, {60, 46, 75, 94}, {60, 47, 75, 94}, {60, 48, 75, 94}, {60, 49, 75, 94}, 4464 {60, 50, 75, 94}, {60, 51, 75, 94}, {60, 52, 75, 94}, {60, 53, 75, 94}, {60, 54, 75, 94}, 4465 {60, 55, 75, 94}, {60, 56, 75, 94}, {60, 57, 75, 94}, {60, 58, 75, 94}, {60, 59, 75, 94}, 4466 {61, 40, 75, 94}, {61, 41, 75, 94}, {61, 42, 75, 94}, {61, 43, 75, 94}, {61, 44, 75, 94}, 4467 {61, 45, 75, 94}, {61, 46, 75, 94}, {61, 47, 75, 94}, {61, 48, 75, 94}, {61, 49, 75, 94}, 4468 {61, 50, 75, 94}, {61, 51, 75, 94}, {61, 52, 75, 94}, {61, 53, 75, 94}, {61, 54, 75, 94}, 4469 {61, 55, 75, 94}, {61, 56, 75, 94}, {61, 57, 75, 94}, {61, 58, 75, 94}, {61, 59, 75, 94}, 4470 {62, 40, 75, 94}, {62, 41, 75, 94}, {62, 42, 75, 94}, {62, 43, 75, 94}, {62, 44, 75, 94}, 4471 {62, 45, 75, 94}, {62, 46, 75, 94}, {62, 47, 75, 94}, {62, 48, 75, 94}, {62, 49, 75, 94}, 4472 {62, 50, 75, 94}, {62, 51, 75, 94}, {62, 52, 75, 94}, {62, 53, 75, 94}, {62, 54, 75, 94}, 4473 {62, 55, 75, 94}, {62, 56, 75, 94}, {62, 57, 75, 94}, {62, 58, 75, 94}, {62, 59, 75, 94}, 4474 {63, 40, 75, 94}, {63, 41, 75, 94}, {63, 42, 75, 94}, {63, 43, 75, 94}, {63, 44, 75, 94}, 4475 {63, 45, 75, 94}, {63, 46, 75, 94}, {63, 47, 75, 94}, {63, 48, 75, 94}, {63, 49, 75, 94}, 4476 {63, 50, 75, 94}, {63, 51, 75, 94}, {63, 52, 75, 94}, {63, 53, 75, 94}, {63, 54, 75, 94}, 4477 {63, 55, 75, 94}, {63, 56, 75, 94}, {63, 57, 75, 94}, {63, 58, 75, 94}, {63, 59, 75, 94}, 4478 {64, 40, 75, 94}, {64, 41, 75, 94}, {64, 42, 75, 94}, {64, 43, 75, 94}, {64, 44, 75, 94}, 4479 {64, 45, 75, 94}, {64, 46, 75, 94}, {64, 47, 75, 94}, {64, 48, 75, 94}, {64, 49, 75, 94}, 4480 {64, 50, 75, 94}, {64, 51, 75, 94}, {64, 52, 75, 94}, {64, 53, 75, 94}, {64, 54, 75, 94}, 4481 {64, 55, 75, 94}, {64, 56, 75, 94}, {64, 57, 75, 94}, {64, 58, 75, 94}, {64, 59, 75, 94}, 4482 {65, 40, 75, 94}, {65, 41, 75, 94}, {65, 42, 75, 94}, {65, 43, 75, 94}, {65, 44, 75, 94}, 4483 {65, 45, 75, 94}, {65, 46, 75, 94}, {65, 47, 75, 94}, {65, 48, 75, 94}, {65, 49, 75, 94}, 4484 {65, 50, 75, 94}, {65, 51, 75, 94}, {65, 52, 75, 94}, {65, 53, 75, 94}, {65, 54, 75, 94}, 4485 {65, 55, 75, 94}, {65, 56, 75, 94}, {65, 57, 75, 94}, {65, 58, 75, 94}, {65, 59, 75, 94}, 4486 {66, 40, 75, 94}, {66, 41, 75, 94}, {66, 42, 75, 94}, {66, 43, 75, 94}, {66, 44, 75, 94}, 4487 {66, 45, 75, 94}, {66, 46, 75, 94}, {66, 47, 75, 94}, {66, 48, 75, 94}, {66, 49, 75, 94}, 4488 {66, 50, 75, 94}, {66, 51, 75, 94}, {66, 52, 75, 94}, {66, 53, 75, 94}, {66, 54, 75, 94}, 4489 {66, 55, 75, 94}, {66, 56, 75, 94}, {66, 57, 75, 94}, {66, 58, 75, 94}, {66, 59, 75, 94}, 4490 {67, 40, 75, 94}, {67, 41, 75, 94}, {67, 42, 75, 94}, {67, 43, 75, 94}, {67, 44, 75, 94}, 4491 {67, 45, 75, 94}, {67, 46, 75, 94}, {67, 47, 75, 94}, {67, 48, 75, 94}, {67, 49, 75, 94}, 4492 {67, 50, 75, 94}, {67, 51, 75, 94}, {67, 52, 75, 94}, {67, 53, 75, 94}, {67, 54, 75, 94}, 4493 {67, 55, 75, 94}, {67, 56, 75, 94}, {67, 57, 75, 94}, {67, 58, 75, 94}, {67, 59, 75, 94}, 4494 {68, 40, 75, 94}, {68, 41, 75, 94}, {68, 42, 75, 94}, {68, 43, 75, 94}, {68, 44, 75, 94}, 4495 {68, 45, 75, 94}, {68, 46, 75, 94}, {68, 47, 75, 94}, {68, 48, 75, 94}, {68, 49, 75, 94}, 4496 {68, 50, 75, 94}, {68, 51, 75, 94}, {68, 52, 75, 94}, {68, 53, 75, 94}, {68, 54, 75, 94}, 4497 {68, 55, 75, 94}, {68, 56, 75, 94}, {68, 57, 75, 94}, {68, 58, 75, 94}, {68, 59, 75, 94}, 4498 {69, 40, 75, 94}, {69, 41, 75, 94}, {69, 42, 75, 94}, {69, 43, 75, 94}, {69, 44, 75, 94}, 4499 {69, 45, 75, 94}, {69, 46, 75, 94}, {69, 47, 75, 94}, {69, 48, 75, 94}, {69, 49, 75, 94}, 4500 {69, 50, 75, 94}, {69, 51, 75, 94}, {69, 52, 75, 94}, {69, 53, 75, 94}, {69, 54, 75, 94}, 4501 {69, 55, 75, 94}, {69, 56, 75, 94}, {69, 57, 75, 94}, {69, 58, 75, 94}, {69, 59, 75, 94}, 4502 {70, 40, 75, 94}, {70, 41, 75, 94}, {70, 42, 75, 94}, {70, 43, 75, 94}, {70, 44, 75, 94}, 4503 {70, 45, 75, 94}, {70, 46, 75, 94}, {70, 47, 75, 94}, {70, 48, 75, 94}, {70, 49, 75, 94}, 4504 {70, 50, 75, 94}, {70, 51, 75, 94}, {70, 52, 75, 94}, {70, 53, 75, 94}, {70, 54, 75, 94}, 4505 {70, 55, 75, 94}, {70, 56, 75, 94}, {70, 57, 75, 94}, {70, 58, 75, 94}, {70, 59, 75, 94}, 4506 {71, 40, 75, 94}, {71, 41, 75, 94}, {71, 42, 75, 94}, {71, 43, 75, 94}, {71, 44, 75, 94}, 4507 {71, 45, 75, 94}, {71, 46, 75, 94}, {71, 47, 75, 94}, {71, 48, 75, 94}, {71, 49, 75, 94}, 4508 {71, 50, 75, 94}, {71, 51, 75, 94}, {71, 52, 75, 94}, {71, 53, 75, 94}, {71, 54, 75, 94}, 4509 {71, 55, 75, 94}, {71, 56, 75, 94}, {71, 57, 75, 94}, {71, 58, 75, 94}, {71, 59, 75, 94}, 4510 {72, 40, 75, 94}, {72, 41, 75, 94}, {72, 42, 75, 94}, {72, 43, 75, 94}, {72, 44, 75, 94}, 4511 {72, 45, 75, 94}, {72, 46, 75, 94}, {72, 47, 75, 94}, {72, 48, 75, 94}, {72, 49, 75, 94}, 4512 {72, 50, 75, 94}, {72, 51, 75, 94}, {72, 52, 75, 94}, {72, 53, 75, 94}, {72, 54, 75, 94}, 4513 {72, 55, 75, 94}, {72, 56, 75, 94}, {72, 57, 75, 94}, {72, 58, 75, 94}, {72, 59, 75, 94}, 4514 {73, 40, 75, 94}, {73, 41, 75, 94}, {73, 42, 75, 94}, {73, 43, 75, 94}, {73, 44, 75, 94}, 4515 {73, 45, 75, 94}, {73, 46, 75, 94}, {73, 47, 75, 94}, {73, 48, 75, 94}, {73, 49, 75, 94}, 4516 {73, 50, 75, 94}, {73, 51, 75, 94}, {73, 52, 75, 94}, {73, 53, 75, 94}, {73, 54, 75, 94}, 4517 {73, 55, 75, 94}, {73, 56, 75, 94}, {73, 57, 75, 94}, {73, 58, 75, 94}, {73, 59, 75, 94}, 4518 {74, 40, 75, 94}, {74, 41, 75, 94}, {74, 42, 75, 94}, {74, 43, 75, 94}, {74, 44, 75, 94}, 4519 {74, 45, 75, 94}, {74, 46, 75, 94}, {74, 47, 75, 94}, {74, 48, 75, 94}, {74, 49, 75, 94}, 4520 {74, 50, 75, 94}, {74, 51, 75, 94}, {74, 52, 75, 94}, {74, 53, 75, 94}, {74, 54, 75, 94}, 4521 {74, 55, 75, 94}, {74, 56, 75, 94}, {74, 57, 75, 94}, {74, 58, 75, 94}, {74, 59, 75, 94}, 4522 {75, 40, 75, 94}, {75, 41, 75, 94}, {75, 42, 75, 94}, {75, 43, 75, 94}, {75, 44, 75, 94}, 4523 {75, 45, 75, 94}, {75, 46, 75, 94}, {75, 47, 75, 94}, {75, 48, 75, 94}, {75, 49, 75, 94}, 4524 {75, 50, 75, 94}, {75, 51, 75, 94}, {75, 52, 75, 94}, {75, 53, 75, 94}, {75, 54, 75, 94}, 4525 {75, 55, 75, 94}, {75, 56, 75, 94}, {75, 57, 75, 94}, {75, 58, 75, 94}, {75, 59, 75, 94}, 4526 {76, 40, 75, 94}, {76, 41, 75, 94}, {76, 42, 75, 94}, {76, 43, 75, 94}, {76, 44, 75, 94}, 4527 {76, 45, 75, 94}, {76, 46, 75, 94}, {76, 47, 75, 94}, {76, 48, 75, 94}, {76, 49, 75, 94}, 4528 {76, 50, 75, 94}, {76, 51, 75, 94}, {76, 52, 75, 94}, {76, 53, 75, 94}, {76, 54, 75, 94}, 4529 {76, 55, 75, 94}, {76, 56, 75, 94}, {76, 57, 75, 94}, {76, 58, 75, 94}, {76, 59, 75, 94}, 4530 {77, 40, 75, 94}, {77, 41, 75, 94}, {77, 42, 75, 94}, {77, 43, 75, 94}, {77, 44, 75, 94}, 4531 {77, 45, 75, 94}, {77, 46, 75, 94}, {77, 47, 75, 94}, {77, 48, 75, 94}, {77, 49, 75, 94}, 4532 {77, 50, 75, 94}, {77, 51, 75, 94}, {77, 52, 75, 94}, {77, 53, 75, 94}, {77, 54, 75, 94}, 4533 {77, 55, 75, 94}, {77, 56, 75, 94}, {77, 57, 75, 94}, {77, 58, 75, 94}, {77, 59, 75, 94}, 4534 {78, 40, 75, 94}, {78, 41, 75, 94}, {78, 42, 75, 94}, {78, 43, 75, 94}, {78, 44, 75, 94}, 4535 {78, 45, 75, 94}, {78, 46, 75, 94}, {78, 47, 75, 94}, {78, 48, 75, 94}, {78, 49, 75, 94}, 4536 {78, 50, 75, 94}, {78, 51, 75, 94}, {78, 52, 75, 94}, {78, 53, 75, 94}, {78, 54, 75, 94}, 4537 {78, 55, 75, 94}, {78, 56, 75, 94}, {78, 57, 75, 94}, {78, 58, 75, 94}, {78, 59, 75, 94}, 4538 {79, 40, 75, 94}, {79, 41, 75, 94}, {79, 42, 75, 94}, {79, 43, 75, 94}, {79, 44, 75, 94}, 4539 {79, 45, 75, 94}, {79, 46, 75, 94}, {79, 47, 75, 94}, {79, 48, 75, 94}, {79, 49, 75, 94}, 4540 {79, 50, 75, 94}, {79, 51, 75, 94}, {79, 52, 75, 94}, {79, 53, 75, 94}, {79, 54, 75, 94}, 4541 {79, 55, 75, 94}, {79, 56, 75, 94}, {79, 57, 75, 94}, {79, 58, 75, 94}, {79, 59, 75, 94}, 4542 {80, 40, 75, 80}, {80, 40, 87, 89}, {80, 40, 93, 94}, 4543 }, 4544 } 4545 bodysplit = testBody{ 4546 label: 5, 4547 offset: dvid.Point3d{75, 40, 80}, 4548 size: dvid.Point3d{20, 20, 10}, 4549 blockSpans: []dvid.Span{ 4550 {2, 1, 2, 2}, 4551 }, 4552 voxelSpans: []dvid.Span{ 4553 {80, 40, 81, 86}, {80, 40, 90, 92}, // These first 2 test splits interleaved in one span. 4554 {80, 41, 75, 94}, {80, 42, 75, 94}, {80, 43, 75, 94}, {80, 44, 75, 94}, 4555 {80, 45, 75, 94}, {80, 46, 75, 94}, {80, 47, 75, 94}, {80, 48, 75, 94}, {80, 49, 75, 94}, 4556 {80, 50, 75, 94}, {80, 51, 75, 94}, {80, 52, 75, 94}, {80, 53, 75, 94}, {80, 54, 75, 94}, 4557 {80, 55, 75, 94}, {80, 56, 75, 94}, {80, 57, 75, 94}, {80, 58, 75, 94}, {80, 59, 75, 94}, 4558 {81, 40, 75, 94}, {81, 41, 75, 94}, {81, 42, 75, 94}, {81, 43, 75, 94}, {81, 44, 75, 94}, 4559 {81, 45, 75, 94}, {81, 46, 75, 94}, {81, 47, 75, 94}, {81, 48, 75, 94}, {81, 49, 75, 94}, 4560 {81, 50, 75, 94}, {81, 51, 75, 94}, {81, 52, 75, 94}, {81, 53, 75, 94}, {81, 54, 75, 94}, 4561 {81, 55, 75, 94}, {81, 56, 75, 94}, {81, 57, 75, 94}, {81, 58, 75, 94}, {81, 59, 75, 94}, 4562 {82, 40, 75, 94}, {82, 41, 75, 94}, {82, 42, 75, 94}, {82, 43, 75, 94}, {82, 44, 75, 94}, 4563 {82, 45, 75, 94}, {82, 46, 75, 94}, {82, 47, 75, 94}, {82, 48, 75, 94}, {82, 49, 75, 94}, 4564 {82, 50, 75, 94}, {82, 51, 75, 94}, {82, 52, 75, 94}, {82, 53, 75, 94}, {82, 54, 75, 94}, 4565 {82, 55, 75, 94}, {82, 56, 75, 94}, {82, 57, 75, 94}, {82, 58, 75, 94}, {82, 59, 75, 94}, 4566 {83, 40, 75, 94}, {83, 41, 75, 94}, {83, 42, 75, 94}, {83, 43, 75, 94}, {83, 44, 75, 94}, 4567 {83, 45, 75, 94}, {83, 46, 75, 94}, {83, 47, 75, 94}, {83, 48, 75, 94}, {83, 49, 75, 94}, 4568 {83, 50, 75, 94}, {83, 51, 75, 94}, {83, 52, 75, 94}, {83, 53, 75, 94}, {83, 54, 75, 94}, 4569 {83, 55, 75, 94}, {83, 56, 75, 94}, {83, 57, 75, 94}, {83, 58, 75, 94}, {83, 59, 75, 94}, 4570 {84, 40, 75, 94}, {84, 41, 75, 94}, {84, 42, 75, 94}, {84, 43, 75, 94}, {84, 44, 75, 94}, 4571 {84, 45, 75, 94}, {84, 46, 75, 94}, {84, 47, 75, 94}, {84, 48, 75, 94}, {84, 49, 75, 94}, 4572 {84, 50, 75, 94}, {84, 51, 75, 94}, {84, 52, 75, 94}, {84, 53, 75, 94}, {84, 54, 75, 94}, 4573 {84, 55, 75, 94}, {84, 56, 75, 94}, {84, 57, 75, 94}, {84, 58, 75, 94}, {84, 59, 75, 94}, 4574 {85, 40, 75, 94}, {85, 41, 75, 94}, {85, 42, 75, 94}, {85, 43, 75, 94}, {85, 44, 75, 94}, 4575 {85, 45, 75, 94}, {85, 46, 75, 94}, {85, 47, 75, 94}, {85, 48, 75, 94}, {85, 49, 75, 94}, 4576 {85, 50, 75, 94}, {85, 51, 75, 94}, {85, 52, 75, 94}, {85, 53, 75, 94}, {85, 54, 75, 94}, 4577 {85, 55, 75, 94}, {85, 56, 75, 94}, {85, 57, 75, 94}, {85, 58, 75, 94}, {85, 59, 75, 94}, 4578 {86, 40, 75, 94}, {86, 41, 75, 94}, {86, 42, 75, 94}, {86, 43, 75, 94}, {86, 44, 75, 94}, 4579 {86, 45, 75, 94}, {86, 46, 75, 94}, {86, 47, 75, 94}, {86, 48, 75, 94}, {86, 49, 75, 94}, 4580 {86, 50, 75, 94}, {86, 51, 75, 94}, {86, 52, 75, 94}, {86, 53, 75, 94}, {86, 54, 75, 94}, 4581 {86, 55, 75, 94}, {86, 56, 75, 94}, {86, 57, 75, 94}, {86, 58, 75, 94}, {86, 59, 75, 94}, 4582 {87, 40, 75, 94}, {87, 41, 75, 94}, {87, 42, 75, 94}, {87, 43, 75, 94}, {87, 44, 75, 94}, 4583 {87, 45, 75, 94}, {87, 46, 75, 94}, {87, 47, 75, 94}, {87, 48, 75, 94}, {87, 49, 75, 94}, 4584 {87, 50, 75, 94}, {87, 51, 75, 94}, {87, 52, 75, 94}, {87, 53, 75, 94}, {87, 54, 75, 94}, 4585 {87, 55, 75, 94}, {87, 56, 75, 94}, {87, 57, 75, 94}, {87, 58, 75, 94}, {87, 59, 75, 94}, 4586 {88, 40, 75, 94}, {88, 41, 75, 94}, {88, 42, 75, 94}, {88, 43, 75, 94}, {88, 44, 75, 94}, 4587 {88, 45, 75, 94}, {88, 46, 75, 94}, {88, 47, 75, 94}, {88, 48, 75, 94}, {88, 49, 75, 94}, 4588 {88, 50, 75, 94}, {88, 51, 75, 94}, {88, 52, 75, 94}, {88, 53, 75, 94}, {88, 54, 75, 94}, 4589 {88, 55, 75, 94}, {88, 56, 75, 94}, {88, 57, 75, 94}, {88, 58, 75, 94}, {88, 59, 75, 94}, 4590 {89, 40, 75, 94}, {89, 41, 75, 94}, {89, 42, 75, 94}, {89, 43, 75, 94}, {89, 44, 75, 94}, 4591 {89, 45, 75, 94}, {89, 46, 75, 94}, {89, 47, 75, 94}, {89, 48, 75, 94}, {89, 49, 75, 94}, 4592 {89, 50, 75, 94}, {89, 51, 75, 94}, {89, 52, 75, 94}, {89, 53, 75, 94}, {89, 54, 75, 94}, 4593 {89, 55, 75, 94}, {89, 56, 75, 94}, {89, 57, 75, 94}, {89, 58, 75, 94}, {89, 59, 75, 94}, 4594 }, 4595 } 4596 body6 = testBody{ 4597 label: 6, 4598 offset: dvid.Point3d{8, 10, 7}, 4599 size: dvid.Point3d{52, 50, 10}, 4600 blockSpans: []dvid.Span{ 4601 {0, 0, 0, 1}, 4602 {0, 1, 0, 1}, 4603 }, 4604 voxelSpans: []dvid.Span{ 4605 {8, 11, 9, 31}, {8, 12, 9, 59}, {8, 13, 9, 59}, {8, 14, 9, 59}, 4606 {8, 15, 19, 59}, {8, 16, 19, 59}, {8, 17, 19, 59}, {8, 18, 19, 59}, 4607 {8, 19, 29, 59}, {8, 20, 29, 59}, {8, 21, 29, 59}, {8, 22, 29, 59}, 4608 {8, 23, 39, 59}, {8, 24, 39, 59}, {8, 25, 39, 59}, {8, 26, 39, 59}, 4609 {8, 23, 39, 59}, {8, 24, 39, 59}, {8, 25, 39, 59}, {8, 26, 39, 59}, 4610 {8, 27, 39, 59}, {8, 28, 39, 59}, {8, 29, 39, 59}, {8, 30, 39, 59}, 4611 {8, 31, 39, 59}, {8, 32, 39, 59}, {8, 33, 39, 59}, {8, 34, 39, 59}, 4612 {8, 35, 39, 59}, {8, 36, 39, 59}, {8, 37, 45, 59}, {8, 38, 39, 59}, 4613 {8, 39, 39, 59}, {8, 40, 39, 59}, {8, 41, 42, 59}, {8, 42, 39, 56}, 4614 {8, 43, 39, 59}, {8, 44, 39, 59}, {8, 45, 39, 59}, {8, 46, 39, 50}, 4615 4616 {8, 11, 9, 59}, {8, 12, 9, 59}, {8, 13, 9, 59}, {8, 14, 9, 59}, 4617 {8, 15, 19, 59}, {8, 16, 19, 59}, {8, 17, 19, 59}, {8, 18, 19, 59}, 4618 {8, 19, 29, 59}, {8, 20, 29, 59}, {8, 21, 29, 59}, {8, 22, 29, 59}, 4619 {8, 23, 39, 59}, {8, 24, 39, 59}, {8, 25, 39, 59}, {8, 26, 39, 59}, 4620 {8, 23, 39, 59}, {8, 24, 39, 59}, {8, 25, 39, 59}, {8, 26, 39, 59}, 4621 {8, 27, 39, 59}, {8, 28, 39, 59}, {8, 29, 39, 59}, {8, 30, 39, 59}, 4622 {8, 31, 39, 59}, {8, 32, 39, 59}, {8, 33, 39, 59}, {8, 34, 39, 59}, 4623 {8, 35, 39, 59}, {8, 36, 39, 59}, {8, 37, 45, 59}, {8, 38, 39, 59}, 4624 {8, 39, 39, 59}, {8, 40, 39, 59}, {8, 41, 42, 59}, {8, 42, 39, 56}, 4625 {8, 43, 39, 59}, {8, 44, 39, 59}, {8, 45, 39, 59}, {8, 46, 39, 50}, 4626 4627 {9, 11, 9, 59}, {9, 12, 9, 59}, {9, 13, 9, 59}, {9, 14, 9, 59}, 4628 {9, 15, 19, 59}, {9, 16, 19, 59}, {9, 17, 19, 59}, {9, 18, 19, 59}, 4629 {9, 19, 29, 59}, {9, 20, 29, 59}, {9, 21, 29, 59}, {9, 22, 29, 59}, 4630 {9, 23, 39, 59}, {9, 24, 39, 59}, {9, 25, 39, 59}, {9, 26, 39, 59}, 4631 {9, 23, 39, 59}, {9, 24, 39, 59}, {9, 25, 39, 59}, {9, 26, 39, 59}, 4632 {9, 27, 39, 59}, {9, 28, 39, 59}, {9, 29, 39, 59}, {9, 30, 39, 59}, 4633 {9, 31, 39, 59}, {9, 32, 39, 59}, {9, 33, 39, 59}, {9, 34, 39, 59}, 4634 {9, 35, 39, 59}, {9, 36, 39, 59}, {9, 37, 45, 59}, {9, 38, 39, 59}, 4635 {9, 39, 39, 59}, {9, 40, 39, 59}, {9, 41, 42, 59}, {9, 42, 39, 56}, 4636 {9, 43, 39, 59}, {9, 44, 39, 59}, {9, 45, 39, 59}, {9, 46, 39, 50}, 4637 4638 {10, 11, 9, 59}, {10, 12, 9, 59}, {10, 13, 9, 59}, {10, 14, 9, 59}, 4639 {10, 15, 19, 59}, {10, 16, 19, 59}, {10, 17, 19, 59}, {10, 18, 19, 59}, 4640 {10, 19, 29, 59}, {10, 20, 29, 59}, {10, 21, 29, 59}, {10, 22, 29, 59}, 4641 {10, 23, 39, 59}, {10, 24, 39, 59}, {10, 25, 39, 59}, {10, 26, 39, 59}, 4642 {10, 23, 39, 59}, {10, 24, 39, 59}, {10, 25, 39, 59}, {10, 26, 39, 59}, 4643 {10, 27, 39, 59}, {10, 28, 39, 59}, {10, 29, 39, 59}, {10, 30, 39, 59}, 4644 {10, 31, 39, 59}, {10, 32, 39, 59}, {10, 33, 39, 59}, {10, 34, 39, 59}, 4645 {10, 35, 39, 59}, {10, 36, 39, 59}, {10, 37, 45, 59}, {10, 38, 39, 59}, 4646 {10, 39, 39, 59}, {10, 40, 39, 59}, {10, 41, 42, 59}, {10, 42, 39, 56}, 4647 {10, 43, 39, 59}, {10, 44, 39, 59}, {10, 45, 39, 59}, {10, 46, 39, 50}, 4648 4649 {11, 11, 9, 59}, {11, 12, 9, 59}, {11, 13, 9, 59}, {11, 14, 9, 59}, 4650 {11, 15, 19, 59}, {11, 16, 19, 59}, {11, 17, 19, 59}, {11, 18, 19, 59}, 4651 {11, 19, 29, 59}, {11, 20, 29, 59}, {11, 21, 29, 59}, {11, 22, 29, 59}, 4652 {11, 23, 39, 59}, {11, 24, 39, 59}, {11, 25, 39, 59}, {11, 26, 39, 59}, 4653 {11, 23, 39, 59}, {11, 24, 39, 59}, {11, 25, 39, 59}, {11, 26, 39, 59}, 4654 {11, 27, 39, 59}, {11, 28, 39, 59}, {11, 29, 39, 59}, {11, 30, 39, 59}, 4655 {11, 31, 39, 59}, {11, 32, 39, 59}, {11, 33, 39, 59}, {11, 34, 39, 59}, 4656 {11, 35, 39, 59}, {11, 36, 39, 59}, {11, 37, 45, 59}, {11, 38, 39, 59}, 4657 {11, 39, 39, 59}, {11, 40, 39, 59}, {11, 41, 42, 59}, {11, 42, 39, 56}, 4658 {11, 43, 39, 59}, {11, 44, 39, 59}, {11, 45, 39, 59}, {11, 46, 39, 50}, 4659 4660 {12, 11, 9, 59}, {12, 12, 9, 59}, {12, 13, 9, 59}, {12, 14, 9, 59}, 4661 {12, 15, 19, 59}, {12, 16, 19, 59}, {12, 17, 19, 59}, {12, 18, 19, 59}, 4662 {12, 19, 29, 59}, {12, 20, 29, 59}, {12, 21, 29, 59}, {12, 22, 29, 59}, 4663 {12, 23, 39, 59}, {12, 24, 39, 59}, {12, 25, 39, 59}, {12, 26, 39, 59}, 4664 {12, 23, 39, 59}, {12, 24, 39, 59}, {12, 25, 39, 59}, {12, 26, 39, 59}, 4665 {12, 27, 39, 59}, {12, 28, 39, 59}, {12, 29, 39, 59}, {12, 30, 39, 59}, 4666 {12, 31, 39, 59}, {12, 32, 39, 59}, {12, 33, 39, 59}, {12, 34, 39, 59}, 4667 {12, 35, 39, 59}, {12, 36, 39, 59}, {12, 37, 45, 59}, {12, 38, 39, 59}, 4668 {12, 39, 39, 59}, {12, 40, 39, 59}, {12, 41, 42, 59}, {12, 42, 39, 56}, 4669 {12, 43, 39, 59}, {12, 44, 39, 59}, {12, 45, 39, 59}, {12, 46, 39, 50}, 4670 }, 4671 } 4672 body7 = testBody{ 4673 label: 7, 4674 offset: dvid.Point3d{68, 10, 7}, 4675 size: dvid.Point3d{52, 50, 10}, 4676 blockSpans: []dvid.Span{ 4677 {2, 0, 0, 1}, 4678 {2, 1, 0, 1}, 4679 }, 4680 voxelSpans: []dvid.Span{ 4681 {78, 11, 9, 59}, {78, 12, 9, 59}, {78, 13, 9, 59}, {78, 14, 9, 59}, 4682 {78, 15, 19, 59}, {78, 16, 19, 59}, {78, 17, 19, 59}, {78, 18, 19, 59}, 4683 {78, 19, 29, 59}, {78, 20, 29, 59}, {78, 21, 29, 59}, {78, 22, 29, 59}, 4684 {78, 23, 39, 59}, {78, 24, 39, 59}, {78, 25, 39, 59}, {78, 26, 39, 59}, 4685 {78, 23, 39, 59}, {78, 24, 39, 59}, {78, 25, 39, 59}, {78, 26, 39, 59}, 4686 {78, 27, 39, 59}, {78, 28, 39, 59}, {78, 29, 39, 59}, {78, 30, 39, 59}, 4687 {78, 31, 39, 59}, {78, 32, 39, 59}, {78, 33, 39, 59}, {78, 34, 39, 59}, 4688 {78, 35, 39, 59}, {78, 36, 39, 59}, {78, 37, 45, 59}, {78, 38, 39, 59}, 4689 {78, 39, 39, 59}, {78, 40, 39, 59}, {78, 41, 42, 59}, {78, 42, 39, 56}, 4690 {78, 43, 39, 59}, {78, 44, 39, 59}, {78, 45, 39, 59}, {78, 46, 39, 50}, 4691 4692 {79, 11, 9, 59}, {79, 12, 9, 59}, {79, 13, 9, 59}, {79, 14, 9, 59}, 4693 {79, 15, 19, 59}, {79, 16, 19, 59}, {79, 17, 19, 59}, {79, 18, 19, 59}, 4694 {79, 19, 29, 59}, {79, 20, 29, 59}, {79, 21, 29, 59}, {79, 22, 29, 59}, 4695 {79, 23, 39, 59}, {79, 24, 39, 59}, {79, 25, 39, 59}, {79, 26, 39, 59}, 4696 {79, 23, 39, 59}, {79, 24, 39, 59}, {79, 25, 39, 59}, {79, 26, 39, 59}, 4697 {79, 27, 39, 59}, {79, 28, 39, 59}, {79, 29, 39, 59}, {79, 30, 39, 59}, 4698 {79, 31, 39, 59}, {79, 32, 39, 59}, {79, 33, 39, 59}, {79, 34, 39, 59}, 4699 {79, 35, 39, 59}, {79, 36, 39, 59}, {79, 37, 45, 59}, {79, 38, 39, 59}, 4700 {79, 39, 39, 59}, {79, 40, 39, 59}, {79, 41, 42, 59}, {79, 42, 39, 56}, 4701 {79, 43, 39, 59}, {79, 44, 39, 59}, {79, 45, 39, 59}, {79, 46, 39, 50}, 4702 4703 {80, 11, 9, 59}, {80, 12, 9, 59}, {80, 13, 9, 59}, {80, 14, 9, 59}, 4704 {80, 15, 19, 59}, {80, 16, 19, 59}, {80, 17, 19, 59}, {80, 18, 19, 59}, 4705 {80, 19, 29, 59}, {80, 20, 29, 59}, {80, 21, 29, 59}, {80, 22, 29, 59}, 4706 {80, 23, 39, 59}, {80, 24, 39, 59}, {80, 25, 39, 59}, {80, 26, 39, 59}, 4707 {80, 23, 39, 59}, {80, 24, 39, 59}, {80, 25, 39, 59}, {80, 26, 39, 59}, 4708 {80, 27, 39, 59}, {80, 28, 39, 59}, {80, 29, 39, 59}, {80, 30, 39, 59}, 4709 {80, 31, 39, 59}, {80, 32, 39, 59}, {80, 33, 39, 59}, {80, 34, 39, 59}, 4710 {80, 35, 39, 59}, {80, 36, 39, 59}, {80, 37, 45, 59}, {80, 38, 39, 59}, 4711 {80, 39, 39, 59}, {80, 40, 39, 59}, {80, 41, 42, 59}, {80, 42, 39, 56}, 4712 {80, 43, 39, 59}, {80, 44, 39, 59}, {80, 45, 39, 59}, {80, 46, 39, 50}, 4713 4714 {81, 11, 9, 59}, {81, 12, 9, 59}, {81, 13, 9, 59}, {81, 14, 9, 59}, 4715 {81, 15, 19, 59}, {81, 16, 19, 59}, {81, 17, 19, 59}, {81, 18, 19, 59}, 4716 {81, 19, 29, 59}, {81, 20, 29, 59}, {81, 21, 29, 59}, {81, 22, 29, 59}, 4717 {81, 23, 39, 59}, {81, 24, 39, 59}, {81, 25, 39, 59}, {81, 26, 39, 59}, 4718 {81, 23, 39, 59}, {81, 24, 39, 59}, {81, 25, 39, 59}, {81, 26, 39, 59}, 4719 {81, 27, 39, 59}, {81, 28, 39, 59}, {81, 29, 39, 59}, {81, 30, 39, 59}, 4720 {81, 31, 39, 59}, {81, 32, 39, 59}, {81, 33, 39, 59}, {81, 34, 39, 59}, 4721 {81, 35, 39, 59}, {81, 36, 39, 59}, {81, 37, 45, 59}, {81, 38, 39, 59}, 4722 {81, 39, 39, 59}, {81, 40, 39, 59}, {81, 41, 42, 59}, {81, 42, 39, 56}, 4723 {81, 43, 39, 59}, {81, 44, 39, 59}, {81, 45, 39, 59}, {81, 46, 39, 50}, 4724 4725 {82, 11, 9, 59}, {82, 12, 9, 59}, {82, 13, 9, 59}, {82, 14, 9, 59}, 4726 {82, 15, 19, 59}, {82, 16, 19, 59}, {82, 17, 19, 59}, {82, 18, 19, 59}, 4727 {82, 19, 29, 59}, {82, 20, 29, 59}, {82, 21, 29, 59}, {82, 22, 29, 59}, 4728 {82, 23, 39, 59}, {82, 24, 39, 59}, {82, 25, 39, 59}, {82, 26, 39, 59}, 4729 {82, 23, 39, 59}, {82, 24, 39, 59}, {82, 25, 39, 59}, {82, 26, 39, 59}, 4730 {82, 27, 39, 59}, {82, 28, 39, 59}, {82, 29, 39, 59}, {82, 30, 39, 59}, 4731 {82, 31, 39, 59}, {82, 32, 39, 59}, {82, 33, 39, 59}, {82, 34, 39, 59}, 4732 {82, 35, 39, 59}, {82, 36, 39, 59}, {82, 37, 45, 59}, {82, 38, 39, 59}, 4733 {82, 39, 39, 59}, {82, 40, 39, 59}, {82, 41, 42, 59}, {82, 42, 39, 56}, 4734 {82, 43, 39, 59}, {82, 44, 39, 59}, {82, 45, 39, 59}, {82, 46, 39, 50}, 4735 }, 4736 } 4737 bodies = []testBody{ 4738 body1, body2, body3, body4, bodysplit, body6, body7, 4739 } 4740 )