浏览代码

Merge pull request #23312 from justincormack/proxy

Make the docker proxy a standalone binary not a re-exec
Tibor Vass 9 年之前
父节点
当前提交
07dd69df8d
共有 45 个文件被更改,包括 540 次插入598 次删除
  1. 3 3
      daemon/cluster/convert/swarm.go
  2. 3 0
      hack/.vendor-helpers.sh
  3. 1 0
      hack/make/.binary-setup
  4. 1 0
      hack/make/.build-deb/rules
  5. 1 0
      hack/make/.build-rpm/docker-engine.spec
  6. 3 0
      hack/make/binary-daemon
  7. 3 0
      hack/make/dynbinary-daemon
  8. 18 0
      hack/make/gccgo
  9. 1 0
      hack/make/install-binary-daemon
  10. 5 0
      hack/make/tgz
  11. 2 2
      hack/vendor.sh
  12. 0 4
      integration-cli/docker_api_swarm_test.go
  13. 0 216
      pkg/proxy/network_proxy_test.go
  14. 5 2
      vendor/src/github.com/docker/libnetwork/Makefile
  15. 67 0
      vendor/src/github.com/docker/libnetwork/cmd/proxy/main.go
  16. 2 2
      vendor/src/github.com/docker/libnetwork/cmd/proxy/proxy.go
  17. 1 1
      vendor/src/github.com/docker/libnetwork/cmd/proxy/stub_proxy.go
  18. 1 1
      vendor/src/github.com/docker/libnetwork/cmd/proxy/tcp_proxy.go
  19. 1 1
      vendor/src/github.com/docker/libnetwork/cmd/proxy/udp_proxy.go
  20. 5 0
      vendor/src/github.com/docker/libnetwork/controller.go
  21. 1 1
      vendor/src/github.com/docker/libnetwork/drivers/bridge/bridge.go
  22. 23 0
      vendor/src/github.com/docker/libnetwork/drivers_ipam.go
  23. 0 22
      vendor/src/github.com/docker/libnetwork/drvregistry/drvregistry.go
  24. 15 6
      vendor/src/github.com/docker/libnetwork/etchosts/etchosts.go
  25. 1 1
      vendor/src/github.com/docker/libnetwork/networkdb/cluster.go
  26. 5 0
      vendor/src/github.com/docker/libnetwork/networkdb/delegate.go
  27. 8 2
      vendor/src/github.com/docker/libnetwork/portmapper/mapper.go
  28. 2 2
      vendor/src/github.com/docker/libnetwork/portmapper/mock_proxy.go
  29. 6 67
      vendor/src/github.com/docker/libnetwork/portmapper/proxy.go
  30. 9 1
      vendor/src/github.com/docker/libnetwork/sandbox_dns_unix.go
  31. 2 0
      vendor/src/github.com/docker/libnetwork/sandbox_externalkey_unix.go
  32. 2 0
      vendor/src/github.com/docker/swarmkit/agent/agent.go
  33. 214 214
      vendor/src/github.com/docker/swarmkit/api/types.pb.go
  34. 4 5
      vendor/src/github.com/docker/swarmkit/api/types.proto
  35. 8 1
      vendor/src/github.com/docker/swarmkit/ca/server.go
  36. 3 5
      vendor/src/github.com/docker/swarmkit/identity/randomid.go
  37. 11 0
      vendor/src/github.com/docker/swarmkit/manager/allocator/networkallocator/networkallocator.go
  38. 21 8
      vendor/src/github.com/docker/swarmkit/manager/controlapi/node.go
  39. 13 0
      vendor/src/github.com/docker/swarmkit/manager/controlapi/service.go
  40. 6 6
      vendor/src/github.com/docker/swarmkit/manager/dispatcher/dispatcher.go
  41. 17 0
      vendor/src/github.com/docker/swarmkit/manager/orchestrator/services.go
  42. 12 7
      vendor/src/github.com/docker/swarmkit/manager/scheduler/constraint.go
  43. 1 11
      vendor/src/github.com/docker/swarmkit/manager/state/raft/membership/cluster.go
  44. 33 6
      vendor/src/github.com/docker/swarmkit/manager/state/raft/raft.go
  45. 0 1
      vendor/src/github.com/docker/swarmkit/manager/state/raft/storage.go

+ 3 - 3
daemon/cluster/convert/swarm.go

@@ -136,13 +136,13 @@ func SwarmSpecUpdateAcceptancePolicy(spec *swarmapi.ClusterSpec, acceptancePolic
 					hashPwd, _ = bcrypt.GenerateFromPassword([]byte(*p.Secret), 0)
 					hashPwd, _ = bcrypt.GenerateFromPassword([]byte(*p.Secret), 0)
 					hashs[*p.Secret] = hashPwd
 					hashs[*p.Secret] = hashPwd
 				}
 				}
-				policy.Secret = &swarmapi.AcceptancePolicy_RoleAdmissionPolicy_HashedSecret{
+				policy.Secret = &swarmapi.AcceptancePolicy_RoleAdmissionPolicy_Secret{
 					Data: hashPwd,
 					Data: hashPwd,
 					Alg:  "bcrypt",
 					Alg:  "bcrypt",
 				}
 				}
 			}
 			}
 		} else if oldSecret := getOldSecret(oldSpec, policy.Role); oldSecret != nil { // else use the old one.
 		} else if oldSecret := getOldSecret(oldSpec, policy.Role); oldSecret != nil { // else use the old one.
-			policy.Secret = &swarmapi.AcceptancePolicy_RoleAdmissionPolicy_HashedSecret{
+			policy.Secret = &swarmapi.AcceptancePolicy_RoleAdmissionPolicy_Secret{
 				Data: oldSecret.Data,
 				Data: oldSecret.Data,
 				Alg:  oldSecret.Alg,
 				Alg:  oldSecret.Alg,
 			}
 			}
@@ -153,7 +153,7 @@ func SwarmSpecUpdateAcceptancePolicy(spec *swarmapi.ClusterSpec, acceptancePolic
 	return nil
 	return nil
 }
 }
 
 
-func getOldSecret(oldSpec *swarmapi.ClusterSpec, role swarmapi.NodeRole) *swarmapi.AcceptancePolicy_RoleAdmissionPolicy_HashedSecret {
+func getOldSecret(oldSpec *swarmapi.ClusterSpec, role swarmapi.NodeRole) *swarmapi.AcceptancePolicy_RoleAdmissionPolicy_Secret {
 	if oldSpec == nil {
 	if oldSpec == nil {
 		return nil
 		return nil
 	}
 	}

+ 3 - 0
hack/.vendor-helpers.sh

@@ -131,6 +131,9 @@ clean() {
 		findArgs+=( -path "vendor/src/$import" )
 		findArgs+=( -path "vendor/src/$import" )
 	done
 	done
 
 
+	# The docker proxy command is built from libnetwork
+	findArgs+=( -or -path vendor/src/github.com/docker/libnetwork/cmd/proxy )
+
 	local IFS=$'\n'
 	local IFS=$'\n'
 	local prune=( $($find vendor -depth -type d -not '(' "${findArgs[@]}" ')') )
 	local prune=( $($find vendor -depth -type d -not '(' "${findArgs[@]}" ')') )
 	unset IFS
 	unset IFS

+ 1 - 0
hack/make/.binary-setup

@@ -2,3 +2,4 @@
 
 
 DOCKER_CLIENT_BINARY_NAME='docker'
 DOCKER_CLIENT_BINARY_NAME='docker'
 DOCKER_DAEMON_BINARY_NAME='dockerd'
 DOCKER_DAEMON_BINARY_NAME='dockerd'
+DOCKER_PROXY_BINARY_NAME='docker-proxy'

+ 1 - 0
hack/make/.build-deb/rules

@@ -22,6 +22,7 @@ override_dh_auto_install:
 	mkdir -p debian/docker-engine/usr/bin
 	mkdir -p debian/docker-engine/usr/bin
 	cp -aT "$$(readlink -f bundles/$(VERSION)/dynbinary-client/docker)" debian/docker-engine/usr/bin/docker
 	cp -aT "$$(readlink -f bundles/$(VERSION)/dynbinary-client/docker)" debian/docker-engine/usr/bin/docker
 	cp -aT "$$(readlink -f bundles/$(VERSION)/dynbinary-daemon/dockerd)" debian/docker-engine/usr/bin/dockerd
 	cp -aT "$$(readlink -f bundles/$(VERSION)/dynbinary-daemon/dockerd)" debian/docker-engine/usr/bin/dockerd
+	cp -aT "$$(readlink -f bundles/$(VERSION)/dynbinary-daemon/docker-proxy)" debian/docker-engine/usr/bin/docker-proxy
 	cp -aT /usr/local/bin/containerd debian/docker-engine/usr/bin/docker-containerd
 	cp -aT /usr/local/bin/containerd debian/docker-engine/usr/bin/docker-containerd
 	cp -aT /usr/local/bin/containerd-shim debian/docker-engine/usr/bin/docker-containerd-shim
 	cp -aT /usr/local/bin/containerd-shim debian/docker-engine/usr/bin/docker-containerd-shim
 	cp -aT /usr/local/bin/ctr debian/docker-engine/usr/bin/docker-containerd-ctr
 	cp -aT /usr/local/bin/ctr debian/docker-engine/usr/bin/docker-containerd-ctr

+ 1 - 0
hack/make/.build-rpm/docker-engine.spec

@@ -126,6 +126,7 @@ export DOCKER_GITCOMMIT=%{_gitcommit}
 install -d $RPM_BUILD_ROOT/%{_bindir}
 install -d $RPM_BUILD_ROOT/%{_bindir}
 install -p -m 755 bundles/%{_origversion}/dynbinary-client/docker-%{_origversion} $RPM_BUILD_ROOT/%{_bindir}/docker
 install -p -m 755 bundles/%{_origversion}/dynbinary-client/docker-%{_origversion} $RPM_BUILD_ROOT/%{_bindir}/docker
 install -p -m 755 bundles/%{_origversion}/dynbinary-daemon/dockerd-%{_origversion} $RPM_BUILD_ROOT/%{_bindir}/dockerd
 install -p -m 755 bundles/%{_origversion}/dynbinary-daemon/dockerd-%{_origversion} $RPM_BUILD_ROOT/%{_bindir}/dockerd
+install -p -m 755 bundles/%{_origversion}/dynbinary-daemon/docker-proxy-%{_origversion} $RPM_BUILD_ROOT/%{_bindir}/docker-proxy
 
 
 # install containerd
 # install containerd
 install -p -m 755 /usr/local/bin/containerd $RPM_BUILD_ROOT/%{_bindir}/docker-containerd
 install -p -m 755 /usr/local/bin/containerd $RPM_BUILD_ROOT/%{_bindir}/docker-containerd

+ 3 - 0
hack/make/binary-daemon

@@ -9,5 +9,8 @@ set -e
 	export BINARY_SHORT_NAME="$DOCKER_DAEMON_BINARY_NAME"
 	export BINARY_SHORT_NAME="$DOCKER_DAEMON_BINARY_NAME"
 	export SOURCE_PATH='./cmd/dockerd'
 	export SOURCE_PATH='./cmd/dockerd'
 	source "${MAKEDIR}/.binary"
 	source "${MAKEDIR}/.binary"
+	export BINARY_SHORT_NAME="$DOCKER_PROXY_BINARY_NAME"
+	export SOURCE_PATH='./vendor/src/github.com/docker/libnetwork/cmd/proxy'
+	source "${MAKEDIR}/.binary"
 	copy_containerd "$DEST" 'hash'
 	copy_containerd "$DEST" 'hash'
 )
 )

+ 3 - 0
hack/make/dynbinary-daemon

@@ -9,4 +9,7 @@ set -e
 	export BUILDFLAGS=( "${BUILDFLAGS[@]/netgo /}" ) # disable netgo, since we don't need it for a dynamic binary
 	export BUILDFLAGS=( "${BUILDFLAGS[@]/netgo /}" ) # disable netgo, since we don't need it for a dynamic binary
 	export BUILDFLAGS=( "${BUILDFLAGS[@]/static_build /}" ) # we're not building a "static" binary here
 	export BUILDFLAGS=( "${BUILDFLAGS[@]/static_build /}" ) # we're not building a "static" binary here
 	source "${MAKEDIR}/.binary"
 	source "${MAKEDIR}/.binary"
+	export BINARY_SHORT_NAME='docker-proxy'
+	export SOURCE_PATH='./vendor/src/github.com/docker/libnetwork/cmd/proxy'
+	source "${MAKEDIR}/.binary"
 )
 )

+ 18 - 0
hack/make/gccgo

@@ -5,6 +5,9 @@ BINARY_NAME="dockerd-$VERSION"
 BINARY_EXTENSION="$(binary_extension)"
 BINARY_EXTENSION="$(binary_extension)"
 BINARY_FULLNAME="$BINARY_NAME$BINARY_EXTENSION"
 BINARY_FULLNAME="$BINARY_NAME$BINARY_EXTENSION"
 
 
+PROXY_NAME="docker-proxy-$VERSION"
+PROXY_FULLNAME="$PROXY_NAME$BINARY_EXTENSION"
+
 CLIENTBIN_NAME="docker-$VERSION"
 CLIENTBIN_NAME="docker-$VERSION"
 CLIENTBIN_FULLNAME="$CLIENTBIN_NAME$BINARY_EXTENSION"
 CLIENTBIN_FULLNAME="$CLIENTBIN_NAME$BINARY_EXTENSION"
 
 
@@ -29,6 +32,21 @@ go build -compiler=gccgo \
 echo "Created binary: $DEST/$BINARY_FULLNAME"
 echo "Created binary: $DEST/$BINARY_FULLNAME"
 ln -sf "$BINARY_FULLNAME" "$DEST/dockerd$BINARY_EXTENSION"
 ln -sf "$BINARY_FULLNAME" "$DEST/dockerd$BINARY_EXTENSION"
 
 
+go build -compiler=gccgo \
+	-o "$DEST/$PROXY_FULLNAME" \
+	"${BUILDFLAGS[@]}" \
+	-gccgoflags "
+		-g
+		$EXTLDFLAGS_STATIC
+		-Wl,--no-export-dynamic
+		-ldl
+		-pthread
+	" \
+	./vendor/src/github.com/docker/libnetwork/cmd/proxy
+
+echo "Created binary: $DEST/$PROXY_FULLNAME"
+ln -sf "$PROXY_FULLNAME" "$DEST/docker-proxy$BINARY_EXTENSION"
+
 copy_containerd "$DEST" "hash"
 copy_containerd "$DEST" "hash"
 hash_files "$DEST/$BINARY_FULLNAME"
 hash_files "$DEST/$BINARY_FULLNAME"
 
 

+ 1 - 0
hack/make/install-binary-daemon

@@ -7,4 +7,5 @@ rm -rf "$DEST"
 	DEST="$(dirname $DEST)/binary-daemon"
 	DEST="$(dirname $DEST)/binary-daemon"
 	source "${MAKEDIR}/.binary-setup"
 	source "${MAKEDIR}/.binary-setup"
 	install_binary "${DEST}/${DOCKER_DAEMON_BINARY_NAME}"
 	install_binary "${DEST}/${DOCKER_DAEMON_BINARY_NAME}"
+	install_binary "${DEST}/${DOCKER_PROXY_BINARY_NAME}"
 )
 )

+ 5 - 0
hack/make/tgz

@@ -18,6 +18,7 @@ for d in "$CROSS/"*/*; do
 
 
 	BINARY_NAME="${DOCKER_CLIENT_BINARY_NAME}-$VERSION"
 	BINARY_NAME="${DOCKER_CLIENT_BINARY_NAME}-$VERSION"
 	DAEMON_BINARY_NAME="${DOCKER_DAEMON_BINARY_NAME}-$VERSION"
 	DAEMON_BINARY_NAME="${DOCKER_DAEMON_BINARY_NAME}-$VERSION"
+	PROXY_BINARY_NAME="${DOCKER_PROXY_BINARY_NAME}-$VERSION"
 	BINARY_EXTENSION="$(export GOOS && binary_extension)"
 	BINARY_EXTENSION="$(export GOOS && binary_extension)"
 	if [ "$GOOS" = 'windows' ]; then
 	if [ "$GOOS" = 'windows' ]; then
 		# if windows use a zip, not tgz
 		# if windows use a zip, not tgz
@@ -29,6 +30,7 @@ for d in "$CROSS/"*/*; do
 	fi
 	fi
 	BINARY_FULLNAME="$BINARY_NAME$BINARY_EXTENSION"
 	BINARY_FULLNAME="$BINARY_NAME$BINARY_EXTENSION"
 	DAEMON_BINARY_FULLNAME="$DAEMON_BINARY_NAME$BINARY_EXTENSION"
 	DAEMON_BINARY_FULLNAME="$DAEMON_BINARY_NAME$BINARY_EXTENSION"
+	PROXY_BINARY_FULLNAME="$PROXY_BINARY_NAME$BINARY_EXTENSION"
 	mkdir -p "$DEST/$GOOS/$GOARCH"
 	mkdir -p "$DEST/$GOOS/$GOARCH"
 	TGZ="$DEST/$GOOS/$GOARCH/$BINARY_NAME$BUNDLE_EXTENSION"
 	TGZ="$DEST/$GOOS/$GOARCH/$BINARY_NAME$BUNDLE_EXTENSION"
 
 
