TUN-2117: read group/system-name from CLI, send it to edge

This commit is contained in:
Nick Vollmar 2019-07-30 13:55:34 -05:00
parent 3c93d9b300
commit 74f3a55c57
9 changed files with 714 additions and 273 deletions

View File

@ -78,6 +78,6 @@ tunnelrpc/tunnelrpc.capnp.go: tunnelrpc/tunnelrpc.capnp
.PHONY: vet .PHONY: vet
vet: vet:
go vet -composites=false ./... go vet ./...
which go-sumtype # go get github.com/BurntSushi/go-sumtype which go-sumtype # go get github.com/BurntSushi/go-sumtype
go-sumtype $$(go list ./...) go-sumtype $$(go list ./...)

View File

@ -427,10 +427,22 @@ func startDeclarativeTunnel(ctx context.Context,
return err return err
} }
var scope pogs.Scope
if c.IsSet("group") == c.IsSet("system-name") {
err = fmt.Errorf("exactly one of --group or --system-name must be specified")
logger.WithError(err).Error("unable to determine scope")
return err
} else if c.IsSet("group") {
scope = pogs.NewGroup(c.String("group"))
} else {
scope = pogs.NewSystemName(c.String("system-name"))
}
cloudflaredConfig := &connection.CloudflaredConfig{ cloudflaredConfig := &connection.CloudflaredConfig{
CloudflaredID: cloudflaredID,
Tags: tags,
BuildInfo: buildInfo, BuildInfo: buildInfo,
CloudflaredID: cloudflaredID,
Scope: scope,
Tags: tags,
} }
serviceDiscoverer, err := serviceDiscoverer(c, logger) serviceDiscoverer, err := serviceDiscoverer(c, logger)
@ -838,6 +850,18 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
EnvVars: []string{"TUNNEL_USE_DECLARATIVE"}, EnvVars: []string{"TUNNEL_USE_DECLARATIVE"},
Hidden: true, Hidden: true,
}), }),
altsrc.NewStringFlag(&cli.StringFlag{
Name: "system-name",
Usage: "Unique identifier for this cloudflared instance. It can be configured individually in the Declarative Tunnel UI. Mutually exclusive with `--group`.",
EnvVars: []string{"TUNNEL_SYSTEM_NAME"},
Hidden: true,
}),
altsrc.NewStringFlag(&cli.StringFlag{
Name: "group",
Usage: "Name of a group of cloudflared instances, of which this instance should be an identical copy. They can be configured collectively in the Declarative Tunnel UI. Mutually exclusive with `--system-name`.",
EnvVars: []string{"TUNNEL_GROUP"},
Hidden: true,
}),
altsrc.NewDurationFlag(&cli.DurationFlag{ altsrc.NewDurationFlag(&cli.DurationFlag{
Name: "dial-edge-timeout", Name: "dial-edge-timeout",
Usage: "Maximum wait time to set up a connection with the edge", Usage: "Maximum wait time to set up a connection with the edge",

View File

@ -47,6 +47,7 @@ type CloudflaredConfig struct {
CloudflaredID uuid.UUID CloudflaredID uuid.UUID
Tags []pogs.Tag Tags []pogs.Tag
BuildInfo *buildinfo.BuildInfo BuildInfo *buildinfo.BuildInfo
Scope pogs.Scope
} }
func NewEdgeManager( func NewEdgeManager(
@ -120,32 +121,34 @@ func (em *EdgeManager) newConnection(ctx context.Context) error {
Logger: em.logger.WithField("subsystem", "muxer"), Logger: em.logger.WithField("subsystem", "muxer"),
}) })
if err != nil { if err != nil {
return errors.Wrap(err, "handshake with edge error") return errors.Wrap(err, "couldn't perform handshake with edge")
} }
h2muxConn, err := newConnection(muxer, edgeIP) h2muxConn, err := newConnection(muxer, edgeIP)
if err != nil { if err != nil {
return errors.Wrap(err, "create h2mux connection error") return errors.Wrap(err, "couldn't create h2mux connection")
} }
go em.serveConn(ctx, h2muxConn) go em.serveConn(ctx, h2muxConn)
connResult, err := h2muxConn.Connect(ctx, &pogs.ConnectParameters{ connResult, err := h2muxConn.Connect(ctx, &pogs.ConnectParameters{
OriginCert: em.state.getUserCredential(),
CloudflaredID: em.cloudflaredConfig.CloudflaredID, CloudflaredID: em.cloudflaredConfig.CloudflaredID,
NumPreviousAttempts: 0,
CloudflaredVersion: em.cloudflaredConfig.BuildInfo.CloudflaredVersion, CloudflaredVersion: em.cloudflaredConfig.BuildInfo.CloudflaredVersion,
NumPreviousAttempts: 0,
OriginCert: em.state.getUserCredential(),
Scope: em.cloudflaredConfig.Scope,
Tags: em.cloudflaredConfig.Tags,
}, em.logger) }, em.logger)
if err != nil { if err != nil {
h2muxConn.Shutdown() h2muxConn.Shutdown()
return errors.Wrap(err, "connect with edge error") return errors.Wrap(err, "couldn't connect to edge")
} }
if connErr := connResult.Err; connErr != nil { if connErr := connResult.Err; connErr != nil {
if !connErr.ShouldRetry { if !connErr.ShouldRetry {
return errors.Wrap(connErr, em.noRetryMessage()) return errors.Wrap(connErr, em.noRetryMessage())
} }
return errors.Wrapf(connErr, "server respond with retry at %v", connErr.RetryAfter) return errors.Wrapf(connErr, "edge responded with RetryAfter=%v", connErr.RetryAfter)
} }
em.state.newConnection(h2muxConn) em.state.newConnection(h2muxConn)

View File

@ -57,8 +57,8 @@ func NewSupervisor(
tunnelHostnames[i] = reverseProxyConfig.TunnelHostname tunnelHostnames[i] = reverseProxyConfig.TunnelHostname
} }
defaultEdgeMgrConfigurable := &connection.EdgeManagerConfigurable{ defaultEdgeMgrConfigurable := &connection.EdgeManagerConfigurable{
tunnelHostnames, TunnelHostnames: tunnelHostnames,
defaultClientConfig.EdgeConnectionConfig, EdgeConnectionConfig: defaultClientConfig.EdgeConnectionConfig,
} }
return &Supervisor{ return &Supervisor{
connManager: connection.NewEdgeManager(streamHandler, defaultEdgeMgrConfigurable, userCredential, tlsConfig, connManager: connection.NewEdgeManager(streamHandler, defaultEdgeMgrConfigurable, userCredential, tlsConfig,
@ -139,8 +139,8 @@ func (s *Supervisor) notifySubsystemsNewConfig(newConfig *pogs.ClientConfig) *po
} }
// Update connManager configurable // Update connManager configurable
s.connManager.UpdateConfigurable(&connection.EdgeManagerConfigurable{ s.connManager.UpdateConfigurable(&connection.EdgeManagerConfigurable{
tunnelHostnames, TunnelHostnames: tunnelHostnames,
newConfig.EdgeConnectionConfig, EdgeConnectionConfig: newConfig.EdgeConnectionConfig,
}) })
// Update streamHandler tunnelHostnameMapper mapping // Update streamHandler tunnelHostnameMapper mapping
failedConfigs := s.streamHandler.UpdateConfig(newConfig.ReverseProxyConfigs) failedConfigs := s.streamHandler.UpdateConfig(newConfig.ReverseProxyConfigs)

View File

@ -12,6 +12,15 @@ import (
capnp "zombiezen.com/go/capnproto2" capnp "zombiezen.com/go/capnproto2"
) )
// Assert *HTTPOriginConfig implements OriginConfig
var _ OriginConfig = (*HTTPOriginConfig)(nil)
// Assert *WebSocketOriginConfig implements OriginConfig
var _ OriginConfig = (*WebSocketOriginConfig)(nil)
// Assert *HelloWorldOriginConfig implements OriginConfig
var _ OriginConfig = (*HelloWorldOriginConfig)(nil)
func TestVersion(t *testing.T) { func TestVersion(t *testing.T) {
firstVersion := InitVersion() firstVersion := InitVersion()
secondVersion := Version(1) secondVersion := Version(1)
@ -35,7 +44,7 @@ func TestClientConfig(t *testing.T) {
c.Origin = sampleHTTPOriginConfig() c.Origin = sampleHTTPOriginConfig()
}), }),
sampleReverseProxyConfig(func(c *ReverseProxyConfig) { sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
c.Origin = sampleHTTPOriginUnixPathConfig() c.Origin = sampleHTTPOriginConfig(unixPathOverride)
}), }),
sampleReverseProxyConfig(func(c *ReverseProxyConfig) { sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
c.Origin = sampleWebSocketOriginConfig() c.Origin = sampleWebSocketOriginConfig()
@ -136,7 +145,7 @@ func TestReverseProxyConfig(t *testing.T) {
c.Origin = sampleHTTPOriginConfig() c.Origin = sampleHTTPOriginConfig()
}), }),
sampleReverseProxyConfig(func(c *ReverseProxyConfig) { sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
c.Origin = sampleHTTPOriginUnixPathConfig() c.Origin = sampleHTTPOriginConfig(unixPathOverride)
}), }),
sampleReverseProxyConfig(func(c *ReverseProxyConfig) { sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
c.Origin = sampleWebSocketOriginConfig() c.Origin = sampleWebSocketOriginConfig()
@ -224,7 +233,17 @@ func TestOriginConfigInvalidURL(t *testing.T) {
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Functions to generate sample data for ease of testing // Functions to generate sample data for ease of testing
//
// There's one "sample" function per struct type. Each goes like this:
// 1. Initialize an instance of the relevant struct.
// 2. Ensure the instance has no zero-valued fields. (This catches the
// error-case where a field was added, but we forgot to add code to
// marshal/unmarshal this field in CapnProto.)
// 3. Apply one or more "override" functions (which accept a
// pointer-to-struct, so they can mutate the instance).
// sampleClientConfig initializes a new ClientConfig literal,
// applies any number of overrides to it, and returns it.
func sampleClientConfig(overrides ...func(*ClientConfig)) *ClientConfig { func sampleClientConfig(overrides ...func(*ClientConfig)) *ClientConfig {
sample := &ClientConfig{ sample := &ClientConfig{
Version: Version(1337), Version: Version(1337),
@ -247,6 +266,8 @@ func sampleClientConfig(overrides ...func(*ClientConfig)) *ClientConfig {
return sample return sample
} }
// sampleDoHProxyConfig initializes a new DoHProxyConfig struct,
// applies any number of overrides to it, and returns it.
func sampleDoHProxyConfig(overrides ...func(*DoHProxyConfig)) *DoHProxyConfig { func sampleDoHProxyConfig(overrides ...func(*DoHProxyConfig)) *DoHProxyConfig {
sample := &DoHProxyConfig{ sample := &DoHProxyConfig{
ListenHost: "127.0.0.1", ListenHost: "127.0.0.1",
@ -260,6 +281,8 @@ func sampleDoHProxyConfig(overrides ...func(*DoHProxyConfig)) *DoHProxyConfig {
return sample return sample
} }
// sampleReverseProxyConfig initializes a new ReverseProxyConfig struct,
// applies any number of overrides to it, and returns it.
func sampleReverseProxyConfig(overrides ...func(*ReverseProxyConfig)) *ReverseProxyConfig { func sampleReverseProxyConfig(overrides ...func(*ReverseProxyConfig)) *ReverseProxyConfig {
sample := &ReverseProxyConfig{ sample := &ReverseProxyConfig{
TunnelHostname: "hijk.example.com", TunnelHostname: "hijk.example.com",
@ -275,9 +298,11 @@ func sampleReverseProxyConfig(overrides ...func(*ReverseProxyConfig)) *ReversePr
return sample return sample
} }
// sampleHTTPOriginConfig initializes a new HTTPOriginConfig literal,
// applies any number of overrides to it, and returns it.
func sampleHTTPOriginConfig(overrides ...func(*HTTPOriginConfig)) *HTTPOriginConfig { func sampleHTTPOriginConfig(overrides ...func(*HTTPOriginConfig)) *HTTPOriginConfig {
sample := &HTTPOriginConfig{ sample := &HTTPOriginConfig{
URLString: "https.example.com", URLString: "https://example.com",
TCPKeepAlive: 7 * time.Second, TCPKeepAlive: 7 * time.Second,
DialDualStack: true, DialDualStack: true,
TLSHandshakeTimeout: 11 * time.Second, TLSHandshakeTimeout: 11 * time.Second,
@ -297,28 +322,14 @@ func sampleHTTPOriginConfig(overrides ...func(*HTTPOriginConfig)) *HTTPOriginCon
return sample return sample
} }
func sampleHTTPOriginUnixPathConfig(overrides ...func(*HTTPOriginConfig)) *HTTPOriginConfig { // unixPathOverride sets the URLString of the given HTTPOriginConfig to be a
sample := &HTTPOriginConfig{ // Unix socket (i.e. `unix:` scheme plus a file path)
URLString: "unix:/var/lib/file.sock", func unixPathOverride(sample *HTTPOriginConfig) {
TCPKeepAlive: 7 * time.Second, sample.URLString = "unix:/var/lib/file.sock"
DialDualStack: true,
TLSHandshakeTimeout: 11 * time.Second,
TLSVerify: true,
OriginCAPool: "/etc/cert.pem",
OriginServerName: "secure.example.com",
MaxIdleConnections: 19,
IdleConnectionTimeout: 17 * time.Second,
ProxyConnectionTimeout: 15 * time.Second,
ExpectContinueTimeout: 21 * time.Second,
ChunkedEncoding: true,
}
sample.ensureNoZeroFields()
for _, f := range overrides {
f(sample)
}
return sample
} }
// sampleWebSocketOriginConfig initializes a new WebSocketOriginConfig
// struct, applies any number of overrides to it, and returns it.
func sampleWebSocketOriginConfig(overrides ...func(*WebSocketOriginConfig)) *WebSocketOriginConfig { func sampleWebSocketOriginConfig(overrides ...func(*WebSocketOriginConfig)) *WebSocketOriginConfig {
sample := &WebSocketOriginConfig{ sample := &WebSocketOriginConfig{
URLString: "ssh://example.com", URLString: "ssh://example.com",
@ -366,7 +377,6 @@ func (c *WebSocketOriginConfig) ensureNoZeroFields() {
// include a field in the sample value, it won't be covered under tests. // include a field in the sample value, it won't be covered under tests.
// This check reduces that risk by requiring fields to be either initialized // This check reduces that risk by requiring fields to be either initialized
// or explicitly uninitialized. // or explicitly uninitialized.
// https://bitbucket.cfdata.org/projects/TUN/repos/cloudflared/pull-requests/151/overview?commentId=348012
func ensureNoZeroFieldsInSample(ptrToSampleValue reflect.Value, allowedZeroFieldNames []string) { func ensureNoZeroFieldsInSample(ptrToSampleValue reflect.Value, allowedZeroFieldNames []string) {
sampleValue := ptrToSampleValue.Elem() sampleValue := ptrToSampleValue.Elem()
structType := ptrToSampleValue.Type().Elem() structType := ptrToSampleValue.Type().Elem()

View File

@ -2,6 +2,7 @@ package pogs
import ( import (
"context" "context"
"fmt"
"time" "time"
"github.com/cloudflare/cloudflared/tunnelrpc" "github.com/cloudflare/cloudflared/tunnelrpc"
@ -127,52 +128,169 @@ func UnmarshalServerInfo(s tunnelrpc.ServerInfo) (*ServerInfo, error) {
return p, err return p, err
} }
//go-sumtype:decl Scope
type Scope interface {
Value() string
isScope()
}
type SystemName struct {
systemName string
}
func NewSystemName(systemName string) *SystemName {
return &SystemName{systemName: systemName}
}
func (s *SystemName) Value() string { return s.systemName }
func (_ *SystemName) isScope() {}
type Group struct {
group string
}
func NewGroup(group string) *Group {
return &Group{group: group}
}
func (g *Group) Value() string { return g.group }
func (_ *Group) isScope() {}
func MarshalScope(s tunnelrpc.Scope, p Scope) error {
ss := s.Value()
switch scope := p.(type) {
case *SystemName:
ss.SetSystemName(scope.systemName)
case *Group:
ss.SetGroup(scope.group)
default:
return fmt.Errorf("unexpected Scope value: %v", p)
}
return nil
}
func UnmarshalScope(s tunnelrpc.Scope) (Scope, error) {
ss := s.Value()
switch ss.Which() {
case tunnelrpc.Scope_value_Which_systemName:
systemName, err := ss.SystemName()
if err != nil {
return nil, err
}
return NewSystemName(systemName), nil
case tunnelrpc.Scope_value_Which_group:
group, err := ss.Group()
if err != nil {
return nil, err
}
return NewGroup(group), nil
default:
return nil, fmt.Errorf("unexpected Scope tag: %v", ss.Which())
}
}
type ConnectParameters struct { type ConnectParameters struct {
OriginCert []byte OriginCert []byte
CloudflaredID uuid.UUID CloudflaredID uuid.UUID
NumPreviousAttempts uint8 NumPreviousAttempts uint8
Tags []Tag Tags []Tag
CloudflaredVersion string CloudflaredVersion string
} Scope Scope
// CapnpConnectParameters is ConnectParameters represented in Cap'n Proto build-in types
type CapnpConnectParameters struct {
OriginCert []byte
CloudflaredID []byte
NumPreviousAttempts uint8
Tags []Tag
CloudflaredVersion string
} }
func MarshalConnectParameters(s tunnelrpc.CapnpConnectParameters, p *ConnectParameters) error { func MarshalConnectParameters(s tunnelrpc.CapnpConnectParameters, p *ConnectParameters) error {
if err := s.SetOriginCert(p.OriginCert); err != nil {
return err
}
cloudflaredIDBytes, err := p.CloudflaredID.MarshalBinary() cloudflaredIDBytes, err := p.CloudflaredID.MarshalBinary()
if err != nil { if err != nil {
return err return err
} }
capnpConnectParameters := &CapnpConnectParameters{ if err := s.SetCloudflaredID(cloudflaredIDBytes); err != nil {
OriginCert: p.OriginCert, return err
CloudflaredID: cloudflaredIDBytes,
NumPreviousAttempts: p.NumPreviousAttempts,
CloudflaredVersion: p.CloudflaredVersion,
} }
return pogs.Insert(tunnelrpc.CapnpConnectParameters_TypeID, s.Struct, capnpConnectParameters) s.SetNumPreviousAttempts(p.NumPreviousAttempts)
if len(p.Tags) > 0 {
tagsCapnpList, err := s.NewTags(int32(len(p.Tags)))
if err != nil {
return err
}
for i, tag := range p.Tags {
tagCapnp := tagsCapnpList.At(i)
if err := tagCapnp.SetName(tag.Name); err != nil {
return err
}
if err := tagCapnp.SetValue(tag.Value); err != nil {
return err
}
}
}
if err := s.SetCloudflaredVersion(p.CloudflaredVersion); err != nil {
return err
}
scope, err := s.NewScope()
if err != nil {
return err
}
return MarshalScope(scope, p.Scope)
} }
func UnmarshalConnectParameters(s tunnelrpc.CapnpConnectParameters) (*ConnectParameters, error) { func UnmarshalConnectParameters(s tunnelrpc.CapnpConnectParameters) (*ConnectParameters, error) {
p := new(CapnpConnectParameters) originCert, err := s.OriginCert()
err := pogs.Extract(p, tunnelrpc.CapnpConnectParameters_TypeID, s.Struct)
if err != nil { if err != nil {
return nil, err return nil, err
} }
cloudflaredID, err := uuid.FromBytes(p.CloudflaredID)
cloudflaredIDBytes, err := s.CloudflaredID()
if err != nil { if err != nil {
return nil, err return nil, err
} }
cloudflaredID, err := uuid.FromBytes(cloudflaredIDBytes)
if err != nil {
return nil, err
}
tagsCapnpList, err := s.Tags()
if err != nil {
return nil, err
}
var tags []Tag
for i := 0; i < tagsCapnpList.Len(); i++ {
tagCapnp := tagsCapnpList.At(i)
name, err := tagCapnp.Name()
if err != nil {
return nil, err
}
value, err := tagCapnp.Value()
if err != nil {
return nil, err
}
tags = append(tags, Tag{Name: name, Value: value})
}
cloudflaredVersion, err := s.CloudflaredVersion()
if err != nil {
return nil, err
}
scopeCapnp, err := s.Scope()
if err != nil {
return nil, err
}
scope, err := UnmarshalScope(scopeCapnp)
if err != nil {
return nil, err
}
return &ConnectParameters{ return &ConnectParameters{
OriginCert: p.OriginCert, OriginCert: originCert,
CloudflaredID: cloudflaredID, CloudflaredID: cloudflaredID,
NumPreviousAttempts: p.NumPreviousAttempts, NumPreviousAttempts: s.NumPreviousAttempts(),
CloudflaredVersion: p.CloudflaredVersion, Tags: tags,
CloudflaredVersion: cloudflaredVersion,
Scope: scope,
}, nil }, nil
} }

View File

@ -0,0 +1,97 @@
package pogs
import (
"reflect"
"testing"
"github.com/cloudflare/cloudflared/tunnelrpc"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
capnp "zombiezen.com/go/capnproto2"
)
// Assert *SystemName implements Scope
var _ Scope = (*SystemName)(nil)
// Assert *Group implements Scope
var _ Scope = (*Group)(nil)
func TestScope(t *testing.T) {
testCases := []Scope{
&SystemName{systemName: "my_system"},
&Group{group: "my_group"},
}
for i, testCase := range testCases {
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
capnpEntity, err := tunnelrpc.NewScope(seg)
if !assert.NoError(t, err) {
t.Fatal("Couldn't initialize a new message")
}
err = MarshalScope(capnpEntity, testCase)
if !assert.NoError(t, err, "testCase index %v failed to marshal", i) {
continue
}
result, err := UnmarshalScope(capnpEntity)
if !assert.NoError(t, err, "testCase index %v failed to unmarshal", i) {
continue
}
assert.Equal(t, testCase, result, "testCase index %v didn't preserve struct through marshalling and unmarshalling", i)
}
}
func TestConnectParameters(t *testing.T) {
testCases := []*ConnectParameters{
sampleConnectParameters(),
sampleConnectParameters(func(c *ConnectParameters) {
c.Scope = &SystemName{systemName: "my_system"}
}),
sampleConnectParameters(func(c *ConnectParameters) {
c.Tags = nil
}),
}
for i, testCase := range testCases {
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
capnpEntity, err := tunnelrpc.NewCapnpConnectParameters(seg)
if !assert.NoError(t, err) {
t.Fatal("Couldn't initialize a new message")
}
err = MarshalConnectParameters(capnpEntity, testCase)
if !assert.NoError(t, err, "testCase index %v failed to marshal", i) {
continue
}
result, err := UnmarshalConnectParameters(capnpEntity)
if !assert.NoError(t, err, "testCase index %v failed to unmarshal", i) {
continue
}
assert.Equal(t, testCase, result, "testCase index %v didn't preserve struct through marshalling and unmarshalling", i)
}
}
func sampleConnectParameters(overrides ...func(*ConnectParameters)) *ConnectParameters {
cloudflaredID, err := uuid.Parse("ED7BA470-8E54-465E-825C-99712043E01C")
if err != nil {
panic(err)
}
sample := &ConnectParameters{
OriginCert: []byte("my-origin-cert"),
CloudflaredID: cloudflaredID,
NumPreviousAttempts: 19,
Tags: []Tag{
Tag{
Name: "provision-method",
Value: "new",
},
},
CloudflaredVersion: "7.0",
Scope: &Group{group: "my_group"},
}
sample.ensureNoZeroFields()
for _, f := range overrides {
f(sample)
}
return sample
}
func (c *ConnectParameters) ensureNoZeroFields() {
ensureNoZeroFieldsInSample(reflect.ValueOf(c), []string{})
}

View File

@ -57,6 +57,17 @@ struct CapnpConnectParameters {
tags @3 :List(Tag); tags @3 :List(Tag);
# release version of cloudflared # release version of cloudflared
cloudflaredVersion @4 :Text; cloudflaredVersion @4 :Text;
# identifier for this cloudflared instance
scope @5 :Scope;
}
struct Scope {
value :union {
# Standalone instance
systemName @0 :Text;
# Associated with a group of identical cloudflared instances
group @1 :Text;
}
} }
struct ConnectResult { struct ConnectResult {

View File

@ -504,12 +504,12 @@ type CapnpConnectParameters struct{ capnp.Struct }
const CapnpConnectParameters_TypeID = 0xa78f37418c1077c8 const CapnpConnectParameters_TypeID = 0xa78f37418c1077c8
func NewCapnpConnectParameters(s *capnp.Segment) (CapnpConnectParameters, error) { func NewCapnpConnectParameters(s *capnp.Segment) (CapnpConnectParameters, error) {
st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 4}) st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 5})
return CapnpConnectParameters{st}, err return CapnpConnectParameters{st}, err
} }
func NewRootCapnpConnectParameters(s *capnp.Segment) (CapnpConnectParameters, error) { func NewRootCapnpConnectParameters(s *capnp.Segment) (CapnpConnectParameters, error) {
st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 4}) st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 5})
return CapnpConnectParameters{st}, err return CapnpConnectParameters{st}, err
} }
@ -603,12 +603,37 @@ func (s CapnpConnectParameters) SetCloudflaredVersion(v string) error {
return s.Struct.SetText(3, v) return s.Struct.SetText(3, v)
} }
func (s CapnpConnectParameters) Scope() (Scope, error) {
p, err := s.Struct.Ptr(4)
return Scope{Struct: p.Struct()}, err
}
func (s CapnpConnectParameters) HasScope() bool {
p, err := s.Struct.Ptr(4)
return p.IsValid() || err != nil
}
func (s CapnpConnectParameters) SetScope(v Scope) error {
return s.Struct.SetPtr(4, v.Struct.ToPtr())
}
// NewScope sets the scope field to a newly
// allocated Scope struct, preferring placement in s's segment.
func (s CapnpConnectParameters) NewScope() (Scope, error) {
ss, err := NewScope(s.Struct.Segment())
if err != nil {
return Scope{}, err
}
err = s.Struct.SetPtr(4, ss.Struct.ToPtr())
return ss, err
}
// CapnpConnectParameters_List is a list of CapnpConnectParameters. // CapnpConnectParameters_List is a list of CapnpConnectParameters.
type CapnpConnectParameters_List struct{ capnp.List } type CapnpConnectParameters_List struct{ capnp.List }
// NewCapnpConnectParameters creates a new list of CapnpConnectParameters. // NewCapnpConnectParameters creates a new list of CapnpConnectParameters.
func NewCapnpConnectParameters_List(s *capnp.Segment, sz int32) (CapnpConnectParameters_List, error) { func NewCapnpConnectParameters_List(s *capnp.Segment, sz int32) (CapnpConnectParameters_List, error) {
l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 4}, sz) l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 5}, sz)
return CapnpConnectParameters_List{l}, err return CapnpConnectParameters_List{l}, err
} }
@ -633,6 +658,147 @@ func (p CapnpConnectParameters_Promise) Struct() (CapnpConnectParameters, error)
return CapnpConnectParameters{s}, err return CapnpConnectParameters{s}, err
} }
func (p CapnpConnectParameters_Promise) Scope() Scope_Promise {
return Scope_Promise{Pipeline: p.Pipeline.GetPipeline(4)}
}
type Scope struct{ capnp.Struct }
type Scope_value Scope
type Scope_value_Which uint16
const (
Scope_value_Which_systemName Scope_value_Which = 0
Scope_value_Which_group Scope_value_Which = 1
)
func (w Scope_value_Which) String() string {
const s = "systemNamegroup"
switch w {
case Scope_value_Which_systemName:
return s[0:10]
case Scope_value_Which_group:
return s[10:15]
}
return "Scope_value_Which(" + strconv.FormatUint(uint64(w), 10) + ")"
}
// Scope_TypeID is the unique identifier for the type Scope.
const Scope_TypeID = 0xc54a4a6fd4d87596
func NewScope(s *capnp.Segment) (Scope, error) {
st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
return Scope{st}, err
}
func NewRootScope(s *capnp.Segment) (Scope, error) {
st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
return Scope{st}, err
}
func ReadRootScope(msg *capnp.Message) (Scope, error) {
root, err := msg.RootPtr()
return Scope{root.Struct()}, err
}
func (s Scope) String() string {
str, _ := text.Marshal(0xc54a4a6fd4d87596, s.Struct)
return str
}
func (s Scope) Value() Scope_value { return Scope_value(s) }
func (s Scope_value) Which() Scope_value_Which {
return Scope_value_Which(s.Struct.Uint16(0))
}
func (s Scope_value) SystemName() (string, error) {
if s.Struct.Uint16(0) != 0 {
panic("Which() != systemName")
}
p, err := s.Struct.Ptr(0)
return p.Text(), err
}
func (s Scope_value) HasSystemName() bool {
if s.Struct.Uint16(0) != 0 {
return false
}
p, err := s.Struct.Ptr(0)
return p.IsValid() || err != nil
}
func (s Scope_value) SystemNameBytes() ([]byte, error) {
p, err := s.Struct.Ptr(0)
return p.TextBytes(), err
}
func (s Scope_value) SetSystemName(v string) error {
s.Struct.SetUint16(0, 0)
return s.Struct.SetText(0, v)
}
func (s Scope_value) Group() (string, error) {
if s.Struct.Uint16(0) != 1 {
panic("Which() != group")
}
p, err := s.Struct.Ptr(0)
return p.Text(), err
}
func (s Scope_value) HasGroup() bool {
if s.Struct.Uint16(0) != 1 {
return false
}
p, err := s.Struct.Ptr(0)
return p.IsValid() || err != nil
}
func (s Scope_value) GroupBytes() ([]byte, error) {
p, err := s.Struct.Ptr(0)
return p.TextBytes(), err
}
func (s Scope_value) SetGroup(v string) error {
s.Struct.SetUint16(0, 1)
return s.Struct.SetText(0, v)
}
// Scope_List is a list of Scope.
type Scope_List struct{ capnp.List }
// NewScope creates a new list of Scope.
func NewScope_List(s *capnp.Segment, sz int32) (Scope_List, error) {
l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz)
return Scope_List{l}, err
}
func (s Scope_List) At(i int) Scope { return Scope{s.List.Struct(i)} }
func (s Scope_List) Set(i int, v Scope) error { return s.List.SetStruct(i, v.Struct) }
func (s Scope_List) String() string {
str, _ := text.MarshalList(0xc54a4a6fd4d87596, s.List)
return str
}
// Scope_Promise is a wrapper for a Scope promised by a client call.
type Scope_Promise struct{ *capnp.Pipeline }
func (p Scope_Promise) Struct() (Scope, error) {
s, err := p.Pipeline.Struct()
return Scope{s}, err
}
func (p Scope_Promise) Value() Scope_value_Promise { return Scope_value_Promise{p.Pipeline} }
// Scope_value_Promise is a wrapper for a Scope_value promised by a client call.
type Scope_value_Promise struct{ *capnp.Pipeline }
func (p Scope_value_Promise) Struct() (Scope_value, error) {
s, err := p.Pipeline.Struct()
return Scope_value{s}, err
}
type ConnectResult struct{ capnp.Struct } type ConnectResult struct{ capnp.Struct }
// ConnectResult_TypeID is the unique identifier for the type ConnectResult. // ConnectResult_TypeID is the unique identifier for the type ConnectResult.
@ -3509,218 +3675,228 @@ func (p ClientService_useConfiguration_Results_Promise) Result() UseConfiguratio
return UseConfigurationResult_Promise{Pipeline: p.Pipeline.GetPipeline(0)} return UseConfigurationResult_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
} }
const schema_db8274f9144abc7e = "x\xda\xacY}\x8c\x1c\xe5y\x7f\x9ey\xf7v|\xe6" + const schema_db8274f9144abc7e = "x\xda\xacY}l\x1cez\x7f\x9ey\xd7\x1e;\xf1" +
"\xce{\xe3\xb9\x80}\xd8\xba\xd6\x02%\x10Lq\\Z" + "f=\xcc\"b\x13\xcb\xa7\x08t\x17\x8e\xa4\x107-" +
"\xb8\xb6Y\xdf\x9d\xcf\xb9\xbd\xf8c\xe7\xf6\xce\x80\xb1%" + "q\xdb\xdb\xd8Nr\xb6/\x1f;\xfe\x08\x10\x12)\x93" +
"\x8fw\xdf\xdb\x1b{vf=\x1f\xf6\x9d\xe5\xc4`\xd9" + "\xdd\xd7\xebIfg6\xf3\x91\xd8Q\xee\x02i(\xe0" +
"\x05\xae\x10l\x82%\xec\x90\x08\xdc\xba|\x08\x1aC@" + "\x92#\xe1.\x15\xc9\x85\x13\xa4\x97\xf2\xa1\\K\xb8\xa0" +
"\x15\xd4\xa4\xa1jK\xda\xa8\"U\x93\xaai\xf3O\x03" + "\xf6(\x9c\x8e\xaa\x14\xd2;\x09P\xa1\x82\x96\xfe\xd1\x83" +
"VU\xd4\x88\x9a\xa4B\xa9\x80\xa9\x9ew>oo9" + "\xa8\x025\xa2p'!N\x17\xa6z\xe6\xdb\xeb\xc5!" +
"\xdbU\xf8\x03\x8f\x9e}\xde\xf7}>\x7f\xcf\xc7\xddv" + "U\xffIV\xcf<\xef\xfb>\x9f\xbf\xe7\xc3\xb7\\n" +
"n\xc9\x06i]\xc7_v\x01h\x8fw\xe4\x83\xdfo" + "Y#\xdc\xdadf\x01\x94SM\xcd\xde\x1fW_;" +
"\xbc}\xf6wN\xfd\xe0\x18(}R\xf0\xd5\x0bc\xbd" + "\xfd\x07\xc7\x7fq\x18\xa4N\xc1\xfb\xce\x0b\xc3\xf9\xcf\x9c" +
"\xbf\xf2\x8e\xfe\x1b\x00\xae\x1f\xc9\x1fB\xf5\x9e\xbc\x0c\xa0" + "C\xff\x0e\x80=\x8f6\xefG\xf9\\\xb3\x08 \xff\xb8" +
"N\xe6\xb7\x01\x06\xfft\xdb\xe1ww\xff\xe2\xe4\x83\xa0" + "y3\xa0\xf7/\xb7\x1cx\x7f\xc7\xaf\x8f\xdd\x0fR'" +
"\xf4a\xca\x99\x93\x01\xd67\xf2s\xa8\x1e\xcf\xcb\xc0\x82" + "&\x9c\x19\x11\xa0\xe7\xe5\xe6\x19\x94\xff\xa3Y\x04\xe6=" +
"o\xde\xdb\xfb\xf7\xf8\xd4\x87'A\xf9\x1c\x02t \xfd" + "zW\xfe\x9f\xf1\xb1O\x8f\x81\xf45\x04hB\xfa\xfc" +
"\xac\xe7\x97J\x80\xeal\xbe\x08\x18\xbc}\xcb\x85\xd7O" + "\xd3\xe6\x05\x02\xa0\xfcFs\x01\xd0{\xed\xe6\x17\x9e?" +
"|\xe7\x81o\x80\xf6YD\x08\xcf\x9f\xce\xff/\x02\xaa" + "\xfa\x93\xfb~\x00\xcaW\x11!8\xffq\xf3o\x11P" +
"/\x0a\x86K\x7f\xf2\xf9\xdc\x8bo/\xff\x96`\x08\xce" + "n\x12\x89\xe1\xe3\x1f}=\xf3\xe3\xd7\xae\xf9\xa1\xcf\xe0" +
"\xfd\xe3]/\x9f\xf8\xceo\xbc\x07\x93\x92\x8c9\x80\xf5" + "\x9dy\xe3\xf6g\x8f\xfe\xe4+\x1f\xc2\xb8 b\x06\xa0" +
"?\xce;\xc4\xfb\xef\xf9\xff\x00\x0c\x1e\xff\x977\xb66" + "g\xb9h\x11\xefj\xf1\xbf\x00\xbd\xef\xbf\xfd\xe2\xa6\xea" +
"N\x9e9\x0b\xcag\xe3\xbb\xde\x94%\x09r\xc1\xed\xff" + "\xb1\x93\xa7A\xfajtWG\x8b @\xc6[\xf5o" +
"zq\xdb\x96\x97\xa7\x9e\x09\x7f\x09\xe5xU~\x99\x8e" + "\x177o|v\xe2\x89\xe0K G\xb6\xe5Y:\xda" +
"\xfe\x8dL\xcf|\xff`\xcf\xc3\x83\xbf\xfb\xe83\xa0\xf5" + "\xd5B\xcf\xbc\xba\xaf\xfd\xc1\xbe?|\xe8\x09P:1" +
"aF\x9f\x0eq\xc9\x7f\xcas\xa8\xe2\x12\xfa\xfcX\xee" + "\xa5OS\x13q\xf6\xb5\xcc\xa0|g\x0b\xfd\x1co\xb9" +
"G\xc0`\xee\xce7\xb6\xff\xe2\x0f\xdd\xe7A[\x8b\xb9" + "\x1d\x01\xbd\x99\xd5/n\xf9\xf5\x9f\xd9O\x83\xb2\x1c3" +
"\xe0\xaf\x1fz\xe7\xc0M\xcfM\xbd%\xa4b\x00\xebo" + "\xde?>\xf0\xde\xdeeOM\xbc\xe2K\xc5\x00z." +
"\xef<KW\x8ft~\x1b0\xe8\xfe\x8b\x9b\xb7>\xfa" + "\xb4\x9e\xa6\xab\xdfi\xfd\x1b@/\xfb\xf77mz\xe8" +
"\xee\xe6\x97\xe8\xea\x8cQC!.v\x0e\xa0\xfa?\x9d" + "\xfd\x0d\xe7\xe8\xea\x94Q\x03!\xa6\x17\xf4\xa2\xfc\xc0\x02" +
"d\xd7K\x82\xfb\x87\xb7l\xff\xeew\xcf\xd7_j\x15" + "\xb2\xeb\xbd\x0b\x88\xfb\xf5\x9b\xb7\xfc\xecg\xcfT\xce\xd5" +
"D\"\xee\x93K\xc7P=\xb7\x94\xb8\x9f^J\xdc\x9f" + "\x0b\"\x10\xf7\x8d\x0b\x87Q^\xbd\x90\xb8W-$\xee" +
")\xe1O\xbf\xb7.\xf7\xe7\x91^\x8c\x98&\xafy\x8f" + "k\x87\xf0\xdd\x9f\xdf\x9a\xf9\xdbP/FL\x1f,\xfc" +
"\x1e7\xae!\x86{?z\xf5\xafF\xde\xff\xd1kY" + "\x90\x1e\xbf\xec3\xdc\xf5\xbb\xe7\xfea\xddGo\xfe4" +
"\x07tvI\xe4\x80\xd5]\xa4\xf8\xea\x9f\x0fu[\xef" + "\xed\x80G\xdb\x04r\xc0\xb96R\xbc\xebR\x7f\xd6\xf8" +
"\x1f\xfd\xde|?\x867\x8dt\x8d\xa1zO\x97pz" + "\xe8\xd0\xcfg\xfb1\xb8\xe9\x9d\xb6a\x94/\xb5\xd1s" +
"\xd7\xb7\x01?|\xfe\x81\x13\xa5w6\xbe\xa5\xf5a\xae" + "\x1f\xb4\xd1m\x7f\xe1\xbe\xfd\xa69<\xfcr\xbdp\xfe" +
"U\x91K]\x87P\xed\xe8\xa6O\xec\x166J\xac\xd2" + "\xb5\xf7f\x05\x94\x8fe\x89\xfbH\xb6\x00\xf8\xe9\xd3\xf7" +
"\xc2.4Y\xb7l/\xaa#\xcb\xe8sp\x99`\x1f" + "\x1d\x1dzo\xed+J'f\xeay\x8fe\xf7\xa3|" +
"\xbb\xf7\xeb\x8fu\\\xfc\xfa[\xadf\x92\x89\xa7Tp" + "\x86x{\x1e\xcfv\x93Ec\x1b\xd6\xb1\xfbz\xbf\xb1" +
"P\xddU\xa0\xcf{\x0a\xcfH\x80A\xdf\xf9\xdf\xfb\xb3" + "h\x17\xca\x17\x17\xd1\xcf\xff\\\xe4\xb3\x0f\xdf\xf5\xbd\x87" +
"\xa1\xdaO~\xd0\"7]\xae\x8e,\xff@\xd5\x96\xd3" + "\x9b.~\xef\x95z\xa3\x8a\xbe\x05r\x16\xca\x97s\xf4" +
"\xd7\x96\xe5\x07\x01\x83\x07>?{h\xeb\x8ds?n" + "\xf3\xb3\xdc\x13\x02\xa0\xf7\xdb\xb3\x7f\xca/\xaex\xf5\x02" +
"\xb5\xa9\x10\xfc\xb9\xe5s\xa8\xbe)\xb8\xdf\x10\xdc\xd2E" + "(_\xc1\x94\x1a\xe3(\xa2\x00\xd0s\xf1\x9a\x95d\xb2" +
"}\xe5}\xff\xfc\xc5\x9ff\xa2h\xad\xfa3\x84\\\xb0" + "K\xd7\xec\x03\xf4:\x9f\xf9\xa3\xbf\xee/\xbf\xf3\x8b:" +
"u\xfb\xbd{;\xbf\xf2\xce;\xd9(\xfaMUX\xfb" + "\x8b\x90 \xf2F\xf9\x13\xf9N\x99~\x8d\xcb\xc4{\xdf" +
"v\x95\x8c\xf9\x8a\xf2\x98z\xe1\xe9?}\x97\x1e\x92[" + "\xd7\xa7\xf7o\xbaq\xe6\xad\x86\x069'\xcf\xa0|\xc1" +
"\xad9\xa9\xee@\xd5P\xe9\x93\xabB\x87$\x9a\xdb\xf9" + "\xe7~\xd9\xe7\x16.\xaa\x1dw\xff\xeb7\xdeM\xc5\xe7" +
"Z\xbfv\x00\xd5\xfd\xd7\x92\\\x8dkI\xae\xdbw\x0f" + "\xaa\xfc\xaf\x102\xde\xa6-w\xedj\xfd\xf6{\xef\xa5" +
"\xf2\x9dw\xdc\xfd\x1e(}l^n\xbeH\x9co\x10" + "\xe3sY\xde\xf7\xe3\x9f\xe4\xc9M\xe7\xa5\x87\xe5\x17\x1e" +
"\xe7\xfa\xd7\xae\x95Q5\xae\x93\x01\x82\xaf\xd5w\xfc\xdd" + "\xff\xab\xf7\xe9!\xb1\xdeO\xdb\xf3[Q\xde\x93\xa7\x9f" +
"\xa5\xe1\xa7\xff\xbbmDk\xd7\x0d\xa0\xaa\x13\xdf\xfa]" + "\xd5\xbc\xafo\x9c'\x8d\xa2H\xbb\xae\x17\xe5\xe9\xebH" +
"\xd7\x09\xf3\xaf_\xf7G??\xf5\xc7\xc3\x97\x16\xdc\xfe" + ".\xf7:\x92k\xd5\x8e>\xbe\xed\xb6;>\x04\xa9\x93" +
"\xdc\x8a!T_[Ar\xbc\xba\xe2K\xea\xc5\x15\xe2" + "\xcd\xca\xfa\xe7\x88\xf3e\xe2\xecy\xe9:\x11\xe5=\x8b" +
"\xf2\xafn\xdcv\xe7\x9a7?\xc8Z\xe2\x1fV| " + "E\x00\xef\xbb\x95\xad\x17>\x1ex\xfc\x7f\xea/\xf7\x15" +
"Rq\x05Yb\xea\x8e\xff\xfa\xd2\x8d_\xfb\xdb\x0fZ" + "\xbasq/\xca\x1a\xf1\xf5\xf0\xc5\xbe\xabzn\xfd\xf3" +
"\xdc#\x18q\xe5\xcd\xa8*+\xe9\xc6\xee\x95E\xc0\xf7" + "K\xc7\xffr\xe0\xe39\xb7\x9f\xeb\xe8G\xf9\xa5\x0e\x92" +
"7}\xebG}\x85\xbe_\xb6\x13t\xddJ\x8a\x93\x95" + "\xe3\xc5\x8eo\xca\x97:\xfc\xcb\xbf\xb3v\xf3\xea\xa5/" +
"\"NV\x0aA\xef\xfe\xd9\x99\x83\xc5o\xfc\xf2C\xd2" + "}\x92\xb6\xc4[\x1d\x9f\x90%>\xe8 KL\xdc\xf6" +
"\x8b\xb5 \xcf\xfe\xbe\x1d\xa8\x1e\xef\xa3\x9b\xef\xef\xa3\xf0" + "\xdf\xdf\xbc\xf1\xbb\xff\xf4I\x9d{|\xc6\xd6\xce\x9bP" +
"\xdf\xfc\xc2O\xbe8}\xea\xfb\xbfj5\x82p\xc8\xda" + "\xee\xe8\xa4\x1b\xaf\xed,\x00~\xb4\xfe\x87ov\xe6:" +
"\xeb\x8f\xa2:x=q\xff\xc1\xf5\x84\x1f\x87\xdf?=" + "\x7f\xd3H\xd0\xd5\x9d\xbbP\xdeH\xbc=C\x9d\xbe\xa0" +
"\xfa\xe8\xce\x17>\xc9ju\xe3\xaa\xd7\x85\x7fW\x91V" + "w\xfc\xea\xe4\xbe\xc2\x0f~\xf3)\xe9\xc5\xea0m\xfa" +
"{O\x1d\xf6F\x9fx$h\x13t\xeb'W\x0d\xa1" + "\xfa\xad(\x1f\xb9\x9en~\xe0zJ\x85\x0dg\xdf\xf9" +
"\xcaW\xd1m\xfa\xaa\x83\xb06\xf0|\xcb\xe2\xa6\xd3\xcc" + "\xc6\xe4\xf1W?\xab7\x82\xef\x90UK\x0e\xa1<\xb4" +
"U\x7f+\xfe\xac\xdeZ\xd5\x9bVs`d\xc6p=" + "\x84\xb8\xd7-!d:\xf0\xd1\x89\xc1\x87\xb6\x9d\xfd<" +
"\xc3\xaaO\x08z\xb1l\x9bFu\xb6\x8c\xa8u\xa1\x04" + "\xad\xd5\xf2\xae\xe7}\xffv\x91V\xbb\x8e\x1fp\x06\x1f" +
"\xa0\xac\x1e\x00@T>\xb3\x03\x00%E\x19\x02(\x1a" + "9\xe25\x08\xba\x9e\xed]\xfd(W\xbb\xe86\xadk" +
"u\xcbvxP3\xdc\xaamY\x1cX\xd5;\xb2G" + "\x1f,\xf7\x1c\xd70\xb8n\xd52\xa5\xdf\x8b~\x96V" +
"7u\xab\xca\x93\x87:\x16>4\xcaM\xd3\xbe\xcbv" + "\x94\xd4\x9aQ\xeb]7\xa5\xd9\x8efT\xc6|z\xa1" +
"\xcc\xda6\xc7\xa8\x1b\xd6\xb0mM\x19u\x802br" + "h\xeaZi\xba\x88\xa8\xb4Q\xa0K]\xbd\x00\x88\xd2" +
"L^xl\xd84\xb8\xe5U\xb8s\xc0\xa8\xf2[}" + "\xb5[\x01P\x90\xa4~\x80\x82V1L\x8b{e\xcd" +
"\x97\x87\xe7|G\xf7\x0c\xdb\xbaa\x9c\xbb\xbe\xe9\xb9\x00" + ".\x99\x86\xc1\x81\x95\x9c\x83;U]5J<~\xa8" +
"Z\x8e\xe5\x00r\x08\xa0t\x0f\x00hK\x18j\xbd\x12" + "i\xeeC\x83\\\xd7\xcd\xdbMK/o\xb6\xb4\x8af" +
"\x16\x1d\xc1\x80=i\xe6\x01b\x0f\xa4o\xe6\x17\xbe\x19" + "\x0c\x98\xc6\x84V\x01(\"\xc6\xc7\xc4\xb9\xc7\x06t\x8d" +
"\xda\x82\xde\xe4\xce\xad\xbe\xe5\xf0\xba\xe1z\xdc\x09\xc97" + "\x1b\xce(\xb7\xf6j%\xbe\xc2\xb5yp\xce\xb5TG" +
"\x14\xcb\xba\xa37\xdc\xec\x83g\x00\xb4\x1e\x86\xda*\x09" + "3\x8d\x1bF\xb8\xed\xea\x8e\x0d\xa0dX\x06 \x83\x00" +
"\x83\xba\xa3Wy\x99;h\xd8\xb5\xad\xbaeW\x18\xaf" + "R\xb6\x17@ia\xa8\xe4\x05,X>\x03\xb6'\x99" +
"b\x07H\xd8\x91y\xb4\x8d#6\xe9\x86\xc9k\xa1v" + "\x07\x88\xed\x90\xbc\xd9<\xf7\xcd\xc0\x16\xf4&\xb7V\xb8" +
"\xb7V\xfb\xc5\xbfZ\x0f\xcbu\x05\x81xD\xdf\x01\xa0" + "\x86\xc5+\x9a\xedp+ \xdfP(\xaa\x96Z\xb5\xd3" +
"\xedf\xa8\x99\x12v\xe3'A/\x15)\xc58\x04\xa0" + "\x0f\x9e\x04P\xda\x19*K\x04\xf4*\x96Z\xe2En" +
"M3\xd4<\x09\xbb\xa5\x8f\x83^\xe1\xb5\xfdk\x004" + "\xa1f\x967\xa9\x869\xcax\x09\x9b@\xc0\xa6\xd4\xa3" +
"\x93\xa16#a7\xfb(\xe8\xa5R\xa0\xf8{\x014" + "\x0d\x1c\xb1^\xd5t^\x0e\xb4[Q\xea\xf6\xffW\xda" +
"\x8f\xa1v\x9f\x84\x81\xeb7\xc9\xa6.0\xdb\xc1\x9e4" + "Y\xa6\xcd\xf3\xfcG\xd4\xad\x00\xca\x0e\x86\x8a.`\x16" +
"\x94#\xeb\xf0Z\x9d,mA\x91W\xc9\xd0\xd8\x13#" + "?\xf7\xf2T\xfe$m?\x802\xc9Pq\x04\xcc\x0a" +
"n\xc8 \xd7\xeci\xecIKDt\xcc\xe1\x07\xb8\xe3" + "\x97\xbd\xbc\xef\xb5=K\x01\x14\x9d\xa12%`\x96\xfd" +
"\xf22\x14\x1c{f\x16{R\xe4m\xb1z\xf7\xd5Z" + "\xce\xcbS\x91\x91\xdc]\x00\x8a\xc3P\xb9[@\xcfv" +
"=vtrj\xf1\xf3\"4\xab\xde\x0d\xe5\xfe\x05\xce" + "kdS\x1b\x98ia{\x12\xca\xa1ux\xb9B\x96" +
"\";v1\xd4VH\x184\xe9W\xeeq`\x8e\x8b" + "6\xa0\xc0Kdhl\x8f\xd09`\x10\xcb\xe6$\xb6" +
"=i\xe9m\x91\xb6M8\x0f\xd3\xff\x87\xc3W\xca\xd1" + "'\xc5'<f\xf1\xbd\xdc\xb2y\x11r\x9695\x8d" +
"-\x8e+\xc2Y\xebM\x1e\xfb\x0a=v\x98\xa1\xf6\xa0" + "\xed\x09J\xd7Y={\xb5V\x8f\x1c\x1d\x9f\x9a\xff\xbc" +
"\x84\x0ab\xe8\xb3\xe3\x0e\x80v\x8c\xa1vBB\x94B" + "\x1f\x9a%\xe7\x86b\xf7\x1cg\x91\x1d\xdb\x18*\x8b\x05" +
"\x8f=r\x16@;\xc1P{RB\x85I\xa1\xc3N" + "\xf4j\xf4\x95;\x1c\x98ec{R\xd4\xeb\xa4m\x10" +
"\xdfL\xbd\x10C\xed\xbc\x84J\x8e\xf5R\x9b\xa1\xbcH" + "\xce\x03\xf4\xef@\xf0J1\xbc\xc5\xb2\xfdpV\x16\xc7" +
"\xc1v\x9e\xa1vA\xc2\xc0\x0eS\x89\xe4\xf7\xb0\x1b$" + "\x8f\x9d\xa0\xc7\x1ea\xa8\xfcH@\x091\xf0\xd9\xe3\x16" +
"\xec\x06\x0c\xaa\xa6\xed\xd7\xa6L\x1d\xfa\x1d^+mL" + "\x80\xf2\x18C\xe5\xac\x80(\x04\x1e{\xea4\x80r\x96" +
"\xe8\x96\xdf(;\xfc\x80\x81\xb6\xef\x0ez\x1eo\xc8M" + "\xa1\xf2w\x02JL\x08\x1c\xf6\xdcM\x00\xca3\x0c\x95" +
"\xcf\xc5<H\x98\x07,xz\xdd\xc5e\x80e\x86\xd8" + "_\x0a(eX\x9e\x1a\x18\xe9\x02\x05\xdb/\x19*o" +
"\x93\xd64@\"&w\xa2\xc3k\xdb\xb9\xe3\x1a\xcc\xb6" + "\x0b(5e\xf2\xd8\x04 \xbd\xb5\x12@y\x9d\xa1\xf2" +
"\xb0\x0b$\xecZ\xdcL\xe3Q@P8D\xb1m;" + "\xae\x80\x9e\x19\xe4\x17)\xe5`\x16\x04\xcc\x02z%\xdd" +
"\x86\\7,\xad\x8b\xe5V\x05Ad\x93\x11Ru\x03" + "t\xcb\x13\xba\x0a\xdd\x16/\x0f\xad\x8d\xe9\x86[-Z" +
"Cm\xb3\x84\xab\xf1\x13\"\x93YJ\xe3\x00\xda(C" + "|\xaf\x86\xa6k\xf79\x0e\xaf\x8a5\xc7\xc6f\x10\xb0" +
"mB\xc2\xd5\xd2\xc7D&\xc3hd\xd62Cm\xa7" + "\x190\xe7\xa8\x15\x1b\x17\x01\x16\x19b{R\xe8\x00\x89" +
"\x84\x85i\xcfkbOZ\xf0\"\xdf\x1d\xe4{\\\xbb" + "\x18\xdf\x89\x16/o\xe1\x96\xad1\xd3\xc06\x10\xb0\x0d" +
"\xba\x8f\x03R\xf6'\xe8\x1b\xfd:\x1d\xa1\x110\xb3\x86" + "\xb0\xdb.\x995\x8e\xedI\xed\xbc\xb2MG\xc2\xe8\xa1" +
"=i\x0b\xd9\xe2x\xd6\xc6\xf1\xc2\xe7Eo\xc4ql" + "\xd8\x09\x13\xc1\xb44\xb1\xa2\x19J\x1b\xcb,\xf1\xbc\xd0" +
"G\x00e\xe2\xed\x91/\xa4J\xc4\xce.\xedH5P" + "\x80\xeb\xc8.k\x18*\x1b\x04\xec\xc2\xcf\x89L6\x1c" +
"\xa4\x0d\xa1Z\xda\x9eT\xfe\xfe\xaa\xee\xbb<\xb1\xa5\xc3" + "\x1a\x01P\x06\x19*c\x02v\x09\x97\x89LVT\xc8" +
"=gvp\xca\x03\xc6\x9d\x046\xdci\xdb7k\xe3" + "\x07E\x86\xca6\x01s\x93\x8eS\xc3\xf6\xa4:\x86B" +
"\x1cd\xcf\x99E\x04\x09qq0\xd9h\x8ffL\x1e" + "\xed\xe3;m\xb3\xb4\x9b\x03\x12T\xc4P\x1d~\x9d\x0c" +
"FeFN\x92i#C\xad\x9c\xca\xb9\x85h\x9b\x19" + "\xa1\x0b\x98^\xc6\xf6\xa4\x93\xad\xd3\x885\x88\x12?@" +
"jw\x93\x9c\x91\xf9'\xc9\xfc\x13\x0c\xb5\xa6\x84\x81I" + "\x0a\xce:\xcb2-\x1fU\xe3\xd0X\xb72Q\"\x8a" +
"\xe9h\x8d\xda\xc0\\/\x117$\x96m\x11\x802H" + "\x8c\xa1\xad\x89\x06\x92\xb0&PK\xd9\x99\xc8\xdf]R" +
"(\x03\x06~\xd3\xf5\x1c\xae7\x00\x93\x88\"\xfeeW" + "]\x9bG6\xf6,\xeeX\xd3}\x13\x0e0n\xc5\x18" +
"\x81\xba-\xd9_\xd6\x0b\"\x8d\xdb\xeb\x90d\xd6\x96\xb1" + "cO\x9a\xae^\x1e\xe1 :\xd64\"\x08\x88\xf3#" +
"\xac\x12QjM\x0e\xa5\xc6n\x9f0\xd3\xb6\xebYz" + "\xcfZs0e\xf2 \x84Sr\x92Lk\x19*\xc5" +
"\x83\x03@\xac\xd8\x11\xbbI\xb0G\xa0\x90t\x83-\xb1" + "D\xce\x8dD\xdb\xc0P\xb9\x83\xe4\x0c\xcd?N\xe6\x1f" +
"q\xf5\xc5*,\x1c\xf3J\xd5\xd9L\xe5\xa8F\xa7Q" + "c\xa8\xd4\x04\xf4t\xca]c\xd0\x04f;\xb1\xb8\x01" +
"\x1c\x1f\xb6-y\xca\xa8cO\xda>\xb5\x08\xd0\xc6\xef" + "\xb1h\xfa\x81)\x82\x80\"\xa0\xe7\xd6l\xc7\xe2j\x15" +
"\x83\xbe7\xcd-\xcf\xa8\x8a\x07\x17\xf8}M\x1a\x9f\x89" + "0\x8e4\xe2_t\x15\x10]\x07\x15E5\xe7\xe7|" +
"\xcdJ_\xc8\x182\xb6\xd9\x96=\xa9!\xe5}|6" + "c\x1d\xe24\xdc8\x9cV\"\xcc\xc3\xf1\xfe\xc4\xd8\x8d" +
"6K?o\xe8\x86\x99x?\xb2\xe6 \xc8_Ny" + "\x13i\xd2\xb4\x1dC\xadr\x00\x88\x14;h\xd6\x08#" +
"\x16\xed6\xa2\xb2\x12\x16\x95bh\x9e\x16\xc8\x9c\x03\xd0" + "\x09A\xe26\xb3.6\xae\xbe\xb2\x05UfV];" +
"\xeec\xa8=\x9c\x11\xf2\xa1\xc7\x00\xb4\x87\x19jOd" + "\x9d*3\xa5\xf04\xfa\xc7\x07LC\x9c\xd0*\xd8\x9e" +
"\x84<5\x94\xc5L\x16a&Y\xf4I\x86\xda\xb3\x12" + "\xf4Zu\x024\xf0{\x9f\xebLr\xc3\xd1J\xfe\x83" +
"b.\x84\xccs\x04\x99\xcf2\xd4^\x91\x04\x0a\x8e\x0e" + "s\xfc\xbe4\x89\xcf\xd8fC+S\x86\x8cl\xb6q" +
"\x0e\xdb\x16FB\xb8\x001\x06\x06\xd3\\w\xbc=\\" + "gbHq7\x9f\x8e!\x80WUM\x8f\xbd\x1fZ" +
"G\xafdy\xdc9\xa0\xa3\x19\xe7\xe0\x11\xcfhp\xdb" + "\xb3\x0f\xc4o%<\xf3%\xcf(!\x88/\x95o\x03" +
"\xf7\x92\x9cl\xe83\xa2dcm4<%\xeb\x9e\x8b" + "Lu\xe5Rv%\x08\xdd{U\xdd\xe5\xf367a" +
"\x9d a'\xa5\x80\xcb\x9da\x87\xd7\x90\xbc\xa1\x9be" + "\x15\x0bjX!00]\x98\x8f\xd5\xfc\xf6\x0c\x80r" +
"\x9dy\xd3Wb\xa0\xf9xYhc\x9eCiE\xa1" + "7C\xe5\xc1\x94\x9a\x0f<\x0c\xa0<\xc8Py$\xa5" +
"\xff\xd2\xf9O9>\x00\x92H]\xd2\xb91\x946\x06" + "\xe6q\x0a\x8d\xa3\x0c\x95S\x04\xd1,\x00\x97\x13\xe4\x93" +
"\xa2\xa0tP_\xf0X\xda\x01\x88\x82\x92\xa7\x1b\xcf\xa4" + "S\x0c\x95'\x05\xc4L\x80\xd0g\x08\xa1\x9fd\xa8\x9c" +
"\x06\x8fD\x1b\xb5\xa1\x18\xa6D,s1t\xf5\x11\x82" + "\x17||\x1d\xec\x1b0\x0d\x0c\x85\xb0\x01\"t\xf5&" +
"'\x83\xa7zFu\xd6@\xdb\x9a\x10\x06\xc2\xd4BU" + "\xb9j9;\xb9\x8a\xce\x90\xe1pk\xaf\x8az\x94\xc5" +
"\xbb\xd1t\xb8\xeb\xa2a[\x9a\xaf\x9b\x06\xf3f\x93\x83" + "\x07\x1d\xad\xcaM\xd7\x89\xb3\xba\xaaN\xf9\x1d\x02\x96\x07" +
"\x8b\xda\x80r?\xcc\x99m\xcd~\xe1$2\xc2m\xb1" + "\x83S\xa2\xea\xd8\xd8\x0a\x02\xb6R\x12\xd9\xdc\x1a\xb0x" +
"\x11\xd4A\x1c\x03\xa8l@\x86\x95\xcd\x98\x86\x89Z\xc2" + "\x19\xc9\x9f\xaa^T\x9939\xc7\xc4\x99+!n\xae" +
"!\x80\xcaF\xa2\x971\x8d\x14u\x0b\xf6\x01TF\x89" + "\x81y\xa8\xbf8\xc0P\xb9\x9f\xb2\x1fS\x83\xacto" +
">\x81\x12b\x18+\xaa\x86\xcf\x03T&\x88\xbc\x1b\xd3" + "/\x08~\xf2\x93\xce\xd5\xfe\xa4\x0f\xf1\xeb\x17U\xa5=" +
"\x12\xab\xee\x12\xd7\xef$\xfa4\xd1;r\xc2|*\xc7" + "\x0f'\x0d\x87_\xbf\x9a\xe9\xc6\x93\x89\xc1C\xd1\x06M" +
"\x9b\x01*\xbb\x89~\x98\xe8yIXP\x9d\xc5\xbd\x00" + "(\x04I\x15\xc9\\\x08\x82\xe5 \x01\x9c\xc6\x13=\xc3" +
"\x95\x19\xa2\x1f#\xba\xdc\xd1\x8b\xa2\xf1G\x07\xa0r\x1f" + "\xb2\xae\xa1i\x8c\xf9\x06\xc2\xc4B%\xb3Z\xb3\xb8m" +
"\xd1\x1f&\xfa\x92\x15\xbd\xb8\x04@}H\xd0\x1f$\xfa" + "\xa3f\x1a\x8a\xab\xea\x1as\xa6\xe3\x83\xf3\xda\x80\xd0#" +
"\xe3D\xef\\\xd9\x8b\x9d\x00\xeaI<\x0aP9A\xf4" + "\xc8\xba\xcd\xb5n\xdfId\x84[\"#\xc8}8\x0c" +
"'\x89\xbe\x14{q)\x80z\x1a\xcf\x00T\x9e$\xfa" + "0\xba\x06\x19\x8en\xc0$L\xe4!\xec\x07\x18]K" +
"\xb3D\xbf&\xdf\x8b\xd7\x00\xa8\xe7\x84<O\x11\xfd\x05" + "\xf4\"&\x91\"o\xc4N\x80\xd1A\xa2\x8f\xa1\x80\x18" +
"L\x00\xa4T\xcb\xe2\x18\x85\x93\x91\xd6jf\xbbI\x18" + "\xc4\x8a\xac\xe0\xd3\x00\xa3cD\xde\x81IE\x97\xb7\xfb" +
"\xf2\xa8\xf5\xc7\x10d\xcbv\x81z\x7f,\xa4\xab\x17@" + "\xd7o#\xfa$&E]\xe6x\x13\xc0\xe8\x0e\xa2\x1f" +
",\x00\x06M\xdb6\xb7\xce\xc7\xc7\xcb\xb5\x0bQX@" + " z\xb3\xe0[P\x9e\xc6]\x00\xa3SD?Lt" +
"\xc1\xb6J\xb5$\xbf\xc2 \xdalC\x7fU7K\xcd" + "\xb1)O\xf3\x81|\x0fZ\x00\xa3w\x13\xfdA\xa2\xb7" +
"D\x12\xc3\x1d\xf4=\xdboB\x7fM\xf7x-\xa9p" + ",\xcec\x0b\xcd\x1f>\xfd~\xa2\x7f\x9f\xe8\xad\x1dy" +
"\x8eomr\xec\xc6\x04r\xa7aX\xba\x09\xc9/\x8b" + "l\x05\x90\x8f\xe1!\x80\xd1\xa3D?E\xf4\x05\x98\xc7" +
"\xc5V\xc1\xf7\x8d\xda\x82d\x93Z\x03\xad\xbf90\xa1" + "\x05\x00\xf2\x09<\x090z\x8a\xe8O\x12}as\x1e" +
"\x8b\xecZ\x92d\xd7M\xd4\x86\xdc\xc0P\xbb-\x03>" + "\x17\x02\xc8g|y\x1e#\xfaY\x8c!h\xa8\x9cF" +
"k\x09!?\xc7P\xfbm\x09\x0b\xd9\xa4\xe8?\xa0\x9b" + "B\x0a'-\xe9\x02\x98i\xc7a\xc8\xc3I\x03\x03\x98" +
">\xbf\x926h\xb2\xa5\x14\x84\xddl\x88\xcf\x99\xd7\x87" + ".\x9a9\x1a50\x97\xec\x90\x001\x07\xe8\xd5LS" +
"\xd2\xd7\x93\xc7\xa9Y\xbc\x85\xa16*\xe1\x11\xd7\xafV" + "\xdf4\x1ba\xaf\xd4\x88\x84a\x019\xd3\x18*\xc7\xf9" +
"I\xe9\xd8\x0aS\xd1\xcc\x00\xfdtw\xc6\x1f\xc98\x1f" + "\x15\x04\xd1\x06\x13\xbaK\xaa>T\x8b%\xd1\xec>\xd7" +
"\xf9\xe3J\xcbn\x9d{\xe1W\xc9\x9a\xb2\xa9^\xc9z" + "1\xdd\x1at\x97U\x87\x97\xe3\x1ai\xb9\xc6z\xcb\xac" +
"\xc3\xfd\x7f\x9e\x1e\xe7n\x81Z\xf6\xcbNf\xc9\x80~" + "\x8e!\xb7\xaa\x9a\xa1\xea\x10\x7f\x99/\xb6r\xae\xab\x95" +
"\xf9\xfa6:1QN\xc7G\x16\x82c\x16\x17\xc6\xb3" + "\xbf4\x9e\xad\x08PKiI:\xfbeT\x9d\xbe\xc6" +
"\xb8\x90\xc2\xc2\xdel\xfa\xc7m\x98\xaa\x89<,\x13}" + "P\xf9\xfdtg\x7f+A\xed\xcd\x0c\x95\xdb\xa8[\x9f" +
"'\xa6}\xb7z\x0f\x9e\x9d\x97\xff\xb9\xc1\x10\x17\xb8\xb8" + "\xb6\x1d^\xdd\xa4\x02Kr\xa4\xbbb\x99nm\xce\xc3" +
"\xbeF\xf4\xa6\xc0\x05\x0cq\xa1!\xee7\x89>\x93\xc5" + "B\xfd\xc3\xdd\xb5\xde1\xd5O\xeb\x968\xad\x97Q\x07" +
"\x05\x1f\xe7\xe6\xe3\x02\x8bq\x81\xf2\xf9\x18\xd1O\x08\\" + "u\x03C\xe5\x96\x14\xea-_\x99\xc8\x91Kgc " +
"\xc8\x85\xb8\xf0\x08\xbe</\xff;;B\\8\x8d\xaf" + "\xf2\x9c\x97\x1atp\xe3uU,\xe8\xda\x83\xd2\x92z" +
"\xcf\xcb\xff\xa5\xf9\x10\x17\xce\x09\xfeg\x89\xfe\x8a\xc0\x85" + "\xbd?y=~\xdc\x0a\xd5\x1d\x14\xf0\xa0\xed\x96Jd" +
"\xa1\x10\x17^\x128r\x9e\xe8\x17\x08\x17|\xc7\xacx" + "\xed\xc8\xfc\x13\xe1l\x04\xddtw*\x10\xe2\xb5E\x18" +
"\x8ea\x01\xd6\xd3`\xad6\xbf\xccys\x10\x0a\xa6q" + "\x08_\xb6c\xa8p'\xf85dL\x98TjE\xb5" +
"\x80'\x98]3ts\xa3\xaf\x9b\xd0_\xf1\xf4\xea\xbe" + "j\xff\x1fO\x8fp;G\xa3\xc9\x15'\xd0x\x11q" +
"\xb4\xd74\xddQ\xdd\xaa\xb98\xad\xef\xe3\x84\xf4r\xb6" + "\xe5\xd2<86VL\xc6d\x16\xa0r\x1a\x90F\xd2" +
"\x16z\xa6\xbb\x9d;\xc6\x14`\xda\x9d&\xbdA\xa1l" + "\x80\x94\xe0\xd1\xae4\xeeD\x1d\xa4\xac\xf8\x00P$\xfa" +
"\xdb\xad-\x83hr\xb8\x13\x82J\xf2[C\x9f)\xd5" + "6L\xe6\x0b\xf9N<=\x0bx2}\x01 q\xff" +
"L>\x8cq\x87\xc0\xac\xb4\xd2\x18\xf4\x8bmY\x18\x96" + "\xfa2\xd1k> a\x00HU\xff~\x9d\xe8Si" +
"\xed\x09\xa3\x7f~=nF\xfdn\\\xd7'\x8a-\x05" + "@rqf6 \xb1\x08\x90\x08H\x0e\x13\xfd\xa8\x0f" +
"\x9b\xcf4y\xd5\x1b\xb6\xd1\xf2\x0c\xcb\xe7\x0b.\xa8N" + "H\x99\x00\x90\x8e\xe0\xb3\xb3\x80\xa7\xb5)\x00\xa4\x13\xf8" +
"\xfb\xd6>^\x1bA\xabj\xd7\x0c\xab\x0e\x0b\x1am\xf6" + "\xfc,\xe0Y\xd0\x1c\x00\xd2\x19\x9f\xffI\xa2\x9f\xf7\x01" +
"iS{\xa6\x91\x11\xd9\x8c\x99e\xb1r\x13\x95e\x8c" + "\xa9?\x00\xa4s>\x80=C\xf4\x17\x08\x90\\K\x1f" +
"\xca\xb22\x90N\x9f\xc5\xaa8Ut\xb8\xee\xb6\x99\xa6" + "u,\xcd\x00\xac$\xc1Z\xaa}\x8b\xf3Z\x1f\xe4t" +
"\xd8\xa7e[1L2z\xad\x87u\x00$\xabW\x8c" + "m/\x8f\x8bEYS\xf5\xb5\xae\xaaC\xf7\xa8\xa3\x96" +
"wa\xca\xfeC )\x86\x8c\xe9\x0a\x11\xe3\x8d\xa1\xb2" + "v'm\xb2n\x0f\xaaF\xd9\xc6Iu7\xa7\x12#" +
"\xcb\x01I\x99\x94QJ6\xde\x18o\xab\x95\xd2\x1cH" + "\xa6\x8b\xb0\xa3\xdb[\xb8\xa5M\x00&\x8du\xdc\xd6\xe4" +
"\xca\x88\x8c,YSc\xbc\x89R\xee\x1c\x02IY+" + "\x8a\xa6Y\xdf\xed\xf8\xfd\x19\xb7\x024\x8b\xbfU\xd5\xa9" +
"\x07qk\x0e\xc5P\x9c\x0d\x18\xc4\x89\x0f\xfd\"\xf57" + "\xa1\xb2\xce\x070jM\x98\x91\x948\x8d\xbe\x98\x86\x81" +
"`\x10\xcf\xef\x18\xb7\xf0\x00\x1b\xf0HT\x166`v" + "A\xbf0\xa6u\xcfn\x04ja\xab\x1e5\x14c\x85" +
"\xe9\xc3>\xad\x8fn\xdf\x1e\x12F\xce0\xd4\x8e\xa5\x18" + "\xbaN\x81O\xd5x\xc9\x190\xd1p4\xc3\xe5s." +
"y\xff\\:P'\xb3\xcb#\xcf\xb7\x9b\xa8\x8f\x02h" + "(M\xba\xc6n^^\x87F\xc9,kF\x05\xe6\xcc" +
"O\x84\x9d`2Q\xbfD-\xe3+\x0c\xb5\x1fJi" + "\x08\xec\x8b\xb6\x13\xa9\x0e\xaa%l\xc9\xe2u\xbb\xb4\x8c" +
"\xbd\x8c\xc3.\xde\x93\xa0\xed\xc4\xc3\xd4\"\xeb\x92(8" + "\xfa\x01\x0c\xfb\x01\xa97\x99\xb2\x0b%\xffT\xc1\xe2\xaa" +
"\xa3\xce\xadui\x12\xd4\xeci\xd1\xd9ax\x95\x0b)" + "\x9d\x94\x86\xf9^\x0b\x97QA\x92\xd1k\xed\xac\x09 " +
"bg7)\xcb2\x9b\x14\x8c\xc78y\x1e\xc0g\xf7" + "^^c\xb4\xf3\x93\xf6\xec\x07A\xd2DLV\xa5\x18" +
"*\xcb\x16\xc7\xccyC\x89\xa889\x115\xf1>\x1e" + "mF\xa5\xed\x16\x08\xd2\xb8\x88B\xfc7\x03\x8c\xf6\xfd" +
"\xe3\xbf\x8c(\x0ay\xbf[\x0e\xe2\xc1\x05\xe3rE\xce" + "\xd2\xd0\x0c\x08\xd2:\x11Y\xbc\xe8\xc7h\xe3&\xad\xee" +
"\xcb\xba\xec*\xa7\xb7q\xde\xef^I%\x88\xb7\xaf\x97" + "\x07AZ.z\xd1T\x01\x85@\x9c5\xe8E\x89\x0f" +
"\x1f\xc2\xc3w\x0a\x14l\xa1B\xc9\xbd{3\xdb\x1d\xd3" + "\xdd~\xea\xafA/\xdaS`4}\x00\xac\xc1\x83a" +
"\x8e\xe6\xa0\xc2\xd6L\xd5^\xccV\xa1\xc0q\x03Z\xa0" + "=Z\x83\xe9\xe5\x16\xfb\xa2\x11\xa0q_J\x189\xc5" +
"\xc3-\xe1\xb7&\x0d\xbf\xa4A\xb8\x7fMf\xcb\x13O" + "P9\x9c`\xe4=\xd4\xab\x1ef\xa8\x1cM\x8d]G" +
"'\xc7\xc7\xa2\xa0|*i8\x95oR\xa0>\xc5P" + "\x9eN\xb7\xa5\xe1\xe6\xe0\xc4\xa1p\xefp>\xb598" +
"{!\x13~\xcf\x8d\xa5\xd3\x89\xcc\x1d'\x96S\xf6\x9d" + "G\xbd\xeay\x86\xca\xebBR\xa8\xa3\xb0\x8b\xf6Ah" +
"\x146M\xbb\xbe\xd9\xb0\xb8K-X\xcbH\xdd\xe4N" + "Z\xd1\x1c8\xcfZ(\x0c\xce\xb0e\xac_\x0eye" +
"C\xb7\xb8\x85\x1e\x81\x91\xef\x10\xa2\xceG\xae\xd2\xc6L" + "s\xd2o)1\xb8\xca\x86\x04\xb1\xd3\x1b\xa3E\xa9\x8d" +
"\xe7\xb6\x98\xfa\x95(\xd8\xc3X\x8f\xcakf~<\x9b" + "\x11F\x13\xa88\x0b\xe0\xd3\xfb\xa3E\xf3c\xe6\xacy" +
"\xd9e\xc4\xcak\xafG;\x82\xdd\x19\xe5w\xd1\xfc\xb8" + "*\x1c\x1b(j\xa2\xbfh`\xf4\xb7%I\"\xefg" +
"\x93\xa16-a\xa0\xfb\x9e=\xd9\xac\xe9\xe8\xf1M\x0e" + "E/\x9a\xb90*W\xe4\xbc\xb4\xcb\xaer\xf0\x1c\xe1" +
"\xdf\xefs\xd9\xaa\xce\xa6s\x14M\x14Uw\x12\x9b\xd4" + "\xdd\xf6\x97\xa9\x04\xd1\x96\xf9\xca\xfb\x83\xe0\x9d\x1c\x05[" +
"\xfbmrxq\xbf\xcf\xb3\x0c\xf1B\x15d\xc3\xae-" + "<\x07\x05\xf7\xeeJm\xb1t3\x1c\xe1r\x9bRU" +
"\xd8\xa4\xb6i\xb6\xee\xe2{*vu\x1f\xf7\xe6-\x9a" + "{>[\x05\x02G\x9do\x8e\x0e\xd7\x85\xdf\xd2$\xfc" +
"C\xb8\x8cU\xd1\xc7\xd3mj\xac\x891\x9e\x19\x99b" + "\xe2\x06\xe1\x9e\xa5\xc90\x10\x8fE\xf7\x0e\x87A\xf9X" +
"\x18\xd9O\x01\xd5d\xa8\x1d\xce\xc0\xc8\xec\\\xea\xf0\xf6" + "\xdc\xe9J\x8f\xce$\x1b\xae8\xfc\x9e\x1aN\xc6\"\x91" +
"\xd5\xf5\xd7S\x10\x17Q\xb2\xed\xb6s\xbc\xc8\xaf(\xd1" + "[V$\xa7\xe8Z\x09l\xeafe\x83fp\x9bz" +
"\xd2\xbf\x1e\\\xbe\xe5\x8a\xc6\xf5\xa8cmiX\xd7\xb4" + "\xbf\xbam@\x8d[U\xd5\xe0\x06:\x04F\xaeE\x88" +
"k\x97wD\x1d\xeb\x1dQ<\xf7\xa4\x7fw\x8c\x9es" + ":\x1b\xb9\x86\xd6\xa6Z\xc6\xf9\xd4\x1f\x0d\x83=\x88\xf5" +
"\xa3.\x11\xd8\x94\xbd\xb0\x01\xfc\xbf\x00\x00\x00\xff\xff\xde" + "\xb0\xbc\xa6F\xdf\xd3\xa95L\xa4\xbc\xf2|\xb8\xde\xd8" +
"T\x04\xc0" "\x91R~;\x8d\xbe\xdb\x18*\x93\x02z\xaa\xeb\x98\xe3" +
"\xb5\xb2\x8a\x0e_o\xf1=.\x17\x8d\xd2t2\xc0\xd1" +
"(S\xb2\xc7\xb1FM\xe7z\x8b\x17\xf6\xb8<\xcd\x10" +
"-\x8eA\xd4\xcc\xf2\x9c\x8dq\x83f\xebv\xbes\xd4" +
",\xed\xe6\xce\xac\x85z\x00\x97\x91*\xeaH\xb25\x8e" +
"4\xd1FR\xb3Z\x04#{(\xa0j\x0c\x95\x03)" +
"\x18\x99\x9eI\x1c\xde\xb8\xba\xfe\xff\x14\xc4y\x94l\xb8" +
"\xd5\x1d)\xf0/\x95h\xc9_I\xae\xdcr\x85{\x82" +
"\xb0c\xadkX\x976j\x97\xb7&\x0d\xba\x1f\xcf\xed" +
"\xc9_n\xc3\xe7\xec\xb0K\x046a\xcem\x00\xff7" +
"\x00\x00\xff\xff\xfd\xa0l\x0d"
func init() { func init() {
schemas.Register(schema_db8274f9144abc7e, schemas.Register(schema_db8274f9144abc7e,
@ -3738,9 +3914,11 @@ func init() {
0xb70431c0dc014915, 0xb70431c0dc014915,
0xb9d4ef45c2b5fc5b, 0xb9d4ef45c2b5fc5b,
0xc082ef6e0d42ed1d, 0xc082ef6e0d42ed1d,
0xc54a4a6fd4d87596,
0xc744e349009087aa, 0xc744e349009087aa,
0xc766a92976e389c4, 0xc766a92976e389c4,
0xc793e50592935b4a, 0xc793e50592935b4a,
0xc9c82ee56583acfa,
0xcbd96442ae3bb01a, 0xcbd96442ae3bb01a,
0xd58a254e7a792b87, 0xd58a254e7a792b87,
0xdc3ed6801961e502, 0xdc3ed6801961e502,