Parcourir la source

Merge pull request #36701 from thaJeztah/bump-swarmkit

Bump SwarmKit to 831df679a0b8a21b4dccd5791667d030642de7ff
Anusha Ragunathan il y a 7 ans
Parent
commit
094aa1a552
24 fichiers modifiés avec 1147 ajouts et 607 suppressions
  1. 2 4
      integration/network/service_test.go
  2. 2 1
      vendor.conf
  3. 2 0
      vendor/github.com/docker/swarmkit/agent/agent.go
  4. 8 1
      vendor/github.com/docker/swarmkit/agent/session.go
  5. 15 1
      vendor/github.com/docker/swarmkit/agent/worker.go
  6. 323 317
      vendor/github.com/docker/swarmkit/api/types.pb.go
  7. 1 0
      vendor/github.com/docker/swarmkit/api/types.proto
  8. 5 64
      vendor/github.com/docker/swarmkit/ca/certificates.go
  9. 5 13
      vendor/github.com/docker/swarmkit/ca/keyutils/keyutils.go
  10. 11 0
      vendor/github.com/docker/swarmkit/fips/fips.go
  11. 66 36
      vendor/github.com/docker/swarmkit/manager/allocator/network.go
  12. 5 1
      vendor/github.com/docker/swarmkit/manager/controlapi/service.go
  13. 17 7
      vendor/github.com/docker/swarmkit/manager/dispatcher/dispatcher.go
  14. 60 1
      vendor/github.com/docker/swarmkit/manager/encryption/encryption.go
  15. 54 0
      vendor/github.com/docker/swarmkit/manager/encryption/fernet.go
  16. 85 112
      vendor/github.com/docker/swarmkit/manager/manager.go
  17. 22 4
      vendor/github.com/docker/swarmkit/manager/state/raft/raft.go
  18. 1 16
      vendor/github.com/docker/swarmkit/manager/state/raft/storage/storage.go
  19. 143 4
      vendor/github.com/docker/swarmkit/node/node.go
  20. 19 25
      vendor/github.com/docker/swarmkit/vendor.conf
  21. 20 0
      vendor/github.com/fernet/fernet-go/License
  22. 22 0
      vendor/github.com/fernet/fernet-go/Readme
  23. 168 0
      vendor/github.com/fernet/fernet-go/fernet.go
  24. 91 0
      vendor/github.com/fernet/fernet-go/key.go

+ 2 - 4
integration/network/service_test.go