@@ -47,6 +49,9 @@ for d in "$CROSS/"*/*; do
 	if [ -f "$d/$DAEMON_BINARY_FULLNAME" ]; then
 	if [ -f "$d/$DAEMON_BINARY_FULLNAME" ]; then
 		cp -L "$d/$DAEMON_BINARY_FULLNAME" "$TAR_PATH/${DOCKER_DAEMON_BINARY_NAME}${BINARY_EXTENSION}"
 		cp -L "$d/$DAEMON_BINARY_FULLNAME" "$TAR_PATH/${DOCKER_DAEMON_BINARY_NAME}${BINARY_EXTENSION}"
 	fi
 	fi
+	if [ -f "$d/$PROXY_BINARY_FULLNAME" ]; then
+		cp -L "$d/$PROXY_BINARY_FULLNAME" "$TAR_PATH/${DOCKER_PROXY_BINARY_NAME}${BINARY_EXTENSION}"
+	fi
 
 
 	# copy over all the containerd binaries
 	# copy over all the containerd binaries
 	copy_containerd $TAR_PATH
 	copy_containerd $TAR_PATH

+ 2 - 2
hack/vendor.sh

@@ -65,7 +65,7 @@ clone git github.com/RackSec/srslog 259aed10dfa74ea2961eddd1d9847619f6e98837
 clone git github.com/imdario/mergo 0.2.1
 clone git github.com/imdario/mergo 0.2.1
 
 
 #get libnetwork packages
 #get libnetwork packages
-clone git github.com/docker/libnetwork 377a7337f2387cce3be1df7a4503446147b68ff1
+clone git github.com/docker/libnetwork 6eece7dcc21dcd34d907f3e91dd71cb8640b661c
 clone git github.com/docker/go-events 39718a26497694185f8fb58a7d6f31947f3dc42d
 clone git github.com/docker/go-events 39718a26497694185f8fb58a7d6f31947f3dc42d
 clone git github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
 clone git github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
 clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
 clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
@@ -139,7 +139,7 @@ clone git github.com/docker/docker-credential-helpers v0.3.0
 clone git github.com/docker/containerd 1b3a81545ca79456086dc2aa424357be98b962ee
 clone git github.com/docker/containerd 1b3a81545ca79456086dc2aa424357be98b962ee
 
 
 # cluster
 # cluster
-clone git github.com/docker/swarmkit 24eaf0021a2eea7938fce7493ce4731f53c2b87c
+clone git github.com/docker/swarmkit 16fa595d3b6fec012830179dc8e9b2d90335527d
 clone git github.com/golang/mock bd3c8e81be01eef76d4b503f5e687d2d1354d2d9
 clone git github.com/golang/mock bd3c8e81be01eef76d4b503f5e687d2d1354d2d9
 clone git github.com/gogo/protobuf 43a2e0b1c32252bfbbdf81f7faa7a88fb3fa4028
 clone git github.com/gogo/protobuf 43a2e0b1c32252bfbbdf81f7faa7a88fb3fa4028
 clone git github.com/cloudflare/cfssl b895b0549c0ff676f92cf09ba971ae02bb41367b
 clone git github.com/cloudflare/cfssl b895b0549c0ff676f92cf09ba971ae02bb41367b

+ 0 - 4
integration-cli/docker_api_swarm_test.go

@@ -277,8 +277,6 @@ func (s *DockerSwarmSuite) TestApiSwarmPromoteDemote(c *check.C) {
 		}
 		}
 		if i > 100 {
 		if i > 100 {
 			c.Errorf("node did not turn into manager")
 			c.Errorf("node did not turn into manager")
-		} else {
-			break
 		}
 		}
 		time.Sleep(100 * time.Millisecond)
 		time.Sleep(100 * time.Millisecond)
 	}
 	}
@@ -296,8 +294,6 @@ func (s *DockerSwarmSuite) TestApiSwarmPromoteDemote(c *check.C) {
 		}
 		}
 		if i > 100 {
 		if i > 100 {
 			c.Errorf("node did not turn into worker")
 			c.Errorf("node did not turn into worker")
-		} else {
-			break
 		}
 		}
 		time.Sleep(100 * time.Millisecond)
 		time.Sleep(100 * time.Millisecond)
 	}
 	}

+ 0 - 216
pkg/proxy/network_proxy_test.go

@@ -1,216 +0,0 @@
-package proxy
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"net"
-	"strings"
-	"testing"
-	"time"
-)
-
-var testBuf = []byte("Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo")
-var testBufSize = len(testBuf)
-
-type EchoServer interface {
-	Run()
-	Close()
-	LocalAddr() net.Addr
-}
-
-type TCPEchoServer struct {
-	listener net.Listener
-	testCtx  *testing.T
-}
-
-type UDPEchoServer struct {
-	conn    net.PacketConn
-	testCtx *testing.T
-}
-
-func NewEchoServer(t *testing.T, proto, address string) EchoServer {
-	var server EchoServer
-	if strings.HasPrefix(proto, "tcp") {
-		listener, err := net.Listen(proto, address)
-		if err != nil {
-			t.Fatal(err)
-		}
-		server = &TCPEchoServer{listener: listener, testCtx: t}
-	} else {
-		socket, err := net.ListenPacket(proto, address)
-		if err != nil {
-			t.Fatal(err)
-		}
-		server = &UDPEchoServer{conn: socket, testCtx: t}
-	}
-	return server
-}
-
-func (server *TCPEchoServer) Run() {
-	go func() {
-		for {
-			client, err := server.listener.Accept()
-			if err != nil {
-				return
-			}
-			go func(client net.Conn) {
-				if _, err := io.Copy(client, client); err != nil {
-					server.testCtx.Logf("can't echo to the client: %v\n", err.Error())
-				}
-				client.Close()
-			}(client)
-		}
-	}()
-}
-
-func (server *TCPEchoServer) LocalAddr() net.Addr { return server.listener.Addr() }
-func (server *TCPEchoServer) Close()              { server.listener.Close() }
-
-func (server *UDPEchoServer) Run() {
-	go func() {
-		readBuf := make([]byte, 1024)
-		for {
-			read, from, err := server.conn.ReadFrom(readBuf)
-			if err != nil {
-				return
-			}
-			for i := 0; i != read; {
-				written, err := server.conn.WriteTo(readBuf[i:read], from)
-				if err != nil {
-					break
-				}
-				i += written
-			}
-		}
-	}()
-}
-
-func (server *UDPEchoServer) LocalAddr() net.Addr { return server.conn.LocalAddr() }
-func (server *UDPEchoServer) Close()              { server.conn.Close() }
-
-func testProxyAt(t *testing.T, proto string, proxy Proxy, addr string) {
-	defer proxy.Close()
-	go proxy.Run()
-	client, err := net.Dial(proto, addr)
-	if err != nil {
-		t.Fatalf("Can't connect to the proxy: %v", err)
-	}
-	defer client.Close()
-	client.SetDeadline(time.Now().Add(10 * time.Second))
-	if _, err = client.Write(testBuf); err != nil {
-		t.Fatal(err)
-	}
-	recvBuf := make([]byte, testBufSize)
-	if _, err = client.Read(recvBuf); err != nil {
-		t.Fatal(err)
-	}
-	if !bytes.Equal(testBuf, recvBuf) {
-		t.Fatal(fmt.Errorf("Expected [%v] but got [%v]", testBuf, recvBuf))
-	}
-}
-
-func testProxy(t *testing.T, proto string, proxy Proxy) {
-	testProxyAt(t, proto, proxy, proxy.FrontendAddr().String())
-}
-
-func TestTCP4Proxy(t *testing.T) {
-	backend := NewEchoServer(t, "tcp", "127.0.0.1:0")
-	defer backend.Close()
-	backend.Run()
-	frontendAddr := &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0}
-	proxy, err := NewProxy(frontendAddr, backend.LocalAddr())
-	if err != nil {
-		t.Fatal(err)
-	}
-	testProxy(t, "tcp", proxy)
-}
-
-func TestTCP6Proxy(t *testing.T) {
-	backend := NewEchoServer(t, "tcp", "[::1]:0")
-	defer backend.Close()
-	backend.Run()
-	frontendAddr := &net.TCPAddr{IP: net.IPv6loopback, Port: 0}
-	proxy, err := NewProxy(frontendAddr, backend.LocalAddr())
-	if err != nil {
-		t.Fatal(err)
-	}
-	testProxy(t, "tcp", proxy)
-}
-
-func TestTCPDualStackProxy(t *testing.T) {
-	// If I understand `godoc -src net favoriteAddrFamily` (used by the
-	// net.Listen* functions) correctly this should work, but it doesn't.
-	t.Skip("No support for dual stack yet")
-	backend := NewEchoServer(t, "tcp", "[::1]:0")
-	defer backend.Close()
-	backend.Run()
-	frontendAddr := &net.TCPAddr{IP: net.IPv6loopback, Port: 0}
-	proxy, err := NewProxy(frontendAddr, backend.LocalAddr())
-	if err != nil {
-		t.Fatal(err)
-	}
-	ipv4ProxyAddr := &net.TCPAddr{
-		IP:   net.IPv4(127, 0, 0, 1),
-		Port: proxy.FrontendAddr().(*net.TCPAddr).Port,
-	}
-	testProxyAt(t, "tcp", proxy, ipv4ProxyAddr.String())
-}
-
-func TestUDP4Proxy(t *testing.T) {
-	backend := NewEchoServer(t, "udp", "127.0.0.1:0")
-	defer backend.Close()
-	backend.Run()
-	frontendAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0}
-	proxy, err := NewProxy(frontendAddr, backend.LocalAddr())
-	if err != nil {
-		t.Fatal(err)
-	}
-	testProxy(t, "udp", proxy)
-}
-
-func TestUDP6Proxy(t *testing.T) {
-	backend := NewEchoServer(t, "udp", "[::1]:0")
-	defer backend.Close()
-	backend.Run()
-	frontendAddr := &net.UDPAddr{IP: net.IPv6loopback, Port: 0}
-	proxy, err := NewProxy(frontendAddr, backend.LocalAddr())
-	if err != nil {
-		t.Fatal(err)
-	}
-	testProxy(t, "udp", proxy)
-}
-
-func TestUDPWriteError(t *testing.T) {
-	frontendAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0}
-	// Hopefully, this port will be free: */
-	backendAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 25587}
-	proxy, err := NewProxy(frontendAddr, backendAddr)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer proxy.Close()
-	go proxy.Run()
-	client, err := net.Dial("udp", "127.0.0.1:25587")
-	if err != nil {
-		t.Fatalf("Can't connect to the proxy: %v", err)
-	}
-	defer client.Close()
-	// Make sure the proxy doesn't stop when there is no actual backend:
-	client.Write(testBuf)
-	client.Write(testBuf)
-	backend := NewEchoServer(t, "udp", "127.0.0.1:25587")
-	defer backend.Close()
-	backend.Run()
-	client.SetDeadline(time.Now().Add(10 * time.Second))
-	if _, err = client.Write(testBuf); err != nil {
-		t.Fatal(err)
-	}
-	recvBuf := make([]byte, testBufSize)
-	if _, err = client.Read(recvBuf); err != nil {
-		t.Fatal(err)
-	}
-	if !bytes.Equal(testBuf, recvBuf) {
-		t.Fatal(fmt.Errorf("Expected [%v] but got [%v]", testBuf, recvBuf))
-	}
-}

+ 5 - 2
vendor/src/github.com/docker/libnetwork/Makefile

