From 395e1db489769108fe279b75737213a2b81ba0c4 Mon Sep 17 00:00:00 2001 From: Jeffrey Picard Date: Tue, 9 Nov 2021 19:39:13 -0500 Subject: [PATCH 01/12] UDPServer / ip address resolution Got the UDPServer ping/pong protocol working internally, only tested against other running go hub servers. Should in theory work with python server and clients, but still need to test that. Also switched to serving udp on the same port as grpc, and taking that into account when pinging other hubs with udp. Unit test for udp ip address lookup. --- server/args.go | 4 -- server/federation.go | 92 +++++++++++++++++++++++++++++++-------- server/federation_test.go | 65 ++++++++++++++++++++++++--- server/server.go | 18 ++++---- server/udp.go | 9 ++-- 5 files changed, 148 insertions(+), 40 deletions(-) diff --git a/server/args.go b/server/args.go index b0374ba..beff48f 100644 --- a/server/args.go +++ b/server/args.go @@ -19,7 +19,6 @@ type Args struct { CmdType int Host string Port string - UDPPort string EsHost string EsPort string PrometheusPort string @@ -39,7 +38,6 @@ type Args struct { const ( DefaultHost = "0.0.0.0" DefaultPort = "50051" - DefaultUdpPort = "41119" DefaultEsHost = "http://localhost" DefaultEsIndex = "claims" DefaultEsPort = "9200" @@ -88,7 +86,6 @@ func ParseArgs(searchRequest *pb.SearchRequest) *Args { port := parser.String("", "rpcport", &argparse.Options{Required: false, Help: "RPC port", Default: DefaultPort}) esHost := parser.String("", "eshost", &argparse.Options{Required: false, Help: "elasticsearch host", Default: DefaultEsHost}) esPort := parser.String("", "esport", &argparse.Options{Required: false, Help: "elasticsearch port", Default: DefaultEsPort}) - udpPort := parser.String("", "uspport", &argparse.Options{Required: false, Help: "udp ping port", Default: DefaultUdpPort}) prometheusPort := parser.String("", "prometheus-port", &argparse.Options{Required: false, Help: "prometheus port", Default: DefaultPrometheusPort}) esIndex := parser.String("", "esindex", &argparse.Options{Required: false, Help: "elasticsearch index name", Default: DefaultEsIndex}) refreshDelta := parser.Int("", "refresh-delta", &argparse.Options{Required: false, Help: "elasticsearch index refresh delta in seconds", Default: DefaultRefreshDelta}) @@ -125,7 +122,6 @@ func ParseArgs(searchRequest *pb.SearchRequest) *Args { Port: *port, EsHost: *esHost, EsPort: *esPort, - UDPPort: *udpPort, PrometheusPort: *prometheusPort, EsIndex: *esIndex, RefreshDelta: *refreshDelta, diff --git a/server/federation.go b/server/federation.go index e6f31cd..cebb5ba 100644 --- a/server/federation.go +++ b/server/federation.go @@ -4,6 +4,7 @@ import ( "bufio" "context" "log" + "math" "os" "strings" "sync/atomic" @@ -66,6 +67,19 @@ func (s *Server) getNumSubs() int64 { return *s.NumPeerSubs } +// getAndSetExternalIp takes the address of a peer running a UDP server and +// pings it, so we can determine our own external IP address. +func (s *Server) getAndSetExternalIp(msg *pb.ServerMessage) error { + myIp, err := UDPPing(msg.Address, msg.Port) + if err != nil { + return err + } + log.Println("my ip: ", myIp) + s.ExternalIP = myIp + + return nil +} + // loadPeers takes the arguments given to the hub at startup and loads the // previously known peers from disk and verifies their existence before // storing them as known peers. Returns a map of peerKey -> object @@ -73,6 +87,33 @@ func (s *Server) loadPeers() error { peerFile := s.Args.PeerFile port := s.Args.Port + // First we make sure our server has come up, so we can answer back to peers. + var failures = 0 + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + +retry: + time.Sleep(time.Second * time.Duration(math.Pow(float64(failures), 2))) + conn, err := grpc.DialContext(ctx, + "0.0.0.0:"+port, + grpc.WithInsecure(), + grpc.WithBlock(), + ) + + if err != nil { + if failures > 3 { + log.Println("Warning! Our endpoint doesn't seem to have come up, didn't load peers") + return err + } + failures += 1 + goto retry + } + if err = conn.Close(); err != nil { + log.Println(err) + } + cancel() + + f, err := os.Open(peerFile) if err != nil { log.Println(err) @@ -97,19 +138,22 @@ func (s *Server) loadPeers() error { } // If the peer is us, skip log.Println(ipPort) - if ipPort[1] == port && localHosts[ipPort[0]] { + if ipPort[1] == port && + (localHosts[ipPort[0]] || ipPort[0] == s.ExternalIP) { log.Println("Self peer, skipping ...") continue } + srvMsg := &pb.ServerMessage{ Address: ipPort[0], Port: ipPort[1], } log.Printf("pinging peer %+v\n", srvMsg) - err := s.addPeer(srvMsg, true) + err = s.addPeer(srvMsg, true, true) if err != nil { log.Println(err) } + } log.Println("Returning from loadPeers") @@ -133,20 +177,18 @@ func (s *Server) subscribeToPeer(peer *FederatedServer) error { defer conn.Close() msg := &pb.ServerMessage{ - Address: s.Args.Host, + Address: s.ExternalIP, Port: s.Args.Port, } c := pb.NewHubClient(conn) - log.Printf("%s:%s subscribing to %+v\n", s.Args.Host, s.Args.Port, peer) + log.Printf("%s:%s subscribing to %+v\n", s.ExternalIP, s.Args.Port, peer) _, err = c.PeerSubscribe(ctx, msg) if err != nil { return err } - s.Subscribed = true - return nil } @@ -175,11 +217,11 @@ func (s *Server) helloPeer(server *FederatedServer) (*pb.HelloMessage, error) { msg := &pb.HelloMessage{ Port: s.Args.Port, - Host: s.Args.Host, + Host: s.ExternalIP, Servers: []*pb.ServerMessage{}, } - log.Printf("%s:%s saying hello to %+v\n", s.Args.Host, s.Args.Port, server) + log.Printf("%s:%s saying hello to %+v\n", s.ExternalIP, s.Args.Port, server) res, err := c.Hello(ctx, msg) if err != nil { log.Println(err) @@ -282,19 +324,31 @@ func (s *Server) notifyPeerSubs(newServer *FederatedServer) { // addPeer takes a new peer as a pb.ServerMessage, optionally checks to see // if they're online, and adds them to our list of peer. If we're not currently // subscribed to a peer, it will also subscribe to it. -func (s *Server) addPeer(msg *pb.ServerMessage, ping bool) error { +func (s *Server) addPeer(msg *pb.ServerMessage, ping bool, subscribe bool) error { + // First thing we get our external ip if we don't have it, otherwise we + // could end up subscribed to our self, which is silly. + if s.ExternalIP == "" { + err := s.getAndSetExternalIp(msg) + if err != nil { + log.Println(err) + log.Println("WARNING: can't determine external IP, continuing with ", s.Args.Host) + } + } + if s.Args.Port == msg.Port && - (localHosts[msg.Address] || msg.Address == s.Args.Host) { - log.Printf("%s:%s addPeer: Self peer, skipping...\n", s.Args.Host, s.Args.Port) + (localHosts[msg.Address] || msg.Address == s.ExternalIP) { + log.Printf("%s:%s addPeer: Self peer, skipping...\n", s.ExternalIP, s.Args.Port) return nil } + k := peerKey(msg) newServer := &FederatedServer{ Address: msg.Address, Port: msg.Port, Ts: time.Now(), } - log.Printf("%s:%s adding peer %+v\n", s.Args.Host, s.Args.Port, msg) + + log.Printf("%s:%s adding peer %+v\n", s.ExternalIP, s.Args.Port, msg) if oldServer, loaded := s.PeerServersLoadOrStore(newServer); !loaded { if ping { _, err := s.helloPeer(newServer) @@ -312,11 +366,11 @@ func (s *Server) addPeer(msg *pb.ServerMessage, ping bool) error { s.notifyPeerSubs(newServer) // Subscribe to all our peers for now - err := s.subscribeToPeer(newServer) - if err != nil { - return err - } else { - s.Subscribed = true + if subscribe { + err := s.subscribeToPeer(newServer) + if err != nil { + return err + } } } else { oldServer.Ts = time.Now() @@ -328,7 +382,7 @@ func (s *Server) addPeer(msg *pb.ServerMessage, ping bool) error { // peers. func (s *Server) mergeFederatedServers(servers []*pb.ServerMessage) { for _, srvMsg := range servers { - err := s.addPeer(srvMsg, false) + err := s.addPeer(srvMsg, false, true) // This shouldn't happen because we're not pinging them. if err != nil { log.Println(err) @@ -352,7 +406,7 @@ func (s *Server) makeHelloMessage() *pb.HelloMessage { return &pb.HelloMessage{ Port: s.Args.Port, - Host: s.Args.Host, + Host: s.ExternalIP, Servers: servers, } } diff --git a/server/federation_test.go b/server/federation_test.go index b6286a8..2719917 100644 --- a/server/federation_test.go +++ b/server/federation_test.go @@ -49,7 +49,6 @@ func makeDefaultArgs() *Args { Port: DefaultPort, EsHost: DefaultEsHost, EsPort: DefaultEsPort, - UDPPort: DefaultUdpPort, PrometheusPort: DefaultPrometheusPort, EsIndex: DefaultEsIndex, RefreshDelta: DefaultRefreshDelta, @@ -89,7 +88,7 @@ func TestAddPeer(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T){ server := MakeHubServer(ctx, args) - server.Subscribed = true + server.ExternalIP = "0.0.0.0" metrics.PeersKnown.Set(0) for i := 0; i < 10; i++ { @@ -107,7 +106,7 @@ func TestAddPeer(t *testing.T) { } } //log.Printf("Adding peer %+v\n", msg) - err := server.addPeer(msg, false) + err := server.addPeer(msg, false, false) if err != nil { log.Println(err) } @@ -148,7 +147,7 @@ func TestPeerWriter(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T){ server := MakeHubServer(ctx, args) - server.Subscribed = true + server.ExternalIP = "0.0.0.0" for i := 0; i < 10; i++ { var msg *pb.ServerMessage @@ -165,7 +164,7 @@ func TestPeerWriter(t *testing.T) { } } //log.Printf("Adding peer %+v\n", msg) - err := server.addPeer(msg, false) + err := server.addPeer(msg, false, false) if err != nil { log.Println(err) } @@ -425,3 +424,59 @@ func TestAddPeerEndpoint3(t *testing.T) { } } + + +// TestAddPeer tests the ability to add peers +func TestUDPServer(t *testing.T) { + ctx := context.Background() + args := makeDefaultArgs() + args.StartUDP = true + args2 := makeDefaultArgs() + args2.Port = "50052" + args2.StartUDP = true + + tests := []struct { + name string + want string + } { + { + name: "hubs server external ip", + want: "127.0.0.1", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T){ + server := MakeHubServer(ctx, args) + server2 := MakeHubServer(ctx, args2) + go server.Run() + go server2.Run() + metrics.PeersKnown.Set(0) + + msg := &pb.ServerMessage{ + Address: "0.0.0.0", + Port: "50052", + } + + err := server.addPeer(msg, true, true) + if err != nil { + log.Println(err) + } + + server.GrpcServer.GracefulStop() + server2.GrpcServer.GracefulStop() + + got1 := server.ExternalIP + if got1 != tt.want { + t.Errorf("server.ExternalIP = %s, want %s\n", got1, tt.want) + t.Errorf("server.Args.Port = %s\n", server.Args.Port) + } + got2 := server2.ExternalIP + if got2 != tt.want { + t.Errorf("server2.ExternalIP = %s, want %s\n", got2, tt.want) + t.Errorf("server2.Args.Port = %s\n", server2.Args.Port) + } + }) + } + +} diff --git a/server/server.go b/server/server.go index e82ebe2..b59bfb4 100644 --- a/server/server.go +++ b/server/server.go @@ -41,7 +41,7 @@ type Server struct { PeerSubs map[string]*FederatedServer PeerSubsMut sync.RWMutex NumPeerSubs *int64 - Subscribed bool + ExternalIP string pb.UnimplementedHubServer } @@ -202,7 +202,7 @@ func MakeHubServer(ctx context.Context, args *Args) *Server { PeerSubs: make(map[string]*FederatedServer), PeerSubsMut: sync.RWMutex{}, NumPeerSubs: numSubs, - Subscribed: false, + ExternalIP: "", } // Start up our background services @@ -219,10 +219,12 @@ func MakeHubServer(ctx context.Context, args *Args) *Server { } // Load peers from disk and subscribe to one if there are any if args.LoadPeers { - err = s.loadPeers() - if err != nil { - log.Println(err) - } + go func() { + err := s.loadPeers() + if err != nil { + log.Println(err) + } + }() } return s @@ -251,7 +253,7 @@ func (s *Server) Hello(ctx context.Context, args *pb.HelloMessage) (*pb.HelloMes } log.Println(server) - err := s.addPeer(&pb.ServerMessage{Address: host, Port: port}, false) + err := s.addPeer(&pb.ServerMessage{Address: host, Port: port}, false, true) // They just contacted us, so this shouldn't happen if err != nil { log.Println(err) @@ -288,7 +290,7 @@ func (s *Server) PeerSubscribe(ctx context.Context, in *pb.ServerMessage) (*pb.S func (s *Server) AddPeer(ctx context.Context, args *pb.ServerMessage) (*pb.StringValue, error) { metrics.RequestsCount.With(prometheus.Labels{"method": "add_peer"}).Inc() var msg = "Success" - err := s.addPeer(args, true) + err := s.addPeer(args, true, true) if err != nil { log.Println(err) msg = "Failed" diff --git a/server/udp.go b/server/udp.go index bf8ad5f..6b5140c 100644 --- a/server/udp.go +++ b/server/udp.go @@ -99,12 +99,12 @@ func decodeSPVPong(data []byte) *SPVPong { parsedProtocalVersion := data[0] flags := data[1] - height := binary.BigEndian.Uint32(data[:2]) + height := binary.BigEndian.Uint32(data[2:]) tip := make([]byte, 32) copy(tip, data[6:38]) srcRawAddr := make([]byte, 4) copy(srcRawAddr, data[38:42]) - country := binary.BigEndian.Uint16(data[:42]) + country := binary.BigEndian.Uint16(data[42:]) return &SPVPong{ protocolVersion: parsedProtocalVersion, flags: flags, @@ -148,7 +148,8 @@ func (pong *SPVPong) DecodeAddress() string { // UDPPing sends a ping over udp to another hub and returns the ip address of // this hub. -func UDPPing(address string) (string, error) { +func UDPPing(ip, port string) (string, error) { + address := ip + ":" + port addr, err := net.ResolveUDPAddr("udp", address) if err != nil { return "", err @@ -192,7 +193,7 @@ func UDPPing(address string) (string, error) { // Ping/Pong protocol to find out about each other without making full TCP // connections. func UDPServer(args *Args) error { - address := ":" + args.UDPPort + address := ":" + args.Port tip := make([]byte, 32) addr, err := net.ResolveUDPAddr("udp", address) if err != nil { From 355eab682c0ceb602ba7e934854ab6a4650f4837 Mon Sep 17 00:00:00 2001 From: Jeffrey Picard Date: Mon, 15 Nov 2021 08:52:32 -0500 Subject: [PATCH 02/12] changes based on comments --- server/federation.go | 18 ++++++++++++------ server/federation_test.go | 9 +++++---- server/server.go | 4 ++-- server/udp.go | 19 +++++++++---------- 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/server/federation.go b/server/federation.go index cebb5ba..9f70c56 100644 --- a/server/federation.go +++ b/server/federation.go @@ -5,6 +5,7 @@ import ( "context" "log" "math" + "net" "os" "strings" "sync/atomic" @@ -27,6 +28,7 @@ var ( "127.0.0.1": true, "0.0.0.0": true, "localhost": true, + "": true, } ) @@ -70,6 +72,7 @@ func (s *Server) getNumSubs() int64 { // getAndSetExternalIp takes the address of a peer running a UDP server and // pings it, so we can determine our own external IP address. func (s *Server) getAndSetExternalIp(msg *pb.ServerMessage) error { + log.Println(msg) myIp, err := UDPPing(msg.Address, msg.Port) if err != nil { return err @@ -139,7 +142,7 @@ retry: // If the peer is us, skip log.Println(ipPort) if ipPort[1] == port && - (localHosts[ipPort[0]] || ipPort[0] == s.ExternalIP) { + (localHosts[ipPort[0]] || ipPort[0] == s.ExternalIP.String()) { log.Println("Self peer, skipping ...") continue } @@ -177,7 +180,7 @@ func (s *Server) subscribeToPeer(peer *FederatedServer) error { defer conn.Close() msg := &pb.ServerMessage{ - Address: s.ExternalIP, + Address: s.ExternalIP.String(), Port: s.Args.Port, } @@ -217,7 +220,7 @@ func (s *Server) helloPeer(server *FederatedServer) (*pb.HelloMessage, error) { msg := &pb.HelloMessage{ Port: s.Args.Port, - Host: s.ExternalIP, + Host: s.ExternalIP.String(), Servers: []*pb.ServerMessage{}, } @@ -327,7 +330,10 @@ func (s *Server) notifyPeerSubs(newServer *FederatedServer) { func (s *Server) addPeer(msg *pb.ServerMessage, ping bool, subscribe bool) error { // First thing we get our external ip if we don't have it, otherwise we // could end up subscribed to our self, which is silly. - if s.ExternalIP == "" { + nilIP := net.IP{} + //localIP0 := net.IPv4(0,0,0,0) + localIP1 := net.IPv4(127,0,0,1) + if s.ExternalIP.Equal(nilIP) || s.ExternalIP.Equal(localIP1) { err := s.getAndSetExternalIp(msg) if err != nil { log.Println(err) @@ -336,7 +342,7 @@ func (s *Server) addPeer(msg *pb.ServerMessage, ping bool, subscribe bool) error } if s.Args.Port == msg.Port && - (localHosts[msg.Address] || msg.Address == s.ExternalIP) { + (localHosts[msg.Address] || msg.Address == s.ExternalIP.String()) { log.Printf("%s:%s addPeer: Self peer, skipping...\n", s.ExternalIP, s.Args.Port) return nil } @@ -406,7 +412,7 @@ func (s *Server) makeHelloMessage() *pb.HelloMessage { return &pb.HelloMessage{ Port: s.Args.Port, - Host: s.ExternalIP, + Host: s.ExternalIP.String(), Servers: servers, } } diff --git a/server/federation_test.go b/server/federation_test.go index 2719917..8ecaf1f 100644 --- a/server/federation_test.go +++ b/server/federation_test.go @@ -5,6 +5,7 @@ import ( "context" "fmt" "log" + "net" "os" "strings" "testing" @@ -88,7 +89,7 @@ func TestAddPeer(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T){ server := MakeHubServer(ctx, args) - server.ExternalIP = "0.0.0.0" + server.ExternalIP = net.IPv4(0,0,0,0) metrics.PeersKnown.Set(0) for i := 0; i < 10; i++ { @@ -147,7 +148,7 @@ func TestPeerWriter(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T){ server := MakeHubServer(ctx, args) - server.ExternalIP = "0.0.0.0" + server.ExternalIP = net.IPv4(0,0,0,0) for i := 0; i < 10; i++ { var msg *pb.ServerMessage @@ -466,12 +467,12 @@ func TestUDPServer(t *testing.T) { server.GrpcServer.GracefulStop() server2.GrpcServer.GracefulStop() - got1 := server.ExternalIP + got1 := server.ExternalIP.String() if got1 != tt.want { t.Errorf("server.ExternalIP = %s, want %s\n", got1, tt.want) t.Errorf("server.Args.Port = %s\n", server.Args.Port) } - got2 := server2.ExternalIP + got2 := server2.ExternalIP.String() if got2 != tt.want { t.Errorf("server2.ExternalIP = %s, want %s\n", got2, tt.want) t.Errorf("server2.Args.Port = %s\n", server2.Args.Port) diff --git a/server/server.go b/server/server.go index b59bfb4..6a15315 100644 --- a/server/server.go +++ b/server/server.go @@ -41,7 +41,7 @@ type Server struct { PeerSubs map[string]*FederatedServer PeerSubsMut sync.RWMutex NumPeerSubs *int64 - ExternalIP string + ExternalIP net.IP pb.UnimplementedHubServer } @@ -202,7 +202,7 @@ func MakeHubServer(ctx context.Context, args *Args) *Server { PeerSubs: make(map[string]*FederatedServer), PeerSubsMut: sync.RWMutex{}, NumPeerSubs: numSubs, - ExternalIP: "", + ExternalIP: net.IPv4(127,0,0,1), } // Start up our background services diff --git a/server/udp.go b/server/udp.go index 6b5140c..1240723 100644 --- a/server/udp.go +++ b/server/udp.go @@ -2,7 +2,6 @@ package server import ( "encoding/binary" - "fmt" "net" "strconv" "strings" @@ -137,8 +136,8 @@ func EncodeAddress(addr string) []byte { } // DecodeAddress gets the string ipv4 address from an SPVPong struct. -func (pong *SPVPong) DecodeAddress() string { - return fmt.Sprintf("%d.%d.%d.%d", +func (pong *SPVPong) DecodeAddress() net.IP { + return net.IPv4( pong.srcAddrRaw[0], pong.srcAddrRaw[1], pong.srcAddrRaw[2], @@ -148,40 +147,40 @@ func (pong *SPVPong) DecodeAddress() string { // UDPPing sends a ping over udp to another hub and returns the ip address of // this hub. -func UDPPing(ip, port string) (string, error) { +func UDPPing(ip, port string) (net.IP, error) { address := ip + ":" + port addr, err := net.ResolveUDPAddr("udp", address) if err != nil { - return "", err + return net.IP{}, err } conn, err := net.DialUDP("udp", nil, addr) if err != nil { - return "", err + return net.IP{}, err } defer conn.Close() _, err = conn.Write(encodeSPVPing()) if err != nil { - return "", err + return net.IP{}, err } buffer := make([]byte, maxBufferSize) deadline := time.Now().Add(time.Second) err = conn.SetReadDeadline(deadline) if err != nil { - return "", err + return net.IP{}, err } n, _, err := conn.ReadFromUDP(buffer) if err != nil { - return "", err + return net.IP{}, err } pong := decodeSPVPong(buffer[:n]) if pong == nil { - return "", errors.Base("Pong decoding failed") + return net.IP{}, errors.Base("Pong decoding failed") } myAddr := pong.DecodeAddress() From 159f4b941ba9e42d72a7ab3963493825fd8466b6 Mon Sep 17 00:00:00 2001 From: Jeffrey Picard Date: Wed, 24 Nov 2021 15:27:38 -0500 Subject: [PATCH 03/12] Add claim protobuf definition for UDP country encoding. --- protobuf/definitions/claim.proto | 1051 +++++++ protobuf/go/claim.pb.go | 5031 ++++++++++++++++++++++++++++++ server/udp.go | 8 +- 3 files changed, 6088 insertions(+), 2 deletions(-) create mode 100644 protobuf/definitions/claim.proto create mode 100644 protobuf/go/claim.pb.go diff --git a/protobuf/definitions/claim.proto b/protobuf/definitions/claim.proto new file mode 100644 index 0000000..9301485 --- /dev/null +++ b/protobuf/definitions/claim.proto @@ -0,0 +1,1051 @@ +syntax = "proto3"; + +option go_package = "github.com/lbryio/hub/protobuf/go/pb"; + +package pb; + +message Claim { + oneof type { + Stream stream = 1; + Channel channel = 2; + ClaimList collection = 3; + ClaimReference repost = 4; + } + string title = 8; + string description = 9; + Source thumbnail = 10; + repeated string tags = 11; + repeated Language languages = 12; + repeated Location locations = 13; +} + +message Stream { + Source source = 1; + string author = 2; + string license = 3; + string license_url = 4; + int64 release_time = 5; // seconds since UNIX epoch + Fee fee = 6; + oneof type { + Image image = 10; + Video video = 11; + Audio audio = 12; + Software software = 13; + } +} + +message Channel { + bytes public_key = 1; + string email = 2; + string website_url = 3; + Source cover = 4; + ClaimList featured = 5; +} + +message ClaimReference { + bytes claim_hash = 1; +} + +message ClaimList { + enum ListType { + COLLECTION = 0; // play lists, etc + DERIVATION = 2; // movie in multiple languages, software for different OSes + } + ListType list_type = 1; + repeated ClaimReference claim_references = 2; +} + +message Source { + bytes hash = 1; // SHA-384 hash of the entire unencrypted file + string name = 2; + uint64 size = 3; + string media_type = 4; + + string url = 5; + bytes sd_hash = 6; // SHA-384 hash of the streams manifest blob + bytes bt_infohash = 7; // 20-byte SHA1 hash used to reference a torrent file +} + +message Fee { + enum Currency { + UNKNOWN_CURRENCY = 0; + LBC = 1; + BTC = 2; + USD = 3; + } + Currency currency = 1; + bytes address = 2; + uint64 amount = 3; // deweys for LBC/BTC, cents for USD +} + +message Image { + uint32 width = 1; + uint32 height = 2; +} + +message Video { + uint32 width = 1; + uint32 height = 2; + uint32 duration = 3; + Audio audio = 15; +} + +message Audio { + uint32 duration = 1; +} + +message Software { + enum OS { + UNKNOWN_OS = 0; + ANY = 1; + LINUX = 2; + WINDOWS = 3; + MAC = 4; + ANDROID = 5; + IOS = 6; + } + string os = 1; +} + +// RFC 5646 +message Language { + Language language = 1; + Script script = 2; + Location.Country region = 3; + + // ISO 639-1 + enum Language { + UNKNOWN_LANGUAGE = 0; + en = 1; + aa = 2; + ab = 3; + ae = 4; + af = 5; + ak = 6; + am = 7; + an = 8; + ar = 9; + as = 10; + av = 11; + ay = 12; + az = 13; + ba = 14; + be = 15; + bg = 16; + bh = 17; + bi = 18; + bm = 19; + bn = 20; + bo = 21; + br = 22; + bs = 23; + ca = 24; + ce = 25; + ch = 26; + co = 27; + cr = 28; + cs = 29; + cu = 30; + cv = 31; + cy = 32; + da = 33; + de = 34; + dv = 35; + dz = 36; + ee = 37; + el = 38; + eo = 39; + es = 40; + et = 41; + eu = 42; + fa = 43; + ff = 44; + fi = 45; + fj = 46; + fo = 47; + fr = 48; + fy = 49; + ga = 50; + gd = 51; + gl = 52; + gn = 53; + gu = 54; + gv = 55; + ha = 56; + he = 57; + hi = 58; + ho = 59; + hr = 60; + ht = 61; + hu = 62; + hy = 63; + hz = 64; + ia = 65; + id = 66; + ie = 67; + ig = 68; + ii = 69; + ik = 70; + io = 71; + is = 72; + it = 73; + iu = 74; + ja = 75; + jv = 76; + ka = 77; + kg = 78; + ki = 79; + kj = 80; + kk = 81; + kl = 82; + km = 83; + kn = 84; + ko = 85; + kr = 86; + ks = 87; + ku = 88; + kv = 89; + kw = 90; + ky = 91; + la = 92; + lb = 93; + lg = 94; + li = 95; + ln = 96; + lo = 97; + lt = 98; + lu = 99; + lv = 100; + mg = 101; + mh = 102; + mi = 103; + mk = 104; + ml = 105; + mn = 106; + mr = 107; + ms = 108; + mt = 109; + my = 110; + na = 111; + nb = 112; + nd = 113; + ne = 114; + ng = 115; + nl = 116; + nn = 117; + no = 118; + nr = 119; + nv = 120; + ny = 121; + oc = 122; + oj = 123; + om = 124; + or = 125; + os = 126; + pa = 127; + pi = 128; + pl = 129; + ps = 130; + pt = 131; + qu = 132; + rm = 133; + rn = 134; + ro = 135; + ru = 136; + rw = 137; + sa = 138; + sc = 139; + sd = 140; + se = 141; + sg = 142; + si = 143; + sk = 144; + sl = 145; + sm = 146; + sn = 147; + so = 148; + sq = 149; + sr = 150; + ss = 151; + st = 152; + su = 153; + sv = 154; + sw = 155; + ta = 156; + te = 157; + tg = 158; + th = 159; + ti = 160; + tk = 161; + tl = 162; + tn = 163; + to = 164; + tr = 165; + ts = 166; + tt = 167; + tw = 168; + ty = 169; + ug = 170; + uk = 171; + ur = 172; + uz = 173; + ve = 174; + vi = 175; + vo = 176; + wa = 177; + wo = 178; + xh = 179; + yi = 180; + yo = 181; + za = 182; + zh = 183; + zu = 184; + } + + // ISO 15924 + enum Script { + UNKNOWN_SCRIPT = 0; + Adlm = 1; + Afak = 2; + Aghb = 3; + Ahom = 4; + Arab = 5; + Aran = 6; + Armi = 7; + Armn = 8; + Avst = 9; + Bali = 10; + Bamu = 11; + Bass = 12; + Batk = 13; + Beng = 14; + Bhks = 15; + Blis = 16; + Bopo = 17; + Brah = 18; + Brai = 19; + Bugi = 20; + Buhd = 21; + Cakm = 22; + Cans = 23; + Cari = 24; + Cham = 25; + Cher = 26; + Cirt = 27; + Copt = 28; + Cpmn = 29; + Cprt = 30; + Cyrl = 31; + Cyrs = 32; + Deva = 33; + Dogr = 34; + Dsrt = 35; + Dupl = 36; + Egyd = 37; + Egyh = 38; + Egyp = 39; + Elba = 40; + Elym = 41; + Ethi = 42; + Geok = 43; + Geor = 44; + Glag = 45; + Gong = 46; + Gonm = 47; + Goth = 48; + Gran = 49; + Grek = 50; + Gujr = 51; + Guru = 52; + Hanb = 53; + Hang = 54; + Hani = 55; + Hano = 56; + Hans = 57; + Hant = 58; + Hatr = 59; + Hebr = 60; + Hira = 61; + Hluw = 62; + Hmng = 63; + Hmnp = 64; + Hrkt = 65; + Hung = 66; + Inds = 67; + Ital = 68; + Jamo = 69; + Java = 70; + Jpan = 71; + Jurc = 72; + Kali = 73; + Kana = 74; + Khar = 75; + Khmr = 76; + Khoj = 77; + Kitl = 78; + Kits = 79; + Knda = 80; + Kore = 81; + Kpel = 82; + Kthi = 83; + Lana = 84; + Laoo = 85; + Latf = 86; + Latg = 87; + Latn = 88; + Leke = 89; + Lepc = 90; + Limb = 91; + Lina = 92; + Linb = 93; + Lisu = 94; + Loma = 95; + Lyci = 96; + Lydi = 97; + Mahj = 98; + Maka = 99; + Mand = 100; + Mani = 101; + Marc = 102; + Maya = 103; + Medf = 104; + Mend = 105; + Merc = 106; + Mero = 107; + Mlym = 108; + Modi = 109; + Mong = 110; + Moon = 111; + Mroo = 112; + Mtei = 113; + Mult = 114; + Mymr = 115; + Nand = 116; + Narb = 117; + Nbat = 118; + Newa = 119; + Nkdb = 120; + Nkgb = 121; + Nkoo = 122; + Nshu = 123; + Ogam = 124; + Olck = 125; + Orkh = 126; + Orya = 127; + Osge = 128; + Osma = 129; + Palm = 130; + Pauc = 131; + Perm = 132; + Phag = 133; + Phli = 134; + Phlp = 135; + Phlv = 136; + Phnx = 137; + Plrd = 138; + Piqd = 139; + Prti = 140; + Qaaa = 141; + Qabx = 142; + Rjng = 143; + Rohg = 144; + Roro = 145; + Runr = 146; + Samr = 147; + Sara = 148; + Sarb = 149; + Saur = 150; + Sgnw = 151; + Shaw = 152; + Shrd = 153; + Shui = 154; + Sidd = 155; + Sind = 156; + Sinh = 157; + Sogd = 158; + Sogo = 159; + Sora = 160; + Soyo = 161; + Sund = 162; + Sylo = 163; + Syrc = 164; + Syre = 165; + Syrj = 166; + Syrn = 167; + Tagb = 168; + Takr = 169; + Tale = 170; + Talu = 171; + Taml = 172; + Tang = 173; + Tavt = 174; + Telu = 175; + Teng = 176; + Tfng = 177; + Tglg = 178; + Thaa = 179; + Thai = 180; + Tibt = 181; + Tirh = 182; + Ugar = 183; + Vaii = 184; + Visp = 185; + Wara = 186; + Wcho = 187; + Wole = 188; + Xpeo = 189; + Xsux = 190; + Yiii = 191; + Zanb = 192; + Zinh = 193; + Zmth = 194; + Zsye = 195; + Zsym = 196; + Zxxx = 197; + Zyyy = 198; + Zzzz = 199; + } +} + +message Location { + Country country = 1; + string state = 2; + string city = 3; + string code = 4; + sint32 latitude = 5; + sint32 longitude = 6; + + enum Country { + UNKNOWN_COUNTRY = 0; + AF = 1; + AX = 2; + AL = 3; + DZ = 4; + AS = 5; + AD = 6; + AO = 7; + AI = 8; + AQ = 9; + AG = 10; + AR = 11; + AM = 12; + AW = 13; + AU = 14; + AT = 15; + AZ = 16; + BS = 17; + BH = 18; + BD = 19; + BB = 20; + BY = 21; + BE = 22; + BZ = 23; + BJ = 24; + BM = 25; + BT = 26; + BO = 27; + BQ = 28; + BA = 29; + BW = 30; + BV = 31; + BR = 32; + IO = 33; + BN = 34; + BG = 35; + BF = 36; + BI = 37; + KH = 38; + CM = 39; + CA = 40; + CV = 41; + KY = 42; + CF = 43; + TD = 44; + CL = 45; + CN = 46; + CX = 47; + CC = 48; + CO = 49; + KM = 50; + CG = 51; + CD = 52; + CK = 53; + CR = 54; + CI = 55; + HR = 56; + CU = 57; + CW = 58; + CY = 59; + CZ = 60; + DK = 61; + DJ = 62; + DM = 63; + DO = 64; + EC = 65; + EG = 66; + SV = 67; + GQ = 68; + ER = 69; + EE = 70; + ET = 71; + FK = 72; + FO = 73; + FJ = 74; + FI = 75; + FR = 76; + GF = 77; + PF = 78; + TF = 79; + GA = 80; + GM = 81; + GE = 82; + DE = 83; + GH = 84; + GI = 85; + GR = 86; + GL = 87; + GD = 88; + GP = 89; + GU = 90; + GT = 91; + GG = 92; + GN = 93; + GW = 94; + GY = 95; + HT = 96; + HM = 97; + VA = 98; + HN = 99; + HK = 100; + HU = 101; + IS = 102; + IN = 103; + ID = 104; + IR = 105; + IQ = 106; + IE = 107; + IM = 108; + IL = 109; + IT = 110; + JM = 111; + JP = 112; + JE = 113; + JO = 114; + KZ = 115; + KE = 116; + KI = 117; + KP = 118; + KR = 119; + KW = 120; + KG = 121; + LA = 122; + LV = 123; + LB = 124; + LS = 125; + LR = 126; + LY = 127; + LI = 128; + LT = 129; + LU = 130; + MO = 131; + MK = 132; + MG = 133; + MW = 134; + MY = 135; + MV = 136; + ML = 137; + MT = 138; + MH = 139; + MQ = 140; + MR = 141; + MU = 142; + YT = 143; + MX = 144; + FM = 145; + MD = 146; + MC = 147; + MN = 148; + ME = 149; + MS = 150; + MA = 151; + MZ = 152; + MM = 153; + NA = 154; + NR = 155; + NP = 156; + NL = 157; + NC = 158; + NZ = 159; + NI = 160; + NE = 161; + NG = 162; + NU = 163; + NF = 164; + MP = 165; + NO = 166; + OM = 167; + PK = 168; + PW = 169; + PS = 170; + PA = 171; + PG = 172; + PY = 173; + PE = 174; + PH = 175; + PN = 176; + PL = 177; + PT = 178; + PR = 179; + QA = 180; + RE = 181; + RO = 182; + RU = 183; + RW = 184; + BL = 185; + SH = 186; + KN = 187; + LC = 188; + MF = 189; + PM = 190; + VC = 191; + WS = 192; + SM = 193; + ST = 194; + SA = 195; + SN = 196; + RS = 197; + SC = 198; + SL = 199; + SG = 200; + SX = 201; + SK = 202; + SI = 203; + SB = 204; + SO = 205; + ZA = 206; + GS = 207; + SS = 208; + ES = 209; + LK = 210; + SD = 211; + SR = 212; + SJ = 213; + SZ = 214; + SE = 215; + CH = 216; + SY = 217; + TW = 218; + TJ = 219; + TZ = 220; + TH = 221; + TL = 222; + TG = 223; + TK = 224; + TO = 225; + TT = 226; + TN = 227; + TR = 228; + TM = 229; + TC = 230; + TV = 231; + UG = 232; + UA = 233; + AE = 234; + GB = 235; + US = 236; + UM = 237; + UY = 238; + UZ = 239; + VU = 240; + VE = 241; + VN = 242; + VG = 243; + VI = 244; + WF = 245; + EH = 246; + YE = 247; + ZM = 248; + ZW = 249; + // UN M.49 Geographic Regions + R001 = 250; // World + R002 = 251; // Africa + R015 = 252; // Northern Africa + R012 = 253; // Algeria DZA + R818 = 254; // Egypt EGY + R434 = 255; // Libya LBY + R504 = 256; // Morocco MAR + R729 = 257; // Sudan SDN LDC + R788 = 258; // Tunisia TUN + R732 = 259; // Western Sahara ESH + R202 = 260; // Sub-Saharan Africa + R014 = 261; // Eastern Africa + R086 = 262; // British Indian Ocean Territory IOT + R108 = 263; // Burundi BDI LDC LLDC + R174 = 264; // Comoros COM LDC SIDS + R262 = 265; // Djibouti DJI LDC + R232 = 266; // Eritrea ERI LDC + R231 = 267; // Ethiopia ETH LDC LLDC + R260 = 268; // French Southern Territories ATF + R404 = 269; // Kenya KEN + R450 = 270; // Madagascar MDG LDC + R454 = 271; // Malawi MWI LDC LLDC + R480 = 272; // Mauritius MUS SIDS + R175 = 273; // Mayotte MYT + R508 = 274; // Mozambique MOZ LDC + R638 = 275; // Réunion REU + R646 = 276; // Rwanda RWA LDC LLDC + R690 = 277; // Seychelles SYC SIDS + R706 = 278; // Somalia SOM LDC + R728 = 279; // South Sudan SSD LDC LLDC + R800 = 280; // Uganda UGA LDC LLDC + R834 = 281; // United Republic of Tanzania TZA LDC + R894 = 282; // Zambia ZMB LDC LLDC + R716 = 283; // Zimbabwe ZWE LLDC + R017 = 284; // Middle Africa + R024 = 285; // Angola AGO LDC + R120 = 286; // Cameroon CMR + R140 = 287; // Central African Republic CAF LDC LLDC + R148 = 288; // Chad TCD LDC LLDC + R178 = 289; // Congo COG + R180 = 290; // Democratic Republic of the Congo COD LDC + R226 = 291; // Equatorial Guinea GNQ + R266 = 292; // Gabon GAB + R678 = 293; // Sao Tome and Principe STP LDC SIDS + R018 = 294; // Southern Africa + R072 = 295; // Botswana BWA LLDC + R748 = 296; // Eswatini SWZ LLDC + R426 = 297; // Lesotho LSO LDC LLDC + R516 = 298; // Namibia NAM + R710 = 299; // South Africa ZAF + R011 = 300; // Western Africa + R204 = 301; // Benin BEN LDC + R854 = 302; // Burkina Faso BFA LDC LLDC + R132 = 303; // Cabo Verde CPV SIDS + R384 = 304; // Côte d’Ivoire CIV + R270 = 305; // Gambia GMB LDC + R288 = 306; // Ghana GHA + R324 = 307; // Guinea GIN LDC + R624 = 308; // Guinea-Bissau GNB LDC SIDS + R430 = 309; // Liberia LBR LDC + R466 = 310; // Mali MLI LDC LLDC + R478 = 311; // Mauritania MRT LDC + R562 = 312; // Niger NER LDC LLDC + R566 = 313; // Nigeria NGA + R654 = 314; // Saint Helena SHN + R686 = 315; // Senegal SEN LDC + R694 = 316; // Sierra Leone SLE LDC + R768 = 317; // Togo TGO LDC + R019 = 318; // Americas + R419 = 319; // Latin America and the Caribbean + R029 = 320; // Caribbean + R660 = 321; // Anguilla AIA SIDS + R028 = 322; // Antigua and Barbuda ATG SIDS + R533 = 323; // Aruba ABW SIDS + R044 = 324; // Bahamas BHS SIDS + R052 = 325; // Barbados BRB SIDS + R535 = 326; // Bonaire, Sint Eustatius and Saba BES SIDS + R092 = 327; // British Virgin Islands VGB SIDS + R136 = 328; // Cayman Islands CYM + R192 = 329; // Cuba CUB SIDS + R531 = 330; // Curaçao CUW SIDS + R212 = 331; // Dominica DMA SIDS + R214 = 332; // Dominican Republic DOM SIDS + R308 = 333; // Grenada GRD SIDS + R312 = 334; // Guadeloupe GLP + R332 = 335; // Haiti HTI LDC SIDS + R388 = 336; // Jamaica JAM SIDS + R474 = 337; // Martinique MTQ + R500 = 338; // Montserrat MSR SIDS + R630 = 339; // Puerto Rico PRI SIDS + R652 = 340; // Saint Barthélemy BLM + R659 = 341; // Saint Kitts and Nevis KNA SIDS + R662 = 342; // Saint Lucia LCA SIDS + R663 = 343; // Saint Martin (French Part) MAF + R670 = 344; // Saint Vincent and the Grenadines VCT SIDS + R534 = 345; // Sint Maarten (Dutch part) SXM SIDS + R780 = 346; // Trinidad and Tobago TTO SIDS + R796 = 347; // Turks and Caicos Islands TCA + R850 = 348; // United States Virgin Islands VIR SIDS + R013 = 349; // Central America + R084 = 350; // Belize BLZ SIDS + R188 = 351; // Costa Rica CRI + R222 = 352; // El Salvador SLV + R320 = 353; // Guatemala GTM + R340 = 354; // Honduras HND + R484 = 355; // Mexico MEX + R558 = 356; // Nicaragua NIC + R591 = 357; // Panama PAN + R005 = 358; // South America + R032 = 359; // Argentina ARG + R068 = 360; // Bolivia (Plurinational State of) BOL LLDC + R074 = 361; // Bouvet Island BVT + R076 = 362; // Brazil BRA + R152 = 363; // Chile CHL + R170 = 364; // Colombia COL + R218 = 365; // Ecuador ECU + R238 = 366; // Falkland Islands (Malvinas) FLK + R254 = 367; // French Guiana GUF + R328 = 368; // Guyana GUY SIDS + R600 = 369; // Paraguay PRY LLDC + R604 = 370; // Peru PER + R239 = 371; // South Georgia and the South Sandwich Islands SGS + R740 = 372; // Suriname SUR SIDS + R858 = 373; // Uruguay URY + R862 = 374; // Venezuela (Bolivarian Republic of) VEN + R021 = 375; // Northern America + R060 = 376; // Bermuda BMU + R124 = 377; // Canada CAN + R304 = 378; // Greenland GRL + R666 = 379; // Saint Pierre and Miquelon SPM + R840 = 380; // United States of America USA + R010 = 381; // Antarctica ATA + R142 = 382; // Asia + R143 = 383; // Central Asia + R398 = 384; // Kazakhstan KAZ LLDC + R417 = 385; // Kyrgyzstan KGZ LLDC + R762 = 386; // Tajikistan TJK LLDC + R795 = 387; // Turkmenistan TKM LLDC + R860 = 388; // Uzbekistan UZB LLDC + R030 = 389; // Eastern Asia + R156 = 390; // China CHN + R344 = 391; // China, Hong Kong Special Administrative Region HKG + R446 = 392; // China, Macao Special Administrative Region MAC + R408 = 393; // Democratic People's Republic of Korea PRK + R392 = 394; // Japan JPN + R496 = 395; // Mongolia MNG LLDC + R410 = 396; // Republic of Korea KOR + R035 = 397; // South-eastern Asia + R096 = 398; // Brunei Darussalam BRN + R116 = 399; // Cambodia KHM LDC + R360 = 400; // Indonesia IDN + R418 = 401; // Lao People's Democratic Republic LAO LDC LLDC + R458 = 402; // Malaysia MYS + R104 = 403; // Myanmar MMR LDC + R608 = 404; // Philippines PHL + R702 = 405; // Singapore SGP SIDS + R764 = 406; // Thailand THA + R626 = 407; // Timor-Leste TLS LDC SIDS + R704 = 408; // Viet Nam VNM + R034 = 409; // Southern Asia + R004 = 410; // Afghanistan AFG LDC LLDC + R050 = 411; // Bangladesh BGD LDC + R064 = 412; // Bhutan BTN LDC LLDC + R356 = 413; // India IND + R364 = 414; // Iran (Islamic Republic of) IRN + R462 = 415; // Maldives MDV SIDS + R524 = 416; // Nepal NPL LDC LLDC + R586 = 417; // Pakistan PAK + R144 = 418; // Sri Lanka LKA + R145 = 419; // Western Asia + R051 = 420; // Armenia ARM LLDC + R031 = 421; // Azerbaijan AZE LLDC + R048 = 422; // Bahrain BHR + R196 = 423; // Cyprus CYP + R268 = 424; // Georgia GEO + R368 = 425; // Iraq IRQ + R376 = 426; // Israel ISR + R400 = 427; // Jordan JOR + R414 = 428; // Kuwait KWT + R422 = 429; // Lebanon LBN + R512 = 430; // Oman OMN + R634 = 431; // Qatar QAT + R682 = 432; // Saudi Arabia SAU + R275 = 433; // State of Palestine PSE + R760 = 434; // Syrian Arab Republic SYR + R792 = 435; // Turkey TUR + R784 = 436; // United Arab Emirates ARE + R887 = 437; // Yemen YEM LDC + R150 = 438; // Europe + R151 = 439; // Eastern Europe + R112 = 440; // Belarus BLR + R100 = 441; // Bulgaria BGR + R203 = 442; // Czechia CZE + R348 = 443; // Hungary HUN + R616 = 444; // Poland POL + R498 = 445; // Republic of Moldova MDA LLDC + R642 = 446; // Romania ROU + R643 = 447; // Russian Federation RUS + R703 = 448; // Slovakia SVK + R804 = 449; // Ukraine UKR + R154 = 450; // Northern Europe + R248 = 451; // Åland Islands ALA + R830 = 452; // Channel Islands + R831 = 453; // Guernsey GGY + R832 = 454; // Jersey JEY + R680 = 455; // Sark + R208 = 456; // Denmark DNK + R233 = 457; // Estonia EST + R234 = 458; // Faroe Islands FRO + R246 = 459; // Finland FIN + R352 = 460; // Iceland ISL + R372 = 461; // Ireland IRL + R833 = 462; // Isle of Man IMN + R428 = 463; // Latvia LVA + R440 = 464; // Lithuania LTU + R578 = 465; // Norway NOR + R744 = 466; // Svalbard and Jan Mayen Islands SJM + R752 = 467; // Sweden SWE + R826 = 468; // United Kingdom of Great Britain and Northern Ireland GBR + R039 = 469; // Southern Europe + R008 = 470; // Albania ALB + R020 = 471; // Andorra AND + R070 = 472; // Bosnia and Herzegovina BIH + R191 = 473; // Croatia HRV + R292 = 474; // Gibraltar GIB + R300 = 475; // Greece GRC + R336 = 476; // Holy See VAT + R380 = 477; // Italy ITA + R470 = 478; // Malta MLT + R499 = 479; // Montenegro MNE + R807 = 480; // North Macedonia MKD LLDC + R620 = 481; // Portugal PRT + R674 = 482; // San Marino SMR + R688 = 483; // Serbia SRB + R705 = 484; // Slovenia SVN + R724 = 485; // Spain ESP + R155 = 486; // Western Europe + R040 = 487; // Austria AUT + R056 = 488; // Belgium BEL + R250 = 489; // France FRA + R276 = 490; // Germany DEU + R438 = 491; // Liechtenstein LIE + R442 = 492; // Luxembourg LUX + R492 = 493; // Monaco MCO + R528 = 494; // Netherlands NLD + R756 = 495; // Switzerland CHE + R009 = 496; // Oceania + R053 = 497; // Australia and New Zealand + R036 = 498; // Australia AUS + R162 = 499; // Christmas Island CXR + R166 = 500; // Cocos (Keeling) Islands CCK + R334 = 501; // Heard Island and McDonald Islands HMD + R554 = 502; // New Zealand NZL + R574 = 503; // Norfolk Island NFK + R054 = 504; // Melanesia + R242 = 505; // Fiji FJI SIDS + R540 = 506; // New Caledonia NCL SIDS + R598 = 507; // Papua New Guinea PNG SIDS + R090 = 508; // Solomon Islands SLB LDC SIDS + R548 = 509; // Vanuatu VUT LDC SIDS + R057 = 510; // Micronesia + R316 = 511; // Guam GUM SIDS + R296 = 512; // Kiribati KIR LDC SIDS + R584 = 513; // Marshall Islands MHL SIDS + R583 = 514; // Micronesia (Federated States of) FSM SIDS + R520 = 515; // Nauru NRU SIDS + R580 = 516; // Northern Mariana Islands MNP SIDS + R585 = 517; // Palau PLW SIDS + R581 = 518; // United States Minor Outlying Islands UMI + R061 = 519; // Polynesia + R016 = 520; // American Samoa ASM SIDS + R184 = 521; // Cook Islands COK SIDS + R258 = 522; // French Polynesia PYF SIDS + R570 = 523; // Niue NIU SIDS + R612 = 524; // Pitcairn PCN + R882 = 525; // Samoa WSM SIDS + R772 = 526; // Tokelau TKL + R776 = 527; // Tonga TON SIDS + R798 = 528; // Tuvalu TUV LDC SIDS + R876 = 529; // Wallis and Futuna Islands WLF + } +} diff --git a/protobuf/go/claim.pb.go b/protobuf/go/claim.pb.go new file mode 100644 index 0000000..0f501c7 --- /dev/null +++ b/protobuf/go/claim.pb.go @@ -0,0 +1,5031 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.17.1 +// source: claim.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ClaimList_ListType int32 + +const ( + ClaimList_COLLECTION ClaimList_ListType = 0 // play lists, etc + ClaimList_DERIVATION ClaimList_ListType = 2 // movie in multiple languages, software for different OSes +) + +// Enum value maps for ClaimList_ListType. +var ( + ClaimList_ListType_name = map[int32]string{ + 0: "COLLECTION", + 2: "DERIVATION", + } + ClaimList_ListType_value = map[string]int32{ + "COLLECTION": 0, + "DERIVATION": 2, + } +) + +func (x ClaimList_ListType) Enum() *ClaimList_ListType { + p := new(ClaimList_ListType) + *p = x + return p +} + +func (x ClaimList_ListType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ClaimList_ListType) Descriptor() protoreflect.EnumDescriptor { + return file_claim_proto_enumTypes[0].Descriptor() +} + +func (ClaimList_ListType) Type() protoreflect.EnumType { + return &file_claim_proto_enumTypes[0] +} + +func (x ClaimList_ListType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ClaimList_ListType.Descriptor instead. +func (ClaimList_ListType) EnumDescriptor() ([]byte, []int) { + return file_claim_proto_rawDescGZIP(), []int{4, 0} +} + +type Fee_Currency int32 + +const ( + Fee_UNKNOWN_CURRENCY Fee_Currency = 0 + Fee_LBC Fee_Currency = 1 + Fee_BTC Fee_Currency = 2 + Fee_USD Fee_Currency = 3 +) + +// Enum value maps for Fee_Currency. +var ( + Fee_Currency_name = map[int32]string{ + 0: "UNKNOWN_CURRENCY", + 1: "LBC", + 2: "BTC", + 3: "USD", + } + Fee_Currency_value = map[string]int32{ + "UNKNOWN_CURRENCY": 0, + "LBC": 1, + "BTC": 2, + "USD": 3, + } +) + +func (x Fee_Currency) Enum() *Fee_Currency { + p := new(Fee_Currency) + *p = x + return p +} + +func (x Fee_Currency) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Fee_Currency) Descriptor() protoreflect.EnumDescriptor { + return file_claim_proto_enumTypes[1].Descriptor() +} + +func (Fee_Currency) Type() protoreflect.EnumType { + return &file_claim_proto_enumTypes[1] +} + +func (x Fee_Currency) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Fee_Currency.Descriptor instead. +func (Fee_Currency) EnumDescriptor() ([]byte, []int) { + return file_claim_proto_rawDescGZIP(), []int{6, 0} +} + +type Software_OS int32 + +const ( + Software_UNKNOWN_OS Software_OS = 0 + Software_ANY Software_OS = 1 + Software_LINUX Software_OS = 2 + Software_WINDOWS Software_OS = 3 + Software_MAC Software_OS = 4 + Software_ANDROID Software_OS = 5 + Software_IOS Software_OS = 6 +) + +// Enum value maps for Software_OS. +var ( + Software_OS_name = map[int32]string{ + 0: "UNKNOWN_OS", + 1: "ANY", + 2: "LINUX", + 3: "WINDOWS", + 4: "MAC", + 5: "ANDROID", + 6: "IOS", + } + Software_OS_value = map[string]int32{ + "UNKNOWN_OS": 0, + "ANY": 1, + "LINUX": 2, + "WINDOWS": 3, + "MAC": 4, + "ANDROID": 5, + "IOS": 6, + } +) + +func (x Software_OS) Enum() *Software_OS { + p := new(Software_OS) + *p = x + return p +} + +func (x Software_OS) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Software_OS) Descriptor() protoreflect.EnumDescriptor { + return file_claim_proto_enumTypes[2].Descriptor() +} + +func (Software_OS) Type() protoreflect.EnumType { + return &file_claim_proto_enumTypes[2] +} + +func (x Software_OS) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Software_OS.Descriptor instead. +func (Software_OS) EnumDescriptor() ([]byte, []int) { + return file_claim_proto_rawDescGZIP(), []int{10, 0} +} + +// ISO 639-1 +type Language_Language int32 + +const ( + Language_UNKNOWN_LANGUAGE Language_Language = 0 + Language_en Language_Language = 1 + Language_aa Language_Language = 2 + Language_ab Language_Language = 3 + Language_ae Language_Language = 4 + Language_af Language_Language = 5 + Language_ak Language_Language = 6 + Language_am Language_Language = 7 + Language_an Language_Language = 8 + Language_ar Language_Language = 9 + Language_as Language_Language = 10 + Language_av Language_Language = 11 + Language_ay Language_Language = 12 + Language_az Language_Language = 13 + Language_ba Language_Language = 14 + Language_be Language_Language = 15 + Language_bg Language_Language = 16 + Language_bh Language_Language = 17 + Language_bi Language_Language = 18 + Language_bm Language_Language = 19 + Language_bn Language_Language = 20 + Language_bo Language_Language = 21 + Language_br Language_Language = 22 + Language_bs Language_Language = 23 + Language_ca Language_Language = 24 + Language_ce Language_Language = 25 + Language_ch Language_Language = 26 + Language_co Language_Language = 27 + Language_cr Language_Language = 28 + Language_cs Language_Language = 29 + Language_cu Language_Language = 30 + Language_cv Language_Language = 31 + Language_cy Language_Language = 32 + Language_da Language_Language = 33 + Language_de Language_Language = 34 + Language_dv Language_Language = 35 + Language_dz Language_Language = 36 + Language_ee Language_Language = 37 + Language_el Language_Language = 38 + Language_eo Language_Language = 39 + Language_es Language_Language = 40 + Language_et Language_Language = 41 + Language_eu Language_Language = 42 + Language_fa Language_Language = 43 + Language_ff Language_Language = 44 + Language_fi Language_Language = 45 + Language_fj Language_Language = 46 + Language_fo Language_Language = 47 + Language_fr Language_Language = 48 + Language_fy Language_Language = 49 + Language_ga Language_Language = 50 + Language_gd Language_Language = 51 + Language_gl Language_Language = 52 + Language_gn Language_Language = 53 + Language_gu Language_Language = 54 + Language_gv Language_Language = 55 + Language_ha Language_Language = 56 + Language_he Language_Language = 57 + Language_hi Language_Language = 58 + Language_ho Language_Language = 59 + Language_hr Language_Language = 60 + Language_ht Language_Language = 61 + Language_hu Language_Language = 62 + Language_hy Language_Language = 63 + Language_hz Language_Language = 64 + Language_ia Language_Language = 65 + Language_id Language_Language = 66 + Language_ie Language_Language = 67 + Language_ig Language_Language = 68 + Language_ii Language_Language = 69 + Language_ik Language_Language = 70 + Language_io Language_Language = 71 + Language_is Language_Language = 72 + Language_it Language_Language = 73 + Language_iu Language_Language = 74 + Language_ja Language_Language = 75 + Language_jv Language_Language = 76 + Language_ka Language_Language = 77 + Language_kg Language_Language = 78 + Language_ki Language_Language = 79 + Language_kj Language_Language = 80 + Language_kk Language_Language = 81 + Language_kl Language_Language = 82 + Language_km Language_Language = 83 + Language_kn Language_Language = 84 + Language_ko Language_Language = 85 + Language_kr Language_Language = 86 + Language_ks Language_Language = 87 + Language_ku Language_Language = 88 + Language_kv Language_Language = 89 + Language_kw Language_Language = 90 + Language_ky Language_Language = 91 + Language_la Language_Language = 92 + Language_lb Language_Language = 93 + Language_lg Language_Language = 94 + Language_li Language_Language = 95 + Language_ln Language_Language = 96 + Language_lo Language_Language = 97 + Language_lt Language_Language = 98 + Language_lu Language_Language = 99 + Language_lv Language_Language = 100 + Language_mg Language_Language = 101 + Language_mh Language_Language = 102 + Language_mi Language_Language = 103 + Language_mk Language_Language = 104 + Language_ml Language_Language = 105 + Language_mn Language_Language = 106 + Language_mr Language_Language = 107 + Language_ms Language_Language = 108 + Language_mt Language_Language = 109 + Language_my Language_Language = 110 + Language_na Language_Language = 111 + Language_nb Language_Language = 112 + Language_nd Language_Language = 113 + Language_ne Language_Language = 114 + Language_ng Language_Language = 115 + Language_nl Language_Language = 116 + Language_nn Language_Language = 117 + Language_no Language_Language = 118 + Language_nr Language_Language = 119 + Language_nv Language_Language = 120 + Language_ny Language_Language = 121 + Language_oc Language_Language = 122 + Language_oj Language_Language = 123 + Language_om Language_Language = 124 + Language_or Language_Language = 125 + Language_os Language_Language = 126 + Language_pa Language_Language = 127 + Language_pi Language_Language = 128 + Language_pl Language_Language = 129 + Language_ps Language_Language = 130 + Language_pt Language_Language = 131 + Language_qu Language_Language = 132 + Language_rm Language_Language = 133 + Language_rn Language_Language = 134 + Language_ro Language_Language = 135 + Language_ru Language_Language = 136 + Language_rw Language_Language = 137 + Language_sa Language_Language = 138 + Language_sc Language_Language = 139 + Language_sd Language_Language = 140 + Language_se Language_Language = 141 + Language_sg Language_Language = 142 + Language_si Language_Language = 143 + Language_sk Language_Language = 144 + Language_sl Language_Language = 145 + Language_sm Language_Language = 146 + Language_sn Language_Language = 147 + Language_so Language_Language = 148 + Language_sq Language_Language = 149 + Language_sr Language_Language = 150 + Language_ss Language_Language = 151 + Language_st Language_Language = 152 + Language_su Language_Language = 153 + Language_sv Language_Language = 154 + Language_sw Language_Language = 155 + Language_ta Language_Language = 156 + Language_te Language_Language = 157 + Language_tg Language_Language = 158 + Language_th Language_Language = 159 + Language_ti Language_Language = 160 + Language_tk Language_Language = 161 + Language_tl Language_Language = 162 + Language_tn Language_Language = 163 + Language_to Language_Language = 164 + Language_tr Language_Language = 165 + Language_ts Language_Language = 166 + Language_tt Language_Language = 167 + Language_tw Language_Language = 168 + Language_ty Language_Language = 169 + Language_ug Language_Language = 170 + Language_uk Language_Language = 171 + Language_ur Language_Language = 172 + Language_uz Language_Language = 173 + Language_ve Language_Language = 174 + Language_vi Language_Language = 175 + Language_vo Language_Language = 176 + Language_wa Language_Language = 177 + Language_wo Language_Language = 178 + Language_xh Language_Language = 179 + Language_yi Language_Language = 180 + Language_yo Language_Language = 181 + Language_za Language_Language = 182 + Language_zh Language_Language = 183 + Language_zu Language_Language = 184 +) + +// Enum value maps for Language_Language. +var ( + Language_Language_name = map[int32]string{ + 0: "UNKNOWN_LANGUAGE", + 1: "en", + 2: "aa", + 3: "ab", + 4: "ae", + 5: "af", + 6: "ak", + 7: "am", + 8: "an", + 9: "ar", + 10: "as", + 11: "av", + 12: "ay", + 13: "az", + 14: "ba", + 15: "be", + 16: "bg", + 17: "bh", + 18: "bi", + 19: "bm", + 20: "bn", + 21: "bo", + 22: "br", + 23: "bs", + 24: "ca", + 25: "ce", + 26: "ch", + 27: "co", + 28: "cr", + 29: "cs", + 30: "cu", + 31: "cv", + 32: "cy", + 33: "da", + 34: "de", + 35: "dv", + 36: "dz", + 37: "ee", + 38: "el", + 39: "eo", + 40: "es", + 41: "et", + 42: "eu", + 43: "fa", + 44: "ff", + 45: "fi", + 46: "fj", + 47: "fo", + 48: "fr", + 49: "fy", + 50: "ga", + 51: "gd", + 52: "gl", + 53: "gn", + 54: "gu", + 55: "gv", + 56: "ha", + 57: "he", + 58: "hi", + 59: "ho", + 60: "hr", + 61: "ht", + 62: "hu", + 63: "hy", + 64: "hz", + 65: "ia", + 66: "id", + 67: "ie", + 68: "ig", + 69: "ii", + 70: "ik", + 71: "io", + 72: "is", + 73: "it", + 74: "iu", + 75: "ja", + 76: "jv", + 77: "ka", + 78: "kg", + 79: "ki", + 80: "kj", + 81: "kk", + 82: "kl", + 83: "km", + 84: "kn", + 85: "ko", + 86: "kr", + 87: "ks", + 88: "ku", + 89: "kv", + 90: "kw", + 91: "ky", + 92: "la", + 93: "lb", + 94: "lg", + 95: "li", + 96: "ln", + 97: "lo", + 98: "lt", + 99: "lu", + 100: "lv", + 101: "mg", + 102: "mh", + 103: "mi", + 104: "mk", + 105: "ml", + 106: "mn", + 107: "mr", + 108: "ms", + 109: "mt", + 110: "my", + 111: "na", + 112: "nb", + 113: "nd", + 114: "ne", + 115: "ng", + 116: "nl", + 117: "nn", + 118: "no", + 119: "nr", + 120: "nv", + 121: "ny", + 122: "oc", + 123: "oj", + 124: "om", + 125: "or", + 126: "os", + 127: "pa", + 128: "pi", + 129: "pl", + 130: "ps", + 131: "pt", + 132: "qu", + 133: "rm", + 134: "rn", + 135: "ro", + 136: "ru", + 137: "rw", + 138: "sa", + 139: "sc", + 140: "sd", + 141: "se", + 142: "sg", + 143: "si", + 144: "sk", + 145: "sl", + 146: "sm", + 147: "sn", + 148: "so", + 149: "sq", + 150: "sr", + 151: "ss", + 152: "st", + 153: "su", + 154: "sv", + 155: "sw", + 156: "ta", + 157: "te", + 158: "tg", + 159: "th", + 160: "ti", + 161: "tk", + 162: "tl", + 163: "tn", + 164: "to", + 165: "tr", + 166: "ts", + 167: "tt", + 168: "tw", + 169: "ty", + 170: "ug", + 171: "uk", + 172: "ur", + 173: "uz", + 174: "ve", + 175: "vi", + 176: "vo", + 177: "wa", + 178: "wo", + 179: "xh", + 180: "yi", + 181: "yo", + 182: "za", + 183: "zh", + 184: "zu", + } + Language_Language_value = map[string]int32{ + "UNKNOWN_LANGUAGE": 0, + "en": 1, + "aa": 2, + "ab": 3, + "ae": 4, + "af": 5, + "ak": 6, + "am": 7, + "an": 8, + "ar": 9, + "as": 10, + "av": 11, + "ay": 12, + "az": 13, + "ba": 14, + "be": 15, + "bg": 16, + "bh": 17, + "bi": 18, + "bm": 19, + "bn": 20, + "bo": 21, + "br": 22, + "bs": 23, + "ca": 24, + "ce": 25, + "ch": 26, + "co": 27, + "cr": 28, + "cs": 29, + "cu": 30, + "cv": 31, + "cy": 32, + "da": 33, + "de": 34, + "dv": 35, + "dz": 36, + "ee": 37, + "el": 38, + "eo": 39, + "es": 40, + "et": 41, + "eu": 42, + "fa": 43, + "ff": 44, + "fi": 45, + "fj": 46, + "fo": 47, + "fr": 48, + "fy": 49, + "ga": 50, + "gd": 51, + "gl": 52, + "gn": 53, + "gu": 54, + "gv": 55, + "ha": 56, + "he": 57, + "hi": 58, + "ho": 59, + "hr": 60, + "ht": 61, + "hu": 62, + "hy": 63, + "hz": 64, + "ia": 65, + "id": 66, + "ie": 67, + "ig": 68, + "ii": 69, + "ik": 70, + "io": 71, + "is": 72, + "it": 73, + "iu": 74, + "ja": 75, + "jv": 76, + "ka": 77, + "kg": 78, + "ki": 79, + "kj": 80, + "kk": 81, + "kl": 82, + "km": 83, + "kn": 84, + "ko": 85, + "kr": 86, + "ks": 87, + "ku": 88, + "kv": 89, + "kw": 90, + "ky": 91, + "la": 92, + "lb": 93, + "lg": 94, + "li": 95, + "ln": 96, + "lo": 97, + "lt": 98, + "lu": 99, + "lv": 100, + "mg": 101, + "mh": 102, + "mi": 103, + "mk": 104, + "ml": 105, + "mn": 106, + "mr": 107, + "ms": 108, + "mt": 109, + "my": 110, + "na": 111, + "nb": 112, + "nd": 113, + "ne": 114, + "ng": 115, + "nl": 116, + "nn": 117, + "no": 118, + "nr": 119, + "nv": 120, + "ny": 121, + "oc": 122, + "oj": 123, + "om": 124, + "or": 125, + "os": 126, + "pa": 127, + "pi": 128, + "pl": 129, + "ps": 130, + "pt": 131, + "qu": 132, + "rm": 133, + "rn": 134, + "ro": 135, + "ru": 136, + "rw": 137, + "sa": 138, + "sc": 139, + "sd": 140, + "se": 141, + "sg": 142, + "si": 143, + "sk": 144, + "sl": 145, + "sm": 146, + "sn": 147, + "so": 148, + "sq": 149, + "sr": 150, + "ss": 151, + "st": 152, + "su": 153, + "sv": 154, + "sw": 155, + "ta": 156, + "te": 157, + "tg": 158, + "th": 159, + "ti": 160, + "tk": 161, + "tl": 162, + "tn": 163, + "to": 164, + "tr": 165, + "ts": 166, + "tt": 167, + "tw": 168, + "ty": 169, + "ug": 170, + "uk": 171, + "ur": 172, + "uz": 173, + "ve": 174, + "vi": 175, + "vo": 176, + "wa": 177, + "wo": 178, + "xh": 179, + "yi": 180, + "yo": 181, + "za": 182, + "zh": 183, + "zu": 184, + } +) + +func (x Language_Language) Enum() *Language_Language { + p := new(Language_Language) + *p = x + return p +} + +func (x Language_Language) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Language_Language) Descriptor() protoreflect.EnumDescriptor { + return file_claim_proto_enumTypes[3].Descriptor() +} + +func (Language_Language) Type() protoreflect.EnumType { + return &file_claim_proto_enumTypes[3] +} + +func (x Language_Language) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Language_Language.Descriptor instead. +func (Language_Language) EnumDescriptor() ([]byte, []int) { + return file_claim_proto_rawDescGZIP(), []int{11, 0} +} + +// ISO 15924 +type Language_Script int32 + +const ( + Language_UNKNOWN_SCRIPT Language_Script = 0 + Language_Adlm Language_Script = 1 + Language_Afak Language_Script = 2 + Language_Aghb Language_Script = 3 + Language_Ahom Language_Script = 4 + Language_Arab Language_Script = 5 + Language_Aran Language_Script = 6 + Language_Armi Language_Script = 7 + Language_Armn Language_Script = 8 + Language_Avst Language_Script = 9 + Language_Bali Language_Script = 10 + Language_Bamu Language_Script = 11 + Language_Bass Language_Script = 12 + Language_Batk Language_Script = 13 + Language_Beng Language_Script = 14 + Language_Bhks Language_Script = 15 + Language_Blis Language_Script = 16 + Language_Bopo Language_Script = 17 + Language_Brah Language_Script = 18 + Language_Brai Language_Script = 19 + Language_Bugi Language_Script = 20 + Language_Buhd Language_Script = 21 + Language_Cakm Language_Script = 22 + Language_Cans Language_Script = 23 + Language_Cari Language_Script = 24 + Language_Cham Language_Script = 25 + Language_Cher Language_Script = 26 + Language_Cirt Language_Script = 27 + Language_Copt Language_Script = 28 + Language_Cpmn Language_Script = 29 + Language_Cprt Language_Script = 30 + Language_Cyrl Language_Script = 31 + Language_Cyrs Language_Script = 32 + Language_Deva Language_Script = 33 + Language_Dogr Language_Script = 34 + Language_Dsrt Language_Script = 35 + Language_Dupl Language_Script = 36 + Language_Egyd Language_Script = 37 + Language_Egyh Language_Script = 38 + Language_Egyp Language_Script = 39 + Language_Elba Language_Script = 40 + Language_Elym Language_Script = 41 + Language_Ethi Language_Script = 42 + Language_Geok Language_Script = 43 + Language_Geor Language_Script = 44 + Language_Glag Language_Script = 45 + Language_Gong Language_Script = 46 + Language_Gonm Language_Script = 47 + Language_Goth Language_Script = 48 + Language_Gran Language_Script = 49 + Language_Grek Language_Script = 50 + Language_Gujr Language_Script = 51 + Language_Guru Language_Script = 52 + Language_Hanb Language_Script = 53 + Language_Hang Language_Script = 54 + Language_Hani Language_Script = 55 + Language_Hano Language_Script = 56 + Language_Hans Language_Script = 57 + Language_Hant Language_Script = 58 + Language_Hatr Language_Script = 59 + Language_Hebr Language_Script = 60 + Language_Hira Language_Script = 61 + Language_Hluw Language_Script = 62 + Language_Hmng Language_Script = 63 + Language_Hmnp Language_Script = 64 + Language_Hrkt Language_Script = 65 + Language_Hung Language_Script = 66 + Language_Inds Language_Script = 67 + Language_Ital Language_Script = 68 + Language_Jamo Language_Script = 69 + Language_Java Language_Script = 70 + Language_Jpan Language_Script = 71 + Language_Jurc Language_Script = 72 + Language_Kali Language_Script = 73 + Language_Kana Language_Script = 74 + Language_Khar Language_Script = 75 + Language_Khmr Language_Script = 76 + Language_Khoj Language_Script = 77 + Language_Kitl Language_Script = 78 + Language_Kits Language_Script = 79 + Language_Knda Language_Script = 80 + Language_Kore Language_Script = 81 + Language_Kpel Language_Script = 82 + Language_Kthi Language_Script = 83 + Language_Lana Language_Script = 84 + Language_Laoo Language_Script = 85 + Language_Latf Language_Script = 86 + Language_Latg Language_Script = 87 + Language_Latn Language_Script = 88 + Language_Leke Language_Script = 89 + Language_Lepc Language_Script = 90 + Language_Limb Language_Script = 91 + Language_Lina Language_Script = 92 + Language_Linb Language_Script = 93 + Language_Lisu Language_Script = 94 + Language_Loma Language_Script = 95 + Language_Lyci Language_Script = 96 + Language_Lydi Language_Script = 97 + Language_Mahj Language_Script = 98 + Language_Maka Language_Script = 99 + Language_Mand Language_Script = 100 + Language_Mani Language_Script = 101 + Language_Marc Language_Script = 102 + Language_Maya Language_Script = 103 + Language_Medf Language_Script = 104 + Language_Mend Language_Script = 105 + Language_Merc Language_Script = 106 + Language_Mero Language_Script = 107 + Language_Mlym Language_Script = 108 + Language_Modi Language_Script = 109 + Language_Mong Language_Script = 110 + Language_Moon Language_Script = 111 + Language_Mroo Language_Script = 112 + Language_Mtei Language_Script = 113 + Language_Mult Language_Script = 114 + Language_Mymr Language_Script = 115 + Language_Nand Language_Script = 116 + Language_Narb Language_Script = 117 + Language_Nbat Language_Script = 118 + Language_Newa Language_Script = 119 + Language_Nkdb Language_Script = 120 + Language_Nkgb Language_Script = 121 + Language_Nkoo Language_Script = 122 + Language_Nshu Language_Script = 123 + Language_Ogam Language_Script = 124 + Language_Olck Language_Script = 125 + Language_Orkh Language_Script = 126 + Language_Orya Language_Script = 127 + Language_Osge Language_Script = 128 + Language_Osma Language_Script = 129 + Language_Palm Language_Script = 130 + Language_Pauc Language_Script = 131 + Language_Perm Language_Script = 132 + Language_Phag Language_Script = 133 + Language_Phli Language_Script = 134 + Language_Phlp Language_Script = 135 + Language_Phlv Language_Script = 136 + Language_Phnx Language_Script = 137 + Language_Plrd Language_Script = 138 + Language_Piqd Language_Script = 139 + Language_Prti Language_Script = 140 + Language_Qaaa Language_Script = 141 + Language_Qabx Language_Script = 142 + Language_Rjng Language_Script = 143 + Language_Rohg Language_Script = 144 + Language_Roro Language_Script = 145 + Language_Runr Language_Script = 146 + Language_Samr Language_Script = 147 + Language_Sara Language_Script = 148 + Language_Sarb Language_Script = 149 + Language_Saur Language_Script = 150 + Language_Sgnw Language_Script = 151 + Language_Shaw Language_Script = 152 + Language_Shrd Language_Script = 153 + Language_Shui Language_Script = 154 + Language_Sidd Language_Script = 155 + Language_Sind Language_Script = 156 + Language_Sinh Language_Script = 157 + Language_Sogd Language_Script = 158 + Language_Sogo Language_Script = 159 + Language_Sora Language_Script = 160 + Language_Soyo Language_Script = 161 + Language_Sund Language_Script = 162 + Language_Sylo Language_Script = 163 + Language_Syrc Language_Script = 164 + Language_Syre Language_Script = 165 + Language_Syrj Language_Script = 166 + Language_Syrn Language_Script = 167 + Language_Tagb Language_Script = 168 + Language_Takr Language_Script = 169 + Language_Tale Language_Script = 170 + Language_Talu Language_Script = 171 + Language_Taml Language_Script = 172 + Language_Tang Language_Script = 173 + Language_Tavt Language_Script = 174 + Language_Telu Language_Script = 175 + Language_Teng Language_Script = 176 + Language_Tfng Language_Script = 177 + Language_Tglg Language_Script = 178 + Language_Thaa Language_Script = 179 + Language_Thai Language_Script = 180 + Language_Tibt Language_Script = 181 + Language_Tirh Language_Script = 182 + Language_Ugar Language_Script = 183 + Language_Vaii Language_Script = 184 + Language_Visp Language_Script = 185 + Language_Wara Language_Script = 186 + Language_Wcho Language_Script = 187 + Language_Wole Language_Script = 188 + Language_Xpeo Language_Script = 189 + Language_Xsux Language_Script = 190 + Language_Yiii Language_Script = 191 + Language_Zanb Language_Script = 192 + Language_Zinh Language_Script = 193 + Language_Zmth Language_Script = 194 + Language_Zsye Language_Script = 195 + Language_Zsym Language_Script = 196 + Language_Zxxx Language_Script = 197 + Language_Zyyy Language_Script = 198 + Language_Zzzz Language_Script = 199 +) + +// Enum value maps for Language_Script. +var ( + Language_Script_name = map[int32]string{ + 0: "UNKNOWN_SCRIPT", + 1: "Adlm", + 2: "Afak", + 3: "Aghb", + 4: "Ahom", + 5: "Arab", + 6: "Aran", + 7: "Armi", + 8: "Armn", + 9: "Avst", + 10: "Bali", + 11: "Bamu", + 12: "Bass", + 13: "Batk", + 14: "Beng", + 15: "Bhks", + 16: "Blis", + 17: "Bopo", + 18: "Brah", + 19: "Brai", + 20: "Bugi", + 21: "Buhd", + 22: "Cakm", + 23: "Cans", + 24: "Cari", + 25: "Cham", + 26: "Cher", + 27: "Cirt", + 28: "Copt", + 29: "Cpmn", + 30: "Cprt", + 31: "Cyrl", + 32: "Cyrs", + 33: "Deva", + 34: "Dogr", + 35: "Dsrt", + 36: "Dupl", + 37: "Egyd", + 38: "Egyh", + 39: "Egyp", + 40: "Elba", + 41: "Elym", + 42: "Ethi", + 43: "Geok", + 44: "Geor", + 45: "Glag", + 46: "Gong", + 47: "Gonm", + 48: "Goth", + 49: "Gran", + 50: "Grek", + 51: "Gujr", + 52: "Guru", + 53: "Hanb", + 54: "Hang", + 55: "Hani", + 56: "Hano", + 57: "Hans", + 58: "Hant", + 59: "Hatr", + 60: "Hebr", + 61: "Hira", + 62: "Hluw", + 63: "Hmng", + 64: "Hmnp", + 65: "Hrkt", + 66: "Hung", + 67: "Inds", + 68: "Ital", + 69: "Jamo", + 70: "Java", + 71: "Jpan", + 72: "Jurc", + 73: "Kali", + 74: "Kana", + 75: "Khar", + 76: "Khmr", + 77: "Khoj", + 78: "Kitl", + 79: "Kits", + 80: "Knda", + 81: "Kore", + 82: "Kpel", + 83: "Kthi", + 84: "Lana", + 85: "Laoo", + 86: "Latf", + 87: "Latg", + 88: "Latn", + 89: "Leke", + 90: "Lepc", + 91: "Limb", + 92: "Lina", + 93: "Linb", + 94: "Lisu", + 95: "Loma", + 96: "Lyci", + 97: "Lydi", + 98: "Mahj", + 99: "Maka", + 100: "Mand", + 101: "Mani", + 102: "Marc", + 103: "Maya", + 104: "Medf", + 105: "Mend", + 106: "Merc", + 107: "Mero", + 108: "Mlym", + 109: "Modi", + 110: "Mong", + 111: "Moon", + 112: "Mroo", + 113: "Mtei", + 114: "Mult", + 115: "Mymr", + 116: "Nand", + 117: "Narb", + 118: "Nbat", + 119: "Newa", + 120: "Nkdb", + 121: "Nkgb", + 122: "Nkoo", + 123: "Nshu", + 124: "Ogam", + 125: "Olck", + 126: "Orkh", + 127: "Orya", + 128: "Osge", + 129: "Osma", + 130: "Palm", + 131: "Pauc", + 132: "Perm", + 133: "Phag", + 134: "Phli", + 135: "Phlp", + 136: "Phlv", + 137: "Phnx", + 138: "Plrd", + 139: "Piqd", + 140: "Prti", + 141: "Qaaa", + 142: "Qabx", + 143: "Rjng", + 144: "Rohg", + 145: "Roro", + 146: "Runr", + 147: "Samr", + 148: "Sara", + 149: "Sarb", + 150: "Saur", + 151: "Sgnw", + 152: "Shaw", + 153: "Shrd", + 154: "Shui", + 155: "Sidd", + 156: "Sind", + 157: "Sinh", + 158: "Sogd", + 159: "Sogo", + 160: "Sora", + 161: "Soyo", + 162: "Sund", + 163: "Sylo", + 164: "Syrc", + 165: "Syre", + 166: "Syrj", + 167: "Syrn", + 168: "Tagb", + 169: "Takr", + 170: "Tale", + 171: "Talu", + 172: "Taml", + 173: "Tang", + 174: "Tavt", + 175: "Telu", + 176: "Teng", + 177: "Tfng", + 178: "Tglg", + 179: "Thaa", + 180: "Thai", + 181: "Tibt", + 182: "Tirh", + 183: "Ugar", + 184: "Vaii", + 185: "Visp", + 186: "Wara", + 187: "Wcho", + 188: "Wole", + 189: "Xpeo", + 190: "Xsux", + 191: "Yiii", + 192: "Zanb", + 193: "Zinh", + 194: "Zmth", + 195: "Zsye", + 196: "Zsym", + 197: "Zxxx", + 198: "Zyyy", + 199: "Zzzz", + } + Language_Script_value = map[string]int32{ + "UNKNOWN_SCRIPT": 0, + "Adlm": 1, + "Afak": 2, + "Aghb": 3, + "Ahom": 4, + "Arab": 5, + "Aran": 6, + "Armi": 7, + "Armn": 8, + "Avst": 9, + "Bali": 10, + "Bamu": 11, + "Bass": 12, + "Batk": 13, + "Beng": 14, + "Bhks": 15, + "Blis": 16, + "Bopo": 17, + "Brah": 18, + "Brai": 19, + "Bugi": 20, + "Buhd": 21, + "Cakm": 22, + "Cans": 23, + "Cari": 24, + "Cham": 25, + "Cher": 26, + "Cirt": 27, + "Copt": 28, + "Cpmn": 29, + "Cprt": 30, + "Cyrl": 31, + "Cyrs": 32, + "Deva": 33, + "Dogr": 34, + "Dsrt": 35, + "Dupl": 36, + "Egyd": 37, + "Egyh": 38, + "Egyp": 39, + "Elba": 40, + "Elym": 41, + "Ethi": 42, + "Geok": 43, + "Geor": 44, + "Glag": 45, + "Gong": 46, + "Gonm": 47, + "Goth": 48, + "Gran": 49, + "Grek": 50, + "Gujr": 51, + "Guru": 52, + "Hanb": 53, + "Hang": 54, + "Hani": 55, + "Hano": 56, + "Hans": 57, + "Hant": 58, + "Hatr": 59, + "Hebr": 60, + "Hira": 61, + "Hluw": 62, + "Hmng": 63, + "Hmnp": 64, + "Hrkt": 65, + "Hung": 66, + "Inds": 67, + "Ital": 68, + "Jamo": 69, + "Java": 70, + "Jpan": 71, + "Jurc": 72, + "Kali": 73, + "Kana": 74, + "Khar": 75, + "Khmr": 76, + "Khoj": 77, + "Kitl": 78, + "Kits": 79, + "Knda": 80, + "Kore": 81, + "Kpel": 82, + "Kthi": 83, + "Lana": 84, + "Laoo": 85, + "Latf": 86, + "Latg": 87, + "Latn": 88, + "Leke": 89, + "Lepc": 90, + "Limb": 91, + "Lina": 92, + "Linb": 93, + "Lisu": 94, + "Loma": 95, + "Lyci": 96, + "Lydi": 97, + "Mahj": 98, + "Maka": 99, + "Mand": 100, + "Mani": 101, + "Marc": 102, + "Maya": 103, + "Medf": 104, + "Mend": 105, + "Merc": 106, + "Mero": 107, + "Mlym": 108, + "Modi": 109, + "Mong": 110, + "Moon": 111, + "Mroo": 112, + "Mtei": 113, + "Mult": 114, + "Mymr": 115, + "Nand": 116, + "Narb": 117, + "Nbat": 118, + "Newa": 119, + "Nkdb": 120, + "Nkgb": 121, + "Nkoo": 122, + "Nshu": 123, + "Ogam": 124, + "Olck": 125, + "Orkh": 126, + "Orya": 127, + "Osge": 128, + "Osma": 129, + "Palm": 130, + "Pauc": 131, + "Perm": 132, + "Phag": 133, + "Phli": 134, + "Phlp": 135, + "Phlv": 136, + "Phnx": 137, + "Plrd": 138, + "Piqd": 139, + "Prti": 140, + "Qaaa": 141, + "Qabx": 142, + "Rjng": 143, + "Rohg": 144, + "Roro": 145, + "Runr": 146, + "Samr": 147, + "Sara": 148, + "Sarb": 149, + "Saur": 150, + "Sgnw": 151, + "Shaw": 152, + "Shrd": 153, + "Shui": 154, + "Sidd": 155, + "Sind": 156, + "Sinh": 157, + "Sogd": 158, + "Sogo": 159, + "Sora": 160, + "Soyo": 161, + "Sund": 162, + "Sylo": 163, + "Syrc": 164, + "Syre": 165, + "Syrj": 166, + "Syrn": 167, + "Tagb": 168, + "Takr": 169, + "Tale": 170, + "Talu": 171, + "Taml": 172, + "Tang": 173, + "Tavt": 174, + "Telu": 175, + "Teng": 176, + "Tfng": 177, + "Tglg": 178, + "Thaa": 179, + "Thai": 180, + "Tibt": 181, + "Tirh": 182, + "Ugar": 183, + "Vaii": 184, + "Visp": 185, + "Wara": 186, + "Wcho": 187, + "Wole": 188, + "Xpeo": 189, + "Xsux": 190, + "Yiii": 191, + "Zanb": 192, + "Zinh": 193, + "Zmth": 194, + "Zsye": 195, + "Zsym": 196, + "Zxxx": 197, + "Zyyy": 198, + "Zzzz": 199, + } +) + +func (x Language_Script) Enum() *Language_Script { + p := new(Language_Script) + *p = x + return p +} + +func (x Language_Script) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Language_Script) Descriptor() protoreflect.EnumDescriptor { + return file_claim_proto_enumTypes[4].Descriptor() +} + +func (Language_Script) Type() protoreflect.EnumType { + return &file_claim_proto_enumTypes[4] +} + +func (x Language_Script) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Language_Script.Descriptor instead. +func (Language_Script) EnumDescriptor() ([]byte, []int) { + return file_claim_proto_rawDescGZIP(), []int{11, 1} +} + +type Location_Country int32 + +const ( + Location_UNKNOWN_COUNTRY Location_Country = 0 + Location_AF Location_Country = 1 + Location_AX Location_Country = 2 + Location_AL Location_Country = 3 + Location_DZ Location_Country = 4 + Location_AS Location_Country = 5 + Location_AD Location_Country = 6 + Location_AO Location_Country = 7 + Location_AI Location_Country = 8 + Location_AQ Location_Country = 9 + Location_AG Location_Country = 10 + Location_AR Location_Country = 11 + Location_AM Location_Country = 12 + Location_AW Location_Country = 13 + Location_AU Location_Country = 14 + Location_AT Location_Country = 15 + Location_AZ Location_Country = 16 + Location_BS Location_Country = 17 + Location_BH Location_Country = 18 + Location_BD Location_Country = 19 + Location_BB Location_Country = 20 + Location_BY Location_Country = 21 + Location_BE Location_Country = 22 + Location_BZ Location_Country = 23 + Location_BJ Location_Country = 24 + Location_BM Location_Country = 25 + Location_BT Location_Country = 26 + Location_BO Location_Country = 27 + Location_BQ Location_Country = 28 + Location_BA Location_Country = 29 + Location_BW Location_Country = 30 + Location_BV Location_Country = 31 + Location_BR Location_Country = 32 + Location_IO Location_Country = 33 + Location_BN Location_Country = 34 + Location_BG Location_Country = 35 + Location_BF Location_Country = 36 + Location_BI Location_Country = 37 + Location_KH Location_Country = 38 + Location_CM Location_Country = 39 + Location_CA Location_Country = 40 + Location_CV Location_Country = 41 + Location_KY Location_Country = 42 + Location_CF Location_Country = 43 + Location_TD Location_Country = 44 + Location_CL Location_Country = 45 + Location_CN Location_Country = 46 + Location_CX Location_Country = 47 + Location_CC Location_Country = 48 + Location_CO Location_Country = 49 + Location_KM Location_Country = 50 + Location_CG Location_Country = 51 + Location_CD Location_Country = 52 + Location_CK Location_Country = 53 + Location_CR Location_Country = 54 + Location_CI Location_Country = 55 + Location_HR Location_Country = 56 + Location_CU Location_Country = 57 + Location_CW Location_Country = 58 + Location_CY Location_Country = 59 + Location_CZ Location_Country = 60 + Location_DK Location_Country = 61 + Location_DJ Location_Country = 62 + Location_DM Location_Country = 63 + Location_DO Location_Country = 64 + Location_EC Location_Country = 65 + Location_EG Location_Country = 66 + Location_SV Location_Country = 67 + Location_GQ Location_Country = 68 + Location_ER Location_Country = 69 + Location_EE Location_Country = 70 + Location_ET Location_Country = 71 + Location_FK Location_Country = 72 + Location_FO Location_Country = 73 + Location_FJ Location_Country = 74 + Location_FI Location_Country = 75 + Location_FR Location_Country = 76 + Location_GF Location_Country = 77 + Location_PF Location_Country = 78 + Location_TF Location_Country = 79 + Location_GA Location_Country = 80 + Location_GM Location_Country = 81 + Location_GE Location_Country = 82 + Location_DE Location_Country = 83 + Location_GH Location_Country = 84 + Location_GI Location_Country = 85 + Location_GR Location_Country = 86 + Location_GL Location_Country = 87 + Location_GD Location_Country = 88 + Location_GP Location_Country = 89 + Location_GU Location_Country = 90 + Location_GT Location_Country = 91 + Location_GG Location_Country = 92 + Location_GN Location_Country = 93 + Location_GW Location_Country = 94 + Location_GY Location_Country = 95 + Location_HT Location_Country = 96 + Location_HM Location_Country = 97 + Location_VA Location_Country = 98 + Location_HN Location_Country = 99 + Location_HK Location_Country = 100 + Location_HU Location_Country = 101 + Location_IS Location_Country = 102 + Location_IN Location_Country = 103 + Location_ID Location_Country = 104 + Location_IR Location_Country = 105 + Location_IQ Location_Country = 106 + Location_IE Location_Country = 107 + Location_IM Location_Country = 108 + Location_IL Location_Country = 109 + Location_IT Location_Country = 110 + Location_JM Location_Country = 111 + Location_JP Location_Country = 112 + Location_JE Location_Country = 113 + Location_JO Location_Country = 114 + Location_KZ Location_Country = 115 + Location_KE Location_Country = 116 + Location_KI Location_Country = 117 + Location_KP Location_Country = 118 + Location_KR Location_Country = 119 + Location_KW Location_Country = 120 + Location_KG Location_Country = 121 + Location_LA Location_Country = 122 + Location_LV Location_Country = 123 + Location_LB Location_Country = 124 + Location_LS Location_Country = 125 + Location_LR Location_Country = 126 + Location_LY Location_Country = 127 + Location_LI Location_Country = 128 + Location_LT Location_Country = 129 + Location_LU Location_Country = 130 + Location_MO Location_Country = 131 + Location_MK Location_Country = 132 + Location_MG Location_Country = 133 + Location_MW Location_Country = 134 + Location_MY Location_Country = 135 + Location_MV Location_Country = 136 + Location_ML Location_Country = 137 + Location_MT Location_Country = 138 + Location_MH Location_Country = 139 + Location_MQ Location_Country = 140 + Location_MR Location_Country = 141 + Location_MU Location_Country = 142 + Location_YT Location_Country = 143 + Location_MX Location_Country = 144 + Location_FM Location_Country = 145 + Location_MD Location_Country = 146 + Location_MC Location_Country = 147 + Location_MN Location_Country = 148 + Location_ME Location_Country = 149 + Location_MS Location_Country = 150 + Location_MA Location_Country = 151 + Location_MZ Location_Country = 152 + Location_MM Location_Country = 153 + Location_NA Location_Country = 154 + Location_NR Location_Country = 155 + Location_NP Location_Country = 156 + Location_NL Location_Country = 157 + Location_NC Location_Country = 158 + Location_NZ Location_Country = 159 + Location_NI Location_Country = 160 + Location_NE Location_Country = 161 + Location_NG Location_Country = 162 + Location_NU Location_Country = 163 + Location_NF Location_Country = 164 + Location_MP Location_Country = 165 + Location_NO Location_Country = 166 + Location_OM Location_Country = 167 + Location_PK Location_Country = 168 + Location_PW Location_Country = 169 + Location_PS Location_Country = 170 + Location_PA Location_Country = 171 + Location_PG Location_Country = 172 + Location_PY Location_Country = 173 + Location_PE Location_Country = 174 + Location_PH Location_Country = 175 + Location_PN Location_Country = 176 + Location_PL Location_Country = 177 + Location_PT Location_Country = 178 + Location_PR Location_Country = 179 + Location_QA Location_Country = 180 + Location_RE Location_Country = 181 + Location_RO Location_Country = 182 + Location_RU Location_Country = 183 + Location_RW Location_Country = 184 + Location_BL Location_Country = 185 + Location_SH Location_Country = 186 + Location_KN Location_Country = 187 + Location_LC Location_Country = 188 + Location_MF Location_Country = 189 + Location_PM Location_Country = 190 + Location_VC Location_Country = 191 + Location_WS Location_Country = 192 + Location_SM Location_Country = 193 + Location_ST Location_Country = 194 + Location_SA Location_Country = 195 + Location_SN Location_Country = 196 + Location_RS Location_Country = 197 + Location_SC Location_Country = 198 + Location_SL Location_Country = 199 + Location_SG Location_Country = 200 + Location_SX Location_Country = 201 + Location_SK Location_Country = 202 + Location_SI Location_Country = 203 + Location_SB Location_Country = 204 + Location_SO Location_Country = 205 + Location_ZA Location_Country = 206 + Location_GS Location_Country = 207 + Location_SS Location_Country = 208 + Location_ES Location_Country = 209 + Location_LK Location_Country = 210 + Location_SD Location_Country = 211 + Location_SR Location_Country = 212 + Location_SJ Location_Country = 213 + Location_SZ Location_Country = 214 + Location_SE Location_Country = 215 + Location_CH Location_Country = 216 + Location_SY Location_Country = 217 + Location_TW Location_Country = 218 + Location_TJ Location_Country = 219 + Location_TZ Location_Country = 220 + Location_TH Location_Country = 221 + Location_TL Location_Country = 222 + Location_TG Location_Country = 223 + Location_TK Location_Country = 224 + Location_TO Location_Country = 225 + Location_TT Location_Country = 226 + Location_TN Location_Country = 227 + Location_TR Location_Country = 228 + Location_TM Location_Country = 229 + Location_TC Location_Country = 230 + Location_TV Location_Country = 231 + Location_UG Location_Country = 232 + Location_UA Location_Country = 233 + Location_AE Location_Country = 234 + Location_GB Location_Country = 235 + Location_US Location_Country = 236 + Location_UM Location_Country = 237 + Location_UY Location_Country = 238 + Location_UZ Location_Country = 239 + Location_VU Location_Country = 240 + Location_VE Location_Country = 241 + Location_VN Location_Country = 242 + Location_VG Location_Country = 243 + Location_VI Location_Country = 244 + Location_WF Location_Country = 245 + Location_EH Location_Country = 246 + Location_YE Location_Country = 247 + Location_ZM Location_Country = 248 + Location_ZW Location_Country = 249 + // UN M.49 Geographic Regions + Location_R001 Location_Country = 250 // World + Location_R002 Location_Country = 251 // Africa + Location_R015 Location_Country = 252 // Northern Africa + Location_R012 Location_Country = 253 // Algeria DZA + Location_R818 Location_Country = 254 // Egypt EGY + Location_R434 Location_Country = 255 // Libya LBY + Location_R504 Location_Country = 256 // Morocco MAR + Location_R729 Location_Country = 257 // Sudan SDN LDC + Location_R788 Location_Country = 258 // Tunisia TUN + Location_R732 Location_Country = 259 // Western Sahara ESH + Location_R202 Location_Country = 260 // Sub-Saharan Africa + Location_R014 Location_Country = 261 // Eastern Africa + Location_R086 Location_Country = 262 // British Indian Ocean Territory IOT + Location_R108 Location_Country = 263 // Burundi BDI LDC LLDC + Location_R174 Location_Country = 264 // Comoros COM LDC SIDS + Location_R262 Location_Country = 265 // Djibouti DJI LDC + Location_R232 Location_Country = 266 // Eritrea ERI LDC + Location_R231 Location_Country = 267 // Ethiopia ETH LDC LLDC + Location_R260 Location_Country = 268 // French Southern Territories ATF + Location_R404 Location_Country = 269 // Kenya KEN + Location_R450 Location_Country = 270 // Madagascar MDG LDC + Location_R454 Location_Country = 271 // Malawi MWI LDC LLDC + Location_R480 Location_Country = 272 // Mauritius MUS SIDS + Location_R175 Location_Country = 273 // Mayotte MYT + Location_R508 Location_Country = 274 // Mozambique MOZ LDC + Location_R638 Location_Country = 275 // Réunion REU + Location_R646 Location_Country = 276 // Rwanda RWA LDC LLDC + Location_R690 Location_Country = 277 // Seychelles SYC SIDS + Location_R706 Location_Country = 278 // Somalia SOM LDC + Location_R728 Location_Country = 279 // South Sudan SSD LDC LLDC + Location_R800 Location_Country = 280 // Uganda UGA LDC LLDC + Location_R834 Location_Country = 281 // United Republic of Tanzania TZA LDC + Location_R894 Location_Country = 282 // Zambia ZMB LDC LLDC + Location_R716 Location_Country = 283 // Zimbabwe ZWE LLDC + Location_R017 Location_Country = 284 // Middle Africa + Location_R024 Location_Country = 285 // Angola AGO LDC + Location_R120 Location_Country = 286 // Cameroon CMR + Location_R140 Location_Country = 287 // Central African Republic CAF LDC LLDC + Location_R148 Location_Country = 288 // Chad TCD LDC LLDC + Location_R178 Location_Country = 289 // Congo COG + Location_R180 Location_Country = 290 // Democratic Republic of the Congo COD LDC + Location_R226 Location_Country = 291 // Equatorial Guinea GNQ + Location_R266 Location_Country = 292 // Gabon GAB + Location_R678 Location_Country = 293 // Sao Tome and Principe STP LDC SIDS + Location_R018 Location_Country = 294 // Southern Africa + Location_R072 Location_Country = 295 // Botswana BWA LLDC + Location_R748 Location_Country = 296 // Eswatini SWZ LLDC + Location_R426 Location_Country = 297 // Lesotho LSO LDC LLDC + Location_R516 Location_Country = 298 // Namibia NAM + Location_R710 Location_Country = 299 // South Africa ZAF + Location_R011 Location_Country = 300 // Western Africa + Location_R204 Location_Country = 301 // Benin BEN LDC + Location_R854 Location_Country = 302 // Burkina Faso BFA LDC LLDC + Location_R132 Location_Country = 303 // Cabo Verde CPV SIDS + Location_R384 Location_Country = 304 // Côte d’Ivoire CIV + Location_R270 Location_Country = 305 // Gambia GMB LDC + Location_R288 Location_Country = 306 // Ghana GHA + Location_R324 Location_Country = 307 // Guinea GIN LDC + Location_R624 Location_Country = 308 // Guinea-Bissau GNB LDC SIDS + Location_R430 Location_Country = 309 // Liberia LBR LDC + Location_R466 Location_Country = 310 // Mali MLI LDC LLDC + Location_R478 Location_Country = 311 // Mauritania MRT LDC + Location_R562 Location_Country = 312 // Niger NER LDC LLDC + Location_R566 Location_Country = 313 // Nigeria NGA + Location_R654 Location_Country = 314 // Saint Helena SHN + Location_R686 Location_Country = 315 // Senegal SEN LDC + Location_R694 Location_Country = 316 // Sierra Leone SLE LDC + Location_R768 Location_Country = 317 // Togo TGO LDC + Location_R019 Location_Country = 318 // Americas + Location_R419 Location_Country = 319 // Latin America and the Caribbean + Location_R029 Location_Country = 320 // Caribbean + Location_R660 Location_Country = 321 // Anguilla AIA SIDS + Location_R028 Location_Country = 322 // Antigua and Barbuda ATG SIDS + Location_R533 Location_Country = 323 // Aruba ABW SIDS + Location_R044 Location_Country = 324 // Bahamas BHS SIDS + Location_R052 Location_Country = 325 // Barbados BRB SIDS + Location_R535 Location_Country = 326 // Bonaire, Sint Eustatius and Saba BES SIDS + Location_R092 Location_Country = 327 // British Virgin Islands VGB SIDS + Location_R136 Location_Country = 328 // Cayman Islands CYM + Location_R192 Location_Country = 329 // Cuba CUB SIDS + Location_R531 Location_Country = 330 // Curaçao CUW SIDS + Location_R212 Location_Country = 331 // Dominica DMA SIDS + Location_R214 Location_Country = 332 // Dominican Republic DOM SIDS + Location_R308 Location_Country = 333 // Grenada GRD SIDS + Location_R312 Location_Country = 334 // Guadeloupe GLP + Location_R332 Location_Country = 335 // Haiti HTI LDC SIDS + Location_R388 Location_Country = 336 // Jamaica JAM SIDS + Location_R474 Location_Country = 337 // Martinique MTQ + Location_R500 Location_Country = 338 // Montserrat MSR SIDS + Location_R630 Location_Country = 339 // Puerto Rico PRI SIDS + Location_R652 Location_Country = 340 // Saint Barthélemy BLM + Location_R659 Location_Country = 341 // Saint Kitts and Nevis KNA SIDS + Location_R662 Location_Country = 342 // Saint Lucia LCA SIDS + Location_R663 Location_Country = 343 // Saint Martin (French Part) MAF + Location_R670 Location_Country = 344 // Saint Vincent and the Grenadines VCT SIDS + Location_R534 Location_Country = 345 // Sint Maarten (Dutch part) SXM SIDS + Location_R780 Location_Country = 346 // Trinidad and Tobago TTO SIDS + Location_R796 Location_Country = 347 // Turks and Caicos Islands TCA + Location_R850 Location_Country = 348 // United States Virgin Islands VIR SIDS + Location_R013 Location_Country = 349 // Central America + Location_R084 Location_Country = 350 // Belize BLZ SIDS + Location_R188 Location_Country = 351 // Costa Rica CRI + Location_R222 Location_Country = 352 // El Salvador SLV + Location_R320 Location_Country = 353 // Guatemala GTM + Location_R340 Location_Country = 354 // Honduras HND + Location_R484 Location_Country = 355 // Mexico MEX + Location_R558 Location_Country = 356 // Nicaragua NIC + Location_R591 Location_Country = 357 // Panama PAN + Location_R005 Location_Country = 358 // South America + Location_R032 Location_Country = 359 // Argentina ARG + Location_R068 Location_Country = 360 // Bolivia (Plurinational State of) BOL LLDC + Location_R074 Location_Country = 361 // Bouvet Island BVT + Location_R076 Location_Country = 362 // Brazil BRA + Location_R152 Location_Country = 363 // Chile CHL + Location_R170 Location_Country = 364 // Colombia COL + Location_R218 Location_Country = 365 // Ecuador ECU + Location_R238 Location_Country = 366 // Falkland Islands (Malvinas) FLK + Location_R254 Location_Country = 367 // French Guiana GUF + Location_R328 Location_Country = 368 // Guyana GUY SIDS + Location_R600 Location_Country = 369 // Paraguay PRY LLDC + Location_R604 Location_Country = 370 // Peru PER + Location_R239 Location_Country = 371 // South Georgia and the South Sandwich Islands SGS + Location_R740 Location_Country = 372 // Suriname SUR SIDS + Location_R858 Location_Country = 373 // Uruguay URY + Location_R862 Location_Country = 374 // Venezuela (Bolivarian Republic of) VEN + Location_R021 Location_Country = 375 // Northern America + Location_R060 Location_Country = 376 // Bermuda BMU + Location_R124 Location_Country = 377 // Canada CAN + Location_R304 Location_Country = 378 // Greenland GRL + Location_R666 Location_Country = 379 // Saint Pierre and Miquelon SPM + Location_R840 Location_Country = 380 // United States of America USA + Location_R010 Location_Country = 381 // Antarctica ATA + Location_R142 Location_Country = 382 // Asia + Location_R143 Location_Country = 383 // Central Asia + Location_R398 Location_Country = 384 // Kazakhstan KAZ LLDC + Location_R417 Location_Country = 385 // Kyrgyzstan KGZ LLDC + Location_R762 Location_Country = 386 // Tajikistan TJK LLDC + Location_R795 Location_Country = 387 // Turkmenistan TKM LLDC + Location_R860 Location_Country = 388 // Uzbekistan UZB LLDC + Location_R030 Location_Country = 389 // Eastern Asia + Location_R156 Location_Country = 390 // China CHN + Location_R344 Location_Country = 391 // China, Hong Kong Special Administrative Region HKG + Location_R446 Location_Country = 392 // China, Macao Special Administrative Region MAC + Location_R408 Location_Country = 393 // Democratic People's Republic of Korea PRK + Location_R392 Location_Country = 394 // Japan JPN + Location_R496 Location_Country = 395 // Mongolia MNG LLDC + Location_R410 Location_Country = 396 // Republic of Korea KOR + Location_R035 Location_Country = 397 // South-eastern Asia + Location_R096 Location_Country = 398 // Brunei Darussalam BRN + Location_R116 Location_Country = 399 // Cambodia KHM LDC + Location_R360 Location_Country = 400 // Indonesia IDN + Location_R418 Location_Country = 401 // Lao People's Democratic Republic LAO LDC LLDC + Location_R458 Location_Country = 402 // Malaysia MYS + Location_R104 Location_Country = 403 // Myanmar MMR LDC + Location_R608 Location_Country = 404 // Philippines PHL + Location_R702 Location_Country = 405 // Singapore SGP SIDS + Location_R764 Location_Country = 406 // Thailand THA + Location_R626 Location_Country = 407 // Timor-Leste TLS LDC SIDS + Location_R704 Location_Country = 408 // Viet Nam VNM + Location_R034 Location_Country = 409 // Southern Asia + Location_R004 Location_Country = 410 // Afghanistan AFG LDC LLDC + Location_R050 Location_Country = 411 // Bangladesh BGD LDC + Location_R064 Location_Country = 412 // Bhutan BTN LDC LLDC + Location_R356 Location_Country = 413 // India IND + Location_R364 Location_Country = 414 // Iran (Islamic Republic of) IRN + Location_R462 Location_Country = 415 // Maldives MDV SIDS + Location_R524 Location_Country = 416 // Nepal NPL LDC LLDC + Location_R586 Location_Country = 417 // Pakistan PAK + Location_R144 Location_Country = 418 // Sri Lanka LKA + Location_R145 Location_Country = 419 // Western Asia + Location_R051 Location_Country = 420 // Armenia ARM LLDC + Location_R031 Location_Country = 421 // Azerbaijan AZE LLDC + Location_R048 Location_Country = 422 // Bahrain BHR + Location_R196 Location_Country = 423 // Cyprus CYP + Location_R268 Location_Country = 424 // Georgia GEO + Location_R368 Location_Country = 425 // Iraq IRQ + Location_R376 Location_Country = 426 // Israel ISR + Location_R400 Location_Country = 427 // Jordan JOR + Location_R414 Location_Country = 428 // Kuwait KWT + Location_R422 Location_Country = 429 // Lebanon LBN + Location_R512 Location_Country = 430 // Oman OMN + Location_R634 Location_Country = 431 // Qatar QAT + Location_R682 Location_Country = 432 // Saudi Arabia SAU + Location_R275 Location_Country = 433 // State of Palestine PSE + Location_R760 Location_Country = 434 // Syrian Arab Republic SYR + Location_R792 Location_Country = 435 // Turkey TUR + Location_R784 Location_Country = 436 // United Arab Emirates ARE + Location_R887 Location_Country = 437 // Yemen YEM LDC + Location_R150 Location_Country = 438 // Europe + Location_R151 Location_Country = 439 // Eastern Europe + Location_R112 Location_Country = 440 // Belarus BLR + Location_R100 Location_Country = 441 // Bulgaria BGR + Location_R203 Location_Country = 442 // Czechia CZE + Location_R348 Location_Country = 443 // Hungary HUN + Location_R616 Location_Country = 444 // Poland POL + Location_R498 Location_Country = 445 // Republic of Moldova MDA LLDC + Location_R642 Location_Country = 446 // Romania ROU + Location_R643 Location_Country = 447 // Russian Federation RUS + Location_R703 Location_Country = 448 // Slovakia SVK + Location_R804 Location_Country = 449 // Ukraine UKR + Location_R154 Location_Country = 450 // Northern Europe + Location_R248 Location_Country = 451 // Åland Islands ALA + Location_R830 Location_Country = 452 // Channel Islands + Location_R831 Location_Country = 453 // Guernsey GGY + Location_R832 Location_Country = 454 // Jersey JEY + Location_R680 Location_Country = 455 // Sark + Location_R208 Location_Country = 456 // Denmark DNK + Location_R233 Location_Country = 457 // Estonia EST + Location_R234 Location_Country = 458 // Faroe Islands FRO + Location_R246 Location_Country = 459 // Finland FIN + Location_R352 Location_Country = 460 // Iceland ISL + Location_R372 Location_Country = 461 // Ireland IRL + Location_R833 Location_Country = 462 // Isle of Man IMN + Location_R428 Location_Country = 463 // Latvia LVA + Location_R440 Location_Country = 464 // Lithuania LTU + Location_R578 Location_Country = 465 // Norway NOR + Location_R744 Location_Country = 466 // Svalbard and Jan Mayen Islands SJM + Location_R752 Location_Country = 467 // Sweden SWE + Location_R826 Location_Country = 468 // United Kingdom of Great Britain and Northern Ireland GBR + Location_R039 Location_Country = 469 // Southern Europe + Location_R008 Location_Country = 470 // Albania ALB + Location_R020 Location_Country = 471 // Andorra AND + Location_R070 Location_Country = 472 // Bosnia and Herzegovina BIH + Location_R191 Location_Country = 473 // Croatia HRV + Location_R292 Location_Country = 474 // Gibraltar GIB + Location_R300 Location_Country = 475 // Greece GRC + Location_R336 Location_Country = 476 // Holy See VAT + Location_R380 Location_Country = 477 // Italy ITA + Location_R470 Location_Country = 478 // Malta MLT + Location_R499 Location_Country = 479 // Montenegro MNE + Location_R807 Location_Country = 480 // North Macedonia MKD LLDC + Location_R620 Location_Country = 481 // Portugal PRT + Location_R674 Location_Country = 482 // San Marino SMR + Location_R688 Location_Country = 483 // Serbia SRB + Location_R705 Location_Country = 484 // Slovenia SVN + Location_R724 Location_Country = 485 // Spain ESP + Location_R155 Location_Country = 486 // Western Europe + Location_R040 Location_Country = 487 // Austria AUT + Location_R056 Location_Country = 488 // Belgium BEL + Location_R250 Location_Country = 489 // France FRA + Location_R276 Location_Country = 490 // Germany DEU + Location_R438 Location_Country = 491 // Liechtenstein LIE + Location_R442 Location_Country = 492 // Luxembourg LUX + Location_R492 Location_Country = 493 // Monaco MCO + Location_R528 Location_Country = 494 // Netherlands NLD + Location_R756 Location_Country = 495 // Switzerland CHE + Location_R009 Location_Country = 496 // Oceania + Location_R053 Location_Country = 497 // Australia and New Zealand + Location_R036 Location_Country = 498 // Australia AUS + Location_R162 Location_Country = 499 // Christmas Island CXR + Location_R166 Location_Country = 500 // Cocos (Keeling) Islands CCK + Location_R334 Location_Country = 501 // Heard Island and McDonald Islands HMD + Location_R554 Location_Country = 502 // New Zealand NZL + Location_R574 Location_Country = 503 // Norfolk Island NFK + Location_R054 Location_Country = 504 // Melanesia + Location_R242 Location_Country = 505 // Fiji FJI SIDS + Location_R540 Location_Country = 506 // New Caledonia NCL SIDS + Location_R598 Location_Country = 507 // Papua New Guinea PNG SIDS + Location_R090 Location_Country = 508 // Solomon Islands SLB LDC SIDS + Location_R548 Location_Country = 509 // Vanuatu VUT LDC SIDS + Location_R057 Location_Country = 510 // Micronesia + Location_R316 Location_Country = 511 // Guam GUM SIDS + Location_R296 Location_Country = 512 // Kiribati KIR LDC SIDS + Location_R584 Location_Country = 513 // Marshall Islands MHL SIDS + Location_R583 Location_Country = 514 // Micronesia (Federated States of) FSM SIDS + Location_R520 Location_Country = 515 // Nauru NRU SIDS + Location_R580 Location_Country = 516 // Northern Mariana Islands MNP SIDS + Location_R585 Location_Country = 517 // Palau PLW SIDS + Location_R581 Location_Country = 518 // United States Minor Outlying Islands UMI + Location_R061 Location_Country = 519 // Polynesia + Location_R016 Location_Country = 520 // American Samoa ASM SIDS + Location_R184 Location_Country = 521 // Cook Islands COK SIDS + Location_R258 Location_Country = 522 // French Polynesia PYF SIDS + Location_R570 Location_Country = 523 // Niue NIU SIDS + Location_R612 Location_Country = 524 // Pitcairn PCN + Location_R882 Location_Country = 525 // Samoa WSM SIDS + Location_R772 Location_Country = 526 // Tokelau TKL + Location_R776 Location_Country = 527 // Tonga TON SIDS + Location_R798 Location_Country = 528 // Tuvalu TUV LDC SIDS + Location_R876 Location_Country = 529 // Wallis and Futuna Islands WLF +) + +// Enum value maps for Location_Country. +var ( + Location_Country_name = map[int32]string{ + 0: "UNKNOWN_COUNTRY", + 1: "AF", + 2: "AX", + 3: "AL", + 4: "DZ", + 5: "AS", + 6: "AD", + 7: "AO", + 8: "AI", + 9: "AQ", + 10: "AG", + 11: "AR", + 12: "AM", + 13: "AW", + 14: "AU", + 15: "AT", + 16: "AZ", + 17: "BS", + 18: "BH", + 19: "BD", + 20: "BB", + 21: "BY", + 22: "BE", + 23: "BZ", + 24: "BJ", + 25: "BM", + 26: "BT", + 27: "BO", + 28: "BQ", + 29: "BA", + 30: "BW", + 31: "BV", + 32: "BR", + 33: "IO", + 34: "BN", + 35: "BG", + 36: "BF", + 37: "BI", + 38: "KH", + 39: "CM", + 40: "CA", + 41: "CV", + 42: "KY", + 43: "CF", + 44: "TD", + 45: "CL", + 46: "CN", + 47: "CX", + 48: "CC", + 49: "CO", + 50: "KM", + 51: "CG", + 52: "CD", + 53: "CK", + 54: "CR", + 55: "CI", + 56: "HR", + 57: "CU", + 58: "CW", + 59: "CY", + 60: "CZ", + 61: "DK", + 62: "DJ", + 63: "DM", + 64: "DO", + 65: "EC", + 66: "EG", + 67: "SV", + 68: "GQ", + 69: "ER", + 70: "EE", + 71: "ET", + 72: "FK", + 73: "FO", + 74: "FJ", + 75: "FI", + 76: "FR", + 77: "GF", + 78: "PF", + 79: "TF", + 80: "GA", + 81: "GM", + 82: "GE", + 83: "DE", + 84: "GH", + 85: "GI", + 86: "GR", + 87: "GL", + 88: "GD", + 89: "GP", + 90: "GU", + 91: "GT", + 92: "GG", + 93: "GN", + 94: "GW", + 95: "GY", + 96: "HT", + 97: "HM", + 98: "VA", + 99: "HN", + 100: "HK", + 101: "HU", + 102: "IS", + 103: "IN", + 104: "ID", + 105: "IR", + 106: "IQ", + 107: "IE", + 108: "IM", + 109: "IL", + 110: "IT", + 111: "JM", + 112: "JP", + 113: "JE", + 114: "JO", + 115: "KZ", + 116: "KE", + 117: "KI", + 118: "KP", + 119: "KR", + 120: "KW", + 121: "KG", + 122: "LA", + 123: "LV", + 124: "LB", + 125: "LS", + 126: "LR", + 127: "LY", + 128: "LI", + 129: "LT", + 130: "LU", + 131: "MO", + 132: "MK", + 133: "MG", + 134: "MW", + 135: "MY", + 136: "MV", + 137: "ML", + 138: "MT", + 139: "MH", + 140: "MQ", + 141: "MR", + 142: "MU", + 143: "YT", + 144: "MX", + 145: "FM", + 146: "MD", + 147: "MC", + 148: "MN", + 149: "ME", + 150: "MS", + 151: "MA", + 152: "MZ", + 153: "MM", + 154: "NA", + 155: "NR", + 156: "NP", + 157: "NL", + 158: "NC", + 159: "NZ", + 160: "NI", + 161: "NE", + 162: "NG", + 163: "NU", + 164: "NF", + 165: "MP", + 166: "NO", + 167: "OM", + 168: "PK", + 169: "PW", + 170: "PS", + 171: "PA", + 172: "PG", + 173: "PY", + 174: "PE", + 175: "PH", + 176: "PN", + 177: "PL", + 178: "PT", + 179: "PR", + 180: "QA", + 181: "RE", + 182: "RO", + 183: "RU", + 184: "RW", + 185: "BL", + 186: "SH", + 187: "KN", + 188: "LC", + 189: "MF", + 190: "PM", + 191: "VC", + 192: "WS", + 193: "SM", + 194: "ST", + 195: "SA", + 196: "SN", + 197: "RS", + 198: "SC", + 199: "SL", + 200: "SG", + 201: "SX", + 202: "SK", + 203: "SI", + 204: "SB", + 205: "SO", + 206: "ZA", + 207: "GS", + 208: "SS", + 209: "ES", + 210: "LK", + 211: "SD", + 212: "SR", + 213: "SJ", + 214: "SZ", + 215: "SE", + 216: "CH", + 217: "SY", + 218: "TW", + 219: "TJ", + 220: "TZ", + 221: "TH", + 222: "TL", + 223: "TG", + 224: "TK", + 225: "TO", + 226: "TT", + 227: "TN", + 228: "TR", + 229: "TM", + 230: "TC", + 231: "TV", + 232: "UG", + 233: "UA", + 234: "AE", + 235: "GB", + 236: "US", + 237: "UM", + 238: "UY", + 239: "UZ", + 240: "VU", + 241: "VE", + 242: "VN", + 243: "VG", + 244: "VI", + 245: "WF", + 246: "EH", + 247: "YE", + 248: "ZM", + 249: "ZW", + 250: "R001", + 251: "R002", + 252: "R015", + 253: "R012", + 254: "R818", + 255: "R434", + 256: "R504", + 257: "R729", + 258: "R788", + 259: "R732", + 260: "R202", + 261: "R014", + 262: "R086", + 263: "R108", + 264: "R174", + 265: "R262", + 266: "R232", + 267: "R231", + 268: "R260", + 269: "R404", + 270: "R450", + 271: "R454", + 272: "R480", + 273: "R175", + 274: "R508", + 275: "R638", + 276: "R646", + 277: "R690", + 278: "R706", + 279: "R728", + 280: "R800", + 281: "R834", + 282: "R894", + 283: "R716", + 284: "R017", + 285: "R024", + 286: "R120", + 287: "R140", + 288: "R148", + 289: "R178", + 290: "R180", + 291: "R226", + 292: "R266", + 293: "R678", + 294: "R018", + 295: "R072", + 296: "R748", + 297: "R426", + 298: "R516", + 299: "R710", + 300: "R011", + 301: "R204", + 302: "R854", + 303: "R132", + 304: "R384", + 305: "R270", + 306: "R288", + 307: "R324", + 308: "R624", + 309: "R430", + 310: "R466", + 311: "R478", + 312: "R562", + 313: "R566", + 314: "R654", + 315: "R686", + 316: "R694", + 317: "R768", + 318: "R019", + 319: "R419", + 320: "R029", + 321: "R660", + 322: "R028", + 323: "R533", + 324: "R044", + 325: "R052", + 326: "R535", + 327: "R092", + 328: "R136", + 329: "R192", + 330: "R531", + 331: "R212", + 332: "R214", + 333: "R308", + 334: "R312", + 335: "R332", + 336: "R388", + 337: "R474", + 338: "R500", + 339: "R630", + 340: "R652", + 341: "R659", + 342: "R662", + 343: "R663", + 344: "R670", + 345: "R534", + 346: "R780", + 347: "R796", + 348: "R850", + 349: "R013", + 350: "R084", + 351: "R188", + 352: "R222", + 353: "R320", + 354: "R340", + 355: "R484", + 356: "R558", + 357: "R591", + 358: "R005", + 359: "R032", + 360: "R068", + 361: "R074", + 362: "R076", + 363: "R152", + 364: "R170", + 365: "R218", + 366: "R238", + 367: "R254", + 368: "R328", + 369: "R600", + 370: "R604", + 371: "R239", + 372: "R740", + 373: "R858", + 374: "R862", + 375: "R021", + 376: "R060", + 377: "R124", + 378: "R304", + 379: "R666", + 380: "R840", + 381: "R010", + 382: "R142", + 383: "R143", + 384: "R398", + 385: "R417", + 386: "R762", + 387: "R795", + 388: "R860", + 389: "R030", + 390: "R156", + 391: "R344", + 392: "R446", + 393: "R408", + 394: "R392", + 395: "R496", + 396: "R410", + 397: "R035", + 398: "R096", + 399: "R116", + 400: "R360", + 401: "R418", + 402: "R458", + 403: "R104", + 404: "R608", + 405: "R702", + 406: "R764", + 407: "R626", + 408: "R704", + 409: "R034", + 410: "R004", + 411: "R050", + 412: "R064", + 413: "R356", + 414: "R364", + 415: "R462", + 416: "R524", + 417: "R586", + 418: "R144", + 419: "R145", + 420: "R051", + 421: "R031", + 422: "R048", + 423: "R196", + 424: "R268", + 425: "R368", + 426: "R376", + 427: "R400", + 428: "R414", + 429: "R422", + 430: "R512", + 431: "R634", + 432: "R682", + 433: "R275", + 434: "R760", + 435: "R792", + 436: "R784", + 437: "R887", + 438: "R150", + 439: "R151", + 440: "R112", + 441: "R100", + 442: "R203", + 443: "R348", + 444: "R616", + 445: "R498", + 446: "R642", + 447: "R643", + 448: "R703", + 449: "R804", + 450: "R154", + 451: "R248", + 452: "R830", + 453: "R831", + 454: "R832", + 455: "R680", + 456: "R208", + 457: "R233", + 458: "R234", + 459: "R246", + 460: "R352", + 461: "R372", + 462: "R833", + 463: "R428", + 464: "R440", + 465: "R578", + 466: "R744", + 467: "R752", + 468: "R826", + 469: "R039", + 470: "R008", + 471: "R020", + 472: "R070", + 473: "R191", + 474: "R292", + 475: "R300", + 476: "R336", + 477: "R380", + 478: "R470", + 479: "R499", + 480: "R807", + 481: "R620", + 482: "R674", + 483: "R688", + 484: "R705", + 485: "R724", + 486: "R155", + 487: "R040", + 488: "R056", + 489: "R250", + 490: "R276", + 491: "R438", + 492: "R442", + 493: "R492", + 494: "R528", + 495: "R756", + 496: "R009", + 497: "R053", + 498: "R036", + 499: "R162", + 500: "R166", + 501: "R334", + 502: "R554", + 503: "R574", + 504: "R054", + 505: "R242", + 506: "R540", + 507: "R598", + 508: "R090", + 509: "R548", + 510: "R057", + 511: "R316", + 512: "R296", + 513: "R584", + 514: "R583", + 515: "R520", + 516: "R580", + 517: "R585", + 518: "R581", + 519: "R061", + 520: "R016", + 521: "R184", + 522: "R258", + 523: "R570", + 524: "R612", + 525: "R882", + 526: "R772", + 527: "R776", + 528: "R798", + 529: "R876", + } + Location_Country_value = map[string]int32{ + "UNKNOWN_COUNTRY": 0, + "AF": 1, + "AX": 2, + "AL": 3, + "DZ": 4, + "AS": 5, + "AD": 6, + "AO": 7, + "AI": 8, + "AQ": 9, + "AG": 10, + "AR": 11, + "AM": 12, + "AW": 13, + "AU": 14, + "AT": 15, + "AZ": 16, + "BS": 17, + "BH": 18, + "BD": 19, + "BB": 20, + "BY": 21, + "BE": 22, + "BZ": 23, + "BJ": 24, + "BM": 25, + "BT": 26, + "BO": 27, + "BQ": 28, + "BA": 29, + "BW": 30, + "BV": 31, + "BR": 32, + "IO": 33, + "BN": 34, + "BG": 35, + "BF": 36, + "BI": 37, + "KH": 38, + "CM": 39, + "CA": 40, + "CV": 41, + "KY": 42, + "CF": 43, + "TD": 44, + "CL": 45, + "CN": 46, + "CX": 47, + "CC": 48, + "CO": 49, + "KM": 50, + "CG": 51, + "CD": 52, + "CK": 53, + "CR": 54, + "CI": 55, + "HR": 56, + "CU": 57, + "CW": 58, + "CY": 59, + "CZ": 60, + "DK": 61, + "DJ": 62, + "DM": 63, + "DO": 64, + "EC": 65, + "EG": 66, + "SV": 67, + "GQ": 68, + "ER": 69, + "EE": 70, + "ET": 71, + "FK": 72, + "FO": 73, + "FJ": 74, + "FI": 75, + "FR": 76, + "GF": 77, + "PF": 78, + "TF": 79, + "GA": 80, + "GM": 81, + "GE": 82, + "DE": 83, + "GH": 84, + "GI": 85, + "GR": 86, + "GL": 87, + "GD": 88, + "GP": 89, + "GU": 90, + "GT": 91, + "GG": 92, + "GN": 93, + "GW": 94, + "GY": 95, + "HT": 96, + "HM": 97, + "VA": 98, + "HN": 99, + "HK": 100, + "HU": 101, + "IS": 102, + "IN": 103, + "ID": 104, + "IR": 105, + "IQ": 106, + "IE": 107, + "IM": 108, + "IL": 109, + "IT": 110, + "JM": 111, + "JP": 112, + "JE": 113, + "JO": 114, + "KZ": 115, + "KE": 116, + "KI": 117, + "KP": 118, + "KR": 119, + "KW": 120, + "KG": 121, + "LA": 122, + "LV": 123, + "LB": 124, + "LS": 125, + "LR": 126, + "LY": 127, + "LI": 128, + "LT": 129, + "LU": 130, + "MO": 131, + "MK": 132, + "MG": 133, + "MW": 134, + "MY": 135, + "MV": 136, + "ML": 137, + "MT": 138, + "MH": 139, + "MQ": 140, + "MR": 141, + "MU": 142, + "YT": 143, + "MX": 144, + "FM": 145, + "MD": 146, + "MC": 147, + "MN": 148, + "ME": 149, + "MS": 150, + "MA": 151, + "MZ": 152, + "MM": 153, + "NA": 154, + "NR": 155, + "NP": 156, + "NL": 157, + "NC": 158, + "NZ": 159, + "NI": 160, + "NE": 161, + "NG": 162, + "NU": 163, + "NF": 164, + "MP": 165, + "NO": 166, + "OM": 167, + "PK": 168, + "PW": 169, + "PS": 170, + "PA": 171, + "PG": 172, + "PY": 173, + "PE": 174, + "PH": 175, + "PN": 176, + "PL": 177, + "PT": 178, + "PR": 179, + "QA": 180, + "RE": 181, + "RO": 182, + "RU": 183, + "RW": 184, + "BL": 185, + "SH": 186, + "KN": 187, + "LC": 188, + "MF": 189, + "PM": 190, + "VC": 191, + "WS": 192, + "SM": 193, + "ST": 194, + "SA": 195, + "SN": 196, + "RS": 197, + "SC": 198, + "SL": 199, + "SG": 200, + "SX": 201, + "SK": 202, + "SI": 203, + "SB": 204, + "SO": 205, + "ZA": 206, + "GS": 207, + "SS": 208, + "ES": 209, + "LK": 210, + "SD": 211, + "SR": 212, + "SJ": 213, + "SZ": 214, + "SE": 215, + "CH": 216, + "SY": 217, + "TW": 218, + "TJ": 219, + "TZ": 220, + "TH": 221, + "TL": 222, + "TG": 223, + "TK": 224, + "TO": 225, + "TT": 226, + "TN": 227, + "TR": 228, + "TM": 229, + "TC": 230, + "TV": 231, + "UG": 232, + "UA": 233, + "AE": 234, + "GB": 235, + "US": 236, + "UM": 237, + "UY": 238, + "UZ": 239, + "VU": 240, + "VE": 241, + "VN": 242, + "VG": 243, + "VI": 244, + "WF": 245, + "EH": 246, + "YE": 247, + "ZM": 248, + "ZW": 249, + "R001": 250, + "R002": 251, + "R015": 252, + "R012": 253, + "R818": 254, + "R434": 255, + "R504": 256, + "R729": 257, + "R788": 258, + "R732": 259, + "R202": 260, + "R014": 261, + "R086": 262, + "R108": 263, + "R174": 264, + "R262": 265, + "R232": 266, + "R231": 267, + "R260": 268, + "R404": 269, + "R450": 270, + "R454": 271, + "R480": 272, + "R175": 273, + "R508": 274, + "R638": 275, + "R646": 276, + "R690": 277, + "R706": 278, + "R728": 279, + "R800": 280, + "R834": 281, + "R894": 282, + "R716": 283, + "R017": 284, + "R024": 285, + "R120": 286, + "R140": 287, + "R148": 288, + "R178": 289, + "R180": 290, + "R226": 291, + "R266": 292, + "R678": 293, + "R018": 294, + "R072": 295, + "R748": 296, + "R426": 297, + "R516": 298, + "R710": 299, + "R011": 300, + "R204": 301, + "R854": 302, + "R132": 303, + "R384": 304, + "R270": 305, + "R288": 306, + "R324": 307, + "R624": 308, + "R430": 309, + "R466": 310, + "R478": 311, + "R562": 312, + "R566": 313, + "R654": 314, + "R686": 315, + "R694": 316, + "R768": 317, + "R019": 318, + "R419": 319, + "R029": 320, + "R660": 321, + "R028": 322, + "R533": 323, + "R044": 324, + "R052": 325, + "R535": 326, + "R092": 327, + "R136": 328, + "R192": 329, + "R531": 330, + "R212": 331, + "R214": 332, + "R308": 333, + "R312": 334, + "R332": 335, + "R388": 336, + "R474": 337, + "R500": 338, + "R630": 339, + "R652": 340, + "R659": 341, + "R662": 342, + "R663": 343, + "R670": 344, + "R534": 345, + "R780": 346, + "R796": 347, + "R850": 348, + "R013": 349, + "R084": 350, + "R188": 351, + "R222": 352, + "R320": 353, + "R340": 354, + "R484": 355, + "R558": 356, + "R591": 357, + "R005": 358, + "R032": 359, + "R068": 360, + "R074": 361, + "R076": 362, + "R152": 363, + "R170": 364, + "R218": 365, + "R238": 366, + "R254": 367, + "R328": 368, + "R600": 369, + "R604": 370, + "R239": 371, + "R740": 372, + "R858": 373, + "R862": 374, + "R021": 375, + "R060": 376, + "R124": 377, + "R304": 378, + "R666": 379, + "R840": 380, + "R010": 381, + "R142": 382, + "R143": 383, + "R398": 384, + "R417": 385, + "R762": 386, + "R795": 387, + "R860": 388, + "R030": 389, + "R156": 390, + "R344": 391, + "R446": 392, + "R408": 393, + "R392": 394, + "R496": 395, + "R410": 396, + "R035": 397, + "R096": 398, + "R116": 399, + "R360": 400, + "R418": 401, + "R458": 402, + "R104": 403, + "R608": 404, + "R702": 405, + "R764": 406, + "R626": 407, + "R704": 408, + "R034": 409, + "R004": 410, + "R050": 411, + "R064": 412, + "R356": 413, + "R364": 414, + "R462": 415, + "R524": 416, + "R586": 417, + "R144": 418, + "R145": 419, + "R051": 420, + "R031": 421, + "R048": 422, + "R196": 423, + "R268": 424, + "R368": 425, + "R376": 426, + "R400": 427, + "R414": 428, + "R422": 429, + "R512": 430, + "R634": 431, + "R682": 432, + "R275": 433, + "R760": 434, + "R792": 435, + "R784": 436, + "R887": 437, + "R150": 438, + "R151": 439, + "R112": 440, + "R100": 441, + "R203": 442, + "R348": 443, + "R616": 444, + "R498": 445, + "R642": 446, + "R643": 447, + "R703": 448, + "R804": 449, + "R154": 450, + "R248": 451, + "R830": 452, + "R831": 453, + "R832": 454, + "R680": 455, + "R208": 456, + "R233": 457, + "R234": 458, + "R246": 459, + "R352": 460, + "R372": 461, + "R833": 462, + "R428": 463, + "R440": 464, + "R578": 465, + "R744": 466, + "R752": 467, + "R826": 468, + "R039": 469, + "R008": 470, + "R020": 471, + "R070": 472, + "R191": 473, + "R292": 474, + "R300": 475, + "R336": 476, + "R380": 477, + "R470": 478, + "R499": 479, + "R807": 480, + "R620": 481, + "R674": 482, + "R688": 483, + "R705": 484, + "R724": 485, + "R155": 486, + "R040": 487, + "R056": 488, + "R250": 489, + "R276": 490, + "R438": 491, + "R442": 492, + "R492": 493, + "R528": 494, + "R756": 495, + "R009": 496, + "R053": 497, + "R036": 498, + "R162": 499, + "R166": 500, + "R334": 501, + "R554": 502, + "R574": 503, + "R054": 504, + "R242": 505, + "R540": 506, + "R598": 507, + "R090": 508, + "R548": 509, + "R057": 510, + "R316": 511, + "R296": 512, + "R584": 513, + "R583": 514, + "R520": 515, + "R580": 516, + "R585": 517, + "R581": 518, + "R061": 519, + "R016": 520, + "R184": 521, + "R258": 522, + "R570": 523, + "R612": 524, + "R882": 525, + "R772": 526, + "R776": 527, + "R798": 528, + "R876": 529, + } +) + +func (x Location_Country) Enum() *Location_Country { + p := new(Location_Country) + *p = x + return p +} + +func (x Location_Country) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Location_Country) Descriptor() protoreflect.EnumDescriptor { + return file_claim_proto_enumTypes[5].Descriptor() +} + +func (Location_Country) Type() protoreflect.EnumType { + return &file_claim_proto_enumTypes[5] +} + +func (x Location_Country) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Location_Country.Descriptor instead. +func (Location_Country) EnumDescriptor() ([]byte, []int) { + return file_claim_proto_rawDescGZIP(), []int{12, 0} +} + +type Claim struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Type: + // *Claim_Stream + // *Claim_Channel + // *Claim_Collection + // *Claim_Repost + Type isClaim_Type `protobuf_oneof:"type"` + Title string `protobuf:"bytes,8,opt,name=title,proto3" json:"title"` + Description string `protobuf:"bytes,9,opt,name=description,proto3" json:"description"` + Thumbnail *Source `protobuf:"bytes,10,opt,name=thumbnail,proto3" json:"thumbnail"` + Tags []string `protobuf:"bytes,11,rep,name=tags,proto3" json:"tags"` + Languages []*Language `protobuf:"bytes,12,rep,name=languages,proto3" json:"languages"` + Locations []*Location `protobuf:"bytes,13,rep,name=locations,proto3" json:"locations"` +} + +func (x *Claim) Reset() { + *x = Claim{} + if protoimpl.UnsafeEnabled { + mi := &file_claim_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Claim) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Claim) ProtoMessage() {} + +func (x *Claim) ProtoReflect() protoreflect.Message { + mi := &file_claim_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Claim.ProtoReflect.Descriptor instead. +func (*Claim) Descriptor() ([]byte, []int) { + return file_claim_proto_rawDescGZIP(), []int{0} +} + +func (m *Claim) GetType() isClaim_Type { + if m != nil { + return m.Type + } + return nil +} + +func (x *Claim) GetStream() *Stream { + if x, ok := x.GetType().(*Claim_Stream); ok { + return x.Stream + } + return nil +} + +func (x *Claim) GetChannel() *Channel { + if x, ok := x.GetType().(*Claim_Channel); ok { + return x.Channel + } + return nil +} + +func (x *Claim) GetCollection() *ClaimList { + if x, ok := x.GetType().(*Claim_Collection); ok { + return x.Collection + } + return nil +} + +func (x *Claim) GetRepost() *ClaimReference { + if x, ok := x.GetType().(*Claim_Repost); ok { + return x.Repost + } + return nil +} + +func (x *Claim) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +func (x *Claim) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Claim) GetThumbnail() *Source { + if x != nil { + return x.Thumbnail + } + return nil +} + +func (x *Claim) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + +func (x *Claim) GetLanguages() []*Language { + if x != nil { + return x.Languages + } + return nil +} + +func (x *Claim) GetLocations() []*Location { + if x != nil { + return x.Locations + } + return nil +} + +type isClaim_Type interface { + isClaim_Type() +} + +type Claim_Stream struct { + Stream *Stream `protobuf:"bytes,1,opt,name=stream,proto3,oneof"` +} + +type Claim_Channel struct { + Channel *Channel `protobuf:"bytes,2,opt,name=channel,proto3,oneof"` +} + +type Claim_Collection struct { + Collection *ClaimList `protobuf:"bytes,3,opt,name=collection,proto3,oneof"` +} + +type Claim_Repost struct { + Repost *ClaimReference `protobuf:"bytes,4,opt,name=repost,proto3,oneof"` +} + +func (*Claim_Stream) isClaim_Type() {} + +func (*Claim_Channel) isClaim_Type() {} + +func (*Claim_Collection) isClaim_Type() {} + +func (*Claim_Repost) isClaim_Type() {} + +type Stream struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Source *Source `protobuf:"bytes,1,opt,name=source,proto3" json:"source"` + Author string `protobuf:"bytes,2,opt,name=author,proto3" json:"author"` + License string `protobuf:"bytes,3,opt,name=license,proto3" json:"license"` + LicenseUrl string `protobuf:"bytes,4,opt,name=license_url,json=licenseUrl,proto3" json:"license_url"` + ReleaseTime int64 `protobuf:"varint,5,opt,name=release_time,json=releaseTime,proto3" json:"release_time"` // seconds since UNIX epoch + Fee *Fee `protobuf:"bytes,6,opt,name=fee,proto3" json:"fee"` + // Types that are assignable to Type: + // *Stream_Image + // *Stream_Video + // *Stream_Audio + // *Stream_Software + Type isStream_Type `protobuf_oneof:"type"` +} + +func (x *Stream) Reset() { + *x = Stream{} + if protoimpl.UnsafeEnabled { + mi := &file_claim_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Stream) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Stream) ProtoMessage() {} + +func (x *Stream) ProtoReflect() protoreflect.Message { + mi := &file_claim_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Stream.ProtoReflect.Descriptor instead. +func (*Stream) Descriptor() ([]byte, []int) { + return file_claim_proto_rawDescGZIP(), []int{1} +} + +func (x *Stream) GetSource() *Source { + if x != nil { + return x.Source + } + return nil +} + +func (x *Stream) GetAuthor() string { + if x != nil { + return x.Author + } + return "" +} + +func (x *Stream) GetLicense() string { + if x != nil { + return x.License + } + return "" +} + +func (x *Stream) GetLicenseUrl() string { + if x != nil { + return x.LicenseUrl + } + return "" +} + +func (x *Stream) GetReleaseTime() int64 { + if x != nil { + return x.ReleaseTime + } + return 0 +} + +func (x *Stream) GetFee() *Fee { + if x != nil { + return x.Fee + } + return nil +} + +func (m *Stream) GetType() isStream_Type { + if m != nil { + return m.Type + } + return nil +} + +func (x *Stream) GetImage() *Image { + if x, ok := x.GetType().(*Stream_Image); ok { + return x.Image + } + return nil +} + +func (x *Stream) GetVideo() *Video { + if x, ok := x.GetType().(*Stream_Video); ok { + return x.Video + } + return nil +} + +func (x *Stream) GetAudio() *Audio { + if x, ok := x.GetType().(*Stream_Audio); ok { + return x.Audio + } + return nil +} + +func (x *Stream) GetSoftware() *Software { + if x, ok := x.GetType().(*Stream_Software); ok { + return x.Software + } + return nil +} + +type isStream_Type interface { + isStream_Type() +} + +type Stream_Image struct { + Image *Image `protobuf:"bytes,10,opt,name=image,proto3,oneof"` +} + +type Stream_Video struct { + Video *Video `protobuf:"bytes,11,opt,name=video,proto3,oneof"` +} + +type Stream_Audio struct { + Audio *Audio `protobuf:"bytes,12,opt,name=audio,proto3,oneof"` +} + +type Stream_Software struct { + Software *Software `protobuf:"bytes,13,opt,name=software,proto3,oneof"` +} + +func (*Stream_Image) isStream_Type() {} + +func (*Stream_Video) isStream_Type() {} + +func (*Stream_Audio) isStream_Type() {} + +func (*Stream_Software) isStream_Type() {} + +type Channel struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PublicKey []byte `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key"` + Email string `protobuf:"bytes,2,opt,name=email,proto3" json:"email"` + WebsiteUrl string `protobuf:"bytes,3,opt,name=website_url,json=websiteUrl,proto3" json:"website_url"` + Cover *Source `protobuf:"bytes,4,opt,name=cover,proto3" json:"cover"` + Featured *ClaimList `protobuf:"bytes,5,opt,name=featured,proto3" json:"featured"` +} + +func (x *Channel) Reset() { + *x = Channel{} + if protoimpl.UnsafeEnabled { + mi := &file_claim_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Channel) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Channel) ProtoMessage() {} + +func (x *Channel) ProtoReflect() protoreflect.Message { + mi := &file_claim_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Channel.ProtoReflect.Descriptor instead. +func (*Channel) Descriptor() ([]byte, []int) { + return file_claim_proto_rawDescGZIP(), []int{2} +} + +func (x *Channel) GetPublicKey() []byte { + if x != nil { + return x.PublicKey + } + return nil +} + +func (x *Channel) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +func (x *Channel) GetWebsiteUrl() string { + if x != nil { + return x.WebsiteUrl + } + return "" +} + +func (x *Channel) GetCover() *Source { + if x != nil { + return x.Cover + } + return nil +} + +func (x *Channel) GetFeatured() *ClaimList { + if x != nil { + return x.Featured + } + return nil +} + +type ClaimReference struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ClaimHash []byte `protobuf:"bytes,1,opt,name=claim_hash,json=claimHash,proto3" json:"claim_hash"` +} + +func (x *ClaimReference) Reset() { + *x = ClaimReference{} + if protoimpl.UnsafeEnabled { + mi := &file_claim_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClaimReference) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClaimReference) ProtoMessage() {} + +func (x *ClaimReference) ProtoReflect() protoreflect.Message { + mi := &file_claim_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClaimReference.ProtoReflect.Descriptor instead. +func (*ClaimReference) Descriptor() ([]byte, []int) { + return file_claim_proto_rawDescGZIP(), []int{3} +} + +func (x *ClaimReference) GetClaimHash() []byte { + if x != nil { + return x.ClaimHash + } + return nil +} + +type ClaimList struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ListType ClaimList_ListType `protobuf:"varint,1,opt,name=list_type,json=listType,proto3,enum=pb.ClaimList_ListType" json:"list_type"` + ClaimReferences []*ClaimReference `protobuf:"bytes,2,rep,name=claim_references,json=claimReferences,proto3" json:"claim_references"` +} + +func (x *ClaimList) Reset() { + *x = ClaimList{} + if protoimpl.UnsafeEnabled { + mi := &file_claim_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClaimList) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClaimList) ProtoMessage() {} + +func (x *ClaimList) ProtoReflect() protoreflect.Message { + mi := &file_claim_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClaimList.ProtoReflect.Descriptor instead. +func (*ClaimList) Descriptor() ([]byte, []int) { + return file_claim_proto_rawDescGZIP(), []int{4} +} + +func (x *ClaimList) GetListType() ClaimList_ListType { + if x != nil { + return x.ListType + } + return ClaimList_COLLECTION +} + +func (x *ClaimList) GetClaimReferences() []*ClaimReference { + if x != nil { + return x.ClaimReferences + } + return nil +} + +type Source struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash"` // SHA-384 hash of the entire unencrypted file + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name"` + Size uint64 `protobuf:"varint,3,opt,name=size,proto3" json:"size"` + MediaType string `protobuf:"bytes,4,opt,name=media_type,json=mediaType,proto3" json:"media_type"` + Url string `protobuf:"bytes,5,opt,name=url,proto3" json:"url"` + SdHash []byte `protobuf:"bytes,6,opt,name=sd_hash,json=sdHash,proto3" json:"sd_hash"` // SHA-384 hash of the streams manifest blob + BtInfohash []byte `protobuf:"bytes,7,opt,name=bt_infohash,json=btInfohash,proto3" json:"bt_infohash"` // 20-byte SHA1 hash used to reference a torrent file +} + +func (x *Source) Reset() { + *x = Source{} + if protoimpl.UnsafeEnabled { + mi := &file_claim_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Source) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Source) ProtoMessage() {} + +func (x *Source) ProtoReflect() protoreflect.Message { + mi := &file_claim_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Source.ProtoReflect.Descriptor instead. +func (*Source) Descriptor() ([]byte, []int) { + return file_claim_proto_rawDescGZIP(), []int{5} +} + +func (x *Source) GetHash() []byte { + if x != nil { + return x.Hash + } + return nil +} + +func (x *Source) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Source) GetSize() uint64 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *Source) GetMediaType() string { + if x != nil { + return x.MediaType + } + return "" +} + +func (x *Source) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +func (x *Source) GetSdHash() []byte { + if x != nil { + return x.SdHash + } + return nil +} + +func (x *Source) GetBtInfohash() []byte { + if x != nil { + return x.BtInfohash + } + return nil +} + +type Fee struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Currency Fee_Currency `protobuf:"varint,1,opt,name=currency,proto3,enum=pb.Fee_Currency" json:"currency"` + Address []byte `protobuf:"bytes,2,opt,name=address,proto3" json:"address"` + Amount uint64 `protobuf:"varint,3,opt,name=amount,proto3" json:"amount"` // deweys for LBC/BTC, cents for USD +} + +func (x *Fee) Reset() { + *x = Fee{} + if protoimpl.UnsafeEnabled { + mi := &file_claim_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Fee) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Fee) ProtoMessage() {} + +func (x *Fee) ProtoReflect() protoreflect.Message { + mi := &file_claim_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Fee.ProtoReflect.Descriptor instead. +func (*Fee) Descriptor() ([]byte, []int) { + return file_claim_proto_rawDescGZIP(), []int{6} +} + +func (x *Fee) GetCurrency() Fee_Currency { + if x != nil { + return x.Currency + } + return Fee_UNKNOWN_CURRENCY +} + +func (x *Fee) GetAddress() []byte { + if x != nil { + return x.Address + } + return nil +} + +func (x *Fee) GetAmount() uint64 { + if x != nil { + return x.Amount + } + return 0 +} + +type Image struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Width uint32 `protobuf:"varint,1,opt,name=width,proto3" json:"width"` + Height uint32 `protobuf:"varint,2,opt,name=height,proto3" json:"height"` +} + +func (x *Image) Reset() { + *x = Image{} + if protoimpl.UnsafeEnabled { + mi := &file_claim_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Image) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Image) ProtoMessage() {} + +func (x *Image) ProtoReflect() protoreflect.Message { + mi := &file_claim_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Image.ProtoReflect.Descriptor instead. +func (*Image) Descriptor() ([]byte, []int) { + return file_claim_proto_rawDescGZIP(), []int{7} +} + +func (x *Image) GetWidth() uint32 { + if x != nil { + return x.Width + } + return 0 +} + +func (x *Image) GetHeight() uint32 { + if x != nil { + return x.Height + } + return 0 +} + +type Video struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Width uint32 `protobuf:"varint,1,opt,name=width,proto3" json:"width"` + Height uint32 `protobuf:"varint,2,opt,name=height,proto3" json:"height"` + Duration uint32 `protobuf:"varint,3,opt,name=duration,proto3" json:"duration"` + Audio *Audio `protobuf:"bytes,15,opt,name=audio,proto3" json:"audio"` +} + +func (x *Video) Reset() { + *x = Video{} + if protoimpl.UnsafeEnabled { + mi := &file_claim_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Video) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Video) ProtoMessage() {} + +func (x *Video) ProtoReflect() protoreflect.Message { + mi := &file_claim_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Video.ProtoReflect.Descriptor instead. +func (*Video) Descriptor() ([]byte, []int) { + return file_claim_proto_rawDescGZIP(), []int{8} +} + +func (x *Video) GetWidth() uint32 { + if x != nil { + return x.Width + } + return 0 +} + +func (x *Video) GetHeight() uint32 { + if x != nil { + return x.Height + } + return 0 +} + +func (x *Video) GetDuration() uint32 { + if x != nil { + return x.Duration + } + return 0 +} + +func (x *Video) GetAudio() *Audio { + if x != nil { + return x.Audio + } + return nil +} + +type Audio struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Duration uint32 `protobuf:"varint,1,opt,name=duration,proto3" json:"duration"` +} + +func (x *Audio) Reset() { + *x = Audio{} + if protoimpl.UnsafeEnabled { + mi := &file_claim_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Audio) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Audio) ProtoMessage() {} + +func (x *Audio) ProtoReflect() protoreflect.Message { + mi := &file_claim_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Audio.ProtoReflect.Descriptor instead. +func (*Audio) Descriptor() ([]byte, []int) { + return file_claim_proto_rawDescGZIP(), []int{9} +} + +func (x *Audio) GetDuration() uint32 { + if x != nil { + return x.Duration + } + return 0 +} + +type Software struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Os string `protobuf:"bytes,1,opt,name=os,proto3" json:"os"` +} + +func (x *Software) Reset() { + *x = Software{} + if protoimpl.UnsafeEnabled { + mi := &file_claim_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Software) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Software) ProtoMessage() {} + +func (x *Software) ProtoReflect() protoreflect.Message { + mi := &file_claim_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Software.ProtoReflect.Descriptor instead. +func (*Software) Descriptor() ([]byte, []int) { + return file_claim_proto_rawDescGZIP(), []int{10} +} + +func (x *Software) GetOs() string { + if x != nil { + return x.Os + } + return "" +} + +// RFC 5646 +type Language struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Language Language_Language `protobuf:"varint,1,opt,name=language,proto3,enum=pb.Language_Language" json:"language"` + Script Language_Script `protobuf:"varint,2,opt,name=script,proto3,enum=pb.Language_Script" json:"script"` + Region Location_Country `protobuf:"varint,3,opt,name=region,proto3,enum=pb.Location_Country" json:"region"` +} + +func (x *Language) Reset() { + *x = Language{} + if protoimpl.UnsafeEnabled { + mi := &file_claim_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Language) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Language) ProtoMessage() {} + +func (x *Language) ProtoReflect() protoreflect.Message { + mi := &file_claim_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Language.ProtoReflect.Descriptor instead. +func (*Language) Descriptor() ([]byte, []int) { + return file_claim_proto_rawDescGZIP(), []int{11} +} + +func (x *Language) GetLanguage() Language_Language { + if x != nil { + return x.Language + } + return Language_UNKNOWN_LANGUAGE +} + +func (x *Language) GetScript() Language_Script { + if x != nil { + return x.Script + } + return Language_UNKNOWN_SCRIPT +} + +func (x *Language) GetRegion() Location_Country { + if x != nil { + return x.Region + } + return Location_UNKNOWN_COUNTRY +} + +type Location struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Country Location_Country `protobuf:"varint,1,opt,name=country,proto3,enum=pb.Location_Country" json:"country"` + State string `protobuf:"bytes,2,opt,name=state,proto3" json:"state"` + City string `protobuf:"bytes,3,opt,name=city,proto3" json:"city"` + Code string `protobuf:"bytes,4,opt,name=code,proto3" json:"code"` + Latitude int32 `protobuf:"zigzag32,5,opt,name=latitude,proto3" json:"latitude"` + Longitude int32 `protobuf:"zigzag32,6,opt,name=longitude,proto3" json:"longitude"` +} + +func (x *Location) Reset() { + *x = Location{} + if protoimpl.UnsafeEnabled { + mi := &file_claim_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Location) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Location) ProtoMessage() {} + +func (x *Location) ProtoReflect() protoreflect.Message { + mi := &file_claim_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Location.ProtoReflect.Descriptor instead. +func (*Location) Descriptor() ([]byte, []int) { + return file_claim_proto_rawDescGZIP(), []int{12} +} + +func (x *Location) GetCountry() Location_Country { + if x != nil { + return x.Country + } + return Location_UNKNOWN_COUNTRY +} + +func (x *Location) GetState() string { + if x != nil { + return x.State + } + return "" +} + +func (x *Location) GetCity() string { + if x != nil { + return x.City + } + return "" +} + +func (x *Location) GetCode() string { + if x != nil { + return x.Code + } + return "" +} + +func (x *Location) GetLatitude() int32 { + if x != nil { + return x.Latitude + } + return 0 +} + +func (x *Location) GetLongitude() int32 { + if x != nil { + return x.Longitude + } + return 0 +} + +var File_claim_proto protoreflect.FileDescriptor + +var file_claim_proto_rawDesc = []byte{ + 0x0a, 0x0b, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, + 0x62, 0x22, 0x8b, 0x03, 0x0a, 0x05, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x12, 0x24, 0x0a, 0x06, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x62, + 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x12, 0x27, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x48, + 0x00, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x2f, 0x0a, 0x0a, 0x63, 0x6f, + 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, + 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, + 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x06, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x62, + 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, + 0x00, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x28, 0x0a, 0x09, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x52, 0x09, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x74, + 0x61, 0x67, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, + 0x2a, 0x0a, 0x09, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, + 0x52, 0x09, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, + 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, + 0xda, 0x02, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x22, 0x0a, 0x06, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x62, 0x2e, + 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, + 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x55, 0x72, + 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, + 0x54, 0x69, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x03, 0x66, 0x65, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x07, 0x2e, 0x70, 0x62, 0x2e, 0x46, 0x65, 0x65, 0x52, 0x03, 0x66, 0x65, 0x65, 0x12, + 0x21, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, + 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x05, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x12, 0x21, 0x0a, 0x05, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x09, 0x2e, 0x70, 0x62, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x48, 0x00, 0x52, 0x05, + 0x76, 0x69, 0x64, 0x65, 0x6f, 0x12, 0x21, 0x0a, 0x05, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x18, 0x0c, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x70, 0x62, 0x2e, 0x41, 0x75, 0x64, 0x69, 0x6f, 0x48, + 0x00, 0x52, 0x05, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x12, 0x2a, 0x0a, 0x08, 0x73, 0x6f, 0x66, 0x74, + 0x77, 0x61, 0x72, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x62, 0x2e, + 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x48, 0x00, 0x52, 0x08, 0x73, 0x6f, 0x66, 0x74, + 0x77, 0x61, 0x72, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xac, 0x01, 0x0a, + 0x07, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1f, 0x0a, + 0x0b, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x20, + 0x0a, 0x05, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, + 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x05, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x12, 0x29, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x64, 0x22, 0x2f, 0x0a, 0x0e, 0x43, + 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1d, 0x0a, + 0x0a, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x09, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x48, 0x61, 0x73, 0x68, 0x22, 0xab, 0x01, 0x0a, + 0x09, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x09, 0x6c, 0x69, + 0x73, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, + 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x6c, 0x69, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x3d, 0x0a, 0x10, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x62, 0x2e, 0x43, + 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0f, 0x63, + 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x22, 0x2a, + 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x4f, + 0x4c, 0x4c, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x45, + 0x52, 0x49, 0x56, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x02, 0x22, 0xaf, 0x01, 0x0a, 0x06, 0x53, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, + 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, + 0x72, 0x6c, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x62, + 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0a, 0x62, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x68, 0x61, 0x73, 0x68, 0x22, 0xa2, 0x01, 0x0a, + 0x03, 0x46, 0x65, 0x65, 0x12, 0x2c, 0x0a, 0x08, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x46, 0x65, 0x65, 0x2e, + 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x08, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x63, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, + 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, + 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3b, 0x0a, 0x08, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, + 0x12, 0x14, 0x0a, 0x10, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x43, 0x55, 0x52, 0x52, + 0x45, 0x4e, 0x43, 0x59, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4c, 0x42, 0x43, 0x10, 0x01, 0x12, + 0x07, 0x0a, 0x03, 0x42, 0x54, 0x43, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x55, 0x53, 0x44, 0x10, + 0x03, 0x22, 0x35, 0x0a, 0x05, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x72, 0x0a, 0x05, 0x56, 0x69, 0x64, 0x65, + 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x05, 0x61, + 0x75, 0x64, 0x69, 0x6f, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x70, 0x62, 0x2e, + 0x41, 0x75, 0x64, 0x69, 0x6f, 0x52, 0x05, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x22, 0x23, 0x0a, 0x05, + 0x41, 0x75, 0x64, 0x69, 0x6f, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0x70, 0x0a, 0x08, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x12, 0x0e, 0x0a, + 0x02, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x6f, 0x73, 0x22, 0x54, 0x0a, + 0x02, 0x4f, 0x53, 0x12, 0x0e, 0x0a, 0x0a, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x4f, + 0x53, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4e, 0x59, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, + 0x4c, 0x49, 0x4e, 0x55, 0x58, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x57, 0x49, 0x4e, 0x44, 0x4f, + 0x57, 0x53, 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x41, 0x43, 0x10, 0x04, 0x12, 0x0b, 0x0a, + 0x07, 0x41, 0x4e, 0x44, 0x52, 0x4f, 0x49, 0x44, 0x10, 0x05, 0x12, 0x07, 0x0a, 0x03, 0x49, 0x4f, + 0x53, 0x10, 0x06, 0x22, 0xe1, 0x1d, 0x0a, 0x08, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, + 0x12, 0x31, 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, + 0x2e, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, + 0x61, 0x67, 0x65, 0x12, 0x2b, 0x0a, 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, + 0x65, 0x2e, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x12, 0x2c, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x22, 0x99, + 0x0c, 0x0a, 0x08, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x55, + 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x4c, 0x41, 0x4e, 0x47, 0x55, 0x41, 0x47, 0x45, 0x10, + 0x00, 0x12, 0x06, 0x0a, 0x02, 0x65, 0x6e, 0x10, 0x01, 0x12, 0x06, 0x0a, 0x02, 0x61, 0x61, 0x10, + 0x02, 0x12, 0x06, 0x0a, 0x02, 0x61, 0x62, 0x10, 0x03, 0x12, 0x06, 0x0a, 0x02, 0x61, 0x65, 0x10, + 0x04, 0x12, 0x06, 0x0a, 0x02, 0x61, 0x66, 0x10, 0x05, 0x12, 0x06, 0x0a, 0x02, 0x61, 0x6b, 0x10, + 0x06, 0x12, 0x06, 0x0a, 0x02, 0x61, 0x6d, 0x10, 0x07, 0x12, 0x06, 0x0a, 0x02, 0x61, 0x6e, 0x10, + 0x08, 0x12, 0x06, 0x0a, 0x02, 0x61, 0x72, 0x10, 0x09, 0x12, 0x06, 0x0a, 0x02, 0x61, 0x73, 0x10, + 0x0a, 0x12, 0x06, 0x0a, 0x02, 0x61, 0x76, 0x10, 0x0b, 0x12, 0x06, 0x0a, 0x02, 0x61, 0x79, 0x10, + 0x0c, 0x12, 0x06, 0x0a, 0x02, 0x61, 0x7a, 0x10, 0x0d, 0x12, 0x06, 0x0a, 0x02, 0x62, 0x61, 0x10, + 0x0e, 0x12, 0x06, 0x0a, 0x02, 0x62, 0x65, 0x10, 0x0f, 0x12, 0x06, 0x0a, 0x02, 0x62, 0x67, 0x10, + 0x10, 0x12, 0x06, 0x0a, 0x02, 0x62, 0x68, 0x10, 0x11, 0x12, 0x06, 0x0a, 0x02, 0x62, 0x69, 0x10, + 0x12, 0x12, 0x06, 0x0a, 0x02, 0x62, 0x6d, 0x10, 0x13, 0x12, 0x06, 0x0a, 0x02, 0x62, 0x6e, 0x10, + 0x14, 0x12, 0x06, 0x0a, 0x02, 0x62, 0x6f, 0x10, 0x15, 0x12, 0x06, 0x0a, 0x02, 0x62, 0x72, 0x10, + 0x16, 0x12, 0x06, 0x0a, 0x02, 0x62, 0x73, 0x10, 0x17, 0x12, 0x06, 0x0a, 0x02, 0x63, 0x61, 0x10, + 0x18, 0x12, 0x06, 0x0a, 0x02, 0x63, 0x65, 0x10, 0x19, 0x12, 0x06, 0x0a, 0x02, 0x63, 0x68, 0x10, + 0x1a, 0x12, 0x06, 0x0a, 0x02, 0x63, 0x6f, 0x10, 0x1b, 0x12, 0x06, 0x0a, 0x02, 0x63, 0x72, 0x10, + 0x1c, 0x12, 0x06, 0x0a, 0x02, 0x63, 0x73, 0x10, 0x1d, 0x12, 0x06, 0x0a, 0x02, 0x63, 0x75, 0x10, + 0x1e, 0x12, 0x06, 0x0a, 0x02, 0x63, 0x76, 0x10, 0x1f, 0x12, 0x06, 0x0a, 0x02, 0x63, 0x79, 0x10, + 0x20, 0x12, 0x06, 0x0a, 0x02, 0x64, 0x61, 0x10, 0x21, 0x12, 0x06, 0x0a, 0x02, 0x64, 0x65, 0x10, + 0x22, 0x12, 0x06, 0x0a, 0x02, 0x64, 0x76, 0x10, 0x23, 0x12, 0x06, 0x0a, 0x02, 0x64, 0x7a, 0x10, + 0x24, 0x12, 0x06, 0x0a, 0x02, 0x65, 0x65, 0x10, 0x25, 0x12, 0x06, 0x0a, 0x02, 0x65, 0x6c, 0x10, + 0x26, 0x12, 0x06, 0x0a, 0x02, 0x65, 0x6f, 0x10, 0x27, 0x12, 0x06, 0x0a, 0x02, 0x65, 0x73, 0x10, + 0x28, 0x12, 0x06, 0x0a, 0x02, 0x65, 0x74, 0x10, 0x29, 0x12, 0x06, 0x0a, 0x02, 0x65, 0x75, 0x10, + 0x2a, 0x12, 0x06, 0x0a, 0x02, 0x66, 0x61, 0x10, 0x2b, 0x12, 0x06, 0x0a, 0x02, 0x66, 0x66, 0x10, + 0x2c, 0x12, 0x06, 0x0a, 0x02, 0x66, 0x69, 0x10, 0x2d, 0x12, 0x06, 0x0a, 0x02, 0x66, 0x6a, 0x10, + 0x2e, 0x12, 0x06, 0x0a, 0x02, 0x66, 0x6f, 0x10, 0x2f, 0x12, 0x06, 0x0a, 0x02, 0x66, 0x72, 0x10, + 0x30, 0x12, 0x06, 0x0a, 0x02, 0x66, 0x79, 0x10, 0x31, 0x12, 0x06, 0x0a, 0x02, 0x67, 0x61, 0x10, + 0x32, 0x12, 0x06, 0x0a, 0x02, 0x67, 0x64, 0x10, 0x33, 0x12, 0x06, 0x0a, 0x02, 0x67, 0x6c, 0x10, + 0x34, 0x12, 0x06, 0x0a, 0x02, 0x67, 0x6e, 0x10, 0x35, 0x12, 0x06, 0x0a, 0x02, 0x67, 0x75, 0x10, + 0x36, 0x12, 0x06, 0x0a, 0x02, 0x67, 0x76, 0x10, 0x37, 0x12, 0x06, 0x0a, 0x02, 0x68, 0x61, 0x10, + 0x38, 0x12, 0x06, 0x0a, 0x02, 0x68, 0x65, 0x10, 0x39, 0x12, 0x06, 0x0a, 0x02, 0x68, 0x69, 0x10, + 0x3a, 0x12, 0x06, 0x0a, 0x02, 0x68, 0x6f, 0x10, 0x3b, 0x12, 0x06, 0x0a, 0x02, 0x68, 0x72, 0x10, + 0x3c, 0x12, 0x06, 0x0a, 0x02, 0x68, 0x74, 0x10, 0x3d, 0x12, 0x06, 0x0a, 0x02, 0x68, 0x75, 0x10, + 0x3e, 0x12, 0x06, 0x0a, 0x02, 0x68, 0x79, 0x10, 0x3f, 0x12, 0x06, 0x0a, 0x02, 0x68, 0x7a, 0x10, + 0x40, 0x12, 0x06, 0x0a, 0x02, 0x69, 0x61, 0x10, 0x41, 0x12, 0x06, 0x0a, 0x02, 0x69, 0x64, 0x10, + 0x42, 0x12, 0x06, 0x0a, 0x02, 0x69, 0x65, 0x10, 0x43, 0x12, 0x06, 0x0a, 0x02, 0x69, 0x67, 0x10, + 0x44, 0x12, 0x06, 0x0a, 0x02, 0x69, 0x69, 0x10, 0x45, 0x12, 0x06, 0x0a, 0x02, 0x69, 0x6b, 0x10, + 0x46, 0x12, 0x06, 0x0a, 0x02, 0x69, 0x6f, 0x10, 0x47, 0x12, 0x06, 0x0a, 0x02, 0x69, 0x73, 0x10, + 0x48, 0x12, 0x06, 0x0a, 0x02, 0x69, 0x74, 0x10, 0x49, 0x12, 0x06, 0x0a, 0x02, 0x69, 0x75, 0x10, + 0x4a, 0x12, 0x06, 0x0a, 0x02, 0x6a, 0x61, 0x10, 0x4b, 0x12, 0x06, 0x0a, 0x02, 0x6a, 0x76, 0x10, + 0x4c, 0x12, 0x06, 0x0a, 0x02, 0x6b, 0x61, 0x10, 0x4d, 0x12, 0x06, 0x0a, 0x02, 0x6b, 0x67, 0x10, + 0x4e, 0x12, 0x06, 0x0a, 0x02, 0x6b, 0x69, 0x10, 0x4f, 0x12, 0x06, 0x0a, 0x02, 0x6b, 0x6a, 0x10, + 0x50, 0x12, 0x06, 0x0a, 0x02, 0x6b, 0x6b, 0x10, 0x51, 0x12, 0x06, 0x0a, 0x02, 0x6b, 0x6c, 0x10, + 0x52, 0x12, 0x06, 0x0a, 0x02, 0x6b, 0x6d, 0x10, 0x53, 0x12, 0x06, 0x0a, 0x02, 0x6b, 0x6e, 0x10, + 0x54, 0x12, 0x06, 0x0a, 0x02, 0x6b, 0x6f, 0x10, 0x55, 0x12, 0x06, 0x0a, 0x02, 0x6b, 0x72, 0x10, + 0x56, 0x12, 0x06, 0x0a, 0x02, 0x6b, 0x73, 0x10, 0x57, 0x12, 0x06, 0x0a, 0x02, 0x6b, 0x75, 0x10, + 0x58, 0x12, 0x06, 0x0a, 0x02, 0x6b, 0x76, 0x10, 0x59, 0x12, 0x06, 0x0a, 0x02, 0x6b, 0x77, 0x10, + 0x5a, 0x12, 0x06, 0x0a, 0x02, 0x6b, 0x79, 0x10, 0x5b, 0x12, 0x06, 0x0a, 0x02, 0x6c, 0x61, 0x10, + 0x5c, 0x12, 0x06, 0x0a, 0x02, 0x6c, 0x62, 0x10, 0x5d, 0x12, 0x06, 0x0a, 0x02, 0x6c, 0x67, 0x10, + 0x5e, 0x12, 0x06, 0x0a, 0x02, 0x6c, 0x69, 0x10, 0x5f, 0x12, 0x06, 0x0a, 0x02, 0x6c, 0x6e, 0x10, + 0x60, 0x12, 0x06, 0x0a, 0x02, 0x6c, 0x6f, 0x10, 0x61, 0x12, 0x06, 0x0a, 0x02, 0x6c, 0x74, 0x10, + 0x62, 0x12, 0x06, 0x0a, 0x02, 0x6c, 0x75, 0x10, 0x63, 0x12, 0x06, 0x0a, 0x02, 0x6c, 0x76, 0x10, + 0x64, 0x12, 0x06, 0x0a, 0x02, 0x6d, 0x67, 0x10, 0x65, 0x12, 0x06, 0x0a, 0x02, 0x6d, 0x68, 0x10, + 0x66, 0x12, 0x06, 0x0a, 0x02, 0x6d, 0x69, 0x10, 0x67, 0x12, 0x06, 0x0a, 0x02, 0x6d, 0x6b, 0x10, + 0x68, 0x12, 0x06, 0x0a, 0x02, 0x6d, 0x6c, 0x10, 0x69, 0x12, 0x06, 0x0a, 0x02, 0x6d, 0x6e, 0x10, + 0x6a, 0x12, 0x06, 0x0a, 0x02, 0x6d, 0x72, 0x10, 0x6b, 0x12, 0x06, 0x0a, 0x02, 0x6d, 0x73, 0x10, + 0x6c, 0x12, 0x06, 0x0a, 0x02, 0x6d, 0x74, 0x10, 0x6d, 0x12, 0x06, 0x0a, 0x02, 0x6d, 0x79, 0x10, + 0x6e, 0x12, 0x06, 0x0a, 0x02, 0x6e, 0x61, 0x10, 0x6f, 0x12, 0x06, 0x0a, 0x02, 0x6e, 0x62, 0x10, + 0x70, 0x12, 0x06, 0x0a, 0x02, 0x6e, 0x64, 0x10, 0x71, 0x12, 0x06, 0x0a, 0x02, 0x6e, 0x65, 0x10, + 0x72, 0x12, 0x06, 0x0a, 0x02, 0x6e, 0x67, 0x10, 0x73, 0x12, 0x06, 0x0a, 0x02, 0x6e, 0x6c, 0x10, + 0x74, 0x12, 0x06, 0x0a, 0x02, 0x6e, 0x6e, 0x10, 0x75, 0x12, 0x06, 0x0a, 0x02, 0x6e, 0x6f, 0x10, + 0x76, 0x12, 0x06, 0x0a, 0x02, 0x6e, 0x72, 0x10, 0x77, 0x12, 0x06, 0x0a, 0x02, 0x6e, 0x76, 0x10, + 0x78, 0x12, 0x06, 0x0a, 0x02, 0x6e, 0x79, 0x10, 0x79, 0x12, 0x06, 0x0a, 0x02, 0x6f, 0x63, 0x10, + 0x7a, 0x12, 0x06, 0x0a, 0x02, 0x6f, 0x6a, 0x10, 0x7b, 0x12, 0x06, 0x0a, 0x02, 0x6f, 0x6d, 0x10, + 0x7c, 0x12, 0x06, 0x0a, 0x02, 0x6f, 0x72, 0x10, 0x7d, 0x12, 0x06, 0x0a, 0x02, 0x6f, 0x73, 0x10, + 0x7e, 0x12, 0x06, 0x0a, 0x02, 0x70, 0x61, 0x10, 0x7f, 0x12, 0x07, 0x0a, 0x02, 0x70, 0x69, 0x10, + 0x80, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x70, 0x6c, 0x10, 0x81, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x70, + 0x73, 0x10, 0x82, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x70, 0x74, 0x10, 0x83, 0x01, 0x12, 0x07, 0x0a, + 0x02, 0x71, 0x75, 0x10, 0x84, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x72, 0x6d, 0x10, 0x85, 0x01, 0x12, + 0x07, 0x0a, 0x02, 0x72, 0x6e, 0x10, 0x86, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x72, 0x6f, 0x10, 0x87, + 0x01, 0x12, 0x07, 0x0a, 0x02, 0x72, 0x75, 0x10, 0x88, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x72, 0x77, + 0x10, 0x89, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x73, 0x61, 0x10, 0x8a, 0x01, 0x12, 0x07, 0x0a, 0x02, + 0x73, 0x63, 0x10, 0x8b, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x73, 0x64, 0x10, 0x8c, 0x01, 0x12, 0x07, + 0x0a, 0x02, 0x73, 0x65, 0x10, 0x8d, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x73, 0x67, 0x10, 0x8e, 0x01, + 0x12, 0x07, 0x0a, 0x02, 0x73, 0x69, 0x10, 0x8f, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x73, 0x6b, 0x10, + 0x90, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x73, 0x6c, 0x10, 0x91, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x73, + 0x6d, 0x10, 0x92, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x73, 0x6e, 0x10, 0x93, 0x01, 0x12, 0x07, 0x0a, + 0x02, 0x73, 0x6f, 0x10, 0x94, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x73, 0x71, 0x10, 0x95, 0x01, 0x12, + 0x07, 0x0a, 0x02, 0x73, 0x72, 0x10, 0x96, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x73, 0x73, 0x10, 0x97, + 0x01, 0x12, 0x07, 0x0a, 0x02, 0x73, 0x74, 0x10, 0x98, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x73, 0x75, + 0x10, 0x99, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x73, 0x76, 0x10, 0x9a, 0x01, 0x12, 0x07, 0x0a, 0x02, + 0x73, 0x77, 0x10, 0x9b, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x74, 0x61, 0x10, 0x9c, 0x01, 0x12, 0x07, + 0x0a, 0x02, 0x74, 0x65, 0x10, 0x9d, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x74, 0x67, 0x10, 0x9e, 0x01, + 0x12, 0x07, 0x0a, 0x02, 0x74, 0x68, 0x10, 0x9f, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x74, 0x69, 0x10, + 0xa0, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x74, 0x6b, 0x10, 0xa1, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x74, + 0x6c, 0x10, 0xa2, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x74, 0x6e, 0x10, 0xa3, 0x01, 0x12, 0x07, 0x0a, + 0x02, 0x74, 0x6f, 0x10, 0xa4, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x74, 0x72, 0x10, 0xa5, 0x01, 0x12, + 0x07, 0x0a, 0x02, 0x74, 0x73, 0x10, 0xa6, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x74, 0x74, 0x10, 0xa7, + 0x01, 0x12, 0x07, 0x0a, 0x02, 0x74, 0x77, 0x10, 0xa8, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x74, 0x79, + 0x10, 0xa9, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x75, 0x67, 0x10, 0xaa, 0x01, 0x12, 0x07, 0x0a, 0x02, + 0x75, 0x6b, 0x10, 0xab, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x75, 0x72, 0x10, 0xac, 0x01, 0x12, 0x07, + 0x0a, 0x02, 0x75, 0x7a, 0x10, 0xad, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x76, 0x65, 0x10, 0xae, 0x01, + 0x12, 0x07, 0x0a, 0x02, 0x76, 0x69, 0x10, 0xaf, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x76, 0x6f, 0x10, + 0xb0, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x77, 0x61, 0x10, 0xb1, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x77, + 0x6f, 0x10, 0xb2, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x78, 0x68, 0x10, 0xb3, 0x01, 0x12, 0x07, 0x0a, + 0x02, 0x79, 0x69, 0x10, 0xb4, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x79, 0x6f, 0x10, 0xb5, 0x01, 0x12, + 0x07, 0x0a, 0x02, 0x7a, 0x61, 0x10, 0xb6, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x7a, 0x68, 0x10, 0xb7, + 0x01, 0x12, 0x07, 0x0a, 0x02, 0x7a, 0x75, 0x10, 0xb8, 0x01, 0x22, 0xaa, 0x10, 0x0a, 0x06, 0x53, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x12, 0x0a, 0x0e, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, + 0x5f, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x64, 0x6c, + 0x6d, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x66, 0x61, 0x6b, 0x10, 0x02, 0x12, 0x08, 0x0a, + 0x04, 0x41, 0x67, 0x68, 0x62, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x68, 0x6f, 0x6d, 0x10, + 0x04, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x72, 0x61, 0x62, 0x10, 0x05, 0x12, 0x08, 0x0a, 0x04, 0x41, + 0x72, 0x61, 0x6e, 0x10, 0x06, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x72, 0x6d, 0x69, 0x10, 0x07, 0x12, + 0x08, 0x0a, 0x04, 0x41, 0x72, 0x6d, 0x6e, 0x10, 0x08, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x76, 0x73, + 0x74, 0x10, 0x09, 0x12, 0x08, 0x0a, 0x04, 0x42, 0x61, 0x6c, 0x69, 0x10, 0x0a, 0x12, 0x08, 0x0a, + 0x04, 0x42, 0x61, 0x6d, 0x75, 0x10, 0x0b, 0x12, 0x08, 0x0a, 0x04, 0x42, 0x61, 0x73, 0x73, 0x10, + 0x0c, 0x12, 0x08, 0x0a, 0x04, 0x42, 0x61, 0x74, 0x6b, 0x10, 0x0d, 0x12, 0x08, 0x0a, 0x04, 0x42, + 0x65, 0x6e, 0x67, 0x10, 0x0e, 0x12, 0x08, 0x0a, 0x04, 0x42, 0x68, 0x6b, 0x73, 0x10, 0x0f, 0x12, + 0x08, 0x0a, 0x04, 0x42, 0x6c, 0x69, 0x73, 0x10, 0x10, 0x12, 0x08, 0x0a, 0x04, 0x42, 0x6f, 0x70, + 0x6f, 0x10, 0x11, 0x12, 0x08, 0x0a, 0x04, 0x42, 0x72, 0x61, 0x68, 0x10, 0x12, 0x12, 0x08, 0x0a, + 0x04, 0x42, 0x72, 0x61, 0x69, 0x10, 0x13, 0x12, 0x08, 0x0a, 0x04, 0x42, 0x75, 0x67, 0x69, 0x10, + 0x14, 0x12, 0x08, 0x0a, 0x04, 0x42, 0x75, 0x68, 0x64, 0x10, 0x15, 0x12, 0x08, 0x0a, 0x04, 0x43, + 0x61, 0x6b, 0x6d, 0x10, 0x16, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x61, 0x6e, 0x73, 0x10, 0x17, 0x12, + 0x08, 0x0a, 0x04, 0x43, 0x61, 0x72, 0x69, 0x10, 0x18, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x68, 0x61, + 0x6d, 0x10, 0x19, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x68, 0x65, 0x72, 0x10, 0x1a, 0x12, 0x08, 0x0a, + 0x04, 0x43, 0x69, 0x72, 0x74, 0x10, 0x1b, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x6f, 0x70, 0x74, 0x10, + 0x1c, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x70, 0x6d, 0x6e, 0x10, 0x1d, 0x12, 0x08, 0x0a, 0x04, 0x43, + 0x70, 0x72, 0x74, 0x10, 0x1e, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x79, 0x72, 0x6c, 0x10, 0x1f, 0x12, + 0x08, 0x0a, 0x04, 0x43, 0x79, 0x72, 0x73, 0x10, 0x20, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x65, 0x76, + 0x61, 0x10, 0x21, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x6f, 0x67, 0x72, 0x10, 0x22, 0x12, 0x08, 0x0a, + 0x04, 0x44, 0x73, 0x72, 0x74, 0x10, 0x23, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x75, 0x70, 0x6c, 0x10, + 0x24, 0x12, 0x08, 0x0a, 0x04, 0x45, 0x67, 0x79, 0x64, 0x10, 0x25, 0x12, 0x08, 0x0a, 0x04, 0x45, + 0x67, 0x79, 0x68, 0x10, 0x26, 0x12, 0x08, 0x0a, 0x04, 0x45, 0x67, 0x79, 0x70, 0x10, 0x27, 0x12, + 0x08, 0x0a, 0x04, 0x45, 0x6c, 0x62, 0x61, 0x10, 0x28, 0x12, 0x08, 0x0a, 0x04, 0x45, 0x6c, 0x79, + 0x6d, 0x10, 0x29, 0x12, 0x08, 0x0a, 0x04, 0x45, 0x74, 0x68, 0x69, 0x10, 0x2a, 0x12, 0x08, 0x0a, + 0x04, 0x47, 0x65, 0x6f, 0x6b, 0x10, 0x2b, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x65, 0x6f, 0x72, 0x10, + 0x2c, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x6c, 0x61, 0x67, 0x10, 0x2d, 0x12, 0x08, 0x0a, 0x04, 0x47, + 0x6f, 0x6e, 0x67, 0x10, 0x2e, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x6f, 0x6e, 0x6d, 0x10, 0x2f, 0x12, + 0x08, 0x0a, 0x04, 0x47, 0x6f, 0x74, 0x68, 0x10, 0x30, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x72, 0x61, + 0x6e, 0x10, 0x31, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x72, 0x65, 0x6b, 0x10, 0x32, 0x12, 0x08, 0x0a, + 0x04, 0x47, 0x75, 0x6a, 0x72, 0x10, 0x33, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x75, 0x72, 0x75, 0x10, + 0x34, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x61, 0x6e, 0x62, 0x10, 0x35, 0x12, 0x08, 0x0a, 0x04, 0x48, + 0x61, 0x6e, 0x67, 0x10, 0x36, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x61, 0x6e, 0x69, 0x10, 0x37, 0x12, + 0x08, 0x0a, 0x04, 0x48, 0x61, 0x6e, 0x6f, 0x10, 0x38, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x61, 0x6e, + 0x73, 0x10, 0x39, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x61, 0x6e, 0x74, 0x10, 0x3a, 0x12, 0x08, 0x0a, + 0x04, 0x48, 0x61, 0x74, 0x72, 0x10, 0x3b, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x65, 0x62, 0x72, 0x10, + 0x3c, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x69, 0x72, 0x61, 0x10, 0x3d, 0x12, 0x08, 0x0a, 0x04, 0x48, + 0x6c, 0x75, 0x77, 0x10, 0x3e, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x6d, 0x6e, 0x67, 0x10, 0x3f, 0x12, + 0x08, 0x0a, 0x04, 0x48, 0x6d, 0x6e, 0x70, 0x10, 0x40, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x72, 0x6b, + 0x74, 0x10, 0x41, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x75, 0x6e, 0x67, 0x10, 0x42, 0x12, 0x08, 0x0a, + 0x04, 0x49, 0x6e, 0x64, 0x73, 0x10, 0x43, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x74, 0x61, 0x6c, 0x10, + 0x44, 0x12, 0x08, 0x0a, 0x04, 0x4a, 0x61, 0x6d, 0x6f, 0x10, 0x45, 0x12, 0x08, 0x0a, 0x04, 0x4a, + 0x61, 0x76, 0x61, 0x10, 0x46, 0x12, 0x08, 0x0a, 0x04, 0x4a, 0x70, 0x61, 0x6e, 0x10, 0x47, 0x12, + 0x08, 0x0a, 0x04, 0x4a, 0x75, 0x72, 0x63, 0x10, 0x48, 0x12, 0x08, 0x0a, 0x04, 0x4b, 0x61, 0x6c, + 0x69, 0x10, 0x49, 0x12, 0x08, 0x0a, 0x04, 0x4b, 0x61, 0x6e, 0x61, 0x10, 0x4a, 0x12, 0x08, 0x0a, + 0x04, 0x4b, 0x68, 0x61, 0x72, 0x10, 0x4b, 0x12, 0x08, 0x0a, 0x04, 0x4b, 0x68, 0x6d, 0x72, 0x10, + 0x4c, 0x12, 0x08, 0x0a, 0x04, 0x4b, 0x68, 0x6f, 0x6a, 0x10, 0x4d, 0x12, 0x08, 0x0a, 0x04, 0x4b, + 0x69, 0x74, 0x6c, 0x10, 0x4e, 0x12, 0x08, 0x0a, 0x04, 0x4b, 0x69, 0x74, 0x73, 0x10, 0x4f, 0x12, + 0x08, 0x0a, 0x04, 0x4b, 0x6e, 0x64, 0x61, 0x10, 0x50, 0x12, 0x08, 0x0a, 0x04, 0x4b, 0x6f, 0x72, + 0x65, 0x10, 0x51, 0x12, 0x08, 0x0a, 0x04, 0x4b, 0x70, 0x65, 0x6c, 0x10, 0x52, 0x12, 0x08, 0x0a, + 0x04, 0x4b, 0x74, 0x68, 0x69, 0x10, 0x53, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x61, 0x6e, 0x61, 0x10, + 0x54, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x61, 0x6f, 0x6f, 0x10, 0x55, 0x12, 0x08, 0x0a, 0x04, 0x4c, + 0x61, 0x74, 0x66, 0x10, 0x56, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x61, 0x74, 0x67, 0x10, 0x57, 0x12, + 0x08, 0x0a, 0x04, 0x4c, 0x61, 0x74, 0x6e, 0x10, 0x58, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x65, 0x6b, + 0x65, 0x10, 0x59, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x65, 0x70, 0x63, 0x10, 0x5a, 0x12, 0x08, 0x0a, + 0x04, 0x4c, 0x69, 0x6d, 0x62, 0x10, 0x5b, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x69, 0x6e, 0x61, 0x10, + 0x5c, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x69, 0x6e, 0x62, 0x10, 0x5d, 0x12, 0x08, 0x0a, 0x04, 0x4c, + 0x69, 0x73, 0x75, 0x10, 0x5e, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x6f, 0x6d, 0x61, 0x10, 0x5f, 0x12, + 0x08, 0x0a, 0x04, 0x4c, 0x79, 0x63, 0x69, 0x10, 0x60, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x79, 0x64, + 0x69, 0x10, 0x61, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x61, 0x68, 0x6a, 0x10, 0x62, 0x12, 0x08, 0x0a, + 0x04, 0x4d, 0x61, 0x6b, 0x61, 0x10, 0x63, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x61, 0x6e, 0x64, 0x10, + 0x64, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x61, 0x6e, 0x69, 0x10, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4d, + 0x61, 0x72, 0x63, 0x10, 0x66, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x61, 0x79, 0x61, 0x10, 0x67, 0x12, + 0x08, 0x0a, 0x04, 0x4d, 0x65, 0x64, 0x66, 0x10, 0x68, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x65, 0x6e, + 0x64, 0x10, 0x69, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x65, 0x72, 0x63, 0x10, 0x6a, 0x12, 0x08, 0x0a, + 0x04, 0x4d, 0x65, 0x72, 0x6f, 0x10, 0x6b, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x6c, 0x79, 0x6d, 0x10, + 0x6c, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x69, 0x10, 0x6d, 0x12, 0x08, 0x0a, 0x04, 0x4d, + 0x6f, 0x6e, 0x67, 0x10, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x6f, 0x6f, 0x6e, 0x10, 0x6f, 0x12, + 0x08, 0x0a, 0x04, 0x4d, 0x72, 0x6f, 0x6f, 0x10, 0x70, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x74, 0x65, + 0x69, 0x10, 0x71, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x75, 0x6c, 0x74, 0x10, 0x72, 0x12, 0x08, 0x0a, + 0x04, 0x4d, 0x79, 0x6d, 0x72, 0x10, 0x73, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x61, 0x6e, 0x64, 0x10, + 0x74, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x61, 0x72, 0x62, 0x10, 0x75, 0x12, 0x08, 0x0a, 0x04, 0x4e, + 0x62, 0x61, 0x74, 0x10, 0x76, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x65, 0x77, 0x61, 0x10, 0x77, 0x12, + 0x08, 0x0a, 0x04, 0x4e, 0x6b, 0x64, 0x62, 0x10, 0x78, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6b, 0x67, + 0x62, 0x10, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6b, 0x6f, 0x6f, 0x10, 0x7a, 0x12, 0x08, 0x0a, + 0x04, 0x4e, 0x73, 0x68, 0x75, 0x10, 0x7b, 0x12, 0x08, 0x0a, 0x04, 0x4f, 0x67, 0x61, 0x6d, 0x10, + 0x7c, 0x12, 0x08, 0x0a, 0x04, 0x4f, 0x6c, 0x63, 0x6b, 0x10, 0x7d, 0x12, 0x08, 0x0a, 0x04, 0x4f, + 0x72, 0x6b, 0x68, 0x10, 0x7e, 0x12, 0x08, 0x0a, 0x04, 0x4f, 0x72, 0x79, 0x61, 0x10, 0x7f, 0x12, + 0x09, 0x0a, 0x04, 0x4f, 0x73, 0x67, 0x65, 0x10, 0x80, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x4f, 0x73, + 0x6d, 0x61, 0x10, 0x81, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x50, 0x61, 0x6c, 0x6d, 0x10, 0x82, 0x01, + 0x12, 0x09, 0x0a, 0x04, 0x50, 0x61, 0x75, 0x63, 0x10, 0x83, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x50, + 0x65, 0x72, 0x6d, 0x10, 0x84, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x50, 0x68, 0x61, 0x67, 0x10, 0x85, + 0x01, 0x12, 0x09, 0x0a, 0x04, 0x50, 0x68, 0x6c, 0x69, 0x10, 0x86, 0x01, 0x12, 0x09, 0x0a, 0x04, + 0x50, 0x68, 0x6c, 0x70, 0x10, 0x87, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x50, 0x68, 0x6c, 0x76, 0x10, + 0x88, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x50, 0x68, 0x6e, 0x78, 0x10, 0x89, 0x01, 0x12, 0x09, 0x0a, + 0x04, 0x50, 0x6c, 0x72, 0x64, 0x10, 0x8a, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x50, 0x69, 0x71, 0x64, + 0x10, 0x8b, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x50, 0x72, 0x74, 0x69, 0x10, 0x8c, 0x01, 0x12, 0x09, + 0x0a, 0x04, 0x51, 0x61, 0x61, 0x61, 0x10, 0x8d, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x51, 0x61, 0x62, + 0x78, 0x10, 0x8e, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x6a, 0x6e, 0x67, 0x10, 0x8f, 0x01, 0x12, + 0x09, 0x0a, 0x04, 0x52, 0x6f, 0x68, 0x67, 0x10, 0x90, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x6f, + 0x72, 0x6f, 0x10, 0x91, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x75, 0x6e, 0x72, 0x10, 0x92, 0x01, + 0x12, 0x09, 0x0a, 0x04, 0x53, 0x61, 0x6d, 0x72, 0x10, 0x93, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x53, + 0x61, 0x72, 0x61, 0x10, 0x94, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x53, 0x61, 0x72, 0x62, 0x10, 0x95, + 0x01, 0x12, 0x09, 0x0a, 0x04, 0x53, 0x61, 0x75, 0x72, 0x10, 0x96, 0x01, 0x12, 0x09, 0x0a, 0x04, + 0x53, 0x67, 0x6e, 0x77, 0x10, 0x97, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x53, 0x68, 0x61, 0x77, 0x10, + 0x98, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x53, 0x68, 0x72, 0x64, 0x10, 0x99, 0x01, 0x12, 0x09, 0x0a, + 0x04, 0x53, 0x68, 0x75, 0x69, 0x10, 0x9a, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x53, 0x69, 0x64, 0x64, + 0x10, 0x9b, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x53, 0x69, 0x6e, 0x64, 0x10, 0x9c, 0x01, 0x12, 0x09, + 0x0a, 0x04, 0x53, 0x69, 0x6e, 0x68, 0x10, 0x9d, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x53, 0x6f, 0x67, + 0x64, 0x10, 0x9e, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x53, 0x6f, 0x67, 0x6f, 0x10, 0x9f, 0x01, 0x12, + 0x09, 0x0a, 0x04, 0x53, 0x6f, 0x72, 0x61, 0x10, 0xa0, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x53, 0x6f, + 0x79, 0x6f, 0x10, 0xa1, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x53, 0x75, 0x6e, 0x64, 0x10, 0xa2, 0x01, + 0x12, 0x09, 0x0a, 0x04, 0x53, 0x79, 0x6c, 0x6f, 0x10, 0xa3, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x53, + 0x79, 0x72, 0x63, 0x10, 0xa4, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x53, 0x79, 0x72, 0x65, 0x10, 0xa5, + 0x01, 0x12, 0x09, 0x0a, 0x04, 0x53, 0x79, 0x72, 0x6a, 0x10, 0xa6, 0x01, 0x12, 0x09, 0x0a, 0x04, + 0x53, 0x79, 0x72, 0x6e, 0x10, 0xa7, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x62, 0x10, + 0xa8, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x54, 0x61, 0x6b, 0x72, 0x10, 0xa9, 0x01, 0x12, 0x09, 0x0a, + 0x04, 0x54, 0x61, 0x6c, 0x65, 0x10, 0xaa, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x54, 0x61, 0x6c, 0x75, + 0x10, 0xab, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x54, 0x61, 0x6d, 0x6c, 0x10, 0xac, 0x01, 0x12, 0x09, + 0x0a, 0x04, 0x54, 0x61, 0x6e, 0x67, 0x10, 0xad, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x54, 0x61, 0x76, + 0x74, 0x10, 0xae, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x54, 0x65, 0x6c, 0x75, 0x10, 0xaf, 0x01, 0x12, + 0x09, 0x0a, 0x04, 0x54, 0x65, 0x6e, 0x67, 0x10, 0xb0, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x54, 0x66, + 0x6e, 0x67, 0x10, 0xb1, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x54, 0x67, 0x6c, 0x67, 0x10, 0xb2, 0x01, + 0x12, 0x09, 0x0a, 0x04, 0x54, 0x68, 0x61, 0x61, 0x10, 0xb3, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x54, + 0x68, 0x61, 0x69, 0x10, 0xb4, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x54, 0x69, 0x62, 0x74, 0x10, 0xb5, + 0x01, 0x12, 0x09, 0x0a, 0x04, 0x54, 0x69, 0x72, 0x68, 0x10, 0xb6, 0x01, 0x12, 0x09, 0x0a, 0x04, + 0x55, 0x67, 0x61, 0x72, 0x10, 0xb7, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x56, 0x61, 0x69, 0x69, 0x10, + 0xb8, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x56, 0x69, 0x73, 0x70, 0x10, 0xb9, 0x01, 0x12, 0x09, 0x0a, + 0x04, 0x57, 0x61, 0x72, 0x61, 0x10, 0xba, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x57, 0x63, 0x68, 0x6f, + 0x10, 0xbb, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x57, 0x6f, 0x6c, 0x65, 0x10, 0xbc, 0x01, 0x12, 0x09, + 0x0a, 0x04, 0x58, 0x70, 0x65, 0x6f, 0x10, 0xbd, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x58, 0x73, 0x75, + 0x78, 0x10, 0xbe, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x59, 0x69, 0x69, 0x69, 0x10, 0xbf, 0x01, 0x12, + 0x09, 0x0a, 0x04, 0x5a, 0x61, 0x6e, 0x62, 0x10, 0xc0, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x5a, 0x69, + 0x6e, 0x68, 0x10, 0xc1, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x5a, 0x6d, 0x74, 0x68, 0x10, 0xc2, 0x01, + 0x12, 0x09, 0x0a, 0x04, 0x5a, 0x73, 0x79, 0x65, 0x10, 0xc3, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x5a, + 0x73, 0x79, 0x6d, 0x10, 0xc4, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x5a, 0x78, 0x78, 0x78, 0x10, 0xc5, + 0x01, 0x12, 0x09, 0x0a, 0x04, 0x5a, 0x79, 0x79, 0x79, 0x10, 0xc6, 0x01, 0x12, 0x09, 0x0a, 0x04, + 0x5a, 0x7a, 0x7a, 0x7a, 0x10, 0xc7, 0x01, 0x22, 0x9d, 0x2a, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x69, + 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x69, 0x74, 0x79, 0x12, 0x12, + 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, + 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x11, 0x52, 0x08, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x1c, + 0x0a, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x11, 0x52, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x22, 0xe8, 0x28, 0x0a, + 0x07, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x13, 0x0a, 0x0f, 0x55, 0x4e, 0x4b, 0x4e, + 0x4f, 0x57, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x52, 0x59, 0x10, 0x00, 0x12, 0x06, 0x0a, + 0x02, 0x41, 0x46, 0x10, 0x01, 0x12, 0x06, 0x0a, 0x02, 0x41, 0x58, 0x10, 0x02, 0x12, 0x06, 0x0a, + 0x02, 0x41, 0x4c, 0x10, 0x03, 0x12, 0x06, 0x0a, 0x02, 0x44, 0x5a, 0x10, 0x04, 0x12, 0x06, 0x0a, + 0x02, 0x41, 0x53, 0x10, 0x05, 0x12, 0x06, 0x0a, 0x02, 0x41, 0x44, 0x10, 0x06, 0x12, 0x06, 0x0a, + 0x02, 0x41, 0x4f, 0x10, 0x07, 0x12, 0x06, 0x0a, 0x02, 0x41, 0x49, 0x10, 0x08, 0x12, 0x06, 0x0a, + 0x02, 0x41, 0x51, 0x10, 0x09, 0x12, 0x06, 0x0a, 0x02, 0x41, 0x47, 0x10, 0x0a, 0x12, 0x06, 0x0a, + 0x02, 0x41, 0x52, 0x10, 0x0b, 0x12, 0x06, 0x0a, 0x02, 0x41, 0x4d, 0x10, 0x0c, 0x12, 0x06, 0x0a, + 0x02, 0x41, 0x57, 0x10, 0x0d, 0x12, 0x06, 0x0a, 0x02, 0x41, 0x55, 0x10, 0x0e, 0x12, 0x06, 0x0a, + 0x02, 0x41, 0x54, 0x10, 0x0f, 0x12, 0x06, 0x0a, 0x02, 0x41, 0x5a, 0x10, 0x10, 0x12, 0x06, 0x0a, + 0x02, 0x42, 0x53, 0x10, 0x11, 0x12, 0x06, 0x0a, 0x02, 0x42, 0x48, 0x10, 0x12, 0x12, 0x06, 0x0a, + 0x02, 0x42, 0x44, 0x10, 0x13, 0x12, 0x06, 0x0a, 0x02, 0x42, 0x42, 0x10, 0x14, 0x12, 0x06, 0x0a, + 0x02, 0x42, 0x59, 0x10, 0x15, 0x12, 0x06, 0x0a, 0x02, 0x42, 0x45, 0x10, 0x16, 0x12, 0x06, 0x0a, + 0x02, 0x42, 0x5a, 0x10, 0x17, 0x12, 0x06, 0x0a, 0x02, 0x42, 0x4a, 0x10, 0x18, 0x12, 0x06, 0x0a, + 0x02, 0x42, 0x4d, 0x10, 0x19, 0x12, 0x06, 0x0a, 0x02, 0x42, 0x54, 0x10, 0x1a, 0x12, 0x06, 0x0a, + 0x02, 0x42, 0x4f, 0x10, 0x1b, 0x12, 0x06, 0x0a, 0x02, 0x42, 0x51, 0x10, 0x1c, 0x12, 0x06, 0x0a, + 0x02, 0x42, 0x41, 0x10, 0x1d, 0x12, 0x06, 0x0a, 0x02, 0x42, 0x57, 0x10, 0x1e, 0x12, 0x06, 0x0a, + 0x02, 0x42, 0x56, 0x10, 0x1f, 0x12, 0x06, 0x0a, 0x02, 0x42, 0x52, 0x10, 0x20, 0x12, 0x06, 0x0a, + 0x02, 0x49, 0x4f, 0x10, 0x21, 0x12, 0x06, 0x0a, 0x02, 0x42, 0x4e, 0x10, 0x22, 0x12, 0x06, 0x0a, + 0x02, 0x42, 0x47, 0x10, 0x23, 0x12, 0x06, 0x0a, 0x02, 0x42, 0x46, 0x10, 0x24, 0x12, 0x06, 0x0a, + 0x02, 0x42, 0x49, 0x10, 0x25, 0x12, 0x06, 0x0a, 0x02, 0x4b, 0x48, 0x10, 0x26, 0x12, 0x06, 0x0a, + 0x02, 0x43, 0x4d, 0x10, 0x27, 0x12, 0x06, 0x0a, 0x02, 0x43, 0x41, 0x10, 0x28, 0x12, 0x06, 0x0a, + 0x02, 0x43, 0x56, 0x10, 0x29, 0x12, 0x06, 0x0a, 0x02, 0x4b, 0x59, 0x10, 0x2a, 0x12, 0x06, 0x0a, + 0x02, 0x43, 0x46, 0x10, 0x2b, 0x12, 0x06, 0x0a, 0x02, 0x54, 0x44, 0x10, 0x2c, 0x12, 0x06, 0x0a, + 0x02, 0x43, 0x4c, 0x10, 0x2d, 0x12, 0x06, 0x0a, 0x02, 0x43, 0x4e, 0x10, 0x2e, 0x12, 0x06, 0x0a, + 0x02, 0x43, 0x58, 0x10, 0x2f, 0x12, 0x06, 0x0a, 0x02, 0x43, 0x43, 0x10, 0x30, 0x12, 0x06, 0x0a, + 0x02, 0x43, 0x4f, 0x10, 0x31, 0x12, 0x06, 0x0a, 0x02, 0x4b, 0x4d, 0x10, 0x32, 0x12, 0x06, 0x0a, + 0x02, 0x43, 0x47, 0x10, 0x33, 0x12, 0x06, 0x0a, 0x02, 0x43, 0x44, 0x10, 0x34, 0x12, 0x06, 0x0a, + 0x02, 0x43, 0x4b, 0x10, 0x35, 0x12, 0x06, 0x0a, 0x02, 0x43, 0x52, 0x10, 0x36, 0x12, 0x06, 0x0a, + 0x02, 0x43, 0x49, 0x10, 0x37, 0x12, 0x06, 0x0a, 0x02, 0x48, 0x52, 0x10, 0x38, 0x12, 0x06, 0x0a, + 0x02, 0x43, 0x55, 0x10, 0x39, 0x12, 0x06, 0x0a, 0x02, 0x43, 0x57, 0x10, 0x3a, 0x12, 0x06, 0x0a, + 0x02, 0x43, 0x59, 0x10, 0x3b, 0x12, 0x06, 0x0a, 0x02, 0x43, 0x5a, 0x10, 0x3c, 0x12, 0x06, 0x0a, + 0x02, 0x44, 0x4b, 0x10, 0x3d, 0x12, 0x06, 0x0a, 0x02, 0x44, 0x4a, 0x10, 0x3e, 0x12, 0x06, 0x0a, + 0x02, 0x44, 0x4d, 0x10, 0x3f, 0x12, 0x06, 0x0a, 0x02, 0x44, 0x4f, 0x10, 0x40, 0x12, 0x06, 0x0a, + 0x02, 0x45, 0x43, 0x10, 0x41, 0x12, 0x06, 0x0a, 0x02, 0x45, 0x47, 0x10, 0x42, 0x12, 0x06, 0x0a, + 0x02, 0x53, 0x56, 0x10, 0x43, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x51, 0x10, 0x44, 0x12, 0x06, 0x0a, + 0x02, 0x45, 0x52, 0x10, 0x45, 0x12, 0x06, 0x0a, 0x02, 0x45, 0x45, 0x10, 0x46, 0x12, 0x06, 0x0a, + 0x02, 0x45, 0x54, 0x10, 0x47, 0x12, 0x06, 0x0a, 0x02, 0x46, 0x4b, 0x10, 0x48, 0x12, 0x06, 0x0a, + 0x02, 0x46, 0x4f, 0x10, 0x49, 0x12, 0x06, 0x0a, 0x02, 0x46, 0x4a, 0x10, 0x4a, 0x12, 0x06, 0x0a, + 0x02, 0x46, 0x49, 0x10, 0x4b, 0x12, 0x06, 0x0a, 0x02, 0x46, 0x52, 0x10, 0x4c, 0x12, 0x06, 0x0a, + 0x02, 0x47, 0x46, 0x10, 0x4d, 0x12, 0x06, 0x0a, 0x02, 0x50, 0x46, 0x10, 0x4e, 0x12, 0x06, 0x0a, + 0x02, 0x54, 0x46, 0x10, 0x4f, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x41, 0x10, 0x50, 0x12, 0x06, 0x0a, + 0x02, 0x47, 0x4d, 0x10, 0x51, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x45, 0x10, 0x52, 0x12, 0x06, 0x0a, + 0x02, 0x44, 0x45, 0x10, 0x53, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x48, 0x10, 0x54, 0x12, 0x06, 0x0a, + 0x02, 0x47, 0x49, 0x10, 0x55, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x52, 0x10, 0x56, 0x12, 0x06, 0x0a, + 0x02, 0x47, 0x4c, 0x10, 0x57, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x44, 0x10, 0x58, 0x12, 0x06, 0x0a, + 0x02, 0x47, 0x50, 0x10, 0x59, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x55, 0x10, 0x5a, 0x12, 0x06, 0x0a, + 0x02, 0x47, 0x54, 0x10, 0x5b, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x47, 0x10, 0x5c, 0x12, 0x06, 0x0a, + 0x02, 0x47, 0x4e, 0x10, 0x5d, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x57, 0x10, 0x5e, 0x12, 0x06, 0x0a, + 0x02, 0x47, 0x59, 0x10, 0x5f, 0x12, 0x06, 0x0a, 0x02, 0x48, 0x54, 0x10, 0x60, 0x12, 0x06, 0x0a, + 0x02, 0x48, 0x4d, 0x10, 0x61, 0x12, 0x06, 0x0a, 0x02, 0x56, 0x41, 0x10, 0x62, 0x12, 0x06, 0x0a, + 0x02, 0x48, 0x4e, 0x10, 0x63, 0x12, 0x06, 0x0a, 0x02, 0x48, 0x4b, 0x10, 0x64, 0x12, 0x06, 0x0a, + 0x02, 0x48, 0x55, 0x10, 0x65, 0x12, 0x06, 0x0a, 0x02, 0x49, 0x53, 0x10, 0x66, 0x12, 0x06, 0x0a, + 0x02, 0x49, 0x4e, 0x10, 0x67, 0x12, 0x06, 0x0a, 0x02, 0x49, 0x44, 0x10, 0x68, 0x12, 0x06, 0x0a, + 0x02, 0x49, 0x52, 0x10, 0x69, 0x12, 0x06, 0x0a, 0x02, 0x49, 0x51, 0x10, 0x6a, 0x12, 0x06, 0x0a, + 0x02, 0x49, 0x45, 0x10, 0x6b, 0x12, 0x06, 0x0a, 0x02, 0x49, 0x4d, 0x10, 0x6c, 0x12, 0x06, 0x0a, + 0x02, 0x49, 0x4c, 0x10, 0x6d, 0x12, 0x06, 0x0a, 0x02, 0x49, 0x54, 0x10, 0x6e, 0x12, 0x06, 0x0a, + 0x02, 0x4a, 0x4d, 0x10, 0x6f, 0x12, 0x06, 0x0a, 0x02, 0x4a, 0x50, 0x10, 0x70, 0x12, 0x06, 0x0a, + 0x02, 0x4a, 0x45, 0x10, 0x71, 0x12, 0x06, 0x0a, 0x02, 0x4a, 0x4f, 0x10, 0x72, 0x12, 0x06, 0x0a, + 0x02, 0x4b, 0x5a, 0x10, 0x73, 0x12, 0x06, 0x0a, 0x02, 0x4b, 0x45, 0x10, 0x74, 0x12, 0x06, 0x0a, + 0x02, 0x4b, 0x49, 0x10, 0x75, 0x12, 0x06, 0x0a, 0x02, 0x4b, 0x50, 0x10, 0x76, 0x12, 0x06, 0x0a, + 0x02, 0x4b, 0x52, 0x10, 0x77, 0x12, 0x06, 0x0a, 0x02, 0x4b, 0x57, 0x10, 0x78, 0x12, 0x06, 0x0a, + 0x02, 0x4b, 0x47, 0x10, 0x79, 0x12, 0x06, 0x0a, 0x02, 0x4c, 0x41, 0x10, 0x7a, 0x12, 0x06, 0x0a, + 0x02, 0x4c, 0x56, 0x10, 0x7b, 0x12, 0x06, 0x0a, 0x02, 0x4c, 0x42, 0x10, 0x7c, 0x12, 0x06, 0x0a, + 0x02, 0x4c, 0x53, 0x10, 0x7d, 0x12, 0x06, 0x0a, 0x02, 0x4c, 0x52, 0x10, 0x7e, 0x12, 0x06, 0x0a, + 0x02, 0x4c, 0x59, 0x10, 0x7f, 0x12, 0x07, 0x0a, 0x02, 0x4c, 0x49, 0x10, 0x80, 0x01, 0x12, 0x07, + 0x0a, 0x02, 0x4c, 0x54, 0x10, 0x81, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4c, 0x55, 0x10, 0x82, 0x01, + 0x12, 0x07, 0x0a, 0x02, 0x4d, 0x4f, 0x10, 0x83, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4d, 0x4b, 0x10, + 0x84, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4d, 0x47, 0x10, 0x85, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4d, + 0x57, 0x10, 0x86, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4d, 0x59, 0x10, 0x87, 0x01, 0x12, 0x07, 0x0a, + 0x02, 0x4d, 0x56, 0x10, 0x88, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4d, 0x4c, 0x10, 0x89, 0x01, 0x12, + 0x07, 0x0a, 0x02, 0x4d, 0x54, 0x10, 0x8a, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4d, 0x48, 0x10, 0x8b, + 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4d, 0x51, 0x10, 0x8c, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4d, 0x52, + 0x10, 0x8d, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4d, 0x55, 0x10, 0x8e, 0x01, 0x12, 0x07, 0x0a, 0x02, + 0x59, 0x54, 0x10, 0x8f, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4d, 0x58, 0x10, 0x90, 0x01, 0x12, 0x07, + 0x0a, 0x02, 0x46, 0x4d, 0x10, 0x91, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4d, 0x44, 0x10, 0x92, 0x01, + 0x12, 0x07, 0x0a, 0x02, 0x4d, 0x43, 0x10, 0x93, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4d, 0x4e, 0x10, + 0x94, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4d, 0x45, 0x10, 0x95, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4d, + 0x53, 0x10, 0x96, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4d, 0x41, 0x10, 0x97, 0x01, 0x12, 0x07, 0x0a, + 0x02, 0x4d, 0x5a, 0x10, 0x98, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4d, 0x4d, 0x10, 0x99, 0x01, 0x12, + 0x07, 0x0a, 0x02, 0x4e, 0x41, 0x10, 0x9a, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4e, 0x52, 0x10, 0x9b, + 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4e, 0x50, 0x10, 0x9c, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4e, 0x4c, + 0x10, 0x9d, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4e, 0x43, 0x10, 0x9e, 0x01, 0x12, 0x07, 0x0a, 0x02, + 0x4e, 0x5a, 0x10, 0x9f, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4e, 0x49, 0x10, 0xa0, 0x01, 0x12, 0x07, + 0x0a, 0x02, 0x4e, 0x45, 0x10, 0xa1, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4e, 0x47, 0x10, 0xa2, 0x01, + 0x12, 0x07, 0x0a, 0x02, 0x4e, 0x55, 0x10, 0xa3, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4e, 0x46, 0x10, + 0xa4, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4d, 0x50, 0x10, 0xa5, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4e, + 0x4f, 0x10, 0xa6, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4f, 0x4d, 0x10, 0xa7, 0x01, 0x12, 0x07, 0x0a, + 0x02, 0x50, 0x4b, 0x10, 0xa8, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x50, 0x57, 0x10, 0xa9, 0x01, 0x12, + 0x07, 0x0a, 0x02, 0x50, 0x53, 0x10, 0xaa, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x50, 0x41, 0x10, 0xab, + 0x01, 0x12, 0x07, 0x0a, 0x02, 0x50, 0x47, 0x10, 0xac, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x50, 0x59, + 0x10, 0xad, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x50, 0x45, 0x10, 0xae, 0x01, 0x12, 0x07, 0x0a, 0x02, + 0x50, 0x48, 0x10, 0xaf, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x50, 0x4e, 0x10, 0xb0, 0x01, 0x12, 0x07, + 0x0a, 0x02, 0x50, 0x4c, 0x10, 0xb1, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x50, 0x54, 0x10, 0xb2, 0x01, + 0x12, 0x07, 0x0a, 0x02, 0x50, 0x52, 0x10, 0xb3, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x51, 0x41, 0x10, + 0xb4, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x52, 0x45, 0x10, 0xb5, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x52, + 0x4f, 0x10, 0xb6, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x52, 0x55, 0x10, 0xb7, 0x01, 0x12, 0x07, 0x0a, + 0x02, 0x52, 0x57, 0x10, 0xb8, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x42, 0x4c, 0x10, 0xb9, 0x01, 0x12, + 0x07, 0x0a, 0x02, 0x53, 0x48, 0x10, 0xba, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4b, 0x4e, 0x10, 0xbb, + 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4c, 0x43, 0x10, 0xbc, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4d, 0x46, + 0x10, 0xbd, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x50, 0x4d, 0x10, 0xbe, 0x01, 0x12, 0x07, 0x0a, 0x02, + 0x56, 0x43, 0x10, 0xbf, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x57, 0x53, 0x10, 0xc0, 0x01, 0x12, 0x07, + 0x0a, 0x02, 0x53, 0x4d, 0x10, 0xc1, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x53, 0x54, 0x10, 0xc2, 0x01, + 0x12, 0x07, 0x0a, 0x02, 0x53, 0x41, 0x10, 0xc3, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x53, 0x4e, 0x10, + 0xc4, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x52, 0x53, 0x10, 0xc5, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x53, + 0x43, 0x10, 0xc6, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x53, 0x4c, 0x10, 0xc7, 0x01, 0x12, 0x07, 0x0a, + 0x02, 0x53, 0x47, 0x10, 0xc8, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x53, 0x58, 0x10, 0xc9, 0x01, 0x12, + 0x07, 0x0a, 0x02, 0x53, 0x4b, 0x10, 0xca, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x53, 0x49, 0x10, 0xcb, + 0x01, 0x12, 0x07, 0x0a, 0x02, 0x53, 0x42, 0x10, 0xcc, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x53, 0x4f, + 0x10, 0xcd, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x5a, 0x41, 0x10, 0xce, 0x01, 0x12, 0x07, 0x0a, 0x02, + 0x47, 0x53, 0x10, 0xcf, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x53, 0x53, 0x10, 0xd0, 0x01, 0x12, 0x07, + 0x0a, 0x02, 0x45, 0x53, 0x10, 0xd1, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x4c, 0x4b, 0x10, 0xd2, 0x01, + 0x12, 0x07, 0x0a, 0x02, 0x53, 0x44, 0x10, 0xd3, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x53, 0x52, 0x10, + 0xd4, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x53, 0x4a, 0x10, 0xd5, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x53, + 0x5a, 0x10, 0xd6, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x53, 0x45, 0x10, 0xd7, 0x01, 0x12, 0x07, 0x0a, + 0x02, 0x43, 0x48, 0x10, 0xd8, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x53, 0x59, 0x10, 0xd9, 0x01, 0x12, + 0x07, 0x0a, 0x02, 0x54, 0x57, 0x10, 0xda, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x54, 0x4a, 0x10, 0xdb, + 0x01, 0x12, 0x07, 0x0a, 0x02, 0x54, 0x5a, 0x10, 0xdc, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x54, 0x48, + 0x10, 0xdd, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x54, 0x4c, 0x10, 0xde, 0x01, 0x12, 0x07, 0x0a, 0x02, + 0x54, 0x47, 0x10, 0xdf, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x54, 0x4b, 0x10, 0xe0, 0x01, 0x12, 0x07, + 0x0a, 0x02, 0x54, 0x4f, 0x10, 0xe1, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x54, 0x54, 0x10, 0xe2, 0x01, + 0x12, 0x07, 0x0a, 0x02, 0x54, 0x4e, 0x10, 0xe3, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x54, 0x52, 0x10, + 0xe4, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x54, 0x4d, 0x10, 0xe5, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x54, + 0x43, 0x10, 0xe6, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x54, 0x56, 0x10, 0xe7, 0x01, 0x12, 0x07, 0x0a, + 0x02, 0x55, 0x47, 0x10, 0xe8, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x55, 0x41, 0x10, 0xe9, 0x01, 0x12, + 0x07, 0x0a, 0x02, 0x41, 0x45, 0x10, 0xea, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x47, 0x42, 0x10, 0xeb, + 0x01, 0x12, 0x07, 0x0a, 0x02, 0x55, 0x53, 0x10, 0xec, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x55, 0x4d, + 0x10, 0xed, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x55, 0x59, 0x10, 0xee, 0x01, 0x12, 0x07, 0x0a, 0x02, + 0x55, 0x5a, 0x10, 0xef, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x56, 0x55, 0x10, 0xf0, 0x01, 0x12, 0x07, + 0x0a, 0x02, 0x56, 0x45, 0x10, 0xf1, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x56, 0x4e, 0x10, 0xf2, 0x01, + 0x12, 0x07, 0x0a, 0x02, 0x56, 0x47, 0x10, 0xf3, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x56, 0x49, 0x10, + 0xf4, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x57, 0x46, 0x10, 0xf5, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x45, + 0x48, 0x10, 0xf6, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x59, 0x45, 0x10, 0xf7, 0x01, 0x12, 0x07, 0x0a, + 0x02, 0x5a, 0x4d, 0x10, 0xf8, 0x01, 0x12, 0x07, 0x0a, 0x02, 0x5a, 0x57, 0x10, 0xf9, 0x01, 0x12, + 0x09, 0x0a, 0x04, 0x52, 0x30, 0x30, 0x31, 0x10, 0xfa, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, + 0x30, 0x32, 0x10, 0xfb, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x31, 0x35, 0x10, 0xfc, 0x01, + 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x31, 0x32, 0x10, 0xfd, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x52, + 0x38, 0x31, 0x38, 0x10, 0xfe, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x33, 0x34, 0x10, 0xff, + 0x01, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x35, 0x30, 0x34, 0x10, 0x80, 0x02, 0x12, 0x09, 0x0a, 0x04, + 0x52, 0x37, 0x32, 0x39, 0x10, 0x81, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, 0x38, 0x38, 0x10, + 0x82, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, 0x33, 0x32, 0x10, 0x83, 0x02, 0x12, 0x09, 0x0a, + 0x04, 0x52, 0x32, 0x30, 0x32, 0x10, 0x84, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x31, 0x34, + 0x10, 0x85, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x38, 0x36, 0x10, 0x86, 0x02, 0x12, 0x09, + 0x0a, 0x04, 0x52, 0x31, 0x30, 0x38, 0x10, 0x87, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x37, + 0x34, 0x10, 0x88, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x32, 0x36, 0x32, 0x10, 0x89, 0x02, 0x12, + 0x09, 0x0a, 0x04, 0x52, 0x32, 0x33, 0x32, 0x10, 0x8a, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x32, + 0x33, 0x31, 0x10, 0x8b, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x32, 0x36, 0x30, 0x10, 0x8c, 0x02, + 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x30, 0x34, 0x10, 0x8d, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, + 0x34, 0x35, 0x30, 0x10, 0x8e, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x35, 0x34, 0x10, 0x8f, + 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x38, 0x30, 0x10, 0x90, 0x02, 0x12, 0x09, 0x0a, 0x04, + 0x52, 0x31, 0x37, 0x35, 0x10, 0x91, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x35, 0x30, 0x38, 0x10, + 0x92, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x36, 0x33, 0x38, 0x10, 0x93, 0x02, 0x12, 0x09, 0x0a, + 0x04, 0x52, 0x36, 0x34, 0x36, 0x10, 0x94, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x36, 0x39, 0x30, + 0x10, 0x95, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, 0x30, 0x36, 0x10, 0x96, 0x02, 0x12, 0x09, + 0x0a, 0x04, 0x52, 0x37, 0x32, 0x38, 0x10, 0x97, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x38, 0x30, + 0x30, 0x10, 0x98, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x38, 0x33, 0x34, 0x10, 0x99, 0x02, 0x12, + 0x09, 0x0a, 0x04, 0x52, 0x38, 0x39, 0x34, 0x10, 0x9a, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, + 0x31, 0x36, 0x10, 0x9b, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x31, 0x37, 0x10, 0x9c, 0x02, + 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x32, 0x34, 0x10, 0x9d, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, + 0x31, 0x32, 0x30, 0x10, 0x9e, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x34, 0x30, 0x10, 0x9f, + 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x34, 0x38, 0x10, 0xa0, 0x02, 0x12, 0x09, 0x0a, 0x04, + 0x52, 0x31, 0x37, 0x38, 0x10, 0xa1, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x38, 0x30, 0x10, + 0xa2, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x32, 0x32, 0x36, 0x10, 0xa3, 0x02, 0x12, 0x09, 0x0a, + 0x04, 0x52, 0x32, 0x36, 0x36, 0x10, 0xa4, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x36, 0x37, 0x38, + 0x10, 0xa5, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x31, 0x38, 0x10, 0xa6, 0x02, 0x12, 0x09, + 0x0a, 0x04, 0x52, 0x30, 0x37, 0x32, 0x10, 0xa7, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, 0x34, + 0x38, 0x10, 0xa8, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x32, 0x36, 0x10, 0xa9, 0x02, 0x12, + 0x09, 0x0a, 0x04, 0x52, 0x35, 0x31, 0x36, 0x10, 0xaa, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, + 0x31, 0x30, 0x10, 0xab, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x31, 0x31, 0x10, 0xac, 0x02, + 0x12, 0x09, 0x0a, 0x04, 0x52, 0x32, 0x30, 0x34, 0x10, 0xad, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, + 0x38, 0x35, 0x34, 0x10, 0xae, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x33, 0x32, 0x10, 0xaf, + 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x33, 0x38, 0x34, 0x10, 0xb0, 0x02, 0x12, 0x09, 0x0a, 0x04, + 0x52, 0x32, 0x37, 0x30, 0x10, 0xb1, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x32, 0x38, 0x38, 0x10, + 0xb2, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x33, 0x32, 0x34, 0x10, 0xb3, 0x02, 0x12, 0x09, 0x0a, + 0x04, 0x52, 0x36, 0x32, 0x34, 0x10, 0xb4, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x33, 0x30, + 0x10, 0xb5, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x36, 0x36, 0x10, 0xb6, 0x02, 0x12, 0x09, + 0x0a, 0x04, 0x52, 0x34, 0x37, 0x38, 0x10, 0xb7, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x35, 0x36, + 0x32, 0x10, 0xb8, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x35, 0x36, 0x36, 0x10, 0xb9, 0x02, 0x12, + 0x09, 0x0a, 0x04, 0x52, 0x36, 0x35, 0x34, 0x10, 0xba, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x36, + 0x38, 0x36, 0x10, 0xbb, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x36, 0x39, 0x34, 0x10, 0xbc, 0x02, + 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, 0x36, 0x38, 0x10, 0xbd, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, + 0x30, 0x31, 0x39, 0x10, 0xbe, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x31, 0x39, 0x10, 0xbf, + 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x32, 0x39, 0x10, 0xc0, 0x02, 0x12, 0x09, 0x0a, 0x04, + 0x52, 0x36, 0x36, 0x30, 0x10, 0xc1, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x32, 0x38, 0x10, + 0xc2, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x35, 0x33, 0x33, 0x10, 0xc3, 0x02, 0x12, 0x09, 0x0a, + 0x04, 0x52, 0x30, 0x34, 0x34, 0x10, 0xc4, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x35, 0x32, + 0x10, 0xc5, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x35, 0x33, 0x35, 0x10, 0xc6, 0x02, 0x12, 0x09, + 0x0a, 0x04, 0x52, 0x30, 0x39, 0x32, 0x10, 0xc7, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x33, + 0x36, 0x10, 0xc8, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x39, 0x32, 0x10, 0xc9, 0x02, 0x12, + 0x09, 0x0a, 0x04, 0x52, 0x35, 0x33, 0x31, 0x10, 0xca, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x32, + 0x31, 0x32, 0x10, 0xcb, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x32, 0x31, 0x34, 0x10, 0xcc, 0x02, + 0x12, 0x09, 0x0a, 0x04, 0x52, 0x33, 0x30, 0x38, 0x10, 0xcd, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, + 0x33, 0x31, 0x32, 0x10, 0xce, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x33, 0x33, 0x32, 0x10, 0xcf, + 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x33, 0x38, 0x38, 0x10, 0xd0, 0x02, 0x12, 0x09, 0x0a, 0x04, + 0x52, 0x34, 0x37, 0x34, 0x10, 0xd1, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x35, 0x30, 0x30, 0x10, + 0xd2, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x36, 0x33, 0x30, 0x10, 0xd3, 0x02, 0x12, 0x09, 0x0a, + 0x04, 0x52, 0x36, 0x35, 0x32, 0x10, 0xd4, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x36, 0x35, 0x39, + 0x10, 0xd5, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x36, 0x36, 0x32, 0x10, 0xd6, 0x02, 0x12, 0x09, + 0x0a, 0x04, 0x52, 0x36, 0x36, 0x33, 0x10, 0xd7, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x36, 0x37, + 0x30, 0x10, 0xd8, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x35, 0x33, 0x34, 0x10, 0xd9, 0x02, 0x12, + 0x09, 0x0a, 0x04, 0x52, 0x37, 0x38, 0x30, 0x10, 0xda, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, + 0x39, 0x36, 0x10, 0xdb, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x38, 0x35, 0x30, 0x10, 0xdc, 0x02, + 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x31, 0x33, 0x10, 0xdd, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, + 0x30, 0x38, 0x34, 0x10, 0xde, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x38, 0x38, 0x10, 0xdf, + 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x32, 0x32, 0x32, 0x10, 0xe0, 0x02, 0x12, 0x09, 0x0a, 0x04, + 0x52, 0x33, 0x32, 0x30, 0x10, 0xe1, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x33, 0x34, 0x30, 0x10, + 0xe2, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x38, 0x34, 0x10, 0xe3, 0x02, 0x12, 0x09, 0x0a, + 0x04, 0x52, 0x35, 0x35, 0x38, 0x10, 0xe4, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x35, 0x39, 0x31, + 0x10, 0xe5, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x30, 0x35, 0x10, 0xe6, 0x02, 0x12, 0x09, + 0x0a, 0x04, 0x52, 0x30, 0x33, 0x32, 0x10, 0xe7, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x36, + 0x38, 0x10, 0xe8, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x37, 0x34, 0x10, 0xe9, 0x02, 0x12, + 0x09, 0x0a, 0x04, 0x52, 0x30, 0x37, 0x36, 0x10, 0xea, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, + 0x35, 0x32, 0x10, 0xeb, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x37, 0x30, 0x10, 0xec, 0x02, + 0x12, 0x09, 0x0a, 0x04, 0x52, 0x32, 0x31, 0x38, 0x10, 0xed, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, + 0x32, 0x33, 0x38, 0x10, 0xee, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x32, 0x35, 0x34, 0x10, 0xef, + 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x33, 0x32, 0x38, 0x10, 0xf0, 0x02, 0x12, 0x09, 0x0a, 0x04, + 0x52, 0x36, 0x30, 0x30, 0x10, 0xf1, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x36, 0x30, 0x34, 0x10, + 0xf2, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x32, 0x33, 0x39, 0x10, 0xf3, 0x02, 0x12, 0x09, 0x0a, + 0x04, 0x52, 0x37, 0x34, 0x30, 0x10, 0xf4, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x38, 0x35, 0x38, + 0x10, 0xf5, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x38, 0x36, 0x32, 0x10, 0xf6, 0x02, 0x12, 0x09, + 0x0a, 0x04, 0x52, 0x30, 0x32, 0x31, 0x10, 0xf7, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x36, + 0x30, 0x10, 0xf8, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x32, 0x34, 0x10, 0xf9, 0x02, 0x12, + 0x09, 0x0a, 0x04, 0x52, 0x33, 0x30, 0x34, 0x10, 0xfa, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x36, + 0x36, 0x36, 0x10, 0xfb, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x38, 0x34, 0x30, 0x10, 0xfc, 0x02, + 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x31, 0x30, 0x10, 0xfd, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, + 0x31, 0x34, 0x32, 0x10, 0xfe, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x34, 0x33, 0x10, 0xff, + 0x02, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x33, 0x39, 0x38, 0x10, 0x80, 0x03, 0x12, 0x09, 0x0a, 0x04, + 0x52, 0x34, 0x31, 0x37, 0x10, 0x81, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, 0x36, 0x32, 0x10, + 0x82, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, 0x39, 0x35, 0x10, 0x83, 0x03, 0x12, 0x09, 0x0a, + 0x04, 0x52, 0x38, 0x36, 0x30, 0x10, 0x84, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x33, 0x30, + 0x10, 0x85, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x35, 0x36, 0x10, 0x86, 0x03, 0x12, 0x09, + 0x0a, 0x04, 0x52, 0x33, 0x34, 0x34, 0x10, 0x87, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x34, + 0x36, 0x10, 0x88, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x30, 0x38, 0x10, 0x89, 0x03, 0x12, + 0x09, 0x0a, 0x04, 0x52, 0x33, 0x39, 0x32, 0x10, 0x8a, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, + 0x39, 0x36, 0x10, 0x8b, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x31, 0x30, 0x10, 0x8c, 0x03, + 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x33, 0x35, 0x10, 0x8d, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, + 0x30, 0x39, 0x36, 0x10, 0x8e, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x31, 0x36, 0x10, 0x8f, + 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x33, 0x36, 0x30, 0x10, 0x90, 0x03, 0x12, 0x09, 0x0a, 0x04, + 0x52, 0x34, 0x31, 0x38, 0x10, 0x91, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x35, 0x38, 0x10, + 0x92, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x30, 0x34, 0x10, 0x93, 0x03, 0x12, 0x09, 0x0a, + 0x04, 0x52, 0x36, 0x30, 0x38, 0x10, 0x94, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, 0x30, 0x32, + 0x10, 0x95, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, 0x36, 0x34, 0x10, 0x96, 0x03, 0x12, 0x09, + 0x0a, 0x04, 0x52, 0x36, 0x32, 0x36, 0x10, 0x97, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, 0x30, + 0x34, 0x10, 0x98, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x33, 0x34, 0x10, 0x99, 0x03, 0x12, + 0x09, 0x0a, 0x04, 0x52, 0x30, 0x30, 0x34, 0x10, 0x9a, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, + 0x35, 0x30, 0x10, 0x9b, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x36, 0x34, 0x10, 0x9c, 0x03, + 0x12, 0x09, 0x0a, 0x04, 0x52, 0x33, 0x35, 0x36, 0x10, 0x9d, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, + 0x33, 0x36, 0x34, 0x10, 0x9e, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x36, 0x32, 0x10, 0x9f, + 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x35, 0x32, 0x34, 0x10, 0xa0, 0x03, 0x12, 0x09, 0x0a, 0x04, + 0x52, 0x35, 0x38, 0x36, 0x10, 0xa1, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x34, 0x34, 0x10, + 0xa2, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x34, 0x35, 0x10, 0xa3, 0x03, 0x12, 0x09, 0x0a, + 0x04, 0x52, 0x30, 0x35, 0x31, 0x10, 0xa4, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x33, 0x31, + 0x10, 0xa5, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x34, 0x38, 0x10, 0xa6, 0x03, 0x12, 0x09, + 0x0a, 0x04, 0x52, 0x31, 0x39, 0x36, 0x10, 0xa7, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x32, 0x36, + 0x38, 0x10, 0xa8, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x33, 0x36, 0x38, 0x10, 0xa9, 0x03, 0x12, + 0x09, 0x0a, 0x04, 0x52, 0x33, 0x37, 0x36, 0x10, 0xaa, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, + 0x30, 0x30, 0x10, 0xab, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x31, 0x34, 0x10, 0xac, 0x03, + 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x32, 0x32, 0x10, 0xad, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, + 0x35, 0x31, 0x32, 0x10, 0xae, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x36, 0x33, 0x34, 0x10, 0xaf, + 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x36, 0x38, 0x32, 0x10, 0xb0, 0x03, 0x12, 0x09, 0x0a, 0x04, + 0x52, 0x32, 0x37, 0x35, 0x10, 0xb1, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, 0x36, 0x30, 0x10, + 0xb2, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, 0x39, 0x32, 0x10, 0xb3, 0x03, 0x12, 0x09, 0x0a, + 0x04, 0x52, 0x37, 0x38, 0x34, 0x10, 0xb4, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x38, 0x38, 0x37, + 0x10, 0xb5, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x35, 0x30, 0x10, 0xb6, 0x03, 0x12, 0x09, + 0x0a, 0x04, 0x52, 0x31, 0x35, 0x31, 0x10, 0xb7, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x31, + 0x32, 0x10, 0xb8, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x30, 0x30, 0x10, 0xb9, 0x03, 0x12, + 0x09, 0x0a, 0x04, 0x52, 0x32, 0x30, 0x33, 0x10, 0xba, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x33, + 0x34, 0x38, 0x10, 0xbb, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x36, 0x31, 0x36, 0x10, 0xbc, 0x03, + 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x39, 0x38, 0x10, 0xbd, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, + 0x36, 0x34, 0x32, 0x10, 0xbe, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x36, 0x34, 0x33, 0x10, 0xbf, + 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, 0x30, 0x33, 0x10, 0xc0, 0x03, 0x12, 0x09, 0x0a, 0x04, + 0x52, 0x38, 0x30, 0x34, 0x10, 0xc1, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x35, 0x34, 0x10, + 0xc2, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x32, 0x34, 0x38, 0x10, 0xc3, 0x03, 0x12, 0x09, 0x0a, + 0x04, 0x52, 0x38, 0x33, 0x30, 0x10, 0xc4, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x38, 0x33, 0x31, + 0x10, 0xc5, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x38, 0x33, 0x32, 0x10, 0xc6, 0x03, 0x12, 0x09, + 0x0a, 0x04, 0x52, 0x36, 0x38, 0x30, 0x10, 0xc7, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x32, 0x30, + 0x38, 0x10, 0xc8, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x32, 0x33, 0x33, 0x10, 0xc9, 0x03, 0x12, + 0x09, 0x0a, 0x04, 0x52, 0x32, 0x33, 0x34, 0x10, 0xca, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x32, + 0x34, 0x36, 0x10, 0xcb, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x33, 0x35, 0x32, 0x10, 0xcc, 0x03, + 0x12, 0x09, 0x0a, 0x04, 0x52, 0x33, 0x37, 0x32, 0x10, 0xcd, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, + 0x38, 0x33, 0x33, 0x10, 0xce, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x32, 0x38, 0x10, 0xcf, + 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x34, 0x30, 0x10, 0xd0, 0x03, 0x12, 0x09, 0x0a, 0x04, + 0x52, 0x35, 0x37, 0x38, 0x10, 0xd1, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, 0x34, 0x34, 0x10, + 0xd2, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, 0x35, 0x32, 0x10, 0xd3, 0x03, 0x12, 0x09, 0x0a, + 0x04, 0x52, 0x38, 0x32, 0x36, 0x10, 0xd4, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x33, 0x39, + 0x10, 0xd5, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x30, 0x38, 0x10, 0xd6, 0x03, 0x12, 0x09, + 0x0a, 0x04, 0x52, 0x30, 0x32, 0x30, 0x10, 0xd7, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x37, + 0x30, 0x10, 0xd8, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x39, 0x31, 0x10, 0xd9, 0x03, 0x12, + 0x09, 0x0a, 0x04, 0x52, 0x32, 0x39, 0x32, 0x10, 0xda, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x33, + 0x30, 0x30, 0x10, 0xdb, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x33, 0x33, 0x36, 0x10, 0xdc, 0x03, + 0x12, 0x09, 0x0a, 0x04, 0x52, 0x33, 0x38, 0x30, 0x10, 0xdd, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, + 0x34, 0x37, 0x30, 0x10, 0xde, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x39, 0x39, 0x10, 0xdf, + 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x38, 0x30, 0x37, 0x10, 0xe0, 0x03, 0x12, 0x09, 0x0a, 0x04, + 0x52, 0x36, 0x32, 0x30, 0x10, 0xe1, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x36, 0x37, 0x34, 0x10, + 0xe2, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x36, 0x38, 0x38, 0x10, 0xe3, 0x03, 0x12, 0x09, 0x0a, + 0x04, 0x52, 0x37, 0x30, 0x35, 0x10, 0xe4, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, 0x32, 0x34, + 0x10, 0xe5, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x35, 0x35, 0x10, 0xe6, 0x03, 0x12, 0x09, + 0x0a, 0x04, 0x52, 0x30, 0x34, 0x30, 0x10, 0xe7, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x35, + 0x36, 0x10, 0xe8, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x32, 0x35, 0x30, 0x10, 0xe9, 0x03, 0x12, + 0x09, 0x0a, 0x04, 0x52, 0x32, 0x37, 0x36, 0x10, 0xea, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, + 0x33, 0x38, 0x10, 0xeb, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x34, 0x32, 0x10, 0xec, 0x03, + 0x12, 0x09, 0x0a, 0x04, 0x52, 0x34, 0x39, 0x32, 0x10, 0xed, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, + 0x35, 0x32, 0x38, 0x10, 0xee, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, 0x35, 0x36, 0x10, 0xef, + 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x30, 0x39, 0x10, 0xf0, 0x03, 0x12, 0x09, 0x0a, 0x04, + 0x52, 0x30, 0x35, 0x33, 0x10, 0xf1, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x33, 0x36, 0x10, + 0xf2, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x36, 0x32, 0x10, 0xf3, 0x03, 0x12, 0x09, 0x0a, + 0x04, 0x52, 0x31, 0x36, 0x36, 0x10, 0xf4, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x33, 0x33, 0x34, + 0x10, 0xf5, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x35, 0x35, 0x34, 0x10, 0xf6, 0x03, 0x12, 0x09, + 0x0a, 0x04, 0x52, 0x35, 0x37, 0x34, 0x10, 0xf7, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x35, + 0x34, 0x10, 0xf8, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x32, 0x34, 0x32, 0x10, 0xf9, 0x03, 0x12, + 0x09, 0x0a, 0x04, 0x52, 0x35, 0x34, 0x30, 0x10, 0xfa, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x35, + 0x39, 0x38, 0x10, 0xfb, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x39, 0x30, 0x10, 0xfc, 0x03, + 0x12, 0x09, 0x0a, 0x04, 0x52, 0x35, 0x34, 0x38, 0x10, 0xfd, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, + 0x30, 0x35, 0x37, 0x10, 0xfe, 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x33, 0x31, 0x36, 0x10, 0xff, + 0x03, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x32, 0x39, 0x36, 0x10, 0x80, 0x04, 0x12, 0x09, 0x0a, 0x04, + 0x52, 0x35, 0x38, 0x34, 0x10, 0x81, 0x04, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x35, 0x38, 0x33, 0x10, + 0x82, 0x04, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x35, 0x32, 0x30, 0x10, 0x83, 0x04, 0x12, 0x09, 0x0a, + 0x04, 0x52, 0x35, 0x38, 0x30, 0x10, 0x84, 0x04, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x35, 0x38, 0x35, + 0x10, 0x85, 0x04, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x35, 0x38, 0x31, 0x10, 0x86, 0x04, 0x12, 0x09, + 0x0a, 0x04, 0x52, 0x30, 0x36, 0x31, 0x10, 0x87, 0x04, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x30, 0x31, + 0x36, 0x10, 0x88, 0x04, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x31, 0x38, 0x34, 0x10, 0x89, 0x04, 0x12, + 0x09, 0x0a, 0x04, 0x52, 0x32, 0x35, 0x38, 0x10, 0x8a, 0x04, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x35, + 0x37, 0x30, 0x10, 0x8b, 0x04, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x36, 0x31, 0x32, 0x10, 0x8c, 0x04, + 0x12, 0x09, 0x0a, 0x04, 0x52, 0x38, 0x38, 0x32, 0x10, 0x8d, 0x04, 0x12, 0x09, 0x0a, 0x04, 0x52, + 0x37, 0x37, 0x32, 0x10, 0x8e, 0x04, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, 0x37, 0x36, 0x10, 0x8f, + 0x04, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x37, 0x39, 0x38, 0x10, 0x90, 0x04, 0x12, 0x09, 0x0a, 0x04, + 0x52, 0x38, 0x37, 0x36, 0x10, 0x91, 0x04, 0x42, 0x26, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x62, 0x72, 0x79, 0x69, 0x6f, 0x2f, 0x68, 0x75, 0x62, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x62, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_claim_proto_rawDescOnce sync.Once + file_claim_proto_rawDescData = file_claim_proto_rawDesc +) + +func file_claim_proto_rawDescGZIP() []byte { + file_claim_proto_rawDescOnce.Do(func() { + file_claim_proto_rawDescData = protoimpl.X.CompressGZIP(file_claim_proto_rawDescData) + }) + return file_claim_proto_rawDescData +} + +var file_claim_proto_enumTypes = make([]protoimpl.EnumInfo, 6) +var file_claim_proto_msgTypes = make([]protoimpl.MessageInfo, 13) +var file_claim_proto_goTypes = []interface{}{ + (ClaimList_ListType)(0), // 0: pb.ClaimList.ListType + (Fee_Currency)(0), // 1: pb.Fee.Currency + (Software_OS)(0), // 2: pb.Software.OS + (Language_Language)(0), // 3: pb.Language.Language + (Language_Script)(0), // 4: pb.Language.Script + (Location_Country)(0), // 5: pb.Location.Country + (*Claim)(nil), // 6: pb.Claim + (*Stream)(nil), // 7: pb.Stream + (*Channel)(nil), // 8: pb.Channel + (*ClaimReference)(nil), // 9: pb.ClaimReference + (*ClaimList)(nil), // 10: pb.ClaimList + (*Source)(nil), // 11: pb.Source + (*Fee)(nil), // 12: pb.Fee + (*Image)(nil), // 13: pb.Image + (*Video)(nil), // 14: pb.Video + (*Audio)(nil), // 15: pb.Audio + (*Software)(nil), // 16: pb.Software + (*Language)(nil), // 17: pb.Language + (*Location)(nil), // 18: pb.Location +} +var file_claim_proto_depIdxs = []int32{ + 7, // 0: pb.Claim.stream:type_name -> pb.Stream + 8, // 1: pb.Claim.channel:type_name -> pb.Channel + 10, // 2: pb.Claim.collection:type_name -> pb.ClaimList + 9, // 3: pb.Claim.repost:type_name -> pb.ClaimReference + 11, // 4: pb.Claim.thumbnail:type_name -> pb.Source + 17, // 5: pb.Claim.languages:type_name -> pb.Language + 18, // 6: pb.Claim.locations:type_name -> pb.Location + 11, // 7: pb.Stream.source:type_name -> pb.Source + 12, // 8: pb.Stream.fee:type_name -> pb.Fee + 13, // 9: pb.Stream.image:type_name -> pb.Image + 14, // 10: pb.Stream.video:type_name -> pb.Video + 15, // 11: pb.Stream.audio:type_name -> pb.Audio + 16, // 12: pb.Stream.software:type_name -> pb.Software + 11, // 13: pb.Channel.cover:type_name -> pb.Source + 10, // 14: pb.Channel.featured:type_name -> pb.ClaimList + 0, // 15: pb.ClaimList.list_type:type_name -> pb.ClaimList.ListType + 9, // 16: pb.ClaimList.claim_references:type_name -> pb.ClaimReference + 1, // 17: pb.Fee.currency:type_name -> pb.Fee.Currency + 15, // 18: pb.Video.audio:type_name -> pb.Audio + 3, // 19: pb.Language.language:type_name -> pb.Language.Language + 4, // 20: pb.Language.script:type_name -> pb.Language.Script + 5, // 21: pb.Language.region:type_name -> pb.Location.Country + 5, // 22: pb.Location.country:type_name -> pb.Location.Country + 23, // [23:23] is the sub-list for method output_type + 23, // [23:23] is the sub-list for method input_type + 23, // [23:23] is the sub-list for extension type_name + 23, // [23:23] is the sub-list for extension extendee + 0, // [0:23] is the sub-list for field type_name +} + +func init() { file_claim_proto_init() } +func file_claim_proto_init() { + if File_claim_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_claim_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Claim); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_claim_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Stream); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_claim_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Channel); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_claim_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClaimReference); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_claim_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClaimList); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_claim_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Source); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_claim_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Fee); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_claim_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Image); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_claim_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Video); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_claim_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Audio); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_claim_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Software); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_claim_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Language); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_claim_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Location); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_claim_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*Claim_Stream)(nil), + (*Claim_Channel)(nil), + (*Claim_Collection)(nil), + (*Claim_Repost)(nil), + } + file_claim_proto_msgTypes[1].OneofWrappers = []interface{}{ + (*Stream_Image)(nil), + (*Stream_Video)(nil), + (*Stream_Audio)(nil), + (*Stream_Software)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_claim_proto_rawDesc, + NumEnums: 6, + NumMessages: 13, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_claim_proto_goTypes, + DependencyIndexes: file_claim_proto_depIdxs, + EnumInfos: file_claim_proto_enumTypes, + MessageInfos: file_claim_proto_msgTypes, + }.Build() + File_claim_proto = out.File + file_claim_proto_rawDesc = nil + file_claim_proto_goTypes = nil + file_claim_proto_depIdxs = nil +} diff --git a/server/udp.go b/server/udp.go index 1240723..65eb18a 100644 --- a/server/udp.go +++ b/server/udp.go @@ -7,6 +7,7 @@ import ( "strings" "time" + pb "github.com/lbryio/hub/protobuf/go" "github.com/lbryio/lbry.go/v2/extras/errors" ) @@ -75,10 +76,13 @@ func (pong *SPVPong) Encode() []byte { } // makeSPVPong creates an SPVPong struct according to given parameters. -// FIXME: Currently, does not correctly encode the country. func makeSPVPong(flags int, height int, tip []byte, sourceAddr string, country string) *SPVPong { byteAddr := EncodeAddress(sourceAddr) - countryInt := 1 + var countryInt int32 + var ok bool + if countryInt, ok = pb.Location_Country_value[country]; !ok { + countryInt = int32(pb.Location_UNKNOWN_COUNTRY) + } return &SPVPong{ protocolVersion: protocolVersion, flags: byte(flags), From ee5fcaef147cd69ef63fd92e5e73c04d184d0172 Mon Sep 17 00:00:00 2001 From: Jeffrey Picard Date: Wed, 24 Nov 2021 16:03:42 -0500 Subject: [PATCH 04/12] Added test for getting IP with udp from prod servers. --- server/udp_test.go | 53 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 server/udp_test.go diff --git a/server/udp_test.go b/server/udp_test.go new file mode 100644 index 0000000..9cc3d9e --- /dev/null +++ b/server/udp_test.go @@ -0,0 +1,53 @@ +package server + +import ( + "log" + "os/exec" + "strings" + "testing" +) + +// TestAddPeer tests the ability to add peers +func TestUDPPing(t *testing.T) { + args := makeDefaultArgs() + args.StartUDP = false + + tests := []struct { + name string + want string + } { + { + name: "Get the right ip from production server.", + want: "SETME", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T){ + + toAddr := "spv16.lbry.com" + toPort := "50001" + + ip, err := UDPPing(toAddr, toPort) + if err != nil { + log.Println(err) + } + + res, err := exec.Command("dig", "@resolver4.opendns.com", "myip.opendns.com", "+short").Output() + + if err != nil { + log.Println(err) + } + + digIP := strings.TrimSpace(string(res)) + udpIP := ip.String() + tt.want = digIP + + got1 := udpIP + if got1 != tt.want { + t.Errorf("got: '%s', want: '%s'\n", got1, tt.want) + } + }) + } + +} From 4e6b47c2a3872fdf9fb5d29377aa3d68661c5860 Mon Sep 17 00:00:00 2001 From: Jeffrey Picard Date: Wed, 24 Nov 2021 16:19:18 -0500 Subject: [PATCH 05/12] Test UDPPing country parsing. --- server/federation.go | 2 +- server/udp.go | 21 +++++++++++++-------- server/udp_test.go | 24 +++++++++++++++--------- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/server/federation.go b/server/federation.go index 9f70c56..c85ff3f 100644 --- a/server/federation.go +++ b/server/federation.go @@ -73,7 +73,7 @@ func (s *Server) getNumSubs() int64 { // pings it, so we can determine our own external IP address. func (s *Server) getAndSetExternalIp(msg *pb.ServerMessage) error { log.Println(msg) - myIp, err := UDPPing(msg.Address, msg.Port) + myIp, _, err := UDPPing(msg.Address, msg.Port) if err != nil { return err } diff --git a/server/udp.go b/server/udp.go index 65eb18a..734025f 100644 --- a/server/udp.go +++ b/server/udp.go @@ -149,47 +149,52 @@ func (pong *SPVPong) DecodeAddress() net.IP { ) } +func (pong *SPVPong) DecodeCountry() string { + return pb.Location_Country_name[int32(pong.country)] +} + // UDPPing sends a ping over udp to another hub and returns the ip address of // this hub. -func UDPPing(ip, port string) (net.IP, error) { +func UDPPing(ip, port string) (net.IP, string, error) { address := ip + ":" + port addr, err := net.ResolveUDPAddr("udp", address) if err != nil { - return net.IP{}, err + return net.IP{}, "", err } conn, err := net.DialUDP("udp", nil, addr) if err != nil { - return net.IP{}, err + return net.IP{}, "", err } defer conn.Close() _, err = conn.Write(encodeSPVPing()) if err != nil { - return net.IP{}, err + return net.IP{}, "", err } buffer := make([]byte, maxBufferSize) deadline := time.Now().Add(time.Second) err = conn.SetReadDeadline(deadline) if err != nil { - return net.IP{}, err + return net.IP{}, "", err } n, _, err := conn.ReadFromUDP(buffer) if err != nil { - return net.IP{}, err + return net.IP{}, "", err } pong := decodeSPVPong(buffer[:n]) if pong == nil { - return net.IP{}, errors.Base("Pong decoding failed") + return net.IP{}, "", errors.Base("Pong decoding failed") } myAddr := pong.DecodeAddress() + country := pong.DecodeCountry() - return myAddr, nil + return myAddr, country, nil } // UDPServer is a goroutine that starts an udp server that implements the hubs diff --git a/server/udp_test.go b/server/udp_test.go index 9cc3d9e..5f1071f 100644 --- a/server/udp_test.go +++ b/server/udp_test.go @@ -13,12 +13,14 @@ func TestUDPPing(t *testing.T) { args.StartUDP = false tests := []struct { - name string - want string + name string + wantIP string + wantCountry string } { { - name: "Get the right ip from production server.", - want: "SETME", + name: "Get the right ip from production server.", + wantIP: "SETME", + wantCountry: "US", }, } @@ -28,7 +30,8 @@ func TestUDPPing(t *testing.T) { toAddr := "spv16.lbry.com" toPort := "50001" - ip, err := UDPPing(toAddr, toPort) + ip, country, err := UDPPing(toAddr, toPort) + gotCountry := country if err != nil { log.Println(err) } @@ -41,11 +44,14 @@ func TestUDPPing(t *testing.T) { digIP := strings.TrimSpace(string(res)) udpIP := ip.String() - tt.want = digIP + tt.wantIP = digIP - got1 := udpIP - if got1 != tt.want { - t.Errorf("got: '%s', want: '%s'\n", got1, tt.want) + gotIP := udpIP + if gotIP != tt.wantIP { + t.Errorf("got: '%s', want: '%s'\n", gotIP, tt.wantIP) + } + if gotCountry != tt.wantCountry { + t.Errorf("got: '%s', want: '%s'\n", gotCountry, tt.wantCountry) } }) } From 0a1ba43d66929533f589a18c77a2f4cbf8aac340 Mon Sep 17 00:00:00 2001 From: Jeffrey Picard Date: Wed, 24 Nov 2021 17:58:05 -0500 Subject: [PATCH 06/12] Full SPVPong parsing and tests against prod server. --- server/federation.go | 3 +- server/udp.go | 36 +++++++++++---- server/udp_test.go | 108 ++++++++++++++++++++++++++----------------- 3 files changed, 94 insertions(+), 53 deletions(-) diff --git a/server/federation.go b/server/federation.go index c85ff3f..25a0dca 100644 --- a/server/federation.go +++ b/server/federation.go @@ -73,10 +73,11 @@ func (s *Server) getNumSubs() int64 { // pings it, so we can determine our own external IP address. func (s *Server) getAndSetExternalIp(msg *pb.ServerMessage) error { log.Println(msg) - myIp, _, err := UDPPing(msg.Address, msg.Port) + pong, err := UDPPing(msg.Address, msg.Port) if err != nil { return err } + myIp := pong.DecodeAddress() log.Println("my ip: ", myIp) s.ExternalIP = myIp diff --git a/server/udp.go b/server/udp.go index 734025f..55cc14a 100644 --- a/server/udp.go +++ b/server/udp.go @@ -153,48 +153,64 @@ func (pong *SPVPong) DecodeCountry() string { return pb.Location_Country_name[int32(pong.country)] } +func (pong *SPVPong) DecodeProtocolVersion() int { + return int(pong.protocolVersion) +} + +func (pong *SPVPong) DecodeHeight() int { + return int(pong.height) +} + +func (pong *SPVPong) DecodeTip() []byte { + return pong.tip +} + +func (pong *SPVPong) DecodeFlags() byte { + return pong.flags +} + // UDPPing sends a ping over udp to another hub and returns the ip address of // this hub. -func UDPPing(ip, port string) (net.IP, string, error) { +func UDPPing(ip, port string) (*SPVPong, error) { address := ip + ":" + port addr, err := net.ResolveUDPAddr("udp", address) if err != nil { - return net.IP{}, "", err + return nil, err } conn, err := net.DialUDP("udp", nil, addr) if err != nil { - return net.IP{}, "", err + return nil, err } defer conn.Close() _, err = conn.Write(encodeSPVPing()) if err != nil { - return net.IP{}, "", err + return nil, err } buffer := make([]byte, maxBufferSize) deadline := time.Now().Add(time.Second) err = conn.SetReadDeadline(deadline) if err != nil { - return net.IP{}, "", err + return nil, err } n, _, err := conn.ReadFromUDP(buffer) if err != nil { - return net.IP{}, "", err + return nil, err } pong := decodeSPVPong(buffer[:n]) if pong == nil { - return net.IP{}, "", errors.Base("Pong decoding failed") + return nil, errors.Base("Pong decoding failed") } - myAddr := pong.DecodeAddress() - country := pong.DecodeCountry() + // myAddr := pong.DecodeAddress() + // country := pong.DecodeCountry() - return myAddr, country, nil + return pong, nil } // UDPServer is a goroutine that starts an udp server that implements the hubs diff --git a/server/udp_test.go b/server/udp_test.go index 5f1071f..ceb3db3 100644 --- a/server/udp_test.go +++ b/server/udp_test.go @@ -1,59 +1,83 @@ package server import ( - "log" - "os/exec" - "strings" - "testing" + "log" + "os/exec" + "strings" + "testing" ) // TestAddPeer tests the ability to add peers func TestUDPPing(t *testing.T) { - args := makeDefaultArgs() - args.StartUDP = false + args := makeDefaultArgs() + args.StartUDP = false - tests := []struct { - name string - wantIP string - wantCountry string - } { - { - name: "Get the right ip from production server.", - wantIP: "SETME", - wantCountry: "US", - }, - } + tests := []struct { + name string + wantIP string + wantCountry string + wantProtocolVersion int + wantHeightMin int + wantFlags byte + } { + { + name: "Correctly parse information from production server.", + wantIP: "SETME", + wantCountry: "US", + wantProtocolVersion: 1, + wantHeightMin: 1060000, + wantFlags: 1, + }, + } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T){ + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T){ - toAddr := "spv16.lbry.com" - toPort := "50001" + toAddr := "spv16.lbry.com" + toPort := "50001" - ip, country, err := UDPPing(toAddr, toPort) - gotCountry := country - if err != nil { - log.Println(err) - } + pong, err := UDPPing(toAddr, toPort) + gotCountry := pong.DecodeCountry() + if err != nil { + log.Println(err) + } - res, err := exec.Command("dig", "@resolver4.opendns.com", "myip.opendns.com", "+short").Output() + res, err := exec.Command("dig", "@resolver4.opendns.com", "myip.opendns.com", "+short").Output() - if err != nil { - log.Println(err) - } + if err != nil { + log.Println(err) + } - digIP := strings.TrimSpace(string(res)) - udpIP := ip.String() - tt.wantIP = digIP + digIP := strings.TrimSpace(string(res)) + udpIP := pong.DecodeAddress().String() + tt.wantIP = digIP - gotIP := udpIP - if gotIP != tt.wantIP { - t.Errorf("got: '%s', want: '%s'\n", gotIP, tt.wantIP) - } - if gotCountry != tt.wantCountry { - t.Errorf("got: '%s', want: '%s'\n", gotCountry, tt.wantCountry) - } - }) - } + log.Println("Height:", pong.DecodeHeight()) + log.Printf("Flags: %x\n", pong.DecodeFlags()) + log.Println("ProtocolVersion:", pong.DecodeProtocolVersion()) + log.Printf("Tip: %x\n", pong.DecodeTip()) + + gotHeight := pong.DecodeHeight() + gotProtocolVersion := pong.DecodeProtocolVersion() + gotFlags := pong.DecodeFlags() + gotIP := udpIP + + if gotIP != tt.wantIP { + t.Errorf("ip: got: '%s', want: '%s'\n", gotIP, tt.wantIP) + } + if gotCountry != tt.wantCountry { + t.Errorf("country: got: '%s', want: '%s'\n", gotCountry, tt.wantCountry) + } + if gotHeight < tt.wantHeightMin { + t.Errorf("height: got: %d, want >=: %d\n", gotHeight, tt.wantHeightMin) + } + if gotProtocolVersion != tt.wantProtocolVersion { + t.Errorf("protocolVersion: got: %d, want: %d\n", gotProtocolVersion, tt.wantProtocolVersion) + } + if gotFlags != tt.wantFlags { + t.Errorf("flags: got: %d, want: %d\n", gotFlags, tt.wantFlags) + } + }) + } } From 72ea236d868d12322cd1f41b901433f26104b2a8 Mon Sep 17 00:00:00 2001 From: Jeffrey Picard Date: Wed, 24 Nov 2021 18:24:06 -0500 Subject: [PATCH 07/12] Run gofmt --- internal/metrics/metrics.go | 5 +- server/args.go | 39 +++++------ server/federation.go | 24 ++++--- server/federation_test.go | 45 ++++++------- server/search.go | 37 +++++------ server/server.go | 7 +- server/udp.go | 23 +++---- server/udp_test.go | 128 ++++++++++++++++++------------------ 8 files changed, 150 insertions(+), 158 deletions(-) diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go index b2f2256..7109664 100644 --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -18,8 +18,8 @@ var ( Help: "Number of errors by type", }, []string{"error_type"}) QueryTime = promauto.NewHistogramVec(prometheus.HistogramOpts{ - Name: "query_time", - Help: "Histogram of query times", + Name: "query_time", + Help: "Histogram of query times", Buckets: HistogramBuckets, }, []string{"method"}) PeersKnown = promauto.NewGauge(prometheus.GaugeOpts{ @@ -31,4 +31,3 @@ var ( Help: "Number of peers that are subscribed to us.", }) ) - diff --git a/server/args.go b/server/args.go index beff48f..2834e5e 100644 --- a/server/args.go +++ b/server/args.go @@ -16,23 +16,24 @@ const ( // Args struct contains the arguments to the hub server. type Args struct { - CmdType int - Host string - Port string - EsHost string - EsPort string - PrometheusPort string - EsIndex string - RefreshDelta int - CacheTTL int - PeerFile string - Country string - DisableEs bool - Debug bool - LoadPeers bool - StartPrometheus bool - StartUDP bool - WritePeers bool + CmdType int + Host string + Port string + EsHost string + EsPort string + PrometheusPort string + EsIndex string + RefreshDelta int + CacheTTL int + PeerFile string + Country string + DisableEs bool + Debug bool + LoadPeers bool + StartPrometheus bool + StartUDP bool + WritePeers bool + DisableFederation bool } const ( @@ -153,7 +154,7 @@ func ParseArgs(searchRequest *pb.SearchRequest) *Args { } /* - Verify no invalid argument combinations + Verify no invalid argument combinations */ if len(*channelIds) > 0 && *channelId != "" { log.Fatal("Cannot specify both channel_id and channel_ids") @@ -194,4 +195,4 @@ func ParseArgs(searchRequest *pb.SearchRequest) *Args { } return args -} \ No newline at end of file +} diff --git a/server/federation.go b/server/federation.go index 25a0dca..e232ab0 100644 --- a/server/federation.go +++ b/server/federation.go @@ -26,13 +26,12 @@ type FederatedServer struct { var ( localHosts = map[string]bool{ "127.0.0.1": true, - "0.0.0.0": true, + "0.0.0.0": true, "localhost": true, - "": true, + "": true, } ) - // peerKey takes a ServerMessage object and returns the key that for that peer // in our peer table. func peerKey(msg *pb.ServerMessage) string { @@ -117,7 +116,6 @@ retry: } cancel() - f, err := os.Open(peerFile) if err != nil { log.Println(err) @@ -135,7 +133,7 @@ retry: } for _, line := range text { - ipPort := strings.Split(line,":") + ipPort := strings.Split(line, ":") if len(ipPort) != 2 { log.Println("Malformed entry in peer file") continue @@ -220,8 +218,8 @@ func (s *Server) helloPeer(server *FederatedServer) (*pb.HelloMessage, error) { c := pb.NewHubClient(conn) msg := &pb.HelloMessage{ - Port: s.Args.Port, - Host: s.ExternalIP.String(), + Port: s.Args.Port, + Host: s.ExternalIP.String(), Servers: []*pb.ServerMessage{}, } @@ -333,7 +331,7 @@ func (s *Server) addPeer(msg *pb.ServerMessage, ping bool, subscribe bool) error // could end up subscribed to our self, which is silly. nilIP := net.IP{} //localIP0 := net.IPv4(0,0,0,0) - localIP1 := net.IPv4(127,0,0,1) + localIP1 := net.IPv4(127, 0, 0, 1) if s.ExternalIP.Equal(nilIP) || s.ExternalIP.Equal(localIP1) { err := s.getAndSetExternalIp(msg) if err != nil { @@ -351,8 +349,8 @@ func (s *Server) addPeer(msg *pb.ServerMessage, ping bool, subscribe bool) error k := peerKey(msg) newServer := &FederatedServer{ Address: msg.Address, - Port: msg.Port, - Ts: time.Now(), + Port: msg.Port, + Ts: time.Now(), } log.Printf("%s:%s adding peer %+v\n", s.ExternalIP, s.Args.Port, msg) @@ -406,14 +404,14 @@ func (s *Server) makeHelloMessage() *pb.HelloMessage { for _, peer := range s.PeerServers { servers = append(servers, &pb.ServerMessage{ Address: peer.Address, - Port: peer.Port, + Port: peer.Port, }) } s.PeerServersMut.RUnlock() return &pb.HelloMessage{ - Port: s.Args.Port, - Host: s.ExternalIP.String(), + Port: s.Args.Port, + Host: s.ExternalIP.String(), Servers: servers, } } diff --git a/server/federation_test.go b/server/federation_test.go index 8ecaf1f..071d326 100644 --- a/server/federation_test.go +++ b/server/federation_test.go @@ -75,7 +75,7 @@ func TestAddPeer(t *testing.T) { tests := []struct { name string want int - } { + }{ { name: "Add 10 peers", want: 10, @@ -87,9 +87,9 @@ func TestAddPeer(t *testing.T) { } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T){ + t.Run(tt.name, func(t *testing.T) { server := MakeHubServer(ctx, args) - server.ExternalIP = net.IPv4(0,0,0,0) + server.ExternalIP = net.IPv4(0, 0, 0, 0) metrics.PeersKnown.Set(0) for i := 0; i < 10; i++ { @@ -134,7 +134,7 @@ func TestPeerWriter(t *testing.T) { tests := []struct { name string want int - } { + }{ { name: "Add 10 peers", want: 10, @@ -146,9 +146,9 @@ func TestPeerWriter(t *testing.T) { } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T){ + t.Run(tt.name, func(t *testing.T) { server := MakeHubServer(ctx, args) - server.ExternalIP = net.IPv4(0,0,0,0) + server.ExternalIP = net.IPv4(0, 0, 0, 0) for i := 0; i < 10; i++ { var msg *pb.ServerMessage @@ -188,12 +188,11 @@ func TestAddPeerEndpoint(t *testing.T) { args2 := makeDefaultArgs() args2.Port = "50052" - tests := []struct { - name string + name string wantServerOne int64 wantServerTwo int64 - } { + }{ { // outside -> server1.AddPeer(server2, ping=true) : server1 = 1, server2 = 0 // server1 -> server2.Hello(server1) : server1 = 1, server2 = 0 @@ -204,14 +203,14 @@ func TestAddPeerEndpoint(t *testing.T) { // server1 -> server2.AddPeer(server2) : server1 = 1, server2 = 1 // server2 self peer, skipping : server1 = 1, server2 = 1 // server1 -> server2.PeerSubscribe(server1) : server1 = 1, server2 = 1 - name: "Add 1 peer", + name: "Add 1 peer", wantServerOne: 1, wantServerTwo: 1, }, } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T){ + t.Run(tt.name, func(t *testing.T) { server := MakeHubServer(ctx, args) server2 := MakeHubServer(ctx, args2) metrics.PeersKnown.Set(0) @@ -262,15 +261,14 @@ func TestAddPeerEndpoint2(t *testing.T) { args2.Port = "50052" args3.Port = "50053" - tests := []struct { - name string + name string wantServerOne int64 wantServerTwo int64 wantServerThree int64 - } { + }{ { - name: "Add 2 peers", + name: "Add 2 peers", wantServerOne: 2, wantServerTwo: 2, wantServerThree: 2, @@ -278,7 +276,7 @@ func TestAddPeerEndpoint2(t *testing.T) { } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T){ + t.Run(tt.name, func(t *testing.T) { server := MakeHubServer(ctx, args) server2 := MakeHubServer(ctx, args2) server3 := MakeHubServer(ctx, args3) @@ -335,7 +333,6 @@ func TestAddPeerEndpoint2(t *testing.T) { } - // TestAddPeerEndpoint3 tests the ability to add peers func TestAddPeerEndpoint3(t *testing.T) { ctx := context.Background() @@ -345,15 +342,14 @@ func TestAddPeerEndpoint3(t *testing.T) { args2.Port = "50052" args3.Port = "50053" - tests := []struct { - name string + name string wantServerOne int64 wantServerTwo int64 wantServerThree int64 - } { + }{ { - name: "Add 1 peer to each", + name: "Add 1 peer to each", wantServerOne: 2, wantServerTwo: 2, wantServerThree: 2, @@ -361,7 +357,7 @@ func TestAddPeerEndpoint3(t *testing.T) { } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T){ + t.Run(tt.name, func(t *testing.T) { server := MakeHubServer(ctx, args) server2 := MakeHubServer(ctx, args2) server3 := MakeHubServer(ctx, args3) @@ -426,7 +422,6 @@ func TestAddPeerEndpoint3(t *testing.T) { } - // TestAddPeer tests the ability to add peers func TestUDPServer(t *testing.T) { ctx := context.Background() @@ -439,7 +434,7 @@ func TestUDPServer(t *testing.T) { tests := []struct { name string want string - } { + }{ { name: "hubs server external ip", want: "127.0.0.1", @@ -447,7 +442,7 @@ func TestUDPServer(t *testing.T) { } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T){ + t.Run(tt.name, func(t *testing.T) { server := MakeHubServer(ctx, args) server2 := MakeHubServer(ctx, args2) go server.Run() diff --git a/server/search.go b/server/search.go index fac6e57..f357f92 100644 --- a/server/search.go +++ b/server/search.go @@ -275,16 +275,16 @@ func (s *Server) Search(ctx context.Context, in *pb.SearchRequest) (*pb.Outputs, setPageVars(in, &pageSize, &from) /* - cache based on search request params - include from value and number of results. - When another search request comes in with same search params - and same or increased offset (which we currently don't even use?) - that will be a cache hit. - FIXME: For now the cache is turned off when in debugging mode - (for unit tests) because it breaks on some of them. - FIXME: Currently the cache just skips the initial search, - the mgets and post processing are still done. There's probably - a more efficient way to store the final result. + cache based on search request params + include from value and number of results. + When another search request comes in with same search params + and same or increased offset (which we currently don't even use?) + that will be a cache hit. + FIXME: For now the cache is turned off when in debugging mode + (for unit tests) because it breaks on some of them. + FIXME: Currently the cache just skips the initial search, + the mgets and post processing are still done. There's probably + a more efficient way to store the final result. */ if val, err := s.QueryCache.Get(cacheKey); err != nil { @@ -518,15 +518,15 @@ func (s *Server) setupEsQuery( } replacements := map[string]string{ - "name": "normalized_name", - "normalized": "normalized_name", - "claim_name": "normalized_name", - "txid": "tx_id", - "nout": "tx_nout", - "reposted": "repost_count", + "name": "normalized_name", + "normalized": "normalized_name", + "claim_name": "normalized_name", + "txid": "tx_id", + "nout": "tx_nout", + "reposted": "repost_count", "valid_channel_signature": "is_signature_valid", - "claim_id": "_id", - "signature_digest": "signature", + "claim_id": "_id", + "signature_digest": "signature", } textFields := map[string]bool{ @@ -967,4 +967,3 @@ func removeBlocked(searchHits []*record) ([]*record, []*record, map[string]*pb.B return newHits, blockedHits, blockedChannels } - diff --git a/server/server.go b/server/server.go index 6a15315..ff45f19 100644 --- a/server/server.go +++ b/server/server.go @@ -45,7 +45,6 @@ type Server struct { pb.UnimplementedHubServer } - func getVersion() string { return meta.Version } @@ -202,7 +201,7 @@ func MakeHubServer(ctx context.Context, args *Args) *Server { PeerSubs: make(map[string]*FederatedServer), PeerSubsMut: sync.RWMutex{}, NumPeerSubs: numSubs, - ExternalIP: net.IPv4(127,0,0,1), + ExternalIP: net.IPv4(127, 0, 0, 1), } // Start up our background services @@ -248,8 +247,8 @@ func (s *Server) Hello(ctx context.Context, args *pb.HelloMessage) (*pb.HelloMes host := args.Host server := &FederatedServer{ Address: host, - Port: port, - Ts: time.Now(), + Port: port, + Ts: time.Now(), } log.Println(server) diff --git a/server/udp.go b/server/udp.go index 55cc14a..774fdd8 100644 --- a/server/udp.go +++ b/server/udp.go @@ -11,9 +11,10 @@ import ( "github.com/lbryio/lbry.go/v2/extras/errors" ) -const maxBufferSize = 1024 +const maxBufferSize = 1024 + // genesis blocktime (which is actually wrong) -const magic = 1446058291 +const magic = 1446058291 const protocolVersion = 1 // SPVPing is a struct for the format of how to ping another hub over udp. @@ -31,7 +32,7 @@ type SPVPong struct { flags byte height uint32 tip []byte // 32 - srcAddrRaw []byte // 4 + srcAddrRaw []byte // 4 country uint16 } @@ -55,7 +56,7 @@ func decodeSPVPing(data []byte) *SPVPing { parsedMagic := binary.BigEndian.Uint32(data) parsedProtocalVersion := data[4] return &SPVPing{ - magic: parsedMagic, + magic: parsedMagic, version: parsedProtocalVersion, } } @@ -65,7 +66,7 @@ func decodeSPVPing(data []byte) *SPVPing { func (pong *SPVPong) Encode() []byte { data := make([]byte, 44) - data[0] = pong.protocolVersion + data[0] = pong.protocolVersion data[1] = pong.flags binary.BigEndian.PutUint32(data[2:], pong.height) copy(data[6:], pong.tip) @@ -110,11 +111,11 @@ func decodeSPVPong(data []byte) *SPVPong { country := binary.BigEndian.Uint16(data[42:]) return &SPVPong{ protocolVersion: parsedProtocalVersion, - flags: flags, - height: height, - tip: tip, - srcAddrRaw: srcRawAddr, - country: country, + flags: flags, + height: height, + tip: tip, + srcAddrRaw: srcRawAddr, + country: country, } } @@ -240,7 +241,7 @@ func UDPServer(args *Args) error { } sAddr := addr.IP.String() - pong := makeSPVPong(0,0, tip, sAddr, args.Country) + pong := makeSPVPong(0, 0, tip, sAddr, args.Country) data := pong.Encode() _, err = conn.WriteToUDP(data, addr) diff --git a/server/udp_test.go b/server/udp_test.go index ceb3db3..43a521e 100644 --- a/server/udp_test.go +++ b/server/udp_test.go @@ -1,83 +1,83 @@ package server import ( - "log" - "os/exec" - "strings" - "testing" + "log" + "os/exec" + "strings" + "testing" ) // TestAddPeer tests the ability to add peers func TestUDPPing(t *testing.T) { - args := makeDefaultArgs() - args.StartUDP = false + args := makeDefaultArgs() + args.StartUDP = false - tests := []struct { - name string - wantIP string - wantCountry string - wantProtocolVersion int - wantHeightMin int - wantFlags byte - } { - { - name: "Correctly parse information from production server.", - wantIP: "SETME", - wantCountry: "US", - wantProtocolVersion: 1, - wantHeightMin: 1060000, - wantFlags: 1, - }, - } + tests := []struct { + name string + wantIP string + wantCountry string + wantProtocolVersion int + wantHeightMin int + wantFlags byte + }{ + { + name: "Correctly parse information from production server.", + wantIP: "SETME", + wantCountry: "US", + wantProtocolVersion: 1, + wantHeightMin: 1060000, + wantFlags: 1, + }, + } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T){ + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { - toAddr := "spv16.lbry.com" - toPort := "50001" + toAddr := "spv16.lbry.com" + toPort := "50001" - pong, err := UDPPing(toAddr, toPort) - gotCountry := pong.DecodeCountry() - if err != nil { - log.Println(err) - } + pong, err := UDPPing(toAddr, toPort) + gotCountry := pong.DecodeCountry() + if err != nil { + log.Println(err) + } - res, err := exec.Command("dig", "@resolver4.opendns.com", "myip.opendns.com", "+short").Output() + res, err := exec.Command("dig", "@resolver4.opendns.com", "myip.opendns.com", "+short").Output() - if err != nil { - log.Println(err) - } + if err != nil { + log.Println(err) + } - digIP := strings.TrimSpace(string(res)) - udpIP := pong.DecodeAddress().String() - tt.wantIP = digIP + digIP := strings.TrimSpace(string(res)) + udpIP := pong.DecodeAddress().String() + tt.wantIP = digIP - log.Println("Height:", pong.DecodeHeight()) - log.Printf("Flags: %x\n", pong.DecodeFlags()) - log.Println("ProtocolVersion:", pong.DecodeProtocolVersion()) - log.Printf("Tip: %x\n", pong.DecodeTip()) + log.Println("Height:", pong.DecodeHeight()) + log.Printf("Flags: %x\n", pong.DecodeFlags()) + log.Println("ProtocolVersion:", pong.DecodeProtocolVersion()) + log.Printf("Tip: %x\n", pong.DecodeTip()) - gotHeight := pong.DecodeHeight() - gotProtocolVersion := pong.DecodeProtocolVersion() - gotFlags := pong.DecodeFlags() - gotIP := udpIP + gotHeight := pong.DecodeHeight() + gotProtocolVersion := pong.DecodeProtocolVersion() + gotFlags := pong.DecodeFlags() + gotIP := udpIP - if gotIP != tt.wantIP { - t.Errorf("ip: got: '%s', want: '%s'\n", gotIP, tt.wantIP) - } - if gotCountry != tt.wantCountry { - t.Errorf("country: got: '%s', want: '%s'\n", gotCountry, tt.wantCountry) - } - if gotHeight < tt.wantHeightMin { - t.Errorf("height: got: %d, want >=: %d\n", gotHeight, tt.wantHeightMin) - } - if gotProtocolVersion != tt.wantProtocolVersion { - t.Errorf("protocolVersion: got: %d, want: %d\n", gotProtocolVersion, tt.wantProtocolVersion) - } - if gotFlags != tt.wantFlags { - t.Errorf("flags: got: %d, want: %d\n", gotFlags, tt.wantFlags) - } - }) - } + if gotIP != tt.wantIP { + t.Errorf("ip: got: '%s', want: '%s'\n", gotIP, tt.wantIP) + } + if gotCountry != tt.wantCountry { + t.Errorf("country: got: '%s', want: '%s'\n", gotCountry, tt.wantCountry) + } + if gotHeight < tt.wantHeightMin { + t.Errorf("height: got: %d, want >=: %d\n", gotHeight, tt.wantHeightMin) + } + if gotProtocolVersion != tt.wantProtocolVersion { + t.Errorf("protocolVersion: got: %d, want: %d\n", gotProtocolVersion, tt.wantProtocolVersion) + } + if gotFlags != tt.wantFlags { + t.Errorf("flags: got: %d, want: %d\n", gotFlags, tt.wantFlags) + } + }) + } } From ca0e8562f3ff133582cd56de205c02a2abd86fcb Mon Sep 17 00:00:00 2001 From: Jeffrey Picard Date: Wed, 24 Nov 2021 18:36:19 -0500 Subject: [PATCH 08/12] Add disable-federation flag, default false --- server/args.go | 65 +++++++++++++++++++++++--------------------- server/federation.go | 10 +++++-- 2 files changed, 42 insertions(+), 33 deletions(-) diff --git a/server/args.go b/server/args.go index 2834e5e..00b24c9 100644 --- a/server/args.go +++ b/server/args.go @@ -37,20 +37,21 @@ type Args struct { } const ( - DefaultHost = "0.0.0.0" - DefaultPort = "50051" - DefaultEsHost = "http://localhost" - DefaultEsIndex = "claims" - DefaultEsPort = "9200" - DefaultPrometheusPort = "2112" - DefaultRefreshDelta = 5 - DefaultCacheTTL = 5 - DefaultPeerFile = "peers.txt" - DefaultCountry = "US" - DefaultLoadPeers = true - DefaultStartPrometheus = true - DefaultStartUDP = true - DefaultWritePeers = true + DefaultHost = "0.0.0.0" + DefaultPort = "50051" + DefaultEsHost = "http://localhost" + DefaultEsIndex = "claims" + DefaultEsPort = "9200" + DefaultPrometheusPort = "2112" + DefaultRefreshDelta = 5 + DefaultCacheTTL = 5 + DefaultPeerFile = "peers.txt" + DefaultCountry = "US" + DefaultLoadPeers = true + DefaultStartPrometheus = true + DefaultStartUDP = true + DefaultWritePeers = true + DefaultDisableFederation = false ) // GetEnvironment takes the environment variables as an array of strings @@ -100,6 +101,7 @@ func ParseArgs(searchRequest *pb.SearchRequest) *Args { startPrometheus := parser.Flag("", "start-prometheus", &argparse.Options{Required: false, Help: "Start prometheus server", Default: DefaultStartPrometheus}) startUdp := parser.Flag("", "start-udp", &argparse.Options{Required: false, Help: "Start UDP ping server", Default: DefaultStartUDP}) writePeers := parser.Flag("", "write-peers", &argparse.Options{Required: false, Help: "Write peer to disk as we learn about them", Default: DefaultWritePeers}) + disableFederation := parser.Flag("", "disable-federation", &argparse.Options{Required: false, Help: "Disable server federation", Default: DefaultDisableFederation}) text := parser.String("", "text", &argparse.Options{Required: false, Help: "text query"}) name := parser.String("", "name", &argparse.Options{Required: false, Help: "name"}) @@ -118,23 +120,24 @@ func ParseArgs(searchRequest *pb.SearchRequest) *Args { } args := &Args{ - CmdType: SearchCmd, - Host: *host, - Port: *port, - EsHost: *esHost, - EsPort: *esPort, - PrometheusPort: *prometheusPort, - EsIndex: *esIndex, - RefreshDelta: *refreshDelta, - CacheTTL: *cacheTTL, - PeerFile: *peerFile, - Country: *country, - DisableEs: *disableEs, - Debug: *debug, - LoadPeers: *loadPeers, - StartPrometheus: *startPrometheus, - StartUDP: *startUdp, - WritePeers: *writePeers, + CmdType: SearchCmd, + Host: *host, + Port: *port, + EsHost: *esHost, + EsPort: *esPort, + PrometheusPort: *prometheusPort, + EsIndex: *esIndex, + RefreshDelta: *refreshDelta, + CacheTTL: *cacheTTL, + PeerFile: *peerFile, + Country: *country, + DisableEs: *disableEs, + Debug: *debug, + LoadPeers: *loadPeers, + StartPrometheus: *startPrometheus, + StartUDP: *startUdp, + WritePeers: *writePeers, + DisableFederation: *disableFederation, } if esHost, ok := environment["ELASTIC_HOST"]; ok { diff --git a/server/federation.go b/server/federation.go index e232ab0..abfabf1 100644 --- a/server/federation.go +++ b/server/federation.go @@ -267,7 +267,10 @@ func (s *Server) writePeers() { // notifyPeer takes a peer to notify and a new peer we just learned about // and calls AddPeer on the first. -func notifyPeer(peerToNotify *FederatedServer, newPeer *FederatedServer) error { +func (s *Server) notifyPeer(peerToNotify *FederatedServer, newPeer *FederatedServer) error { + if s.Args.DisableFederation { + return nil + } ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() @@ -303,7 +306,7 @@ func (s *Server) notifyPeerSubs(newServer *FederatedServer) { s.PeerSubsMut.RLock() for key, peer := range s.PeerSubs { log.Printf("Notifying peer %s of new node %+v\n", key, newServer) - err := notifyPeer(peer, newServer) + err := s.notifyPeer(peer, newServer) if err != nil { log.Println("Failed to send data to ", key) log.Println(err) @@ -327,6 +330,9 @@ func (s *Server) notifyPeerSubs(newServer *FederatedServer) { // if they're online, and adds them to our list of peer. If we're not currently // subscribed to a peer, it will also subscribe to it. func (s *Server) addPeer(msg *pb.ServerMessage, ping bool, subscribe bool) error { + if s.Args.DisableFederation { + return nil + } // First thing we get our external ip if we don't have it, otherwise we // could end up subscribed to our self, which is silly. nilIP := net.IP{} From 283686ecac7130e481ea83d9744f1f6a39dc2883 Mon Sep 17 00:00:00 2001 From: Jeffrey Picard Date: Wed, 24 Nov 2021 18:56:34 -0500 Subject: [PATCH 09/12] Fix startup flags --- main.go | 14 +---- server/args.go | 110 +++++++++++++++++++------------------- server/federation.go | 2 +- server/federation_test.go | 40 +++++++------- server/server.go | 6 +-- server/udp_test.go | 2 +- 6 files changed, 81 insertions(+), 93 deletions(-) diff --git a/main.go b/main.go index f99ddc8..f87acd3 100644 --- a/main.go +++ b/main.go @@ -26,19 +26,7 @@ func main() { s := server.MakeHubServer(ctxWCancel, args) s.Run() - //l, err := net.Listen("tcp", ":"+args.Port) - //if err != nil { - // log.Fatalf("failed to listen: %v", err) - //} - // - //pb.RegisterHubServer(s.GrpcServer, s) - //reflection.Register(s.GrpcServer) - // - //log.Printf("listening on %s\n", l.Addr().String()) - //log.Println(s.Args) - //if err := s.GrpcServer.Serve(l); err != nil { - // log.Fatalf("failed to serve: %v", err) - //} + return } diff --git a/server/args.go b/server/args.go index 00b24c9..655de9a 100644 --- a/server/args.go +++ b/server/args.go @@ -16,42 +16,42 @@ const ( // Args struct contains the arguments to the hub server. type Args struct { - CmdType int - Host string - Port string - EsHost string - EsPort string - PrometheusPort string - EsIndex string - RefreshDelta int - CacheTTL int - PeerFile string - Country string - DisableEs bool - Debug bool - LoadPeers bool - StartPrometheus bool - StartUDP bool - WritePeers bool - DisableFederation bool + CmdType int + Host string + Port string + EsHost string + EsPort string + PrometheusPort string + EsIndex string + RefreshDelta int + CacheTTL int + PeerFile string + Country string + DisableEs bool + Debug bool + DisableLoadPeers bool + DisableStartPrometheus bool + DisableStartUDP bool + DisableWritePeers bool + DisableFederation bool } const ( - DefaultHost = "0.0.0.0" - DefaultPort = "50051" - DefaultEsHost = "http://localhost" - DefaultEsIndex = "claims" - DefaultEsPort = "9200" - DefaultPrometheusPort = "2112" - DefaultRefreshDelta = 5 - DefaultCacheTTL = 5 - DefaultPeerFile = "peers.txt" - DefaultCountry = "US" - DefaultLoadPeers = true - DefaultStartPrometheus = true - DefaultStartUDP = true - DefaultWritePeers = true - DefaultDisableFederation = false + DefaultHost = "0.0.0.0" + DefaultPort = "50051" + DefaultEsHost = "http://localhost" + DefaultEsIndex = "claims" + DefaultEsPort = "9200" + DefaultPrometheusPort = "2112" + DefaultRefreshDelta = 5 + DefaultCacheTTL = 5 + DefaultPeerFile = "peers.txt" + DefaultCountry = "US" + DefaultDisableLoadPeers = false + DefaultDisableStartPrometheus = false + DefaultDisableStartUDP = false + DefaultDisableWritePeers = false + DefaultDisableFederation = false ) // GetEnvironment takes the environment variables as an array of strings @@ -97,10 +97,10 @@ func ParseArgs(searchRequest *pb.SearchRequest) *Args { debug := parser.Flag("", "debug", &argparse.Options{Required: false, Help: "enable debug logging", Default: false}) disableEs := parser.Flag("", "disable-es", &argparse.Options{Required: false, Help: "Disable elastic search, for running/testing independently", Default: false}) - loadPeers := parser.Flag("", "load-peers", &argparse.Options{Required: false, Help: "load peers from disk at startup", Default: DefaultLoadPeers}) - startPrometheus := parser.Flag("", "start-prometheus", &argparse.Options{Required: false, Help: "Start prometheus server", Default: DefaultStartPrometheus}) - startUdp := parser.Flag("", "start-udp", &argparse.Options{Required: false, Help: "Start UDP ping server", Default: DefaultStartUDP}) - writePeers := parser.Flag("", "write-peers", &argparse.Options{Required: false, Help: "Write peer to disk as we learn about them", Default: DefaultWritePeers}) + disableLoadPeers := parser.Flag("", "disable-load-peers", &argparse.Options{Required: false, Help: "Disable load peers from disk at startup", Default: DefaultDisableLoadPeers}) + disableStartPrometheus := parser.Flag("", "disable-start-prometheus", &argparse.Options{Required: false, Help: "Disable start prometheus server", Default: DefaultDisableStartPrometheus}) + disableStartUdp := parser.Flag("", "disable-start-udp", &argparse.Options{Required: false, Help: "Disable start UDP ping server", Default: DefaultDisableStartUDP}) + disableWritePeers := parser.Flag("", "disable-write-peers", &argparse.Options{Required: false, Help: "Disable write peer to disk as we learn about them", Default: DefaultDisableWritePeers}) disableFederation := parser.Flag("", "disable-federation", &argparse.Options{Required: false, Help: "Disable server federation", Default: DefaultDisableFederation}) text := parser.String("", "text", &argparse.Options{Required: false, Help: "text query"}) @@ -120,24 +120,24 @@ func ParseArgs(searchRequest *pb.SearchRequest) *Args { } args := &Args{ - CmdType: SearchCmd, - Host: *host, - Port: *port, - EsHost: *esHost, - EsPort: *esPort, - PrometheusPort: *prometheusPort, - EsIndex: *esIndex, - RefreshDelta: *refreshDelta, - CacheTTL: *cacheTTL, - PeerFile: *peerFile, - Country: *country, - DisableEs: *disableEs, - Debug: *debug, - LoadPeers: *loadPeers, - StartPrometheus: *startPrometheus, - StartUDP: *startUdp, - WritePeers: *writePeers, - DisableFederation: *disableFederation, + CmdType: SearchCmd, + Host: *host, + Port: *port, + EsHost: *esHost, + EsPort: *esPort, + PrometheusPort: *prometheusPort, + EsIndex: *esIndex, + RefreshDelta: *refreshDelta, + CacheTTL: *cacheTTL, + PeerFile: *peerFile, + Country: *country, + DisableEs: *disableEs, + Debug: *debug, + DisableLoadPeers: *disableLoadPeers, + DisableStartPrometheus: *disableStartPrometheus, + DisableStartUDP: *disableStartUdp, + DisableWritePeers: *disableWritePeers, + DisableFederation: *disableFederation, } if esHost, ok := environment["ELASTIC_HOST"]; ok { diff --git a/server/federation.go b/server/federation.go index abfabf1..304aff6 100644 --- a/server/federation.go +++ b/server/federation.go @@ -237,7 +237,7 @@ func (s *Server) helloPeer(server *FederatedServer) (*pb.HelloMessage, error) { // writePeers writes our current known peers to disk. func (s *Server) writePeers() { - if !s.Args.WritePeers { + if s.Args.DisableWritePeers { return } f, err := os.Create(s.Args.PeerFile) diff --git a/server/federation_test.go b/server/federation_test.go index 071d326..ed29dd2 100644 --- a/server/federation_test.go +++ b/server/federation_test.go @@ -45,23 +45,23 @@ func removeFile(fileName string) { func makeDefaultArgs() *Args { args := &Args{ - CmdType: ServeCmd, - Host: DefaultHost, - Port: DefaultPort, - EsHost: DefaultEsHost, - EsPort: DefaultEsPort, - PrometheusPort: DefaultPrometheusPort, - EsIndex: DefaultEsIndex, - RefreshDelta: DefaultRefreshDelta, - CacheTTL: DefaultCacheTTL, - PeerFile: DefaultPeerFile, - Country: DefaultCountry, - DisableEs: true, - Debug: true, - LoadPeers: false, - StartPrometheus: false, - StartUDP: false, - WritePeers: false, + CmdType: ServeCmd, + Host: DefaultHost, + Port: DefaultPort, + EsHost: DefaultEsHost, + EsPort: DefaultEsPort, + PrometheusPort: DefaultPrometheusPort, + EsIndex: DefaultEsIndex, + RefreshDelta: DefaultRefreshDelta, + CacheTTL: DefaultCacheTTL, + PeerFile: DefaultPeerFile, + Country: DefaultCountry, + DisableEs: true, + Debug: true, + DisableLoadPeers: true, + DisableStartPrometheus: true, + DisableStartUDP: true, + DisableWritePeers: true, } return args @@ -129,7 +129,7 @@ func TestAddPeer(t *testing.T) { func TestPeerWriter(t *testing.T) { ctx := context.Background() args := makeDefaultArgs() - args.WritePeers = true + args.DisableWritePeers = false tests := []struct { name string @@ -426,10 +426,10 @@ func TestAddPeerEndpoint3(t *testing.T) { func TestUDPServer(t *testing.T) { ctx := context.Background() args := makeDefaultArgs() - args.StartUDP = true + args.DisableStartUDP = false args2 := makeDefaultArgs() args2.Port = "50052" - args2.StartUDP = true + args2.DisableStartUDP = false tests := []struct { name string diff --git a/server/server.go b/server/server.go index ff45f19..16472ce 100644 --- a/server/server.go +++ b/server/server.go @@ -205,10 +205,10 @@ func MakeHubServer(ctx context.Context, args *Args) *Server { } // Start up our background services - if args.StartPrometheus { + if !args.DisableStartPrometheus { go s.prometheusEndpoint(s.Args.PrometheusPort, "metrics") } - if args.StartUDP { + if !args.DisableStartUDP { go func() { err := UDPServer(args) if err != nil { @@ -217,7 +217,7 @@ func MakeHubServer(ctx context.Context, args *Args) *Server { }() } // Load peers from disk and subscribe to one if there are any - if args.LoadPeers { + if !args.DisableLoadPeers { go func() { err := s.loadPeers() if err != nil { diff --git a/server/udp_test.go b/server/udp_test.go index 43a521e..8b8db8c 100644 --- a/server/udp_test.go +++ b/server/udp_test.go @@ -10,7 +10,7 @@ import ( // TestAddPeer tests the ability to add peers func TestUDPPing(t *testing.T) { args := makeDefaultArgs() - args.StartUDP = false + args.DisableStartUDP = true tests := []struct { name string From 1c1d288654db51cb6e04daf35055d85bfaf84de7 Mon Sep 17 00:00:00 2001 From: Jeffrey Picard Date: Wed, 24 Nov 2021 19:14:52 -0500 Subject: [PATCH 10/12] Set UDP flags correctly. --- server/udp.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server/udp.go b/server/udp.go index 774fdd8..1830977 100644 --- a/server/udp.go +++ b/server/udp.go @@ -16,6 +16,9 @@ const maxBufferSize = 1024 // genesis blocktime (which is actually wrong) const magic = 1446058291 const protocolVersion = 1 +const defaultFlags = 0b00000000 + +var availableFlag = 0b00000001 // SPVPing is a struct for the format of how to ping another hub over udp. // format b'!lB64s' @@ -241,7 +244,7 @@ func UDPServer(args *Args) error { } sAddr := addr.IP.String() - pong := makeSPVPong(0, 0, tip, sAddr, args.Country) + pong := makeSPVPong(defaultFlags|availableFlag, 0, tip, sAddr, args.Country) data := pong.Encode() _, err = conn.WriteToUDP(data, addr) From 2e52c1639c25c8d42bd7d3d130773b00103b0174 Mon Sep 17 00:00:00 2001 From: Jeffrey Picard Date: Wed, 1 Dec 2021 19:32:23 -0500 Subject: [PATCH 11/12] Refactor and fixes related to PR comments. --- server/federation.go | 88 +++++++++++++++++++-------------------- server/federation_test.go | 22 +++++----- server/server.go | 31 ++++++++------ server/udp.go | 6 +-- server/udp_test.go | 2 +- 5 files changed, 74 insertions(+), 75 deletions(-) diff --git a/server/federation.go b/server/federation.go index 304aff6..6348764 100644 --- a/server/federation.go +++ b/server/federation.go @@ -16,8 +16,8 @@ import ( "google.golang.org/grpc" ) -// FederatedServer hold relevant information about peers that we known about. -type FederatedServer struct { +// Peer holds relevant information about peers that we know about. +type Peer struct { Address string Port string Ts time.Time @@ -28,19 +28,19 @@ var ( "127.0.0.1": true, "0.0.0.0": true, "localhost": true, - "": true, + "": true, // Empty net.IP turned into a string } ) -// peerKey takes a ServerMessage object and returns the key that for that peer +// peerKey takes a peer and returns the key that for that peer // in our peer table. -func peerKey(msg *pb.ServerMessage) string { - return msg.Address + ":" + msg.Port +func peerKey(peer *Peer) string { + return peer.Address + ":" + peer.Port } // peerKey is a function on a FederatedServer struct to return the key for that // peer is out peer table. -func (peer *FederatedServer) peerKey() string { +func (peer *Peer) peerKey() string { return peer.Address + ":" + peer.Port } @@ -68,11 +68,10 @@ func (s *Server) getNumSubs() int64 { return *s.NumPeerSubs } -// getAndSetExternalIp takes the address of a peer running a UDP server and +// getAndSetExternalIp takes the ip and port of a peer running a UDP server and // pings it, so we can determine our own external IP address. -func (s *Server) getAndSetExternalIp(msg *pb.ServerMessage) error { - log.Println(msg) - pong, err := UDPPing(msg.Address, msg.Port) +func (s *Server) getAndSetExternalIp(ip, port string) error { + pong, err := UDPPing(ip, port) if err != nil { return err } @@ -146,12 +145,13 @@ retry: continue } - srvMsg := &pb.ServerMessage{ + newPeer := &Peer{ Address: ipPort[0], Port: ipPort[1], + Ts: time.Now(), } - log.Printf("pinging peer %+v\n", srvMsg) - err = s.addPeer(srvMsg, true, true) + log.Printf("pinging peer %+v\n", newPeer) + err = s.addPeer(newPeer, true, true) if err != nil { log.Println(err) } @@ -164,7 +164,7 @@ retry: // subscribeToPeer subscribes us to a peer to we'll get updates about their // known peers. -func (s *Server) subscribeToPeer(peer *FederatedServer) error { +func (s *Server) subscribeToPeer(peer *Peer) error { ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() @@ -199,13 +199,13 @@ func (s *Server) subscribeToPeer(peer *FederatedServer) error { // This is used to confirm existence of peers on start and let them // know about us. Returns the response from the server on success, // nil otherwise. -func (s *Server) helloPeer(server *FederatedServer) (*pb.HelloMessage, error) { +func (s *Server) helloPeer(peer *Peer) (*pb.HelloMessage, error) { log.Println("In helloPeer") ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() conn, err := grpc.DialContext(ctx, - server.Address+":"+server.Port, + peer.Address+":"+peer.Port, grpc.WithInsecure(), grpc.WithBlock(), ) @@ -223,7 +223,7 @@ func (s *Server) helloPeer(server *FederatedServer) (*pb.HelloMessage, error) { Servers: []*pb.ServerMessage{}, } - log.Printf("%s:%s saying hello to %+v\n", s.ExternalIP, s.Args.Port, server) + log.Printf("%s:%s saying hello to %+v\n", s.ExternalIP, s.Args.Port, peer) res, err := c.Hello(ctx, msg) if err != nil { log.Println(err) @@ -266,8 +266,8 @@ func (s *Server) writePeers() { } // notifyPeer takes a peer to notify and a new peer we just learned about -// and calls AddPeer on the first. -func (s *Server) notifyPeer(peerToNotify *FederatedServer, newPeer *FederatedServer) error { +// and informs the already known peer about the new peer. +func (s *Server) notifyPeer(peerToNotify *Peer, newPeer *Peer) error { if s.Args.DisableFederation { return nil } @@ -301,12 +301,12 @@ func (s *Server) notifyPeer(peerToNotify *FederatedServer, newPeer *FederatedSer // notifyPeerSubs takes a new peer server we just learned about and notifies // all the peers that have subscribed to us about it. -func (s *Server) notifyPeerSubs(newServer *FederatedServer) { +func (s *Server) notifyPeerSubs(newPeer *Peer) { var unsubscribe []string s.PeerSubsMut.RLock() for key, peer := range s.PeerSubs { - log.Printf("Notifying peer %s of new node %+v\n", key, newServer) - err := s.notifyPeer(peer, newServer) + log.Printf("Notifying peer %s of new node %+v\n", key, newPeer) + err := s.notifyPeer(peer, newPeer) if err != nil { log.Println("Failed to send data to ", key) log.Println(err) @@ -326,43 +326,36 @@ func (s *Server) notifyPeerSubs(newServer *FederatedServer) { s.PeerSubsMut.Unlock() } -// addPeer takes a new peer as a pb.ServerMessage, optionally checks to see -// if they're online, and adds them to our list of peer. If we're not currently -// subscribed to a peer, it will also subscribe to it. -func (s *Server) addPeer(msg *pb.ServerMessage, ping bool, subscribe bool) error { +// addPeer takes a new peer, optionally checks to see if they're online, and +// adds them to our list of peers. It will also optionally subscribe to it. +func (s *Server) addPeer(newPeer *Peer, ping bool, subscribe bool) error { if s.Args.DisableFederation { return nil } // First thing we get our external ip if we don't have it, otherwise we // could end up subscribed to our self, which is silly. nilIP := net.IP{} - //localIP0 := net.IPv4(0,0,0,0) localIP1 := net.IPv4(127, 0, 0, 1) if s.ExternalIP.Equal(nilIP) || s.ExternalIP.Equal(localIP1) { - err := s.getAndSetExternalIp(msg) + err := s.getAndSetExternalIp(newPeer.Address, newPeer.Port) if err != nil { log.Println(err) log.Println("WARNING: can't determine external IP, continuing with ", s.Args.Host) } } - if s.Args.Port == msg.Port && - (localHosts[msg.Address] || msg.Address == s.ExternalIP.String()) { + if s.Args.Port == newPeer.Port && + (localHosts[newPeer.Address] || newPeer.Address == s.ExternalIP.String()) { log.Printf("%s:%s addPeer: Self peer, skipping...\n", s.ExternalIP, s.Args.Port) return nil } - k := peerKey(msg) - newServer := &FederatedServer{ - Address: msg.Address, - Port: msg.Port, - Ts: time.Now(), - } + k := peerKey(newPeer) - log.Printf("%s:%s adding peer %+v\n", s.ExternalIP, s.Args.Port, msg) - if oldServer, loaded := s.PeerServersLoadOrStore(newServer); !loaded { + log.Printf("%s:%s adding peer %+v\n", s.ExternalIP, s.Args.Port, newPeer) + if oldServer, loaded := s.PeerServersLoadOrStore(newPeer); !loaded { if ping { - _, err := s.helloPeer(newServer) + _, err := s.helloPeer(newPeer) if err != nil { s.PeerServersMut.Lock() delete(s.PeerServers, k) @@ -374,11 +367,11 @@ func (s *Server) addPeer(msg *pb.ServerMessage, ping bool, subscribe bool) error s.incNumPeers() metrics.PeersKnown.Inc() s.writePeers() - s.notifyPeerSubs(newServer) + s.notifyPeerSubs(newPeer) // Subscribe to all our peers for now if subscribe { - err := s.subscribeToPeer(newServer) + err := s.subscribeToPeer(newPeer) if err != nil { return err } @@ -389,11 +382,16 @@ func (s *Server) addPeer(msg *pb.ServerMessage, ping bool, subscribe bool) error return nil } -// mergeFederatedServers is an internal convenience function to add a list of +// mergePeers is an internal convenience function to add a list of // peers. -func (s *Server) mergeFederatedServers(servers []*pb.ServerMessage) { +func (s *Server) mergePeers(servers []*pb.ServerMessage) { for _, srvMsg := range servers { - err := s.addPeer(srvMsg, false, true) + newPeer := &Peer{ + Address: srvMsg.Address, + Port: srvMsg.Port, + Ts: time.Now(), + } + err := s.addPeer(newPeer, false, true) // This shouldn't happen because we're not pinging them. if err != nil { log.Println(err) diff --git a/server/federation_test.go b/server/federation_test.go index ed29dd2..33963bb 100644 --- a/server/federation_test.go +++ b/server/federation_test.go @@ -93,21 +93,21 @@ func TestAddPeer(t *testing.T) { metrics.PeersKnown.Set(0) for i := 0; i < 10; i++ { - var msg *pb.ServerMessage + var peer *Peer if strings.Contains(tt.name, "1 unique") { - msg = &pb.ServerMessage{ + peer = &Peer{ Address: "1.1.1.1", Port: "50051", } } else { x := i + 1 - msg = &pb.ServerMessage{ + peer = &Peer{ Address: fmt.Sprintf("%d.%d.%d.%d", x, x, x, x), Port: "50051", } } //log.Printf("Adding peer %+v\n", msg) - err := server.addPeer(msg, false, false) + err := server.addPeer(peer, false, false) if err != nil { log.Println(err) } @@ -151,21 +151,21 @@ func TestPeerWriter(t *testing.T) { server.ExternalIP = net.IPv4(0, 0, 0, 0) for i := 0; i < 10; i++ { - var msg *pb.ServerMessage + var peer *Peer if strings.Contains(tt.name, "1 unique") { - msg = &pb.ServerMessage{ + peer = &Peer{ Address: "1.1.1.1", Port: "50051", } } else { x := i + 1 - msg = &pb.ServerMessage{ + peer = &Peer{ Address: fmt.Sprintf("%d.%d.%d.%d", x, x, x, x), Port: "50051", } } - //log.Printf("Adding peer %+v\n", msg) - err := server.addPeer(msg, false, false) + //log.Printf("Adding peer %+v\n", peer) + err := server.addPeer(peer, false, false) if err != nil { log.Println(err) } @@ -449,12 +449,12 @@ func TestUDPServer(t *testing.T) { go server2.Run() metrics.PeersKnown.Set(0) - msg := &pb.ServerMessage{ + peer := &Peer{ Address: "0.0.0.0", Port: "50052", } - err := server.addPeer(msg, true, true) + err := server.addPeer(peer, true, true) if err != nil { log.Println(err) } diff --git a/server/server.go b/server/server.go index 16472ce..fea59c6 100644 --- a/server/server.go +++ b/server/server.go @@ -35,10 +35,10 @@ type Server struct { LastRefreshCheck time.Time RefreshDelta time.Duration NumESRefreshes int64 - PeerServers map[string]*FederatedServer + PeerServers map[string]*Peer PeerServersMut sync.RWMutex NumPeerServers *int64 - PeerSubs map[string]*FederatedServer + PeerSubs map[string]*Peer PeerSubsMut sync.RWMutex NumPeerSubs *int64 ExternalIP net.IP @@ -88,7 +88,7 @@ func getVersion() string { 'blockchain.address.unsubscribe' */ -func (s *Server) PeerSubsLoadOrStore(peer *FederatedServer) (actual *FederatedServer, loaded bool) { +func (s *Server) PeerSubsLoadOrStore(peer *Peer) (actual *Peer, loaded bool) { key := peer.peerKey() s.PeerSubsMut.RLock() if actual, ok := s.PeerSubs[key]; ok { @@ -103,7 +103,7 @@ func (s *Server) PeerSubsLoadOrStore(peer *FederatedServer) (actual *FederatedSe } } -func (s *Server) PeerServersLoadOrStore(peer *FederatedServer) (actual *FederatedServer, loaded bool) { +func (s *Server) PeerServersLoadOrStore(peer *Peer) (actual *Peer, loaded bool) { key := peer.peerKey() s.PeerServersMut.RLock() if actual, ok := s.PeerServers[key]; ok { @@ -195,10 +195,10 @@ func MakeHubServer(ctx context.Context, args *Args) *Server { LastRefreshCheck: time.Now(), RefreshDelta: refreshDelta, NumESRefreshes: 0, - PeerServers: make(map[string]*FederatedServer), + PeerServers: make(map[string]*Peer), PeerServersMut: sync.RWMutex{}, NumPeerServers: numPeers, - PeerSubs: make(map[string]*FederatedServer), + PeerSubs: make(map[string]*Peer), PeerSubsMut: sync.RWMutex{}, NumPeerSubs: numSubs, ExternalIP: net.IPv4(127, 0, 0, 1), @@ -245,21 +245,21 @@ func (s *Server) Hello(ctx context.Context, args *pb.HelloMessage) (*pb.HelloMes metrics.RequestsCount.With(prometheus.Labels{"method": "hello"}).Inc() port := args.Port host := args.Host - server := &FederatedServer{ + newPeer := &Peer{ Address: host, Port: port, Ts: time.Now(), } - log.Println(server) + log.Println(newPeer) - err := s.addPeer(&pb.ServerMessage{Address: host, Port: port}, false, true) + err := s.addPeer(newPeer, false, true) // They just contacted us, so this shouldn't happen if err != nil { log.Println(err) } - s.mergeFederatedServers(args.Servers) + s.mergePeers(args.Servers) s.writePeers() - s.notifyPeerSubs(server) + s.notifyPeerSubs(newPeer) return s.makeHelloMessage(), nil } @@ -269,7 +269,7 @@ func (s *Server) Hello(ctx context.Context, args *pb.HelloMessage) (*pb.HelloMes func (s *Server) PeerSubscribe(ctx context.Context, in *pb.ServerMessage) (*pb.StringValue, error) { metrics.RequestsCount.With(prometheus.Labels{"method": "peer_subscribe"}).Inc() var msg = "Success" - peer := &FederatedServer{ + peer := &Peer{ Address: in.Address, Port: in.Port, Ts: time.Now(), @@ -289,7 +289,12 @@ func (s *Server) PeerSubscribe(ctx context.Context, in *pb.ServerMessage) (*pb.S func (s *Server) AddPeer(ctx context.Context, args *pb.ServerMessage) (*pb.StringValue, error) { metrics.RequestsCount.With(prometheus.Labels{"method": "add_peer"}).Inc() var msg = "Success" - err := s.addPeer(args, true, true) + newPeer := &Peer{ + Address: args.Address, + Port: args.Port, + Ts: time.Now(), + } + err := s.addPeer(newPeer, true, true) if err != nil { log.Println(err) msg = "Failed" diff --git a/server/udp.go b/server/udp.go index 1830977..6e7d454 100644 --- a/server/udp.go +++ b/server/udp.go @@ -17,8 +17,7 @@ const maxBufferSize = 1024 const magic = 1446058291 const protocolVersion = 1 const defaultFlags = 0b00000000 - -var availableFlag = 0b00000001 +const availableFlag = 0b00000001 // SPVPing is a struct for the format of how to ping another hub over udp. // format b'!lB64s' @@ -211,9 +210,6 @@ func UDPPing(ip, port string) (*SPVPong, error) { return nil, errors.Base("Pong decoding failed") } - // myAddr := pong.DecodeAddress() - // country := pong.DecodeCountry() - return pong, nil } diff --git a/server/udp_test.go b/server/udp_test.go index 8b8db8c..1db0566 100644 --- a/server/udp_test.go +++ b/server/udp_test.go @@ -7,7 +7,7 @@ import ( "testing" ) -// TestAddPeer tests the ability to add peers +// TestUDPPing tests UDPPing correctness against prod server. func TestUDPPing(t *testing.T) { args := makeDefaultArgs() args.DisableStartUDP = true From 2a1d6fa7d47385d64f8fc742aa6b91ea61eca4ce Mon Sep 17 00:00:00 2001 From: Jeffrey Picard Date: Fri, 3 Dec 2021 11:52:21 -0500 Subject: [PATCH 12/12] Updates based on code review --- .github/workflows/build-short.yml | 2 +- .github/workflows/build.yml | 2 +- server/federation.go | 23 +++++++++++------------ server/server.go | 18 +++++++++--------- server/udp.go | 3 +++ 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build-short.yml b/.github/workflows/build-short.yml index 08c2726..c064b41 100644 --- a/.github/workflows/build-short.yml +++ b/.github/workflows/build-short.yml @@ -11,4 +11,4 @@ jobs: with: go-version: 1.16.5 - run: go build . - - run: cd server && go test -v -race \ No newline at end of file + - run: go test -v -race ./... \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d1b0dc7..0b407d6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,4 +30,4 @@ jobs: - run: go get github.com/golang/protobuf/protoc-gen-go google.golang.org/grpc/cmd/protoc-gen-go-grpc - run: go build . - run: ./protobuf/build.sh - - run: cd server && go test -v -race + - run: go test -v -race ./... diff --git a/server/federation.go b/server/federation.go index 6348764..288561f 100644 --- a/server/federation.go +++ b/server/federation.go @@ -18,9 +18,9 @@ import ( // Peer holds relevant information about peers that we know about. type Peer struct { - Address string - Port string - Ts time.Time + Address string + Port string + LastSeen time.Time } var ( @@ -68,8 +68,7 @@ func (s *Server) getNumSubs() int64 { return *s.NumPeerSubs } -// getAndSetExternalIp takes the ip and port of a peer running a UDP server and -// pings it, so we can determine our own external IP address. +// getAndSetExternalIp detects the server's external IP and stores it. func (s *Server) getAndSetExternalIp(ip, port string) error { pong, err := UDPPing(ip, port) if err != nil { @@ -146,9 +145,9 @@ retry: } newPeer := &Peer{ - Address: ipPort[0], - Port: ipPort[1], - Ts: time.Now(), + Address: ipPort[0], + Port: ipPort[1], + LastSeen: time.Now(), } log.Printf("pinging peer %+v\n", newPeer) err = s.addPeer(newPeer, true, true) @@ -377,7 +376,7 @@ func (s *Server) addPeer(newPeer *Peer, ping bool, subscribe bool) error { } } } else { - oldServer.Ts = time.Now() + oldServer.LastSeen = time.Now() } return nil } @@ -387,9 +386,9 @@ func (s *Server) addPeer(newPeer *Peer, ping bool, subscribe bool) error { func (s *Server) mergePeers(servers []*pb.ServerMessage) { for _, srvMsg := range servers { newPeer := &Peer{ - Address: srvMsg.Address, - Port: srvMsg.Port, - Ts: time.Now(), + Address: srvMsg.Address, + Port: srvMsg.Port, + LastSeen: time.Now(), } err := s.addPeer(newPeer, false, true) // This shouldn't happen because we're not pinging them. diff --git a/server/server.go b/server/server.go index fea59c6..8efea8d 100644 --- a/server/server.go +++ b/server/server.go @@ -246,9 +246,9 @@ func (s *Server) Hello(ctx context.Context, args *pb.HelloMessage) (*pb.HelloMes port := args.Port host := args.Host newPeer := &Peer{ - Address: host, - Port: port, - Ts: time.Now(), + Address: host, + Port: port, + LastSeen: time.Now(), } log.Println(newPeer) @@ -270,9 +270,9 @@ func (s *Server) PeerSubscribe(ctx context.Context, in *pb.ServerMessage) (*pb.S metrics.RequestsCount.With(prometheus.Labels{"method": "peer_subscribe"}).Inc() var msg = "Success" peer := &Peer{ - Address: in.Address, - Port: in.Port, - Ts: time.Now(), + Address: in.Address, + Port: in.Port, + LastSeen: time.Now(), } if _, loaded := s.PeerSubsLoadOrStore(peer); !loaded { @@ -290,9 +290,9 @@ func (s *Server) AddPeer(ctx context.Context, args *pb.ServerMessage) (*pb.Strin metrics.RequestsCount.With(prometheus.Labels{"method": "add_peer"}).Inc() var msg = "Success" newPeer := &Peer{ - Address: args.Address, - Port: args.Port, - Ts: time.Now(), + Address: args.Address, + Port: args.Port, + LastSeen: time.Now(), } err := s.addPeer(newPeer, true, true) if err != nil { diff --git a/server/udp.go b/server/udp.go index 6e7d454..eef6552 100644 --- a/server/udp.go +++ b/server/udp.go @@ -14,6 +14,9 @@ import ( const maxBufferSize = 1024 // genesis blocktime (which is actually wrong) +// magic constant for the UDPPing protocol. The above comment is taken from +// the python code this was implemented off of. +// https://github.com/lbryio/lbry-sdk/blob/7d49b046d44a4b7067d5dc1d6cd65ff0475c71c8/lbry/wallet/server/udp.py#L12 const magic = 1446058291 const protocolVersion = 1 const defaultFlags = 0b00000000