@@ -43,7 +43,7 @@ func TestServiceWithPredefinedNetwork(t *testing.T) {
 
 const ingressNet = "ingress"
 
-func TestServiceWithIngressNetwork(t *testing.T) {
+func TestServiceRemoveKeepsIngressNetwork(t *testing.T) {
 	defer setupTest(t)()
 	d := swarm.NewSwarm(t, testEnv)
 	defer d.Stop(t)
@@ -54,9 +54,7 @@ func TestServiceWithIngressNetwork(t *testing.T) {
 	poll.WaitOn(t, swarmIngressReady(client), swarm.NetworkPoll)
 
 	var instances uint64 = 1
-	serviceName := "TestIngressService"
-	serviceSpec := swarmServiceSpec(serviceName, instances)
-	serviceSpec.TaskTemplate.Networks = append(serviceSpec.TaskTemplate.Networks, swarmtypes.NetworkAttachmentConfig{Target: ingressNet})
+	serviceSpec := swarmServiceSpec(t.Name()+"-service", instances)
 	serviceSpec.EndpointSpec = &swarmtypes.EndpointSpec{
 		Ports: []swarmtypes.PortConfig{
 			{

+ 2 - 1
vendor.conf

@@ -119,9 +119,10 @@ github.com/dmcgowan/go-tar go1.10
 github.com/stevvooe/ttrpc d4528379866b0ce7e9d71f3eb96f0582fc374577
 
 # cluster
-github.com/docker/swarmkit 49a9d7f6ba3c1925262641e694c18eb43575f74b
+github.com/docker/swarmkit 831df679a0b8a21b4dccd5791667d030642de7ff
 github.com/gogo/protobuf v0.4
 github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a
+github.com/fernet/fernet-go 1b2437bc582b3cfbb341ee5a29f8ef5b42912ff2
 github.com/google/certificate-transparency d90e65c3a07988180c5b1ece71791c0b6506826e
 golang.org/x/crypto 558b6879de74bc843225cde5686419267ff707ca
 golang.org/x/time a4bde12657593d5e90d0533a3e4fd95e635124cb

+ 2 - 0
vendor/github.com/docker/swarmkit/agent/agent.go

@@ -324,6 +324,8 @@ func (a *Agent) run(ctx context.Context) {
 			registered = nil // we only care about this once per session
 			backoff = 0      // reset backoff
 			sessionq = a.sessionq
+			// re-report all task statuses when re-establishing a session
+			go a.worker.Report(ctx, reporter)
 		case err := <-session.errs:
 			// TODO(stevvooe): This may actually block if a session is closed
 			// but no error was sent. This must be the only place

+ 8 - 1
vendor/github.com/docker/swarmkit/agent/session.go

@@ -67,7 +67,14 @@ func newSession(ctx context.Context, agent *Agent, delay time.Duration, sessionI
 	)
 
 	if err != nil {
-		s.errs <- err
+		// since we are returning without launching the session goroutine, we
+		// need to provide the delay that is guaranteed by calling this
+		// function. We launch a goroutine so that we only delay the retry and
+		// avoid blocking the main loop.
+		go func() {
+			time.Sleep(delay)
+			s.errs <- err
+		}()
 		return s
 	}
 

+ 15 - 1
vendor/github.com/docker/swarmkit/agent/worker.go

@@ -39,6 +39,9 @@ type Worker interface {
 	// The listener will be removed if the context is cancelled.
 	Listen(ctx context.Context, reporter StatusReporter)
 
+	// Report resends the status of all tasks controlled by this worker.
+	Report(ctx context.Context, reporter StatusReporter)
+
 	// Subscribe to log messages matching the subscription.
 	Subscribe(ctx context.Context, subscription *api.SubscriptionMessage) error
 
@@ -416,12 +419,23 @@ func (w *worker) Listen(ctx context.Context, reporter StatusReporter) {
 	}()
 
 	// report the current statuses to the new listener
+	w.reportAllStatuses(ctx, reporter)
+}
+
+func (w *worker) Report(ctx context.Context, reporter StatusReporter) {
+	w.mu.Lock()
+	defer w.mu.Unlock()
+
+	w.reportAllStatuses(ctx, reporter)
+}
+
+func (w *worker) reportAllStatuses(ctx context.Context, reporter StatusReporter) {
 	if err := w.db.View(func(tx *bolt.Tx) error {
 		return WalkTaskStatus(tx, func(id string, status *api.TaskStatus) error {
 			return reporter.UpdateTaskStatus(ctx, id, status)
 		})
 	}); err != nil {
-		log.G(ctx).WithError(err).Errorf("failed reporting initial statuses to registered listener %v", reporter)
+		log.G(ctx).WithError(err).Errorf("failed reporting initial statuses")
 	}
 }
 

+ 323 - 317
vendor/github.com/docker/swarmkit/api/types.pb.go

@@ -578,15 +578,18 @@ type MaybeEncryptedRecord_Algorithm int32
 const (
 	MaybeEncryptedRecord_NotEncrypted                 MaybeEncryptedRecord_Algorithm = 0
 	MaybeEncryptedRecord_NACLSecretboxSalsa20Poly1305 MaybeEncryptedRecord_Algorithm = 1
+	MaybeEncryptedRecord_FernetAES128CBC              MaybeEncryptedRecord_Algorithm = 2
 )
 
 var MaybeEncryptedRecord_Algorithm_name = map[int32]string{
 	0: "NONE",
 	1: "SECRETBOX_SALSA20_POLY1305",
+	2: "FERNET_AES_128_CBC",
 }
 var MaybeEncryptedRecord_Algorithm_value = map[string]int32{
 	"NONE": 0,
 	"SECRETBOX_SALSA20_POLY1305": 1,
+	"FERNET_AES_128_CBC":         2,
 }
 
 func (x MaybeEncryptedRecord_Algorithm) String() string {
@@ -17043,321 +17046,324 @@ var (
 func init() { proto.RegisterFile("github.com/docker/swarmkit/api/types.proto", fileDescriptorTypes) }
 
 var fileDescriptorTypes = []byte{
-	// 5054 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x5a, 0x4d, 0x6c, 0x24, 0x49,
-	0x56, 0x76, 0xfd, 0xba, 0xea, 0x55, 0xd9, 0x4e, 0x47, 0x7b, 0x7b, 0xdc, 0xb5, 0xdd, 0x76, 0x4d,
-	0xce, 0xf4, 0xce, 0x6c, 0x6f, 0x53, 0xfd, 0xb7, 0xbb, 0xea, 0x99, 0x61, 0x77, 0xa6, 0xfe, 0x6c,
-	0xd7, 0xb6, 0x5d, 0x55, 0x8a, 0x2a, 0x77, 0xef, 0x22, 0x41, 0x92, 0xce, 0x0c, 0x97, 0x73, 0x9c,
-	0x95, 0x51, 0x64, 0x66, 0xd9, 0x5d, 0x2c, 0x88, 0x16, 0x07, 0x40, 0x3e, 0xc1, 0x89, 0x45, 0xc8,
-	0x08, 0x09, 0x8e, 0x48, 0x1c, 0x40, 0x42, 0x70, 0x1a, 0x24, 0x84, 0xf6, 0x06, 0x0b, 0x12, 0x5a,
-	0x81, 0x64, 0x58, 0x1f, 0xb8, 0xad, 0xe0, 0x82, 0xb8, 0x80, 0x84, 0xe2, 0x27, 0xb3, 0xd2, 0xd5,
-	0x69, 0xbb, 0x87, 0xdd, 0x8b, 0x5d, 0xf1, 0xde, 0xf7, 0x5e, 0x44, 0xbc, 0x88, 0x78, 0xf1, 0xde,
-	0x8b, 0x84, 0x7b, 0x03, 0xcb, 0x3f, 0x18, 0xef, 0x55, 0x0c, 0x3a, 0x7c, 0x60, 0x52, 0xe3, 0x90,
-	0xb8, 0x0f, 0xbc, 0x63, 0xdd, 0x1d, 0x1e, 0x5a, 0xfe, 0x03, 0x7d, 0x64, 0x3d, 0xf0, 0x27, 0x23,
-	0xe2, 0x55, 0x46, 0x2e, 0xf5, 0x29, 0x42, 0x02, 0x50, 0x09, 0x00, 0x95, 0xa3, 0x47, 0xa5, 0xf5,
-	0x01, 0xa5, 0x03, 0x9b, 0x3c, 0xe0, 0x88, 0xbd, 0xf1, 0xfe, 0x03, 0xdf, 0x1a, 0x12, 0xcf, 0xd7,
-	0x87, 0x23, 0x21, 0x54, 0x5a, 0x9b, 0x05, 0x98, 0x63, 0x57, 0xf7, 0x2d, 0xea, 0x48, 0xfe, 0xca,
-	0x80, 0x0e, 0x28, 0xff, 0xf9, 0x80, 0xfd, 0x12, 0x54, 0x75, 0x1d, 0xe6, 0x9f, 0x13, 0xd7, 0xb3,
-	0xa8, 0x83, 0x56, 0x20, 0x63, 0x39, 0x26, 0x79, 0xb9, 0x9a, 0x28, 0x27, 0xde, 0x4f, 0x63, 0xd1,
-	0x50, 0x1f, 0x02, 0xb4, 0xd8, 0x8f, 0xa6, 0xe3, 0xbb, 0x13, 0xa4, 0x40, 0xea, 0x90, 0x4c, 0x38,
-	0x22, 0x8f, 0xd9, 0x4f, 0x46, 0x39, 0xd2, 0xed, 0xd5, 0xa4, 0xa0, 0x1c, 0xe9, 0xb6, 0xfa, 0xa3,
-	0x04, 0x14, 0xaa, 0x8e, 0x43, 0x7d, 0xde, 0xbb, 0x87, 0x10, 0xa4, 0x1d, 0x7d, 0x48, 0xa4, 0x10,
-	0xff, 0x8d, 0xea, 0x90, 0xb5, 0xf5, 0x3d, 0x62, 0x7b, 0xab, 0xc9, 0x72, 0xea, 0xfd, 0xc2, 0xe3,
-	0xaf, 0x54, 0x5e, 0x9f, 0x72, 0x25, 0xa2, 0xa4, 0xb2, 0xcd, 0xd1, 0x7c, 0x10, 0x58, 0x8a, 0xa2,
-	0x6f, 0xc2, 0xbc, 0xe5, 0x98, 0x96, 0x41, 0xbc, 0xd5, 0x34, 0xd7, 0xb2, 0x16, 0xa7, 0x65, 0x3a,
-	0xfa, 0x5a, 0xfa, 0xfb, 0x67, 0xeb, 0x73, 0x38, 0x10, 0x2a, 0x7d, 0x00, 0x85, 0x88, 0xda, 0x98,
-	0xb9, 0xad, 0x40, 0xe6, 0x48, 0xb7, 0xc7, 0x44, 0xce, 0x4e, 0x34, 0x3e, 0x4c, 0x3e, 0x4d, 0xa8,
-	0x9f, 0xc0, 0x4a, 0x5b, 0x1f, 0x12, 0x73, 0x93, 0x38, 0xc4, 0xb5, 0x0c, 0x4c, 0x3c, 0x3a, 0x76,
-	0x0d, 0xc2, 0xe6, 0x7a, 0x68, 0x39, 0x66, 0x30, 0x57, 0xf6, 0x3b, 0x5e, 0x8b, 0x5a, 0x87, 0xb7,
-	0x1a, 0x96, 0x67, 0xb8, 0xc4, 0x27, 0x9f, 0x5b, 0x49, 0x2a, 0x50, 0x72, 0x96, 0x80, 0xa5, 0x59,
-	0xe9, 0x9f, 0x83, 0x1b, 0xcc, 0xc4, 0xa6, 0xe6, 0x4a, 0x8a, 0xe6, 0x8d, 0x88, 0xc1, 0x95, 0x15,
-	0x1e, 0xbf, 0x1f, 0x67, 0xa1, 0xb8, 0x99, 0x6c, 0xcd, 0xe1, 0x65, 0xae, 0x26, 0x20, 0xf4, 0x46,
-	0xc4, 0x40, 0x06, 0xdc, 0x34, 0xe5, 0xa0, 0x67, 0xd4, 0x27, 0xb9, 0xfa, 0xd8, 0x65, 0xbc, 0x64,
-	0x9a, 0x5b, 0x73, 0x78, 0x25, 0x50, 0x16, 0xed, 0xa4, 0x06, 0x90, 0x0b, 0x74, 0xab, 0xdf, 0x4b,
-	0x40, 0x3e, 0x60, 0x7a, 0xe8, 0xcb, 0x90, 0x77, 0x74, 0x87, 0x6a, 0xc6, 0x68, 0xec, 0xf1, 0x09,
-	0xa5, 0x6a, 0xc5, 0xf3, 0xb3, 0xf5, 0x5c, 0x5b, 0x77, 0x68, 0xbd, 0xbb, 0xeb, 0xe1, 0x1c, 0x63,
-	0xd7, 0x47, 0x63, 0x0f, 0xbd, 0x0d, 0xc5, 0x21, 0x19, 0x52, 0x77, 0xa2, 0xed, 0x4d, 0x7c, 0xe2,
-	0x49, 0xb3, 0x15, 0x04, 0xad, 0xc6, 0x48, 0xe8, 0x1b, 0x30, 0x3f, 0x10, 0x43, 0x5a, 0x4d, 0xf1,
-	0xed, 0xf3, 0x4e, 0xdc, 0xe8, 0x67, 0x46, 0x8d, 0x03, 0x19, 0xf5, 0xb7, 0x13, 0xb0, 0x12, 0x52,
-	0xc9, 0x2f, 0x8d, 0x2d, 0x97, 0x0c, 0x89, 0xe3, 0x7b, 0xe8, 0x6b, 0x90, 0xb5, 0xad, 0xa1, 0xe5,
-	0x7b, 0xd2, 0xe6, 0x77, 0xe2, 0xd4, 0x86, 0x93, 0xc2, 0x12, 0x8c, 0xaa, 0x50, 0x74, 0x89, 0x47,
-	0xdc, 0x23, 0xb1, 0xe3, 0xa5, 0x45, 0xaf, 0x11, 0xbe, 0x20, 0xa2, 0x6e, 0x40, 0xae, 0x6b, 0xeb,
-	0xfe, 0x3e, 0x75, 0x87, 0x48, 0x85, 0xa2, 0xee, 0x1a, 0x07, 0x96, 0x4f, 0x0c, 0x7f, 0xec, 0x06,
-	0xa7, 0xef, 0x02, 0x0d, 0xdd, 0x84, 0x24, 0x15, 0x1d, 0xe5, 0x6b, 0xd9, 0xf3, 0xb3, 0xf5, 0x64,
-	0xa7, 0x87, 0x93, 0xd4, 0x53, 0x3f, 0x82, 0xe5, 0xae, 0x3d, 0x1e, 0x58, 0x4e, 0x83, 0x78, 0x86,
-	0x6b, 0x8d, 0x98, 0x76, 0xb6, 0x2b, 0x99, 0x8f, 0x0a, 0x76, 0x25, 0xfb, 0x1d, 0x1e, 0xed, 0xe4,
-	0xf4, 0x68, 0xab, 0xbf, 0x99, 0x84, 0xe5, 0xa6, 0x33, 0xb0, 0x1c, 0x12, 0x95, 0xbe, 0x0b, 0x8b,
-	0x84, 0x13, 0xb5, 0x23, 0xe1, 0x6e, 0xa4, 0x9e, 0x05, 0x41, 0x0d, 0x7c, 0x50, 0x6b, 0xc6, 0x2f,
-	0x3c, 0x8a, 0x9b, 0xfe, 0x6b, 0xda, 0x63, 0xbd, 0x43, 0x13, 0xe6, 0x47, 0x7c, 0x12, 0x9e, 0x5c,
-	0xde, 0xbb, 0x71, 0xba, 0x5e, 0x9b, 0x67, 0xe0, 0x24, 0xa4, 0xec, 0x4f, 0xe2, 0x24, 0xfe, 0x24,
-	0x09, 0x4b, 0x6d, 0x6a, 0x5e, 0xb0, 0x43, 0x09, 0x72, 0x07, 0xd4, 0xf3, 0x23, 0x0e, 0x31, 0x6c,
-	0xa3, 0xa7, 0x90, 0x1b, 0xc9, 0xe5, 0x93, 0xab, 0x7f, 0x3b, 0x7e, 0xc8, 0x02, 0x83, 0x43, 0x34,
-	0xfa, 0x08, 0xf2, 0xc1, 0x91, 0x61, 0xb3, 0x7d, 0x83, 0x8d, 0x33, 0xc5, 0xa3, 0x6f, 0x40, 0x56,
-	0x2c, 0xc2, 0x6a, 0x9a, 0x4b, 0xde, 0x7d, 0x23, 0x9b, 0x63, 0x29, 0x84, 0x36, 0x21, 0xe7, 0xdb,
-	0x9e, 0x66, 0x39, 0xfb, 0x74, 0x35, 0xc3, 0x15, 0xac, 0xc7, 0x3a, 0x19, 0x6a, 0x92, 0xfe, 0x76,
-	0xaf, 0xe5, 0xec, 0xd3, 0x5a, 0xe1, 0xfc, 0x6c, 0x7d, 0x5e, 0x36, 0xf0, 0xbc, 0x6f, 0x7b, 0xec,
-	0x87, 0xfa, 0x3b, 0x09, 0x28, 0x44, 0x50, 0xe8, 0x0e, 0x80, 0xef, 0x8e, 0x3d, 0x5f, 0x73, 0x29,
-	0xf5, 0xb9, 0xb1, 0x8a, 0x38, 0xcf, 0x29, 0x98, 0x52, 0x1f, 0x55, 0xe0, 0x86, 0x41, 0x5c, 0x5f,
-	0xb3, 0x3c, 0x6f, 0x4c, 0x5c, 0xcd, 0x1b, 0xef, 0x7d, 0x4a, 0x0c, 0x9f, 0x1b, 0xae, 0x88, 0x97,
-	0x19, 0xab, 0xc5, 0x39, 0x3d, 0xc1, 0x40, 0x4f, 0xe0, 0x66, 0x14, 0x3f, 0x1a, 0xef, 0xd9, 0x96,
-	0xa1, 0xb1, 0xc5, 0x4c, 0x71, 0x91, 0x1b, 0x53, 0x91, 0x2e, 0xe7, 0x3d, 0x23, 0x13, 0xf5, 0x87,
-	0x09, 0x50, 0xb0, 0xbe, 0xef, 0xef, 0x90, 0xe1, 0x1e, 0x71, 0x7b, 0xbe, 0xee, 0x8f, 0x3d, 0x74,
-	0x13, 0xb2, 0x36, 0xd1, 0x4d, 0xe2, 0xf2, 0x41, 0xe5, 0xb0, 0x6c, 0xa1, 0x5d, 0x76, 0x82, 0x75,
-	0xe3, 0x40, 0xdf, 0xb3, 0x6c, 0xcb, 0x9f, 0xf0, 0xa1, 0x2c, 0xc6, 0x6f, 0xe1, 0x59, 0x9d, 0x15,
-	0x1c, 0x11, 0xc4, 0x17, 0xd4, 0xa0, 0x55, 0x98, 0x1f, 0x12, 0xcf, 0xd3, 0x07, 0x84, 0x8f, 0x34,
-	0x8f, 0x83, 0xa6, 0xfa, 0x11, 0x14, 0xa3, 0x72, 0xa8, 0x00, 0xf3, 0xbb, 0xed, 0x67, 0xed, 0xce,
-	0x8b, 0xb6, 0x32, 0x87, 0x96, 0xa0, 0xb0, 0xdb, 0xc6, 0xcd, 0x6a, 0x7d, 0xab, 0x5a, 0xdb, 0x6e,
-	0x2a, 0x09, 0xb4, 0x00, 0xf9, 0x69, 0x33, 0xa9, 0xfe, 0x59, 0x02, 0x80, 0x99, 0x5b, 0x4e, 0xea,
-	0x43, 0xc8, 0x78, 0xbe, 0xee, 0x8b, 0x5d, 0xb9, 0xf8, 0xf8, 0xdd, 0xcb, 0xd6, 0x50, 0x8e, 0x97,
-	0xfd, 0x23, 0x58, 0x88, 0x44, 0x47, 0x98, 0xbc, 0x30, 0x42, 0xe6, 0x20, 0x74, 0xd3, 0x74, 0xe5,
-	0xc0, 0xf9, 0x6f, 0xf5, 0x23, 0xc8, 0x70, 0xe9, 0x8b, 0xc3, 0xcd, 0x41, 0xba, 0xc1, 0x7e, 0x25,
-	0x50, 0x1e, 0x32, 0xb8, 0x59, 0x6d, 0x7c, 0x47, 0x49, 0x22, 0x05, 0x8a, 0x8d, 0x56, 0xaf, 0xde,
-	0x69, 0xb7, 0x9b, 0xf5, 0x7e, 0xb3, 0xa1, 0xa4, 0xd4, 0xbb, 0x90, 0x69, 0x0d, 0x99, 0xe6, 0xdb,
-	0x6c, 0xcb, 0xef, 0x13, 0x97, 0x38, 0x46, 0x70, 0x92, 0xa6, 0x04, 0xf5, 0xc7, 0x05, 0xc8, 0xec,
-	0xd0, 0xb1, 0xe3, 0xa3, 0xc7, 0x11, 0xb7, 0xb5, 0x18, 0x1f, 0x21, 0x70, 0x60, 0xa5, 0x3f, 0x19,
-	0x11, 0xe9, 0xd6, 0x6e, 0x42, 0x56, 0x1c, 0x0e, 0x39, 0x1d, 0xd9, 0x62, 0x74, 0x5f, 0x77, 0x07,
-	0xc4, 0x97, 0xf3, 0x91, 0x2d, 0xf4, 0x3e, 0xbb, 0xb1, 0x74, 0x93, 0x3a, 0xf6, 0x84, 0x9f, 0xa1,
-	0x9c, 0xb8, 0x96, 0x30, 0xd1, 0xcd, 0x8e, 0x63, 0x4f, 0x70, 0xc8, 0x45, 0x5b, 0x50, 0xdc, 0xb3,
-	0x1c, 0x53, 0xa3, 0x23, 0xe1, 0xe4, 0x33, 0x97, 0x9f, 0x38, 0x31, 0xaa, 0x9a, 0xe5, 0x98, 0x1d,
-	0x01, 0xc6, 0x85, 0xbd, 0x69, 0x03, 0xb5, 0x61, 0xf1, 0x88, 0xda, 0xe3, 0x21, 0x09, 0x75, 0x65,
-	0xb9, 0xae, 0xf7, 0x2e, 0xd7, 0xf5, 0x9c, 0xe3, 0x03, 0x6d, 0x0b, 0x47, 0xd1, 0x26, 0x7a, 0x06,
-	0x0b, 0xfe, 0x70, 0xb4, 0xef, 0x85, 0xea, 0xe6, 0xb9, 0xba, 0x2f, 0x5d, 0x61, 0x30, 0x06, 0x0f,
-	0xb4, 0x15, 0xfd, 0x48, 0x0b, 0x6d, 0x42, 0xc1, 0xa0, 0x8e, 0x67, 0x79, 0x3e, 0x71, 0x8c, 0xc9,
-	0x6a, 0x8e, 0xdb, 0xfe, 0x8a, 0x59, 0xd6, 0xa7, 0x60, 0x1c, 0x95, 0x2c, 0xfd, 0x7a, 0x0a, 0x0a,
-	0x11, 0x13, 0xa0, 0x1e, 0x14, 0x46, 0x2e, 0x1d, 0xe9, 0x03, 0x7e, 0xe3, 0xc9, 0x45, 0x7d, 0xf4,
-	0x46, 0xe6, 0xab, 0x74, 0xa7, 0x82, 0x38, 0xaa, 0x45, 0x3d, 0x4d, 0x42, 0x21, 0xc2, 0x44, 0xf7,
-	0x20, 0x87, 0xbb, 0xb8, 0xf5, 0xbc, 0xda, 0x6f, 0x2a, 0x73, 0xa5, 0xdb, 0x27, 0xa7, 0xe5, 0x55,
-	0xae, 0x2d, 0xaa, 0xa0, 0xeb, 0x5a, 0x47, 0x6c, 0x0f, 0xbf, 0x0f, 0xf3, 0x01, 0x34, 0x51, 0xfa,
-	0xe2, 0xc9, 0x69, 0xf9, 0xad, 0x59, 0x68, 0x04, 0x89, 0x7b, 0x5b, 0x55, 0xdc, 0x6c, 0x28, 0xc9,
-	0x78, 0x24, 0xee, 0x1d, 0xe8, 0x2e, 0x31, 0xd1, 0x97, 0x20, 0x2b, 0x81, 0xa9, 0x52, 0xe9, 0xe4,
-	0xb4, 0x7c, 0x73, 0x16, 0x38, 0xc5, 0xe1, 0xde, 0x76, 0xf5, 0x79, 0x53, 0x49, 0xc7, 0xe3, 0x70,
-	0xcf, 0xd6, 0x8f, 0x08, 0x7a, 0x17, 0x32, 0x02, 0x96, 0x29, 0xdd, 0x3a, 0x39, 0x2d, 0x7f, 0xe1,
-	0x35, 0x75, 0x0c, 0x55, 0x5a, 0xfd, 0xad, 0x3f, 0x5a, 0x9b, 0xfb, 0xab, 0x3f, 0x5e, 0x53, 0x66,
-	0xd9, 0xa5, 0xff, 0x49, 0xc0, 0xc2, 0x85, 0xbd, 0x83, 0x54, 0xc8, 0x3a, 0xd4, 0xa0, 0x23, 0x71,
-	0x11, 0xe6, 0x6a, 0x70, 0x7e, 0xb6, 0x9e, 0x6d, 0xd3, 0x3a, 0x1d, 0x4d, 0xb0, 0xe4, 0xa0, 0x67,
-	0x33, 0x57, 0xf9, 0x93, 0x37, 0xdc, 0x98, 0xb1, 0x97, 0xf9, 0xc7, 0xb0, 0x60, 0xba, 0xd6, 0x11,
-	0x71, 0x35, 0x83, 0x3a, 0xfb, 0xd6, 0x40, 0x5e, 0x72, 0xa5, 0xd8, 0x78, 0x93, 0x03, 0x71, 0x51,
-	0x08, 0xd4, 0x39, 0xfe, 0x27, 0xb8, 0xc6, 0x4b, 0xcf, 0xa1, 0x18, 0xdd, 0xea, 0xec, 0x5e, 0xf2,
-	0xac, 0x5f, 0x26, 0x32, 0xb0, 0xe4, 0x61, 0x28, 0xce, 0x33, 0x8a, 0x08, 0x2b, 0xdf, 0x83, 0xf4,
-	0x90, 0x9a, 0x42, 0xcf, 0x42, 0xed, 0x06, 0x8b, 0x26, 0xfe, 0xf9, 0x6c, 0xbd, 0x40, 0xbd, 0xca,
-	0x86, 0x65, 0x93, 0x1d, 0x6a, 0x12, 0xcc, 0x01, 0xea, 0x11, 0xa4, 0x99, 0xcf, 0x41, 0x5f, 0x84,
-	0x74, 0xad, 0xd5, 0x6e, 0x28, 0x73, 0xa5, 0xe5, 0x93, 0xd3, 0xf2, 0x02, 0x37, 0x09, 0x63, 0xb0,
-	0xbd, 0x8b, 0xd6, 0x21, 0xfb, 0xbc, 0xb3, 0xbd, 0xbb, 0xc3, 0xb6, 0xd7, 0x8d, 0x93, 0xd3, 0xf2,
-	0x52, 0xc8, 0x16, 0x46, 0x43, 0x77, 0x20, 0xd3, 0xdf, 0xe9, 0x6e, 0xf4, 0x94, 0x64, 0x09, 0x9d,
-	0x9c, 0x96, 0x17, 0x43, 0x3e, 0x1f, 0x73, 0x69, 0x59, 0xae, 0x6a, 0x3e, 0xa4, 0xab, 0x3f, 0x48,
-	0x40, 0x21, 0x72, 0xe0, 0xd8, 0xc6, 0x6c, 0x34, 0x37, 0xaa, 0xbb, 0xdb, 0x7d, 0x65, 0x2e, 0xb2,
-	0x31, 0x23, 0x90, 0x06, 0xd9, 0xd7, 0xc7, 0x36, 0xf3, 0x73, 0x50, 0xef, 0xb4, 0x7b, 0xad, 0x5e,
-	0xbf, 0xd9, 0xee, 0x2b, 0x89, 0xd2, 0xea, 0xc9, 0x69, 0x79, 0x65, 0x16, 0xbc, 0x31, 0xb6, 0x6d,
-	0xb6, 0x35, 0xeb, 0xd5, 0xfa, 0x16, 0xdf, 0xeb, 0xd3, 0xad, 0x19, 0x41, 0xd5, 0x75, 0xe3, 0x80,
-	0x98, 0xe8, 0x3e, 0xe4, 0x1b, 0xcd, 0xed, 0xe6, 0x66, 0x95, 0x7b, 0xf7, 0xd2, 0x9d, 0x93, 0xd3,
-	0xf2, 0xad, 0xd7, 0x7b, 0xb7, 0xc9, 0x40, 0xf7, 0x89, 0x39, 0xb3, 0x45, 0x23, 0x10, 0xf5, 0xbf,
-	0x92, 0xb0, 0x80, 0x59, 0x3a, 0xec, 0xfa, 0x5d, 0x6a, 0x5b, 0xc6, 0x04, 0x75, 0x21, 0x6f, 0x50,
-	0xc7, 0xb4, 0x22, 0x7e, 0xe2, 0xf1, 0x25, 0x21, 0xd1, 0x54, 0x2a, 0x68, 0xd5, 0x03, 0x49, 0x3c,
-	0x55, 0x82, 0x1e, 0x40, 0xc6, 0x24, 0xb6, 0x3e, 0x91, 0xb1, 0xd9, 0xad, 0x8a, 0x48, 0xb8, 0x2b,
-	0x41, 0xc2, 0x5d, 0x69, 0xc8, 0x84, 0x1b, 0x0b, 0x1c, 0xcf, 0x41, 0xf4, 0x97, 0x9a, 0xee, 0xfb,
-	0x64, 0x38, 0xf2, 0x45, 0x60, 0x96, 0xc6, 0x85, 0xa1, 0xfe, 0xb2, 0x2a, 0x49, 0xe8, 0x11, 0x64,
-	0x8f, 0x2d, 0xc7, 0xa4, 0xc7, 0x32, 0xf6, 0xba, 0x42, 0xa9, 0x04, 0xaa, 0x27, 0x2c, 0x24, 0x99,
-	0x19, 0x26, 0xdb, 0x43, 0xed, 0x4e, 0xbb, 0x19, 0xec, 0x21, 0xc9, 0xef, 0x38, 0x6d, 0xea, 0xb0,
-	0xf3, 0x0f, 0x9d, 0xb6, 0xb6, 0x51, 0x6d, 0x6d, 0xef, 0x62, 0xb6, 0x8f, 0x56, 0x4e, 0x4e, 0xcb,
-	0x4a, 0x08, 0xd9, 0xd0, 0x2d, 0x9b, 0x25, 0x03, 0xb7, 0x20, 0x55, 0x6d, 0x7f, 0x47, 0x49, 0x96,
-	0x94, 0x93, 0xd3, 0x72, 0x31, 0x64, 0x57, 0x9d, 0xc9, 0xd4, 0xee, 0xb3, 0xfd, 0xaa, 0x7f, 0x97,
-	0x82, 0xe2, 0xee, 0xc8, 0xd4, 0x7d, 0x22, 0xce, 0x19, 0x2a, 0x43, 0x61, 0xa4, 0xbb, 0xba, 0x6d,
-	0x13, 0xdb, 0xf2, 0x86, 0xb2, 0x94, 0x10, 0x25, 0xa1, 0x0f, 0xde, 0xd4, 0x8c, 0xb5, 0x1c, 0x3b,
-	0x3b, 0xdf, 0xfb, 0xd7, 0xf5, 0x44, 0x60, 0xd0, 0x5d, 0x58, 0xdc, 0x17, 0xa3, 0xd5, 0x74, 0x83,
-	0x2f, 0x6c, 0x8a, 0x2f, 0x6c, 0x25, 0x6e, 0x61, 0xa3, 0xc3, 0xaa, 0xc8, 0x49, 0x56, 0xb9, 0x14,
-	0x5e, 0xd8, 0x8f, 0x36, 0xd1, 0x13, 0x98, 0x1f, 0x52, 0xc7, 0xf2, 0xa9, 0x7b, 0xfd, 0x2a, 0x04,
-	0x48, 0x74, 0x0f, 0x96, 0xd9, 0xe2, 0x06, 0xe3, 0xe1, 0x6c, 0x7e, 0x9d, 0x27, 0xf1, 0xd2, 0x50,
-	0x7f, 0x29, 0x3b, 0xc4, 0x8c, 0x8c, 0x6a, 0x90, 0xa1, 0x2e, 0x8b, 0x17, 0xb3, 0x7c, 0xb8, 0xf7,
-	0xaf, 0x1d, 0xae, 0x68, 0x74, 0x98, 0x0c, 0x16, 0xa2, 0xea, 0xd7, 0x61, 0xe1, 0xc2, 0x24, 0x58,
-	0x98, 0xd4, 0xad, 0xee, 0xf6, 0x9a, 0xca, 0x1c, 0x2a, 0x42, 0xae, 0xde, 0x69, 0xf7, 0x5b, 0xed,
-	0x5d, 0x16, 0xe7, 0x15, 0x21, 0x87, 0x3b, 0xdb, 0xdb, 0xb5, 0x6a, 0xfd, 0x99, 0x92, 0x54, 0x2b,
-	0x50, 0x88, 0x68, 0x43, 0x8b, 0x00, 0xbd, 0x7e, 0xa7, 0xab, 0x6d, 0xb4, 0x70, 0xaf, 0x2f, 0xa2,
-	0xc4, 0x5e, 0xbf, 0x8a, 0xfb, 0x92, 0x90, 0x50, 0xff, 0x23, 0x19, 0xac, 0xa8, 0x0c, 0x0c, 0x6b,
-	0x17, 0x03, 0xc3, 0x2b, 0x06, 0x2f, 0x43, 0xc3, 0x69, 0x23, 0x0c, 0x10, 0x3f, 0x00, 0xe0, 0x1b,
-	0x87, 0x98, 0x9a, 0xee, 0xcb, 0x85, 0x2f, 0xbd, 0x66, 0xe4, 0x7e, 0x50, 0xd1, 0xc2, 0x79, 0x89,
-	0xae, 0xfa, 0xe8, 0x1b, 0x50, 0x34, 0xe8, 0x70, 0x64, 0x13, 0x29, 0x9c, 0xba, 0x56, 0xb8, 0x10,
-	0xe2, 0xab, 0x7e, 0x34, 0x34, 0x4d, 0x5f, 0x0c, 0x9e, 0x7f, 0x23, 0x11, 0x58, 0x26, 0x26, 0x1a,
-	0x2d, 0x42, 0x6e, 0xb7, 0xdb, 0xa8, 0xf6, 0x5b, 0xed, 0x4d, 0x25, 0x81, 0x00, 0xb2, 0xdc, 0xd4,
-	0x0d, 0x25, 0xc9, 0xa2, 0xe8, 0x7a, 0x67, 0xa7, 0xbb, 0xdd, 0xe4, 0x1e, 0x0b, 0xad, 0x80, 0x12,
-	0x18, 0x5b, 0xe3, 0x86, 0x6c, 0x36, 0x94, 0x34, 0xba, 0x01, 0x4b, 0x21, 0x55, 0x4a, 0x66, 0xd0,
-	0x4d, 0x40, 0x21, 0x71, 0xaa, 0x22, 0xab, 0xfe, 0x2a, 0x2c, 0xd5, 0xa9, 0xe3, 0xeb, 0x96, 0x13,
-	0x66, 0x18, 0x8f, 0xd9, 0xa4, 0x25, 0x49, 0xb3, 0x64, 0x25, 0xa8, 0xb6, 0x74, 0x7e, 0xb6, 0x5e,
-	0x08, 0xa1, 0xad, 0x06, 0x0f, 0x95, 0x64, 0xc3, 0x64, 0xe7, 0x77, 0x64, 0x99, 0xdc, 0xb8, 0x99,
-	0xda, 0xfc, 0xf9, 0xd9, 0x7a, 0xaa, 0xdb, 0x6a, 0x60, 0x46, 0x43, 0x5f, 0x84, 0x3c, 0x79, 0x69,
-	0xf9, 0x9a, 0xc1, 0xee, 0x25, 0x66, 0xc0, 0x0c, 0xce, 0x31, 0x42, 0x9d, 0x5d, 0x43, 0x35, 0x80,
-	0x2e, 0x75, 0x7d, 0xd9, 0xf3, 0x57, 0x21, 0x33, 0xa2, 0x2e, 0xaf, 0x5d, 0x5c, 0x5a, 0x51, 0x63,
-	0x70, 0xb1, 0x51, 0xb1, 0x00, 0xab, 0xbf, 0x97, 0x02, 0xe8, 0xeb, 0xde, 0xa1, 0x54, 0xf2, 0x14,
-	0xf2, 0x61, 0x75, 0x52, 0x16, 0x41, 0xae, 0x5c, 0xed, 0x10, 0x8c, 0x9e, 0x04, 0x9b, 0x4d, 0xe4,
-	0x4e, 0xb1, 0x49, 0x6c, 0xd0, 0x51, 0x5c, 0xfa, 0x71, 0x31, 0x41, 0x62, 0xd7, 0x3c, 0x71, 0x5d,
-	0xb9, 0xf2, 0xec, 0x27, 0xaa, 0xf3, 0x6b, 0x41, 0x18, 0x4d, 0x46, 0xdf, 0xb1, 0x65, 0x9f, 0x99,
-	0x15, 0xd9, 0x9a, 0xc3, 0x53, 0x39, 0xf4, 0x31, 0x14, 0xd8, 0xbc, 0x35, 0x8f, 0xf3, 0x64, 0xe0,
-	0x7d, 0xa9, 0xa9, 0x84, 0x06, 0x0c, 0xa3, 0xa9, 0x95, 0xef, 0x00, 0xe8, 0xa3, 0x91, 0x6d, 0x11,
-	0x53, 0xdb, 0x9b, 0xf0, 0x48, 0x3b, 0x8f, 0xf3, 0x92, 0x52, 0x9b, 0xb0, 0xe3, 0x12, 0xb0, 0x75,
-	0x9f, 0x47, 0xcf, 0xd7, 0x18, 0x50, 0xa2, 0xab, 0x7e, 0x4d, 0x81, 0x45, 0x77, 0xec, 0x30, 0x83,
-	0xca, 0xd1, 0xa9, 0x7f, 0x9a, 0x84, 0xb7, 0xda, 0xc4, 0x3f, 0xa6, 0xee, 0x61, 0xd5, 0xf7, 0x75,
-	0xe3, 0x60, 0x48, 0x1c, 0xb9, 0x7c, 0x91, 0x84, 0x26, 0x71, 0x21, 0xa1, 0x59, 0x85, 0x79, 0xdd,
-	0xb6, 0x74, 0x8f, 0x88, 0xe0, 0x2d, 0x8f, 0x83, 0x26, 0x4b, 0xbb, 0x58, 0x12, 0x47, 0x3c, 0x8f,
-	0x88, 0xba, 0x0a, 0x1b, 0x78, 0x40, 0x40, 0xdf, 0x85, 0x9b, 0x32, 0x4c, 0xd3, 0xc3, 0xae, 0x58,
-	0x42, 0x11, 0x14, 0x68, 0x9b, 0xb1, 0x59, 0x65, 0xfc, 0xe0, 0x64, 0x1c, 0x37, 0x25, 0x77, 0x46,
-	0xbe, 0x8c, 0x0a, 0x57, 0xcc, 0x18, 0x56, 0x69, 0x13, 0x6e, 0x5d, 0x2a, 0xf2, 0xb9, 0xea, 0x36,
-	0xff, 0x98, 0x04, 0x68, 0x75, 0xab, 0x3b, 0xd2, 0x48, 0x0d, 0xc8, 0xee, 0xeb, 0x43, 0xcb, 0x9e,
-	0x5c, 0xe5, 0x01, 0xa7, 0xf8, 0x4a, 0x55, 0x98, 0x63, 0x83, 0xcb, 0x60, 0x29, 0xcb, 0x73, 0xca,
-	0xf1, 0x9e, 0x43, 0xfc, 0x30, 0xa7, 0xe4, 0x2d, 0x36, 0x0c, 0x57, 0x77, 0xc2, 0xad, 0x2b, 0x1a,
-	0x6c, 0x01, 0x58, 0xc8, 0x73, 0xac, 0x4f, 0x02, 0xb7, 0x25, 0x9b, 0x68, 0x8b, 0x57, 0x47, 0x89,
-	0x7b, 0x44, 0xcc, 0xd5, 0x0c, 0x37, 0xea, 0x75, 0xe3, 0xc1, 0x12, 0x2e, 0x6c, 0x17, 0x4a, 0x97,
-	0x3e, 0xe2, 0x21, 0xd3, 0x94, 0xf5, 0xb9, 0x6c, 0xf4, 0x10, 0x16, 0x2e, 0xcc, 0xf3, 0xb5, 0x64,
-	0xbe, 0xd5, 0x7d, 0xfe, 0x55, 0x25, 0x2d, 0x7f, 0x7d, 0x5d, 0xc9, 0xaa, 0x7f, 0x9b, 0x12, 0x8e,
-	0x46, 0x5a, 0x35, 0xfe, 0x55, 0x20, 0xc7, 0x77, 0xb7, 0x41, 0x6d, 0xe9, 0x00, 0xde, 0xbb, 0xda,
-	0xff, 0xb0, 0x9c, 0x8e, 0xc3, 0x71, 0x28, 0x88, 0xd6, 0xa1, 0x20, 0x76, 0xb1, 0xc6, 0x0e, 0x1c,
-	0x37, 0xeb, 0x02, 0x06, 0x41, 0x62, 0x92, 0xe8, 0x2e, 0x2c, 0xf2, 0xe2, 0x8f, 0x77, 0x40, 0x4c,
-	0x81, 0x49, 0x73, 0xcc, 0x42, 0x48, 0xe5, 0xb0, 0x1d, 0x28, 0x4a, 0x82, 0xc6, 0xe3, 0xf9, 0x0c,
-	0x1f, 0xd0, 0xbd, 0xeb, 0x06, 0x24, 0x44, 0x78, 0x98, 0x5f, 0x18, 0x4d, 0x1b, 0xea, 0x2f, 0x42,
-	0x2e, 0x18, 0x2c, 0x5a, 0x85, 0x54, 0xbf, 0xde, 0x55, 0xe6, 0x4a, 0x4b, 0x27, 0xa7, 0xe5, 0x42,
-	0x40, 0xee, 0xd7, 0xbb, 0x8c, 0xb3, 0xdb, 0xe8, 0x2a, 0x89, 0x8b, 0x9c, 0xdd, 0x46, 0x17, 0x95,
-	0x20, 0xdd, 0xab, 0xf7, 0xbb, 0x41, 0x7c, 0x16, 0xb0, 0x18, 0xad, 0x94, 0x66, 0xf1, 0x99, 0xba,
-	0x0f, 0x85, 0x48, 0xef, 0xe8, 0x1d, 0x98, 0x6f, 0xb5, 0x37, 0x71, 0xb3, 0xd7, 0x53, 0xe6, 0x4a,
-	0x37, 0x4f, 0x4e, 0xcb, 0x28, 0xc2, 0x6d, 0x39, 0x03, 0xb6, 0x76, 0xe8, 0x0e, 0xa4, 0xb7, 0x3a,
-	0xec, 0xde, 0x17, 0xc9, 0x45, 0x04, 0xb1, 0x45, 0x3d, 0xbf, 0x74, 0x43, 0x06, 0x7e, 0x51, 0xc5,
-	0xea, 0xef, 0x27, 0x20, 0x2b, 0x0e, 0x5a, 0xec, 0x22, 0x56, 0x61, 0x3e, 0x28, 0x21, 0x88, 0xc4,
-	0xef, 0xbd, 0xcb, 0x93, 0xb4, 0x8a, 0xcc, 0xa9, 0xc4, 0xd6, 0x0c, 0xe4, 0x4a, 0x1f, 0x42, 0x31,
-	0xca, 0xf8, 0x5c, 0x1b, 0xf3, 0xbb, 0x50, 0x60, 0x7b, 0x3f, 0x48, 0xd6, 0x1e, 0x43, 0x56, 0x38,
-	0x8b, 0xf0, 0x1e, 0xba, 0x3c, 0x63, 0x94, 0x48, 0xf4, 0x14, 0xe6, 0x45, 0x96, 0x19, 0x54, 0x8e,
-	0xd7, 0xae, 0x3e, 0x61, 0x38, 0x80, 0xab, 0x1f, 0x43, 0xba, 0x4b, 0x88, 0xcb, 0x6c, 0xef, 0x50,
-	0x93, 0x4c, 0xaf, 0x6e, 0x99, 0x20, 0x9b, 0xa4, 0xd5, 0x60, 0x09, 0xb2, 0x49, 0x5a, 0x66, 0x58,
-	0x1b, 0x4b, 0x46, 0x6a, 0x63, 0x7d, 0x28, 0xbe, 0x20, 0xd6, 0xe0, 0xc0, 0x27, 0x26, 0x57, 0x74,
-	0x1f, 0xd2, 0x23, 0x12, 0x0e, 0x7e, 0x35, 0x76, 0xf3, 0x11, 0xe2, 0x62, 0x8e, 0x62, 0x3e, 0xe6,
-	0x98, 0x4b, 0xcb, 0xe7, 0x0e, 0xd9, 0x52, 0xff, 0x21, 0x09, 0x8b, 0x2d, 0xcf, 0x1b, 0xeb, 0x8e,
-	0x11, 0x44, 0x75, 0xdf, 0xbc, 0x18, 0xd5, 0xc5, 0xbe, 0x0b, 0x5d, 0x14, 0xb9, 0x58, 0xf2, 0x93,
-	0x37, 0x6b, 0x32, 0xbc, 0x59, 0xd5, 0x1f, 0x27, 0x82, 0xba, 0xde, 0xdd, 0x88, 0x2b, 0x10, 0x39,
-	0x62, 0x54, 0x13, 0xd9, 0x75, 0x0e, 0x1d, 0x7a, 0xec, 0xa0, 0xb7, 0x21, 0x83, 0x9b, 0xed, 0xe6,
-	0x0b, 0x25, 0x21, 0xb6, 0xe7, 0x05, 0x10, 0x26, 0x0e, 0x39, 0x66, 0x9a, 0xba, 0xcd, 0x76, 0x83,
-	0x45, 0x61, 0xc9, 0x18, 0x4d, 0x5d, 0xe2, 0x98, 0x96, 0x33, 0x40, 0xef, 0x40, 0xb6, 0xd5, 0xeb,
-	0xed, 0xf2, 0x14, 0xf2, 0xad, 0x93, 0xd3, 0xf2, 0x8d, 0x0b, 0x28, 0x5e, 0xd3, 0x35, 0x19, 0x88,
-	0xa5, 0x40, 0x2c, 0x3e, 0x8b, 0x01, 0xb1, 0xd8, 0x5a, 0x80, 0x70, 0xa7, 0x5f, 0xed, 0x37, 0x95,
-	0x4c, 0x0c, 0x08, 0x53, 0xf6, 0x57, 0x1e, 0xb7, 0x7f, 0x49, 0x82, 0x52, 0x35, 0x0c, 0x32, 0xf2,
-	0x19, 0x5f, 0x66, 0x9d, 0x7d, 0xc8, 0x8d, 0xd8, 0x2f, 0x8b, 0x04, 0x11, 0xd4, 0xd3, 0xd8, 0x97,
-	0xcd, 0x19, 0xb9, 0x0a, 0xa6, 0x36, 0xa9, 0x9a, 0x43, 0xcb, 0xf3, 0x2c, 0xea, 0x08, 0x1a, 0x0e,
-	0x35, 0x95, 0xfe, 0x33, 0x01, 0x37, 0x62, 0x10, 0xe8, 0x21, 0xa4, 0x5d, 0x6a, 0x07, 0x6b, 0x78,
-	0xfb, 0xb2, 0x92, 0x2d, 0x13, 0xc5, 0x1c, 0x89, 0xd6, 0x00, 0xf4, 0xb1, 0x4f, 0x75, 0xde, 0x3f,
-	0x5f, 0xbd, 0x1c, 0x8e, 0x50, 0xd0, 0x0b, 0xc8, 0x7a, 0xc4, 0x70, 0x49, 0x10, 0x67, 0x7f, 0xfc,
-	0xff, 0x1d, 0x7d, 0xa5, 0xc7, 0xd5, 0x60, 0xa9, 0xae, 0x54, 0x81, 0xac, 0xa0, 0xb0, 0x6d, 0x6f,
-	0xea, 0xbe, 0x2e, 0x0b, 0xfa, 0xfc, 0x37, 0xdb, 0x4d, 0xba, 0x3d, 0x08, 0x76, 0x93, 0x6e, 0x0f,
-	0xd4, 0xbf, 0x49, 0x02, 0x34, 0x5f, 0xfa, 0xc4, 0x75, 0x74, 0xbb, 0x5e, 0x45, 0xcd, 0xc8, 0xcd,
-	0x20, 0x66, 0xfb, 0xe5, 0xd8, 0x57, 0x8a, 0x50, 0xa2, 0x52, 0xaf, 0xc6, 0xdc, 0x0d, 0xb7, 0x20,
-	0x35, 0x76, 0xe5, 0x63, 0xb5, 0x88, 0x91, 0x77, 0xf1, 0x36, 0x66, 0x34, 0xd4, 0x9c, 0xba, 0xad,
-	0xd4, 0xe5, 0x4f, 0xd2, 0x91, 0x0e, 0x62, 0x5d, 0x17, 0x3b, 0xf9, 0x86, 0xae, 0x19, 0x44, 0xde,
-	0x2a, 0x45, 0x71, 0xf2, 0xeb, 0xd5, 0x3a, 0x71, 0x7d, 0x9c, 0x35, 0x74, 0xf6, 0xff, 0x27, 0xf2,
-	0x6f, 0xf7, 0x01, 0xa6, 0x53, 0x43, 0x6b, 0x90, 0xa9, 0x6f, 0xf4, 0x7a, 0xdb, 0xca, 0x9c, 0x70,
-	0xe0, 0x53, 0x16, 0x27, 0xab, 0x7f, 0x99, 0x84, 0x5c, 0xbd, 0x2a, 0xaf, 0xdc, 0x3a, 0x28, 0xdc,
-	0x2b, 0xf1, 0x67, 0x10, 0xf2, 0x72, 0x64, 0xb9, 0x13, 0xe9, 0x58, 0xae, 0x48, 0x78, 0x17, 0x99,
-	0x08, 0x1b, 0x75, 0x93, 0x0b, 0x20, 0x0c, 0x45, 0x22, 0x8d, 0xa0, 0x19, 0x7a, 0xe0, 0xe3, 0xd7,
-	0xae, 0x36, 0x96, 0x48, 0x5d, 0xa6, 0x6d, 0x0f, 0x17, 0x02, 0x25, 0x75, 0xdd, 0x43, 0x1f, 0xc0,
-	0x92, 0x67, 0x0d, 0x1c, 0xcb, 0x19, 0x68, 0x81, 0xf1, 0xf8, 0x9b, 0x4c, 0x6d, 0xf9, 0xfc, 0x6c,
-	0x7d, 0xa1, 0x27, 0x58, 0xd2, 0x86, 0x0b, 0x12, 0x59, 0xe7, 0xa6, 0x44, 0x5f, 0x87, 0xc5, 0x88,
-	0x28, 0xb3, 0xa2, 0x30, 0xbb, 0x72, 0x7e, 0xb6, 0x5e, 0x0c, 0x25, 0x9f, 0x91, 0x09, 0x2e, 0x86,
-	0x82, 0xcf, 0x08, 0xaf, 0xcd, 0xec, 0x53, 0xd7, 0x20, 0x9a, 0xcb, 0xcf, 0x34, 0xbf, 0xdd, 0xd3,
-	0xb8, 0xc0, 0x69, 0xe2, 0x98, 0xab, 0xcf, 0xe1, 0x46, 0xc7, 0x35, 0x0e, 0x88, 0xe7, 0x0b, 0x53,
-	0x48, 0x2b, 0x7e, 0x0c, 0xb7, 0x7d, 0xdd, 0x3b, 0xd4, 0x0e, 0x2c, 0xcf, 0xa7, 0xee, 0x44, 0x73,
-	0x89, 0x4f, 0x1c, 0xc6, 0xd7, 0xf8, 0x43, 0xae, 0x2c, 0x08, 0xde, 0x62, 0x98, 0x2d, 0x01, 0xc1,
-	0x01, 0x62, 0x9b, 0x01, 0xd4, 0x16, 0x14, 0x59, 0x0a, 0x23, 0x8b, 0x6a, 0x6c, 0xf6, 0x60, 0xd3,
-	0x81, 0xf6, 0xc6, 0xd7, 0x54, 0xde, 0xa6, 0x03, 0xf1, 0x53, 0xfd, 0x36, 0x28, 0x0d, 0xcb, 0x1b,
-	0xe9, 0xbe, 0x71, 0x10, 0x54, 0x3a, 0x51, 0x03, 0x94, 0x03, 0xa2, 0xbb, 0xfe, 0x1e, 0xd1, 0x7d,
-	0x6d, 0x44, 0x5c, 0x8b, 0x9a, 0xd7, 0xaf, 0xf2, 0x52, 0x28, 0xd2, 0xe5, 0x12, 0xea, 0x7f, 0x27,
-	0x00, 0xb0, 0xbe, 0x1f, 0x44, 0x6b, 0x5f, 0x81, 0x65, 0xcf, 0xd1, 0x47, 0xde, 0x01, 0xf5, 0x35,
-	0xcb, 0xf1, 0x89, 0x7b, 0xa4, 0xdb, 0xb2, 0xb8, 0xa3, 0x04, 0x8c, 0x96, 0xa4, 0xa3, 0xfb, 0x80,
-	0x0e, 0x09, 0x19, 0x69, 0xd4, 0x36, 0xb5, 0x80, 0x29, 0x9e, 0x99, 0xd3, 0x58, 0x61, 0x9c, 0x8e,
-	0x6d, 0xf6, 0x02, 0x3a, 0xaa, 0xc1, 0x1a, 0x9b, 0x3e, 0x71, 0x7c, 0xd7, 0x22, 0x9e, 0xb6, 0x4f,
-	0x5d, 0xcd, 0xb3, 0xe9, 0xb1, 0xb6, 0x4f, 0x6d, 0x9b, 0x1e, 0x13, 0x37, 0xa8, 0x9b, 0x95, 0x6c,
-	0x3a, 0x68, 0x0a, 0xd0, 0x06, 0x75, 0x7b, 0x36, 0x3d, 0xde, 0x08, 0x10, 0x2c, 0xa4, 0x9b, 0xce,
-	0xd9, 0xb7, 0x8c, 0xc3, 0x20, 0xa4, 0x0b, 0xa9, 0x7d, 0xcb, 0x38, 0x44, 0xef, 0xc0, 0x02, 0xb1,
-	0x09, 0x2f, 0x9f, 0x08, 0x54, 0x86, 0xa3, 0x8a, 0x01, 0x91, 0x81, 0xd4, 0x4f, 0x40, 0x69, 0x3a,
-	0x86, 0x3b, 0x19, 0x45, 0xd6, 0xfc, 0x3e, 0x20, 0xe6, 0x24, 0x35, 0x9b, 0x1a, 0x87, 0xda, 0x50,
-	0x77, 0xf4, 0x01, 0x1b, 0x97, 0x78, 0xfd, 0x53, 0x18, 0x67, 0x9b, 0x1a, 0x87, 0x3b, 0x92, 0xae,
-	0x7e, 0x00, 0xd0, 0x1b, 0xb9, 0x44, 0x37, 0x3b, 0x2c, 0x9a, 0x60, 0xa6, 0xe3, 0x2d, 0xcd, 0x94,
-	0xaf, 0xa7, 0xd4, 0x95, 0x47, 0x5d, 0x11, 0x8c, 0x46, 0x48, 0x57, 0x7f, 0x1e, 0x6e, 0x74, 0x6d,
-	0xdd, 0xe0, 0x5f, 0x12, 0x74, 0xc3, 0xe7, 0x2c, 0xf4, 0x14, 0xb2, 0x02, 0x2a, 0x57, 0x32, 0xf6,
-	0xb8, 0x4d, 0xfb, 0xdc, 0x9a, 0xc3, 0x12, 0x5f, 0x2b, 0x02, 0x4c, 0xf5, 0xa8, 0x7f, 0x9e, 0x80,
-	0x7c, 0xa8, 0x1f, 0x95, 0xc5, 0x2b, 0x8d, 0xef, 0xea, 0x96, 0x23, 0x33, 0xfe, 0x3c, 0x8e, 0x92,
-	0x50, 0x0b, 0x0a, 0xa3, 0x50, 0xfa, 0xca, 0x78, 0x2e, 0x66, 0xd4, 0x38, 0x2a, 0x8b, 0x3e, 0x84,
-	0x7c, 0xf0, 0x5c, 0x1d, 0x78, 0xd8, 0xab, 0x5f, 0xb7, 0xa7, 0x70, 0xf5, 0x9b, 0x00, 0xdf, 0xa2,
-	0x96, 0xd3, 0xa7, 0x87, 0xc4, 0xe1, 0xcf, 0xaf, 0x2c, 0x5f, 0x24, 0x81, 0x15, 0x65, 0x8b, 0x97,
-	0x01, 0xc4, 0x12, 0x84, 0xaf, 0x90, 0xa2, 0xa9, 0xfe, 0x75, 0x12, 0xb2, 0x98, 0x52, 0xbf, 0x5e,
-	0x45, 0x65, 0xc8, 0x4a, 0x3f, 0xc1, 0xef, 0x9f, 0x5a, 0xfe, 0xfc, 0x6c, 0x3d, 0x23, 0x1c, 0x44,
-	0xc6, 0xe0, 0x9e, 0x21, 0xe2, 0xc1, 0x93, 0x97, 0x79, 0x70, 0xf4, 0x10, 0x8a, 0x12, 0xa4, 0x1d,
-	0xe8, 0xde, 0x81, 0x48, 0xde, 0x6a, 0x8b, 0xe7, 0x67, 0xeb, 0x20, 0x90, 0x5b, 0xba, 0x77, 0x80,
-	0x41, 0xa0, 0xd9, 0x6f, 0xd4, 0x84, 0xc2, 0xa7, 0xd4, 0x72, 0x34, 0x9f, 0x4f, 0x42, 0x16, 0x1a,
-	0x63, 0xd7, 0x71, 0x3a, 0x55, 0xf9, 0x2d, 0x02, 0x7c, 0x3a, 0x9d, 0x7c, 0x13, 0x16, 0x5c, 0x4a,
-	0x7d, 0xe1, 0xb6, 0x2c, 0xea, 0xc8, 0x1a, 0x46, 0x39, 0xb6, 0xb4, 0x4d, 0xa9, 0x8f, 0x25, 0x0e,
-	0x17, 0xdd, 0x48, 0x0b, 0x3d, 0x84, 0x15, 0x5b, 0xf7, 0x7c, 0x8d, 0xfb, 0x3b, 0x73, 0xaa, 0x2d,
-	0xcb, 0x8f, 0x1a, 0x62, 0xbc, 0x0d, 0xce, 0x0a, 0x24, 0xd4, 0x7f, 0x4a, 0x40, 0x81, 0x4d, 0xc6,
-	0xda, 0xb7, 0x0c, 0x16, 0xe4, 0x7d, 0xfe, 0xd8, 0xe3, 0x16, 0xa4, 0x0c, 0xcf, 0x95, 0x46, 0xe5,
-	0x97, 0x6f, 0xbd, 0x87, 0x31, 0xa3, 0xa1, 0x4f, 0x20, 0x2b, 0x6b, 0x29, 0x22, 0xec, 0x50, 0xaf,
-	0x0f, 0x47, 0xa5, 0x6d, 0xa4, 0x1c, 0xdf, 0xcb, 0xd3, 0xd1, 0x89, 0x4b, 0x00, 0x47, 0x49, 0xe8,
-	0x26, 0x24, 0x0d, 0x61, 0x2e, 0xf9, 0xb1, 0x4b, 0xbd, 0x8d, 0x93, 0x86, 0xa3, 0xfe, 0x20, 0x01,
-	0x0b, 0xd3, 0x03, 0xcf, 0x76, 0xc0, 0x6d, 0xc8, 0x7b, 0xe3, 0x3d, 0x6f, 0xe2, 0xf9, 0x64, 0x18,
-	0x3c, 0x2d, 0x87, 0x04, 0xd4, 0x82, 0xbc, 0x6e, 0x0f, 0xa8, 0x6b, 0xf9, 0x07, 0x43, 0x99, 0xa5,
-	0xc6, 0x87, 0x0a, 0x51, 0x9d, 0x95, 0x6a, 0x20, 0x82, 0xa7, 0xd2, 0xc1, 0xbd, 0x2f, 0xbe, 0x3f,
-	0xe0, 0xf7, 0xfe, 0xdb, 0x50, 0xb4, 0xf5, 0x21, 0x2f, 0x2e, 0xf9, 0xd6, 0x50, 0xcc, 0x23, 0x8d,
-	0x0b, 0x92, 0xd6, 0xb7, 0x86, 0x44, 0x55, 0x21, 0x1f, 0x2a, 0x43, 0x4b, 0x50, 0xa8, 0x36, 0x7b,
-	0xda, 0xa3, 0xc7, 0x4f, 0xb5, 0xcd, 0xfa, 0x8e, 0x32, 0x27, 0x63, 0xd3, 0xbf, 0x48, 0xc0, 0x82,
-	0x74, 0x47, 0x32, 0xde, 0x7f, 0x07, 0xe6, 0x5d, 0x7d, 0xdf, 0x0f, 0x32, 0x92, 0xb4, 0xd8, 0xd5,
-	0xcc, 0xc3, 0xb3, 0x8c, 0x84, 0xb1, 0xe2, 0x33, 0x92, 0xc8, 0xc7, 0x0e, 0xa9, 0x2b, 0x3f, 0x76,
-	0x48, 0xff, 0x54, 0x3e, 0x76, 0x50, 0x7f, 0x0d, 0x60, 0xc3, 0xb2, 0x49, 0x5f, 0xd4, 0xa1, 0xe2,
-	0xf2, 0x4b, 0x16, 0xc3, 0xc9, 0x3a, 0x67, 0x10, 0xc3, 0xb5, 0x1a, 0x98, 0xd1, 0x18, 0x6b, 0x60,
-	0x99, 0xf2, 0x30, 0x72, 0xd6, 0x26, 0x63, 0x0d, 0x2c, 0x33, 0x7c, 0x95, 0x4b, 0x5f, 0xf7, 0x2a,
-	0x77, 0x9a, 0x80, 0x25, 0x19, 0xbb, 0x86, 0xee, 0xf7, 0xcb, 0x90, 0x17, 0x61, 0xec, 0x34, 0xa1,
-	0xe3, 0x0f, 0xfc, 0x02, 0xd7, 0x6a, 0xe0, 0x9c, 0x60, 0xb7, 0x4c, 0xb4, 0x0e, 0x05, 0x09, 0x8d,
-	0x7c, 0x18, 0x05, 0x82, 0xd4, 0x66, 0xc3, 0xff, 0x2a, 0xa4, 0xf7, 0x2d, 0x9b, 0xc8, 0x8d, 0x1e,
-	0xeb, 0x00, 0xa6, 0x06, 0xd8, 0x9a, 0xc3, 0x1c, 0x5d, 0xcb, 0x05, 0x85, 0x3a, 0x3e, 0x3e, 0x99,
-	0x76, 0x46, 0xc7, 0x27, 0x32, 0xd0, 0x99, 0xf1, 0x09, 0x1c, 0x1b, 0x9f, 0x60, 0x8b, 0xf1, 0x49,
-	0x68, 0x74, 0x7c, 0x82, 0xf4, 0x53, 0x19, 0xdf, 0x36, 0xdc, 0xac, 0xd9, 0xba, 0x71, 0x68, 0x5b,
-	0x9e, 0x4f, 0xcc, 0xa8, 0xc7, 0x78, 0x0c, 0xd9, 0x0b, 0x41, 0xe7, 0x55, 0x15, 0x4d, 0x89, 0x54,
-	0xff, 0x3d, 0x01, 0xc5, 0x2d, 0xa2, 0xdb, 0xfe, 0xc1, 0xb4, 0x6c, 0xe4, 0x13, 0xcf, 0x97, 0x97,
-	0x15, 0xff, 0x8d, 0xbe, 0x06, 0xb9, 0x30, 0x26, 0xb9, 0xf6, 0x6d, 0x2e, 0x84, 0xa2, 0x27, 0x30,
-	0xcf, 0xce, 0x18, 0x1d, 0x07, 0xc9, 0xce, 0x55, 0xcf, 0x3e, 0x12, 0xc9, 0x2e, 0x19, 0x97, 0xf0,
-	0x20, 0x84, 0x6f, 0xa5, 0x0c, 0x0e, 0x9a, 0xe8, 0x67, 0xa1, 0xc8, 0x5f, 0x2d, 0x82, 0x98, 0x2b,
-	0x73, 0x9d, 0xce, 0x82, 0x78, 0x78, 0x14, 0xf1, 0xd6, 0xff, 0x26, 0x60, 0x65, 0x47, 0x9f, 0xec,
-	0x11, 0xe9, 0x36, 0x88, 0x89, 0x89, 0x41, 0x5d, 0x13, 0x75, 0xa3, 0xee, 0xe6, 0x8a, 0x77, 0xcc,
-	0x38, 0xe1, 0x78, 0xaf, 0x13, 0x24, 0x60, 0xc9, 0x48, 0x02, 0xb6, 0x02, 0x19, 0x87, 0x3a, 0x06,
-	0x91, 0xbe, 0x48, 0x34, 0x54, 0x2b, 0xea, 0x6a, 0x4a, 0xe1, 0x13, 0x23, 0x2f, 0x40, 0xb5, 0xa9,
-	0x1f, 0xf6, 0x86, 0x3e, 0x81, 0x52, 0xaf, 0x59, 0xc7, 0xcd, 0x7e, 0xad, 0xf3, 0x6d, 0xad, 0x57,
-	0xdd, 0xee, 0x55, 0x1f, 0x3f, 0xd4, 0xba, 0x9d, 0xed, 0xef, 0x3c, 0x7a, 0xf2, 0xf0, 0x6b, 0x4a,
-	0xa2, 0x54, 0x3e, 0x39, 0x2d, 0xdf, 0x6e, 0x57, 0xeb, 0xdb, 0xe2, 0xc4, 0xec, 0xd1, 0x97, 0x3d,
-	0xdd, 0xf6, 0xf4, 0xc7, 0x0f, 0xbb, 0xd4, 0x9e, 0x30, 0x0c, 0xdb, 0xd6, 0xc5, 0xe8, 0x7d, 0x15,
-	0xbd, 0x86, 0x13, 0x97, 0x5e, 0xc3, 0xd3, 0xdb, 0x3c, 0x79, 0xc9, 0x6d, 0xbe, 0x01, 0x2b, 0x86,
-	0x4b, 0x3d, 0x4f, 0x63, 0xd1, 0x3f, 0x31, 0x67, 0xf2, 0x8b, 0x2f, 0x9c, 0x9f, 0xad, 0x2f, 0xd7,
-	0x19, 0xbf, 0xc7, 0xd9, 0x52, 0xfd, 0xb2, 0x11, 0x21, 0xf1, 0x9e, 0xd4, 0x3f, 0x48, 0xb1, 0x40,
-	0xca, 0x3a, 0xb2, 0x6c, 0x32, 0x20, 0x1e, 0x7a, 0x0e, 0x4b, 0x86, 0x4b, 0x4c, 0x16, 0xd6, 0xeb,
-	0x76, 0xf4, 0x03, 0xdb, 0x9f, 0x89, 0x8d, 0x69, 0x42, 0xc1, 0x4a, 0x3d, 0x94, 0xea, 0x8d, 0x88,
-	0x81, 0x17, 0x8d, 0x0b, 0x6d, 0xf4, 0x29, 0x2c, 0x79, 0xc4, 0xb6, 0x9c, 0xf1, 0x4b, 0xcd, 0xa0,
-	0x8e, 0x4f, 0x5e, 0x06, 0xaf, 0x65, 0xd7, 0xe9, 0xed, 0x35, 0xb7, 0x99, 0x54, 0x5d, 0x08, 0xd5,
-	0xd0, 0xf9, 0xd9, 0xfa, 0xe2, 0x45, 0x1a, 0x5e, 0x94, 0x9a, 0x65, 0xbb, 0xd4, 0x86, 0xc5, 0x8b,
-	0xa3, 0x41, 0x2b, 0xf2, 0xec, 0x73, 0x17, 0x12, 0x9c, 0x6d, 0x74, 0x1b, 0x72, 0x2e, 0x19, 0x58,
-	0x9e, 0xef, 0x0a, 0x33, 0x33, 0x4e, 0x48, 0x61, 0x27, 0x5f, 0x7c, 0x1d, 0x55, 0xfa, 0x15, 0x98,
-	0xe9, 0x91, 0x1d, 0x16, 0xd3, 0xf2, 0xf4, 0x3d, 0xa9, 0x32, 0x87, 0x83, 0x26, 0xdb, 0x83, 0x63,
-	0x2f, 0x0c, 0xd4, 0xf8, 0x6f, 0x46, 0xe3, 0x11, 0x85, 0xfc, 0x56, 0x8c, 0xc7, 0x0c, 0xc1, 0x47,
-	0xa7, 0xe9, 0xc8, 0x47, 0xa7, 0x2b, 0x90, 0xb1, 0xc9, 0x11, 0xb1, 0xc5, 0x5d, 0x8e, 0x45, 0xe3,
-	0xde, 0x43, 0x28, 0x06, 0x5f, 0x37, 0xf2, 0xaf, 0x2a, 0x72, 0x90, 0xee, 0x57, 0x7b, 0xcf, 0x94,
-	0x39, 0x04, 0x90, 0x15, 0x9b, 0x53, 0xbc, 0xe4, 0xd5, 0x3b, 0xed, 0x8d, 0xd6, 0xa6, 0x92, 0xbc,
-	0xf7, 0xbb, 0x69, 0xc8, 0x87, 0x6f, 0x49, 0xec, 0xee, 0x68, 0x37, 0x5f, 0x04, 0xbb, 0x3b, 0xa4,
-	0xb7, 0xc9, 0x31, 0x7a, 0x7b, 0x5a, 0x85, 0xfa, 0x44, 0x3c, 0x9e, 0x87, 0xec, 0xa0, 0x02, 0xf5,
-	0x2e, 0xe4, 0xaa, 0xbd, 0x5e, 0x6b, 0xb3, 0xdd, 0x6c, 0x28, 0x9f, 0x25, 0x4a, 0x5f, 0x38, 0x39,
-	0x2d, 0x2f, 0x87, 0xa0, 0xaa, 0x27, 0x36, 0x1f, 0x47, 0xd5, 0xeb, 0xcd, 0x6e, 0xbf, 0xd9, 0x50,
-	0x5e, 0x25, 0x67, 0x51, 0xbc, 0xaa, 0xc2, 0x3f, 0xeb, 0xc9, 0x77, 0x71, 0xb3, 0x5b, 0xc5, 0xac,
-	0xc3, 0xcf, 0x92, 0xa2, 0x38, 0x36, 0xed, 0xd1, 0x25, 0x23, 0xdd, 0x65, 0x7d, 0xae, 0x05, 0xdf,
-	0xc9, 0xbd, 0x4a, 0x89, 0x4f, 0x3f, 0xa6, 0x0f, 0x63, 0x44, 0x37, 0x27, 0xac, 0x37, 0xfe, 0x22,
-	0xc9, 0xd5, 0xa4, 0x66, 0x7a, 0xeb, 0x31, 0xdf, 0xc3, 0xb4, 0xa8, 0x30, 0x8f, 0x77, 0xdb, 0x6d,
-	0x06, 0x7a, 0x95, 0x9e, 0x99, 0x1d, 0x1e, 0x3b, 0x2c, 0x63, 0x46, 0x77, 0x21, 0x17, 0x3c, 0x58,
-	0x2a, 0x9f, 0xa5, 0x67, 0x06, 0x54, 0x0f, 0x5e, 0x5b, 0x79, 0x87, 0x5b, 0xbb, 0x7d, 0xfe, 0x19,
-	0xdf, 0xab, 0xcc, 0x6c, 0x87, 0x07, 0x63, 0xdf, 0xa4, 0xc7, 0x0e, 0x3b, 0xb3, 0xb2, 0x0e, 0xf7,
-	0x59, 0x46, 0x14, 0x2d, 0x42, 0x8c, 0x2c, 0xc2, 0xbd, 0x0b, 0x39, 0xdc, 0xfc, 0x96, 0xf8, 0xe2,
-	0xef, 0x55, 0x76, 0x46, 0x0f, 0x26, 0x9f, 0x12, 0x83, 0xf5, 0x56, 0x86, 0x2c, 0x6e, 0xee, 0x74,
-	0x9e, 0x37, 0x95, 0x3f, 0xcc, 0xce, 0xe8, 0xc1, 0x64, 0x48, 0xf9, 0x77, 0x4f, 0xb9, 0x0e, 0xee,
-	0x6e, 0x55, 0xf9, 0xa2, 0xcc, 0xea, 0xe9, 0xb8, 0xa3, 0x03, 0xdd, 0x21, 0xe6, 0xf4, 0x0b, 0x99,
-	0x90, 0x75, 0xef, 0x17, 0x20, 0x17, 0xc4, 0xae, 0x68, 0x0d, 0xb2, 0x2f, 0x3a, 0xf8, 0x59, 0x13,
-	0x2b, 0x73, 0xc2, 0xca, 0x01, 0xe7, 0x85, 0xc8, 0x3a, 0xca, 0x30, 0xbf, 0x53, 0x6d, 0x57, 0x37,
-	0x9b, 0x38, 0x28, 0xa2, 0x07, 0x00, 0x19, 0x80, 0x95, 0x14, 0xd9, 0x41, 0xa8, 0xb3, 0xb6, 0xfa,
-	0xfd, 0x1f, 0xad, 0xcd, 0xfd, 0xf0, 0x47, 0x6b, 0x73, 0xaf, 0xce, 0xd7, 0x12, 0xdf, 0x3f, 0x5f,
-	0x4b, 0xfc, 0xfd, 0xf9, 0x5a, 0xe2, 0xdf, 0xce, 0xd7, 0x12, 0x7b, 0x59, 0x7e, 0x4d, 0x3c, 0xf9,
-	0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x6b, 0x9b, 0x2e, 0x8d, 0x2e, 0x32, 0x00, 0x00,
+	// 5091 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x7a, 0x5d, 0x6c, 0x23, 0x59,
+	0x56, 0x7f, 0xec, 0xd8, 0x8e, 0x7d, 0xec, 0x24, 0xd5, 0xb7, 0xb3, 0x3d, 0x69, 0x6f, 0x4f, 0x92,
+	0xa9, 0x99, 0xde, 0x99, 0xed, 0x9d, 0xbf, 0xfb, 0x6b, 0x77, 0xd5, 0x33, 0xf3, 0xdf, 0x9d, 0xb1,
+	0xcb, 0x95, 0x8e, 0xb7, 0x13, 0xdb, 0xba, 0x76, 0xba, 0x77, 0x91, 0xa0, 0xa8, 0x54, 0xdd, 0x38,
+	0x35, 0x29, 0xd7, 0x35, 0x55, 0xe5, 0xa4, 0xcd, 0x82, 0x18, 0xf1, 0x00, 0x28, 0x4f, 0xf0, 0x02,
+	0x8b, 0x50, 0x10, 0x12, 0xbc, 0x81, 0xc4, 0x03, 0x48, 0x08, 0x9e, 0x06, 0x09, 0xa1, 0x7d, 0x83,
+	0x05, 0x09, 0xad, 0x40, 0x0a, 0x6c, 0x1e, 0x78, 0x5b, 0xc1, 0x0b, 0xe2, 0x85, 0x07, 0x74, 0x3f,
+	0xaa, 0x5c, 0x71, 0x57, 0x92, 0x19, 0x76, 0x5f, 0x12, 0xdf, 0x73, 0x7e, 0xe7, 0xdc, 0x7b, 0xcf,
+	0xbd, 0xf7, 0xdc, 0x73, 0xce, 0x2d, 0xb8, 0x37, 0x70, 0xc2, 0x83, 0xf1, 0x5e, 0xcd, 0xa2, 0xc3,
+	0xfb, 0x36, 0xb5, 0x0e, 0x89, 0x7f, 0x3f, 0x38, 0x36, 0xfd, 0xe1, 0xa1, 0x13, 0xde, 0x37, 0x47,
+	0xce, 0xfd, 0x70, 0x32, 0x22, 0x41, 0x6d, 0xe4, 0xd3, 0x90, 0x22, 0x24, 0x00, 0xb5, 0x08, 0x50,
+	0x3b, 0x7a, 0x58, 0x5d, 0x1f, 0x50, 0x3a, 0x70, 0xc9, 0x7d, 0x8e, 0xd8, 0x1b, 0xef, 0xdf, 0x0f,
+	0x9d, 0x21, 0x09, 0x42, 0x73, 0x38, 0x12, 0x42, 0xd5, 0xb5, 0x59, 0x80, 0x3d, 0xf6, 0xcd, 0xd0,
+	0xa1, 0x9e, 0xe4, 0xaf, 0x0c, 0xe8, 0x80, 0xf2, 0x9f, 0xf7, 0xd9, 0x2f, 0x41, 0x55, 0xd7, 0x61,
+	0xe1, 0x39, 0xf1, 0x03, 0x87, 0x7a, 0x68, 0x05, 0xf2, 0x8e, 0x67, 0x93, 0x97, 0xab, 0x99, 0x8d,
+	0xcc, 0x3b, 0x39, 0x2c, 0x1a, 0xea, 0x03, 0x80, 0x16, 0xfb, 0xa1, 0x7b, 0xa1, 0x3f, 0x41, 0x0a,
+	0xcc, 0x1f, 0x92, 0x09, 0x47, 0x94, 0x30, 0xfb, 0xc9, 0x28, 0x47, 0xa6, 0xbb, 0x9a, 0x15, 0x94,
+	0x23, 0xd3, 0x55, 0x7f, 0x94, 0x81, 0x72, 0xdd, 0xf3, 0x68, 0xc8, 0x7b, 0x0f, 0x10, 0x82, 0x9c,
+	0x67, 0x0e, 0x89, 0x14, 0xe2, 0xbf, 0x91, 0x06, 0x05, 0xd7, 0xdc, 0x23, 0x6e, 0xb0, 0x9a, 0xdd,
+	0x98, 0x7f, 0xa7, 0xfc, 0xe8, 0x2b, 0xb5, 0x57, 0xa7, 0x5c, 0x4b, 0x28, 0xa9, 0x6d, 0x73, 0x34,
+	0x1f, 0x04, 0x96, 0xa2, 0xe8, 0x9b, 0xb0, 0xe0, 0x78, 0xb6, 0x63, 0x91, 0x60, 0x35, 0xc7, 0xb5,
+	0xac, 0xa5, 0x69, 0x99, 0x8e, 0xbe, 0x91, 0xfb, 0xfe, 0xd9, 0xfa, 0x1c, 0x8e, 0x84, 0xaa, 0xef,
+	0x41, 0x39, 0xa1, 0x36, 0x65, 0x6e, 0x2b, 0x90, 0x3f, 0x32, 0xdd, 0x31, 0x91, 0xb3, 0x13, 0x8d,
+	0xf7, 0xb3, 0x4f, 0x32, 0xea, 0x47, 0xb0, 0xd2, 0x36, 0x87, 0xc4, 0x7e, 0x4a, 0x3c, 0xe2, 0x3b,
+	0x16, 0x26, 0x01, 0x1d, 0xfb, 0x16, 0x61, 0x73, 0x3d, 0x74, 0x3c, 0x3b, 0x9a, 0x2b, 0xfb, 0x9d,
+	0xae, 0x45, 0xd5, 0xe0, 0xb5, 0xa6, 0x13, 0x58, 0x3e, 0x09, 0xc9, 0xe7, 0x56, 0x32, 0x1f, 0x29,
+	0x39, 0xcb, 0xc0, 0xf2, 0xac, 0xf4, 0xcf, 0xc0, 0x4d, 0x66, 0x62, 0xdb, 0xf0, 0x25, 0xc5, 0x08,
+	0x46, 0xc4, 0xe2, 0xca, 0xca, 0x8f, 0xde, 0x49, 0xb3, 0x50, 0xda, 0x4c, 0xb6, 0xe6, 0xf0, 0x0d,
+	0xae, 0x26, 0x22, 0xf4, 0x46, 0xc4, 0x42, 0x16, 0xdc, 0xb2, 0xe5, 0xa0, 0x67, 0xd4, 0x67, 0xb9,
+	0xfa, 0xd4, 0x65, 0xbc, 0x64, 0x9a, 0x5b, 0x73, 0x78, 0x25, 0x52, 0x96, 0xec, 0xa4, 0x01, 0x50,
+	0x8c, 0x74, 0xab, 0xdf, 0xcb, 0x40, 0x29, 0x62, 0x06, 0xe8, 0xcb, 0x50, 0xf2, 0x4c, 0x8f, 0x1a,
+	0xd6, 0x68, 0x1c, 0xf0, 0x09, 0xcd, 0x37, 0x2a, 0xe7, 0x67, 0xeb, 0xc5, 0xb6, 0xe9, 0x51, 0xad,
+	0xbb, 0x1b, 0xe0, 0x22, 0x63, 0x6b, 0xa3, 0x71, 0x80, 0xde, 0x80, 0xca, 0x90, 0x0c, 0xa9, 0x3f,
+	0x31, 0xf6, 0x26, 0x21, 0x09, 0xa4, 0xd9, 0xca, 0x82, 0xd6, 0x60, 0x24, 0xf4, 0x0d, 0x58, 0x18,
+	0x88, 0x21, 0xad, 0xce, 0xf3, 0xed, 0xf3, 0x66, 0xda, 0xe8, 0x67, 0x46, 0x8d, 0x23, 0x19, 0xf5,
+	0x37, 0x33, 0xb0, 0x12, 0x53, 0xc9, 0x2f, 0x8c, 0x1d, 0x9f, 0x0c, 0x89, 0x17, 0x06, 0xe8, 0x6b,
+	0x50, 0x70, 0x9d, 0xa1, 0x13, 0x06, 0xd2, 0xe6, 0xaf, 0xa7, 0xa9, 0x8d, 0x27, 0x85, 0x25, 0x18,
+	0xd5, 0xa1, 0xe2, 0x93, 0x80, 0xf8, 0x47, 0x62, 0xc7, 0x4b, 0x8b, 0x5e, 0x23, 0x7c, 0x41, 0x44,
+	0xdd, 0x84, 0x62, 0xd7, 0x35, 0xc3, 0x7d, 0xea, 0x0f, 0x91, 0x0a, 0x15, 0xd3, 0xb7, 0x0e, 0x9c,
+	0x90, 0x58, 0xe1, 0xd8, 0x8f, 0x4e, 0xdf, 0x05, 0x1a, 0xba, 0x05, 0x59, 0x2a, 0x3a, 0x2a, 0x35,
+	0x0a, 0xe7, 0x67, 0xeb, 0xd9, 0x4e, 0x0f, 0x67, 0x69, 0xa0, 0x7e, 0x00, 0x37, 0xba, 0xee, 0x78,
+	0xe0, 0x78, 0x4d, 0x12, 0x58, 0xbe, 0x33, 0x62, 0xda, 0xd9, 0xae, 0x64, 0x3e, 0x2a, 0xda, 0x95,
+	0xec, 0x77, 0x7c, 0xb4, 0xb3, 0xd3, 0xa3, 0xad, 0xfe, 0x7a, 0x16, 0x6e, 0xe8, 0xde, 0xc0, 0xf1,
+	0x48, 0x52, 0xfa, 0x2e, 0x2c, 0x11, 0x4e, 0x34, 0x8e, 0x84, 0xbb, 0x91, 0x7a, 0x16, 0x05, 0x35,
+	0xf2, 0x41, 0xad, 0x19, 0xbf, 0xf0, 0x30, 0x6d, 0xfa, 0xaf, 0x68, 0x4f, 0xf5, 0x0e, 0x3a, 0x2c,
+	0x8c, 0xf8, 0x24, 0x02, 0xb9, 0xbc, 0x77, 0xd3, 0x74, 0xbd, 0x32, 0xcf, 0xc8, 0x49, 0x48, 0xd9,
+	0x9f, 0xc4, 0x49, 0xfc, 0x49, 0x16, 0x96, 0xdb, 0xd4, 0xbe, 0x60, 0x87, 0x2a, 0x14, 0x0f, 0x68,
+	0x10, 0x26, 0x1c, 0x62, 0xdc, 0x46, 0x4f, 0xa0, 0x38, 0x92, 0xcb, 0x27, 0x57, 0xff, 0x4e, 0xfa,
+	0x90, 0x05, 0x06, 0xc7, 0x68, 0xf4, 0x01, 0x94, 0xa2, 0x23, 0xc3, 0x66, 0xfb, 0x19, 0x36, 0xce,
+	0x14, 0x8f, 0xbe, 0x01, 0x05, 0xb1, 0x08, 0xab, 0x39, 0x2e, 0x79, 0xf7, 0x33, 0xd9, 0x1c, 0x4b,
+	0x21, 0xf4, 0x14, 0x8a, 0xa1, 0x1b, 0x18, 0x8e, 0xb7, 0x4f, 0x57, 0xf3, 0x5c, 0xc1, 0x7a, 0xaa,
+	0x93, 0xa1, 0x36, 0xe9, 0x6f, 0xf7, 0x5a, 0xde, 0x3e, 0x6d, 0x94, 0xcf, 0xcf, 0xd6, 0x17, 0x64,
+	0x03, 0x2f, 0x84, 0x6e, 0xc0, 0x7e, 0xa8, 0xbf, 0x95, 0x81, 0x72, 0x02, 0x85, 0x5e, 0x07, 0x08,
+	0xfd, 0x71, 0x10, 0x1a, 0x3e, 0xa5, 0x21, 0x37, 0x56, 0x05, 0x97, 0x38, 0x05, 0x53, 0x1a, 0xa2,
+	0x1a, 0xdc, 0xb4, 0x88, 0x1f, 0x1a, 0x4e, 0x10, 0x8c, 0x89, 0x6f, 0x04, 0xe3, 0xbd, 0x8f, 0x89,
+	0x15, 0x72, 0xc3, 0x55, 0xf0, 0x0d, 0xc6, 0x6a, 0x71, 0x4e, 0x4f, 0x30, 0xd0, 0x63, 0xb8, 0x95,
+	0xc4, 0x8f, 0xc6, 0x7b, 0xae, 0x63, 0x19, 0x6c, 0x31, 0xe7, 0xb9, 0xc8, 0xcd, 0xa9, 0x48, 0x97,
+	0xf3, 0x9e, 0x91, 0x89, 0xfa, 0xc3, 0x0c, 0x28, 0xd8, 0xdc, 0x0f, 0x77, 0xc8, 0x70, 0x8f, 0xf8,
+	0xbd, 0xd0, 0x0c, 0xc7, 0x01, 0xba, 0x05, 0x05, 0x97, 0x98, 0x36, 0xf1, 0xf9, 0xa0, 0x8a, 0x58,
+	0xb6, 0xd0, 0x2e, 0x3b, 0xc1, 0xa6, 0x75, 0x60, 0xee, 0x39, 0xae, 0x13, 0x4e, 0xf8, 0x50, 0x96,
+	0xd2, 0xb7, 0xf0, 0xac, 0xce, 0x1a, 0x4e, 0x08, 0xe2, 0x0b, 0x6a, 0xd0, 0x2a, 0x2c, 0x0c, 0x49,
+	0x10, 0x98, 0x03, 0xc2, 0x47, 0x5a, 0xc2, 0x51, 0x53, 0xfd, 0x00, 0x2a, 0x49, 0x39, 0x54, 0x86,
+	0x85, 0xdd, 0xf6, 0xb3, 0x76, 0xe7, 0x45, 0x5b, 0x99, 0x43, 0xcb, 0x50, 0xde, 0x6d, 0x63, 0xbd,
+	0xae, 0x6d, 0xd5, 0x1b, 0xdb, 0xba, 0x92, 0x41, 0x8b, 0x50, 0x9a, 0x36, 0xb3, 0xea, 0x9f, 0x65,
+	0x00, 0x98, 0xb9, 0xe5, 0xa4, 0xde, 0x87, 0x7c, 0x10, 0x9a, 0xa1, 0xd8, 0x95, 0x4b, 0x8f, 0xde,
+	0xba, 0x6c, 0x0d, 0xe5, 0x78, 0xd9, 0x3f, 0x82, 0x85, 0x48, 0x72, 0x84, 0xd9, 0x0b, 0x23, 0x64,
+	0x0e, 0xc2, 0xb4, 0x6d, 0x5f, 0x0e, 0x9c, 0xff, 0x56, 0x3f, 0x80, 0x3c, 0x97, 0xbe, 0x38, 0xdc,
+	0x22, 0xe4, 0x9a, 0xec, 0x57, 0x06, 0x95, 0x20, 0x8f, 0xf5, 0x7a, 0xf3, 0x3b, 0x4a, 0x16, 0x29,
+	0x50, 0x69, 0xb6, 0x7a, 0x5a, 0xa7, 0xdd, 0xd6, 0xb5, 0xbe, 0xde, 0x54, 0xe6, 0xd5, 0xbb, 0x90,
+	0x6f, 0x0d, 0x99, 0xe6, 0x3b, 0x6c, 0xcb, 0xef, 0x13, 0x9f, 0x78, 0x56, 0x74, 0x92, 0xa6, 0x04,
+	0xf5, 0xc7, 0x65, 0xc8, 0xef, 0xd0, 0xb1, 0x17, 0xa2, 0x47, 0x09, 0xb7, 0xb5, 0x94, 0x1e, 0x21,
+	0x70, 0x60, 0xad, 0x3f, 0x19, 0x11, 0xe9, 0xd6, 0x6e, 0x41, 0x41, 0x1c, 0x0e, 0x39, 0x1d, 0xd9,
+	0x62, 0xf4, 0xd0, 0xf4, 0x07, 0x24, 0x94, 0xf3, 0x91, 0x2d, 0xf4, 0x0e, 0xbb, 0xb1, 0x4c, 0x9b,
+	0x7a, 0xee, 0x84, 0x9f, 0xa1, 0xa2, 0xb8, 0x96, 0x30, 0x31, 0xed, 0x8e, 0xe7, 0x4e, 0x70, 0xcc,
+	0x45, 0x5b, 0x50, 0xd9, 0x73, 0x3c, 0xdb, 0xa0, 0x23, 0xe1, 0xe4, 0xf3, 0x97, 0x9f, 0x38, 0x31,
+	0xaa, 0x86, 0xe3, 0xd9, 0x1d, 0x01, 0xc6, 0xe5, 0xbd, 0x69, 0x03, 0xb5, 0x61, 0xe9, 0x88, 0xba,
+	0xe3, 0x21, 0x89, 0x75, 0x15, 0xb8, 0xae, 0xb7, 0x2f, 0xd7, 0xf5, 0x9c, 0xe3, 0x23, 0x6d, 0x8b,
+	0x47, 0xc9, 0x26, 0x7a, 0x06, 0x8b, 0xe1, 0x70, 0xb4, 0x1f, 0xc4, 0xea, 0x16, 0xb8, 0xba, 0x2f,
+	0x5d, 0x61, 0x30, 0x06, 0x8f, 0xb4, 0x55, 0xc2, 0x44, 0x0b, 0x3d, 0x85, 0xb2, 0x45, 0xbd, 0xc0,
+	0x09, 0x42, 0xe2, 0x59, 0x93, 0xd5, 0x22, 0xb7, 0xfd, 0x15, 0xb3, 0xd4, 0xa6, 0x60, 0x9c, 0x94,
+	0xac, 0xfe, 0xea, 0x3c, 0x94, 0x13, 0x26, 0x40, 0x3d, 0x28, 0x8f, 0x7c, 0x3a, 0x32, 0x07, 0xfc,
+	0xc6, 0x93, 0x8b, 0xfa, 0xf0, 0x33, 0x99, 0xaf, 0xd6, 0x9d, 0x0a, 0xe2, 0xa4, 0x16, 0xf5, 0x34,
+	0x0b, 0xe5, 0x04, 0x13, 0xdd, 0x83, 0x22, 0xee, 0xe2, 0xd6, 0xf3, 0x7a, 0x5f, 0x57, 0xe6, 0xaa,
+	0x77, 0x4e, 0x4e, 0x37, 0x56, 0xb9, 0xb6, 0xa4, 0x82, 0xae, 0xef, 0x1c, 0xb1, 0x3d, 0xfc, 0x0e,
+	0x2c, 0x44, 0xd0, 0x4c, 0xf5, 0x8b, 0x27, 0xa7, 0x1b, 0xaf, 0xcd, 0x42, 0x13, 0x48, 0xdc, 0xdb,
+	0xaa, 0x63, 0xbd, 0xa9, 0x64, 0xd3, 0x91, 0xb8, 0x77, 0x60, 0xfa, 0xc4, 0x46, 0x5f, 0x82, 0x82,
+	0x04, 0xce, 0x57, 0xab, 0x27, 0xa7, 0x1b, 0xb7, 0x66, 0x81, 0x53, 0x1c, 0xee, 0x6d, 0xd7, 0x9f,
+	0xeb, 0x4a, 0x2e, 0x1d, 0x87, 0x7b, 0xae, 0x79, 0x44, 0xd0, 0x5b, 0x90, 0x17, 0xb0, 0x7c, 0xf5,
+	0xf6, 0xc9, 0xe9, 0xc6, 0x17, 0x5e, 0x51, 0xc7, 0x50, 0xd5, 0xd5, 0xdf, 0xf8, 0xc3, 0xb5, 0xb9,
+	0xbf, 0xfa, 0xa3, 0x35, 0x65, 0x96, 0x5d, 0xfd, 0x9f, 0x0c, 0x2c, 0x5e, 0xd8, 0x3b, 0x48, 0x85,
+	0x82, 0x47, 0x2d, 0x3a, 0x12, 0x17, 0x61, 0xb1, 0x01, 0xe7, 0x67, 0xeb, 0x85, 0x36, 0xd5, 0xe8,
+	0x68, 0x82, 0x25, 0x07, 0x3d, 0x9b, 0xb9, 0xca, 0x1f, 0x7f, 0xc6, 0x8d, 0x99, 0x7a, 0x99, 0x7f,
+	0x08, 0x8b, 0xb6, 0xef, 0x1c, 0x11, 0xdf, 0xb0, 0xa8, 0xb7, 0xef, 0x0c, 0xe4, 0x25, 0x57, 0x4d,
+	0x8d, 0x37, 0x39, 0x10, 0x57, 0x84, 0x80, 0xc6, 0xf1, 0x3f, 0xc1, 0x35, 0x5e, 0x7d, 0x0e, 0x95,
+	0xe4, 0x56, 0x67, 0xf7, 0x52, 0xe0, 0xfc, 0x22, 0x91, 0x81, 0x25, 0x0f, 0x43, 0x71, 0x89, 0x51,
+	0x44, 0x58, 0xf9, 0x36, 0xe4, 0x86, 0xd4, 0x16, 0x7a, 0x16, 0x1b, 0x37, 0x59, 0x34, 0xf1, 0xcf,
+	0x67, 0xeb, 0x65, 0x1a, 0xd4, 0x36, 0x1d, 0x97, 0xec, 0x50, 0x9b, 0x60, 0x0e, 0x50, 0x8f, 0x20,
+	0xc7, 0x7c, 0x0e, 0xfa, 0x22, 0xe4, 0x1a, 0xad, 0x76, 0x53, 0x99, 0xab, 0xde, 0x38, 0x39, 0xdd,
+	0x58, 0xe4, 0x26, 0x61, 0x0c, 0xb6, 0x77, 0xd1, 0x3a, 0x14, 0x9e, 0x77, 0xb6, 0x77, 0x77, 0xd8,
+	0xf6, 0xba, 0x79, 0x72, 0xba, 0xb1, 0x1c, 0xb3, 0x85, 0xd1, 0xd0, 0xeb, 0x90, 0xef, 0xef, 0x74,
+	0x37, 0x7b, 0x4a, 0xb6, 0x8a, 0x4e, 0x4e, 0x37, 0x96, 0x62, 0x3e, 0x1f, 0x73, 0xf5, 0x86, 0x5c,
+	0xd5, 0x52, 0x4c, 0x57, 0x7f, 0x90, 0x81, 0x72, 0xe2, 0xc0, 0xb1, 0x8d, 0xd9, 0xd4, 0x37, 0xeb,
+	0xbb, 0xdb, 0x7d, 0x65, 0x2e, 0xb1, 0x31, 0x13, 0x90, 0x26, 0xd9, 0x37, 0xc7, 0x2e, 0xf3, 0x73,
+	0xa0, 0x75, 0xda, 0xbd, 0x56, 0xaf, 0xaf, 0xb7, 0xfb, 0x4a, 0xa6, 0xba, 0x7a, 0x72, 0xba, 0xb1,
+	0x32, 0x0b, 0xde, 0x1c, 0xbb, 0x2e, 0xdb, 0x9a, 0x5a, 0x5d, 0xdb, 0xe2, 0x7b, 0x7d, 0xba, 0x35,
+	0x13, 0x28, 0xcd, 0xb4, 0x0e, 0x88, 0x8d, 0xde, 0x85, 0x52, 0x53, 0xdf, 0xd6, 0x9f, 0xd6, 0xb9,
+	0x77, 0xaf, 0xbe, 0x7e, 0x72, 0xba, 0x71, 0xfb, 0xd5, 0xde, 0x5d, 0x32, 0x30, 0x43, 0x62, 0xcf,
+	0x6c, 0xd1, 0x04, 0x44, 0xfd, 0xaf, 0x2c, 0x2c, 0x62, 0x96, 0x0e, 0xfb, 0x61, 0x97, 0xba, 0x8e,
+	0x35, 0x41, 0x5d, 0x28, 0x59, 0xd4, 0xb3, 0x9d, 0x84, 0x9f, 0x78, 0x74, 0x49, 0x48, 0x34, 0x95,
+	0x8a, 0x5a, 0x5a, 0x24, 0x89, 0xa7, 0x4a, 0xd0, 0x7d, 0xc8, 0xdb, 0xc4, 0x35, 0x27, 0x32, 0x36,
+	0xbb, 0x5d, 0x13, 0x09, 0x77, 0x2d, 0x4a, 0xb8, 0x6b, 0x4d, 0x99, 0x70, 0x63, 0x81, 0xe3, 0x39,
+	0x88, 0xf9, 0xd2, 0x30, 0xc3, 0x90, 0x0c, 0x47, 0xa1, 0x08, 0xcc, 0x72, 0xb8, 0x3c, 0x34, 0x5f,
+	0xd6, 0x25, 0x09, 0x3d, 0x84, 0xc2, 0xb1, 0xe3, 0xd9, 0xf4, 0x58, 0xc6, 0x5e, 0x57, 0x28, 0x95,
+	0x40, 0xf5, 0x84, 0x85, 0x24, 0x33, 0xc3, 0x64, 0x7b, 0xa8, 0xdd, 0x69, 0xeb, 0xd1, 0x1e, 0x92,
+	0xfc, 0x8e, 0xd7, 0xa6, 0x1e, 0x3b, 0xff, 0xd0, 0x69, 0x1b, 0x9b, 0xf5, 0xd6, 0xf6, 0x2e, 0x66,
+	0xfb, 0x68, 0xe5, 0xe4, 0x74, 0x43, 0x89, 0x21, 0x9b, 0xa6, 0xe3, 0xb2, 0x64, 0xe0, 0x36, 0xcc,
+	0xd7, 0xdb, 0xdf, 0x51, 0xb2, 0x55, 0xe5, 0xe4, 0x74, 0xa3, 0x12, 0xb3, 0xeb, 0xde, 0x64, 0x6a,
+	0xf7, 0xd9, 0x7e, 0xd5, 0xbf, 0x9b, 0x87, 0xca, 0xee, 0xc8, 0x36, 0x43, 0x22, 0xce, 0x19, 0xda,
+	0x80, 0xf2, 0xc8, 0xf4, 0x4d, 0xd7, 0x25, 0xae, 0x13, 0x0c, 0x65, 0x29, 0x21, 0x49, 0x42, 0xef,
+	0x7d, 0x56, 0x33, 0x36, 0x8a, 0xec, 0xec, 0x7c, 0xef, 0x5f, 0xd7, 0x33, 0x91, 0x41, 0x77, 0x61,
+	0x69, 0x5f, 0x8c, 0xd6, 0x30, 0x2d, 0xbe, 0xb0, 0xf3, 0x7c, 0x61, 0x6b, 0x69, 0x0b, 0x9b, 0x1c,
+	0x56, 0x4d, 0x4e, 0xb2, 0xce, 0xa5, 0xf0, 0xe2, 0x7e, 0xb2, 0x89, 0x1e, 0xc3, 0xc2, 0x90, 0x7a,
+	0x4e, 0x48, 0xfd, 0xeb, 0x57, 0x21, 0x42, 0xa2, 0x7b, 0x70, 0x83, 0x2d, 0x6e, 0x34, 0x1e, 0xce,
+	0xe6, 0xd7, 0x79, 0x16, 0x2f, 0x0f, 0xcd, 0x97, 0xb2, 0x43, 0xcc, 0xc8, 0xa8, 0x01, 0x79, 0xea,
+	0xb3, 0x78, 0xb1, 0xc0, 0x87, 0xfb, 0xee, 0xb5, 0xc3, 0x15, 0x8d, 0x0e, 0x93, 0xc1, 0x42, 0x54,
+	0xfd, 0x3a, 0x2c, 0x5e, 0x98, 0x04, 0x0b, 0x93, 0xba, 0xf5, 0xdd, 0x9e, 0xae, 0xcc, 0xa1, 0x0a,
+	0x14, 0xb5, 0x4e, 0xbb, 0xdf, 0x6a, 0xef, 0xb2, 0x38, 0xaf, 0x02, 0x45, 0xdc, 0xd9, 0xde, 0x6e,
+	0xd4, 0xb5, 0x67, 0x4a, 0x56, 0xad, 0x41, 0x39, 0xa1, 0x0d, 0x2d, 0x01, 0xf4, 0xfa, 0x9d, 0xae,
+	0xb1, 0xd9, 0xc2, 0xbd, 0xbe, 0x88, 0x12, 0x7b, 0xfd, 0x3a, 0xee, 0x4b, 0x42, 0x46, 0xfd, 0x8f,
+	0x6c, 0xb4, 0xa2, 0x32, 0x30, 0x6c, 0x5c, 0x0c, 0x0c, 0xaf, 0x18, 0xbc, 0x0c, 0x0d, 0xa7, 0x8d,
+	0x38, 0x40, 0x7c, 0x0f, 0x80, 0x6f, 0x1c, 0x62, 0x1b, 0x66, 0x28, 0x17, 0xbe, 0xfa, 0x8a, 0x91,
+	0xfb, 0x51, 0x45, 0x0b, 0x97, 0x24, 0xba, 0x1e, 0xa2, 0x6f, 0x40, 0xc5, 0xa2, 0xc3, 0x91, 0x4b,
+	0xa4, 0xf0, 0xfc, 0xb5, 0xc2, 0xe5, 0x18, 0x5f, 0x0f, 0x93, 0xa1, 0x69, 0xee, 0x62, 0xf0, 0xfc,
+	0x6b, 0x99, 0xc8, 0x32, 0x29, 0xd1, 0x68, 0x05, 0x8a, 0xbb, 0xdd, 0x66, 0xbd, 0xdf, 0x6a, 0x3f,
+	0x55, 0x32, 0x08, 0xa0, 0xc0, 0x4d, 0xdd, 0x54, 0xb2, 0x2c, 0x8a, 0xd6, 0x3a, 0x3b, 0xdd, 0x6d,
+	0x9d, 0x7b, 0x2c, 0xb4, 0x02, 0x4a, 0x64, 0x6c, 0x83, 0x1b, 0x52, 0x6f, 0x2a, 0x39, 0x74, 0x13,
+	0x96, 0x63, 0xaa, 0x94, 0xcc, 0xa3, 0x5b, 0x80, 0x62, 0xe2, 0x54, 0x45, 0x41, 0xfd, 0x65, 0x58,
+	0xd6, 0xa8, 0x17, 0x9a, 0x8e, 0x17, 0x67, 0x18, 0x8f, 0xd8, 0xa4, 0x25, 0xc9, 0x70, 0x64, 0x25,
+	0xa8, 0xb1, 0x7c, 0x7e, 0xb6, 0x5e, 0x8e, 0xa1, 0xad, 0x26, 0x0f, 0x95, 0x64, 0xc3, 0x66, 0xe7,
+	0x77, 0xe4, 0xd8, 0xdc, 0xb8, 0xf9, 0xc6, 0xc2, 0xf9, 0xd9, 0xfa, 0x7c, 0xb7, 0xd5, 0xc4, 0x8c,
+	0x86, 0xbe, 0x08, 0x25, 0xf2, 0xd2, 0x09, 0x0d, 0x8b, 0xdd, 0x4b, 0xcc, 0x80, 0x79, 0x5c, 0x64,
+	0x04, 0x8d, 0x5d, 0x43, 0x0d, 0x80, 0x2e, 0xf5, 0x43, 0xd9, 0xf3, 0x57, 0x21, 0x3f, 0xa2, 0x3e,
+	0xaf, 0x5d, 0x5c, 0x5a, 0x51, 0x63, 0x70, 0xb1, 0x51, 0xb1, 0x00, 0xab, 0xbf, 0x3b, 0x0f, 0xd0,
+	0x37, 0x83, 0x43, 0xa9, 0xe4, 0x09, 0x94, 0xe2, 0xea, 0xa4, 0x2c, 0x82, 0x5c, 0xb9, 0xda, 0x31,
+	0x18, 0x3d, 0x8e, 0x36, 0x9b, 0xc8, 0x9d, 0x52, 0x93, 0xd8, 0xa8, 0xa3, 0xb4, 0xf4, 0xe3, 0x62,
+	0x82, 0xc4, 0xae, 0x79, 0xe2, 0xfb, 0x72, 0xe5, 0xd9, 0x4f, 0xa4, 0xf1, 0x6b, 0x41, 0x18, 0x4d,
+	0x46, 0xdf, 0xa9, 0x65, 0x9f, 0x99, 0x15, 0xd9, 0x9a, 0xc3, 0x53, 0x39, 0xf4, 0x21, 0x94, 0xd9,
+	0xbc, 0x8d, 0x80, 0xf3, 0x64, 0xe0, 0x7d, 0xa9, 0xa9, 0x84, 0x06, 0x0c, 0xa3, 0xa9, 0x95, 0x5f,
+	0x07, 0x30, 0x47, 0x23, 0xd7, 0x21, 0xb6, 0xb1, 0x37, 0xe1, 0x91, 0x76, 0x09, 0x97, 0x24, 0xa5,
+	0x31, 0x61, 0xc7, 0x25, 0x62, 0x9b, 0x21, 0x8f, 0x9e, 0xaf, 0x31, 0xa0, 0x44, 0xd7, 0xc3, 0x86,
+	0x02, 0x4b, 0xfe, 0xd8, 0x63, 0x06, 0x95, 0xa3, 0x53, 0xff, 0x34, 0x0b, 0xaf, 0xb5, 0x49, 0x78,
+	0x4c, 0xfd, 0xc3, 0x7a, 0x18, 0x9a, 0xd6, 0xc1, 0x90, 0x78, 0x72, 0xf9, 0x12, 0x09, 0x4d, 0xe6,
+	0x42, 0x42, 0xb3, 0x0a, 0x0b, 0xa6, 0xeb, 0x98, 0x01, 0x11, 0xc1, 0x5b, 0x09, 0x47, 0x4d, 0x96,
+	0x76, 0xb1, 0x24, 0x8e, 0x04, 0x01, 0x11, 0x75, 0x15, 0x36, 0xf0, 0x88, 0x80, 0xbe, 0x0b, 0xb7,
+	0x64, 0x98, 0x66, 0xc6, 0x5d, 0xb1, 0x84, 0x22, 0x2a, 0xd0, 0xea, 0xa9, 0x59, 0x65, 0xfa, 0xe0,
+	0x64, 0x1c, 0x37, 0x25, 0x77, 0x46, 0xa1, 0x8c, 0x0a, 0x57, 0xec, 0x14, 0x56, 0xf5, 0x29, 0xdc,
+	0xbe, 0x54, 0xe4, 0x73, 0xd5, 0x6d, 0xfe, 0x31, 0x0b, 0xd0, 0xea, 0xd6, 0x77, 0xa4, 0x91, 0x9a,
+	0x50, 0xd8, 0x37, 0x87, 0x8e, 0x3b, 0xb9, 0xca, 0x03, 0x4e, 0xf1, 0xb5, 0xba, 0x30, 0xc7, 0x26,
+	0x97, 0xc1, 0x52, 0x96, 0xe7, 0x94, 0xe3, 0x3d, 0x8f, 0x84, 0x71, 0x4e, 0xc9, 0x5b, 0x6c, 0x18,
+	0xbe, 0xe9, 0xc5, 0x5b, 0x57, 0x34, 0xd8, 0x02, 0xb0, 0x90, 0xe7, 0xd8, 0x9c, 0x44, 0x6e, 0x4b,
+	0x36, 0xd1, 0x16, 0xaf, 0x8e, 0x12, 0xff, 0x88, 0xd8, 0xab, 0x79, 0x6e, 0xd4, 0xeb, 0xc6, 0x83,
+	0x25, 0x5c, 0xd8, 0x2e, 0x96, 0xae, 0x7e, 0xc0, 0x43, 0xa6, 0x29, 0xeb, 0x73, 0xd9, 0xe8, 0x01,
+	0x2c, 0x5e, 0x98, 0xe7, 0x2b, 0xc9, 0x7c, 0xab, 0xfb, 0xfc, 0xab, 0x4a, 0x4e, 0xfe, 0xfa, 0xba,
+	0x52, 0x50, 0xff, 0x76, 0x5e, 0x38, 0x1a, 0x69, 0xd5, 0xf4, 0x57, 0x81, 0x22, 0xdf, 0xdd, 0x16,
+	0x75, 0xa5, 0x03, 0x78, 0xfb, 0x6a, 0xff, 0xc3, 0x72, 0x3a, 0x0e, 0xc7, 0xb1, 0x20, 0x5a, 0x87,
+	0xb2, 0xd8, 0xc5, 0x06, 0x3b, 0x70, 0xdc, 0xac, 0x8b, 0x18, 0x04, 0x89, 0x49, 0xa2, 0xbb, 0xb0,
+	0xc4, 0x8b, 0x3f, 0xc1, 0x01, 0xb1, 0x05, 0x26, 0xc7, 0x31, 0x8b, 0x31, 0x95, 0xc3, 0x76, 0xa0,
+	0x22, 0x09, 0x06, 0x8f, 0xe7, 0xf3, 0x7c, 0x40, 0xf7, 0xae, 0x1b, 0x90, 0x10, 0xe1, 0x61, 0x7e,
+	0x79, 0x34, 0x6d, 0xa8, 0x3f, 0x0f, 0xc5, 0x68, 0xb0, 0x68, 0x15, 0xe6, 0xfb, 0x5a, 0x57, 0x99,
+	0xab, 0x2e, 0x9f, 0x9c, 0x6e, 0x94, 0x23, 0x72, 0x5f, 0xeb, 0x32, 0xce, 0x6e, 0xb3, 0xab, 0x64,
+	0x2e, 0x72, 0x76, 0x9b, 0x5d, 0x54, 0x85, 0x5c, 0x4f, 0xeb, 0x77, 0xa3, 0xf8, 0x2c, 0x62, 0x31,
+	0x5a, 0x35, 0xc7, 0xe2, 0x33, 0x75, 0x1f, 0xca, 0x89, 0xde, 0xd1, 0x9b, 0xb0, 0xd0, 0x6a, 0x3f,
+	0xc5, 0x7a, 0xaf, 0xa7, 0xcc, 0x55, 0x6f, 0x9d, 0x9c, 0x6e, 0xa0, 0x04, 0xb7, 0xe5, 0x0d, 0xd8,
+	0xda, 0xa1, 0xd7, 0x21, 0xb7, 0xd5, 0x61, 0xf7, 0xbe, 0x48, 0x2e, 0x12, 0x88, 0x2d, 0x1a, 0x84,
+	0xd5, 0x9b, 0x32, 0xf0, 0x4b, 0x2a, 0x56, 0x7f, 0x2f, 0x03, 0x05, 0x71, 0xd0, 0x52, 0x17, 0xb1,
+	0x0e, 0x0b, 0x51, 0x09, 0x41, 0x24, 0x7e, 0x6f, 0x5f, 0x9e, 0xa4, 0xd5, 0x64, 0x4e, 0x25, 0xb6,
+	0x66, 0x24, 0x57, 0x7d, 0x1f, 0x2a, 0x49, 0xc6, 0xe7, 0xda, 0x98, 0xdf, 0x85, 0x32, 0xdb, 0xfb,
+	0x51, 0xb2, 0xf6, 0x08, 0x0a, 0xc2, 0x59, 0xc4, 0xf7, 0xd0, 0xe5, 0x19, 0xa3, 0x44, 0xa2, 0x27,
+	0xb0, 0x20, 0xb2, 0xcc, 0xa8, 0x72, 0xbc, 0x76, 0xf5, 0x09, 0xc3, 0x11, 0x5c, 0xfd, 0x10, 0x72,
+	0x5d, 0x42, 0x7c, 0x66, 0x7b, 0x8f, 0xda, 0x64, 0x7a, 0x75, 0xcb, 0x04, 0xd9, 0x26, 0xad, 0x26,
+	0x4b, 0x90, 0x6d, 0xd2, 0xb2, 0xe3, 0xda, 0x58, 0x36, 0x51, 0x1b, 0xeb, 0x43, 0xe5, 0x05, 0x71,
+	0x06, 0x07, 0x21, 0xb1, 0xb9, 0xa2, 0x77, 0x21, 0x37, 0x22, 0xf1, 0xe0, 0x57, 0x53, 0x37, 0x1f,
+	0x21, 0x3e, 0xe6, 0x28, 0xe6, 0x63, 0x8e, 0xb9, 0xb4, 0x7c, 0xee, 0x90, 0x2d, 0xf5, 0x1f, 0xb2,
+	0xb0, 0xd4, 0x0a, 0x82, 0xb1, 0xe9, 0x59, 0x51, 0x54, 0xf7, 0xcd, 0x8b, 0x51, 0x5d, 0xea, 0xbb,
+	0xd0, 0x45, 0x91, 0x8b, 0x25, 0x3f, 0x79, 0xb3, 0x66, 0xe3, 0x9b, 0x55, 0xfd, 0x71, 0x26, 0xaa,
+	0xeb, 0xdd, 0x4d, 0xb8, 0x02, 0x91, 0x23, 0x26, 0x35, 0x91, 0x5d, 0xef, 0xd0, 0xa3, 0xc7, 0x1e,
+	0x7a, 0x03, 0xf2, 0x58, 0x6f, 0xeb, 0x2f, 0x94, 0x8c, 0xd8, 0x9e, 0x17, 0x40, 0x98, 0x78, 0xe4,
+	0x98, 0x69, 0xea, 0xea, 0xed, 0x26, 0x8b, 0xc2, 0xb2, 0x29, 0x9a, 0xba, 0xc4, 0xb3, 0x1d, 0x6f,
+	0x80, 0xde, 0x84, 0x42, 0xab, 0xd7, 0xdb, 0xe5, 0x29, 0xe4, 0x6b, 0x27, 0xa7, 0x1b, 0x37, 0x2f,
+	0xa0, 0x78, 0x4d, 0xd7, 0x66, 0x20, 0x96, 0x02, 0xb1, 0xf8, 0x2c, 0x05, 0xc4, 0x62, 0x6b, 0x01,
+	0xc2, 0x9d, 0x7e, 0xbd, 0xaf, 0x2b, 0xf9, 0x14, 0x10, 0xa6, 0xec, 0xaf, 0x3c, 0x6e, 0xff, 0x92,
+	0x05, 0xa5, 0x6e, 0x59, 0x64, 0x14, 0x32, 0xbe, 0xcc, 0x3a, 0xfb, 0x50, 0x1c, 0xb1, 0x5f, 0x0e,
+	0x89, 0x22, 0xa8, 0x27, 0xa9, 0x2f, 0x9b, 0x33, 0x72, 0x35, 0x4c, 0x5d, 0x52, 0xb7, 0x87, 0x4e,
+	0x10, 0x38, 0xd4, 0x13, 0x34, 0x1c, 0x6b, 0xaa, 0xfe, 0x67, 0x06, 0x6e, 0xa6, 0x20, 0xd0, 0x03,
+	0xc8, 0xf9, 0xd4, 0x8d, 0xd6, 0xf0, 0xce, 0x65, 0x25, 0x5b, 0x26, 0x8a, 0x39, 0x12, 0xad, 0x01,
+	0x98, 0xe3, 0x90, 0x9a, 0xbc, 0x7f, 0xbe, 0x7a, 0x45, 0x9c, 0xa0, 0xa0, 0x17, 0x50, 0x08, 0x88,
+	0xe5, 0x93, 0x28, 0xce, 0xfe, 0xf0, 0xff, 0x3a, 0xfa, 0x5a, 0x8f, 0xab, 0xc1, 0x52, 0x5d, 0xb5,
+	0x06, 0x05, 0x41, 0x61, 0xdb, 0xde, 0x36, 0x43, 0x53, 0x16, 0xf4, 0xf9, 0x6f, 0xb6, 0x9b, 0x4c,
+	0x77, 0x10, 0xed, 0x26, 0xd3, 0x1d, 0xa8, 0x7f, 0x93, 0x05, 0xd0, 0x5f, 0x86, 0xc4, 0xf7, 0x4c,
+	0x57, 0xab, 0x23, 0x3d, 0x71, 0x33, 0x88, 0xd9, 0x7e, 0x39, 0xf5, 0x95, 0x22, 0x96, 0xa8, 0x69,
+	0xf5, 0x94, 0xbb, 0xe1, 0x36, 0xcc, 0x8f, 0x7d, 0xf9, 0x58, 0x2d, 0x62, 0xe4, 0x5d, 0xbc, 0x8d,
+	0x19, 0x0d, 0xe9, 0x53, 0xb7, 0x35, 0x7f, 0xf9, 0x93, 0x74, 0xa2, 0x83, 0x54, 0xd7, 0xc5, 0x4e,
+	0xbe, 0x65, 0x1a, 0x16, 0x91, 0xb7, 0x4a, 0x45, 0x9c, 0x7c, 0xad, 0xae, 0x11, 0x3f, 0xc4, 0x05,
+	0xcb, 0x64, 0xff, 0x7f, 0x22, 0xff, 0xf6, 0x2e, 0xc0, 0x74, 0x6a, 0x68, 0x0d, 0xf2, 0xda, 0x66,
+	0xaf, 0xb7, 0xad, 0xcc, 0x09, 0x07, 0x3e, 0x65, 0x71, 0xb2, 0xfa, 0x97, 0x59, 0x28, 0x6a, 0x75,
+	0x79, 0xe5, 0x6a, 0xa0, 0x70, 0xaf, 0xc4, 0x9f, 0x41, 0xc8, 0xcb, 0x91, 0xe3, 0x4f, 0xa4, 0x63,
+	0xb9, 0x22, 0xe1, 0x5d, 0x62, 0x22, 0x6c, 0xd4, 0x3a, 0x17, 0x40, 0x18, 0x2a, 0x44, 0x1a, 0xc1,
+	0xb0, 0xcc, 0xc8, 0xc7, 0xaf, 0x5d, 0x6d, 0x2c, 0x91, 0xba, 0x4c, 0xdb, 0x01, 0x2e, 0x47, 0x4a,
+	0x34, 0x33, 0x40, 0xef, 0xc1, 0x72, 0xe0, 0x0c, 0x3c, 0xc7, 0x1b, 0x18, 0x91, 0xf1, 0xf8, 0x9b,
+	0x4c, 0xe3, 0xc6, 0xf9, 0xd9, 0xfa, 0x62, 0x4f, 0xb0, 0xa4, 0x0d, 0x17, 0x25, 0x52, 0xe3, 0xa6,
+	0x44, 0x5f, 0x87, 0xa5, 0x84, 0x28, 0xb3, 0xa2, 0x30, 0xbb, 0x72, 0x7e, 0xb6, 0x5e, 0x89, 0x25,
+	0x9f, 0x91, 0x09, 0xae, 0xc4, 0x82, 0xcf, 0x08, 0xaf, 0xcd, 0xec, 0x53, 0xdf, 0x22, 0x86, 0xcf,
+	0xcf, 0x34, 0xbf, 0xdd, 0x73, 0xb8, 0xcc, 0x69, 0xe2, 0x98, 0xab, 0xcf, 0xe1, 0x66, 0xc7, 0xb7,
+	0x0e, 0x48, 0x10, 0x0a, 0x53, 0x48, 0x2b, 0x7e, 0x08, 0x77, 0x42, 0x33, 0x38, 0x34, 0x0e, 0x9c,
+	0x20, 0xa4, 0xfe, 0xc4, 0xf0, 0x49, 0x48, 0x3c, 0xc6, 0x37, 0xf8, 0x43, 0xae, 0x2c, 0x08, 0xde,
+	0x66, 0x98, 0x2d, 0x01, 0xc1, 0x11, 0x62, 0x9b, 0x01, 0xd4, 0x16, 0x54, 0x58, 0x0a, 0x23, 0x8b,
+	0x6a, 0x6c, 0xf6, 0xe0, 0xd2, 0x81, 0xf1, 0x99, 0xaf, 0xa9, 0x92, 0x4b, 0x07, 0xe2, 0xa7, 0xfa,
+	0x6d, 0x50, 0x9a, 0x4e, 0x30, 0x32, 0x43, 0xeb, 0x20, 0xaa, 0x74, 0xa2, 0x26, 0x28, 0x07, 0xc4,
+	0xf4, 0xc3, 0x3d, 0x62, 0x86, 0xc6, 0x88, 0xf8, 0x0e, 0xb5, 0xaf, 0x5f, 0xe5, 0xe5, 0x58, 0xa4,
+	0xcb, 0x25, 0xd4, 0xff, 0xce, 0x00, 0x60, 0x73, 0x3f, 0x8a, 0xd6, 0xbe, 0x02, 0x37, 0x02, 0xcf,
+	0x1c, 0x05, 0x07, 0x34, 0x34, 0x1c, 0x2f, 0x24, 0xfe, 0x91, 0xe9, 0xca, 0xe2, 0x8e, 0x12, 0x31,
+	0x5a, 0x92, 0x8e, 0xde, 0x05, 0x74, 0x48, 0xc8, 0xc8, 0xa0, 0xae, 0x6d, 0x44, 0x4c, 0xf1, 0xcc,
+	0x9c, 0xc3, 0x0a, 0xe3, 0x74, 0x5c, 0xbb, 0x17, 0xd1, 0x51, 0x03, 0xd6, 0xd8, 0xf4, 0x89, 0x17,
+	0xfa, 0x0e, 0x09, 0x8c, 0x7d, 0xea, 0x1b, 0x81, 0x4b, 0x8f, 0x8d, 0x7d, 0xea, 0xba, 0xf4, 0x98,
+	0xf8, 0x51, 0xdd, 0xac, 0xea, 0xd2, 0x81, 0x2e, 0x40, 0x9b, 0xd4, 0xef, 0xb9, 0xf4, 0x78, 0x33,
+	0x42, 0xb0, 0x90, 0x6e, 0x3a, 0xe7, 0xd0, 0xb1, 0x0e, 0xa3, 0x90, 0x2e, 0xa6, 0xf6, 0x1d, 0xeb,
+	0x10, 0xbd, 0x09, 0x8b, 0xc4, 0x25, 0xbc, 0x7c, 0x22, 0x50, 0x79, 0x8e, 0xaa, 0x44, 0x44, 0x06,
+	0x52, 0x3f, 0x02, 0x45, 0xf7, 0x2c, 0x7f, 0x32, 0x4a, 0xac, 0xf9, 0xbb, 0x80, 0x98, 0x93, 0x34,
+	0x5c, 0x6a, 0x1d, 0x1a, 0x43, 0xd3, 0x33, 0x07, 0x6c, 0x5c, 0xe2, 0xf5, 0x4f, 0x61, 0x9c, 0x6d,
+	0x6a, 0x1d, 0xee, 0x48, 0xba, 0xfa, 0x1e, 0x40, 0x6f, 0xe4, 0x13, 0xd3, 0xee, 0xb0, 0x68, 0x82,
+	0x99, 0x8e, 0xb7, 0x0c, 0x5b, 0xbe, 0x9e, 0x52, 0x5f, 0x1e, 0x75, 0x45, 0x30, 0x9a, 0x31, 0x5d,
+	0xfd, 0x59, 0xb8, 0xd9, 0x75, 0x4d, 0x8b, 0x7f, 0x49, 0xd0, 0x8d, 0x9f, 0xb3, 0xd0, 0x13, 0x28,
+	0x08, 0xa8, 0x5c, 0xc9, 0xd4, 0xe3, 0x36, 0xed, 0x73, 0x6b, 0x0e, 0x4b, 0x7c, 0xa3, 0x02, 0x30,
+	0xd5, 0xa3, 0xfe, 0x79, 0x06, 0x4a, 0xb1, 0x7e, 0xb4, 0x21, 0x5e, 0x69, 0x42, 0xdf, 0x74, 0x3c,
+	0x99, 0xf1, 0x97, 0x70, 0x92, 0x84, 0x5a, 0x50, 0x1e, 0xc5, 0xd2, 0x57, 0xc6, 0x73, 0x29, 0xa3,
+	0xc6, 0x49, 0x59, 0xf4, 0x3e, 0x94, 0xa2, 0xe7, 0xea, 0xc8, 0xc3, 0x5e, 0xfd, 0xba, 0x3d, 0x85,
+	0xab, 0xdf, 0x04, 0xf8, 0x16, 0x75, 0xbc, 0x3e, 0x3d, 0x24, 0x1e, 0x7f, 0x7e, 0x65, 0xf9, 0x22,
+	0x89, 0xac, 0x28, 0x5b, 0xbc, 0x0c, 0x20, 0x96, 0x20, 0x7e, 0x85, 0x14, 0x4d, 0xf5, 0xaf, 0xb3,
+	0x50, 0xc0, 0x94, 0x86, 0x5a, 0x1d, 0x6d, 0x40, 0x41, 0xfa, 0x09, 0x7e, 0xff, 0x34, 0x4a, 0xe7,
+	0x67, 0xeb, 0x79, 0xe1, 0x20, 0xf2, 0x16, 0xf7, 0x0c, 0x09, 0x0f, 0x9e, 0xbd, 0xcc, 0x83, 0xa3,
+	0x07, 0x50, 0x91, 0x20, 0xe3, 0xc0, 0x0c, 0x0e, 0x44, 0xf2, 0xd6, 0x58, 0x3a, 0x3f, 0x5b, 0x07,
+	0x81, 0xdc, 0x32, 0x83, 0x03, 0x0c, 0x02, 0xcd, 0x7e, 0x23, 0x1d, 0xca, 0x1f, 0x53, 0xc7, 0x33,
+	0x42, 0x3e, 0x09, 0x59, 0x68, 0x4c, 0x5d, 0xc7, 0xe9, 0x54, 0xe5, 0xb7, 0x08, 0xf0, 0xf1, 0x74,
+	0xf2, 0x3a, 0x2c, 0xfa, 0x94, 0x86, 0xc2, 0x6d, 0x39, 0xd4, 0x93, 0x35, 0x8c, 0x8d, 0xd4, 0xd2,
+	0x36, 0xa5, 0x21, 0x96, 0x38, 0x5c, 0xf1, 0x13, 0x2d, 0xf4, 0x00, 0x56, 0x5c, 0x33, 0x08, 0x0d,
+	0xee, 0xef, 0xec, 0xa9, 0xb6, 0x02, 0x3f, 0x6a, 0x88, 0xf1, 0x36, 0x39, 0x2b, 0x92, 0x50, 0xff,
+	0x29, 0x03, 0x65, 0x36, 0x19, 0x67, 0xdf, 0xb1, 0x58, 0x90, 0xf7, 0xf9, 0x63, 0x8f, 0xdb, 0x30,
+	0x6f, 0x05, 0xbe, 0x34, 0x2a, 0xbf, 0x7c, 0xb5, 0x1e, 0xc6, 0x8c, 0x86, 0x3e, 0x82, 0x82, 0xac,
+	0xa5, 0x88, 0xb0, 0x43, 0xbd, 0x3e, 0x1c, 0x95, 0xb6, 0x91, 0x72, 0x7c, 0x2f, 0x4f, 0x47, 0x27,
+	0x2e, 0x01, 0x9c, 0x24, 0xa1, 0x5b, 0x90, 0xb5, 0x84, 0xb9, 0xe4, 0xc7, 0x2e, 0x5a, 0x1b, 0x67,
+	0x2d, 0x4f, 0xfd, 0x41, 0x06, 0x16, 0xa7, 0x07, 0x9e, 0xed, 0x80, 0x3b, 0x50, 0x0a, 0xc6, 0x7b,
+	0xc1, 0x24, 0x08, 0xc9, 0x30, 0x7a, 0x5a, 0x8e, 0x09, 0xa8, 0x05, 0x25, 0xd3, 0x1d, 0x50, 0xdf,
+	0x09, 0x0f, 0x86, 0x32, 0x4b, 0x4d, 0x0f, 0x15, 0x92, 0x3a, 0x6b, 0xf5, 0x48, 0x04, 0x4f, 0xa5,
+	0xa3, 0x7b, 0x5f, 0x7c, 0x7f, 0xc0, 0xef, 0xfd, 0x37, 0xa0, 0xe2, 0x9a, 0x43, 0x5e, 0x5c, 0x0a,
+	0x9d, 0xa1, 0x98, 0x47, 0x0e, 0x97, 0x25, 0xad, 0xef, 0x0c, 0x89, 0xaa, 0x42, 0x29, 0x56, 0x86,
+	0x96, 0xa1, 0x5c, 0xd7, 0x7b, 0xc6, 0xc3, 0x47, 0x4f, 0x8c, 0xa7, 0xda, 0x8e, 0x32, 0x27, 0x63,
+	0xd3, 0xbf, 0xc8, 0xc0, 0xa2, 0x74, 0x47, 0x32, 0xde, 0x7f, 0x13, 0x16, 0x7c, 0x73, 0x3f, 0x8c,
+	0x32, 0x92, 0x9c, 0xd8, 0xd5, 0xcc, 0xc3, 0xb3, 0x8c, 0x84, 0xb1, 0xd2, 0x33, 0x92, 0xc4, 0xc7,
+	0x0e, 0xf3, 0x57, 0x7e, 0xec, 0x90, 0xfb, 0xa9, 0x7c, 0xec, 0xa0, 0xfe, 0x0a, 0xc0, 0xa6, 0xe3,
+	0x92, 0xbe, 0xa8, 0x43, 0xa5, 0xe5, 0x97, 0x2c, 0x86, 0x93, 0x75, 0xce, 0x28, 0x86, 0x6b, 0x35,
+	0x31, 0xa3, 0x31, 0xd6, 0xc0, 0xb1, 0xe5, 0x61, 0xe4, 0xac, 0xa7, 0x8c, 0x35, 0x70, 0xec, 0xf8,
+	0x55, 0x2e, 0x77, 0xdd, 0xab, 0xdc, 0x69, 0x06, 0x96, 0x65, 0xec, 0x1a, 0xbb, 0xdf, 0x2f, 0x43,
+	0x49, 0x84, 0xb1, 0xd3, 0x84, 0x8e, 0x3f, 0xf0, 0x0b, 0x5c, 0xab, 0x89, 0x8b, 0x82, 0xdd, 0xb2,
+	0xd1, 0x3a, 0x94, 0x25, 0x34, 0xf1, 0x61, 0x14, 0x08, 0x52, 0x9b, 0x0d, 0xff, 0xab, 0x90, 0xdb,
+	0x77, 0x5c, 0x22, 0x37, 0x7a, 0xaa, 0x03, 0x98, 0x1a, 0x60, 0x6b, 0x0e, 0x73, 0x74, 0xa3, 0x18,
+	0x15, 0xea, 0xf8, 0xf8, 0x64, 0xda, 0x99, 0x1c, 0x9f, 0xc8, 0x40, 0x67, 0xc6, 0x27, 0x70, 0x6c,
+	0x7c, 0x82, 0x2d, 0xc6, 0x27, 0xa1, 0xc9, 0xf1, 0x09, 0xd2, 0x4f, 0x65, 0x7c, 0xdb, 0x70, 0xab,
+	0xe1, 0x9a, 0xd6, 0xa1, 0xeb, 0x04, 0x21, 0xb1, 0x93, 0x1e, 0xe3, 0x11, 0x14, 0x2e, 0x04, 0x9d,
+	0x57, 0x55, 0x34, 0x25, 0x52, 0xfd, 0xf7, 0x0c, 0x54, 0xb6, 0x88, 0xe9, 0x86, 0x07, 0xd3, 0xb2,
+	0x51, 0x48, 0x82, 0x50, 0x5e, 0x56, 0xfc, 0x37, 0xfa, 0x1a, 0x14, 0xe3, 0x98, 0xe4, 0xda, 0xb7,
+	0xb9, 0x18, 0x8a, 0x1e, 0xc3, 0x02, 0x3b, 0x63, 0x74, 0x1c, 0x25, 0x3b, 0x57, 0x3d, 0xfb, 0x48,
+	0x24, 0xbb, 0x64, 0x7c, 0xc2, 0x83, 0x10, 0xbe, 0x95, 0xf2, 0x38, 0x6a, 0xa2, 0xff, 0x0f, 0x15,
+	0xfe, 0x6a, 0x11, 0xc5, 0x5c, 0xf9, 0xeb, 0x74, 0x96, 0xc5, 0xc3, 0xa3, 0x88, 0xb7, 0xfe, 0x38,
+	0x0b, 0x2b, 0x3b, 0xe6, 0x64, 0x8f, 0x48, 0xb7, 0x41, 0x6c, 0x4c, 0x2c, 0xea, 0xdb, 0xa8, 0x9b,
+	0x74, 0x37, 0x57, 0xbc, 0x63, 0xa6, 0x09, 0xa7, 0x7b, 0x9d, 0x28, 0x01, 0xcb, 0x26, 0x12, 0xb0,
+	0x15, 0xc8, 0x7b, 0xd4, 0xb3, 0x88, 0xf4, 0x45, 0xa2, 0xa1, 0xfe, 0x76, 0x26, 0xe9, 0x6b, 0xaa,
+	0xf1, 0x1b, 0x23, 0xaf, 0x40, 0xb5, 0x69, 0x18, 0x77, 0x87, 0x3e, 0x82, 0x6a, 0x4f, 0xd7, 0xb0,
+	0xde, 0x6f, 0x74, 0xbe, 0x6d, 0xf4, 0xea, 0xdb, 0xbd, 0xfa, 0xa3, 0x07, 0x46, 0xb7, 0xb3, 0xfd,
+	0x9d, 0x87, 0x8f, 0x1f, 0x7c, 0x4d, 0xc9, 0x54, 0x37, 0x4e, 0x4e, 0x37, 0xee, 0xb4, 0xeb, 0xda,
+	0xb6, 0x38, 0x32, 0x7b, 0xf4, 0x65, 0xcf, 0x74, 0x03, 0xf3, 0xd1, 0x83, 0x2e, 0x75, 0x27, 0x0c,
+	0x83, 0xbe, 0x02, 0x68, 0x53, 0xc7, 0x6d, 0xbd, 0x6f, 0x44, 0x0e, 0x4d, 0x6b, 0x68, 0x4a, 0x56,
+	0xa4, 0x35, 0x9b, 0xc4, 0xf7, 0x48, 0x58, 0xd7, 0x7b, 0x0f, 0x1f, 0x3d, 0xd1, 0x1a, 0x1a, 0x3b,
+	0x04, 0x95, 0xe4, 0xed, 0x96, 0xbc, 0xb4, 0x33, 0x97, 0x5e, 0xda, 0xd3, 0xbb, 0x3f, 0x7b, 0xc9,
+	0xdd, 0xbf, 0x09, 0x2b, 0x96, 0x4f, 0x83, 0xc0, 0x60, 0xb9, 0x02, 0xb1, 0x67, 0xb2, 0x91, 0x2f,
+	0x9c, 0x9f, 0xad, 0xdf, 0xd0, 0x18, 0xbf, 0xc7, 0xd9, 0x52, 0xfd, 0x0d, 0x2b, 0x41, 0xe2, 0x3d,
+	0xa9, 0xbf, 0x3f, 0xcf, 0xc2, 0x2e, 0xe7, 0xc8, 0x71, 0xc9, 0x80, 0x04, 0xe8, 0x39, 0x2c, 0x5b,
+	0x3e, 0xb1, 0x59, 0x12, 0x60, 0xba, 0xc9, 0xcf, 0x71, 0xff, 0x5f, 0x6a, 0x04, 0x14, 0x0b, 0xd6,
+	0xb4, 0x58, 0xaa, 0x37, 0x22, 0x16, 0x5e, 0xb2, 0x2e, 0xb4, 0xd1, 0xc7, 0xb0, 0x1c, 0x10, 0xd7,
+	0xf1, 0xc6, 0x2f, 0x0d, 0x8b, 0x7a, 0x21, 0x79, 0x19, 0xbd, 0xad, 0x5d, 0xa7, 0xb7, 0xa7, 0x6f,
+	0x33, 0x29, 0x4d, 0x08, 0x35, 0xd0, 0xf9, 0xd9, 0xfa, 0xd2, 0x45, 0x1a, 0x5e, 0x92, 0x9a, 0x65,
+	0xbb, 0xda, 0x86, 0xa5, 0x8b, 0xa3, 0x41, 0x2b, 0xd2, 0x53, 0x70, 0x87, 0x13, 0x79, 0x02, 0x74,
+	0x07, 0x8a, 0x3e, 0x19, 0x38, 0x41, 0xe8, 0x0b, 0x33, 0x33, 0x4e, 0x4c, 0x61, 0x7e, 0x42, 0x7c,
+	0x4b, 0x55, 0xfd, 0x25, 0x98, 0xe9, 0x91, 0x1d, 0x2d, 0xdb, 0x09, 0xcc, 0x3d, 0xa9, 0xb2, 0x88,
+	0xa3, 0x26, 0xdb, 0xb1, 0xe3, 0x20, 0x0e, 0xeb, 0xf8, 0x6f, 0x46, 0xe3, 0xf1, 0x87, 0xfc, 0xb2,
+	0x8c, 0x47, 0x18, 0xd1, 0x27, 0xaa, 0xb9, 0xc4, 0x27, 0xaa, 0x2b, 0x90, 0x77, 0xc9, 0x11, 0x71,
+	0xc5, 0xcd, 0x8f, 0x45, 0xe3, 0xde, 0x03, 0xa8, 0x44, 0xdf, 0x42, 0xf2, 0x6f, 0x30, 0x8a, 0x90,
+	0xeb, 0xd7, 0x7b, 0xcf, 0x94, 0x39, 0x04, 0x50, 0x10, 0x3b, 0x59, 0xbc, 0xfb, 0x69, 0x9d, 0xf6,
+	0x66, 0xeb, 0xa9, 0x92, 0xbd, 0xf7, 0x3b, 0x39, 0x28, 0xc5, 0x2f, 0x4f, 0xec, 0xa6, 0x69, 0xeb,
+	0x2f, 0xa2, 0xa3, 0x10, 0xd3, 0xdb, 0xe4, 0x18, 0xbd, 0x31, 0xad, 0x59, 0x7d, 0x24, 0x9e, 0xda,
+	0x63, 0x76, 0x54, 0xaf, 0x7a, 0x0b, 0x8a, 0xf5, 0x5e, 0xaf, 0xf5, 0xb4, 0xad, 0x37, 0x95, 0x4f,
+	0x33, 0xd5, 0x2f, 0x9c, 0x9c, 0x6e, 0xdc, 0x88, 0x41, 0xf5, 0x40, 0x6c, 0x3e, 0x8e, 0xd2, 0x34,
+	0xbd, 0xdb, 0xd7, 0x9b, 0xca, 0x27, 0xd9, 0x59, 0x14, 0xaf, 0xc1, 0xf0, 0x8f, 0x80, 0x4a, 0x5d,
+	0xac, 0x77, 0xeb, 0x98, 0x75, 0xf8, 0x69, 0x56, 0x94, 0xd2, 0xa6, 0x3d, 0xfa, 0x64, 0x64, 0xfa,
+	0xac, 0xcf, 0xb5, 0xe8, 0xab, 0xba, 0x4f, 0xe6, 0xc5, 0x87, 0x22, 0xd3, 0x67, 0x34, 0x62, 0xda,
+	0x13, 0xd6, 0x1b, 0x7f, 0xbf, 0xe4, 0x6a, 0xe6, 0x67, 0x7a, 0xeb, 0x31, 0x4f, 0xc5, 0xb4, 0xa8,
+	0xb0, 0x80, 0x77, 0xdb, 0x6d, 0x06, 0xfa, 0x24, 0x37, 0x33, 0x3b, 0x3c, 0xf6, 0x58, 0x7e, 0x8d,
+	0xee, 0x42, 0x31, 0x7a, 0xde, 0x54, 0x3e, 0xcd, 0xcd, 0x0c, 0x48, 0x8b, 0xde, 0x66, 0x79, 0x87,
+	0x5b, 0xbb, 0x7d, 0xfe, 0xd1, 0xdf, 0x27, 0xf9, 0xd9, 0x0e, 0x0f, 0xc6, 0xa1, 0x4d, 0x8f, 0x3d,
+	0x76, 0x66, 0x65, 0xd5, 0xee, 0xd3, 0xbc, 0xf0, 0x05, 0x31, 0x46, 0x96, 0xec, 0xde, 0x82, 0x22,
+	0xd6, 0xbf, 0x25, 0xbe, 0x0f, 0xfc, 0xa4, 0x30, 0xa3, 0x07, 0x93, 0x8f, 0x89, 0xc5, 0x7a, 0xdb,
+	0x80, 0x02, 0xd6, 0x77, 0x3a, 0xcf, 0x75, 0xe5, 0x0f, 0x0a, 0x33, 0x7a, 0x30, 0x19, 0x52, 0xfe,
+	0x95, 0x54, 0xb1, 0x83, 0xbb, 0x5b, 0x75, 0xbe, 0x28, 0xb3, 0x7a, 0x3a, 0xfe, 0xe8, 0xc0, 0xf4,
+	0x88, 0x3d, 0xfd, 0x9e, 0x26, 0x66, 0xdd, 0xfb, 0x39, 0x28, 0x46, 0x91, 0x2e, 0x5a, 0x83, 0xc2,
+	0x8b, 0x0e, 0x7e, 0xa6, 0x63, 0x65, 0x4e, 0x58, 0x39, 0xe2, 0xbc, 0x10, 0x39, 0xca, 0x06, 0x2c,
+	0xec, 0xd4, 0xdb, 0xf5, 0xa7, 0x3a, 0x8e, 0x4a, 0xee, 0x11, 0x40, 0x86, 0x6b, 0x55, 0x45, 0x76,
+	0x10, 0xeb, 0x6c, 0xac, 0x7e, 0xff, 0x47, 0x6b, 0x73, 0x3f, 0xfc, 0xd1, 0xda, 0xdc, 0x27, 0xe7,
+	0x6b, 0x99, 0xef, 0x9f, 0xaf, 0x65, 0xfe, 0xfe, 0x7c, 0x2d, 0xf3, 0x6f, 0xe7, 0x6b, 0x99, 0xbd,
+	0x02, 0xbf, 0x54, 0x1e, 0xff, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x92, 0xe0, 0x5d, 0x4a, 0x5c,
+	0x32, 0x00, 0x00,
 }

+ 1 - 0
vendor/github.com/docker/swarmkit/api/types.proto

@@ -1035,6 +1035,7 @@ message MaybeEncryptedRecord {
 	enum Algorithm {
 		NONE = 0 [(gogoproto.enumvalue_customname) = "NotEncrypted"];
 		SECRETBOX_SALSA20_POLY1305 = 1 [(gogoproto.enumvalue_customname) = "NACLSecretboxSalsa20Poly1305"];
+		FERNET_AES_128_CBC = 2 [(gogoproto.enumvalue_customname) = "FernetAES128CBC"];
 	}
 
 	Algorithm algorithm = 1;

+ 5 - 64
vendor/github.com/docker/swarmkit/ca/certificates.go

@@ -29,6 +29,7 @@ import (
 	"github.com/docker/swarmkit/ca/keyutils"
 	"github.com/docker/swarmkit/ca/pkcs8"
 	"github.com/docker/swarmkit/connectionbroker"
+	"github.com/docker/swarmkit/fips"
 	"github.com/docker/swarmkit/ioutils"
 	"github.com/opencontainers/go-digest"
 	"github.com/pkg/errors"
@@ -51,13 +52,6 @@ const (
 	RootKeySize = 256
 	// RootKeyAlgo defines the default algorithm for the root CA Key
 	RootKeyAlgo = "ecdsa"
-	// PassphraseENVVar defines the environment variable to look for the
-	// root CA private key material encryption key
-	PassphraseENVVar = "SWARM_ROOT_CA_PASSPHRASE"
-	// PassphraseENVVarPrev defines the alternate environment variable to look for the
-	// root CA private key material encryption key. It can be used for seamless
-	// KEK rotations.
-	PassphraseENVVarPrev = "SWARM_ROOT_CA_PASSPHRASE_PREV"
 	// RootCAExpiration represents the default expiration for the root CA in seconds (20 years)
 	RootCAExpiration = "630720000s"
 	// DefaultNodeCertExpiration represents the default expiration for node certificates (3 months)
@@ -641,28 +635,10 @@ func newLocalSigner(keyBytes, certBytes []byte, certExpiry time.Duration, rootPo
 		return nil, errors.Wrap(err, "error while validating signing CA certificate against roots and intermediates")
 	}
 
-	var (
-		passphraseStr              string
-		passphrase, passphrasePrev []byte
-		priv                       crypto.Signer
-	)
-
-	// Attempt two distinct passphrases, so we can do a hitless passphrase rotation
-	if passphraseStr = os.Getenv(PassphraseENVVar); passphraseStr != "" {
-		passphrase = []byte(passphraseStr)
-	}
-
-	if p := os.Getenv(PassphraseENVVarPrev); p != "" {
-		passphrasePrev = []byte(p)
-	}
-
-	// Attempt to decrypt the current private-key with the passphrases provided
-	priv, err = keyutils.ParsePrivateKeyPEMWithPassword(keyBytes, passphrase)
+	// The key should not be encrypted, but it could be in PKCS8 format rather than PKCS1
+	priv, err := keyutils.ParsePrivateKeyPEMWithPassword(keyBytes, nil)
 	if err != nil {
-		priv, err = keyutils.ParsePrivateKeyPEMWithPassword(keyBytes, passphrasePrev)
-		if err != nil {
-			return nil, errors.Wrap(err, "malformed private key")
-		}
+		return nil, errors.Wrap(err, "malformed private key")
 	}
 
 	// We will always use the first certificate inside of the root bundle as the active one
@@ -675,17 +651,6 @@ func newLocalSigner(keyBytes, certBytes []byte, certExpiry time.Duration, rootPo
 		return nil, err
 	}
 
-	// If the key was loaded from disk unencrypted, but there is a passphrase set,
-	// ensure it is encrypted, so it doesn't hit raft in plain-text
-	// we don't have to check for nil, because if we couldn't pem-decode the bytes, then parsing above would have failed
-	keyBlock, _ := pem.Decode(keyBytes)
-	if passphraseStr != "" && !keyutils.IsEncryptedPEMBlock(keyBlock) {
-		keyBytes, err = EncryptECPrivateKey(keyBytes, passphraseStr)
-		if err != nil {
-			return nil, errors.Wrap(err, "unable to encrypt signing CA key material")
-		}
-	}
-
 	return &LocalSigner{Cert: certBytes, Key: keyBytes, Signer: signer, parsedCert: parsedCerts[0], cryptoSigner: priv}, nil
 }
 
@@ -818,7 +783,7 @@ func CreateRootCA(rootCN string) (RootCA, error) {
 	}
 
 	// Convert key to PKCS#8 in FIPS mode
-	if keyutils.FIPSEnabled() {
+	if fips.Enabled() {
 		key, err = pkcs8.ConvertECPrivateKeyPEM(key)
 		if err != nil {
 			return RootCA{}, err
@@ -976,30 +941,6 @@ func GenerateNewCSR() ([]byte, []byte, error) {
 	return csr, key, err
 }
 
-// EncryptECPrivateKey receives a PEM encoded private key and returns an encrypted
-// AES256 version using a passphrase
-// TODO: Make this method generic to handle RSA keys
-func EncryptECPrivateKey(key []byte, passphraseStr string) ([]byte, error) {
-	passphrase := []byte(passphraseStr)
-
-	keyBlock, _ := pem.Decode(key)
-	if keyBlock == nil {
-		// This RootCA does not have a valid signer.
-		return nil, errors.New("error while decoding PEM key")
-	}
-
-	encryptedPEMBlock, err := keyutils.EncryptPEMBlock(keyBlock.Bytes, passphrase)
-	if err != nil {
-		return nil, err
-	}
-
-	if encryptedPEMBlock.Headers == nil {
-		return nil, errors.New("unable to encrypt key - invalid PEM file produced")
-	}
-
-	return pem.EncodeToMemory(encryptedPEMBlock), nil
-}
-
 // NormalizePEMs takes a bundle of PEM-encoded certificates in a certificate bundle,
 // decodes them, removes headers, and re-encodes them to make sure that they have
 // consistent whitespace.  Note that this is intended to normalize x509 certificates

+ 5 - 13
vendor/github.com/docker/swarmkit/ca/keyutils/keyutils.go

@@ -10,22 +10,14 @@ import (
 	"crypto/x509"
 	"encoding/pem"
 	"errors"
-	"os"
 
 	"github.com/cloudflare/cfssl/helpers"
 	"github.com/docker/swarmkit/ca/pkcs8"
+	"github.com/docker/swarmkit/fips"
 )
 
 var errFIPSUnsupportedKeyFormat = errors.New("unsupported key format due to FIPS compliance")
 
-// FIPSEnvVar is the environment variable which stores FIPS mode state
-const FIPSEnvVar = "GOFIPS"
-
-// FIPSEnabled returns true when FIPS mode is enabled
-func FIPSEnabled() bool {
-	return os.Getenv(FIPSEnvVar) != ""
-}
-
 // IsPKCS8 returns true if the provided der bytes is encrypted/unencrypted PKCS#8 key
 func IsPKCS8(derBytes []byte) bool {
 	if _, err := x509.ParsePKCS8PrivateKey(derBytes); err == nil {
@@ -49,7 +41,7 @@ func ParsePrivateKeyPEMWithPassword(pemBytes, password []byte) (crypto.Signer, e
 
 	if IsPKCS8(block.Bytes) {
 		return pkcs8.ParsePrivateKeyPEMWithPassword(pemBytes, password)
-	} else if FIPSEnabled() {
+	} else if fips.Enabled() {
 		return nil, errFIPSUnsupportedKeyFormat
 	}
 
@@ -59,7 +51,7 @@ func ParsePrivateKeyPEMWithPassword(pemBytes, password []byte) (crypto.Signer, e
 // IsEncryptedPEMBlock checks if a PKCS#1 or PKCS#8 PEM-block is encrypted or not
 // It returns false in FIPS mode even if PKCS#1 is encrypted
 func IsEncryptedPEMBlock(block *pem.Block) bool {
-	return pkcs8.IsEncryptedPEMBlock(block) || (!FIPSEnabled() && x509.IsEncryptedPEMBlock(block))
+	return pkcs8.IsEncryptedPEMBlock(block) || (!fips.Enabled() && x509.IsEncryptedPEMBlock(block))
 }
 
 // DecryptPEMBlock requires PKCS#1 or PKCS#8 PEM Block and password to decrypt and return unencrypted der []byte
@@ -67,7 +59,7 @@ func IsEncryptedPEMBlock(block *pem.Block) bool {
 func DecryptPEMBlock(block *pem.Block, password []byte) ([]byte, error) {
 	if IsPKCS8(block.Bytes) {
 		return pkcs8.DecryptPEMBlock(block, password)
-	} else if FIPSEnabled() {
+	} else if fips.Enabled() {
 		return nil, errFIPSUnsupportedKeyFormat
 	}
 
@@ -79,7 +71,7 @@ func DecryptPEMBlock(block *pem.Block, password []byte) ([]byte, error) {
 func EncryptPEMBlock(data, password []byte) (*pem.Block, error) {
 	if IsPKCS8(data) {
 		return pkcs8.EncryptPEMBlock(data, password)
-	} else if FIPSEnabled() {
+	} else if fips.Enabled() {
 		return nil, errFIPSUnsupportedKeyFormat
 	}
 

+ 11 - 0
vendor/github.com/docker/swarmkit/fips/fips.go

@@ -0,0 +1,11 @@
+package fips
+
+import "os"
+
+// EnvVar is the environment variable which stores FIPS mode state
+const EnvVar = "GOFIPS"
+
+// Enabled returns true when FIPS mode is enabled
+func Enabled() bool {
+	return os.Getenv(EnvVar) != ""
+}

+ 66 - 36
vendor/github.com/docker/swarmkit/manager/allocator/network.go

@@ -118,42 +118,15 @@ func (a *Allocator) doNetworkInit(ctx context.Context) (err error) {
 		return errors.Wrap(err, "failure while looking for ingress network during init")
 	}
 
-	// Allocate networks in the store so far before we started
-	// watching.
-	var networks []*api.Network
-	a.store.View(func(tx store.ReadTx) {
-		networks, err = store.FindNetworks(tx, store.All)
-	})
-	if err != nil {
-		return errors.Wrap(err, "error listing all networks in store while trying to allocate during init")
-	}
-
-	var allocatedNetworks []*api.Network
-	for _, n := range networks {
-		if na.IsAllocated(n) {
-			continue
-		}
-
-		if err := a.allocateNetwork(ctx, n); err != nil {
-			log.G(ctx).WithError(err).Errorf("failed allocating network %s during init", n.ID)
-			continue
-		}
-		allocatedNetworks = append(allocatedNetworks, n)
-	}
-
-	if err := a.store.Batch(func(batch *store.Batch) error {
-		for _, n := range allocatedNetworks {
-			if err := a.commitAllocatedNetwork(ctx, batch, n); err != nil {
-				log.G(ctx).WithError(err).Errorf("failed committing allocation of network %s during init", n.ID)
-			}
-		}
-		return nil
-	}); err != nil {
-		log.G(ctx).WithError(err).Error("failed committing allocation of networks during init")
+	// First, allocate (read it as restore) objects likes network,nodes,serives
+	// and tasks that were already allocated. Then go on the allocate objects
+	// that are in raft and were previously not allocated. The reason being, during
+	// restore, we  make sure that we populate the allocated states of
+	// the objects in the raft onto our in memory state.
+	if err := a.allocateNetworks(ctx, true); err != nil {
+		return err
 	}
 
-	// First, allocate objects that already have addresses associated with
-	// them, to reserve these IP addresses in internal state.
 	if err := a.allocateNodes(ctx, true); err != nil {
 		return err
 	}
@@ -164,6 +137,11 @@ func (a *Allocator) doNetworkInit(ctx context.Context) (err error) {
 	if err := a.allocateTasks(ctx, true); err != nil {
 		return err
 	}
+	// Now allocate objects that were not previously allocated
+	// but were present in the raft.
+	if err := a.allocateNetworks(ctx, false); err != nil {
+		return err
+	}
 
 	if err := a.allocateNodes(ctx, false); err != nil {
 		return err
@@ -184,7 +162,6 @@ func (a *Allocator) doNetworkAlloc(ctx context.Context, ev events.Event) {
 		if nc.nwkAllocator.IsAllocated(n) {
 			break
 		}
-
 		if IsIngressNetwork(n) && nc.ingressNetwork != nil {
 			log.G(ctx).Errorf("Cannot allocate ingress network %s (%s) because another ingress network is already present: %s (%s)",
 				n.ID, n.Spec.Annotations.Name, nc.ingressNetwork.ID, nc.ingressNetwork.Spec.Annotations)
@@ -560,6 +537,60 @@ func (a *Allocator) deallocateNode(node *api.Node) error {
 	return nil
 }
 
+// allocateNetworks allocates (restores) networks in the store so far before we process
+// watched events. existingOnly flags is set to true to specify if only allocated
+// networks need to be restored.
+func (a *Allocator) allocateNetworks(ctx context.Context, existingOnly bool) error {
+	var (
+		nc       = a.netCtx
+		networks []*api.Network
+		err      error
+	)
+	a.store.View(func(tx store.ReadTx) {
+		networks, err = store.FindNetworks(tx, store.All)
+	})
+	if err != nil {
+		return errors.Wrap(err, "error listing all networks in store while trying to allocate during init")
+	}
+
+	var allocatedNetworks []*api.Network
+	for _, n := range networks {
+		if nc.nwkAllocator.IsAllocated(n) {
+			continue
+		}
+		// Network is considered allocated only if the DriverState and IPAM are NOT nil.
+		// During initial restore (existingOnly being true), check the network state in
+		// raft store. If it is allocated, then restore the same in the in memory allocator
+		// state. If it is not allocated, then skip allocating the network at this step.
+		// This is to avoid allocating  an in-use network IP, subnet pool or vxlan id to
+		// another network.
+		if existingOnly &&
+			(n.DriverState == nil ||
+				n.IPAM == nil) {
+			continue
+		}
+
+		if err := a.allocateNetwork(ctx, n); err != nil {
+			log.G(ctx).WithField("existingOnly", existingOnly).WithError(err).Errorf("failed allocating network %s during init", n.ID)
+			continue
+		}
+		allocatedNetworks = append(allocatedNetworks, n)
+	}
+
+	if err := a.store.Batch(func(batch *store.Batch) error {
+		for _, n := range allocatedNetworks {
+			if err := a.commitAllocatedNetwork(ctx, batch, n); err != nil {
+				log.G(ctx).WithError(err).Errorf("failed committing allocation of network %s during init", n.ID)
+			}
+		}
+		return nil
+	}); err != nil {
+		log.G(ctx).WithError(err).Error("failed committing allocation of networks during init")
+	}
+
+	return nil
+}
+
 // allocateServices allocates services in the store so far before we process
 // watched events.
 func (a *Allocator) allocateServices(ctx context.Context, existingAddressesOnly bool) error {
@@ -580,7 +611,6 @@ func (a *Allocator) allocateServices(ctx context.Context, existingAddressesOnly
 		if nc.nwkAllocator.IsServiceAllocated(s, networkallocator.OnInit) {
 			continue
 		}
-
 		if existingAddressesOnly &&
 			(s.Endpoint == nil ||
 				len(s.Endpoint.VirtualIPs) == 0) {

+ 5 - 1
vendor/github.com/docker/swarmkit/manager/controlapi/service.go

@@ -644,7 +644,7 @@ func (s *Server) CreateService(ctx context.Context, request *api.CreateServiceRe
 		return nil, err
 	}
 
-	if err := s.validateNetworks(request.Spec.Networks); err != nil {
+	if err := s.validateNetworks(request.Spec.Task.Networks); err != nil {
 		return nil, err
 	}
 
@@ -727,6 +727,10 @@ func (s *Server) UpdateService(ctx context.Context, request *api.UpdateServiceRe
 		return nil, err
 	}
 
+	if err := s.validateNetworks(request.Spec.Task.Networks); err != nil {
+		return nil, err
+	}
+
 	var service *api.Service
 	s.store.View(func(tx store.ReadTx) {
 		service = store.GetService(tx, request.ServiceID)

+ 17 - 7
vendor/github.com/docker/swarmkit/manager/dispatcher/dispatcher.go

@@ -165,16 +165,10 @@ type Dispatcher struct {
 }
 
 // New returns Dispatcher with cluster interface(usually raft.Node).
-func New(cluster Cluster, c *Config, dp *drivers.DriverProvider, securityConfig *ca.SecurityConfig) *Dispatcher {
+func New() *Dispatcher {
 	d := &Dispatcher{
-		dp:                    dp,
-		nodes:                 newNodeStore(c.HeartbeatPeriod, c.HeartbeatEpsilon, c.GracePeriodMultiplier, c.RateLimitPeriod),
 		downNodes:             newNodeStore(defaultNodeDownPeriod, 0, 1, 0),
-		store:                 cluster.MemoryStore(),
-		cluster:               cluster,
 		processUpdatesTrigger: make(chan struct{}, 1),
-		config:                c,
-		securityConfig:        securityConfig,
 	}
 
 	d.processUpdatesCond = sync.NewCond(&d.processUpdatesLock)
@@ -182,6 +176,21 @@ func New(cluster Cluster, c *Config, dp *drivers.DriverProvider, securityConfig
 	return d
 }
 
+// Init is used to initialize the dispatcher and
+// is typically called before starting the dispatcher
+// when a manager becomes a leader.
+// The dispatcher is a grpc server, and unlike other components,
+// it can't simply be recreated on becoming a leader.
+// This function ensures the dispatcher restarts with a clean slate.
+func (d *Dispatcher) Init(cluster Cluster, c *Config, dp *drivers.DriverProvider, securityConfig *ca.SecurityConfig) {
+	d.cluster = cluster
+	d.config = c
+	d.securityConfig = securityConfig
+	d.dp = dp
+	d.store = cluster.MemoryStore()
+	d.nodes = newNodeStore(c.HeartbeatPeriod, c.HeartbeatEpsilon, c.GracePeriodMultiplier, c.RateLimitPeriod)
+}
+
 func getWeightedPeers(cluster Cluster) []*api.WeightedPeer {
 	members := cluster.GetMemberlist()
 	var mgrs []*api.WeightedPeer
@@ -333,6 +342,7 @@ func (d *Dispatcher) Stop() error {
 	// cancelled and should fail organically.
 	d.rpcRW.Lock()
 	d.nodes.Clean()
+	d.downNodes.Clean()
 	d.rpcRW.Unlock()
 
 	d.processUpdatesLock.Lock()

+ 60 - 1
vendor/github.com/docker/swarmkit/manager/encryption/encryption.go

@@ -8,6 +8,7 @@ import (
 	"strings"
 
 	"github.com/docker/swarmkit/api"
+	"github.com/docker/swarmkit/fips"
 	"github.com/gogo/protobuf/proto"
 	"github.com/pkg/errors"
 )
@@ -59,6 +60,60 @@ func (n noopCrypter) Algorithm() api.MaybeEncryptedRecord_Algorithm {
 // decrypt any data
 var NoopCrypter = noopCrypter{}
 
+// specificDecryptor represents a specific type of Decrypter, like NaclSecretbox or Fernet.
+// It does not apply to a more general decrypter like MultiDecrypter.
+type specificDecrypter interface {
+	Decrypter
+	Algorithm() api.MaybeEncryptedRecord_Algorithm
+}
+
+// MultiDecrypter is a decrypter that will attempt to decrypt with multiple decrypters.  It
+// references them by algorithm, so that only the relevant decrypters are checked instead of
+// every single one. The reason for multiple decrypters per algorithm is to support hitless
+// encryption key rotation.
+//
+// For raft encryption for instance, during an encryption key rotation, it's possible to have
+// some raft logs encrypted with the old key and some encrypted with the new key, so we need a
+// decrypter that can decrypt both.
+type MultiDecrypter struct {
+	decrypters map[api.MaybeEncryptedRecord_Algorithm][]Decrypter
+}
+
+// Decrypt tries to decrypt using any decrypters that match the given algorithm.
+func (m MultiDecrypter) Decrypt(r api.MaybeEncryptedRecord) (result []byte, err error) {
+	decrypters, ok := m.decrypters[r.Algorithm]
+	if !ok {
+		return nil, fmt.Errorf("cannot decrypt record encrypted using %s",
+			api.MaybeEncryptedRecord_Algorithm_name[int32(r.Algorithm)])
+	}
+	for _, d := range decrypters {
+		result, err = d.Decrypt(r)
+		if err == nil {
+			return
+		}
+	}
+	return
+}
+
+// NewMultiDecrypter returns a new MultiDecrypter given multiple Decrypters.  If any of
+// the Decrypters are also MultiDecrypters, they are flattened into a single map, but
+// it does not deduplicate any decrypters.
+// Note that if something is neither a MultiDecrypter nor a specificDecrypter, it is
+// ignored.
+func NewMultiDecrypter(decrypters ...Decrypter) MultiDecrypter {
+	m := MultiDecrypter{decrypters: make(map[api.MaybeEncryptedRecord_Algorithm][]Decrypter)}
+	for _, d := range decrypters {
+		if md, ok := d.(MultiDecrypter); ok {
+			for algo, dec := range md.decrypters {
+				m.decrypters[algo] = append(m.decrypters[algo], dec...)
+			}
+		} else if sd, ok := d.(specificDecrypter); ok {
+			m.decrypters[sd.Algorithm()] = append(m.decrypters[sd.Algorithm()], sd)
+		}
+	}
+	return m
+}
+
 // Decrypt turns a slice of bytes serialized as an MaybeEncryptedRecord into a slice of plaintext bytes
 func Decrypt(encryptd []byte, decrypter Decrypter) ([]byte, error) {
 	if decrypter == nil {
@@ -97,8 +152,12 @@ func Encrypt(plaintext []byte, encrypter Encrypter) ([]byte, error) {
 
 // Defaults returns a default encrypter and decrypter
 func Defaults(key []byte) (Encrypter, Decrypter) {
+	f := NewFernet(key)
+	if fips.Enabled() {
+		return f, f
+	}
 	n := NewNACLSecretbox(key)
-	return n, n
+	return n, NewMultiDecrypter(n, f)
 }
 
 // GenerateSecretKey generates a secret key that can be used for encrypting data

+ 54 - 0
vendor/github.com/docker/swarmkit/manager/encryption/fernet.go

@@ -0,0 +1,54 @@
+package encryption
+
+import (
+	"fmt"
+
+	"github.com/docker/swarmkit/api"
+
+	"github.com/fernet/fernet-go"
+)
+
+// Fernet wraps the `fernet` library as an implementation of encrypter/decrypter.
+type Fernet struct {
+	key fernet.Key
+}
+
+// NewFernet returns a new Fernet encrypter/decrypter with the given key
+func NewFernet(key []byte) Fernet {
+	frnt := Fernet{}
+	copy(frnt.key[:], key)
+	return frnt
+}
+
+// Algorithm returns the type of algorithm this is (Fernet, which uses AES128-CBC)
+func (f Fernet) Algorithm() api.MaybeEncryptedRecord_Algorithm {
+	return api.MaybeEncryptedRecord_FernetAES128CBC
+}
+
+// Encrypt encrypts some bytes and returns an encrypted record
+func (f Fernet) Encrypt(data []byte) (*api.MaybeEncryptedRecord, error) {
+	out, err := fernet.EncryptAndSign(data, &f.key)
+	if err != nil {
+		return nil, err
+	}
+	// fernet generates its own IVs, so nonce is empty
+	return &api.MaybeEncryptedRecord{
+		Algorithm: f.Algorithm(),
+		Data:      out,
+	}, nil
+}
+
+// Decrypt decrypts a MaybeEncryptedRecord and returns some bytes
+func (f Fernet) Decrypt(record api.MaybeEncryptedRecord) ([]byte, error) {
+	if record.Algorithm != f.Algorithm() {
+		return nil, fmt.Errorf("record is not a Fernet message")
+	}
+
+	// -1 skips the TTL check, since we don't care about message expiry
+	out := fernet.VerifyAndDecrypt(record.Data, -1, []*fernet.Key{&f.key})
+	// VerifyandDecrypt returns a nil message if it can't be verified and decrypted
+	if out == nil {
+		return nil, fmt.Errorf("decryption error using Fernet")
+	}
+	return out, nil
+}

+ 85 - 112
vendor/github.com/docker/swarmkit/manager/manager.go

@@ -2,7 +2,6 @@ package manager
 
 import (
 	"crypto/tls"
-	"encoding/pem"
 	"fmt"
 	"net"
 	"os"
@@ -17,7 +16,6 @@ import (
 	gmetrics "github.com/docker/go-metrics"
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/ca"
-	"github.com/docker/swarmkit/ca/keyutils"
 	"github.com/docker/swarmkit/connectionbroker"
 	"github.com/docker/swarmkit/identity"
 	"github.com/docker/swarmkit/log"
@@ -227,17 +225,51 @@ func New(config *Config) (*Manager, error) {
 	}
 	raftNode := raft.NewNode(newNodeOpts)
 
+	// the interceptorWrappers are functions that wrap the prometheus grpc
+	// interceptor, and add some of code to log errors locally. one for stream
+	// and one for unary. this is needed because the grpc unary interceptor
+	// doesn't natively do chaining, you have to implement it in the caller.
+	// note that even though these are logging errors, we're still using
+	// debug level. returning errors from GRPC methods is common and expected,
+	// and logging an ERROR every time a user mistypes a service name would
+	// pollute the logs really fast.
+	//
+	// NOTE(dperny): Because of the fact that these functions are very simple
+	// in their operation and have no side effects other than the log output,
+	// they are not automatically tested. If you modify them later, make _sure_
+	// that they are correct. If you add substantial side effects, abstract
+	// these out and test them!
+	unaryInterceptorWrapper := func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
+		// pass the call down into the grpc_prometheus interceptor
+		resp, err := grpc_prometheus.UnaryServerInterceptor(ctx, req, info, handler)
+		if err != nil {
+			log.G(ctx).WithField("rpc", info.FullMethod).WithError(err).Debug("error handling rpc")
+		}
+		return resp, err
+	}
+
+	streamInterceptorWrapper := func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
+		// we can't re-write a stream context, so don't bother creating a
+		// sub-context like in unary methods
+		// pass the call down into the grpc_prometheus interceptor
+		err := grpc_prometheus.StreamServerInterceptor(srv, ss, info, handler)
+		if err != nil {
+			log.G(ss.Context()).WithField("rpc", info.FullMethod).WithError(err).Debug("error handling streaming rpc")
+		}
+		return err
+	}
+
 	opts := []grpc.ServerOption{
 		grpc.Creds(config.SecurityConfig.ServerTLSCreds),
-		grpc.StreamInterceptor(grpc_prometheus.StreamServerInterceptor),
-		grpc.UnaryInterceptor(grpc_prometheus.UnaryServerInterceptor),
+		grpc.StreamInterceptor(streamInterceptorWrapper),
+		grpc.UnaryInterceptor(unaryInterceptorWrapper),
 		grpc.MaxMsgSize(transport.GRPCMaxMsgSize),
 	}
 
 	m := &Manager{
 		config:          *config,
 		caserver:        ca.NewServer(raftNode.MemoryStore(), config.SecurityConfig),
-		dispatcher:      dispatcher.New(raftNode, dispatcher.DefaultConfig(), drivers.New(config.PluginGetter), config.SecurityConfig),
+		dispatcher:      dispatcher.New(),
 		logbroker:       logbroker.New(raftNode.MemoryStore()),
 		watchServer:     watchapi.NewServer(raftNode.MemoryStore()),
 		server:          grpc.NewServer(opts...),
@@ -620,6 +652,10 @@ func (m *Manager) Stop(ctx context.Context, clearData bool) {
 		m.collector.Stop()
 	}
 
+	// The following components are gRPC services that are
+	// registered when creating the manager and will need
+	// to be re-registered if they are recreated.
+	// For simplicity, they are not nilled out.
 	m.dispatcher.Stop()
 	m.logbroker.Stop()
 	m.watchServer.Stop()
@@ -768,111 +804,39 @@ func (m *Manager) watchForClusterChanges(ctx context.Context) error {
 	return nil
 }
 
-// rotateRootCAKEK will attempt to rotate the key-encryption-key for root CA key-material in raft.
-// If there is no passphrase set in ENV, it returns.
-// If there is plain-text root key-material, and a passphrase set, it encrypts it.
-// If there is encrypted root key-material and it is using the current passphrase, it returns.
-// If there is encrypted root key-material, and it is using the previous passphrase, it
-// re-encrypts it with the current passphrase.
-func (m *Manager) rotateRootCAKEK(ctx context.Context, clusterID string) error {
-	// If we don't have a KEK, we won't ever be rotating anything
-	strPassphrase := os.Getenv(ca.PassphraseENVVar)
-	strPassphrasePrev := os.Getenv(ca.PassphraseENVVarPrev)
-	if strPassphrase == "" && strPassphrasePrev == "" {
-		return nil
-	}
-	if strPassphrase != "" {
-		log.G(ctx).Warn("Encrypting the root CA key in swarm using environment variables is deprecated. " +
-			"Support for decrypting or rotating the key will be removed in the future.")
-	}
-
-	passphrase := []byte(strPassphrase)
-	passphrasePrev := []byte(strPassphrasePrev)
-
-	s := m.raftNode.MemoryStore()
-	var (
-		cluster  *api.Cluster
-		err      error
-		finalKey []byte
-	)
-	// Retrieve the cluster identified by ClusterID
-	return s.Update(func(tx store.Tx) error {
-		cluster = store.GetCluster(tx, clusterID)
-		if cluster == nil {
-			return fmt.Errorf("cluster not found: %s", clusterID)
-		}
-
-		// Try to get the private key from the cluster
-		privKeyPEM := cluster.RootCA.CAKey
-		if len(privKeyPEM) == 0 {
-			// We have no PEM root private key in this cluster.
-			log.G(ctx).Warnf("cluster %s does not have private key material", clusterID)
-			return nil
-		}
-
-		// Decode the PEM private key
-		keyBlock, _ := pem.Decode(privKeyPEM)
-		if keyBlock == nil {
-			return fmt.Errorf("invalid PEM-encoded private key inside of cluster %s", clusterID)
-		}
-
-		if keyutils.IsEncryptedPEMBlock(keyBlock) {
-			// PEM encryption does not have a digest, so sometimes decryption doesn't
-			// error even with the wrong passphrase.  So actually try to parse it into a valid key.
-			_, err := keyutils.ParsePrivateKeyPEMWithPassword(privKeyPEM, []byte(passphrase))
-			if err == nil {
-				// This key is already correctly encrypted with the correct KEK, nothing to do here
-				return nil
-			}
-
-			// This key is already encrypted, but failed with current main passphrase.
-			// Let's try to decrypt with the previous passphrase, and parse into a valid key, for the
-			// same reason as above.
-			_, err = keyutils.ParsePrivateKeyPEMWithPassword(privKeyPEM, []byte(passphrasePrev))
-			if err != nil {
-				// We were not able to decrypt either with the main or backup passphrase, error
-				return err
-			}
-			// ok the above passphrase is correct, so decrypt the PEM block so we can re-encrypt -
-			// since the key was successfully decrypted above, there will be no error doing PEM
-			// decryption
-			unencryptedDER, _ := keyutils.DecryptPEMBlock(keyBlock, []byte(passphrasePrev))
-			unencryptedKeyBlock := &pem.Block{
-				Type:  keyBlock.Type,
-				Bytes: unencryptedDER,
-			}
-
-			// we were able to decrypt the key with the previous passphrase - if the current passphrase is empty,
-			// the we store the decrypted key in raft
-			finalKey = pem.EncodeToMemory(unencryptedKeyBlock)
-
-			// the current passphrase is not empty, so let's encrypt with the new one and store it in raft
-			if strPassphrase != "" {
-				finalKey, err = ca.EncryptECPrivateKey(finalKey, strPassphrase)
-				if err != nil {
-					log.G(ctx).WithError(err).Debugf("failed to rotate the key-encrypting-key for the root key material of cluster %s", clusterID)
-					return err
-				}
-			}
-		} else if strPassphrase != "" {
-			// If this key is not encrypted, and the passphrase is not nil, then we have to encrypt it
-			finalKey, err = ca.EncryptECPrivateKey(privKeyPEM, strPassphrase)
-			if err != nil {
-				log.G(ctx).WithError(err).Debugf("failed to rotate the key-encrypting-key for the root key material of cluster %s", clusterID)
-				return err
-			}
-		} else {
-			return nil // don't update if it's not encrypted and we don't want it encrypted
+// getLeaderNodeID is a small helper function returning a string with the
+// leader's node ID. it is only used for logging, and should not be relied on
+// to give a node ID for actual operational purposes (because it returns errors
+// as nicely decorated strings)
+func (m *Manager) getLeaderNodeID() string {
+	// get the current leader ID. this variable tracks the leader *only* for
+	// the purposes of logging leadership changes, and should not be relied on
+	// for other purposes
+	leader, leaderErr := m.raftNode.Leader()
+	switch leaderErr {
+	case raft.ErrNoRaftMember:
+		// this is an unlikely case, but we have to handle it. this means this
+		// node is not a member of the raft quorum. this won't look very pretty
+		// in logs ("leadership changed from aslkdjfa to ErrNoRaftMember") but
+		// it also won't be very common
+		return "not yet part of a raft cluster"
+	case raft.ErrNoClusterLeader:
+		return "no cluster leader"
+	default:
+		id, err := m.raftNode.GetNodeIDByRaftID(leader)
+		// the only possible error here is "ErrMemberUnknown"
+		if err != nil {
+			return "an unknown node"
 		}
-
-		log.G(ctx).Infof("Updating the encryption on the root key material of cluster %s", clusterID)
-		cluster.RootCA.CAKey = finalKey
-		return store.UpdateCluster(tx, cluster)
-	})
+		return id
+	}
 }
 
 // handleLeadershipEvents handles the is leader event or is follower event.
 func (m *Manager) handleLeadershipEvents(ctx context.Context, leadershipCh chan events.Event) {
+	// get the current leader and save it for logging leadership changes in
+	// this loop
+	oldLeader := m.getLeaderNodeID()
 	for {
 		select {
 		case leadershipEvent := <-leadershipCh:
@@ -891,6 +855,12 @@ func (m *Manager) handleLeadershipEvents(ctx context.Context, leadershipCh chan
 				leaderMetric.Set(0)
 			}
 			m.mu.Unlock()
+
+			newLeader := m.getLeaderNodeID()
+			// maybe we should use logrus fields for old and new leader, so
+			// that users are better able to ingest leadership changes into log
+			// aggregators?
+			log.G(ctx).Infof("leadership changed from %v to %v", oldLeader, newLeader)
 		case <-ctx.Done():
 			return
 		}
@@ -938,7 +908,10 @@ func (m *Manager) becomeLeader(ctx context.Context) {
 	initialCAConfig := ca.DefaultCAConfig()
 	initialCAConfig.ExternalCAs = m.config.ExternalCAs
 
-	var unlockKeys []*api.EncryptionKey
+	var (
+		unlockKeys []*api.EncryptionKey
+		err        error
+	)
 	if m.config.AutoLockManagers {
 		unlockKeys = []*api.EncryptionKey{{
 			Subsystem: ca.ManagerRole,
@@ -991,12 +964,6 @@ func (m *Manager) becomeLeader(ctx context.Context) {
 		return nil
 	})
 
-	// Attempt to rotate the key-encrypting-key of the root CA key-material
-	err := m.rotateRootCAKEK(ctx, clusterID)
-	if err != nil {
-		log.G(ctx).WithError(err).Error("root key-encrypting-key rotation failed")
-	}
-
 	m.replicatedOrchestrator = replicated.NewReplicatedOrchestrator(s)
 	m.constraintEnforcer = constraintenforcer.New(s)
 	m.globalOrchestrator = global.NewGlobalOrchestrator(s)
@@ -1025,6 +992,8 @@ func (m *Manager) becomeLeader(ctx context.Context) {
 	}
 
 	go func(d *dispatcher.Dispatcher) {
+		// Initialize the dispatcher.
+		d.Init(m.raftNode, dispatcher.DefaultConfig(), drivers.New(m.config.PluginGetter), m.config.SecurityConfig)
 		if err := d.Run(ctx); err != nil {
 			log.G(ctx).WithError(err).Error("Dispatcher exited with an error")
 		}
@@ -1084,6 +1053,10 @@ func (m *Manager) becomeLeader(ctx context.Context) {
 
 // becomeFollower shuts down the subsystems that are only run by the leader.
 func (m *Manager) becomeFollower() {
+	// The following components are gRPC services that are
+	// registered when creating the manager and will need
+	// to be re-registered if they are recreated.
+	// For simplicity, they are not nilled out.
 	m.dispatcher.Stop()
 	m.logbroker.Stop()
 	m.caserver.Stop()

+ 22 - 4
vendor/github.com/docker/swarmkit/manager/state/raft/raft.go

@@ -474,8 +474,11 @@ func (n *Node) joinCluster(ctx context.Context) error {
 // raft node that can be modified and customized
 func DefaultNodeConfig() *raft.Config {
 	return &raft.Config{
-		HeartbeatTick:   1,
-		ElectionTick:    3,
+		HeartbeatTick: 1,
+		// Recommended value in etcd/raft is 10 x (HeartbeatTick).
+		// Lower values were seen to have caused instability because of
+		// frequent leader elections when running on flakey networks.
+		ElectionTick:    10,
 		MaxSizePerMsg:   math.MaxUint16,
 		MaxInflightMsgs: 256,
 		Logger:          log.L,
@@ -489,8 +492,11 @@ func DefaultRaftConfig() api.RaftConfig {
 		KeepOldSnapshots:           0,
 		SnapshotInterval:           10000,
 		LogEntriesForSlowFollowers: 500,
-		ElectionTick:               3,
-		HeartbeatTick:              1,
+		// Recommended value in etcd/raft is 10 x (HeartbeatTick).
+		// Lower values were seen to have caused instability because of
+		// frequent leader elections when running on flakey networks.
+		HeartbeatTick: 1,
+		ElectionTick:  10,
 	}
 }
 
@@ -1703,6 +1709,18 @@ func (n *Node) GetMemberByNodeID(nodeID string) *membership.Member {
 	return nil
 }
 
+// GetNodeIDByRaftID returns the generic Node ID of a member given its raft ID.
+// It returns ErrMemberUnknown if the raft ID is unknown.
+func (n *Node) GetNodeIDByRaftID(raftID uint64) (string, error) {
+	if member, ok := n.cluster.Members()[raftID]; ok {
+		return member.NodeID, nil
+	}
+	// this is the only possible error value that should be returned; the
+	// manager code depends on this. if you need to add more errors later, make
+	// sure that you update the callers of this method accordingly
+	return "", ErrMemberUnknown
+}
+
 // IsMember checks if the raft node has effectively joined
 // a cluster of existing members.
 func (n *Node) IsMember() bool {

+ 1 - 16
vendor/github.com/docker/swarmkit/manager/state/raft/storage/storage.go

@@ -13,7 +13,6 @@ import (
 	"github.com/coreos/etcd/snap"
 	"github.com/coreos/etcd/wal"
 	"github.com/coreos/etcd/wal/walpb"
-	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/log"
 	"github.com/docker/swarmkit/manager/encryption"
 	"github.com/pkg/errors"
@@ -34,20 +33,6 @@ var versionedWALSnapDirs = []walSnapDirs{
 	{wal: "wal", snap: "snap"},
 }
 
-// MultiDecrypter attempts to decrypt with a list of decrypters
-type MultiDecrypter []encryption.Decrypter
-
-// Decrypt tries to decrypt using all the decrypters
-func (m MultiDecrypter) Decrypt(r api.MaybeEncryptedRecord) (result []byte, err error) {
-	for _, d := range m {
-		result, err = d.Decrypt(r)
-		if err == nil {
-			return
-		}
-	}
-	return
-}
-
 // EncryptedRaftLogger saves raft data to disk
 type EncryptedRaftLogger struct {
 	StateDir      string
@@ -75,7 +60,7 @@ func (e *EncryptedRaftLogger) BootstrapFromDisk(ctx context.Context, oldEncrypti
 			_, d := encryption.Defaults(key)
 			decrypters = append(decrypters, d)
 		}
-		decrypter = MultiDecrypter(decrypters)
+		decrypter = encryption.NewMultiDecrypter(decrypters...)
 	}
 
 	snapFactory := NewSnapFactory(encrypter, decrypter)

+ 143 - 4
vendor/github.com/docker/swarmkit/node/node.go

@@ -260,12 +260,16 @@ func (n *Node) currentRole() api.NodeRole {
 func (n *Node) run(ctx context.Context) (err error) {
 	defer func() {
 		n.err = err
+		// close the n.closed channel to indicate that the Node has completely
+		// terminated
 		close(n.closed)
 	}()
 	ctx, cancel := context.WithCancel(ctx)
 	defer cancel()
 	ctx = log.WithModule(ctx, "node")
 
+	// set up a goroutine to monitor the stop channel, and cancel the run
+	// context when the node is stopped
 	go func(ctx context.Context) {
 		select {
 		case <-ctx.Done():
@@ -274,6 +278,17 @@ func (n *Node) run(ctx context.Context) (err error) {
 		}
 	}(ctx)
 
+	// First thing's first: get the SecurityConfig for this node. This includes
+	// the certificate information, and the root CA.  It also returns a cancel
+	// function. This is needed because the SecurityConfig is a live object,
+	// and provides a watch queue so that caller can observe changes to the
+	// security config. This watch queue has to be closed, which is done by the
+	// secConfigCancel function.
+	//
+	// It's also noteworthy that loading the security config with the node's
+	// loadSecurityConfig method has the side effect of setting the node's ID
+	// and role fields, meaning it isn't until after that point that node knows
+	// its ID
 	paths := ca.NewConfigPaths(filepath.Join(n.config.StateDir, certDirectory))
 	securityConfig, secConfigCancel, err := n.loadSecurityConfig(ctx, paths)
 	if err != nil {
@@ -281,11 +296,23 @@ func (n *Node) run(ctx context.Context) (err error) {
 	}
 	defer secConfigCancel()
 
+	// Now that we have the security config, we can get a TLSRenewer, which is
+	// a live component handling certificate rotation.
 	renewer := ca.NewTLSRenewer(securityConfig, n.connBroker, paths.RootCA)
 
+	// Now that we have the security goop all loaded, we know the Node's ID and
+	// can add that to our logging context.
 	ctx = log.WithLogger(ctx, log.G(ctx).WithField("node.id", n.NodeID()))
 
+	// Next, set up the task database. The task database is used by the agent
+	// to keep a persistent local record of its tasks. Since every manager also
+	// has an agent, every node needs a task database, so we do this regardless
+	// of role.
 	taskDBPath := filepath.Join(n.config.StateDir, "worker", "tasks.db")
+	// Doing os.MkdirAll will create the necessary directory path for the task
+	// database if it doesn't already exist, and if it does already exist, no
+	// error will be returned, so we use this regardless of whether this node
+	// is new or not.
 	if err := os.MkdirAll(filepath.Dir(taskDBPath), 0777); err != nil {
 		return err
 	}
@@ -296,8 +323,18 @@ func (n *Node) run(ctx context.Context) (err error) {
 	}
 	defer db.Close()
 
+	// agentDone is a channel that represents the agent having exited. We start
+	// the agent in a goroutine a few blocks down, and before that goroutine
+	// exits, it closes this channel to signal to the goroutine just below to
+	// terminate.
 	agentDone := make(chan struct{})
 
+	// This goroutine is the node changes loop. The n.notifyNodeChange
+	// channel is passed to the agent. When an new node object gets sent down
+	// to the agent, it gets passed back up to this node object, so that we can
+	// check if a role update or a root certificate rotation is required. This
+	// handles root rotation, but the renewer handles regular certification
+	// rotation.
 	go func() {
 		// lastNodeDesiredRole is the last-seen value of Node.Spec.DesiredRole,
 		// used to make role changes "edge triggered" and avoid renewal loops.
@@ -354,9 +391,14 @@ func (n *Node) run(ctx context.Context) (err error) {
 		}
 	}()
 
+	// Now we're going to launch the main component goroutines, the Agent, the
+	// Manager (maybe) and the certificate updates loop. We shouldn't exit
+	// the node object until all 3 of these components have terminated, so we
+	// create a waitgroup to block termination of the node until then
 	var wg sync.WaitGroup
 	wg.Add(3)
 
+	// These two blocks update some of the metrics settings.
 	nodeInfo.WithValues(
 		securityConfig.ClientTLSCreds.Organization(),
 		securityConfig.ClientTLSCreds.NodeID(),
@@ -368,6 +410,10 @@ func (n *Node) run(ctx context.Context) (err error) {
 		nodeManager.Set(0)
 	}
 
+	// We created the renewer way up when we were creating the SecurityConfig
+	// at the beginning of run, but now we're ready to start receiving
+	// CertificateUpdates, and launch a goroutine to handle this. Updates is a
+	// channel we iterate containing the results of certificate renewals.
 	updates := renewer.Start(ctx)
 	go func() {
 		for certUpdate := range updates {
@@ -375,12 +421,14 @@ func (n *Node) run(ctx context.Context) (err error) {
 				logrus.Warnf("error renewing TLS certificate: %v", certUpdate.Err)
 				continue
 			}
+			// Set the new role, and notify our waiting role changing logic
+			// that the role has changed.
 			n.Lock()
 			n.role = certUpdate.Role
 			n.roleCond.Broadcast()
 			n.Unlock()
 
-			// Export the new role.
+			// Export the new role for metrics
 			if n.currentRole() == api.NodeRoleManager {
 				nodeManager.Set(1)
 			} else {
@@ -391,13 +439,19 @@ func (n *Node) run(ctx context.Context) (err error) {
 		wg.Done()
 	}()
 
+	// and, finally, start the two main components: the manager and the agent
 	role := n.role
 
+	// Channels to signal when these respective components are up and ready to
+	// go.
 	managerReady := make(chan struct{})
 	agentReady := make(chan struct{})
+	// these variables are defined in this scope so that they're closed on by
+	// respective goroutines below.
 	var managerErr error
 	var agentErr error
 	go func() {
+		// superviseManager is a routine that watches our manager role
 		managerErr = n.superviseManager(ctx, securityConfig, paths.RootCA, managerReady, renewer) // store err and loop
 		wg.Done()
 		cancel()
@@ -409,6 +463,11 @@ func (n *Node) run(ctx context.Context) (err error) {
 		close(agentDone)
 	}()
 
+	// This goroutine is what signals that the node has fully started by
+	// closing the n.ready channel. First, it waits for the agent to start.
+	// Then, if this node is a manager, it will wait on either the manager
+	// starting, or the node role changing. This ensures that if the node is
+	// demoted before the manager starts, it doesn't get stuck.
 	go func() {
 		<-agentReady
 		if role == ca.ManagerRole {
@@ -428,6 +487,8 @@ func (n *Node) run(ctx context.Context) (err error) {
 		close(n.ready)
 	}()
 
+	// And, finally, we park and wait for the node to close up. If we get any
+	// error other than context canceled, we return it.
 	wg.Wait()
 	if managerErr != nil && errors.Cause(managerErr) != context.Canceled {
 		return managerErr
@@ -435,6 +496,9 @@ func (n *Node) run(ctx context.Context) (err error) {
 	if agentErr != nil && errors.Cause(agentErr) != context.Canceled {
 		return agentErr
 	}
+	// NOTE(dperny): we return err here, but the last time I can see err being
+	// set is when we open the boltdb way up in this method, so I don't know
+	// what returning err is supposed to do.
 	return err
 }
 
@@ -477,11 +541,25 @@ func (n *Node) Err(ctx context.Context) error {
 	}
 }
 
+// runAgent starts the node's agent. When the agent has started, the provided
+// ready channel is closed. When the agent exits, this will return the error
+// that caused it.
 func (n *Node) runAgent(ctx context.Context, db *bolt.DB, securityConfig *ca.SecurityConfig, ready chan<- struct{}) error {
-	waitCtx, waitCancel := context.WithCancel(ctx)
+	// First, get a channel for knowing when a remote peer has been selected.
+	// The value returned from the remotesCh is ignored, we just need to know
+	// when the peer is selected
 	remotesCh := n.remotes.WaitSelect(ctx)
+	// then, we set up a new context to pass specifically to
+	// ListenControlSocket, and start that method to wait on a connection on
+	// the cluster control API.
+	waitCtx, waitCancel := context.WithCancel(ctx)
 	controlCh := n.ListenControlSocket(waitCtx)
 
+	// The goal here to wait either until we have a remote peer selected, or
+	// connection to the control
+	// socket. These are both ways to connect the
+	// agent to a manager, and we need to wait until one or the other is
+	// available to start the agent
 waitPeer:
 	for {
 		select {
@@ -490,20 +568,28 @@ waitPeer:
 		case <-remotesCh:
 			break waitPeer
 		case conn := <-controlCh:
+			// conn will probably be nil the first time we call this, probably,
+			// but only a non-nil conn represent an actual connection.
 			if conn != nil {
 				break waitPeer
 			}
 		}
 	}
 
+	// We can stop listening for new control socket connections once we're
+	// ready
 	waitCancel()
 
+	// NOTE(dperny): not sure why we need to recheck the context here. I guess
+	// it avoids a race if the context was canceled at the same time that a
+	// connection or peer was available. I think it's just an optimization.
 	select {
 	case <-ctx.Done():
 		return ctx.Err()
 	default:
 	}
 
+	// Now we can go ahead and configure, create, and start the agent.
 	secChangesCh, secChangesCancel := securityConfig.Watch()
 	defer secChangesCancel()
 
@@ -524,8 +610,8 @@ waitPeer:
 			CertIssuerSubject:   issuer.Subject,
 		},
 	}
-	// if a join address has been specified, then if the agent fails to connect due to a TLS error, fail fast - don't
-	// keep re-trying to join
+	// if a join address has been specified, then if the agent fails to connect
+	// due to a TLS error, fail fast - don't keep re-trying to join
 	if n.config.JoinAddr != "" {
 		agentConfig.SessionTracker = &firstSessionErrorTracker{}
 	}
@@ -548,6 +634,7 @@ waitPeer:
 		n.Unlock()
 	}()
 
+	// when the agent indicates that it is ready, we close the ready channel.
 	go func() {
 		<-a.Ready()
 		close(ready)
@@ -785,6 +872,10 @@ func (n *Node) initManagerConnection(ctx context.Context, ready chan<- struct{})
 	return nil
 }
 
+// waitRole takes a context and a role. it the blocks until the context is
+// canceled or the node's role updates to the provided role. returns nil when
+// the node has acquired the provided role, or ctx.Err() if the context is
+// canceled
 func (n *Node) waitRole(ctx context.Context, role string) error {
 	n.roleCond.L.Lock()
 	if role == n.role {
@@ -814,7 +905,13 @@ func (n *Node) waitRole(ctx context.Context, role string) error {
 	return nil
 }
 
+// runManager runs the manager on this node. It returns a boolean indicating if
+// the stoppage was due to a role change, and an error indicating why the
+// manager stopped
 func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig, rootPaths ca.CertPaths, ready chan struct{}, workerRole <-chan struct{}) (bool, error) {
+	// First, set up this manager's advertise and listen addresses, if
+	// provided. they might not be provided if this node is joining the cluster
+	// instead of creating a new one.
 	var remoteAPI *manager.RemoteAddrs
 	if n.config.ListenRemoteAPI != "" {
 		remoteAPI = &manager.RemoteAddrs{
@@ -851,8 +948,15 @@ func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig
 	if err != nil {
 		return false, err
 	}
+	// The done channel is used to signal that the manager has exited.
 	done := make(chan struct{})
+	// runErr is an error value set by the goroutine that runs the manager
 	var runErr error
+
+	// The context used to start this might have a logger associated with it
+	// that we'd like to reuse, but we don't want to use that context, so we
+	// pass to the goroutine only the logger, and create a new context with
+	//that logger.
 	go func(logger *logrus.Entry) {
 		if err := m.Run(log.WithLogger(context.Background(), logger)); err != nil {
 			runErr = err
@@ -860,6 +964,9 @@ func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig
 		close(done)
 	}(log.G(ctx))
 
+	// clearData is set in the select below, and is used to signal why the
+	// manager is stopping, and indicate whether or not to delete raft data and
+	// keys when stopping the manager.
 	var clearData bool
 	defer func() {
 		n.Lock()
@@ -877,9 +984,26 @@ func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig
 	connCtx, connCancel := context.WithCancel(ctx)
 	defer connCancel()
 
+	// launch a goroutine that will manage our local connection to the manager
+	// from the agent. Remember the managerReady channel created way back in
+	// run? This is actually where we close it. Not when the manager starts,
+	// but when a connection to the control socket has been established.
 	go n.initManagerConnection(connCtx, ready)
 
 	// wait for manager stop or for role change
+	// The manager can be stopped one of 4 ways:
+	// 1. The manager may have errored out and returned an error, closing the
+	//    done channel in the process
+	// 2. The node may have been demoted to a worker. In this case, we're gonna
+	//    have to stop the manager ourselves, setting clearData to true so the
+	//    local raft data, certs, keys, etc, are nuked.
+	// 3. The manager may have been booted from raft. This could happen if it's
+	//    removed from the raft quorum but the role update hasn't registered
+	//    yet. The fact that there is more than 1 code path to cause the
+	//    manager to exit is a possible source of bugs.
+	// 4. The context may have been canceled from above, in which case we
+	//    should stop the manager ourselves, but indicate that this is NOT a
+	//    demotion.
 	select {
 	case <-done:
 		return false, runErr
@@ -895,12 +1019,22 @@ func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig
 	return clearData, nil
 }
 
+// superviseManager controls whether or not we are running a manager on this
+// node
 func (n *Node) superviseManager(ctx context.Context, securityConfig *ca.SecurityConfig, rootPaths ca.CertPaths, ready chan struct{}, renewer *ca.TLSRenewer) error {
+	// superviseManager is a loop, because we can come in and out of being a
+	// manager, and need to appropriately handle that without disrupting the
+	// node functionality.
 	for {
+		// if we're not a manager, we're just gonna park here and wait until we
+		// are. For normal agent nodes, we'll stay here forever, as intended.
 		if err := n.waitRole(ctx, ca.ManagerRole); err != nil {
 			return err
 		}
 
+		// Once we know we are a manager, we get ourselves ready for when we
+		// lose that role. we create a channel to signal that we've become a
+		// worker, and close it when n.waitRole completes.
 		workerRole := make(chan struct{})
 		waitRoleCtx, waitRoleCancel := context.WithCancel(ctx)
 		go func() {
@@ -909,6 +1043,9 @@ func (n *Node) superviseManager(ctx context.Context, securityConfig *ca.Security
 			}
 		}()
 
+		// the ready channel passed to superviseManager is in turn passed down
+		// to the runManager function. It's used to signal to the caller that
+		// the manager has started.
 		wasRemoved, err := n.runManager(ctx, securityConfig, rootPaths, ready, workerRole)
 		if err != nil {
 			waitRoleCancel()
@@ -967,6 +1104,8 @@ func (n *Node) superviseManager(ctx context.Context, securityConfig *ca.Security
 			return err
 		}
 
+		// set ready to nil after the first time we've gone through this, as we
+		// don't need to signal after the first time that the manager is ready.
 		ready = nil
 	}
 }

+ 19 - 25
vendor/github.com/docker/swarmkit/vendor.conf

@@ -11,40 +11,34 @@ github.com/docker/go-metrics d466d4f6fd960e01820085bd7e1a24426ee7ef18
 
 # etcd/raft
 github.com/coreos/etcd v3.2.1
-github.com/coreos/go-systemd v12
+github.com/coreos/go-systemd v15
 github.com/coreos/pkg v3
 github.com/prometheus/client_golang 52437c81da6b127a9925d17eb3a382a2e5fd395e
 github.com/prometheus/client_model fa8ad6fec33561be4280a8f0514318c79d7f6cb6
 github.com/prometheus/common ebdfc6da46522d58825777cf1f90490a5b1ef1d8
 github.com/prometheus/procfs abf152e5f3e97f2fafac028d2cc06c1feb87ffa5
 
-github.com/docker/distribution b38e5838b7b2f2ad48e06ec4b500011976080621
-github.com/docker/docker 8af4db6f002ac907b6ef8610b237879dfcaa5b7a
-github.com/docker/go-connections 3ede32e2033de7505e6500d6c868c2b9ed9f169d
+github.com/docker/distribution edc3ab29cdff8694dd6feb85cfeb4b5f1b38ed9c
+github.com/docker/docker 3d14173a2900b60200d9b1475abd5138f4315981
+github.com/docker/go-connections 7beb39f0b969b075d1325fecb092faf27fd357b6
 github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
-github.com/docker/go-units 954fed01cc617c55d838fa2230073f2cb17386c8
-github.com/docker/libkv 9fd56606e928ff1f309808f5d5a0b7a2ef73f9a8
-github.com/docker/libnetwork 21544598c53fa36a3c771a8725c643dd2340f845 
-github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
-github.com/opencontainers/runc d40db12e72a40109dfcf28539f5ee0930d2f0277
-github.com/opencontainers/go-digest 21dfd564fd89c944783d00d069f33e3e7123c448 
-github.com/opencontainers/image-spec v1.0.0
+github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1
+github.com/docker/libkv 1d8431073ae03cdaedb198a89722f3aab6d418ef
+github.com/docker/libnetwork 1b91bc94094ecfdae41daa465cc0c8df37dfb3dd
+github.com/opencontainers/runc 4fc53a81fb7c994640722ac585fa9ca548971871
+github.com/opencontainers/go-digest 21dfd564fd89c944783d00d069f33e3e7123c448
+github.com/opencontainers/image-spec v1.0.1
+github.com/ishidawataru/sctp 07191f837fedd2f13d1ec7b5f885f0f3ec54b1cb
 
-# containerd executor
-github.com/containerd/containerd 29a4dd7f46e0780d0bff2a237dc600a5b90a4dd5
-github.com/containerd/fifo 69b99525e472735860a5269b75af1970142b3062
-github.com/opencontainers/runtime-spec v1.0.0
-golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c
-github.com/containerd/continuity cf279e6ac893682272b4479d4c67fd3abf878b4e
-
-github.com/davecgh/go-spew 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d
-github.com/Microsoft/go-winio v0.4.2
-github.com/sirupsen/logrus v1.0.1
+github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76 # v1.1.0
+github.com/Microsoft/go-winio v0.4.6
+github.com/sirupsen/logrus v1.0.3
 github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9
-github.com/boltdb/bolt e72f08ddb5a52992c0a44c7dda9316c7333938b2
+github.com/boltdb/bolt fff57c100f4dea1905678da7e90d92429dff2904
 github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a
 github.com/dustin/go-humanize 8929fe90cee4b2cb9deb468b51fb34eba64d1bf0
-github.com/google/certificate-transparency 0f6e3d1d1ba4d03fdaab7cd716f36255c2e48341
+github.com/fernet/fernet-go 1b2437bc582b3cfbb341ee5a29f8ef5b42912ff2
+github.com/google/certificate-transparency d90e65c3a07988180c5b1ece71791c0b6506826e
 github.com/hashicorp/go-immutable-radix 8e8ed81f8f0bf1bdd829593fdd5c29922c1ea990
 github.com/hashicorp/go-memdb cb9a474f84cc5e41b273b20c6927680b2a8776ad
 github.com/hashicorp/golang-lru a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4
@@ -57,8 +51,8 @@ github.com/rcrowley/go-metrics 51425a2415d21afadfd55cd93432c0bc69e9598d
 github.com/spf13/cobra 8e91712f174ced10270cf66615e0a9127e7c4de5
 github.com/spf13/pflag 7f60f83a2c81bc3c3c0d5297f61ddfa68da9d3b7
 github.com/stretchr/testify v1.1.4
-golang.org/x/crypto 3fbbcd23f1cb824e69491a5930cfeff09b12f4d2
+golang.org/x/crypto 558b6879de74bc843225cde5686419267ff707ca
 golang.org/x/net 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6
-golang.org/x/sys 739734461d1c916b6c72a63d7efda2b27edb369f
+golang.org/x/sys 37707fdb30a5b38865cfb95e5aab41707daec7fd
 golang.org/x/text f72d8390a633d5dfb0cc84043294db9f6c935756
 golang.org/x/time a4bde12657593d5e90d0533a3e4fd95e635124cb

+ 20 - 0
vendor/github.com/fernet/fernet-go/License

@@ -0,0 +1,20 @@
+Copyright © 2013 Keith Rarick
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 22 - 0
vendor/github.com/fernet/fernet-go/Readme

@@ -0,0 +1,22 @@
+Fernet takes a user-provided *message* (an arbitrary sequence of
+bytes), a *key* (256 bits), and the current time, and produces a
+*token*, which contains the message in a form that can't be read
+or altered without the key.
+
+This package is compatible with the other implementations at
+https://github.com/fernet. They can exchange tokens freely among
+each other.
+
+Documentation: http://godoc.org/github.com/fernet/fernet-go
+
+
+INSTALL
+
+	$ go get github.com/fernet/fernet-go
+
+
+For more information and background, see the Fernet spec at
+https://github.com/fernet/spec.
+
+Fernet is distributed under the terms of the MIT license.
+See the License file for details.

+ 168 - 0
vendor/github.com/fernet/fernet-go/fernet.go

@@ -0,0 +1,168 @@
+// Package fernet takes a user-provided message (an arbitrary
+// sequence of bytes), a key (256 bits), and the current time,
+// and produces a token, which contains the message in a form
+// that can't be read or altered without the key.
+//
+// For more information and background, see the Fernet spec
+// at https://github.com/fernet/spec.
+//
+// Subdirectories in this package provide command-line tools
+// for working with Fernet keys and tokens.
+package fernet
+
+import (
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/hmac"
+	"crypto/rand"
+	"crypto/sha256"
+	"crypto/subtle"
+	"encoding/base64"
+	"encoding/binary"
+	"io"
+	"time"
+)
+
+const (
+	version      byte = 0x80
+	tsOffset          = 1
+	ivOffset          = tsOffset + 8
+	payOffset         = ivOffset + aes.BlockSize
+	overhead          = 1 + 8 + aes.BlockSize + sha256.Size // ver + ts + iv + hmac
+	maxClockSkew      = 60 * time.Second
+)
+
+var encoding = base64.URLEncoding
+
+// generates a token from msg, writes it into tok, and returns the
+// number of bytes generated, which is encodedLen(msg).
+// len(tok) must be >= encodedLen(len(msg))
+func gen(tok, msg, iv []byte, ts time.Time, k *Key) int {
+	tok[0] = version
+	binary.BigEndian.PutUint64(tok[tsOffset:], uint64(ts.Unix()))
+	copy(tok[ivOffset:], iv)
+	p := tok[payOffset:]
+	n := pad(p, msg, aes.BlockSize)
+	bc, _ := aes.NewCipher(k.cryptBytes())
+	cipher.NewCBCEncrypter(bc, iv).CryptBlocks(p[:n], p[:n])
+	genhmac(p[n:n], tok[:payOffset+n], k.signBytes())
+	return payOffset + n + sha256.Size
+}
+
+// token length for input msg of length n, not including base64
+func encodedLen(n int) int {
+	const k = aes.BlockSize
+	return n/k*k + k + overhead
+}
+
+// max msg length for tok of length n, for binary token (no base64)
+// upper bound; not exact
+func decodedLen(n int) int {
+	return n - overhead
+}
+
+// if msg is nil, decrypts in place and returns a slice of tok.
+func verify(msg, tok []byte, ttl time.Duration, now time.Time, k *Key) []byte {
+	if len(tok) < 1 || tok[0] != version {
+		return nil
+	}
+	ts := time.Unix(int64(binary.BigEndian.Uint64(tok[1:])), 0)
+	if ttl >= 0 && (now.After(ts.Add(ttl)) || ts.After(now.Add(maxClockSkew))) {
+		return nil
+	}
+	n := len(tok) - sha256.Size
+	var hmac [sha256.Size]byte
+	genhmac(hmac[:0], tok[:n], k.signBytes())
+	if subtle.ConstantTimeCompare(tok[n:], hmac[:]) != 1 {
+		return nil
+	}
+	pay := tok[payOffset : len(tok)-sha256.Size]
+	if len(pay)%aes.BlockSize != 0 {
+		return nil
+	}
+	if msg != nil {
+		copy(msg, pay)
+		pay = msg
+	}
+	bc, _ := aes.NewCipher(k.cryptBytes())
+	iv := tok[9:][:aes.BlockSize]
+	cipher.NewCBCDecrypter(bc, iv).CryptBlocks(pay, pay)
+	return unpad(pay)
+}
+
+// Pads p to a multiple of k using PKCS #7 standard block padding.
+// See http://tools.ietf.org/html/rfc5652#section-6.3.
+func pad(q, p []byte, k int) int {
+	n := len(p)/k*k + k
+	copy(q, p)
+	c := byte(n - len(p))
+	for i := len(p); i < n; i++ {
+		q[i] = c
+	}
+	return n
+}
+
+// Removes PKCS #7 standard block padding from p.
+// See http://tools.ietf.org/html/rfc5652#section-6.3.
+// This function is the inverse of pad.
+// If the padding is not well-formed, unpad returns nil.
+func unpad(p []byte) []byte {
+	c := p[len(p)-1]
+	for i := len(p) - int(c); i < len(p); i++ {
+		if i < 0 || p[i] != c {
+			return nil
+		}
+	}
+	return p[:len(p)-int(c)]
+}
+
+func b64enc(src []byte) []byte {
+	dst := make([]byte, encoding.EncodedLen(len(src)))
+	encoding.Encode(dst, src)
+	return dst
+}
+
+func b64dec(src []byte) []byte {
+	dst := make([]byte, encoding.DecodedLen(len(src)))
+	n, err := encoding.Decode(dst, src)
+	if err != nil {
+		return nil
+	}
+	return dst[:n]
+}
+
+func genhmac(q, p, k []byte) {
+	h := hmac.New(sha256.New, k)
+	h.Write(p)
+	h.Sum(q)
+}
+
+// EncryptAndSign encrypts and signs msg with key k and returns the resulting
+// fernet token. If msg contains text, the text should be encoded
+// with UTF-8 to follow fernet convention.
+func EncryptAndSign(msg []byte, k *Key) (tok []byte, err error) {
+	iv := make([]byte, aes.BlockSize)
+	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
+		return nil, err
+	}
+	b := make([]byte, encodedLen(len(msg)))
+	n := gen(b, msg, iv, time.Now(), k)
+	tok = make([]byte, encoding.EncodedLen(n))
+	encoding.Encode(tok, b[:n])
+	return tok, nil
+}
+
+// VerifyAndDecrypt verifies that tok is a valid fernet token that was signed
+// with a key in k at most ttl time ago only if ttl is greater than zero.
+// Returns the message contained in tok if tok is valid, otherwise nil.
+func VerifyAndDecrypt(tok []byte, ttl time.Duration, k []*Key) (msg []byte) {
+	b := make([]byte, encoding.DecodedLen(len(tok)))
+	n, _ := encoding.Decode(b, tok)
+	for _, k1 := range k {
+		msg = verify(nil, b[:n], ttl, time.Now(), k1)
+		if msg != nil {
+			return msg
+		}
+	}
+	return nil
+}

+ 91 - 0
vendor/github.com/fernet/fernet-go/key.go

@@ -0,0 +1,91 @@
+package fernet
+
+import (
+	"crypto/rand"
+	"encoding/base64"
+	"encoding/hex"
+	"errors"
+	"io"
+)
+
+var (
+	errKeyLen = errors.New("fernet: key decodes to wrong size")
+	errNoKeys = errors.New("fernet: no keys provided")
+)
+
+// Key represents a key.
+type Key [32]byte
+
+func (k *Key) cryptBytes() []byte {
+	return k[len(k)/2:]
+}
+
+func (k *Key) signBytes() []byte {
+	return k[:len(k)/2]
+}
+
+// Generate initializes k with pseudorandom data from package crypto/rand.
+func (k *Key) Generate() error {
+	_, err := io.ReadFull(rand.Reader, k[:])
+	return err
+}
+
+// Encode returns the URL-safe base64 encoding of k.
+func (k *Key) Encode() string {
+	return encoding.EncodeToString(k[:])
+}
+
+// DecodeKey decodes a key from s and returns it. The key can be in
+// hexadecimal, standard base64, or URL-safe base64.
+func DecodeKey(s string) (*Key, error) {
+	var b []byte
+	var err error
+	if s == "" {
+		return nil, errors.New("empty key")
+	}
+	if len(s) == hex.EncodedLen(len(Key{})) {
+		b, err = hex.DecodeString(s)
+	} else {
+		b, err = base64.StdEncoding.DecodeString(s)
+		if err != nil {
+			b, err = base64.URLEncoding.DecodeString(s)
+		}
+	}
+	if err != nil {
+		return nil, err
+	}
+	if len(b) != len(Key{}) {
+		return nil, errKeyLen
+	}
+	k := new(Key)
+	copy(k[:], b)
+	return k, nil
+}
+
+// DecodeKeys decodes each element of a using DecodeKey and returns the
+// resulting keys. Requires at least one key.
+func DecodeKeys(a ...string) ([]*Key, error) {
+	if len(a) == 0 {
+		return nil, errNoKeys
+	}
+	var err error
+	ks := make([]*Key, len(a))
+	for i, s := range a {
+		ks[i], err = DecodeKey(s)
+		if err != nil {
+			return nil, err
+		}
+	}
+	return ks, nil
+}
+
+// MustDecodeKeys is like DecodeKeys, but panics if an error occurs.
+// It simplifies safe initialization of global variables holding
+// keys.
+func MustDecodeKeys(a ...string) []*Key {
+	k, err := DecodeKeys(a...)
+	if err != nil {
+		panic(err)
+	}
+	return k
+}