@@ -7,6 +7,7 @@ docker = docker run --rm -it ${dockerargs} $$EXTRA_ARGS ${container_env} ${build
 ciargs = -e CIRCLECI -e "COVERALLS_TOKEN=$$COVERALLS_TOKEN" -e "INSIDECONTAINER=-incontainer=true"
 ciargs = -e CIRCLECI -e "COVERALLS_TOKEN=$$COVERALLS_TOKEN" -e "INSIDECONTAINER=-incontainer=true"
 cidocker = docker run ${dockerargs} ${ciargs} $$EXTRA_ARGS ${container_env} ${build_image}
 cidocker = docker run ${dockerargs} ${ciargs} $$EXTRA_ARGS ${container_env} ${build_image}
 CROSS_PLATFORMS = linux/amd64 linux/386 linux/arm windows/amd64
 CROSS_PLATFORMS = linux/amd64 linux/386 linux/arm windows/amd64
+export PATH := $(CURDIR)/bin:$(PATH)
 
 
 all: ${build_image}.created build check integration-tests clean
 all: ${build_image}.created build check integration-tests clean
 
 
@@ -24,10 +25,11 @@ build: ${build_image}.created
 build-local:
 build-local:
 	@mkdir -p "bin"
 	@mkdir -p "bin"
 	$(shell which godep) go build -tags experimental -o "bin/dnet" ./cmd/dnet
 	$(shell which godep) go build -tags experimental -o "bin/dnet" ./cmd/dnet
+	$(shell which godep) go build -o "bin/docker-proxy" ./cmd/proxy
 
 
 clean:
 clean:
 	@if [ -d bin ]; then \
 	@if [ -d bin ]; then \
-		echo "Removing dnet binaries"; \
+		echo "Removing dnet and proxy binaries"; \
 		rm -rf bin; \
 		rm -rf bin; \
 	fi
 	fi
 
 
@@ -41,6 +43,7 @@ cross: ${build_image}.created
 
 
 cross-local:
 cross-local:
 	$(shell which godep) go build -o "bin/dnet-$$GOOS-$$GOARCH" ./cmd/dnet
 	$(shell which godep) go build -o "bin/dnet-$$GOOS-$$GOARCH" ./cmd/dnet
+	$(shell which godep) go build -o "bin/docker-proxy-$$GOOS-$$GOARCH" ./cmd/proxy
 
 
 check: ${build_image}.created
 check: ${build_image}.created
 	@${docker} ./wrapmake.sh check-local
 	@${docker} ./wrapmake.sh check-local
@@ -102,4 +105,4 @@ circle-ci-check: ${build_image}.created
 circle-ci-build: ${build_image}.created
 circle-ci-build: ${build_image}.created
 	@${cidocker} make build-local
 	@${cidocker} make build-local
 
 
-circle-ci: circle-ci-check circle-ci-cross circle-ci-build integration-tests
+circle-ci: circle-ci-build circle-ci-check circle-ci-cross integration-tests

+ 67 - 0
vendor/src/github.com/docker/libnetwork/cmd/proxy/main.go

@@ -0,0 +1,67 @@
+package main
+
+import (
+	"flag"
+	"fmt"
+	"log"
+	"net"
+	"os"
+	"os/signal"
+	"syscall"
+)
+
+func main() {
+	f := os.NewFile(3, "signal-parent")
+	host, container := parseHostContainerAddrs()
+
+	p, err := NewProxy(host, container)
+	if err != nil {
+		fmt.Fprintf(f, "1\n%s", err)
+		f.Close()
+		os.Exit(1)
+	}
+	go handleStopSignals(p)
+	fmt.Fprint(f, "0\n")
+	f.Close()
+
+	// Run will block until the proxy stops
+	p.Run()
+}
+
+// parseHostContainerAddrs parses the flags passed on reexec to create the TCP or UDP
+// net.Addrs to map the host and container ports
+func parseHostContainerAddrs() (host net.Addr, container net.Addr) {
+	var (
+		proto         = flag.String("proto", "tcp", "proxy protocol")
+		hostIP        = flag.String("host-ip", "", "host ip")
+		hostPort      = flag.Int("host-port", -1, "host port")
+		containerIP   = flag.String("container-ip", "", "container ip")
+		containerPort = flag.Int("container-port", -1, "container port")
+	)
+
+	flag.Parse()
+
+	switch *proto {
+	case "tcp":
+		host = &net.TCPAddr{IP: net.ParseIP(*hostIP), Port: *hostPort}
+		container = &net.TCPAddr{IP: net.ParseIP(*containerIP), Port: *containerPort}
+	case "udp":
+		host = &net.UDPAddr{IP: net.ParseIP(*hostIP), Port: *hostPort}
+		container = &net.UDPAddr{IP: net.ParseIP(*containerIP), Port: *containerPort}
+	default:
+		log.Fatalf("unsupported protocol %s", *proto)
+	}
+
+	return host, container
+}
+
+func handleStopSignals(p Proxy) {
+	s := make(chan os.Signal, 10)
+	signal.Notify(s, os.Interrupt, syscall.SIGTERM)
+
+	for range s {
+		p.Close()
+
+		os.Exit(0)
+	}
+}

+ 2 - 2
pkg/proxy/proxy.go → vendor/src/github.com/docker/libnetwork/cmd/proxy/proxy.go

@@ -1,6 +1,6 @@
-// Package proxy provides a network Proxy interface and implementations for TCP
+// docker-proxy provides a network Proxy interface and implementations for TCP
 // and UDP.
 // and UDP.
-package proxy
+package main
 
 
 import (
 import (
 	"fmt"
 	"fmt"

+ 1 - 1
pkg/proxy/stub_proxy.go → vendor/src/github.com/docker/libnetwork/cmd/proxy/stub_proxy.go

@@ -1,4 +1,4 @@
-package proxy
+package main
 
 
 import (
 import (
 	"net"
 	"net"

+ 1 - 1
pkg/proxy/tcp_proxy.go → vendor/src/github.com/docker/libnetwork/cmd/proxy/tcp_proxy.go

@@ -1,4 +1,4 @@
-package proxy
+package main
 
 
 import (
 import (
 	"io"
 	"io"

+ 1 - 1
pkg/proxy/udp_proxy.go → vendor/src/github.com/docker/libnetwork/cmd/proxy/udp_proxy.go

@@ -1,4 +1,4 @@
-package proxy
+package main
 
 
 import (
 import (
 	"encoding/binary"
 	"encoding/binary"

+ 5 - 0
vendor/src/github.com/docker/libnetwork/controller.go

@@ -193,6 +193,11 @@ func New(cfgOptions ...config.Option) (NetworkController, error) {
 			return nil, err
 			return nil, err
 		}
 		}
 	}
 	}
+
+	if err = initIPAMDrivers(drvRegistry, nil, c.getStore(datastore.GlobalScope)); err != nil {
+		return nil, err
+	}
+
 	c.drvRegistry = drvRegistry
 	c.drvRegistry = drvRegistry
 
 
 	if c.cfg != nil && c.cfg.Cluster.Watcher != nil {
 	if c.cfg != nil && c.cfg.Cluster.Watcher != nil {

+ 1 - 1
vendor/src/github.com/docker/libnetwork/drivers/bridge/bridge.go

@@ -330,7 +330,7 @@ func (c *networkConfiguration) conflictsWithNetworks(id string, others []*bridge
 		// bridges. This could not be completely caught by the config conflict
 		// bridges. This could not be completely caught by the config conflict
 		// check, because networks which config does not specify the AddressIPv4
 		// check, because networks which config does not specify the AddressIPv4
 		// get their address and subnet selected by the driver (see electBridgeIPv4())
 		// get their address and subnet selected by the driver (see electBridgeIPv4())
-		if c.AddressIPv4 != nil {
+		if c.AddressIPv4 != nil && nwBridge.bridgeIPv4 != nil {
 			if nwBridge.bridgeIPv4.Contains(c.AddressIPv4.IP) ||
 			if nwBridge.bridgeIPv4.Contains(c.AddressIPv4.IP) ||
 				c.AddressIPv4.Contains(nwBridge.bridgeIPv4.IP) {
 				c.AddressIPv4.Contains(nwBridge.bridgeIPv4.IP) {
 				return types.ForbiddenErrorf("conflicts with network %s (%s) by ip network", nwID, nwConfig.BridgeName)
 				return types.ForbiddenErrorf("conflicts with network %s (%s) by ip network", nwID, nwConfig.BridgeName)

+ 23 - 0
vendor/src/github.com/docker/libnetwork/drivers_ipam.go

@@ -0,0 +1,23 @@
+package libnetwork
+
+import (
+	"github.com/docker/libnetwork/drvregistry"
+	"github.com/docker/libnetwork/ipamapi"
+	builtinIpam "github.com/docker/libnetwork/ipams/builtin"
+	nullIpam "github.com/docker/libnetwork/ipams/null"
+	remoteIpam "github.com/docker/libnetwork/ipams/remote"
+)
+
+func initIPAMDrivers(r *drvregistry.DrvRegistry, lDs, gDs interface{}) error {
+	for _, fn := range [](func(ipamapi.Callback, interface{}, interface{}) error){
+		builtinIpam.Init,
+		remoteIpam.Init,
+		nullIpam.Init,
+	} {
+		if err := fn(r, lDs, gDs); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}

+ 0 - 22
vendor/src/github.com/docker/libnetwork/drvregistry/drvregistry.go

@@ -8,10 +8,6 @@ import (
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/ipamapi"
 	"github.com/docker/libnetwork/ipamapi"
 	"github.com/docker/libnetwork/types"
 	"github.com/docker/libnetwork/types"
-
-	builtinIpam "github.com/docker/libnetwork/ipams/builtin"
-	nullIpam "github.com/docker/libnetwork/ipams/null"
-	remoteIpam "github.com/docker/libnetwork/ipams/remote"
 )
 )
 
 
 type driverData struct {
 type driverData struct {
@@ -64,10 +60,6 @@ func New(lDs, gDs interface{}, dfn DriverNotifyFunc, ifn IPAMNotifyFunc) (*DrvRe
 		ifn:         ifn,
 		ifn:         ifn,
 	}
 	}
 
 
-	if err := r.initIPAMs(lDs, gDs); err != nil {
-		return nil, err
-	}
-
 	return r, nil
 	return r, nil
 }
 }
 
 
@@ -157,20 +149,6 @@ func (r *DrvRegistry) IPAMDefaultAddressSpaces(name string) (string, string, err
 	return i.defaultLocalAddressSpace, i.defaultGlobalAddressSpace, nil
 	return i.defaultLocalAddressSpace, i.defaultGlobalAddressSpace, nil
 }
 }
 
 
-func (r *DrvRegistry) initIPAMs(lDs, gDs interface{}) error {
-	for _, fn := range [](func(ipamapi.Callback, interface{}, interface{}) error){
-		builtinIpam.Init,
-		remoteIpam.Init,
-		nullIpam.Init,
-	} {
-		if err := fn(r, nil, gDs); err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
-
 // RegisterDriver registers the network driver when it gets discovered.
 // RegisterDriver registers the network driver when it gets discovered.
 func (r *DrvRegistry) RegisterDriver(ntype string, driver driverapi.Driver, capability driverapi.Capability) error {
 func (r *DrvRegistry) RegisterDriver(ntype string, driver driverapi.Driver, capability driverapi.Capability) error {
 	if strings.TrimSpace(ntype) == "" {
 	if strings.TrimSpace(ntype) == "" {

+ 15 - 6
vendor/src/github.com/docker/libnetwork/etchosts/etchosts.go

@@ -119,25 +119,34 @@ func Add(path string, recs []Record) error {
 		return nil
 		return nil
 	}
 	}
 
 
-	f, err := os.Open(path)
+	b, err := mergeRecords(path, recs)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	content := bytes.NewBuffer(nil)
+	return ioutil.WriteFile(path, b, 0644)
+}
 
 
-	_, err = content.ReadFrom(f)
+func mergeRecords(path string, recs []Record) ([]byte, error) {
+	f, err := os.Open(path)
 	if err != nil {
 	if err != nil {
-		return err
+		return nil, err
+	}
+	defer f.Close()
+
+	content := bytes.NewBuffer(nil)
+
+	if _, err := content.ReadFrom(f); err != nil {
+		return nil, err
 	}
 	}
 
 
 	for _, r := range recs {
 	for _, r := range recs {
 		if _, err := r.WriteTo(content); err != nil {
 		if _, err := r.WriteTo(content); err != nil {
-			return err
+			return nil, err
 		}
 		}
 	}
 	}
 
 
-	return ioutil.WriteFile(path, content.Bytes(), 0644)
+	return content.Bytes(), nil
 }
 }
 
 
 // Delete deletes an arbitrary number of Records already existing in /etc/hosts file
 // Delete deletes an arbitrary number of Records already existing in /etc/hosts file

+ 1 - 1
vendor/src/github.com/docker/libnetwork/networkdb/cluster.go

@@ -14,7 +14,7 @@ import (
 	"github.com/hashicorp/memberlist"
 	"github.com/hashicorp/memberlist"
 )
 )
 
 
-const reapInterval = 2 * time.Second
+const reapInterval = 30 * time.Second
 
 
 type logWriter struct{}
 type logWriter struct{}
 
 

+ 5 - 0
vendor/src/github.com/docker/libnetwork/networkdb/delegate.go

@@ -130,6 +130,11 @@ func (nDB *NetworkDB) handleTableMessage(buf []byte, isBulkSync bool) {
 		return
 		return
 	}
 	}
 
 
+	// Ignore messages that this node generated.
+	if tEvent.NodeName == nDB.config.NodeName {
+		return
+	}
+
 	// Do not rebroadcast a bulk sync
 	// Do not rebroadcast a bulk sync
 	if rebroadcast := nDB.handleTableEvent(&tEvent); rebroadcast && !isBulkSync {
 	if rebroadcast := nDB.handleTableEvent(&tEvent); rebroadcast && !isBulkSync {
 		var err error
 		var err error

+ 8 - 2
vendor/src/github.com/docker/libnetwork/portmapper/mapper.go

@@ -90,7 +90,10 @@ func (pm *PortMapper) MapRange(container net.Addr, hostIP net.IP, hostPortStart,
 		}
 		}
 
 
 		if useProxy {
 		if useProxy {
-			m.userlandProxy = newProxy(proto, hostIP, allocatedHostPort, container.(*net.TCPAddr).IP, container.(*net.TCPAddr).Port)
+			m.userlandProxy, err = newProxy(proto, hostIP, allocatedHostPort, container.(*net.TCPAddr).IP, container.(*net.TCPAddr).Port)
+			if err != nil {
+				return nil, err
+			}
 		} else {
 		} else {
 			m.userlandProxy = newDummyProxy(proto, hostIP, allocatedHostPort)
 			m.userlandProxy = newDummyProxy(proto, hostIP, allocatedHostPort)
 		}
 		}
@@ -107,7 +110,10 @@ func (pm *PortMapper) MapRange(container net.Addr, hostIP net.IP, hostPortStart,
 		}
 		}
 
 
 		if useProxy {
 		if useProxy {
-			m.userlandProxy = newProxy(proto, hostIP, allocatedHostPort, container.(*net.UDPAddr).IP, container.(*net.UDPAddr).Port)
+			m.userlandProxy, err = newProxy(proto, hostIP, allocatedHostPort, container.(*net.UDPAddr).IP, container.(*net.UDPAddr).Port)
+			if err != nil {
+				return nil, err
+			}
 		} else {
 		} else {
 			m.userlandProxy = newDummyProxy(proto, hostIP, allocatedHostPort)
 			m.userlandProxy = newDummyProxy(proto, hostIP, allocatedHostPort)
 		}
 		}

+ 2 - 2
vendor/src/github.com/docker/libnetwork/portmapper/mock_proxy.go

@@ -2,8 +2,8 @@ package portmapper
 
 
 import "net"
 import "net"
 
 
-func newMockProxyCommand(proto string, hostIP net.IP, hostPort int, containerIP net.IP, containerPort int) userlandProxy {
-	return &mockProxyCommand{}
+func newMockProxyCommand(proto string, hostIP net.IP, hostPort int, containerIP net.IP, containerPort int) (userlandProxy, error) {
+	return &mockProxyCommand{}, nil
 }
 }
 
 
 type mockProxyCommand struct {
 type mockProxyCommand struct {

+ 6 - 67
vendor/src/github.com/docker/libnetwork/portmapper/proxy.go

@@ -1,29 +1,19 @@
 package portmapper
 package portmapper
 
 
 import (
 import (
-	"flag"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
 	"io/ioutil"
 	"io/ioutil"
-	"log"
 	"net"
 	"net"
 	"os"
 	"os"
 	"os/exec"
 	"os/exec"
-	"os/signal"
 	"strconv"
 	"strconv"
 	"syscall"
 	"syscall"
 	"time"
 	"time"
-
-	"github.com/docker/docker/pkg/proxy"
-	"github.com/docker/docker/pkg/reexec"
 )
 )
 
 
 const userlandProxyCommandName = "docker-proxy"
 const userlandProxyCommandName = "docker-proxy"
 
 
-func init() {
-	reexec.Register(userlandProxyCommandName, execProxy)
-}
-
 type userlandProxy interface {
 type userlandProxy interface {
 	Start() error
 	Start() error
 	Stop() error
 	Stop() error
@@ -35,66 +25,15 @@ type proxyCommand struct {
 	cmd *exec.Cmd
 	cmd *exec.Cmd
 }
 }
 
 
-// execProxy is the reexec function that is registered to start the userland proxies
-func execProxy() {
-	f := os.NewFile(3, "signal-parent")
-	host, container := parseHostContainerAddrs()
+func newProxyCommand(proto string, hostIP net.IP, hostPort int, containerIP net.IP, containerPort int) (userlandProxy, error) {
+	cmd, err := exec.LookPath(userlandProxyCommandName)
 
 
-	p, err := proxy.NewProxy(host, container)
 	if err != nil {
 	if err != nil {
-		fmt.Fprintf(f, "1\n%s", err)
-		f.Close()
-		os.Exit(1)
-	}
-	go handleStopSignals(p)
-	fmt.Fprint(f, "0\n")
-	f.Close()
-
-	// Run will block until the proxy stops
-	p.Run()
-}
-
-// parseHostContainerAddrs parses the flags passed on reexec to create the TCP or UDP
-// net.Addrs to map the host and container ports
-func parseHostContainerAddrs() (host net.Addr, container net.Addr) {
-	var (
-		proto         = flag.String("proto", "tcp", "proxy protocol")
-		hostIP        = flag.String("host-ip", "", "host ip")
-		hostPort      = flag.Int("host-port", -1, "host port")
-		containerIP   = flag.String("container-ip", "", "container ip")
-		containerPort = flag.Int("container-port", -1, "container port")
-	)
-
-	flag.Parse()
-
-	switch *proto {
-	case "tcp":
-		host = &net.TCPAddr{IP: net.ParseIP(*hostIP), Port: *hostPort}
-		container = &net.TCPAddr{IP: net.ParseIP(*containerIP), Port: *containerPort}
-	case "udp":
-		host = &net.UDPAddr{IP: net.ParseIP(*hostIP), Port: *hostPort}
-		container = &net.UDPAddr{IP: net.ParseIP(*containerIP), Port: *containerPort}
-	default:
-		log.Fatalf("unsupported protocol %s", *proto)
-	}
-
-	return host, container
-}
-
-func handleStopSignals(p proxy.Proxy) {
-	s := make(chan os.Signal, 10)
-	signal.Notify(s, os.Interrupt, syscall.SIGTERM, syscall.SIGSTOP)
-
-	for range s {
-		p.Close()
-
-		os.Exit(0)
+		return nil, err
 	}
 	}
-}
 
 
-func newProxyCommand(proto string, hostIP net.IP, hostPort int, containerIP net.IP, containerPort int) userlandProxy {
 	args := []string{
 	args := []string{
-		userlandProxyCommandName,
+		cmd,
 		"-proto", proto,
 		"-proto", proto,
 		"-host-ip", hostIP.String(),
 		"-host-ip", hostIP.String(),
 		"-host-port", strconv.Itoa(hostPort),
 		"-host-port", strconv.Itoa(hostPort),
@@ -104,13 +43,13 @@ func newProxyCommand(proto string, hostIP net.IP, hostPort int, containerIP net.
 
 
 	return &proxyCommand{
 	return &proxyCommand{
 		cmd: &exec.Cmd{
 		cmd: &exec.Cmd{
-			Path: reexec.Self(),
+			Path: cmd,
 			Args: args,
 			Args: args,
 			SysProcAttr: &syscall.SysProcAttr{
 			SysProcAttr: &syscall.SysProcAttr{
 				Pdeathsig: syscall.SIGTERM, // send a sigterm to the proxy if the daemon process dies
 				Pdeathsig: syscall.SIGTERM, // send a sigterm to the proxy if the daemon process dies
 			},
 			},
 		},
 		},
-	}
+	}, nil
 }
 }
 
 
 func (p *proxyCommand) Start() error {
 func (p *proxyCommand) Start() error {

+ 9 - 1
vendor/src/github.com/docker/libnetwork/sandbox_dns_unix.go

@@ -275,7 +275,15 @@ func (sb *sandbox) updateDNS(ipv6Enabled bool) error {
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	if err = ioutil.WriteFile(tmpHashFile.Name(), []byte(newRC.Hash), filePerm); err != nil {
+	if err = tmpHashFile.Chmod(filePerm); err != nil {
+		tmpHashFile.Close()
+		return err
+	}
+	_, err = tmpHashFile.Write([]byte(newRC.Hash))
+	if err1 := tmpHashFile.Close(); err == nil {
+		err = err1
+	}
+	if err != nil {
 		return err
 		return err
 	}
 	}
 	return os.Rename(tmpHashFile.Name(), hashFile)
 	return os.Rename(tmpHashFile.Name(), hashFile)

+ 2 - 0
vendor/src/github.com/docker/libnetwork/sandbox_externalkey_unix.go

@@ -135,6 +135,8 @@ func (c *controller) acceptClientConnections(sock string, l net.Listener) {
 			continue
 			continue
 		}
 		}
 		go func() {
 		go func() {
+			defer conn.Close()
+
 			err := c.processExternalKey(conn)
 			err := c.processExternalKey(conn)
 			ret := success
 			ret := success
 			if err != nil {
 			if err != nil {

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

@@ -195,6 +195,8 @@ func (a *Agent) run(ctx context.Context) {
 				log.G(ctx).WithError(err).Error("agent: closing session failed")
 				log.G(ctx).WithError(err).Error("agent: closing session failed")
 			}
 			}
 			sessionq = nil
 			sessionq = nil
+			// if we're here before <-registered, do nothing for that event
+			registered = nil
 		case <-session.closed:
 		case <-session.closed:
 			log.G(ctx).Debugf("agent: rebuild session")
 			log.G(ctx).Debugf("agent: rebuild session")
 
 

+ 214 - 214
vendor/src/github.com/docker/swarmkit/api/types.pb.go

@@ -954,7 +954,7 @@ type AcceptancePolicy_RoleAdmissionPolicy struct {
 	Autoaccept bool `protobuf:"varint,2,opt,name=autoaccept,proto3" json:"autoaccept,omitempty"`
 	Autoaccept bool `protobuf:"varint,2,opt,name=autoaccept,proto3" json:"autoaccept,omitempty"`
 	// Secret represents a user-provided string that is necessary for new
 	// Secret represents a user-provided string that is necessary for new
 	// nodes to join the cluster
 	// nodes to join the cluster
-	Secret *AcceptancePolicy_RoleAdmissionPolicy_HashedSecret `protobuf:"bytes,3,opt,name=secret" json:"secret,omitempty"`
+	Secret *AcceptancePolicy_RoleAdmissionPolicy_Secret `protobuf:"bytes,3,opt,name=secret" json:"secret,omitempty"`
 }
 }
 
 
 func (m *AcceptancePolicy_RoleAdmissionPolicy) Reset()      { *m = AcceptancePolicy_RoleAdmissionPolicy{} }
 func (m *AcceptancePolicy_RoleAdmissionPolicy) Reset()      { *m = AcceptancePolicy_RoleAdmissionPolicy{} }
@@ -963,18 +963,18 @@ func (*AcceptancePolicy_RoleAdmissionPolicy) Descriptor() ([]byte, []int) {
 	return fileDescriptorTypes, []int{23, 0}
 	return fileDescriptorTypes, []int{23, 0}
 }
 }
 
 
-type AcceptancePolicy_RoleAdmissionPolicy_HashedSecret struct {
-	// The actual hashed content
+type AcceptancePolicy_RoleAdmissionPolicy_Secret struct {
+	// The actual content (possibly hashed)
 	Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
 	Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
-	// The type of hash we are using
+	// The type of hash we are using, or "plaintext"
 	Alg string `protobuf:"bytes,2,opt,name=alg,proto3" json:"alg,omitempty"`
 	Alg string `protobuf:"bytes,2,opt,name=alg,proto3" json:"alg,omitempty"`
 }
 }
 
 
-func (m *AcceptancePolicy_RoleAdmissionPolicy_HashedSecret) Reset() {
-	*m = AcceptancePolicy_RoleAdmissionPolicy_HashedSecret{}
+func (m *AcceptancePolicy_RoleAdmissionPolicy_Secret) Reset() {
+	*m = AcceptancePolicy_RoleAdmissionPolicy_Secret{}
 }
 }
-func (*AcceptancePolicy_RoleAdmissionPolicy_HashedSecret) ProtoMessage() {}
-func (*AcceptancePolicy_RoleAdmissionPolicy_HashedSecret) Descriptor() ([]byte, []int) {
+func (*AcceptancePolicy_RoleAdmissionPolicy_Secret) ProtoMessage() {}
+func (*AcceptancePolicy_RoleAdmissionPolicy_Secret) Descriptor() ([]byte, []int) {
 	return fileDescriptorTypes, []int{23, 0, 0}
 	return fileDescriptorTypes, []int{23, 0, 0}
 }
 }
 
 
@@ -1145,7 +1145,7 @@ func init() {
 	proto.RegisterType((*IssuanceStatus)(nil), "docker.swarmkit.v1.IssuanceStatus")
 	proto.RegisterType((*IssuanceStatus)(nil), "docker.swarmkit.v1.IssuanceStatus")
 	proto.RegisterType((*AcceptancePolicy)(nil), "docker.swarmkit.v1.AcceptancePolicy")
 	proto.RegisterType((*AcceptancePolicy)(nil), "docker.swarmkit.v1.AcceptancePolicy")
 	proto.RegisterType((*AcceptancePolicy_RoleAdmissionPolicy)(nil), "docker.swarmkit.v1.AcceptancePolicy.RoleAdmissionPolicy")
 	proto.RegisterType((*AcceptancePolicy_RoleAdmissionPolicy)(nil), "docker.swarmkit.v1.AcceptancePolicy.RoleAdmissionPolicy")
-	proto.RegisterType((*AcceptancePolicy_RoleAdmissionPolicy_HashedSecret)(nil), "docker.swarmkit.v1.AcceptancePolicy.RoleAdmissionPolicy.HashedSecret")
+	proto.RegisterType((*AcceptancePolicy_RoleAdmissionPolicy_Secret)(nil), "docker.swarmkit.v1.AcceptancePolicy.RoleAdmissionPolicy.Secret")
 	proto.RegisterType((*ExternalCA)(nil), "docker.swarmkit.v1.ExternalCA")
 	proto.RegisterType((*ExternalCA)(nil), "docker.swarmkit.v1.ExternalCA")
 	proto.RegisterType((*CAConfig)(nil), "docker.swarmkit.v1.CAConfig")
 	proto.RegisterType((*CAConfig)(nil), "docker.swarmkit.v1.CAConfig")
 	proto.RegisterType((*OrchestrationConfig)(nil), "docker.swarmkit.v1.OrchestrationConfig")
 	proto.RegisterType((*OrchestrationConfig)(nil), "docker.swarmkit.v1.OrchestrationConfig")
@@ -1593,12 +1593,12 @@ func (m *AcceptancePolicy_RoleAdmissionPolicy) Copy() *AcceptancePolicy_RoleAdmi
 	return o
 	return o
 }
 }
 
 
-func (m *AcceptancePolicy_RoleAdmissionPolicy_HashedSecret) Copy() *AcceptancePolicy_RoleAdmissionPolicy_HashedSecret {
+func (m *AcceptancePolicy_RoleAdmissionPolicy_Secret) Copy() *AcceptancePolicy_RoleAdmissionPolicy_Secret {
 	if m == nil {
 	if m == nil {
 		return nil
 		return nil
 	}
 	}
 
 
-	o := &AcceptancePolicy_RoleAdmissionPolicy_HashedSecret{
+	o := &AcceptancePolicy_RoleAdmissionPolicy_Secret{
 		Data: m.Data,
 		Data: m.Data,
 		Alg:  m.Alg,
 		Alg:  m.Alg,
 	}
 	}
@@ -2180,12 +2180,12 @@ func (this *AcceptancePolicy_RoleAdmissionPolicy) GoString() string {
 	s = append(s, "}")
 	s = append(s, "}")
 	return strings.Join(s, "")
 	return strings.Join(s, "")
 }
 }
-func (this *AcceptancePolicy_RoleAdmissionPolicy_HashedSecret) GoString() string {
+func (this *AcceptancePolicy_RoleAdmissionPolicy_Secret) GoString() string {
 	if this == nil {
 	if this == nil {
 		return "nil"
 		return "nil"
 	}
 	}
 	s := make([]string, 0, 6)
 	s := make([]string, 0, 6)
-	s = append(s, "&api.AcceptancePolicy_RoleAdmissionPolicy_HashedSecret{")
+	s = append(s, "&api.AcceptancePolicy_RoleAdmissionPolicy_Secret{")
 	s = append(s, "Data: "+fmt.Sprintf("%#v", this.Data)+",\n")
 	s = append(s, "Data: "+fmt.Sprintf("%#v", this.Data)+",\n")
 	s = append(s, "Alg: "+fmt.Sprintf("%#v", this.Alg)+",\n")
 	s = append(s, "Alg: "+fmt.Sprintf("%#v", this.Alg)+",\n")
 	s = append(s, "}")
 	s = append(s, "}")
@@ -3407,7 +3407,7 @@ func (m *AcceptancePolicy_RoleAdmissionPolicy) MarshalTo(data []byte) (int, erro
 	return i, nil
 	return i, nil
 }
 }
 
 
-func (m *AcceptancePolicy_RoleAdmissionPolicy_HashedSecret) Marshal() (data []byte, err error) {
+func (m *AcceptancePolicy_RoleAdmissionPolicy_Secret) Marshal() (data []byte, err error) {
 	size := m.Size()
 	size := m.Size()
 	data = make([]byte, size)
 	data = make([]byte, size)
 	n, err := m.MarshalTo(data)
 	n, err := m.MarshalTo(data)
@@ -3417,7 +3417,7 @@ func (m *AcceptancePolicy_RoleAdmissionPolicy_HashedSecret) Marshal() (data []by
 	return data[:n], nil
 	return data[:n], nil
 }
 }
 
 
-func (m *AcceptancePolicy_RoleAdmissionPolicy_HashedSecret) MarshalTo(data []byte) (int, error) {
+func (m *AcceptancePolicy_RoleAdmissionPolicy_Secret) MarshalTo(data []byte) (int, error) {
 	var i int
 	var i int
 	_ = i
 	_ = i
 	var l int
 	var l int
@@ -4301,7 +4301,7 @@ func (m *AcceptancePolicy_RoleAdmissionPolicy) Size() (n int) {
 	return n
 	return n
 }
 }
 
 
-func (m *AcceptancePolicy_RoleAdmissionPolicy_HashedSecret) Size() (n int) {
+func (m *AcceptancePolicy_RoleAdmissionPolicy_Secret) Size() (n int) {
 	var l int
 	var l int
 	_ = l
 	_ = l
 	l = len(m.Data)
 	l = len(m.Data)
@@ -4866,16 +4866,16 @@ func (this *AcceptancePolicy_RoleAdmissionPolicy) String() string {
 	s := strings.Join([]string{`&AcceptancePolicy_RoleAdmissionPolicy{`,
 	s := strings.Join([]string{`&AcceptancePolicy_RoleAdmissionPolicy{`,
 		`Role:` + fmt.Sprintf("%v", this.Role) + `,`,
 		`Role:` + fmt.Sprintf("%v", this.Role) + `,`,
 		`Autoaccept:` + fmt.Sprintf("%v", this.Autoaccept) + `,`,
 		`Autoaccept:` + fmt.Sprintf("%v", this.Autoaccept) + `,`,
-		`Secret:` + strings.Replace(fmt.Sprintf("%v", this.Secret), "AcceptancePolicy_RoleAdmissionPolicy_HashedSecret", "AcceptancePolicy_RoleAdmissionPolicy_HashedSecret", 1) + `,`,
+		`Secret:` + strings.Replace(fmt.Sprintf("%v", this.Secret), "AcceptancePolicy_RoleAdmissionPolicy_Secret", "AcceptancePolicy_RoleAdmissionPolicy_Secret", 1) + `,`,
 		`}`,
 		`}`,
 	}, "")
 	}, "")
 	return s
 	return s
 }
 }
-func (this *AcceptancePolicy_RoleAdmissionPolicy_HashedSecret) String() string {
+func (this *AcceptancePolicy_RoleAdmissionPolicy_Secret) String() string {
 	if this == nil {
 	if this == nil {
 		return "nil"
 		return "nil"
 	}
 	}
-	s := strings.Join([]string{`&AcceptancePolicy_RoleAdmissionPolicy_HashedSecret{`,
+	s := strings.Join([]string{`&AcceptancePolicy_RoleAdmissionPolicy_Secret{`,
 		`Data:` + fmt.Sprintf("%v", this.Data) + `,`,
 		`Data:` + fmt.Sprintf("%v", this.Data) + `,`,
 		`Alg:` + fmt.Sprintf("%v", this.Alg) + `,`,
 		`Alg:` + fmt.Sprintf("%v", this.Alg) + `,`,
 		`}`,
 		`}`,
@@ -8641,7 +8641,7 @@ func (m *AcceptancePolicy_RoleAdmissionPolicy) Unmarshal(data []byte) error {
 				return io.ErrUnexpectedEOF
 				return io.ErrUnexpectedEOF
 			}
 			}
 			if m.Secret == nil {
 			if m.Secret == nil {
-				m.Secret = &AcceptancePolicy_RoleAdmissionPolicy_HashedSecret{}
+				m.Secret = &AcceptancePolicy_RoleAdmissionPolicy_Secret{}
 			}
 			}
 			if err := m.Secret.Unmarshal(data[iNdEx:postIndex]); err != nil {
 			if err := m.Secret.Unmarshal(data[iNdEx:postIndex]); err != nil {
 				return err
 				return err
@@ -8668,7 +8668,7 @@ func (m *AcceptancePolicy_RoleAdmissionPolicy) Unmarshal(data []byte) error {
 	}
 	}
 	return nil
 	return nil
 }
 }
-func (m *AcceptancePolicy_RoleAdmissionPolicy_HashedSecret) Unmarshal(data []byte) error {
+func (m *AcceptancePolicy_RoleAdmissionPolicy_Secret) Unmarshal(data []byte) error {
 	l := len(data)
 	l := len(data)
 	iNdEx := 0
 	iNdEx := 0
 	for iNdEx < l {
 	for iNdEx < l {
@@ -8691,10 +8691,10 @@ func (m *AcceptancePolicy_RoleAdmissionPolicy_HashedSecret) Unmarshal(data []byt
 		fieldNum := int32(wire >> 3)
 		fieldNum := int32(wire >> 3)
 		wireType := int(wire & 0x7)
 		wireType := int(wire & 0x7)
 		if wireType == 4 {
 		if wireType == 4 {
-			return fmt.Errorf("proto: HashedSecret: wiretype end group for non-group")
+			return fmt.Errorf("proto: Secret: wiretype end group for non-group")
 		}
 		}
 		if fieldNum <= 0 {
 		if fieldNum <= 0 {
-			return fmt.Errorf("proto: HashedSecret: illegal tag %d (wire type %d)", fieldNum, wire)
+			return fmt.Errorf("proto: Secret: illegal tag %d (wire type %d)", fieldNum, wire)
 		}
 		}
 		switch fieldNum {
 		switch fieldNum {
 		case 1:
 		case 1:
@@ -10199,196 +10199,196 @@ var (
 )
 )
 
 
 var fileDescriptorTypes = []byte{
 var fileDescriptorTypes = []byte{
-	// 3043 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x58, 0x4d, 0x6c, 0x1b, 0xc7,
-	0x15, 0x16, 0x7f, 0x45, 0x0e, 0x29, 0x89, 0x5e, 0x3b, 0x8e, 0xcc, 0xa8, 0xb2, 0xbb, 0x89, 0x1b,
-	0xe7, 0xa7, 0x4c, 0xac, 0xa4, 0x85, 0x9b, 0xa0, 0x4d, 0x96, 0x3f, 0xb2, 0x58, 0x4b, 0x24, 0x31,
-	0x94, 0x64, 0x04, 0x45, 0x4b, 0xac, 0x96, 0x23, 0x69, 0xa3, 0xe5, 0x2e, 0xbb, 0xbb, 0x94, 0x4c,
+	// 3042 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x58, 0xcd, 0x6f, 0x1b, 0xc7,
+	0x15, 0x17, 0x3f, 0x45, 0x3e, 0x52, 0x12, 0xbd, 0x76, 0x1c, 0x99, 0x51, 0x65, 0x77, 0x13, 0x37,
+	0xce, 0x47, 0x99, 0x58, 0x49, 0x0b, 0x37, 0x41, 0xeb, 0x2c, 0x3f, 0x64, 0xb1, 0x96, 0x48, 0x62,
+	0xa8, 0x0f, 0x04, 0x05, 0x4a, 0xac, 0x96, 0x23, 0x71, 0xa3, 0xe5, 0x2e, 0xbb, 0xbb, 0x94, 0x4c,
 	0x14, 0x05, 0x9c, 0x5e, 0x5a, 0x04, 0x3d, 0xf4, 0x5e, 0x04, 0x41, 0xd1, 0xa2, 0xb7, 0x9e, 0x0b,
 	0x14, 0x05, 0x9c, 0x5e, 0x5a, 0x04, 0x3d, 0xf4, 0x5e, 0x04, 0x41, 0xd1, 0xa2, 0xb7, 0x9e, 0x0b,
-	0xf4, 0xe4, 0xa3, 0x8f, 0x2d, 0x0a, 0x14, 0x39, 0x05, 0x4d, 0x7a, 0xe8, 0xb5, 0x40, 0x0f, 0x39,
-	0xb4, 0x87, 0xbe, 0x37, 0x3f, 0xcb, 0x1f, 0xaf, 0x15, 0xa7, 0xc9, 0x81, 0xe0, 0xce, 0x7b, 0xdf,
-	0x7b, 0x33, 0x6f, 0xe6, 0xcd, 0xfb, 0x19, 0x52, 0x08, 0xc7, 0x43, 0x16, 0x54, 0x86, 0xbe, 0x17,
-	0x7a, 0x9a, 0xd6, 0xf7, 0xac, 0x13, 0xe6, 0x57, 0x82, 0x33, 0xd3, 0x1f, 0x9c, 0xd8, 0x61, 0xe5,
-	0xf4, 0x66, 0xf9, 0x4a, 0x68, 0x0f, 0x58, 0x10, 0x9a, 0x83, 0xe1, 0x2b, 0xd1, 0x97, 0x80, 0x97,
-	0x9f, 0xee, 0x8f, 0x7c, 0x33, 0xb4, 0x3d, 0xf7, 0x15, 0xf5, 0x21, 0x19, 0x97, 0x8e, 0xbc, 0x23,
-	0x8f, 0x7f, 0xbe, 0x82, 0x5f, 0x82, 0xaa, 0x5f, 0x25, 0x8b, 0xfb, 0xcc, 0x0f, 0x00, 0xa6, 0x5d,
-	0x22, 0x19, 0xdb, 0xed, 0xb3, 0x7b, 0xab, 0x89, 0x6b, 0x89, 0x1b, 0x69, 0x2a, 0x06, 0xfa, 0x6f,
-	0x12, 0xa4, 0x60, 0xb8, 0xae, 0x17, 0x72, 0x5d, 0x81, 0xa6, 0x91, 0xb4, 0x6b, 0x0e, 0x18, 0x07,
-	0xe5, 0x29, 0xff, 0xd6, 0x6a, 0x24, 0xeb, 0x98, 0x07, 0xcc, 0x09, 0x56, 0x93, 0xd7, 0x52, 0x37,
-	0x0a, 0x1b, 0x2f, 0x55, 0x1e, 0x5d, 0x73, 0x65, 0x4a, 0x49, 0x65, 0x9b, 0xa3, 0x1b, 0x6e, 0xe8,
-	0x8f, 0xa9, 0x14, 0x2d, 0x7f, 0x87, 0x14, 0xa6, 0xc8, 0x5a, 0x89, 0xa4, 0x4e, 0xd8, 0x58, 0x4e,
-	0x83, 0x9f, 0xb8, 0xbe, 0x53, 0xd3, 0x19, 0x31, 0x98, 0x04, 0x69, 0x62, 0xf0, 0x46, 0xf2, 0x56,
-	0x42, 0x7f, 0x87, 0xe4, 0x29, 0x0b, 0xbc, 0x91, 0x6f, 0xb1, 0x40, 0x7b, 0x81, 0xe4, 0x5d, 0xd3,
-	0xf5, 0x7a, 0xd6, 0x70, 0x14, 0x70, 0xf1, 0x54, 0xb5, 0xf8, 0xe9, 0xc7, 0x57, 0x73, 0x2d, 0x20,
-	0xd6, 0x3a, 0x7b, 0x01, 0xcd, 0x21, 0xbb, 0x06, 0x5c, 0xed, 0xeb, 0xa4, 0x38, 0x60, 0x03, 0xcf,
-	0x1f, 0xf7, 0x0e, 0xc6, 0x21, 0x0b, 0xb8, 0xe2, 0x14, 0x2d, 0x08, 0x5a, 0x15, 0x49, 0xfa, 0xaf,
-	0x12, 0xe4, 0x92, 0xd2, 0x4d, 0xd9, 0x8f, 0x47, 0xb6, 0xcf, 0x06, 0xcc, 0x0d, 0x03, 0xed, 0x5b,
-	0x60, 0xb3, 0x3d, 0xb0, 0x43, 0x31, 0x47, 0x61, 0xe3, 0x6b, 0x71, 0x36, 0x47, 0xab, 0xa2, 0x12,
-	0xac, 0x19, 0xa4, 0xe8, 0xb3, 0x80, 0xf9, 0xa7, 0x62, 0x27, 0xf8, 0x94, 0x9f, 0x2b, 0x3c, 0x23,
-	0xa2, 0x6f, 0x92, 0x5c, 0xc7, 0x31, 0xc3, 0x43, 0xcf, 0x1f, 0x68, 0x3a, 0x29, 0x9a, 0xbe, 0x75,
-	0x6c, 0x87, 0xcc, 0x0a, 0x47, 0xbe, 0x3a, 0x95, 0x19, 0x9a, 0x76, 0x99, 0x24, 0x3d, 0x31, 0x51,
-	0xbe, 0x9a, 0x85, 0x9d, 0x48, 0xb6, 0xbb, 0x14, 0x28, 0xfa, 0x9b, 0xe4, 0x42, 0xc7, 0x19, 0x1d,
-	0xd9, 0x6e, 0x9d, 0x05, 0x96, 0x6f, 0x0f, 0x51, 0x3b, 0x1e, 0x2f, 0x3a, 0x9f, 0x3a, 0x5e, 0xfc,
-	0x8e, 0x8e, 0x3c, 0x39, 0x39, 0x72, 0xfd, 0xe7, 0x49, 0x72, 0xa1, 0xe1, 0x82, 0x30, 0x9b, 0x96,
-	0xbe, 0x4e, 0x96, 0x19, 0x27, 0xf6, 0x4e, 0x85, 0x53, 0x49, 0x3d, 0x4b, 0x82, 0xaa, 0x3c, 0xad,
-	0x39, 0xe7, 0x2f, 0x37, 0xe3, 0xcc, 0x7f, 0x44, 0x7b, 0x9c, 0xd7, 0x68, 0x0d, 0xb2, 0x38, 0xe4,
-	0x46, 0x04, 0xab, 0x29, 0xae, 0xeb, 0x7a, 0x9c, 0xae, 0x47, 0xec, 0xac, 0xa6, 0x1f, 0x7e, 0x7c,
-	0x75, 0x81, 0x2a, 0xd9, 0x2f, 0xe3, 0x7c, 0xff, 0x48, 0x90, 0x95, 0x96, 0xd7, 0x9f, 0xd9, 0x87,
-	0x32, 0xc9, 0x1d, 0x7b, 0x41, 0x38, 0x75, 0x51, 0xa2, 0xb1, 0x76, 0x8b, 0xe4, 0x86, 0xf2, 0xf8,
-	0xe4, 0xe9, 0xaf, 0xc5, 0x2f, 0x59, 0x60, 0x68, 0x84, 0xd6, 0xde, 0x24, 0x79, 0x5f, 0xf9, 0x04,
-	0x58, 0xfb, 0x04, 0x8e, 0x33, 0xc1, 0x6b, 0xdf, 0x25, 0x59, 0x71, 0x08, 0xab, 0x69, 0x2e, 0x79,
-	0xfd, 0x89, 0xf6, 0x9c, 0x4a, 0x21, 0xfd, 0xa3, 0x04, 0x29, 0x51, 0xf3, 0x30, 0xdc, 0x61, 0x83,
-	0x03, 0xe6, 0x77, 0xe1, 0x22, 0xc3, 0xfd, 0xb9, 0x0c, 0xe7, 0xc8, 0xcc, 0x3e, 0xf3, 0xb9, 0x91,
-	0x39, 0x2a, 0x47, 0xda, 0x1e, 0x3a, 0xb9, 0x69, 0x1d, 0x9b, 0x07, 0xb6, 0x63, 0x87, 0x63, 0x6e,
-	0xe6, 0x72, 0xfc, 0x29, 0xcf, 0xeb, 0x84, 0xc5, 0x4f, 0x04, 0xe9, 0x8c, 0x1a, 0x6d, 0x95, 0x2c,
-	0x42, 0xac, 0x0b, 0xcc, 0x23, 0xc6, 0xad, 0xcf, 0x53, 0x35, 0x04, 0x57, 0x2e, 0x4e, 0xcb, 0x69,
-	0x05, 0xb2, 0xb8, 0xd7, 0xba, 0xd3, 0x6a, 0xdf, 0x6d, 0x95, 0x16, 0xb4, 0x15, 0x52, 0xd8, 0x6b,
-	0xd1, 0x86, 0x51, 0xdb, 0x32, 0xaa, 0xdb, 0x8d, 0x52, 0x42, 0x5b, 0x82, 0x70, 0x11, 0x0d, 0x93,
-	0xfa, 0x87, 0x09, 0x42, 0xf0, 0x00, 0xa5, 0x51, 0x6f, 0x90, 0x0c, 0xc4, 0xd3, 0x50, 0x1c, 0xdc,
-	0xf2, 0xc6, 0x73, 0x71, 0xab, 0x9e, 0xc0, 0x2b, 0xf8, 0xc7, 0xa8, 0x10, 0x99, 0x5e, 0x61, 0x72,
-	0x7e, 0x85, 0x19, 0x8e, 0x9c, 0x5d, 0x5a, 0x8e, 0xa4, 0xeb, 0xf8, 0x95, 0xd0, 0xf2, 0x24, 0x03,
-	0x6b, 0xaa, 0xbf, 0x53, 0x4a, 0x82, 0xf3, 0x15, 0xeb, 0xcd, 0x6e, 0xad, 0xdd, 0x6a, 0x35, 0x6a,
-	0xbb, 0x8d, 0x7a, 0x29, 0xa5, 0x5f, 0x27, 0x99, 0xe6, 0x00, 0xb4, 0x68, 0x6b, 0xe8, 0x01, 0x87,
-	0xcc, 0x67, 0xae, 0xa5, 0x1c, 0x6b, 0x42, 0xd0, 0x7f, 0x99, 0x23, 0x99, 0x1d, 0x6f, 0xe4, 0x86,
-	0xda, 0xc6, 0xd4, 0x2d, 0x5e, 0xde, 0x58, 0x8f, 0x33, 0x81, 0x03, 0x2b, 0xbb, 0x80, 0x92, 0xb7,
-	0x1c, 0x0e, 0x53, 0xf8, 0x8a, 0x5c, 0xba, 0x1c, 0x21, 0x3d, 0x34, 0xfd, 0x23, 0x16, 0xca, 0x4d,
-	0x97, 0x23, 0xed, 0x06, 0xc9, 0xc1, 0xe9, 0xf4, 0x3d, 0xd7, 0x19, 0x73, 0x97, 0xca, 0x89, 0x30,
-	0x0b, 0xe7, 0xd0, 0x6f, 0x03, 0x8d, 0x46, 0x5c, 0x6d, 0x8b, 0x14, 0x0f, 0x20, 0x99, 0xf4, 0xbc,
-	0xa1, 0x88, 0x79, 0x99, 0xc7, 0x3b, 0xa0, 0x58, 0x55, 0x15, 0xd0, 0x6d, 0x01, 0xa6, 0x85, 0x83,
-	0xc9, 0x40, 0x6b, 0x91, 0xe5, 0x53, 0xcf, 0x19, 0x0d, 0x58, 0xa4, 0x2b, 0xcb, 0x75, 0x3d, 0xff,
-	0x78, 0x5d, 0xfb, 0x1c, 0xaf, 0xb4, 0x2d, 0x9d, 0x4e, 0x0f, 0xcb, 0x3f, 0x4b, 0x91, 0xc2, 0xd4,
-	0x64, 0x5a, 0x97, 0x14, 0x20, 0x2d, 0x0e, 0xcd, 0x23, 0x1e, 0x6a, 0xe5, 0xf6, 0xdd, 0x7c, 0xa2,
-	0x85, 0x56, 0x3a, 0x13, 0x41, 0x3a, 0xad, 0x45, 0xff, 0x20, 0x49, 0x0a, 0x53, 0x4c, 0xed, 0x45,
-	0x92, 0xa3, 0x1d, 0xda, 0xdc, 0x37, 0x76, 0x1b, 0xa5, 0x85, 0xf2, 0xda, 0xfb, 0x1f, 0x5c, 0x5b,
-	0xe5, 0xda, 0xa6, 0x15, 0x74, 0x7c, 0xfb, 0x14, 0xbd, 0xe5, 0x06, 0x59, 0x54, 0xd0, 0x44, 0xf9,
-	0x19, 0x80, 0x3e, 0x3d, 0x0f, 0x9d, 0x42, 0xd2, 0xee, 0x96, 0x41, 0xc1, 0x61, 0x92, 0xf1, 0x48,
-	0xda, 0x3d, 0x36, 0x7d, 0xd6, 0xd7, 0xbe, 0x41, 0xb2, 0x12, 0x98, 0x2a, 0x97, 0x01, 0x78, 0x79,
-	0x1e, 0x38, 0xc1, 0xd1, 0xee, 0xb6, 0xb1, 0xdf, 0x28, 0xa5, 0xe3, 0x71, 0xb4, 0xeb, 0x98, 0xa7,
-	0x4c, 0x7b, 0x0e, 0x5c, 0x9b, 0xc3, 0x32, 0xe5, 0x2b, 0x00, 0x7b, 0xea, 0x11, 0x75, 0x88, 0x2a,
-	0xaf, 0xfe, 0xe2, 0xb7, 0xeb, 0x0b, 0x7f, 0xfa, 0xdd, 0x7a, 0x69, 0x9e, 0x5d, 0xfe, 0x6f, 0x82,
-	0x2c, 0xcd, 0x9c, 0x12, 0x64, 0xb5, 0xac, 0xeb, 0x59, 0xde, 0x50, 0x44, 0xe0, 0x5c, 0x95, 0x80,
-	0x63, 0x65, 0x5b, 0x5e, 0x0d, 0x28, 0x54, 0x72, 0xb4, 0x3b, 0x73, 0x39, 0xe4, 0xb5, 0x27, 0x74,
-	0x81, 0xd8, 0x2c, 0xf2, 0x16, 0x59, 0xea, 0xc3, 0x3e, 0x32, 0xbf, 0x67, 0x79, 0xee, 0xa1, 0x7d,
-	0x24, 0xa3, 0x6b, 0x39, 0x4e, 0x67, 0x9d, 0x03, 0x69, 0x51, 0x08, 0xd4, 0x38, 0xfe, 0xcb, 0xe4,
-	0x8f, 0xbb, 0x24, 0x8d, 0xb7, 0x50, 0x7b, 0x86, 0xa4, 0xab, 0xcd, 0x56, 0x1d, 0x5c, 0xe2, 0x02,
-	0xec, 0xe2, 0x12, 0x5f, 0x3a, 0x32, 0xd0, 0xc7, 0xb4, 0xab, 0x24, 0xbb, 0xdf, 0xde, 0xde, 0xdb,
-	0x41, 0x37, 0xb8, 0x08, 0xec, 0x95, 0x88, 0x2d, 0x8c, 0x2b, 0x5f, 0x90, 0xdb, 0x9b, 0x8f, 0x18,
-	0xfa, 0x7f, 0x92, 0x64, 0x89, 0x62, 0x6d, 0xe8, 0x87, 0x1d, 0xcf, 0xb1, 0xad, 0xb1, 0xd6, 0x21,
-	0x79, 0xb0, 0xaf, 0x6f, 0x4f, 0x39, 0xf7, 0xc6, 0x63, 0x12, 0xc8, 0x44, 0x4a, 0x8d, 0x6a, 0x4a,
-	0x92, 0x4e, 0x94, 0x40, 0xa0, 0xc9, 0xf4, 0x99, 0x63, 0x8e, 0xcf, 0xcb, 0x64, 0x75, 0x59, 0x87,
-	0x52, 0x01, 0xe5, 0x55, 0x97, 0x79, 0xaf, 0x67, 0x86, 0x21, 0x1b, 0x0c, 0x43, 0x91, 0xc9, 0xd2,
-	0x50, 0x75, 0x99, 0xf7, 0x0c, 0x49, 0xd2, 0x5e, 0x27, 0xd9, 0x33, 0x30, 0xdb, 0x3b, 0x93, 0xc9,
-	0xea, 0x7c, 0xbd, 0x12, 0xab, 0xbf, 0x8f, 0x39, 0x6a, 0x6e, 0xb1, 0xb8, 0xad, 0xad, 0x76, 0xab,
-	0xa1, 0xb6, 0x55, 0xf2, 0xdb, 0x6e, 0xcb, 0x73, 0xd1, 0x75, 0x49, 0xbb, 0xd5, 0xdb, 0x34, 0x9a,
-	0xdb, 0x7b, 0x14, 0xb7, 0xf6, 0x12, 0x40, 0x4a, 0x11, 0x64, 0xd3, 0xb4, 0x1d, 0x2c, 0xa0, 0xae,
-	0x90, 0x94, 0xd1, 0x82, 0xc8, 0x5c, 0x2e, 0x01, 0xbb, 0x18, 0xb1, 0x0d, 0x77, 0x3c, 0xf1, 0xea,
-	0xf9, 0x79, 0xf5, 0x77, 0x49, 0x71, 0x6f, 0xd8, 0x87, 0x9b, 0x29, 0x3c, 0x44, 0xbb, 0x06, 0xa1,
-	0xc5, 0xf4, 0x4d, 0xc7, 0x61, 0x8e, 0x1d, 0x0c, 0x64, 0x8d, 0x3d, 0x4d, 0x82, 0xc2, 0xe0, 0xc9,
-	0xf7, 0x52, 0xd6, 0x2f, 0x42, 0x40, 0xff, 0x29, 0x59, 0x81, 0x59, 0x42, 0x13, 0x12, 0xb5, 0x4a,
-	0xcd, 0x1b, 0xa4, 0x68, 0x29, 0x52, 0xcf, 0xee, 0x0b, 0x57, 0xac, 0xae, 0xc0, 0x45, 0x2a, 0x44,
-	0xd0, 0x66, 0x9d, 0x16, 0x22, 0x50, 0xb3, 0x8f, 0x76, 0x0e, 0x01, 0x8a, 0xd3, 0x67, 0xaa, 0x8b,
-	0x00, 0x4d, 0x75, 0x00, 0x82, 0x34, 0xd8, 0xc5, 0x3c, 0xbb, 0x67, 0x87, 0x70, 0x3d, 0xfa, 0x22,
-	0xf9, 0x66, 0x68, 0x0e, 0x09, 0x35, 0x18, 0xeb, 0xef, 0x25, 0x09, 0xd9, 0x35, 0x83, 0x13, 0x39,
-	0x35, 0x94, 0x29, 0x51, 0x53, 0x72, 0x5e, 0x71, 0xbc, 0xab, 0x40, 0x74, 0x82, 0xd7, 0x5e, 0x53,
-	0xd9, 0x57, 0xd4, 0x0c, 0xf1, 0x82, 0x72, 0xae, 0xb8, 0xb4, 0x3b, 0x5b, 0x18, 0xe0, 0x45, 0x64,
-	0xbe, 0xcf, 0xbd, 0x08, 0x2e, 0x22, 0x7c, 0x42, 0xaf, 0x92, 0x8f, 0x6c, 0x96, 0x99, 0xe8, 0xd9,
-	0xb8, 0x49, 0xe6, 0x36, 0x74, 0x6b, 0x81, 0x4e, 0xe4, 0xaa, 0x25, 0xb2, 0xec, 0xc3, 0x35, 0x83,
-	0x55, 0xf7, 0x02, 0xce, 0xd6, 0xff, 0x0a, 0x7b, 0xd0, 0xec, 0x18, 0x3b, 0xf2, 0xb4, 0xeb, 0x24,
-	0x7b, 0x68, 0x0e, 0x6c, 0x67, 0x2c, 0xaf, 0xd9, 0xcb, 0x71, 0x53, 0x4c, 0xf0, 0x15, 0xa3, 0xdf,
-	0x87, 0x52, 0x2d, 0xd8, 0xe4, 0x32, 0x54, 0xca, 0xf2, 0x94, 0x3c, 0x3a, 0x70, 0x21, 0xf5, 0xaa,
-	0x94, 0xcc, 0x47, 0x18, 0x4c, 0x7c, 0xd3, 0x8d, 0xac, 0x15, 0x03, 0xdc, 0x05, 0x88, 0xa8, 0xec,
-	0xcc, 0x1c, 0x4b, 0x7b, 0xd5, 0x10, 0x12, 0x70, 0x4e, 0x74, 0x10, 0xac, 0x0f, 0x26, 0x63, 0xb4,
-	0xfc, 0xbc, 0xf5, 0x50, 0x09, 0x17, 0x61, 0x32, 0x92, 0x2e, 0xbf, 0xc9, 0x43, 0xca, 0x84, 0xf5,
-	0x85, 0x22, 0xdd, 0xab, 0x64, 0x69, 0xc6, 0xce, 0x47, 0x6a, 0xa1, 0x66, 0x67, 0xff, 0xf5, 0x52,
-	0x5a, 0x7e, 0x7d, 0xbb, 0x94, 0xd5, 0xff, 0x0d, 0xa5, 0x59, 0xc7, 0xe3, 0xd7, 0x0a, 0x77, 0x35,
-	0xbe, 0xf7, 0xcc, 0xf1, 0x4e, 0xd6, 0xf2, 0x1c, 0xe9, 0x33, 0xb1, 0xc5, 0xc0, 0x44, 0x0b, 0x26,
-	0x6a, 0x0e, 0xa7, 0x91, 0x20, 0x84, 0xd7, 0x82, 0xa8, 0x6a, 0x7a, 0x43, 0xc0, 0xf1, 0x6d, 0x5d,
-	0xa2, 0x44, 0x90, 0x50, 0x12, 0x1b, 0x9b, 0xe1, 0xe8, 0x00, 0xae, 0xe9, 0x31, 0xeb, 0x0b, 0x4c,
-	0x9a, 0x63, 0x96, 0x22, 0x2a, 0xc2, 0xf4, 0x3a, 0xb4, 0x66, 0x4a, 0xe7, 0x2a, 0x49, 0xed, 0xd6,
-	0x3a, 0x10, 0x77, 0x56, 0x20, 0x6a, 0x14, 0x14, 0x19, 0x48, 0xc8, 0xd9, 0xab, 0x77, 0x20, 0xdc,
-	0xcc, 0x70, 0x80, 0x54, 0x4e, 0x63, 0x38, 0xd1, 0x7f, 0x9d, 0x20, 0x59, 0x91, 0x65, 0x62, 0x2d,
-	0x36, 0xc8, 0xa2, 0xaa, 0x7e, 0x44, 0xea, 0x7b, 0xfe, 0xf1, 0x69, 0xaa, 0x22, 0xb3, 0x9e, 0x38,
-	0x47, 0x25, 0x57, 0x7e, 0x83, 0x14, 0xa7, 0x19, 0x5f, 0xe8, 0x14, 0x7f, 0x42, 0x0a, 0xe8, 0x28,
-	0x2a, 0x57, 0x6f, 0x90, 0xac, 0xc8, 0x84, 0xf2, 0xaa, 0x9f, 0x97, 0x33, 0x25, 0x12, 0x22, 0xdd,
-	0xa2, 0xc8, 0xb3, 0xaa, 0x69, 0x5b, 0x3f, 0xdf, 0x1d, 0xa9, 0x82, 0xeb, 0x6f, 0x91, 0x74, 0x87,
-	0x81, 0x86, 0x67, 0xc9, 0xa2, 0x0b, 0xa1, 0x67, 0x12, 0xd9, 0x64, 0x89, 0xd0, 0x67, 0x10, 0xb1,
-	0xb2, 0xc8, 0x82, 0x78, 0x06, 0x9b, 0x67, 0x82, 0xbf, 0xa9, 0xbe, 0x15, 0xbf, 0xf5, 0x5d, 0x52,
-	0xbc, 0xcb, 0xec, 0xa3, 0xe3, 0x10, 0x4e, 0x0c, 0x15, 0xbd, 0x4c, 0xd2, 0x43, 0x16, 0x2d, 0x7e,
-	0x35, 0xd6, 0x75, 0x80, 0x4f, 0x39, 0x0a, 0x2f, 0xe4, 0x19, 0x97, 0x96, 0x4f, 0x05, 0x72, 0xa4,
-	0xff, 0x21, 0x49, 0x96, 0x9b, 0x41, 0x30, 0x32, 0xa1, 0x0c, 0x97, 0x51, 0xf0, 0x7b, 0xb3, 0x6d,
-	0xc4, 0x8d, 0x58, 0x0b, 0x67, 0x44, 0x66, 0x5b, 0x09, 0x19, 0xb9, 0x92, 0x51, 0xe4, 0xd2, 0x1f,
-	0x26, 0x54, 0x0f, 0x71, 0x7d, 0xea, 0xde, 0x94, 0x57, 0xc1, 0x89, 0x2e, 0x4d, 0x6b, 0x62, 0x7b,
-	0xee, 0x89, 0xeb, 0x9d, 0xb9, 0x90, 0x68, 0xa1, 0xa7, 0x68, 0x35, 0xee, 0x82, 0xa7, 0x5d, 0x06,
-	0x90, 0x36, 0x03, 0xa2, 0xcc, 0x65, 0x67, 0xa8, 0xa9, 0xd3, 0x68, 0xd5, 0x9b, 0xad, 0xdb, 0x90,
-	0xde, 0x1e, 0xd5, 0xd4, 0x61, 0x90, 0xce, 0xdc, 0x23, 0xd8, 0xee, 0x6c, 0xb3, 0xdb, 0xdd, 0xe3,
-	0x25, 0xe3, 0xd3, 0x80, 0xba, 0x38, 0x83, 0xc2, 0x01, 0xd4, 0x8b, 0x00, 0xc2, 0x4c, 0x0a, 0xa0,
-	0x74, 0x0c, 0x08, 0x93, 0x29, 0x04, 0x10, 0xe1, 0xe1, 0xff, 0x4c, 0x92, 0x92, 0x61, 0x59, 0x6c,
-	0x18, 0x22, 0x5f, 0x56, 0x27, 0xbb, 0x70, 0x93, 0xf1, 0xcb, 0x66, 0xf8, 0xa6, 0x82, 0x6e, 0x71,
-	0x2b, 0xf6, 0x1d, 0x69, 0x4e, 0xae, 0x42, 0x3d, 0x87, 0x19, 0xfd, 0x81, 0x1d, 0xe0, 0xdb, 0x82,
-	0xa0, 0xd1, 0x48, 0x13, 0x56, 0x97, 0x17, 0x63, 0x10, 0xda, 0xab, 0x24, 0xed, 0x03, 0x59, 0x1e,
-	0xcf, 0xda, 0xe3, 0xba, 0x3c, 0x14, 0xa5, 0x1c, 0xa9, 0xad, 0x13, 0x62, 0x8e, 0x42, 0xcf, 0xe4,
-	0xf3, 0xf3, 0x83, 0xc9, 0xd1, 0x29, 0x8a, 0xf6, 0x43, 0x88, 0xd6, 0xcc, 0xf2, 0x65, 0xa3, 0x54,
-	0xd8, 0x68, 0xfc, 0xbf, 0xab, 0xaf, 0x6c, 0x99, 0x18, 0x51, 0xba, 0x5c, 0x19, 0x95, 0x4a, 0xcb,
-	0xaf, 0x93, 0xe2, 0x34, 0x1d, 0xbd, 0x1b, 0xca, 0x0b, 0x93, 0x1b, 0x50, 0xa4, 0xfc, 0x1b, 0x9d,
-	0xc6, 0x74, 0x8e, 0x94, 0xd3, 0xc0, 0xa7, 0xfe, 0x21, 0xe4, 0xa5, 0xc6, 0xbd, 0x90, 0xf9, 0xae,
-	0xe9, 0xd4, 0x0c, 0xad, 0x31, 0x15, 0x2d, 0x85, 0xe5, 0x2f, 0xc4, 0xbe, 0x03, 0x44, 0x12, 0x95,
-	0x9a, 0x11, 0x13, 0x2f, 0xa1, 0x52, 0x18, 0xf9, 0x8e, 0x7c, 0x53, 0xe2, 0x95, 0xc2, 0x1e, 0xdd,
-	0xa6, 0x48, 0xc3, 0x07, 0x19, 0x15, 0x9d, 0x52, 0x8f, 0x7f, 0x0c, 0x9c, 0x9a, 0xe0, 0xab, 0x8f,
-	0x50, 0x2f, 0x13, 0x32, 0x59, 0x35, 0x1c, 0x5b, 0xa6, 0xb6, 0xd9, 0xed, 0x6e, 0xc3, 0x55, 0xe1,
-	0x95, 0xf3, 0x84, 0xc5, 0xc9, 0xfa, 0xef, 0x13, 0x24, 0x57, 0x33, 0x64, 0x86, 0xd9, 0x24, 0x25,
-	0x1e, 0x57, 0x2c, 0xe6, 0x87, 0x3d, 0x76, 0x6f, 0x68, 0xfb, 0x63, 0x19, 0x1a, 0xce, 0x2f, 0x41,
-	0x97, 0x51, 0xaa, 0x06, 0x42, 0x0d, 0x2e, 0xa3, 0x51, 0x52, 0x64, 0xd2, 0xc4, 0x9e, 0x65, 0xaa,
-	0x40, 0xbd, 0x7e, 0xfe, 0x56, 0x88, 0xf2, 0x6c, 0x32, 0x86, 0xe6, 0x57, 0x29, 0xa9, 0x99, 0x81,
-	0xbe, 0x4f, 0x2e, 0xb6, 0x7d, 0xeb, 0x18, 0x0a, 0x25, 0x31, 0xa9, 0x5c, 0xf2, 0x5b, 0x64, 0x2d,
-	0x84, 0x82, 0xa8, 0x77, 0x6c, 0x07, 0x21, 0x3e, 0x65, 0x82, 0x6f, 0x30, 0x17, 0xf9, 0x3d, 0xfe,
-	0xe4, 0x28, 0x9e, 0x40, 0xe9, 0x15, 0xc4, 0x6c, 0x09, 0x08, 0x55, 0x88, 0x6d, 0x04, 0xe8, 0x3f,
-	0x20, 0xa5, 0xba, 0x1d, 0x0c, 0xcd, 0x10, 0x74, 0xcb, 0x7e, 0x46, 0xbb, 0x4d, 0x4a, 0xc7, 0x0c,
-	0xea, 0xd9, 0x03, 0x66, 0x42, 0x4e, 0x64, 0xbe, 0xed, 0xf5, 0x9f, 0x68, 0x1f, 0x56, 0x22, 0xa9,
-	0x0e, 0x17, 0xd2, 0x3f, 0x83, 0x0c, 0x8e, 0x6f, 0x3c, 0x52, 0xef, 0x4b, 0xe4, 0x42, 0xe0, 0x9a,
-	0xc3, 0xe0, 0xd8, 0x0b, 0x7b, 0xb6, 0x1b, 0xe2, 0xa3, 0xa6, 0x23, 0x6b, 0xe1, 0x92, 0x62, 0x34,
-	0x25, 0x1d, 0x62, 0xb3, 0x76, 0xc2, 0xd8, 0xb0, 0xe7, 0x39, 0xfd, 0x9e, 0x62, 0x8a, 0x87, 0x4c,
-	0x40, 0x23, 0xa7, 0xed, 0xf4, 0xbb, 0x8a, 0xae, 0x55, 0xc9, 0xba, 0xe3, 0x1d, 0xf5, 0xc0, 0x32,
-	0x1f, 0xee, 0x7d, 0xef, 0xd0, 0xf3, 0x7b, 0x81, 0xe3, 0x9d, 0xc1, 0x87, 0x03, 0x7f, 0xcc, 0x57,
-	0x8d, 0x46, 0x19, 0x50, 0x0d, 0x01, 0xda, 0xf4, 0xfc, 0x2e, 0xf0, 0x36, 0x15, 0x02, 0xd3, 0xfc,
-	0xc4, 0xec, 0xd0, 0xb6, 0x4e, 0x54, 0x9a, 0x8f, 0xa8, 0xbb, 0x40, 0x84, 0x48, 0xb7, 0xc4, 0x1c,
-	0x66, 0xf1, 0x4d, 0xe6, 0xa8, 0x0c, 0x47, 0x15, 0x15, 0x11, 0x41, 0xfa, 0x37, 0x49, 0xbe, 0xe3,
-	0x98, 0x16, 0x7f, 0x2e, 0xc6, 0xea, 0x1f, 0x52, 0x18, 0x9e, 0x1c, 0x58, 0x2d, 0xc2, 0x5b, 0x9e,
-	0x4e, 0x93, 0xf4, 0xf7, 0x20, 0xe9, 0x53, 0xcf, 0x0b, 0xe1, 0x92, 0x5e, 0x23, 0x59, 0xcb, 0xec,
-	0x29, 0x77, 0x2f, 0x56, 0xf3, 0xe0, 0x16, 0x99, 0x9a, 0x71, 0x87, 0x8d, 0x69, 0xc6, 0x32, 0xe1,
-	0x0f, 0xd3, 0x1f, 0x20, 0xd0, 0x49, 0xf9, 0x76, 0x14, 0x45, 0xfa, 0x03, 0x2f, 0x06, 0x0a, 0x05,
-	0x61, 0xfc, 0x87, 0x08, 0x57, 0x94, 0xa0, 0xde, 0x31, 0x04, 0x0e, 0x51, 0x2c, 0x56, 0x97, 0x01,
-	0x49, 0x04, 0x12, 0xc3, 0x09, 0x25, 0x02, 0x8d, 0xdf, 0xfa, 0xdf, 0x12, 0xa4, 0x80, 0x03, 0xfb,
-	0xd0, 0xb6, 0x30, 0xcf, 0x7c, 0xf1, 0x18, 0x09, 0x81, 0xc1, 0x0a, 0x7c, 0xb9, 0x28, 0x1e, 0x18,
-	0x6a, 0x5d, 0x4a, 0x91, 0xa6, 0xbd, 0x0d, 0xe1, 0x91, 0xe7, 0x39, 0x19, 0x1e, 0xf5, 0xcf, 0xcf,
-	0x88, 0xb2, 0xcb, 0x91, 0x72, 0x7c, 0x13, 0x27, 0xab, 0xe3, 0x47, 0x53, 0xa4, 0xd3, 0x24, 0x7c,
-	0xea, 0xb6, 0x5c, 0x7e, 0x1a, 0xf2, 0xa9, 0xbb, 0xd6, 0xa2, 0x40, 0xd1, 0xff, 0x92, 0x20, 0x4b,
-	0x0d, 0xd7, 0xf2, 0xc7, 0x3c, 0xa4, 0xe0, 0x0e, 0xae, 0x91, 0x3c, 0x14, 0xd3, 0xc1, 0x38, 0x80,
-	0x8e, 0x53, 0xbd, 0xa4, 0x45, 0x04, 0xad, 0x49, 0xf2, 0x10, 0x3c, 0x3d, 0xdf, 0x0e, 0x8f, 0x07,
-	0xb2, 0xaa, 0x8c, 0x0f, 0x63, 0xd3, 0x3a, 0x2b, 0x86, 0x12, 0xa1, 0x13, 0x69, 0x15, 0xb8, 0x52,
-	0x7c, 0xb1, 0x3c, 0x70, 0x41, 0xff, 0xeb, 0x40, 0xab, 0x03, 0xf5, 0x62, 0x0f, 0x3b, 0x08, 0x6e,
-	0x07, 0xb4, 0x82, 0x92, 0x86, 0x5d, 0x91, 0xae, 0x93, 0x7c, 0xa4, 0x0c, 0xdf, 0x2f, 0x8d, 0x46,
-	0xb7, 0x77, 0x73, 0xe3, 0x56, 0xef, 0x76, 0x6d, 0x07, 0xc2, 0x98, 0xc8, 0xa1, 0x7f, 0x04, 0x9b,
-	0x76, 0x4c, 0x17, 0xba, 0x1c, 0xd5, 0xf3, 0x81, 0x57, 0xf8, 0x70, 0xd5, 0x54, 0x51, 0x94, 0x16,
-	0x5e, 0x81, 0xb7, 0x0f, 0x8b, 0x22, 0x64, 0xc5, 0x17, 0x45, 0x53, 0xef, 0xb8, 0xa9, 0x73, 0xdf,
-	0x71, 0xd3, 0x5f, 0xc9, 0x3b, 0xee, 0x8b, 0x9f, 0xa5, 0x48, 0x3e, 0xea, 0xe1, 0xd0, 0x65, 0xb0,
-	0x46, 0x59, 0x10, 0xdd, 0x75, 0x44, 0x6f, 0xf1, 0xea, 0x24, 0x6f, 0x6c, 0x6f, 0xb7, 0x6b, 0x06,
-	0x3e, 0x83, 0xbe, 0x2d, 0x8a, 0x98, 0x08, 0x60, 0xc0, 0xa5, 0xc5, 0x43, 0xef, 0x6b, 0xfa, 0xa4,
-	0x88, 0xb9, 0x2f, 0x7b, 0xf8, 0x08, 0xa5, 0x2a, 0x98, 0xe7, 0x48, 0xce, 0xe8, 0x76, 0x9b, 0xb7,
-	0x5b, 0xa0, 0xe9, 0x41, 0xa2, 0xfc, 0x14, 0x80, 0x2e, 0x4c, 0x54, 0x41, 0xf2, 0x3d, 0x72, 0x41,
-	0x13, 0xa2, 0x6a, 0xb5, 0x46, 0x07, 0xe7, 0xbb, 0x9f, 0x9c, 0x47, 0xf1, 0xd4, 0xcd, 0x1f, 0xc6,
-	0xf2, 0x1d, 0xda, 0xe8, 0x18, 0x14, 0x67, 0x7c, 0x90, 0x9c, 0x5b, 0x57, 0xc7, 0x67, 0xd0, 0xd5,
-	0xe3, 0x9c, 0xeb, 0xea, 0x4d, 0xf7, 0x7e, 0xaa, 0xac, 0x01, 0x66, 0x79, 0xd2, 0xb8, 0xc2, 0xfe,
-	0x8e, 0x71, 0xb6, 0xee, 0xae, 0x41, 0x77, 0xb9, 0x9a, 0xd4, 0xdc, 0x6c, 0x5d, 0x7c, 0x4e, 0x40,
-	0x2d, 0x60, 0x1d, 0xdd, 0x6b, 0xb5, 0xb8, 0x75, 0xe9, 0x39, 0xeb, 0xe8, 0xc8, 0x75, 0x11, 0x73,
-	0x1d, 0x52, 0x58, 0x7b, 0xa7, 0xb3, 0xdd, 0xd8, 0x6d, 0x94, 0x1e, 0xa4, 0xe7, 0x16, 0x54, 0xf3,
-	0x06, 0x43, 0x87, 0x85, 0xc2, 0xbc, 0xee, 0xd6, 0xde, 0x2e, 0x7f, 0x72, 0xbe, 0x9f, 0x99, 0x9f,
-	0xf0, 0x78, 0x14, 0xf6, 0xb1, 0x6c, 0xbc, 0x16, 0xd5, 0x71, 0x0f, 0x32, 0x22, 0x65, 0x46, 0x18,
-	0x51, 0xc4, 0xa1, 0x1e, 0xda, 0xf8, 0xbe, 0x78, 0x9d, 0xbe, 0x9f, 0x9d, 0xd3, 0x43, 0xd9, 0xbb,
-	0x10, 0x05, 0xa1, 0xd4, 0x8b, 0x9e, 0xa4, 0x22, 0xd6, 0x8b, 0x3f, 0x22, 0x39, 0x15, 0x30, 0x60,
-	0x77, 0xb2, 0x77, 0xdb, 0xf4, 0x4e, 0x83, 0xc2, 0xd1, 0xf3, 0xdd, 0x51, 0x9c, 0xbb, 0x9e, 0x0f,
-	0xde, 0x05, 0xcb, 0x58, 0xdc, 0x31, 0x5a, 0xc6, 0x6d, 0x00, 0xc8, 0x37, 0x2f, 0x05, 0x90, 0x5e,
-	0x5f, 0x2e, 0xc9, 0x09, 0x22, 0x9d, 0xd5, 0xb5, 0x87, 0x9f, 0xac, 0x2f, 0x7c, 0x04, 0xbf, 0x7f,
-	0x7d, 0xb2, 0x9e, 0xb8, 0xff, 0xe9, 0x7a, 0xe2, 0x21, 0xfc, 0xfe, 0x0c, 0xbf, 0xbf, 0xc3, 0xef,
-	0x20, 0xcb, 0xeb, 0x97, 0xd7, 0xfe, 0x17, 0x00, 0x00, 0xff, 0xff, 0x61, 0x4f, 0x38, 0x13, 0x5f,
-	0x1d, 0x00, 0x00,
+	0xf4, 0xe4, 0xa3, 0x8f, 0x2d, 0x0a, 0x14, 0x01, 0x0a, 0x04, 0x4d, 0xfa, 0x0f, 0x04, 0xe8, 0x21,
+	0x87, 0xf6, 0xd0, 0x37, 0x1f, 0xbb, 0x4b, 0xd2, 0x6b, 0xc5, 0x6e, 0x72, 0x20, 0xb8, 0xf3, 0xde,
+	0xef, 0xbd, 0x99, 0x37, 0xf3, 0xe6, 0x7d, 0x0c, 0x14, 0xfc, 0xc9, 0x88, 0x7a, 0x95, 0x91, 0xeb,
+	0xf8, 0x8e, 0xa2, 0xf4, 0x1d, 0xe3, 0x84, 0xba, 0x15, 0xef, 0x4c, 0x77, 0x87, 0x27, 0xa6, 0x5f,
+	0x39, 0xbd, 0x59, 0xbe, 0xe2, 0x9b, 0x43, 0xea, 0xf9, 0xfa, 0x70, 0xf4, 0x5a, 0xf8, 0x25, 0xe0,
+	0xe5, 0x67, 0xfb, 0x63, 0x57, 0xf7, 0x4d, 0xc7, 0x7e, 0x2d, 0xf8, 0x90, 0x8c, 0x4b, 0xc7, 0xce,
+	0xb1, 0xc3, 0x3f, 0x5f, 0x63, 0x5f, 0x82, 0xaa, 0x5e, 0x85, 0xc5, 0x7d, 0xea, 0x7a, 0x08, 0x53,
+	0x2e, 0x41, 0xc6, 0xb4, 0xfb, 0xf4, 0xde, 0x6a, 0xe2, 0x5a, 0xe2, 0x46, 0x9a, 0x88, 0x81, 0xfa,
+	0xdb, 0x04, 0x14, 0x34, 0xdb, 0x76, 0x7c, 0xae, 0xcb, 0x53, 0x14, 0x48, 0xdb, 0xfa, 0x90, 0x72,
+	0x50, 0x9e, 0xf0, 0x6f, 0xa5, 0x06, 0x59, 0x4b, 0x3f, 0xa4, 0x96, 0xb7, 0x9a, 0xbc, 0x96, 0xba,
+	0x51, 0xd8, 0x78, 0xa5, 0xf2, 0xe8, 0x9a, 0x2b, 0x53, 0x4a, 0x2a, 0xdb, 0x1c, 0xdd, 0xb0, 0x7d,
+	0x77, 0x42, 0xa4, 0x68, 0xf9, 0x7b, 0x50, 0x98, 0x22, 0x2b, 0x25, 0x48, 0x9d, 0xd0, 0x89, 0x9c,
+	0x86, 0x7d, 0xb2, 0xf5, 0x9d, 0xea, 0xd6, 0x98, 0xe2, 0x24, 0x8c, 0x26, 0x06, 0x6f, 0x25, 0x6f,
+	0x25, 0xd4, 0x77, 0x21, 0x4f, 0xa8, 0xe7, 0x8c, 0x5d, 0x83, 0x7a, 0xca, 0x4b, 0x90, 0xb7, 0x75,
+	0xdb, 0xe9, 0x19, 0xa3, 0xb1, 0xc7, 0xc5, 0x53, 0xd5, 0xe2, 0x67, 0x9f, 0x5c, 0xcd, 0xb5, 0x90,
+	0x58, 0xeb, 0xec, 0x79, 0x24, 0xc7, 0xd8, 0x35, 0xe4, 0x2a, 0xdf, 0x84, 0xe2, 0x90, 0x0e, 0x1d,
+	0x77, 0xd2, 0x3b, 0x9c, 0xf8, 0xd4, 0xe3, 0x8a, 0x53, 0xa4, 0x20, 0x68, 0x55, 0x46, 0x52, 0x7f,
+	0x9d, 0x80, 0x4b, 0x81, 0x6e, 0x42, 0x7f, 0x32, 0x36, 0x5d, 0x3a, 0xa4, 0xb6, 0xef, 0x29, 0xdf,
+	0x41, 0x9b, 0xcd, 0xa1, 0xe9, 0x8b, 0x39, 0x0a, 0x1b, 0xdf, 0x88, 0xb3, 0x39, 0x5c, 0x15, 0x91,
+	0x60, 0x45, 0x83, 0xa2, 0x4b, 0x3d, 0xea, 0x9e, 0x8a, 0x9d, 0xe0, 0x53, 0x7e, 0xa9, 0xf0, 0x8c,
+	0x88, 0xba, 0x09, 0xb9, 0x8e, 0xa5, 0xfb, 0x47, 0x8e, 0x3b, 0x54, 0x54, 0x28, 0xea, 0xae, 0x31,
+	0x30, 0x7d, 0x6a, 0xf8, 0x63, 0x37, 0x38, 0x95, 0x19, 0x9a, 0x72, 0x19, 0x92, 0x8e, 0x98, 0x28,
+	0x5f, 0xcd, 0xe2, 0x4e, 0x24, 0xdb, 0x5d, 0x82, 0x14, 0xf5, 0x6d, 0xb8, 0xd0, 0xb1, 0xc6, 0xc7,
+	0xa6, 0x5d, 0xa7, 0x9e, 0xe1, 0x9a, 0x23, 0xa6, 0x9d, 0x1d, 0x2f, 0x73, 0xbe, 0xe0, 0x78, 0xd9,
+	0x77, 0x78, 0xe4, 0xc9, 0xe8, 0xc8, 0xd5, 0x5f, 0x24, 0xe1, 0x42, 0xc3, 0x46, 0x61, 0x3a, 0x2d,
+	0x7d, 0x1d, 0x96, 0x29, 0x27, 0xf6, 0x4e, 0x85, 0x53, 0x49, 0x3d, 0x4b, 0x82, 0x1a, 0x78, 0x5a,
+	0x73, 0xce, 0x5f, 0x6e, 0xc6, 0x99, 0xff, 0x88, 0xf6, 0x38, 0xaf, 0x51, 0x1a, 0xb0, 0x38, 0xe2,
+	0x46, 0x78, 0xab, 0x29, 0xae, 0xeb, 0x7a, 0x9c, 0xae, 0x47, 0xec, 0xac, 0xa6, 0x1f, 0x7e, 0x72,
+	0x75, 0x81, 0x04, 0xb2, 0x5f, 0xc5, 0xf9, 0xfe, 0x95, 0x80, 0x95, 0x96, 0xd3, 0x9f, 0xd9, 0x87,
+	0x32, 0xe4, 0x06, 0x8e, 0xe7, 0x4f, 0x5d, 0x94, 0x70, 0xac, 0xdc, 0x82, 0xdc, 0x48, 0x1e, 0x9f,
+	0x3c, 0xfd, 0xb5, 0xf8, 0x25, 0x0b, 0x0c, 0x09, 0xd1, 0xca, 0xdb, 0x90, 0x77, 0x03, 0x9f, 0x40,
+	0x6b, 0x9f, 0xc0, 0x71, 0x22, 0xbc, 0xf2, 0x7d, 0xc8, 0x8a, 0x43, 0x58, 0x4d, 0x73, 0xc9, 0xeb,
+	0x4f, 0xb4, 0xe7, 0x44, 0x0a, 0xa9, 0x1f, 0x27, 0xa0, 0x44, 0xf4, 0x23, 0x7f, 0x87, 0x0e, 0x0f,
+	0xa9, 0xdb, 0xc5, 0x8b, 0x8c, 0xf7, 0xe7, 0x32, 0x9e, 0x23, 0xd5, 0xfb, 0xd4, 0xe5, 0x46, 0xe6,
+	0x88, 0x1c, 0x29, 0x7b, 0xcc, 0xc9, 0x75, 0x63, 0xa0, 0x1f, 0x9a, 0x96, 0xe9, 0x4f, 0xb8, 0x99,
+	0xcb, 0xf1, 0xa7, 0x3c, 0xaf, 0x13, 0x17, 0x1f, 0x09, 0x92, 0x19, 0x35, 0xca, 0x2a, 0x2c, 0x62,
+	0xac, 0xf3, 0xf4, 0x63, 0xca, 0xad, 0xcf, 0x93, 0x60, 0x88, 0xae, 0x5c, 0x9c, 0x96, 0x53, 0x0a,
+	0xb0, 0xb8, 0xd7, 0xba, 0xdb, 0x6a, 0x1f, 0xb4, 0x4a, 0x0b, 0xca, 0x0a, 0x14, 0xf6, 0x5a, 0xa4,
+	0xa1, 0xd5, 0xb6, 0xb4, 0xea, 0x76, 0xa3, 0x94, 0x50, 0x96, 0x30, 0x5c, 0x84, 0xc3, 0xa4, 0xfa,
+	0x51, 0x02, 0x80, 0x1d, 0xa0, 0x34, 0xea, 0x2d, 0xc8, 0x60, 0x3c, 0xf5, 0xc5, 0xc1, 0x2d, 0x6f,
+	0xbc, 0x10, 0xb7, 0xea, 0x08, 0x5e, 0x61, 0x7f, 0x94, 0x08, 0x91, 0xe9, 0x15, 0x26, 0xe7, 0x57,
+	0x98, 0xe1, 0xc8, 0xd9, 0xa5, 0xe5, 0x20, 0x5d, 0x67, 0x5f, 0x09, 0x25, 0x0f, 0x19, 0x5c, 0x53,
+	0xfd, 0xdd, 0x52, 0x12, 0x9d, 0xaf, 0x58, 0x6f, 0x76, 0x6b, 0xed, 0x56, 0xab, 0x51, 0xdb, 0x6d,
+	0xd4, 0x4b, 0x29, 0xf5, 0x3a, 0x64, 0x9a, 0x43, 0xd4, 0xa2, 0xac, 0x31, 0x0f, 0x38, 0xa2, 0x2e,
+	0xb5, 0x8d, 0xc0, 0xb1, 0x22, 0x82, 0xfa, 0xab, 0x1c, 0x64, 0x76, 0x9c, 0xb1, 0xed, 0x2b, 0x1b,
+	0x53, 0xb7, 0x78, 0x79, 0x63, 0x3d, 0xce, 0x04, 0x0e, 0xac, 0xec, 0x22, 0x4a, 0xde, 0x72, 0x3c,
+	0x4c, 0xe1, 0x2b, 0x72, 0xe9, 0x72, 0xc4, 0xe8, 0xbe, 0xee, 0x1e, 0x53, 0x5f, 0x6e, 0xba, 0x1c,
+	0x29, 0x37, 0x20, 0x87, 0xa7, 0xd3, 0x77, 0x6c, 0x6b, 0xc2, 0x5d, 0x2a, 0x27, 0xc2, 0x2c, 0x9e,
+	0x43, 0xbf, 0x8d, 0x34, 0x12, 0x72, 0x95, 0x2d, 0x28, 0x1e, 0x62, 0x32, 0xe9, 0x39, 0x23, 0x11,
+	0xf3, 0x32, 0x8f, 0x77, 0x40, 0xb1, 0xaa, 0x2a, 0xa2, 0xdb, 0x02, 0x4c, 0x0a, 0x87, 0xd1, 0x40,
+	0x69, 0xc1, 0xf2, 0xa9, 0x63, 0x8d, 0x87, 0x34, 0xd4, 0x95, 0xe5, 0xba, 0x5e, 0x7c, 0xbc, 0xae,
+	0x7d, 0x8e, 0x0f, 0xb4, 0x2d, 0x9d, 0x4e, 0x0f, 0xcb, 0x3f, 0x4f, 0x41, 0x61, 0x6a, 0x32, 0xa5,
+	0x0b, 0x05, 0x4c, 0x8b, 0x23, 0xfd, 0x98, 0x87, 0x5a, 0xb9, 0x7d, 0x37, 0x9f, 0x68, 0xa1, 0x95,
+	0x4e, 0x24, 0x48, 0xa6, 0xb5, 0xa8, 0x1f, 0x26, 0xa1, 0x30, 0xc5, 0x54, 0x5e, 0x86, 0x1c, 0xe9,
+	0x90, 0xe6, 0xbe, 0xb6, 0xdb, 0x28, 0x2d, 0x94, 0xd7, 0x3e, 0xf8, 0xf0, 0xda, 0x2a, 0xd7, 0x36,
+	0xad, 0xa0, 0xe3, 0x9a, 0xa7, 0xcc, 0x5b, 0x6e, 0xc0, 0x62, 0x00, 0x4d, 0x94, 0x9f, 0x43, 0xe8,
+	0xb3, 0xf3, 0xd0, 0x29, 0x24, 0xe9, 0x6e, 0x69, 0x04, 0x1d, 0x26, 0x19, 0x8f, 0x24, 0xdd, 0x81,
+	0xee, 0xd2, 0xbe, 0xf2, 0x2d, 0xc8, 0x4a, 0x60, 0xaa, 0x5c, 0x46, 0xe0, 0xe5, 0x79, 0x60, 0x84,
+	0x23, 0xdd, 0x6d, 0x6d, 0xbf, 0x51, 0x4a, 0xc7, 0xe3, 0x48, 0xd7, 0xd2, 0x4f, 0xa9, 0xf2, 0x02,
+	0xba, 0x36, 0x87, 0x65, 0xca, 0x57, 0x10, 0xf6, 0xcc, 0x23, 0xea, 0x18, 0xaa, 0xbc, 0xfa, 0xcb,
+	0xdf, 0xad, 0x2f, 0xfc, 0xf9, 0xf7, 0xeb, 0xa5, 0x79, 0x76, 0xf9, 0xbf, 0x09, 0x58, 0x9a, 0x39,
+	0x25, 0xcc, 0x6a, 0x59, 0xdb, 0x31, 0x9c, 0x91, 0x88, 0xc0, 0xb9, 0x2a, 0xa0, 0x63, 0x65, 0x5b,
+	0x4e, 0x0d, 0x29, 0x44, 0x72, 0x94, 0xbb, 0x73, 0x39, 0xe4, 0x8d, 0x27, 0x74, 0x81, 0xd8, 0x2c,
+	0x72, 0x1b, 0x96, 0xfa, 0xb8, 0x8f, 0xd4, 0xed, 0x19, 0x8e, 0x7d, 0x64, 0x1e, 0xcb, 0xe8, 0x5a,
+	0x8e, 0xd3, 0x59, 0xe7, 0x40, 0x52, 0x14, 0x02, 0x35, 0x8e, 0xff, 0x2a, 0xf9, 0xe3, 0x00, 0xd2,
+	0xec, 0x16, 0x2a, 0xcf, 0x41, 0xba, 0xda, 0x6c, 0xd5, 0xd1, 0x25, 0x2e, 0xe0, 0x2e, 0x2e, 0xf1,
+	0xa5, 0x33, 0x06, 0xf3, 0x31, 0xe5, 0x2a, 0x64, 0xf7, 0xdb, 0xdb, 0x7b, 0x3b, 0xcc, 0x0d, 0x2e,
+	0x22, 0x7b, 0x25, 0x64, 0x0b, 0xe3, 0xca, 0x17, 0xe4, 0xf6, 0xe6, 0x43, 0x86, 0xfa, 0x9f, 0x24,
+	0x2c, 0x11, 0x56, 0x1b, 0xba, 0x7e, 0xc7, 0xb1, 0x4c, 0x63, 0xa2, 0x74, 0x20, 0x8f, 0xf6, 0xf5,
+	0xcd, 0x29, 0xe7, 0xde, 0x78, 0x4c, 0x02, 0x89, 0xa4, 0x82, 0x51, 0x2d, 0x90, 0x24, 0x91, 0x12,
+	0x0c, 0x34, 0x99, 0x3e, 0xb5, 0xf4, 0xc9, 0x79, 0x99, 0xac, 0x2e, 0xeb, 0x50, 0x22, 0xa0, 0xbc,
+	0xea, 0xd2, 0xef, 0xf5, 0x74, 0xdf, 0xa7, 0xc3, 0x91, 0x2f, 0x32, 0x59, 0x1a, 0xab, 0x2e, 0xfd,
+	0x9e, 0x26, 0x49, 0xca, 0x9b, 0x90, 0x3d, 0x43, 0xb3, 0x9d, 0x33, 0x99, 0xac, 0xce, 0xd7, 0x2b,
+	0xb1, 0xea, 0x07, 0x2c, 0x47, 0xcd, 0x2d, 0x96, 0x6d, 0x6b, 0xab, 0xdd, 0x6a, 0x04, 0xdb, 0x2a,
+	0xf9, 0x6d, 0xbb, 0xe5, 0xd8, 0xcc, 0x75, 0xa1, 0xdd, 0xea, 0x6d, 0x6a, 0xcd, 0xed, 0x3d, 0xc2,
+	0xb6, 0xf6, 0x12, 0x42, 0x4a, 0x21, 0x64, 0x53, 0x37, 0x2d, 0x56, 0x40, 0x5d, 0x81, 0x94, 0xd6,
+	0xc2, 0xc8, 0x5c, 0x2e, 0x21, 0xbb, 0x18, 0xb2, 0x35, 0x7b, 0x12, 0x79, 0xf5, 0xfc, 0xbc, 0xea,
+	0x7b, 0x50, 0xdc, 0x1b, 0xf5, 0xf1, 0x66, 0x0a, 0x0f, 0x51, 0xae, 0x61, 0x68, 0xd1, 0x5d, 0xdd,
+	0xb2, 0xa8, 0x65, 0x7a, 0x43, 0x59, 0x63, 0x4f, 0x93, 0xb0, 0x30, 0x78, 0xf2, 0xbd, 0x94, 0xf5,
+	0x8b, 0x10, 0x50, 0x7f, 0x06, 0x2b, 0x38, 0x8b, 0xaf, 0x63, 0xa2, 0x0e, 0x52, 0xf3, 0x06, 0x14,
+	0x8d, 0x80, 0xd4, 0x33, 0xfb, 0xc2, 0x15, 0xab, 0x2b, 0x78, 0x91, 0x0a, 0x21, 0xb4, 0x59, 0x27,
+	0x85, 0x10, 0xd4, 0xec, 0x33, 0x3b, 0x47, 0x08, 0x65, 0xd3, 0x67, 0xaa, 0x8b, 0x08, 0x4d, 0x75,
+	0x10, 0xc2, 0x68, 0xb8, 0x8b, 0x79, 0x7a, 0xcf, 0xf4, 0xf1, 0x7a, 0xf4, 0x45, 0xf2, 0xcd, 0x90,
+	0x1c, 0x23, 0xd4, 0x70, 0xac, 0xbe, 0x9f, 0x04, 0xd8, 0xd5, 0xbd, 0x13, 0x39, 0x35, 0x96, 0x29,
+	0x61, 0x53, 0x72, 0x5e, 0x71, 0xbc, 0x1b, 0x80, 0x48, 0x84, 0x57, 0xde, 0x08, 0xb2, 0xaf, 0xa8,
+	0x19, 0xe2, 0x05, 0xe5, 0x5c, 0x71, 0x69, 0x77, 0xb6, 0x30, 0x60, 0x17, 0x91, 0xba, 0x2e, 0xf7,
+	0x22, 0xbc, 0x88, 0xf8, 0x89, 0xbd, 0x4a, 0x3e, 0xb4, 0x59, 0x66, 0xa2, 0xe7, 0xe3, 0x26, 0x99,
+	0xdb, 0xd0, 0xad, 0x05, 0x12, 0xc9, 0x55, 0x4b, 0xb0, 0xec, 0xe2, 0x35, 0xc3, 0x55, 0xf7, 0x3c,
+	0xce, 0x56, 0xff, 0x86, 0x7b, 0xd0, 0xec, 0x68, 0x3b, 0xf2, 0xb4, 0xeb, 0x90, 0x3d, 0xd2, 0x87,
+	0xa6, 0x35, 0x91, 0xd7, 0xec, 0xd5, 0xb8, 0x29, 0x22, 0x7c, 0x45, 0xeb, 0xf7, 0xb1, 0x54, 0xf3,
+	0x36, 0xb9, 0x0c, 0x91, 0xb2, 0x3c, 0x25, 0x8f, 0x0f, 0x6d, 0x4c, 0xbd, 0x41, 0x4a, 0xe6, 0x23,
+	0x16, 0x4c, 0x5c, 0xdd, 0x0e, 0xad, 0x15, 0x03, 0xb6, 0x0b, 0x18, 0x51, 0xe9, 0x99, 0x3e, 0x91,
+	0xf6, 0x06, 0x43, 0x4c, 0xc0, 0x39, 0xd1, 0x41, 0xd0, 0x3e, 0x9a, 0xcc, 0xa2, 0xe5, 0x97, 0xad,
+	0x87, 0x48, 0xb8, 0x08, 0x93, 0xa1, 0x74, 0xf9, 0x6d, 0x1e, 0x52, 0x22, 0xd6, 0x53, 0x45, 0xba,
+	0xd7, 0x61, 0x69, 0xc6, 0xce, 0x47, 0x6a, 0xa1, 0x66, 0x67, 0xff, 0xcd, 0x52, 0x5a, 0x7e, 0x7d,
+	0xb7, 0x94, 0x55, 0xff, 0x8d, 0xa5, 0x59, 0xc7, 0xe1, 0xd7, 0x8a, 0xed, 0x6a, 0x7c, 0xef, 0x99,
+	0xe3, 0x9d, 0xac, 0xe1, 0x58, 0xd2, 0x67, 0x62, 0x8b, 0x81, 0x48, 0x0b, 0x4b, 0xd4, 0x1c, 0x4e,
+	0x42, 0x41, 0x0c, 0xaf, 0x05, 0x51, 0xd5, 0xf4, 0x46, 0x88, 0xe3, 0xdb, 0xba, 0x44, 0x40, 0x90,
+	0x98, 0x24, 0x6b, 0x6c, 0x46, 0xe3, 0x43, 0xbc, 0xa6, 0x03, 0xda, 0x17, 0x98, 0x34, 0xc7, 0x2c,
+	0x85, 0x54, 0x06, 0x53, 0xeb, 0xd8, 0x9a, 0x05, 0x3a, 0x57, 0x21, 0xb5, 0x5b, 0xeb, 0x60, 0xdc,
+	0x59, 0xc1, 0xa8, 0x51, 0x08, 0xc8, 0x48, 0x62, 0x9c, 0xbd, 0x7a, 0x07, 0xc3, 0xcd, 0x0c, 0x07,
+	0x49, 0xe5, 0x34, 0x0b, 0x27, 0xea, 0x6f, 0x12, 0x90, 0x15, 0x59, 0x26, 0xd6, 0x62, 0x0d, 0x16,
+	0x83, 0xea, 0x47, 0xa4, 0xbe, 0x17, 0x1f, 0x9f, 0xa6, 0x2a, 0x32, 0xeb, 0x89, 0x73, 0x0c, 0xe4,
+	0xca, 0x6f, 0x41, 0x71, 0x9a, 0xf1, 0x54, 0xa7, 0xf8, 0x53, 0x28, 0x30, 0x47, 0x09, 0x72, 0xf5,
+	0x06, 0x64, 0x45, 0x26, 0x94, 0x57, 0xfd, 0xbc, 0x9c, 0x29, 0x91, 0x18, 0xe9, 0x16, 0x45, 0x9e,
+	0x0d, 0x9a, 0xb6, 0xf5, 0xf3, 0xdd, 0x91, 0x04, 0x70, 0xf5, 0x36, 0xa4, 0x3b, 0x14, 0x35, 0x3c,
+	0x0f, 0x8b, 0x36, 0x86, 0x9e, 0x28, 0xb2, 0xc9, 0x12, 0xa1, 0x4f, 0x31, 0x62, 0x65, 0x19, 0x0b,
+	0xe3, 0x19, 0x6e, 0x9e, 0x8e, 0xfe, 0x16, 0xf4, 0xad, 0xec, 0x5b, 0xdd, 0x85, 0xe2, 0x01, 0x35,
+	0x8f, 0x07, 0x3e, 0x9e, 0x18, 0x53, 0xf4, 0x2a, 0xa4, 0x47, 0x34, 0x5c, 0xfc, 0x6a, 0xac, 0xeb,
+	0x20, 0x9f, 0x70, 0x14, 0xbb, 0x90, 0x67, 0x5c, 0x5a, 0x3e, 0x15, 0xc8, 0x91, 0xfa, 0xc7, 0x24,
+	0x2c, 0x37, 0x3d, 0x6f, 0xac, 0x63, 0x19, 0x2e, 0xa3, 0xe0, 0x0f, 0x66, 0xdb, 0x88, 0x1b, 0xb1,
+	0x16, 0xce, 0x88, 0xcc, 0xb6, 0x12, 0x32, 0x72, 0x25, 0xc3, 0xc8, 0xa5, 0x3e, 0x4c, 0x04, 0x3d,
+	0xc4, 0xf5, 0xa9, 0x7b, 0x53, 0x5e, 0x45, 0x27, 0xba, 0x34, 0xad, 0x89, 0xee, 0xd9, 0x27, 0xb6,
+	0x73, 0x66, 0x63, 0xa2, 0xc5, 0x9e, 0xa2, 0xd5, 0x38, 0x40, 0x4f, 0xbb, 0x8c, 0x20, 0x65, 0x06,
+	0x44, 0xa8, 0x4d, 0xcf, 0x98, 0xa6, 0x4e, 0xa3, 0x55, 0x6f, 0xb6, 0xee, 0x60, 0x7a, 0x7b, 0x54,
+	0x53, 0x87, 0x62, 0x3a, 0xb3, 0x8f, 0x71, 0xbb, 0xb3, 0xcd, 0x6e, 0x77, 0x8f, 0x97, 0x8c, 0xcf,
+	0x22, 0xea, 0xe2, 0x0c, 0x8a, 0x0d, 0xb0, 0x5e, 0x44, 0x10, 0xcb, 0xa4, 0x08, 0x4a, 0xc7, 0x80,
+	0x58, 0x32, 0xc5, 0x00, 0x22, 0x3c, 0xfc, 0x1f, 0x49, 0x28, 0x69, 0x86, 0x41, 0x47, 0x3e, 0xe3,
+	0xcb, 0xea, 0x64, 0x17, 0x6f, 0x32, 0xfb, 0x32, 0x29, 0x7b, 0x53, 0x61, 0x6e, 0x71, 0x2b, 0xf6,
+	0x1d, 0x69, 0x4e, 0xae, 0x42, 0x1c, 0x8b, 0x6a, 0xfd, 0xa1, 0xe9, 0xb1, 0xb7, 0x05, 0x41, 0x23,
+	0xa1, 0xa6, 0xf2, 0xe7, 0x09, 0xb8, 0x18, 0x83, 0x50, 0x5e, 0x87, 0xb4, 0x8b, 0x64, 0x79, 0x3c,
+	0x6b, 0x8f, 0xeb, 0xf2, 0x98, 0x28, 0xe1, 0x48, 0x65, 0x1d, 0x40, 0x1f, 0xfb, 0x8e, 0xce, 0xe7,
+	0xe7, 0x07, 0x93, 0x23, 0x53, 0x14, 0xe5, 0x00, 0xa3, 0x35, 0x35, 0x5c, 0xd9, 0x28, 0x15, 0x36,
+	0x6e, 0xff, 0xbf, 0xab, 0xaf, 0x74, 0xb9, 0x1a, 0x22, 0xd5, 0x95, 0x2b, 0x58, 0xb0, 0xf3, 0x2f,
+	0xe6, 0xd1, 0x58, 0x52, 0xe8, 0x7c, 0xd1, 0x45, 0xc2, 0xbf, 0x99, 0xa3, 0xe8, 0xd6, 0x71, 0xe0,
+	0x28, 0xf8, 0xa9, 0x7e, 0x84, 0xb9, 0xa8, 0x71, 0xcf, 0xa7, 0xae, 0xad, 0x5b, 0x35, 0x4d, 0x69,
+	0x4c, 0x45, 0x48, 0x61, 0xed, 0x4b, 0xb1, 0xbd, 0x7f, 0x28, 0x51, 0xa9, 0x69, 0x31, 0x31, 0x12,
+	0xab, 0x83, 0xb1, 0x6b, 0xc9, 0x77, 0x24, 0x5e, 0x1d, 0xec, 0x91, 0x6d, 0xc2, 0x68, 0xec, 0x11,
+	0x26, 0x88, 0x48, 0xa9, 0xc7, 0x3f, 0x00, 0x4e, 0x4d, 0xf0, 0xf5, 0x47, 0xa5, 0x57, 0x01, 0xa2,
+	0x55, 0xe3, 0x51, 0x65, 0x6a, 0x9b, 0xdd, 0xee, 0x36, 0x5e, 0x0f, 0x5e, 0x2d, 0x47, 0x2c, 0x4e,
+	0x56, 0xff, 0x90, 0x80, 0x5c, 0x4d, 0x93, 0x59, 0x65, 0x13, 0x4a, 0x3c, 0x96, 0x18, 0xd4, 0xf5,
+	0x7b, 0xf4, 0xde, 0xc8, 0x74, 0x27, 0x32, 0x1c, 0x9c, 0x5f, 0x76, 0x2e, 0x33, 0xa9, 0x1a, 0x0a,
+	0x35, 0xb8, 0x8c, 0x42, 0xa0, 0x48, 0xa5, 0x89, 0x3d, 0x43, 0x0f, 0x82, 0xf3, 0xfa, 0xf9, 0x5b,
+	0x21, 0x4a, 0xb2, 0x68, 0x8c, 0x0d, 0x6f, 0xa0, 0xa4, 0xa6, 0x7b, 0xea, 0x3e, 0x5c, 0x6c, 0xbb,
+	0xc6, 0x00, 0x8b, 0x23, 0x31, 0xa9, 0x5c, 0xf2, 0x6d, 0x58, 0xf3, 0xb1, 0x08, 0xea, 0x0d, 0x4c,
+	0xcf, 0x67, 0xcf, 0x97, 0xe8, 0x1b, 0xd4, 0x66, 0xfc, 0x1e, 0x7f, 0x66, 0x14, 0xcf, 0x9e, 0xe4,
+	0x0a, 0xc3, 0x6c, 0x09, 0x08, 0x09, 0x10, 0xdb, 0x0c, 0xa0, 0xfe, 0x08, 0x4a, 0x75, 0xd3, 0x1b,
+	0xe9, 0x3e, 0xea, 0x96, 0x3d, 0x8c, 0x72, 0x07, 0x4a, 0x03, 0x8a, 0x35, 0xec, 0x21, 0xd5, 0x31,
+	0x0f, 0x52, 0xd7, 0x74, 0xfa, 0x4f, 0xb4, 0x0f, 0x2b, 0xa1, 0x54, 0x87, 0x0b, 0xa9, 0x5f, 0x60,
+	0xd6, 0x66, 0xef, 0x3a, 0x52, 0xef, 0x2b, 0x70, 0xc1, 0xb3, 0xf5, 0x91, 0x37, 0x70, 0xfc, 0x9e,
+	0x69, 0xfb, 0xec, 0x21, 0xd3, 0x92, 0xf5, 0x6f, 0x29, 0x60, 0x34, 0x25, 0x1d, 0xe3, 0xb1, 0x72,
+	0x42, 0xe9, 0xa8, 0xe7, 0x58, 0xfd, 0x5e, 0xc0, 0x14, 0x8f, 0x97, 0x88, 0x66, 0x9c, 0xb6, 0xd5,
+	0xef, 0x06, 0x74, 0xa5, 0x0a, 0xeb, 0x96, 0x73, 0xdc, 0x43, 0xcb, 0x5c, 0xbc, 0xeb, 0xbd, 0x23,
+	0xc7, 0xed, 0x79, 0x96, 0x73, 0x86, 0x1f, 0x16, 0xfe, 0x51, 0x37, 0x68, 0x2e, 0xca, 0x88, 0x6a,
+	0x08, 0xd0, 0xa6, 0xe3, 0x76, 0x91, 0xb7, 0x19, 0x20, 0x58, 0x6a, 0x8f, 0xcc, 0xf6, 0x4d, 0xe3,
+	0x24, 0x48, 0xed, 0x21, 0x75, 0x17, 0x89, 0x18, 0xdd, 0x96, 0xa8, 0x45, 0x0d, 0xbe, 0xc9, 0x1c,
+	0x95, 0xe1, 0xa8, 0x62, 0x40, 0x64, 0x20, 0xf5, 0xdb, 0x90, 0xef, 0x58, 0xba, 0xc1, 0x9f, 0x88,
+	0x59, 0xc5, 0x8f, 0x69, 0x8b, 0x9d, 0x1c, 0x5a, 0x2d, 0x42, 0x5a, 0x9e, 0x4c, 0x93, 0xd4, 0xf7,
+	0x31, 0xd1, 0x13, 0xc7, 0xf1, 0xf1, 0x92, 0x5e, 0x83, 0xac, 0xa1, 0xf7, 0x02, 0x77, 0x2f, 0x56,
+	0xf3, 0xe8, 0x16, 0x99, 0x9a, 0x76, 0x97, 0x4e, 0x48, 0xc6, 0xd0, 0xf1, 0x8f, 0xa5, 0x3c, 0x44,
+	0x30, 0x27, 0xe5, 0xdb, 0x51, 0x14, 0x29, 0x0f, 0xbd, 0x18, 0x29, 0x04, 0x85, 0xd9, 0x3f, 0x46,
+	0xb5, 0xa2, 0x04, 0xf5, 0x06, 0xba, 0x37, 0x10, 0x05, 0x62, 0x75, 0x19, 0x91, 0x20, 0x90, 0x5b,
+	0x48, 0x25, 0x20, 0xd0, 0xec, 0x5b, 0xfd, 0x7b, 0x02, 0x0a, 0x6c, 0x60, 0x1e, 0x99, 0x06, 0xcb,
+	0x2d, 0x4f, 0x1f, 0x17, 0x31, 0x30, 0x18, 0x9e, 0x2b, 0x17, 0xc5, 0x03, 0x43, 0xad, 0x4b, 0x08,
+	0xa3, 0x29, 0xef, 0x60, 0x48, 0xe4, 0xb9, 0x4d, 0x86, 0x44, 0xf5, 0xcb, 0xb3, 0xa0, 0xec, 0x6c,
+	0xa4, 0x1c, 0xdf, 0xc4, 0x68, 0x75, 0xfc, 0x68, 0x8a, 0x64, 0x9a, 0xc4, 0x9e, 0xb7, 0x0d, 0x9b,
+	0x9f, 0x86, 0x7c, 0xde, 0xae, 0xb5, 0x08, 0x52, 0xd4, 0xbf, 0x26, 0x60, 0xa9, 0x61, 0x1b, 0xee,
+	0x84, 0x87, 0x14, 0xb6, 0x83, 0x6b, 0x90, 0xc7, 0x02, 0xda, 0x9b, 0x78, 0xd8, 0x65, 0x06, 0xaf,
+	0x67, 0x21, 0x41, 0x69, 0x42, 0x1e, 0x83, 0xa7, 0xe3, 0x9a, 0xfe, 0x60, 0x28, 0x2b, 0xc9, 0xf8,
+	0x30, 0x36, 0xad, 0xb3, 0xa2, 0x05, 0x22, 0x24, 0x92, 0x0e, 0x02, 0x57, 0x8a, 0x2f, 0x96, 0x07,
+	0x2e, 0xec, 0x79, 0x2d, 0x6c, 0x6f, 0xb0, 0x46, 0xec, 0xb1, 0xae, 0x81, 0xdb, 0x81, 0xed, 0x9f,
+	0xa4, 0xb1, 0x4e, 0x48, 0x55, 0x21, 0x1f, 0x2a, 0x63, 0x6f, 0x96, 0x5a, 0xa3, 0xdb, 0xbb, 0xb9,
+	0x71, 0xab, 0x77, 0xa7, 0xb6, 0x83, 0x61, 0x4c, 0xe4, 0xcd, 0x3f, 0xa1, 0x4d, 0x3b, 0xba, 0x8d,
+	0x9d, 0x4d, 0xd0, 0xe7, 0xa1, 0x57, 0xb8, 0x78, 0xd5, 0x82, 0x42, 0x28, 0x2d, 0xbc, 0x82, 0xdd,
+	0x3e, 0x56, 0x08, 0x31, 0x56, 0x7c, 0x21, 0x34, 0xf5, 0x76, 0x9b, 0x3a, 0xf7, 0xed, 0x36, 0xfd,
+	0xb5, 0xbc, 0xdd, 0xbe, 0xfc, 0x45, 0x0a, 0xf2, 0x61, 0xdf, 0xc6, 0x5c, 0x86, 0xd5, 0x25, 0x0b,
+	0xa2, 0xa3, 0x0e, 0xe9, 0x2d, 0x5e, 0x91, 0xe4, 0xb5, 0xed, 0xed, 0x76, 0x4d, 0x63, 0x4f, 0x9f,
+	0xef, 0x88, 0xc2, 0x25, 0x04, 0x68, 0x78, 0x69, 0xd9, 0xa1, 0xf7, 0x15, 0x35, 0x2a, 0x5c, 0xee,
+	0xcb, 0xbe, 0x3d, 0x44, 0x05, 0x55, 0xcb, 0x0b, 0x90, 0xd3, 0xba, 0xdd, 0xe6, 0x9d, 0x16, 0x6a,
+	0x7a, 0x90, 0x28, 0x3f, 0x83, 0xa0, 0x0b, 0x91, 0x2a, 0x4c, 0xb8, 0xc7, 0x36, 0x6a, 0x62, 0xa8,
+	0x5a, 0xad, 0xd1, 0x61, 0xf3, 0xdd, 0x4f, 0xce, 0xa3, 0x78, 0xba, 0xe6, 0x8f, 0x61, 0xf9, 0x0e,
+	0x69, 0x74, 0x34, 0xc2, 0x66, 0x7c, 0x90, 0x9c, 0x5b, 0x57, 0xc7, 0xa5, 0xd8, 0xc9, 0xb3, 0x39,
+	0xd7, 0x83, 0x77, 0xdc, 0xfb, 0xa9, 0xb2, 0x82, 0x98, 0xe5, 0xa8, 0x59, 0xc5, 0xfd, 0x9d, 0xb0,
+	0xd9, 0xba, 0xbb, 0x1a, 0xd9, 0xe5, 0x6a, 0x52, 0x73, 0xb3, 0x75, 0xd9, 0x13, 0x02, 0xd3, 0x82,
+	0xd6, 0x91, 0xbd, 0x56, 0x8b, 0x5b, 0x97, 0x9e, 0xb3, 0x8e, 0x8c, 0x6d, 0x9b, 0x61, 0xae, 0x63,
+	0x0a, 0x6b, 0xef, 0x74, 0xb6, 0x1b, 0xbb, 0x8d, 0xd2, 0x83, 0xf4, 0xdc, 0x82, 0x6a, 0xce, 0x70,
+	0x64, 0x51, 0x5f, 0x98, 0xd7, 0xdd, 0xda, 0xdb, 0xe5, 0xcf, 0xcc, 0xf7, 0x33, 0xf3, 0x13, 0x0e,
+	0xc6, 0x7e, 0x9f, 0x95, 0x8a, 0xd7, 0xc2, 0xda, 0xed, 0x41, 0x46, 0xa4, 0xcc, 0x10, 0x23, 0x0a,
+	0x37, 0xa6, 0x87, 0x34, 0x7e, 0x28, 0x5e, 0xa4, 0xef, 0x67, 0xe7, 0xf4, 0x10, 0xfa, 0x1e, 0x46,
+	0x41, 0x2c, 0xef, 0xc2, 0x67, 0xa8, 0x90, 0xf5, 0xf2, 0x8f, 0x21, 0x17, 0x04, 0x0c, 0xdc, 0x9d,
+	0xec, 0x41, 0x9b, 0xdc, 0x6d, 0x10, 0x3c, 0x7a, 0xbe, 0x3b, 0x01, 0xe7, 0xc0, 0x71, 0xd1, 0xbb,
+	0x70, 0x19, 0x8b, 0x3b, 0x5a, 0x4b, 0xbb, 0x83, 0x00, 0xf9, 0xce, 0x15, 0x00, 0xa4, 0xd7, 0x97,
+	0x4b, 0x72, 0x82, 0x50, 0x67, 0x75, 0xed, 0xe1, 0xa7, 0xeb, 0x0b, 0x1f, 0xe3, 0xef, 0xf3, 0x4f,
+	0xd7, 0x13, 0xf7, 0x3f, 0x5b, 0x4f, 0x3c, 0xc4, 0xdf, 0x5f, 0xf0, 0xf7, 0x4f, 0xfc, 0x1d, 0x66,
+	0x79, 0xfd, 0xf2, 0xc6, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x79, 0xcb, 0x88, 0x96, 0x53, 0x1d,
+	0x00, 0x00,
 }
 }

+ 4 - 5
vendor/src/github.com/docker/swarmkit/api/types.proto

@@ -426,10 +426,10 @@ message IssuanceStatus {
 
 
 message AcceptancePolicy {
 message AcceptancePolicy {
 	message RoleAdmissionPolicy {
 	message RoleAdmissionPolicy {
-		message HashedSecret {
-			// The actual hashed content
+		message Secret {
+			// The actual content (possibly hashed)
 			bytes data = 1;
 			bytes data = 1;
-			// The type of hash we are using
+			// The type of hash we are using, or "plaintext"
 			string alg = 2;
 			string alg = 2;
 		}
 		}
 
 
@@ -439,13 +439,12 @@ message AcceptancePolicy {
 		bool autoaccept = 2;
 		bool autoaccept = 2;
 		// Secret represents a user-provided string that is necessary for new
 		// Secret represents a user-provided string that is necessary for new
 		// nodes to join the cluster
 		// nodes to join the cluster
-		HashedSecret secret = 3;
+		Secret secret = 3;
 	}
 	}
 
 
 	repeated RoleAdmissionPolicy policies = 1;
 	repeated RoleAdmissionPolicy policies = 1;
 }
 }
 
 
-
 message ExternalCA {
 message ExternalCA {
 	enum CAProtocol {
 	enum CAProtocol {
 		CFSSL = 0 [(gogoproto.enumvalue_customname) = "CAProtocolCFSSL"];
 		CFSSL = 0 [(gogoproto.enumvalue_customname) = "CAProtocolCFSSL"];

+ 8 - 1
vendor/src/github.com/docker/swarmkit/ca/server.go

@@ -1,6 +1,8 @@
 package ca
 package ca
 
 
 import (
 import (
+	"crypto/subtle"
+	"errors"
 	"fmt"
 	"fmt"
 	"strings"
 	"strings"
 	"sync"
 	"sync"
@@ -255,7 +257,7 @@ func (s *Server) IssueNodeCertificate(ctx context.Context, request *api.IssueNod
 }
 }
 
 
 // checkSecretValidity verifies if a secret string matches the secret hash stored in the
 // checkSecretValidity verifies if a secret string matches the secret hash stored in the
-// Acceptance Policy. It currently only supports bcrypted hashes.
+// Acceptance Policy. It currently only supports bcrypted hashes and plaintext.
 func checkSecretValidity(policy *api.AcceptancePolicy_RoleAdmissionPolicy, secret string) error {
 func checkSecretValidity(policy *api.AcceptancePolicy_RoleAdmissionPolicy, secret string) error {
 	if policy == nil || secret == "" {
 	if policy == nil || secret == "" {
 		return fmt.Errorf("invalid policy or secret")
 		return fmt.Errorf("invalid policy or secret")
@@ -264,6 +266,11 @@ func checkSecretValidity(policy *api.AcceptancePolicy_RoleAdmissionPolicy, secre
 	switch strings.ToLower(policy.Secret.Alg) {
 	switch strings.ToLower(policy.Secret.Alg) {
 	case "bcrypt":
 	case "bcrypt":
 		return bcrypt.CompareHashAndPassword(policy.Secret.Data, []byte(secret))
 		return bcrypt.CompareHashAndPassword(policy.Secret.Data, []byte(secret))
+	case "plaintext":
+		if subtle.ConstantTimeCompare(policy.Secret.Data, []byte(secret)) == 1 {
+			return nil
+		}
+		return errors.New("incorrect secret")
 	}
 	}
 
 
 	return fmt.Errorf("hash algorithm not supported: %s", policy.Secret.Alg)
 	return fmt.Errorf("hash algorithm not supported: %s", policy.Secret.Alg)

+ 3 - 5
vendor/src/github.com/docker/swarmkit/identity/randomid.go

@@ -16,9 +16,8 @@ var (
 // parameters for random identifier generation. We can tweak this when there is
 // parameters for random identifier generation. We can tweak this when there is
 // time for further analysis.
 // time for further analysis.
 const (
 const (
-	randomIDEntropyBytes     = 16
-	randomNodeIDEntropyBytes = 8
-	randomIDBase             = 36
+	randomIDEntropyBytes = 16
+	randomIDBase         = 36
 
 
 	// To ensure that all identifiers are fixed length, we make sure they
 	// To ensure that all identifiers are fixed length, we make sure they
 	// get padded out to 25 characters, which is the maximum for the base36
 	// get padded out to 25 characters, which is the maximum for the base36
@@ -28,8 +27,7 @@ const (
 	// was calculated from floor(log(2^128-1, 36)) + 1.
 	// was calculated from floor(log(2^128-1, 36)) + 1.
 	//
 	//
 	// See http://mathworld.wolfram.com/NumberLength.html for more information.
 	// See http://mathworld.wolfram.com/NumberLength.html for more information.
-	maxRandomIDLength     = 25
-	maxRandomNodeIDLength = 13
+	maxRandomIDLength = 25
 )
 )
 
 
 // NewID generates a new identifier for use where random identifiers with low
 // NewID generates a new identifier for use where random identifiers with low

+ 11 - 0
vendor/src/github.com/docker/swarmkit/manager/allocator/networkallocator/networkallocator.go

@@ -8,6 +8,8 @@ import (
 	"github.com/docker/libnetwork/drivers/overlay/ovmanager"
 	"github.com/docker/libnetwork/drivers/overlay/ovmanager"
 	"github.com/docker/libnetwork/drvregistry"
 	"github.com/docker/libnetwork/drvregistry"
 	"github.com/docker/libnetwork/ipamapi"
 	"github.com/docker/libnetwork/ipamapi"
+	builtinIpam "github.com/docker/libnetwork/ipams/builtin"
+	nullIpam "github.com/docker/libnetwork/ipams/null"
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/log"
 	"github.com/docker/swarmkit/log"
 	"golang.org/x/net/context"
 	"golang.org/x/net/context"
@@ -76,6 +78,15 @@ func New() (*NetworkAllocator, error) {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
+	for _, fn := range [](func(ipamapi.Callback, interface{}, interface{}) error){
+		builtinIpam.Init,
+		nullIpam.Init,
+	} {
+		if err := fn(reg, nil, nil); err != nil {
+			return nil, err
+		}
+	}
+
 	pa, err := newPortAllocator()
 	pa, err := newPortAllocator()
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err

+ 21 - 8
vendor/src/github.com/docker/swarmkit/manager/controlapi/node.go

@@ -2,6 +2,7 @@ package controlapi
 
 
 import (
 import (
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/api"
+	"github.com/docker/swarmkit/manager/state/raft/membership"
 	"github.com/docker/swarmkit/manager/state/store"
 	"github.com/docker/swarmkit/manager/state/store"
 	"golang.org/x/net/context"
 	"golang.org/x/net/context"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc"
@@ -188,8 +189,10 @@ func (s *Server) UpdateNode(ctx context.Context, request *api.UpdateNodeRequest)
 
 
 	var (
 	var (
 		node   *api.Node
 		node   *api.Node
+		member *membership.Member
 		demote bool
 		demote bool
 	)
 	)
+
 	err := s.store.Update(func(tx store.Tx) error {
 	err := s.store.Update(func(tx store.Tx) error {
 		node = store.GetNode(tx, request.NodeID)
 		node = store.GetNode(tx, request.NodeID)
 		if node == nil {
 		if node == nil {
@@ -199,6 +202,8 @@ func (s *Server) UpdateNode(ctx context.Context, request *api.UpdateNodeRequest)
 		// Demotion sanity checks.
 		// Demotion sanity checks.
 		if node.Spec.Role == api.NodeRoleManager && request.Spec.Role == api.NodeRoleWorker {
 		if node.Spec.Role == api.NodeRoleManager && request.Spec.Role == api.NodeRoleWorker {
 			demote = true
 			demote = true
+
+			// Check for manager entries in Store.
 			managers, err := store.FindNodes(tx, store.ByRole(api.NodeRoleManager))
 			managers, err := store.FindNodes(tx, store.ByRole(api.NodeRoleManager))
 			if err != nil {
 			if err != nil {
 				return grpc.Errorf(codes.Internal, "internal store error: %v", err)
 				return grpc.Errorf(codes.Internal, "internal store error: %v", err)
@@ -206,6 +211,16 @@ func (s *Server) UpdateNode(ctx context.Context, request *api.UpdateNodeRequest)
 			if len(managers) == 1 && managers[0].ID == node.ID {
 			if len(managers) == 1 && managers[0].ID == node.ID {
 				return grpc.Errorf(codes.FailedPrecondition, "attempting to demote the last manager of the swarm")
 				return grpc.Errorf(codes.FailedPrecondition, "attempting to demote the last manager of the swarm")
 			}
 			}
+
+			// Check for node in memberlist
+			if member = s.raft.GetMemberByNodeID(request.NodeID); member == nil {
+				return grpc.Errorf(codes.NotFound, "can't find manager in raft memberlist")
+			}
+
+			// Quorum safeguard
+			if !s.raft.CanRemoveMember(member.RaftID) {
+				return grpc.Errorf(codes.FailedPrecondition, "can't remove member from the raft: this would result in a loss of quorum")
+			}
 		}
 		}
 
 
 		node.Meta.Version = *request.NodeVersion
 		node.Meta.Version = *request.NodeVersion
@@ -220,14 +235,12 @@ func (s *Server) UpdateNode(ctx context.Context, request *api.UpdateNodeRequest)
 	}
 	}
 
 
 	if demote && s.raft != nil {
 	if demote && s.raft != nil {
-		memberlist := s.raft.GetMemberlist()
-		for raftID, member := range memberlist {
-			if member.NodeID == request.NodeID {
-				if err := s.raft.RemoveMember(ctx, raftID); err != nil {
-					return nil, err
-				}
-				break
-			}
+		// TODO(abronan): the remove can potentially fail and leave the node with
+		// an incorrect role (worker rather than manager), we need to reconcile the
+		// memberlist with the desired state rather than attempting to remove the
+		// member once.
+		if err := s.raft.RemoveMember(ctx, member.RaftID); err != nil {
+			return nil, grpc.Errorf(codes.Internal, "cannot demote manager to worker: %v", err)
 		}
 		}
 	}
 	}
 
 

+ 13 - 0
vendor/src/github.com/docker/swarmkit/manager/controlapi/service.go

@@ -7,6 +7,7 @@ import (
 	"github.com/docker/engine-api/types/reference"
 	"github.com/docker/engine-api/types/reference"
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/identity"
 	"github.com/docker/swarmkit/identity"
+	"github.com/docker/swarmkit/manager/scheduler"
 	"github.com/docker/swarmkit/manager/state/store"
 	"github.com/docker/swarmkit/manager/state/store"
 	"github.com/docker/swarmkit/protobuf/ptypes"
 	"github.com/docker/swarmkit/protobuf/ptypes"
 	"golang.org/x/net/context"
 	"golang.org/x/net/context"
@@ -75,6 +76,14 @@ func validateRestartPolicy(rp *api.RestartPolicy) error {
 	return nil
 	return nil
 }
 }
 
 
+func validatePlacement(placement *api.Placement) error {
+	if placement == nil {
+		return nil
+	}
+	_, err := scheduler.ParseExprs(placement.Constraints)
+	return err
+}
+
 func validateUpdate(uc *api.UpdateConfig) error {
 func validateUpdate(uc *api.UpdateConfig) error {
 	if uc == nil {
 	if uc == nil {
 		return nil
 		return nil
@@ -101,6 +110,10 @@ func validateTask(taskSpec api.TaskSpec) error {
 		return err
 		return err
 	}
 	}
 
 
+	if err := validatePlacement(taskSpec.Placement); err != nil {
+		return err
+	}
+
 	if taskSpec.GetRuntime() == nil {
 	if taskSpec.GetRuntime() == nil {
 		return grpc.Errorf(codes.InvalidArgument, "TaskSpec: missing runtime")
 		return grpc.Errorf(codes.InvalidArgument, "TaskSpec: missing runtime")
 	}
 	}

+ 6 - 6
vendor/src/github.com/docker/swarmkit/manager/dispatcher/dispatcher.go

@@ -328,14 +328,14 @@ func (d *Dispatcher) isRunning() bool {
 }
 }
 
 
 // register is used for registration of node with particular dispatcher.
 // register is used for registration of node with particular dispatcher.
-func (d *Dispatcher) register(ctx context.Context, nodeID string, description *api.NodeDescription) (string, string, error) {
+func (d *Dispatcher) register(ctx context.Context, nodeID string, description *api.NodeDescription) (string, error) {
 	// prevent register until we're ready to accept it
 	// prevent register until we're ready to accept it
 	if err := d.isRunningLocked(); err != nil {
 	if err := d.isRunningLocked(); err != nil {
-		return "", "", err
+		return "", err
 	}
 	}
 
 
 	if err := d.nodes.CheckRateLimit(nodeID); err != nil {
 	if err := d.nodes.CheckRateLimit(nodeID); err != nil {
-		return "", "", err
+		return "", err
 	}
 	}
 
 
 	// create or update node in store
 	// create or update node in store
@@ -355,7 +355,7 @@ func (d *Dispatcher) register(ctx context.Context, nodeID string, description *a
 
 
 	})
 	})
 	if err != nil {
 	if err != nil {
-		return "", "", err
+		return "", err
 	}
 	}
 
 
 	expireFunc := func() {
 	expireFunc := func() {
@@ -377,7 +377,7 @@ func (d *Dispatcher) register(ctx context.Context, nodeID string, description *a
 	// time a node registers, we invalidate the session and issue a new
 	// time a node registers, we invalidate the session and issue a new
 	// session, once identity is proven. This will cause misbehaved agents to
 	// session, once identity is proven. This will cause misbehaved agents to
 	// be kicked when multiple connections are made.
 	// be kicked when multiple connections are made.
-	return rn.Node.ID, rn.SessionID, nil
+	return rn.SessionID, nil
 }
 }
 
 
 // UpdateTaskStatus updates status of task. Node should send such updates
 // UpdateTaskStatus updates status of task. Node should send such updates
@@ -650,7 +650,7 @@ func (d *Dispatcher) Session(r *api.SessionRequest, stream api.Dispatcher_Sessio
 	}
 	}
 
 
 	// register the node.
 	// register the node.
-	nodeID, sessionID, err := d.register(stream.Context(), nodeID, r.Description)
+	sessionID, err := d.register(stream.Context(), nodeID, r.Description)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}

+ 17 - 0
vendor/src/github.com/docker/swarmkit/manager/orchestrator/services.go

@@ -70,6 +70,15 @@ func (r *ReplicatedOrchestrator) resolveService(ctx context.Context, task *api.T
 	return service
 	return service
 }
 }
 
 
+type tasksByRunningState []*api.Task
+
+func (ts tasksByRunningState) Len() int      { return len(ts) }
+func (ts tasksByRunningState) Swap(i, j int) { ts[i], ts[j] = ts[j], ts[i] }
+
+func (ts tasksByRunningState) Less(i, j int) bool {
+	return ts[i].Status.State == api.TaskStateRunning && ts[j].Status.State != api.TaskStateRunning
+}
+
 type taskWithIndex struct {
 type taskWithIndex struct {
 	task *api.Task
 	task *api.Task
 
 
@@ -139,6 +148,14 @@ func (r *ReplicatedOrchestrator) reconcile(ctx context.Context, service *api.Ser
 
 
 		// Preferentially remove tasks on the nodes that have the most
 		// Preferentially remove tasks on the nodes that have the most
 		// copies of this service, to leave a more balanced result.
 		// copies of this service, to leave a more balanced result.
+
+		// First sort tasks such that tasks which are currently running
+		// (in terms of observed state) appear before non-running tasks.
+		// This will cause us to prefer to remove non-running tasks, all
+		// other things being equal in terms of node balance.
+
+		sort.Sort(tasksByRunningState(runningTasks))
+
 		// Assign each task an index that counts it as the nth copy of
 		// Assign each task an index that counts it as the nth copy of
 		// of the service on its node (1, 2, 3, ...), and sort the
 		// of the service on its node (1, 2, 3, ...), and sort the
 		// tasks by this counter value.
 		// tasks by this counter value.

+ 12 - 7
vendor/src/github.com/docker/swarmkit/manager/scheduler/constraint.go

@@ -18,14 +18,19 @@ type ConstraintFilter struct {
 
 
 // SetTask returns true when the filter is enable for a given task.
 // SetTask returns true when the filter is enable for a given task.
 func (f *ConstraintFilter) SetTask(t *api.Task) bool {
 func (f *ConstraintFilter) SetTask(t *api.Task) bool {
-	if t.Spec.Placement != nil && len(t.Spec.Placement.Constraints) > 0 {
-		constraints, err := ParseExprs(t.Spec.Placement.Constraints)
-		if err == nil {
-			f.constraints = constraints
-			return true
-		}
+	if t.Spec.Placement == nil || len(t.Spec.Placement.Constraints) == 0 {
+		return false
+	}
+
+	constraints, err := ParseExprs(t.Spec.Placement.Constraints)
+	if err != nil {
+		// constraints have been validated at controlapi
+		// if in any case it finds an error here, treat this task
+		// as constraint filter disabled.
+		return false
 	}
 	}
-	return false
+	f.constraints = constraints
+	return true
 }
 }
 
 
 // Check returns true if the task's constraint is supported by the given node.
 // Check returns true if the task's constraint is supported by the given node.

+ 1 - 11
vendor/src/github.com/docker/swarmkit/manager/state/raft/membership/cluster.go

@@ -165,19 +165,11 @@ func (c *Cluster) ValidateConfigurationChange(cc raftpb.ConfChange) error {
 // that might block or harm the Cluster on Member recovery
 // that might block or harm the Cluster on Member recovery
 func (c *Cluster) CanRemoveMember(from uint64, id uint64) bool {
 func (c *Cluster) CanRemoveMember(from uint64, id uint64) bool {
 	members := c.Members()
 	members := c.Members()
-
-	nmembers := 0
 	nreachable := 0
 	nreachable := 0
 
 
 	for _, m := range members {
 	for _, m := range members {
-		// Skip the node that is going to be deleted
-		if m.RaftID == id {
-			continue
-		}
-
 		// Local node from where the remove is issued
 		// Local node from where the remove is issued
 		if m.RaftID == from {
 		if m.RaftID == from {
-			nmembers++
 			nreachable++
 			nreachable++
 			continue
 			continue
 		}
 		}
@@ -186,8 +178,6 @@ func (c *Cluster) CanRemoveMember(from uint64, id uint64) bool {
 		if err == nil && connState == grpc.Ready {
 		if err == nil && connState == grpc.Ready {
 			nreachable++
 			nreachable++
 		}
 		}
-
-		nmembers++
 	}
 	}
 
 
 	// Special case of 2 managers
 	// Special case of 2 managers
@@ -195,7 +185,7 @@ func (c *Cluster) CanRemoveMember(from uint64, id uint64) bool {
 		return false
 		return false
 	}
 	}
 
 
-	nquorum := nmembers/2 + 1
+	nquorum := (len(members)+1)/2 + 1
 	if nreachable < nquorum {
 	if nreachable < nquorum {
 		return false
 		return false
 	}
 	}

+ 33 - 6
vendor/src/github.com/docker/swarmkit/manager/state/raft/raft.go

@@ -94,6 +94,7 @@ type Node struct {
 	wal         *wal.WAL
 	wal         *wal.WAL
 	snapshotter *snap.Snapshotter
 	snapshotter *snap.Snapshotter
 	wasLeader   bool
 	wasLeader   bool
+	restored    bool
 	isMember    uint32
 	isMember    uint32
 	joinAddr    string
 	joinAddr    string
 
 
@@ -394,6 +395,18 @@ func (n *Node) Run(ctx context.Context) error {
 				}
 				}
 			}
 			}
 
 
+			// If we are the only registered member after
+			// restoring from the state, campaign to be the
+			// leader.
+			if !n.restored {
+				if len(n.cluster.Members()) <= 1 {
+					if err := n.Campaign(n.Ctx); err != nil {
+						panic("raft: cannot campaign to be the leader on node restore")
+					}
+				}
+				n.restored = true
+			}
+
 			// Advance the state machine
 			// Advance the state machine
 			n.Advance()
 			n.Advance()
 
 
@@ -638,7 +651,14 @@ func (n *Node) Leave(ctx context.Context, req *api.LeaveRequest) (*api.LeaveResp
 	return &api.LeaveResponse{}, nil
 	return &api.LeaveResponse{}, nil
 }
 }
 
 
-// RemoveMember submits a configuration change to remove a member from the raft cluster.
+// CanRemoveMember checks if a member can be removed from
+// the context of the current node.
+func (n *Node) CanRemoveMember(id uint64) bool {
+	return n.cluster.CanRemoveMember(n.Config.ID, id)
+}
+
+// RemoveMember submits a configuration change to remove a member from the raft cluster
+// after checking if the operation would not result in a loss of quorum.
 func (n *Node) RemoveMember(ctx context.Context, id uint64) error {
 func (n *Node) RemoveMember(ctx context.Context, id uint64) error {
 	n.membershipLock.Lock()
 	n.membershipLock.Lock()
 	defer n.membershipLock.Unlock()
 	defer n.membershipLock.Unlock()
@@ -828,6 +848,18 @@ func (n *Node) GetMemberlist() map[uint64]*api.RaftMember {
 	return memberlist
 	return memberlist
 }
 }
 
 
+// GetMemberByNodeID returns member information based
+// on its generic Node ID.
+func (n *Node) GetMemberByNodeID(nodeID string) *membership.Member {
+	members := n.cluster.Members()
+	for _, member := range members {
+		if member.NodeID == nodeID {
+			return member
+		}
+	}
+	return nil
+}
+
 // IsMember checks if the raft node has effectively joined
 // IsMember checks if the raft node has effectively joined
 // a cluster of existing members.
 // a cluster of existing members.
 func (n *Node) IsMember() bool {
 func (n *Node) IsMember() bool {
@@ -1172,11 +1204,6 @@ func (n *Node) applyRemoveNode(cc raftpb.ConfChange) (err error) {
 		}
 		}
 	}
 	}
 
 
-	// Do not unregister yourself
-	if n.Config.ID == cc.NodeID {
-		return nil
-	}
-
 	return n.cluster.RemoveMember(cc.NodeID)
 	return n.cluster.RemoveMember(cc.NodeID)
 }
 }
 
 

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

@@ -65,7 +65,6 @@ func (n *Node) loadAndStart(ctx context.Context, forceNewCluster bool) error {
 		return err
 		return err
 	}
 	}
 
 
-	n.Node = raft.RestartNode(n.Config)
 	return nil
 	return nil
 }
 }