diff --git a/cmd/cloudflared/tunnel/cmd.go b/cmd/cloudflared/tunnel/cmd.go index 2de58774..95085925 100644 --- a/cmd/cloudflared/tunnel/cmd.go +++ b/cmd/cloudflared/tunnel/cmd.go @@ -506,21 +506,19 @@ func startDeclarativeTunnel(ctx context.Context, 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") + name := c.String("name") + group := c.String("group") + if group == "" { + err := fmt.Errorf("--group must be specified") + logger.WithError(err).Error("unable to parse group name") return err - } else if c.IsSet("group") { - scope = pogs.NewGroup(c.String("group")) - } else { - scope = pogs.NewSystemName(c.String("system-name")) } cloudflaredConfig := &connection.CloudflaredConfig{ BuildInfo: buildInfo, CloudflaredID: cloudflaredID, - Scope: scope, + Name: name, + Group: group, Tags: tags, } @@ -944,15 +942,15 @@ func tunnelFlags(shouldHide bool) []cli.Flag { 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"}, + Name: "name", + Usage: "Friendly name for this cloudflared instance.", + EnvVars: []string{"TUNNEL_DECLARATIVE_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"}, + Usage: "The group whose behavior this cloudflared instance will adopt. This behavior can be configured by editing the group's 'intent' in the Declarative Tunnel UI.", + EnvVars: []string{"TUNNEL_DECLARATIVE_GROUP"}, Hidden: true, }), altsrc.NewDurationFlag(&cli.DurationFlag{ diff --git a/connection/manager.go b/connection/manager.go index 29949062..7533f4a0 100644 --- a/connection/manager.go +++ b/connection/manager.go @@ -47,7 +47,8 @@ type CloudflaredConfig struct { CloudflaredID uuid.UUID Tags []pogs.Tag BuildInfo *buildinfo.BuildInfo - Scope pogs.Scope + Name string + Group string } func NewEdgeManager( @@ -136,7 +137,8 @@ func (em *EdgeManager) newConnection(ctx context.Context) error { CloudflaredVersion: em.cloudflaredConfig.BuildInfo.CloudflaredVersion, NumPreviousAttempts: 0, OriginCert: em.state.getUserCredential(), - Scope: em.cloudflaredConfig.Scope, + Name: em.cloudflaredConfig.Name, + Group: em.cloudflaredConfig.Group, Tags: em.cloudflaredConfig.Tags, }, em.logger) if err != nil { diff --git a/tunnelrpc/pogs/json.go b/tunnelrpc/pogs/json.go index 497ee4d8..952b1b34 100644 --- a/tunnelrpc/pogs/json.go +++ b/tunnelrpc/pogs/json.go @@ -8,39 +8,6 @@ import ( "github.com/pkg/errors" ) -// ScopeUnmarshaler can marshal a Scope pog from JSON. -type ScopeUnmarshaler struct { - Scope Scope -} - -// UnmarshalJSON takes in a JSON string, and attempts to marshal it into a Scope. -// If successful, the Scope member of this ScopeUnmarshaler is set and nil is returned. -// If unsuccessful, returns an error. -func (su *ScopeUnmarshaler) UnmarshalJSON(b []byte) error { - var scopeJSON map[string]interface{} - if err := json.Unmarshal(b, &scopeJSON); err != nil { - return errors.Wrapf(err, "cannot unmarshal %s into scopeJSON", string(b)) - } - - if group, ok := scopeJSON["group"]; ok { - if val, ok := group.(string); ok { - su.Scope = NewGroup(val) - return nil - } - return fmt.Errorf("JSON should have been a Scope, but the 'group' key contained %v", group) - } - - if systemName, ok := scopeJSON["system_name"]; ok { - if val, ok := systemName.(string); ok { - su.Scope = NewSystemName(val) - return nil - } - return fmt.Errorf("JSON should have been a Scope, but the 'system_name' key contained %v", systemName) - } - - return fmt.Errorf("JSON should have been an object with one root key, either 'system_name' or 'group'") -} - // OriginConfigJSONHandler is a wrapper to serialize OriginConfig with type information, and deserialize JSON // into an OriginConfig. type OriginConfigJSONHandler struct { diff --git a/tunnelrpc/pogs/json_test.go b/tunnelrpc/pogs/json_test.go index 70a896a4..8d09f8cd 100644 --- a/tunnelrpc/pogs/json_test.go +++ b/tunnelrpc/pogs/json_test.go @@ -9,59 +9,6 @@ import ( "github.com/stretchr/testify/assert" ) -func TestScopeUnmarshaler_UnmarshalJSON(t *testing.T) { - type fields struct { - Scope Scope - } - type args struct { - b []byte - } - tests := []struct { - name string - fields fields - args args - wantErr bool - wantScope Scope - }{ - { - name: "group_successful", - args: args{b: []byte(`{"group": "my-group"}`)}, - wantScope: NewGroup("my-group"), - }, - { - name: "system_name_successful", - args: args{b: []byte(`{"system_name": "my-computer"}`)}, - wantScope: NewSystemName("my-computer"), - }, - { - name: "not_a_scope", - args: args{b: []byte(`{"x": "y"}`)}, - wantErr: true, - }, - { - name: "malformed_group", - args: args{b: []byte(`{"group": ["a", "b"]}`)}, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - su := &ScopeUnmarshaler{ - Scope: tt.fields.Scope, - } - err := su.UnmarshalJSON(tt.args.b) - if !tt.wantErr { - if err != nil { - t.Errorf("ScopeUnmarshaler.UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr) - } - if !eqScope(tt.wantScope, su.Scope) { - t.Errorf("Wanted scope %v but got scope %v", tt.wantScope, su.Scope) - } - } - }) - } -} - func TestUnmarshalOrigin(t *testing.T) { tests := []struct { jsonLiteral string @@ -336,7 +283,3 @@ type prettyJSON string func prettyToValidJSON(prettyJSON string) string { return strings.ReplaceAll(strings.ReplaceAll(prettyJSON, "\n", ""), "\t", "") } - -func eqScope(s1, s2 Scope) bool { - return s1.Value() == s2.Value() && s1.PostgresType() == s2.PostgresType() -} diff --git a/tunnelrpc/pogs/tunnelrpc.go b/tunnelrpc/pogs/tunnelrpc.go index 8d41b63a..bb3953ed 100644 --- a/tunnelrpc/pogs/tunnelrpc.go +++ b/tunnelrpc/pogs/tunnelrpc.go @@ -2,7 +2,6 @@ package pogs import ( "context" - "fmt" "time" "github.com/cloudflare/cloudflared/tunnelrpc" @@ -129,82 +128,14 @@ func UnmarshalServerInfo(s tunnelrpc.ServerInfo) (*ServerInfo, error) { return p, err } -//go-sumtype:decl Scope -type Scope interface { - Value() string - PostgresType() string - GraphQLType() 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) PostgresType() string { return "system_name" } -func (_ *SystemName) GraphQLType() string { return "SYSTEM_NAME" } - -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) PostgresType() string { return "group" } -func (_ *Group) GraphQLType() string { return "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 { OriginCert []byte CloudflaredID uuid.UUID NumPreviousAttempts uint8 Tags []Tag CloudflaredVersion string - Scope Scope + Name string + Group string } func MarshalConnectParameters(s tunnelrpc.CapnpConnectParameters, p *ConnectParameters) error { @@ -237,11 +168,13 @@ func MarshalConnectParameters(s tunnelrpc.CapnpConnectParameters, p *ConnectPara if err := s.SetCloudflaredVersion(p.CloudflaredVersion); err != nil { return err } - scope, err := s.NewScope() - if err != nil { + if err := s.SetName(p.Name); err != nil { return err } - return MarshalScope(scope, p.Scope) + if err := s.SetGroup(p.Group); err != nil { + return err + } + return nil } func UnmarshalConnectParameters(s tunnelrpc.CapnpConnectParameters) (*ConnectParameters, error) { @@ -282,11 +215,12 @@ func UnmarshalConnectParameters(s tunnelrpc.CapnpConnectParameters) (*ConnectPar return nil, err } - scopeCapnp, err := s.Scope() + name, err := s.Name() if err != nil { return nil, err } - scope, err := UnmarshalScope(scopeCapnp) + + group, err := s.Group() if err != nil { return nil, err } @@ -297,7 +231,8 @@ func UnmarshalConnectParameters(s tunnelrpc.CapnpConnectParameters) (*ConnectPar NumPreviousAttempts: s.NumPreviousAttempts(), Tags: tags, CloudflaredVersion: cloudflaredVersion, - Scope: scope, + Name: name, + Group: group, }, nil } diff --git a/tunnelrpc/pogs/tunnelrpc_test.go b/tunnelrpc/pogs/tunnelrpc_test.go index b2f2e71e..7daea8bc 100644 --- a/tunnelrpc/pogs/tunnelrpc_test.go +++ b/tunnelrpc/pogs/tunnelrpc_test.go @@ -11,35 +11,6 @@ import ( 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 sampleTestConnectResult() *ConnectResult { return &ConnectResult{ Err: &ConnectError{ @@ -78,7 +49,7 @@ func TestConnectParameters(t *testing.T) { testCases := []*ConnectParameters{ sampleConnectParameters(), sampleConnectParameters(func(c *ConnectParameters) { - c.Scope = &SystemName{systemName: "my_system"} + c.Name = "" }), sampleConnectParameters(func(c *ConnectParameters) { c.Tags = nil @@ -118,7 +89,8 @@ func sampleConnectParameters(overrides ...func(*ConnectParameters)) *ConnectPara }, }, CloudflaredVersion: "7.0", - Scope: &Group{group: "my_group"}, + Name: "My Computer", + Group: "www", } sample.ensureNoZeroFields() for _, f := range overrides { diff --git a/tunnelrpc/tunnelrpc.capnp b/tunnelrpc/tunnelrpc.capnp index 5beecc18..5ae59456 100644 --- a/tunnelrpc/tunnelrpc.capnp +++ b/tunnelrpc/tunnelrpc.capnp @@ -57,17 +57,10 @@ struct CapnpConnectParameters { tags @3 :List(Tag); # release version of cloudflared 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; - } + # friendly name for this cloudflared instance + name @5 :Text; + # group whose behavior this cloudflared instance will adopt + group @6 :Text; } struct ConnectResult { diff --git a/tunnelrpc/tunnelrpc.capnp.go b/tunnelrpc/tunnelrpc.capnp.go index 0dd6ab0e..175e8e15 100644 --- a/tunnelrpc/tunnelrpc.capnp.go +++ b/tunnelrpc/tunnelrpc.capnp.go @@ -504,12 +504,12 @@ type CapnpConnectParameters struct{ capnp.Struct } const CapnpConnectParameters_TypeID = 0xa78f37418c1077c8 func NewCapnpConnectParameters(s *capnp.Segment) (CapnpConnectParameters, error) { - st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 5}) + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 6}) return CapnpConnectParameters{st}, err } func NewRootCapnpConnectParameters(s *capnp.Segment) (CapnpConnectParameters, error) { - st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 5}) + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 6}) return CapnpConnectParameters{st}, err } @@ -603,29 +603,42 @@ func (s CapnpConnectParameters) SetCloudflaredVersion(v string) error { return s.Struct.SetText(3, v) } -func (s CapnpConnectParameters) Scope() (Scope, error) { +func (s CapnpConnectParameters) Name() (string, error) { p, err := s.Struct.Ptr(4) - return Scope{Struct: p.Struct()}, err + return p.Text(), err } -func (s CapnpConnectParameters) HasScope() bool { +func (s CapnpConnectParameters) HasName() 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()) +func (s CapnpConnectParameters) NameBytes() ([]byte, error) { + p, err := s.Struct.Ptr(4) + return p.TextBytes(), err } -// 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 +func (s CapnpConnectParameters) SetName(v string) error { + return s.Struct.SetText(4, v) +} + +func (s CapnpConnectParameters) Group() (string, error) { + p, err := s.Struct.Ptr(5) + return p.Text(), err +} + +func (s CapnpConnectParameters) HasGroup() bool { + p, err := s.Struct.Ptr(5) + return p.IsValid() || err != nil +} + +func (s CapnpConnectParameters) GroupBytes() ([]byte, error) { + p, err := s.Struct.Ptr(5) + return p.TextBytes(), err +} + +func (s CapnpConnectParameters) SetGroup(v string) error { + return s.Struct.SetText(5, v) } // CapnpConnectParameters_List is a list of CapnpConnectParameters. @@ -633,7 +646,7 @@ type CapnpConnectParameters_List struct{ capnp.List } // NewCapnpConnectParameters creates a new list of CapnpConnectParameters. func NewCapnpConnectParameters_List(s *capnp.Segment, sz int32) (CapnpConnectParameters_List, error) { - l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 5}, sz) + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 6}, sz) return CapnpConnectParameters_List{l}, err } @@ -658,147 +671,6 @@ func (p CapnpConnectParameters_Promise) Struct() (CapnpConnectParameters, error) 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 } // ConnectResult_TypeID is the unique identifier for the type ConnectResult. @@ -3704,229 +3576,223 @@ func (p ClientService_useConfiguration_Results_Promise) Result() UseConfiguratio return UseConfigurationResult_Promise{Pipeline: p.Pipeline.GetPipeline(0)} } -const schema_db8274f9144abc7e = "x\xda\xacY}l]\xe5y\x7f\x9e\xf3^\xfb\xd8\x89" + - "o\xae\x0f\xe7\"b\x13\xcbU\x04jCI\x06\xf1\xb2" + - "\x11o\xeb\x8d\xed$\xb5\xdd|\xdc\xe3\x8f\x00!\x91r" + - "r\xef\xeb\xeb\xe3\x9c{\xce\xcd\xf9\x08v\x946\x90\x85" + - "\x01\x1e)\x09m&\x92\x86\x0a\xb2f|(]\x09\x0d" + - "\xda\xca\xa0*\xd3\x18d\xad\x04h0\xc1\xc6\xfeX!" + - "\x9a@\x8b\x18\xb4\x12\xa2*\x9c\xe99\xdf\xbe\xbeu\xc2" + - "\xd4\x7f\x92\xab\xe7<\xef\xfb>\x9f\xbf\xe7\xc37e[" + - "\xd7\x0977\x99Y\x00\xe5TS\xb3\xf7\xa7\xd5WO" + - "\xff\xd1\xf1\x9f\x1f\x06\xa9S\xf0\xbe\xf5\xfcp\xfeS\xe7" + - "\xd0\x7f\x00`\xcf#\xcd\xfbQ>\xd7,\x02\xc8?l" + - "\xde\x0a\xe8\xfd\xebM\x07\xde\xdb\xf5\xabc\xf7\x81\xd4\x89" + - "\x09gF\x04\xe8y\xa9y\x16\xe5\xffl\x16\x81y\x8f" + - "\xdc\x91\xff\x17|\xf4\x93c }\x05\x01\x9a\x90>\xff" + - "\xa4y\x91\x00(\xbf\xde\\\x00\xf4^\xbd\xf1\xf9\xe7\x8e" + - "\xfe\xf8\xde\xef\x81\xf2eD\x08\xce\x7f\xd4\xfc\x1b\x04\x94" + - "\x9bDb\xf8\xe8\x07_\xcd\xfc\xf0\xd5\xab\xbe\xef3x" + - "g^\xbf\xf5\x99\xa3?\xfe\xd2\x070.\x88\x98\x01\xe8" + - "Y)Z\xc4\xbbV\xfco@\xef\xbbo\xbd\xb0\xa5z" + - "\xec\xe4i\x90\xbe\x1c\xdd\xd5\xd1\"\x08\x90\xf1\xd6\xfc\xfb" + - "\xc5\xad\x9b\x9f\x99x<\xf8\x12\xc8\x91my\x86\x8ev" + - "\xb5\xd03\xaf\xdc\xd9\xfe@\xdf\x1f?\xf88(\x9d\x98" + - "\xd2\xa7\xa9\x898\xfbZfQ\xbe\xbd\x85~\x8e\xb7\xdc" + - "\x8a\x80\xde\xec\xda\x17\xb6\xfd\xea/\xec\xa7@Y\x89\x19" + - "\xef\x9f\xee\x7fw\xdf\x8a''^\xf6\xa5b\x00=\x17" + - "ZO\xd3\xd5o\xb7\xfe\x08\xd0\xcb\xfe\xc3\x0d[\x1e|" + - "o\xd39\xba:e\xd4@\x88\x99E\xbd(\xdf\xbf\x88" + - "\xecz\xcf\"\xe2~\xed\xc6m?\xfd\xe9\xd3\x95s\xf5" + - "\x82\x08\xc4}\xfd\xe2a\x94\xd7.&\xee5\x8b\x89\xfb" + - "\xea!|\xe7g7g\xfe.\xd4\x8b\x11\xd3\xfb\x8b?" + - "\xa0\xc7?\xf3\x19\xee\xf8\xed\xb3\xff\xb8\xe1\xc37~\x92" + - "v\xc0#m\x029\xe0\\\x1b)\xdeu\xa9?k|" + - "x\xe8gs\xfd\x18\xdc\xf4v\xdb0\xca\x97\xda\xe8\xb9" + - "\xf7\xdb\xe8\xb6\xbfr\xdfz\xc3\x1c\x1e~\xa9^8\xff" + - "\xda{\xb2\x02\xca\xc7\xb2\xc4}$[\x00\xfc\xe4\xa9{" + - "\x8f\x0e\xbd\xbb\xfee\xa5\x133\xf5\xbc\xc7\xb2\xfbQ>" + - "C\xbc=\x8fe\xbb\xc9\xa2\xb1\x0d\xeb\xd8}\xbd__" + - "2\x85\xf2\xc5%\xf4\xf3\xbf\x96\xf8\xec\xc3w|\xe7\xa1" + - "\xa6\x8b\xdfy\xb9\xde\xa8\xa2o\x81\x9c\x85\xf2g9\xfa" + - "\xf9i\xeeq\x01\xd0\xfb\xcd\xd9?\xe7\x17W\xbdr\x01" + - "\x94/aJ\x8dq\x14Q\x00\xe8\xb9x\xd5j2\xd9" + - "\xa5\xab\xee\x04\xf4:\x9f\xfe\x93\xbf\xed/\xbf\xfd\xf3:" + - "\x8b\x90 \xf2f\xf9c\xf9v\x99~\x8d\xcb\xc4{\xef" + - "Wg\xf6o\xb9~\xf6\xcd\x86\x069'\xcf\xa2|\xc1" + - "\xe7~\xc9\xe7\x16.\xaa\x1dw\xfd\xdb\xd7\xdeI\xc5\xe7" + - "\x9a\xfc/\x112\xde\x96mwL\xb5~\xf3\xddw\xd3" + - "\xf1\xb9\"\xef\xfb\xf1\xcf\xf2\xe4\xa6\xf3\xd2C\xf2\xf3\x8f" + - "\xfd\xcd{\xf4\x90X\xef\xa7\x9d\xf9\xed(\xef\xcd\xd3\xcf" + - "j\xde\xd77\xce\x93FQ\xa4]\xd3\x8b\xf2\xcc5$" + - "\x97{\x0d\xc9\xb5fW\x1f\xdfq\xcbm\x1f\x80\xd4\xc9" + - "\xe6d\xfd\xb3\xc4\xf9\x12q\xf6\xbcx\x8d\x88\xf2\xde\xa5" + - "\"\x80\xf7\xed\xca\xf6\x0b\x1f\x0d<\xf6\xbf\xf5\x97\xfb\x0a" + - "\xdd\xbe\xb4\x17e\x8d\xf8z\xf8R\xdfU=7\xff\xe5" + - "\xa5\xe3\x7f=\xf0\xd1\xbc\xdb\xcfu\xf4\xa3\xfcb\x07\xc9" + - "\xf1B\xc7\xd7\xe5K\x1d\xfe\xe5\xdfZ\xbfu\xed\xf2\x17" + - "?N[\xe2\xcd\x8e\x8f\xc9\x12\xefw\x90%&n\xf9" + - "\x9f\xaf_\xff\xed\x7f\xfe\xb8\xce=>ck\xe7\x0d(" + - "wt\xd2\x8dWw\x16\x00?\xdc\xf8\xfd7:s\x9d" + - "\xbfn$\xe8\xda\xce)\x947\x13o\xcfP\xa7/\xe8" + - "m\xbf\x03\xb6'\x99\x07" + - "\x88\xed\x90\xbc\xd9<\xff\xcd\xc0\x16\xf4&\xb7V\xb9\x86" + - "\xc5+\x9a\xedp+ _W(\xaa\x96Z\xb5\xd3\x0f" + - "\x9e\x04P\xda\x19*\xcb\x04\xf4*\x96Z\xe2En\xa1" + - "f\x96\xb7\xa8\x869\xcax\x09\x9b@\xc0\xa6\xd4\xa3\x0d" + - "\x1c\xb1Q\xd5t^\x0e\xb4[U\xea\xf6\xffW\xdaY" + - "\xa6\xcd\xf3\xfcG\xd4\xed\x00\xca.\x86\x8a.`\x16?" + - "\xf7\xf2T\xfe$m?\x802\xc9Pq\x04\xcc\x0a\x9f" + - "yy\xdfk{\x97\x03(:CeZ\xc0,\xfb\xad" + - "\x97\xa7\"#\xb9S\x00\x8a\xc3P\xb9K@\xcfvk" + - "dS\x1b\x98ia{\x12\xca\xa1ux\xb9B\x966" + - "\xa0\xc0Kdhl\x8f\xd09`\x10\xcb\xe6$\xb6'" + - "\xc5'\xb5\xf0y?" + - "4K\xceu\xc5\xeey\xce\";\xb61T\x96\x0a\xe8" + - "\xd5\xe8+w80\xcb\xc6\xf6\xa4\xa8\xd7I\xdb \x9c" + - "\x07\xe8\xdf\x81\xe0\x95bx\x8be\xfb\xe1\xac,\x8d\x1f" + - ";A\x8f=\xccP\xf9\x81\x80\x12b\xe0\xb3\xc7,\x00" + - "\xe5Q\x86\xcaY\x01Q\x08<\xf6\xe4i\x00\xe5,C" + - "\xe5\xef\x05\x94\x98\x108\xec\xd9\x1b\x00\x94\xa7\x19*\xbf" + - "\x10P\xca\xb0<50\xd2\x05\x0a\xb6_0T\xde\x12" + - "Pj\xca\xe4\xb1\x09@zs5\x80\xf2\x1aC\xe5\x1d" + - "\x01=3\xc8/R\xca\xc1,\x08\x98\x05\xf4J\xba\xe9" + - "\x96't\x15\xba-^\x1eZ\x1f\xd3\x0d\xb7Z\xb4\xf8" + - ">\x0dM\xd7\xees\x1c^\x15k\x8e\x8d\xcd `3" + - "`\xceQ+6.\x01,2\xc4\xf6\xa4\xd0\x01\x121" + - "\xbe\x13-^\xde\xc6-[c\xa6\x81m `\x1b`" + - "\xb7]2k\x1c\xdb\x93\xdayy\x9b\x8e\x84\xd1C\xb1" + - "\x13&\x82iibE3\x946\x96Y\xe6y\xa1\x01" + - "7\x90]\xd61T6\x09\xd8\x85\x9f\x13\x99l84" + - "\x02\xa0\x0c2T\xc6\x04\xec\x12>#2YQ!\x1f" + - "\x14\x19*;\x04\xccM:N\x0d\xdb\x93\xea\x18\x0au" + - "'\xdfm\x9b\xa5=\x1c\x90\xa0\"\x86\xea\xf0\xebd\x08" + - "]\xc0\xf42\xb6'\x9dl\x9dF\xacA\x94\xf8\x01R" + - "p6X\x96i\xf9\xa8\x1a\x87\xc6\x86\xd5\x89\x12Qd" + - "\x0cmO4\x90\x84u\x81Z\xca\xeeD\xfe\xee\x92\xea" + - "\xda<\xb2\xb1gq\xc7\x9a\xe9\x9bp\x80q+\xc6\x18" + - "{\xd2t\xf5\xf2\x08\x07\xd1\xb1f\x10A@\\\x18y" + - "\xd6\x9b\x83)\x93\x07!\x9c\x92\x93dZ\xcfP)&" + - "rn&\xda&\x86\xcam$gh\xfeq2\xff\x18" + - "C\xa5&\xa0\xa7S\xee\x1a\x83&0\xdb\x89\xc5\x0d\x88" + - "E\xd3\x0fL\x11\x04\x14\x01=\xb7f;\x16W\xab\x80" + - "q\xa4\x11\xff\x92/\x00\xd1uPQTs~\xce7" + - "\xd6!N\xc3\xcd\xc3i%\xc2<\x1c\xefO\x8c\xdd8" + - "\x91&M\xdb1\xd4*\x07\x80H\xb1\x83f\x8d0\x92" + - "\x10$n3\xebb\xe3\x8bW\xb6\xa0\xca\xcc\xa9k\xa7" + - "Se\xa6\x14\x9eF\xff\xf8\x80i\x88\x13Z\x05\xdb\x93" + - "^\xabN\x80\x06~\xefs\x9dIn8Z\xc9\x7fp" + - "\x9e\xdf\x97'\xf1\x19\xdblhu\xca\x90\x91\xcd6\xef" + - "N\x0c)\xee\xe131\x04\xf0\xaa\xaa\xe9\xb1\xf7Ck" + - "\xf6\x81\xf8\x8d\x84g\xa1\xe4\x19%\x04\xf1\xa5\xf2m\x80" + - "\xa9\xae\\\xca\xae\x06\xa1{\x9f\xaa\xbb|\xc1\xe6&\xac" + - "bA\x0d+\x04\x06\xa6\x0b\xf3\xb1\x9a\xdf\x9c\x05P\xee" + - "b\xa8<\x90R\xf3\xfe\x87\x00\x94\x07\x18*\x0f\xa7\xd4" + - "\xff\x13D?\xef\x03R" + - "\x7f\x00H\xe7|\x00{\x9a\xe8\xcf\x13 \xb9\x96>\xea" + - "X\x9a\x01XI\x82\xb5T\xfb\x06\xe7\xb5>\xc8\xe9\xda" + - ">\x1e\x17\x8b\xb2\xa6\xea\xeb]U\x87\xeeQG-\xed" + - "I\xdad\xdd\x1eT\x8d\xb2\x8d\x93\xea\x1eN%FL" + - "\x17aG\xb7\xb7qK\x9b\x00L\x1a\xeb\xb8\xad\xc9\x15" + - "M\xb3\xbe\xdb\xf1\xfb3n\x05h\x16\x7f\xab\xaa\xd3C" + - "e\x9d\x0f`\xd4\x9a0#)q\x1a}1\x0d\x03\x83" + - "~aL\xeb\x9e\xdb\x08\xd4\xc2V=j(\xc6\x0au" + - "\x9d\x02\x9f\xae\xf1\x923`\xa2\xe1h\x86\xcb\xe7]P" + - "\x9at\x8d=\xbc\xbc\x01\x8d\x92Y\xd6\x8c\x0a\xcc\x9b\x11" + - "\xd8\xef\xdaN\xa4:\xa8\x96\xb0%\x8b\xd7\xed\xd2\x0a\xea" + - "\x070\xec\x07\xa4\xded\xca.\x94\xfcS\x05\x8b\xabv" + - "R\x1a\x16z-\\F\x05IF\xaf\xb5\xb3&\x80x" + - "y\x8d\xd1\xceO\xda\xbb\x1f\x04I\x131Y\x95b\xb4" + - "\x19\x95vZ H\xe3\"\x0a\xf1\xdf\x0c0\xda\xf7K" + - "C\xb3 H\x1bDd\xf1\xa2\x1f\xa3\x8d\x9b\xb4\xb6\x1f" + - "\x04i\xa5\xe8ES\x05\x14\x02q\xd6\xa1\x17%>t" + - "\xfb\xa9\xbf\x0e\xbdhO\x81\xd1\xf4\x01\xb0\x0e\x0f\x86\xf5" + - "h\x1d\xa6\x97[\xecw\x8d\x00\x8d\xfbR\xc2\xc8i\x86" + - "\xca\xe1\x04#\xef\xa6^\xf50C\xe5hj\xec:\xf2" + - "T\xba-\x0d7\x07'\x0e\x85{\x87\xf3\xa9\xcd\xc19" + - "\xeaU\xcf3T^\x13\x92B\x1d\x85]\xb4\x0fB\xd3" + - "\x8a\xe6\xc0\x05\xd6Bap\x86-c\xfdr\xc8+\x9b" + - "\x93~K\x89\xc1U6$\x88\x9d\xde\x18-Im\x8c" + - "0\x9a@\xc59\x00\x9f\xde\x1f-Y\x183\xe7\xccS" + - "\xe1\xd8@Q\x13\xfdE\x03\xa3\xbf-I\x12y?+" + - "z\xd1\xcc\x85Q\xb9\"\xe7\xa5]\xf6\x05\x07\xcf\x11\xde" + - "m_I%\x88\xb6\xcc\x97\xdf\x1f\x04\xef\xe4(\xd8\xe2" + - "9(\xb8w*\xb5\xc5\xd2\xcdp\x84\xcbmIU\xed" + - "\x85l\x15\x08\x1cu\xbe9:\\\x17~\xcb\x93\xf0\x8b" + - "\x1b\x84\xbb\x97'\xc3@<\x16\xdd3\x1c\x06\xe5\xa3q" + - "\xa7+=2\x9bl\xb8\xe2\xf0{r8\x19\x8bDn" + - "Y\x91\x9c\xa2k%\xb0\xa9\x9b\x95M\x9a\xc1m\xea\xfd" + - "\xea\xb6\x015nUU\x83\x1b\xe8\x10\x18\xb9\x16!\xea" + - "\\\xe4\x1aZ\x9fj\x19\x17R\x7f4\x0c\xf6 \xd6\xc3" + - "\xf2\x9a\x1a}O\xa7\xd60\x91\xf2\xcas\xe1zcW" + - "J\xf9\x9d4\xfa\xee`\xa8L\x0a\xe8\xa9\xaec\x8e\xd7" + - "\xca*:|\xa3\xc5\xf7\xba\\4J3\xc9\x00G\xa3" + - "L\xc9\x1e\xc7\x1a5\x9d\x1b-^\xd8\xeb\xf24C\xb4" + - "8\x06Q3\xcb\xf36\xc6\x0d\x9a\xad[\xf9\xeeQ\xb3" + - "\xb4\x87;s\x16\xea\x01\\F\xaa\xa8#\xc9\xd68\xd2" + - "D\x1bI\xcdj\x11\x8c\xec\xa5\x80\xaa1T\x0e\xa4`" + - "df6qx\xe3\xea\xfa\xfb)\x88\x0b(\xd9p\xab" + - ";R\xe0W\x94h\xc9_I.\xdfr\x85{\x82\xb0" + - "c\xbd\x92]\xc8\x9ce]\x18\x10\xcaT\xb2?\xf2\x83" + - "\xbc=\xf9sn(\x83\x1d\xb6\x8e\xc0&\xcc\x06]a" + - "0U\x0d\x98\x10Bk\xfdF\xe7\xff\x02\x00\x00\xff\xff" + - "\xd4\xcdz3" +const schema_db8274f9144abc7e = "x\xda\xacY{p\\\xe5u?\xe7~\xab\xbd\x96-" + + "y\xf7r\x15\x88\x84=j<0\x09\x04S\x8cK\x1b" + + "\xd4N\xd6\x92,Gr\xfc\xd8O+\x1b0\xf6\x8c\xaf" + + "w?\xad\xae}\xf7\xde\xf5}\x18\xc9cb\xf0\x98\x02" + + "*\x04C\xf0\x0cv C\xdc\xba<\x06\xca#0\x1d" + + "\xa8\x9d\x92N)\xd0\x94!L\xa0S\xb7\xc9\x1f\x04<" + + "\x0dL2\x04B\x87\xd2\x01n\xe7\xdc\xb7VB\xb6;" + + "\xfd\x07\xae\xcf\x9e\xef\xfb\xce\xf3w\x1e\xba\xe2\xe7\x0bV" + + "I+\xda\xfe\xbe\x03\x80\xdf\xdb\x96\xf7\xff\xac\xf1\xda\xb1" + + "?>\xfc\xd3\x83\xa0\xf4H\xfewN\xac\xed\xfa\xc4=" + + "\xf0\x1f\x00\xb8r(\xbf\x17\xd5\xeb\xf22\x80\xba)\xbf" + + "\x11\xd0\xff\xf9\x15\xfb\xde\xd9\xfe\xfb\xbbo\x03\xa5\x07S" + + "\xce\x9c\x0c\xb0\xb2\x91\x9fF\xf5\x96\xbc\x0c\xcc\x7f\xe0\xfa" + + "\xae\x7f\xc6\x07?\xbe\x1b\x94\xaf!@\x1b\xd2\xcfZ~" + + "\xa1\x04\xa8N\xe5K\x80\xfek\x97\x9dx\xfe\xd0\x8fn" + + "\xfd>\xf0\xaf\"Bx\xfeH\xfe\x7f\x10P}<`" + + "\xf8\xe0\xaf\xbe\x9e{\xfc\xb5\xf3~\x100\xf8\xc7_\xbf" + + "\xe6\xe9C?\xfa\x83\xf7`\x93$c\x0e`\xe5\x9by" + + "\x9bx\xdf\xca\xff'\xa0\x7f\xef\xbf\x9d\xdc\xd0\xb8\xfb\xe8" + + "1P\xbe\x1a\xdf\xf5\x13Y\x92 \xe7_\xf5\xef\xa77" + + "\xae\x7fz\xfc\xa1\xf0\x97P\x8eg\xe5\xa7\xe9\xe8\x8b2" + + "=\xf3\xf2\x0d\xc5;\xfa\xff\xe4\xae\x87\x80\xf7`F\x9f" + + "6\xd2x\xe5\xbb\xf24\xaa\xb8\x80>?\x93\xefB@" + + "\x7f\xfa\xea\x93\x9b\x7f\xff\xe7\xce\xa3\xc0\x97c\xce\xff\xc7" + + "\xdb\xdf\xdes\xc9#\xe3/\x05R1\x80\x95\x8f\xb7\x1f" + + "\xa3\xabO\xb6?\x01\xe8w\xfe\xdd\xa5\x1b\xeezg\xdd" + + "Stu\xc6\xa8\xa1\x10\xdb\x16\xf6\xa1\xdaXHv\xd5" + + "\x17\x12\xf7\xcf.\xdb\xfc\xe3\x1f?Y\x7f\xaaU\x10\x89" + + "\xb8\xdb\x17\xadEu\xe9\"\xe2\xee^D\xdc_\x1a\xc1" + + "_\xbc\xb0\"\xf7\xb7\x91^\x8c\x98^]\xf4^`\x92" + + "\x80\xe1\xfaO\x9f\xfd\x87\xa1\xf7\xdfx.\xeb\x80\x9b;" + + "$r\xc0\xe1\x0eR|\xe9o\x07:\xcd\xf7\x0f\xbc0" + + "\xd3\x8f\xe1M';\xd6\xa2\xfaz\x07=\xf7j\xc7\x13" + + "\x80\x1f?z\xeb\xa1\x91\xb7W\xbf\xc4{0\xd7\xaa\x88" + + "\xde\xb9\x17\xd5\x1b;\xe9s\xaa\xb3\x97l\x94X\xa5\x85" + + "=\xd0\xe4\x91\xc5;Q=\xb9\x98>\x9f[\x1c\xb0\xaf" + + "\xbd\xfe{\xf7\xb4\x9d\xfe\xdeK\xadf\x92\x037\x16l" + + "T\xdf,\xd0\xe7\xeb\x85\x87$@\xbf\xe7\xc9?\xfd\x9b" + + "\x81\xda\xa9\x9f\xb6\xc8M\x97\xab'\xcf\xfbP}\xe5<" + + "\xfaz\xf1\xbc\x1b\x00\xfd[\xbf>\xb5w\xc3\xc5\xd3o" + + "\xb6\xda4\x10\xfc+\xea4\xaaW\xab\xc4}\x95J\xdc" + + "\xd2i\xad\xfb\xa6\x7f\xfd\xe6/2Qt\\\xfd\x15B" + + "\xce\xdf\xb0\xf9\xfa\x9d\xed7\xbe\xfdv6\x8a\x8e\xa8\x81" + + "\xb5\x1fW\xc9\x98\xcf(\xf7\xa8'~\xf8\xd7\xef\xd0C" + + "r\xab5_U\xb7\xa0\xfa\x16=\xb4\xf2\x97j\xa0C" + + "\x12\xcds\xf9\xfa\xd4\xf9}\xa8\xbe{>\xc9u\xfa|" + + "\x92\xeb\xaa\xed\xfdb\xeb7\xae}\x0f\x94\x1e6#7" + + "/\xbe\xa0\x0f\xd5\xab.\xa0C+.\x90Q}\x8b>" + + "\xfd\xef\xd6\xb7\xbc\xf2\xc1\xe0\x0f\x7f\xd7zy\xa0\xd0+" + + "t\xe4Tp\xe4\xcd\x0b\x02\xf3\xaf\\\xf1\x17\xbf=\xfc" + + "\x97\x83\x1f\xcc\xba\xfd+\xdd\x03\xa8\xae\xe8&9\x96w" + + "\x7fK\xdd\xd6\x1d\\\xfe\x9d\xd5\x1b\xaf^\xf6\x93\x0f\xb3" + + "\x96\x18\xea\xfe\x90,q]7Yb\xfc\x1b\xbf\xf9\xd6" + + "\xc5\xdf\xfd\xa7\x0f[\xdc\x130Nu_\x8a\xea\xed\xc1" + + "\x8d\xb7\x10\xf3\xfbk~\xf0FO\xa1\xe7\xa3\xb9\x04}" + + "\xa4\x9b\xe2\xa4;\x88\x93\xee@\xd0k\x7fu\xf4\x86\xd2" + + "\xf7?\xfa\x98\xf4b-\xc8\xf3n\xcf\x16T?\xeb\xa1" + + "\x9b?\xe9\xa1\xf0_\xf7\xd8\xa9oN\x1c~\xf9\x93V" + + "#\x04\x0e9~\xe1\x01T\x9f\xbb\x90\xb8\x9f\xbd\x90\xf0" + + "c\xdf\xfbG\x86\xef\xda\xfa\xd8\xe7Y\xad\x1eX\xf2|" + + "\xe0\xdf%\xa4\xd5\xce\xc3\xfb\xdc\xe1\xfb\xee\xf4\xe7J\x96" + + "W\x97\x0c\xa0\xfa\xcb%t\xdb\xa9%O\xc0r\xdf\xf5" + + "LS\x18v3W\xfd\xc3\xf8\xb3zyUk\x9a\xcd" + + "\xbe\xa1I\xddqu\xb3>\x16\xd0Ke\xcb\xd0\xabS" + + "eD\xde\x81\x12\x80\xb2\xb4\x0f\x00Q\xf9\xd2\x16\x00\x94" + + "\x14e\x00\xa0\xa4\xd7M\xcb\x16~Mw\xaa\x96i\x0a" + + "`Uw\xff\x0e\xcd\xd0\xcc\xaaH\x1ej\x9b\xfd\xd0\xb0" + + "0\x0c\xeb\x1a\xcb6j\x1bm\xbd\xae\x9b\x83\x969\xae" + + "\xd7\x01\xca\x88\xc91y\xf6\xb1AC\x17\xa6[\x11\xf6" + + "\x1e\xbd*.\xf7\x1c\x11\x9e\xf3l\xcd\xd5-\xf3\xa2Q" + + "\xe1x\x86\xeb\x00\xf0\x1c\xcb\x01\xe4\x10@\xe9\xec\x03\xe0" + + "\x0b\x18\xf2.\x09Kv\xc0\x80\xc54\xf3\x00\xb1\x08\xe9" + + "\x9b\xf9\xd9o\x86\xb6\xa07\x85}\xb9g\xda\xa2\xae;" + + "\xae\xb0C\xf2E\xa5\xb2fk\x0d'\xfb\xe0Q\x00^" + + "d\xc8\x97H\xe8\xd7m\xad*\xca\xc2F\xdd\xaam\xd0" + + "L\xab\xc2D\x15\xdb@\xc2\xb6\xcc\xa3s8b\x8d\xa6" + + "\x1b\xa2\x16jwy\xb57\xf8?/\xb2\\\x87\xef\x07" + + "\x8fh[\x00\xf8v\x86\xdc\x90\xb0\x13?\xf7\xbb\xa8H" + + ")\xfa^\x00>\xc1\x90\xbb\x12vJ\x9f\xf9]\x81\xd7" + + "v/\x03\xe0\x06C>)a'\xfb\xd4\xef\xa2R\xa0" + + "x;\x01\xb8\xcb\x90\xdf$\xa1\xefxM\xb2\xa9\x03\xcc" + + "\xb2\xb1\x98\x86rd\x1dQ\xab\x93\xa5M(\x89*\x19" + + "\x1a\x8b1\xe2\x86\x0cr\xcd\x9a\xc0bZ\"\xa2c\xb6" + + "\xd8#lG\x94\xa1`[\x93SXL\x91\xb7\xc5\xea" + + "\x9d\xe7j\xf5\xd8\xd1\xc9\xa9\xf9\xcf\x07\xa1Yu/*" + + "\xf7\xcer\x16\xd9\xb1\x83!\xff\xb2\x84~\x93~\x15\xae" + + "\x00f;XLKo\x8b\xb4s\x84\xf3 \xfdw0" + + "|\xa5\x1c\xddb;A8\xf3%\xc9c\xcf\xd2c\xcf" + + "0\xe4/H\xa8 \x86>;i\x03\xf0\x13\x0c\xf9\xcb" + + "\x12\xa2\x14z\xec\xc5c\x00\xfce\x86\xfc\x0d\x09\x15&" + + "\x85\x0e{\xfdR\x00\xfe/\x0c\xf9\xaf%Tr\xac\x8b" + + "\xda\x0c\xe54\x05\xdb\xaf\x19\xf2\x8f$T\xdar]\xd8" + + "\x06\xa0|@\x9c\xbfa\xc8\xff[B%\xdf\xd6\x85y" + + "\x00\xe5\xbf\xae\x04\xe0\xbfc\xc8?\x95\xd0\xb7\xc2\xa4#" + + "M]\xec\x04\x09;\x01\xfd\xaaay\xb5qC\x83^" + + "[\xd4FV't\xd3k\x94m\xb1GG\xcbs\xfa" + + "]W4\xe4\xa6\xeb`\x1e$\xcc\x03\x16\\\xad\xee\xe0" + + "b\xc02C,\xa6\xd5\x0f\x90\x88\xc9\x9dh\x8b\xdaf" + + "a;:\xb3L\xec\x00\x09;\x00\x0b\xa6\xd6\x10\xf1?" + + "z\xeb\xb6\xe55\xe3\x7f\xcdg\xeb\xd1(\xaa(\xa6\xa2" + + "\x04\xb1l]\xae\xeb&\xef`\xb9%\xbe\x1f\x19v\x88" + + "\xac\xb0\x8a!_'\xe1R\xfc\x9c\xc8d\xdb\x91Q\x00" + + ">\xcc\x90\x8fI\xb8T\xfa\x8c\xc8d]N\xbe)3" + + "\xe4[%,L\xb8n\x13\x8bi\xd5\x8c\x02\xe0\x06\xb1" + + "\xc3\xb1\xaa\xbb\x04 AH\x02\xe1\xd1\xaf\x13\x11\xa4\x01" + + "3jXL\xfb\xd0\x96\xe8asDO\x108%w" + + "\xc8\xb6-;@\xdb$d\x86\xaeL\x95\x88#fd" + + "K\xaa\x81\"\xad\x0a\xd5\xe2;R\xf9{\xab\x9a\xe7$" + + "\x96\xf5m\xe1\xdaS\xfd\xe3.0a'\xd8\xe3LX" + + "\x9eQ\x1b\x15 \xbb\xf6\x14\"H\x88\xf3#\xd2jk" + + "8c\xf20\xb43r\x92L\xab\x19\xf2r*\xe7z" + + "\xa2\xadc\xc8\xaf%9#\xf3o\"\xf3\x8f1\xe4M" + + "\x09}\x83r\xda\x1c\xb6\x809n\"nH,[A" + + "l\xca \xa1\x0c\xe8{M\xc7\xb5\x85\xd6\x00L\x82\x8d" + + "\xf8\x17\x9f\x03t\xb7@HY+\x04X0\xb7\x0eI" + + "z\xae_\x9bU\"\xca\xcfM\x03\xa9\xb1\xe7\xce\xa5\x09" + + "\xcbq)\xbc\x01 Vl\xbf\xd5$\xec$dIZ" + + "\xca\x96\xd88\xf7\x8a\x17V\x9f\x19\xf5\xeeX\xa6\xfcT" + + "\xa3\xd3\x18\x1c\x1f\xb4Ly\\\xafc1\xed\xc1Z\x04" + + "\x98\xc3\xef\xfd\x9e;!LW\xaf\x06\x0f\xce\xf2\xfb\xb2" + + "4>\x13\x9b\x8d\\\x991dl\xb3\xf5;RC\xca" + + "\xbb\xc4T\x92\xf8\xa2\xa1\xe9F\xe2\xfd\xc8\x9a\xfd \x7f" + + ";\xe5\x99\xb7e\x89jSX\x99J\xa1yH\xc8\xae" + + "D\xc8\x1b\xa7\x01\xf8M\x0c\xf9\x1d\x19!o\xbf\x07\x80" + + "\xdf\xc1\x90\xdf\x97\x11\xf209\xf6\x10C~?\x01/" + + "\x0b\xa1\xe1\x08Y\xf4~\x86\xfca\x091\x17\xe2\xeeq" + + "\xc2\xdd\x87\x19\xf2g\xa4\x00 \x87\xfb\x07-\x13#!" + + "\x1c\x80\x18\x1e\xfd\x09\xa1\xd9\xee\x0e\xa1\xa1;b\xba\xc2" + + "\xde\xa3\xa1\x11\xe7\xe0~Wo\x08\xcbs\x93\x9clh" + + "\x93A\xdd\xc7\xdapxJ\xd6\\\x07\xdbA\xc2vJ" + + "\x01G\xd8\x83\xb6\xa8!yC3\xca\x1as'\xce\xc6" + + "@3\xf1\xb20\x87y\xa8k\xd8\xc7\x90\xdfF\xb9\x8b" + + "\x99!R\xb9\xa5\x0f\xa4 uI\xe7\xc6@\xda]\x04" + + "U\x89j\xcd\xee{\xd26\"\xa8JTkn<\x9a" + + "\x1a<\x12m\xd8\x82R\x98\x12\xb1\xcc\xa5\xd0\xd5\xfb\x09" + + "\x9et\x91\xea\x19\x15k\x1d-s,0\x10\xa6\x16\xaa" + + "Z\x8d\xa6-\x1c\x07u\xcb\xe4\x9ef\xe8\xcc\x9dJ\x0e" + + "\xcek\x03\xca\xfd0g66{\x03'\x91\x11\xae\x88" + + "\x8d\xa0\xf6\xe3Z\x80\xca*dXY\x87i\x98\xa8#" + + "8\x00PYM\xf42\xa6\x91\xa2\xae\xc7\x1e\x80\xca0" + + "\xd1\xc7PB\x0ccE\xe5\xf8(@e\x8c\xc8\xdb1" + + "\xad\xd3\xea\xb6\xe0\xfa\xadD\x9f\xc0\xb4T\xab\x02/\x05" + + "\xa8l'\xfa>\xa2\xe7\xa5\xc0\x82\xea\x14\xee\x04\xa8L" + + "\x12\xfd \xd1\xe5\xb6.\xea\xfa\xd5\x9b\xd1\x06\xa8\xdcD" + + "\xf4;\x88\xbe\xe0\xcb]\xb8\x00@\xbd=\xa0\xdfF\xf4" + + "{\x89\xde\xde\xdd\x85\xed\x00\xea\xddx\x00\xa0r\x88\xe8" + + "\xf7\x13}!v\xe1B\x00\xf5\x08\x1e\x05\xa8\xdcO\xf4" + + "\x87\x89\xbe(\xdf\x85\x8b\x00\xd4\xe3\x81<\x0f\x12\xfd1" + + "L\x00d\xa4\x96\xc51\x0a'=-\xe3\xccr\x920" + + "\x14\xd1\xfc\x80!\xc8\x96\xad\x02\x0d\x10XH\xf77\x80" + + "X\x00\xf4\x9b\x96el\x98\x89\x8fg\xea$\xa2\xb0\x80" + + "\x82e\x8e\xd4\x92\xfc\x0a\x83h\x9d\x05\xbdU\xcd\x18I" + + "\x1b\x08\xdd\xe9\xf7\\\xcbkBoMsE-\xa9p" + + "\xb6g\xae\xb1\xad\xc6\x18\x0a\xbb\xa1\x9b\x9a\x01\xc9/\xf3" + + "\xc5V\xc1\xf3\xf4\xda\xacd\x93Z\x03\xad\xb7\xd97\xa6" + + "\x05\xd9\xb5 \xc9\xaeK\xa8\x0d\xb9\x88!\xbf\"\x03>" + + "\xcb\x09!\xbf\xc6\x90\xff\x91\xd4\xd2\x06\xed\xd1\x0cO\x9c" + + "M\x1b\xb4\xa9\xa5\x14\x84-q\x88\xcf\x99\xd7\x07\xd2\xd7" + + "\x93\xc7\xa9\xe3\xbc\x8c!\x1f\x96p\xbf\xe3U\xab\xa4t" + + "l\x85\xf1h\xf0\x80^\xba;\xe3\x8fd'\x10\xf9\xe3" + + "l\xcbn]\xb8\xe1\xd7\x889nQ\xbd\x92\xb5\x86\xf3" + + "\x7f<=*\x9c\x02\xf5\xfdg\x1c\xef\x92)\xff\xcc\xf5" + + "mxl\xac\x9c\xce\xa0,\x04\xc7,.\x8cfq!" + + "\x85\x85\x9d\xd9\xf4\x8f\xdb0\x95\x07yX&\xfaVL" + + "\x9bw\xf5:<6#\xffs\xfd!.\x88\xe0\xfa\x1a" + + "\xd1\x9b\x01.`\x88\x0b\x8d\xe0~\x83\xe8\x93Y\\\xf0" + + "pz&.\xb0\x18\x17(\x9f\x0f\x12\xfdP\x80\x0b\xb9" + + "\x10\x17\xee\xc4\xa7g\xe4\x7f{[\x88\x0bG\xf0\xf9\x19" + + "\xf9\xbf0\x1f\xe2\xc2\xf1\x80\xffa\xa2?\x13\xe0\xc2@" + + "\x88\x0bO\x058\xf2$\xd1O\x10.x\xb6Qqm" + + "\xdd\x04\xac\xa7\xc1Zm~[\x88f?\x14\x0c}\x8f" + + "H0\xbb\xa6k\xc6jO3\xa0\xb7\xe2j\xd5]i" + + "\xafi8\xc3\x9aYspB\xdb%\x08\xe9\xe5l-" + + "t\x0dg\xb3\xb0\xf5q\xc0\xb4;Mz\x83B\xd9\xb2" + + "Z[\x86\xa0\xc9\x11v\x08*\xc9o\x0dmr\xa4f" + + "\x88A\x8c;\x04f\xa6\x95F\xa7_,\xd3\xc4\xb0l" + + "\x8f\xe9\xbd3\xebq3\xeaw\xe3\xba>Vj)\xd8" + + "b\xb2)\xaa\xee\xa0\x85\xa6\xab\x9b\x9e\x98uAu\xc2" + + "3w\x89\xda\x10\x9aU\xab\xa6\x9bu\x98\xd5h\xb3/" + + "\x1a\xfd3\x8dL\x90\xcd\x98\xd98+\x97PY\xc6\xa8" + + ",+}\xe9\x08[\xaa\x06\xa7J\xb6\xd0\x9c\x14\xa1\xe7" + + "{-\xda\xf4\x84IF\xaf\x15Y\x1b@\xb2\xbf\xc5x" + + "\xa1\xa6\xec\xde\x0b\x92\xa2\xcb\x98\xee!1^;*\xdb" + + "l\x90\x94M2J\xc9\xda\x1c\xe3\x95\xb722\x0d\x92" + + "2$#Kv\xdd\x18\xaf\xb3\x94\xab\x07@R\x96\xcb" + + "~\xdc\x9aC)\x14g\x15\xfaq\xe2Co\x90\xfa\xab" + + "\xd0\x8f\x97\x00\x18\xb7\xf0\x00\xabp\x7fT\x16Vav" + + "s\xc4\xbe\xa8\x8f\x9e\xbb=$\x8c\x9cd\xc8\x0f\xa6\x18" + + "y3\xb5\x8c\x07\x19\xf2C\x99\xd9\xe5\xceG\xb3\xdda" + + "4\x96\x1f9\x00\xc0\xef\x0b;\xc1d,\x7f\xeaX4" + + "\xe9\xffLJ\xebe\x1cv\xf1\xb2\x05-;\x1e\xa6\xe6" + + "\xd9\xb9D\xc1\x19un\xad\x9b\x17\xbffM\x04\x9d\x1d" + + "\x86W9\x90\"vv\x1d\xb38\xb3\x8e\xc1x\x8c\x93" + + "g\x00|v9\xb3x~\xcc\x9c1\x94\x04\x15'\x17" + + "DM\xbc\xd4\xc7\xf8\xcf+\x8aB\xde\xef\x94\xfdxp" + + "\xc1\xb8\\\x91\xf3\xb2.;\xc7\xe9mT\xf4:gS" + + "\x09\xe2\x15\xee\x99\x87\xf0\xf0\x9d\x02\x05[\xa8Pr\xef" + + "\xce\xcc\x8a\xc8\xb0\xa29\xa8\xb0!S\xb5\xe7\xb3U(" + + "p\xdc\x80\x16\xe8pK\xf8-K\xc3/i\x10n^" + + "\x96\xf6\xe4\xc9tr\xcb\xda((\x1fL\x1aN\xe5\x01" + + "\x0a\xd4\x07\x19\xf2\xc72\xe1\xf7\xc8\xdat:\x91\x85m" + + "\xc7r\xca\x9e\x9d\xc2\xa6a\xd5\xd7\xe9\xa6p\xa8\x05k" + + "\x19\xa9\x9b\xc2nh\xa60\xd1%0\xf2lB\xd4\x99" + + "\xc85\xb2:\xd3\xb9\xcd\xa7~%\x0a\xf60\xd6\xa3\xf2" + + "\x9a\x99\x1f\x8fev\x19\xb1\xf2\xfc\xf9hG\xb0=\xa3" + + "\xfc6\x9a\x1f\xb72\xe4\x13\x12\xfa\x9a\xe7Z\x9b\x9a5" + + "\x0d]\xb1\xc6\x16\xbb=!\x9b\xd5\xa9t\x8e\xa2\x89\xa2" + + "\xeal\xc2&\xf5~klQ\xda\xed\x89,C\xbc\x95" + + "\x05Y\xb7j\xb3\xd6\xb1s4[\xd7\x88\x1d\x15\xab\xba" + + "K\xb83\xb6\xd5!\\\xc6\xaah\xa3\xe9J6\xd6D" + + "\x1f\xcd\x8cL1\x8c\xec\xa6\x80j2\xe4\xfb202" + + "5\x9d:|\xee\xea\xfa\xffS\x10\xe7Qr\xce\x95\xe9" + + "hI\x9cU\xa2\xa5\x7f\x828s\xcb\x15\x8d\xebQ\xc7" + + "z6\x0b\x85\x19\x1b\xaf( \xf8\xcet\x09\x13\x04y" + + "1\xfd\x8bf$\x83\x13\xb5\x8e\xc0\xc6\xad9\xba\xc2p" + + "\xb8\x19\xb4 \x82\xd6\xd6\xb5\xc8\xff\x06\x00\x00\xff\xffX" + + "t1W" func init() { schemas.Register(schema_db8274f9144abc7e, @@ -3944,11 +3810,9 @@ func init() { 0xb70431c0dc014915, 0xb9d4ef45c2b5fc5b, 0xc082ef6e0d42ed1d, - 0xc54a4a6fd4d87596, 0xc744e349009087aa, 0xc766a92976e389c4, 0xc793e50592935b4a, - 0xc9c82ee56583acfa, 0xcbd96442ae3bb01a, 0xd58a254e7a792b87, 0xdc3ed6801961e502,