lnwire: update NodeAnnouncement to handle multiple addresses

This commit modifies address handling in the NodeAnnouncement struct,
switching from net.TCPAddr to []net.Addr. This enables more flexible
address handling with multiple types and multiple addresses for each
node. This commit addresses the first part of issue #131 .
This commit is contained in:
bryanvu 2017-02-17 01:29:23 -08:00 committed by Olaoluwa Osuntokun
parent 65c15c4cb0
commit 9ffac9eae1
16 changed files with 594 additions and 397 deletions

@ -73,4 +73,8 @@ var (
// ErrNodeAliasNotFound is returned when alias for node can't be found.
ErrNodeAliasNotFound = fmt.Errorf("alias for node not found")
// ErrUnknownAddressType is returned when a node's addressType is not
// an expected value.
ErrUnknownAddressType = fmt.Errorf("address type cannot be resolved")
)

@ -114,6 +114,16 @@ type ChannelGraph struct {
// * LRU cache for edges?
}
// addressType specifies the network protocol and version that should be used
// when connecting to a node at a particular address.
type addressType uint8
const (
tcp4Addr addressType = 0
tcp6Addr addressType = 1
onionAddr addressType = 2
)
// ForEachChannel iterates through all the channel edges stored within the
// graph and invokes the passed callback for each edge. The callback takes two
// edges as since this is a directed graph, both the in/out edges are visited.
@ -801,7 +811,7 @@ type LightningNode struct {
LastUpdate time.Time
// Address is the TCP address this node is reachable over.
Address *net.TCPAddr
Addresses []net.Addr
// PubKey is the node's long-term identity public key. This key will be
// used to authenticated any advertisements/updates sent by the node.
@ -1265,7 +1275,7 @@ func (c *ChannelGraph) NewChannelEdgePolicy() *ChannelEdgePolicy {
func putLightningNode(nodeBucket *bolt.Bucket, aliasBucket *bolt.Bucket, node *LightningNode) error {
var (
scratch [8]byte
scratch [16]byte
b bytes.Buffer
)
@ -1276,13 +1286,8 @@ func putLightningNode(nodeBucket *bolt.Bucket, aliasBucket *bolt.Bucket, node *L
}
updateUnix := uint64(node.LastUpdate.Unix())
byteOrder.PutUint64(scratch[:], updateUnix)
if _, err := b.Write(scratch[:]); err != nil {
return err
}
addrString := node.Address.String()
if err := wire.WriteVarString(&b, 0, addrString); err != nil {
byteOrder.PutUint64(scratch[:8], updateUnix)
if _, err := b.Write(scratch[:8]); err != nil {
return err
}
@ -1304,6 +1309,41 @@ func putLightningNode(nodeBucket *bolt.Bucket, aliasBucket *bolt.Bucket, node *L
return err
}
numAddresses := uint16(len(node.Addresses))
byteOrder.PutUint16(scratch[:2], numAddresses)
if _, err := b.Write(scratch[:2]); err != nil {
return err
}
for _, address := range node.Addresses {
if address.Network() == "tcp" {
if address.(*net.TCPAddr).IP.To4() != nil {
scratch[0] = uint8(tcp4Addr)
if _, err := b.Write(scratch[:1]); err != nil {
return err
}
copy(scratch[:4], address.(*net.TCPAddr).IP.To4())
if _, err := b.Write(scratch[:4]); err != nil {
return err
}
} else {
scratch[0] = uint8(tcp6Addr)
if _, err := b.Write(scratch[:1]); err != nil {
return err
}
copy(scratch[:], address.(*net.TCPAddr).IP.To16())
if _, err := b.Write(scratch[:]); err != nil {
return err
}
}
byteOrder.PutUint16(scratch[:2],
uint16(address.(*net.TCPAddr).Port))
if _, err := b.Write(scratch[:2]); err != nil {
return err
}
}
}
return nodeBucket.Put(nodePub, b.Bytes())
}
@ -1321,8 +1361,8 @@ func fetchLightningNode(nodeBucket *bolt.Bucket,
func deserializeLightningNode(r io.Reader) (*LightningNode, error) {
node := &LightningNode{}
var scratch [8]byte
if _, err := r.Read(scratch[:]); err != nil {
return nil, err
}
@ -1330,19 +1370,11 @@ func deserializeLightningNode(r io.Reader) (*LightningNode, error) {
unix := int64(byteOrder.Uint64(scratch[:]))
node.LastUpdate = time.Unix(unix, 0)
addrString, err := wire.ReadVarString(r, 0)
if err != nil {
return nil, err
}
node.Address, err = net.ResolveTCPAddr("tcp", addrString)
if err != nil {
return nil, err
}
var pub [33]byte
if _, err := r.Read(pub[:]); err != nil {
return nil, err
}
var err error
node.PubKey, err = btcec.ParsePubKey(pub[:], btcec.S256())
if err != nil {
return nil, err
@ -1363,6 +1395,51 @@ func deserializeLightningNode(r io.Reader) (*LightningNode, error) {
return nil, err
}
if _, err := r.Read(scratch[:2]); err != nil {
return nil, err
}
numAddresses := int(byteOrder.Uint16(scratch[:2]))
var addresses []net.Addr
for i := 0; i < numAddresses; i++ {
var address net.Addr
if _, err := r.Read(scratch[:1]); err != nil {
return nil, err
}
switch addressType(scratch[0]) {
case tcp4Addr:
addr := &net.TCPAddr{}
var ip [4]byte
if _, err := r.Read(ip[:]); err != nil {
return nil, err
}
addr.IP = (net.IP)(ip[:])
if _, err := r.Read(scratch[:2]); err != nil {
return nil, err
}
addr.Port = int(byteOrder.Uint16(scratch[:2]))
address = addr
case tcp6Addr:
addr := &net.TCPAddr{}
var ip [16]byte
if _, err := r.Read(ip[:]); err != nil {
return nil, err
}
addr.IP = (net.IP)(ip[:])
if _, err := r.Read(scratch[:2]); err != nil {
return nil, err
}
addr.Port = int(byteOrder.Uint16(scratch[:2]))
address = addr
default:
return nil, ErrUnknownAddressType
}
addresses = append(addresses, address)
}
node.Addresses = addresses
return node, nil
}

@ -21,7 +21,9 @@ import (
)
var (
testAddr, _ = net.ResolveTCPAddr("tcp", "10.0.0.1:9000")
testAddr = &net.TCPAddr{IP: (net.IP)([]byte{0xA, 0x0, 0x0, 0x1}),
Port: 9000}
testAddrs = []net.Addr{testAddr}
randSource = prand.NewSource(time.Now().Unix())
randInts = prand.New(randSource)
@ -44,7 +46,7 @@ func createTestVertex(db *DB) (*LightningNode, error) {
pub := priv.PubKey().SerializeCompressed()
return &LightningNode{
LastUpdate: time.Unix(updateTime, 0),
Address: testAddr,
Addresses: testAddrs,
PubKey: priv.PubKey(),
Color: color.RGBA{1, 2, 3, 0},
Alias: "kek" + string(pub[:]),
@ -66,7 +68,7 @@ func TestNodeInsertionAndDeletion(t *testing.T) {
_, testPub := btcec.PrivKeyFromBytes(btcec.S256(), key[:])
node := &LightningNode{
LastUpdate: time.Unix(1232342, 0),
Address: testAddr,
Addresses: testAddrs,
PubKey: testPub,
Color: color.RGBA{1, 2, 3, 0},
Alias: "kek",

@ -55,6 +55,7 @@ It has these top-level messages:
NodeInfoRequest
NodeInfo
LightningNode
NodeAddress
RoutingPolicy
ChannelEdge
ChannelGraphRequest
@ -90,7 +91,7 @@ package lnrpc
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import _ "google.golang.org/genproto/googleapis/api/annotations"
import _ "github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/google/api"
import (
context "golang.org/x/net/context"
@ -384,7 +385,7 @@ func (m *LightningAddress) GetHost() string {
}
type SendManyRequest struct {
AddrToAmount map[string]int64 `protobuf:"bytes,1,rep,name=AddrToAmount" json:"AddrToAmount,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
AddrToAmount map[string]int64 `protobuf:"bytes,1,rep,name=AddrToAmount,json=addrToAmount" json:"AddrToAmount,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
}
func (m *SendManyRequest) Reset() { *m = SendManyRequest{} }
@ -1714,10 +1715,10 @@ func (m *NodeInfo) GetTotalCapacity() int64 {
}
type LightningNode struct {
LastUpdate uint32 `protobuf:"varint,1,opt,name=last_update" json:"last_update,omitempty"`
PubKey string `protobuf:"bytes,2,opt,name=pub_key" json:"pub_key,omitempty"`
Address string `protobuf:"bytes,3,opt,name=address" json:"address,omitempty"`
Alias string `protobuf:"bytes,4,opt,name=alias" json:"alias,omitempty"`
LastUpdate uint32 `protobuf:"varint,1,opt,name=last_update" json:"last_update,omitempty"`
PubKey string `protobuf:"bytes,2,opt,name=pub_key" json:"pub_key,omitempty"`
Alias string `protobuf:"bytes,3,opt,name=alias" json:"alias,omitempty"`
Addresses []*NodeAddress `protobuf:"bytes,4,rep,name=addresses" json:"addresses,omitempty"`
}
func (m *LightningNode) Reset() { *m = LightningNode{} }
@ -1739,16 +1740,40 @@ func (m *LightningNode) GetPubKey() string {
return ""
}
func (m *LightningNode) GetAddress() string {
func (m *LightningNode) GetAlias() string {
if m != nil {
return m.Address
return m.Alias
}
return ""
}
func (m *LightningNode) GetAlias() string {
func (m *LightningNode) GetAddresses() []*NodeAddress {
if m != nil {
return m.Alias
return m.Addresses
}
return nil
}
type NodeAddress struct {
Network string `protobuf:"bytes,1,opt,name=network" json:"network,omitempty"`
Addr string `protobuf:"bytes,2,opt,name=addr" json:"addr,omitempty"`
}
func (m *NodeAddress) Reset() { *m = NodeAddress{} }
func (m *NodeAddress) String() string { return proto.CompactTextString(m) }
func (*NodeAddress) ProtoMessage() {}
func (*NodeAddress) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{46} }
func (m *NodeAddress) GetNetwork() string {
if m != nil {
return m.Network
}
return ""
}
func (m *NodeAddress) GetAddr() string {
if m != nil {
return m.Addr
}
return ""
}
@ -1763,7 +1788,7 @@ type RoutingPolicy struct {
func (m *RoutingPolicy) Reset() { *m = RoutingPolicy{} }
func (m *RoutingPolicy) String() string { return proto.CompactTextString(m) }
func (*RoutingPolicy) ProtoMessage() {}
func (*RoutingPolicy) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{46} }
func (*RoutingPolicy) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{47} }
func (m *RoutingPolicy) GetTimeLockDelta() uint32 {
if m != nil {
@ -1807,7 +1832,7 @@ type ChannelEdge struct {
func (m *ChannelEdge) Reset() { *m = ChannelEdge{} }
func (m *ChannelEdge) String() string { return proto.CompactTextString(m) }
func (*ChannelEdge) ProtoMessage() {}
func (*ChannelEdge) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{47} }
func (*ChannelEdge) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{48} }
func (m *ChannelEdge) GetChannelId() uint64 {
if m != nil {
@ -1871,7 +1896,7 @@ type ChannelGraphRequest struct {
func (m *ChannelGraphRequest) Reset() { *m = ChannelGraphRequest{} }
func (m *ChannelGraphRequest) String() string { return proto.CompactTextString(m) }
func (*ChannelGraphRequest) ProtoMessage() {}
func (*ChannelGraphRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{48} }
func (*ChannelGraphRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{49} }
type ChannelGraph struct {
Nodes []*LightningNode `protobuf:"bytes,1,rep,name=nodes" json:"nodes,omitempty"`
@ -1881,7 +1906,7 @@ type ChannelGraph struct {
func (m *ChannelGraph) Reset() { *m = ChannelGraph{} }
func (m *ChannelGraph) String() string { return proto.CompactTextString(m) }
func (*ChannelGraph) ProtoMessage() {}
func (*ChannelGraph) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{49} }
func (*ChannelGraph) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{50} }
func (m *ChannelGraph) GetNodes() []*LightningNode {
if m != nil {
@ -1904,7 +1929,7 @@ type ChanInfoRequest struct {
func (m *ChanInfoRequest) Reset() { *m = ChanInfoRequest{} }
func (m *ChanInfoRequest) String() string { return proto.CompactTextString(m) }
func (*ChanInfoRequest) ProtoMessage() {}
func (*ChanInfoRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{50} }
func (*ChanInfoRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{51} }
func (m *ChanInfoRequest) GetChanId() uint64 {
if m != nil {
@ -1919,7 +1944,7 @@ type NetworkInfoRequest struct {
func (m *NetworkInfoRequest) Reset() { *m = NetworkInfoRequest{} }
func (m *NetworkInfoRequest) String() string { return proto.CompactTextString(m) }
func (*NetworkInfoRequest) ProtoMessage() {}
func (*NetworkInfoRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{51} }
func (*NetworkInfoRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{52} }
type NetworkInfo struct {
GraphDiameter uint32 `protobuf:"varint,1,opt,name=graph_diameter" json:"graph_diameter,omitempty"`
@ -1936,7 +1961,7 @@ type NetworkInfo struct {
func (m *NetworkInfo) Reset() { *m = NetworkInfo{} }
func (m *NetworkInfo) String() string { return proto.CompactTextString(m) }
func (*NetworkInfo) ProtoMessage() {}
func (*NetworkInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{52} }
func (*NetworkInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{53} }
func (m *NetworkInfo) GetGraphDiameter() uint32 {
if m != nil {
@ -2007,7 +2032,7 @@ type GraphTopologySubscription struct {
func (m *GraphTopologySubscription) Reset() { *m = GraphTopologySubscription{} }
func (m *GraphTopologySubscription) String() string { return proto.CompactTextString(m) }
func (*GraphTopologySubscription) ProtoMessage() {}
func (*GraphTopologySubscription) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{53} }
func (*GraphTopologySubscription) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{54} }
type GraphTopologyUpdate struct {
NodeUpdates []*NodeUpdate `protobuf:"bytes,1,rep,name=node_updates,json=nodeUpdates" json:"node_updates,omitempty"`
@ -2018,7 +2043,7 @@ type GraphTopologyUpdate struct {
func (m *GraphTopologyUpdate) Reset() { *m = GraphTopologyUpdate{} }
func (m *GraphTopologyUpdate) String() string { return proto.CompactTextString(m) }
func (*GraphTopologyUpdate) ProtoMessage() {}
func (*GraphTopologyUpdate) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{54} }
func (*GraphTopologyUpdate) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{55} }
func (m *GraphTopologyUpdate) GetNodeUpdates() []*NodeUpdate {
if m != nil {
@ -2051,7 +2076,7 @@ type NodeUpdate struct {
func (m *NodeUpdate) Reset() { *m = NodeUpdate{} }
func (m *NodeUpdate) String() string { return proto.CompactTextString(m) }
func (*NodeUpdate) ProtoMessage() {}
func (*NodeUpdate) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{55} }
func (*NodeUpdate) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{56} }
func (m *NodeUpdate) GetAddresses() []string {
if m != nil {
@ -2093,7 +2118,7 @@ type ChannelEdgeUpdate struct {
func (m *ChannelEdgeUpdate) Reset() { *m = ChannelEdgeUpdate{} }
func (m *ChannelEdgeUpdate) String() string { return proto.CompactTextString(m) }
func (*ChannelEdgeUpdate) ProtoMessage() {}
func (*ChannelEdgeUpdate) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{56} }
func (*ChannelEdgeUpdate) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{57} }
func (m *ChannelEdgeUpdate) GetChanId() uint64 {
if m != nil {
@ -2147,7 +2172,7 @@ type ClosedChannelUpdate struct {
func (m *ClosedChannelUpdate) Reset() { *m = ClosedChannelUpdate{} }
func (m *ClosedChannelUpdate) String() string { return proto.CompactTextString(m) }
func (*ClosedChannelUpdate) ProtoMessage() {}
func (*ClosedChannelUpdate) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{57} }
func (*ClosedChannelUpdate) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{58} }
func (m *ClosedChannelUpdate) GetChanId() uint64 {
if m != nil {
@ -2184,7 +2209,7 @@ type SetAliasRequest struct {
func (m *SetAliasRequest) Reset() { *m = SetAliasRequest{} }
func (m *SetAliasRequest) String() string { return proto.CompactTextString(m) }
func (*SetAliasRequest) ProtoMessage() {}
func (*SetAliasRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{58} }
func (*SetAliasRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{59} }
func (m *SetAliasRequest) GetNewAlias() string {
if m != nil {
@ -2199,7 +2224,7 @@ type SetAliasResponse struct {
func (m *SetAliasResponse) Reset() { *m = SetAliasResponse{} }
func (m *SetAliasResponse) String() string { return proto.CompactTextString(m) }
func (*SetAliasResponse) ProtoMessage() {}
func (*SetAliasResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{59} }
func (*SetAliasResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{60} }
type Invoice struct {
Memo string `protobuf:"bytes,1,opt,name=memo" json:"memo,omitempty"`
@ -2216,7 +2241,7 @@ type Invoice struct {
func (m *Invoice) Reset() { *m = Invoice{} }
func (m *Invoice) String() string { return proto.CompactTextString(m) }
func (*Invoice) ProtoMessage() {}
func (*Invoice) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{60} }
func (*Invoice) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{61} }
func (m *Invoice) GetMemo() string {
if m != nil {
@ -2289,7 +2314,7 @@ type AddInvoiceResponse struct {
func (m *AddInvoiceResponse) Reset() { *m = AddInvoiceResponse{} }
func (m *AddInvoiceResponse) String() string { return proto.CompactTextString(m) }
func (*AddInvoiceResponse) ProtoMessage() {}
func (*AddInvoiceResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{61} }
func (*AddInvoiceResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{62} }
func (m *AddInvoiceResponse) GetRHash() []byte {
if m != nil {
@ -2313,7 +2338,7 @@ type PaymentHash struct {
func (m *PaymentHash) Reset() { *m = PaymentHash{} }
func (m *PaymentHash) String() string { return proto.CompactTextString(m) }
func (*PaymentHash) ProtoMessage() {}
func (*PaymentHash) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{62} }
func (*PaymentHash) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{63} }
func (m *PaymentHash) GetRHashStr() string {
if m != nil {
@ -2336,7 +2361,7 @@ type ListInvoiceRequest struct {
func (m *ListInvoiceRequest) Reset() { *m = ListInvoiceRequest{} }
func (m *ListInvoiceRequest) String() string { return proto.CompactTextString(m) }
func (*ListInvoiceRequest) ProtoMessage() {}
func (*ListInvoiceRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{63} }
func (*ListInvoiceRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{64} }
func (m *ListInvoiceRequest) GetPendingOnly() bool {
if m != nil {
@ -2352,7 +2377,7 @@ type ListInvoiceResponse struct {
func (m *ListInvoiceResponse) Reset() { *m = ListInvoiceResponse{} }
func (m *ListInvoiceResponse) String() string { return proto.CompactTextString(m) }
func (*ListInvoiceResponse) ProtoMessage() {}
func (*ListInvoiceResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{64} }
func (*ListInvoiceResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{65} }
func (m *ListInvoiceResponse) GetInvoices() []*Invoice {
if m != nil {
@ -2367,7 +2392,7 @@ type InvoiceSubscription struct {
func (m *InvoiceSubscription) Reset() { *m = InvoiceSubscription{} }
func (m *InvoiceSubscription) String() string { return proto.CompactTextString(m) }
func (*InvoiceSubscription) ProtoMessage() {}
func (*InvoiceSubscription) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{65} }
func (*InvoiceSubscription) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{66} }
type Payment struct {
PaymentHash string `protobuf:"bytes,1,opt,name=payment_hash" json:"payment_hash,omitempty"`
@ -2380,7 +2405,7 @@ type Payment struct {
func (m *Payment) Reset() { *m = Payment{} }
func (m *Payment) String() string { return proto.CompactTextString(m) }
func (*Payment) ProtoMessage() {}
func (*Payment) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{66} }
func (*Payment) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{67} }
func (m *Payment) GetPaymentHash() string {
if m != nil {
@ -2423,7 +2448,7 @@ type ListPaymentsRequest struct {
func (m *ListPaymentsRequest) Reset() { *m = ListPaymentsRequest{} }
func (m *ListPaymentsRequest) String() string { return proto.CompactTextString(m) }
func (*ListPaymentsRequest) ProtoMessage() {}
func (*ListPaymentsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{67} }
func (*ListPaymentsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{68} }
type ListPaymentsResponse struct {
Payments []*Payment `protobuf:"bytes,1,rep,name=payments" json:"payments,omitempty"`
@ -2432,7 +2457,7 @@ type ListPaymentsResponse struct {
func (m *ListPaymentsResponse) Reset() { *m = ListPaymentsResponse{} }
func (m *ListPaymentsResponse) String() string { return proto.CompactTextString(m) }
func (*ListPaymentsResponse) ProtoMessage() {}
func (*ListPaymentsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{68} }
func (*ListPaymentsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{69} }
func (m *ListPaymentsResponse) GetPayments() []*Payment {
if m != nil {
@ -2447,7 +2472,7 @@ type DeleteAllPaymentsRequest struct {
func (m *DeleteAllPaymentsRequest) Reset() { *m = DeleteAllPaymentsRequest{} }
func (m *DeleteAllPaymentsRequest) String() string { return proto.CompactTextString(m) }
func (*DeleteAllPaymentsRequest) ProtoMessage() {}
func (*DeleteAllPaymentsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{69} }
func (*DeleteAllPaymentsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{70} }
type DeleteAllPaymentsResponse struct {
}
@ -2455,7 +2480,7 @@ type DeleteAllPaymentsResponse struct {
func (m *DeleteAllPaymentsResponse) Reset() { *m = DeleteAllPaymentsResponse{} }
func (m *DeleteAllPaymentsResponse) String() string { return proto.CompactTextString(m) }
func (*DeleteAllPaymentsResponse) ProtoMessage() {}
func (*DeleteAllPaymentsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{70} }
func (*DeleteAllPaymentsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{71} }
type DebugLevelRequest struct {
Show bool `protobuf:"varint,1,opt,name=show" json:"show,omitempty"`
@ -2465,7 +2490,7 @@ type DebugLevelRequest struct {
func (m *DebugLevelRequest) Reset() { *m = DebugLevelRequest{} }
func (m *DebugLevelRequest) String() string { return proto.CompactTextString(m) }
func (*DebugLevelRequest) ProtoMessage() {}
func (*DebugLevelRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{71} }
func (*DebugLevelRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{72} }
func (m *DebugLevelRequest) GetShow() bool {
if m != nil {
@ -2488,7 +2513,7 @@ type DebugLevelResponse struct {
func (m *DebugLevelResponse) Reset() { *m = DebugLevelResponse{} }
func (m *DebugLevelResponse) String() string { return proto.CompactTextString(m) }
func (*DebugLevelResponse) ProtoMessage() {}
func (*DebugLevelResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{72} }
func (*DebugLevelResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{73} }
func (m *DebugLevelResponse) GetSubSystems() string {
if m != nil {
@ -2504,7 +2529,7 @@ type PayReqString struct {
func (m *PayReqString) Reset() { *m = PayReqString{} }
func (m *PayReqString) String() string { return proto.CompactTextString(m) }
func (*PayReqString) ProtoMessage() {}
func (*PayReqString) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{73} }
func (*PayReqString) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{74} }
func (m *PayReqString) GetPayReq() string {
if m != nil {
@ -2522,7 +2547,7 @@ type PayReq struct {
func (m *PayReq) Reset() { *m = PayReq{} }
func (m *PayReq) String() string { return proto.CompactTextString(m) }
func (*PayReq) ProtoMessage() {}
func (*PayReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{74} }
func (*PayReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{75} }
func (m *PayReq) GetDestination() string {
if m != nil {
@ -2593,6 +2618,7 @@ func init() {
proto.RegisterType((*NodeInfoRequest)(nil), "lnrpc.NodeInfoRequest")
proto.RegisterType((*NodeInfo)(nil), "lnrpc.NodeInfo")
proto.RegisterType((*LightningNode)(nil), "lnrpc.LightningNode")
proto.RegisterType((*NodeAddress)(nil), "lnrpc.NodeAddress")
proto.RegisterType((*RoutingPolicy)(nil), "lnrpc.RoutingPolicy")
proto.RegisterType((*ChannelEdge)(nil), "lnrpc.ChannelEdge")
proto.RegisterType((*ChannelGraphRequest)(nil), "lnrpc.ChannelGraphRequest")
@ -3927,252 +3953,254 @@ var _Lightning_serviceDesc = grpc.ServiceDesc{
func init() { proto.RegisterFile("rpc.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 3937 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x5a, 0xcd, 0x6f, 0x1c, 0xc9,
0x75, 0x57, 0x0f, 0x87, 0xe4, 0xcc, 0x9b, 0x19, 0x7e, 0x14, 0x29, 0x72, 0x34, 0xd2, 0xae, 0xb5,
0x65, 0x61, 0xc5, 0x30, 0x0b, 0x52, 0xcb, 0x04, 0x1b, 0x79, 0x37, 0xc9, 0x82, 0x2b, 0xd1, 0xa2,
0x60, 0x9a, 0xa2, 0x9b, 0xda, 0x95, 0x63, 0x23, 0x98, 0x34, 0xa7, 0x8b, 0xc3, 0xb6, 0x7a, 0xba,
0x7b, 0xbb, 0x6b, 0x48, 0x8d, 0x05, 0x22, 0x81, 0xe3, 0x5b, 0x12, 0x18, 0x41, 0x80, 0x1c, 0x8d,
// 3972 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xa4, 0x5a, 0xcd, 0x6f, 0x1c, 0xc9,
0x75, 0x57, 0xcf, 0x0c, 0xc9, 0x99, 0x37, 0x33, 0xfc, 0x28, 0x52, 0xe4, 0x68, 0xa8, 0x5d, 0x6b,
0xcb, 0xc2, 0x8a, 0x61, 0x16, 0xa4, 0x96, 0x09, 0x36, 0xf2, 0x2a, 0xc9, 0x82, 0x2b, 0xd1, 0xa2,
0x60, 0x9a, 0xa2, 0x9b, 0xda, 0x95, 0x63, 0x23, 0x98, 0x34, 0x67, 0x8a, 0xc3, 0xb6, 0x7a, 0xba,
0x7b, 0xbb, 0x6b, 0x48, 0x8d, 0x05, 0x22, 0x81, 0xe3, 0x5b, 0x12, 0x18, 0x81, 0x81, 0x1c, 0x8d,
0x00, 0x39, 0xe7, 0x92, 0x6b, 0xfe, 0x86, 0x00, 0x06, 0x7c, 0xca, 0x21, 0xb7, 0x20, 0xf7, 0xdc,
0x73, 0x08, 0x5e, 0x7d, 0x74, 0x57, 0x75, 0x37, 0x77, 0x15, 0xf8, 0x34, 0x53, 0xbf, 0x7a, 0xf5,
0xaa, 0xea, 0xd5, 0x7b, 0xaf, 0xde, 0x7b, 0xd5, 0xd0, 0x4e, 0x93, 0xd1, 0x4e, 0x92, 0xc6, 0x3c,
0x26, 0xf3, 0x61, 0x94, 0x26, 0xa3, 0xc1, 0xbd, 0x71, 0x1c, 0x8f, 0x43, 0xb6, 0xeb, 0x25, 0xc1,
0xae, 0x17, 0x45, 0x31, 0xf7, 0x78, 0x10, 0x47, 0x99, 0x24, 0xa2, 0xff, 0xe3, 0x40, 0xe7, 0x65,
0xea, 0x45, 0x99, 0x37, 0x42, 0x98, 0xf4, 0x61, 0x91, 0xbf, 0x19, 0x5e, 0x78, 0xd9, 0x45, 0xdf,
0xb9, 0xef, 0x6c, 0xb5, 0x5d, 0xdd, 0x24, 0x1b, 0xb0, 0xe0, 0x4d, 0xe2, 0x69, 0xc4, 0xfb, 0x8d,
0xfb, 0xce, 0xd6, 0x9c, 0xab, 0x5a, 0xe4, 0x23, 0x58, 0x8d, 0xa6, 0x93, 0xe1, 0x28, 0x8e, 0xce,
0x83, 0x74, 0x22, 0x99, 0xf7, 0xe7, 0xee, 0x3b, 0x5b, 0xf3, 0x6e, 0xb5, 0x83, 0xbc, 0x0f, 0x70,
0x16, 0xc6, 0xa3, 0xd7, 0x72, 0x8a, 0xa6, 0x98, 0xc2, 0x40, 0x08, 0x85, 0xae, 0x6a, 0xb1, 0x60,
0x7c, 0xc1, 0xfb, 0xf3, 0x82, 0x91, 0x85, 0x21, 0x0f, 0x1e, 0x4c, 0xd8, 0x30, 0xe3, 0xde, 0x24,
0xe9, 0x2f, 0x88, 0xd5, 0x18, 0x88, 0xe8, 0x8f, 0xb9, 0x17, 0x0e, 0xcf, 0x19, 0xcb, 0xfa, 0x8b,
0xaa, 0x3f, 0x47, 0x68, 0x1f, 0x36, 0x9e, 0x31, 0x6e, 0xec, 0x3a, 0x73, 0xd9, 0xd7, 0x53, 0x96,
0x71, 0x7a, 0x04, 0xc4, 0x80, 0x9f, 0x32, 0xee, 0x05, 0x61, 0x46, 0x3e, 0x81, 0x2e, 0x37, 0x88,
0xfb, 0xce, 0xfd, 0xb9, 0xad, 0xce, 0x1e, 0xd9, 0x11, 0xf2, 0xdd, 0x31, 0x06, 0xb8, 0x16, 0x1d,
0xfd, 0x8d, 0x03, 0x9d, 0x53, 0x16, 0xf9, 0x8a, 0x3b, 0x21, 0xd0, 0xf4, 0x59, 0xc6, 0x85, 0x60,
0xbb, 0xae, 0xf8, 0x4f, 0xbe, 0x03, 0x1d, 0xfc, 0x1d, 0x66, 0x3c, 0x0d, 0xa2, 0xb1, 0x10, 0x6d,
0xdb, 0x05, 0x84, 0x4e, 0x05, 0x42, 0x56, 0x60, 0xce, 0x9b, 0x70, 0x21, 0xd0, 0x39, 0x17, 0xff,
0x92, 0x0f, 0xa0, 0x9b, 0x78, 0xb3, 0x09, 0x8b, 0x78, 0x21, 0xc4, 0xae, 0xdb, 0x51, 0xd8, 0x21,
0x4a, 0x71, 0x07, 0xd6, 0x4c, 0x12, 0xcd, 0x7d, 0x5e, 0x70, 0x5f, 0x35, 0x28, 0xd5, 0x24, 0x0f,
0x61, 0x59, 0xd3, 0xa7, 0x72, 0xb1, 0x42, 0xac, 0x6d, 0x77, 0x49, 0xc1, 0x5a, 0x40, 0x11, 0x74,
0xe5, 0x8e, 0xb2, 0x24, 0x8e, 0x32, 0x46, 0xb6, 0x61, 0x45, 0x0f, 0x4c, 0x52, 0x16, 0x4c, 0xbc,
0x31, 0x53, 0xdb, 0xab, 0xe0, 0x64, 0x0f, 0x7a, 0xf9, 0x24, 0xf1, 0x94, 0x33, 0xb1, 0xd9, 0xce,
0x5e, 0x57, 0xc9, 0xd1, 0x45, 0xcc, 0xb5, 0x49, 0xe8, 0x2f, 0x1c, 0xe8, 0x3e, 0xb9, 0xf0, 0xa2,
0x88, 0x85, 0x27, 0x71, 0x10, 0x71, 0xd4, 0x8f, 0xf3, 0x69, 0xe4, 0x07, 0xd1, 0x78, 0xc8, 0xdf,
0x04, 0xbe, 0x9a, 0xcc, 0xc2, 0x70, 0x51, 0x66, 0x1b, 0x77, 0xaf, 0x04, 0x5b, 0xc1, 0x91, 0x5f,
0x3c, 0xe5, 0xc9, 0x94, 0x0f, 0x83, 0xc8, 0x67, 0x6f, 0x84, 0x9c, 0x7b, 0xae, 0x85, 0xd1, 0x3f,
0x85, 0x95, 0x23, 0x54, 0xbc, 0x28, 0x88, 0xc6, 0xfb, 0xbe, 0x9f, 0xb2, 0x2c, 0x43, 0x6b, 0x48,
0xa6, 0x67, 0xaf, 0xd9, 0x4c, 0x99, 0x89, 0x6a, 0xe1, 0x19, 0x5f, 0xc4, 0x19, 0x57, 0xf3, 0x89,
0xff, 0xf4, 0x9f, 0x1c, 0x58, 0x46, 0xa9, 0xfd, 0xd0, 0x8b, 0x66, 0x5a, 0x17, 0x8e, 0xa0, 0x8b,
0xac, 0x5e, 0xc6, 0xfb, 0xd2, 0xa6, 0xa4, 0x4e, 0x6d, 0x29, 0x59, 0x94, 0xa8, 0x77, 0x4c, 0xd2,
0x83, 0x88, 0xa7, 0x33, 0xd7, 0x1a, 0x3d, 0xf8, 0x1c, 0x56, 0x2b, 0x24, 0xa8, 0x39, 0xc5, 0xfa,
0xf0, 0x2f, 0x59, 0x87, 0xf9, 0x4b, 0x2f, 0x9c, 0x32, 0x65, 0xc1, 0xb2, 0xf1, 0x69, 0xe3, 0xb1,
0x43, 0x3f, 0x84, 0x95, 0x62, 0x4e, 0x75, 0xb6, 0x04, 0x9a, 0xb9, 0x88, 0xdb, 0xae, 0xf8, 0x8f,
0xa2, 0x40, 0xba, 0x27, 0x71, 0x90, 0x1b, 0x0d, 0xd2, 0x79, 0xbe, 0x9f, 0x6a, 0x3a, 0xfc, 0x7f,
0x93, 0xb3, 0xa0, 0x0f, 0x61, 0xd5, 0x18, 0xff, 0x0d, 0x13, 0xfd, 0xda, 0x81, 0xd5, 0x63, 0x76,
0xa5, 0xc4, 0xad, 0xa7, 0x7a, 0x0c, 0x4d, 0x3e, 0x4b, 0xa4, 0x8a, 0x2d, 0xed, 0x3d, 0x50, 0xd2,
0xaa, 0xd0, 0xed, 0xa8, 0xe6, 0xcb, 0x59, 0xc2, 0x5c, 0x31, 0x82, 0xbe, 0x80, 0x8e, 0x01, 0x92,
0x4d, 0x58, 0x7b, 0xf5, 0xfc, 0xe5, 0xf1, 0xc1, 0xe9, 0xe9, 0xf0, 0xe4, 0xcb, 0x2f, 0x7e, 0x70,
0xf0, 0x67, 0xc3, 0xc3, 0xfd, 0xd3, 0xc3, 0x95, 0x5b, 0x64, 0x03, 0xc8, 0xf1, 0xc1, 0xe9, 0xcb,
0x83, 0xa7, 0x16, 0xee, 0x90, 0x65, 0xe8, 0x98, 0x40, 0x83, 0x0e, 0xa0, 0x7f, 0xcc, 0xae, 0x5e,
0x05, 0x3c, 0x62, 0x59, 0x66, 0x4f, 0x4f, 0x77, 0x80, 0x98, 0x6b, 0x52, 0xdb, 0xec, 0xc3, 0xa2,
0x27, 0x21, 0xed, 0x5a, 0x55, 0x93, 0x7e, 0x09, 0xe4, 0x49, 0x1c, 0x45, 0x6c, 0xc4, 0x4f, 0x18,
0x4b, 0xf5, 0x66, 0x7f, 0xdf, 0x90, 0x6b, 0x67, 0x6f, 0x53, 0x6d, 0xb6, 0xac, 0x89, 0x4a, 0xe0,
0x04, 0x9a, 0x09, 0x4b, 0x27, 0x42, 0xdc, 0x2d, 0x57, 0xfc, 0xa7, 0xbb, 0xb0, 0x66, 0xb1, 0x2d,
0xd6, 0x91, 0x30, 0x96, 0x0e, 0x95, 0xc4, 0xe7, 0x5d, 0xdd, 0xa4, 0xff, 0xea, 0x40, 0xf3, 0xf0,
0xe5, 0xd1, 0x13, 0x32, 0x80, 0x56, 0x10, 0x8d, 0xe2, 0x09, 0x3a, 0x0d, 0x47, 0x70, 0xcc, 0xdb,
0x37, 0xde, 0x03, 0xf7, 0xa0, 0x2d, 0x7c, 0x0d, 0x7a, 0x6a, 0x61, 0x46, 0x5d, 0xb7, 0x00, 0xf0,
0x96, 0x60, 0x6f, 0x92, 0x20, 0x15, 0xd7, 0x80, 0x76, 0xee, 0x4d, 0x61, 0x6c, 0xd5, 0x0e, 0xb4,
0xe0, 0x94, 0x5d, 0xc6, 0x23, 0x09, 0xfa, 0x2c, 0xf4, 0x66, 0xc2, 0x79, 0xf5, 0xdc, 0x0a, 0x4e,
0xff, 0x7b, 0x0e, 0x7a, 0xfb, 0x23, 0x1e, 0x5c, 0x32, 0xe5, 0x28, 0xc4, 0x0a, 0x05, 0xa0, 0xd6,
0xae, 0x5a, 0xe4, 0x01, 0xf4, 0x52, 0x36, 0x89, 0x39, 0x1b, 0x2a, 0xd3, 0x95, 0x46, 0x6a, 0x83,
0x48, 0x35, 0x92, 0x8c, 0x86, 0x09, 0xba, 0x1c, 0xb1, 0x97, 0xb6, 0x6b, 0x83, 0x28, 0x44, 0x04,
0x50, 0x88, 0xb8, 0x8b, 0xa6, 0xab, 0x9b, 0x28, 0xbb, 0x91, 0x97, 0x78, 0xa3, 0x80, 0xcb, 0x35,
0xcf, 0xb9, 0x79, 0x1b, 0x79, 0x87, 0xf1, 0xc8, 0x0b, 0x87, 0x67, 0x5e, 0xe8, 0x45, 0x23, 0xa6,
0x2e, 0x2f, 0x1b, 0x24, 0x1f, 0xc2, 0x92, 0x5a, 0x92, 0x26, 0x93, 0x77, 0x58, 0x09, 0x45, 0x99,
0x4e, 0xa3, 0x8c, 0x71, 0x1e, 0x32, 0x3f, 0x27, 0x6d, 0x09, 0xd2, 0x6a, 0x07, 0x79, 0x04, 0x6b,
0xf2, 0x0e, 0xcc, 0x3c, 0x1e, 0x67, 0x17, 0x41, 0x36, 0xcc, 0x58, 0xc4, 0xfb, 0x6d, 0x41, 0x5f,
0xd7, 0x45, 0x1e, 0xc3, 0x66, 0x09, 0x4e, 0xd9, 0x88, 0x05, 0x97, 0xcc, 0xef, 0x83, 0x18, 0x75,
0x53, 0x37, 0xb9, 0x0f, 0x1d, 0xbc, 0xfa, 0xa7, 0x89, 0xef, 0x71, 0x96, 0xf5, 0x3b, 0x42, 0x42,
0x26, 0x44, 0x3e, 0x86, 0x5e, 0xc2, 0xa4, 0x2f, 0xbe, 0xe0, 0xe1, 0x28, 0xeb, 0x77, 0x85, 0x03,
0xec, 0x28, 0x2d, 0x47, 0x2d, 0x74, 0x6d, 0x0a, 0x7a, 0x1b, 0xd6, 0x8e, 0x82, 0x8c, 0xab, 0x53,
0xce, 0x8d, 0xed, 0x10, 0xd6, 0x6d, 0x58, 0xa9, 0xf9, 0x23, 0x68, 0xa9, 0x23, 0xc3, 0x05, 0x20,
0xf3, 0x75, 0xc5, 0xdc, 0xd2, 0x16, 0x37, 0xa7, 0xa2, 0xbf, 0x6c, 0x40, 0x13, 0x2d, 0x45, 0x58,
0xc8, 0xf4, 0x6c, 0x58, 0x78, 0x4f, 0xdd, 0x34, 0x6d, 0xa7, 0x61, 0xd9, 0x8e, 0x69, 0xdd, 0x73,
0x96, 0x75, 0x8b, 0x90, 0x67, 0xc6, 0x99, 0x92, 0xb7, 0xd4, 0x16, 0x03, 0x29, 0xfa, 0x53, 0x36,
0xba, 0x14, 0x2a, 0x93, 0xf7, 0x23, 0x82, 0x0a, 0x95, 0x79, 0x5c, 0x8e, 0x96, 0xfa, 0x92, 0xb7,
0x75, 0x9f, 0x18, 0xb9, 0x58, 0xf4, 0x89, 0x71, 0x7d, 0x58, 0x0c, 0xa2, 0xb3, 0x78, 0x1a, 0xf9,
0x42, 0x29, 0x5a, 0xae, 0x6e, 0xa2, 0xa9, 0x26, 0xe2, 0x16, 0x0c, 0x26, 0x4c, 0x29, 0x40, 0x01,
0x50, 0x82, 0xd7, 0x5d, 0x26, 0x7c, 0x46, 0x2e, 0xe4, 0x4f, 0x60, 0xd5, 0xc0, 0x94, 0x84, 0x3f,
0x80, 0x79, 0xdc, 0xbd, 0x0e, 0x88, 0xf4, 0xd9, 0x09, 0x67, 0x23, 0x7b, 0xe8, 0x0a, 0x2c, 0x3d,
0x63, 0xfc, 0x79, 0x74, 0x1e, 0x6b, 0x4e, 0xff, 0xd9, 0x80, 0xe5, 0x1c, 0x52, 0x8c, 0xb6, 0x60,
0x39, 0xf0, 0x59, 0xc4, 0x03, 0x3e, 0x1b, 0x5a, 0xb7, 0x6a, 0x19, 0xc6, 0x1b, 0xcc, 0x0b, 0x03,
0x2f, 0x53, 0xa6, 0x2b, 0x1b, 0x64, 0x0f, 0xd6, 0x51, 0xb7, 0xb4, 0xba, 0xe4, 0xc7, 0x2e, 0x2f,
0xf3, 0xda, 0x3e, 0x34, 0x07, 0xc4, 0xa5, 0x6b, 0x28, 0x86, 0x48, 0x97, 0x54, 0xd7, 0x85, 0x52,
0x93, 0x9c, 0x70, 0xcb, 0xd2, 0x1b, 0x15, 0x40, 0x25, 0x70, 0x5d, 0x90, 0x81, 0x44, 0x39, 0x70,
0x35, 0x82, 0xdf, 0x56, 0x25, 0xf8, 0xdd, 0x82, 0xe5, 0x6c, 0x16, 0x8d, 0x98, 0x3f, 0xe4, 0x31,
0xce, 0x1b, 0x44, 0xe2, 0x74, 0x5a, 0x6e, 0x19, 0x16, 0x61, 0x3a, 0xcb, 0x78, 0xc4, 0xb8, 0x30,
0xc5, 0x96, 0xab, 0x9b, 0xf4, 0xe7, 0xe2, 0x2e, 0xc9, 0x23, 0xee, 0x2f, 0x85, 0xbd, 0x91, 0xbb,
0xd0, 0x96, 0xf3, 0x64, 0x17, 0x9e, 0x8a, 0x99, 0x5a, 0x02, 0x38, 0xbd, 0xf0, 0x30, 0xa0, 0xb4,
0x96, 0x2e, 0x35, 0xbb, 0x23, 0xb0, 0x43, 0xb9, 0xf2, 0x07, 0xb0, 0xa4, 0x63, 0xf9, 0x6c, 0x18,
0xb2, 0x73, 0xae, 0x03, 0xa5, 0x68, 0x3a, 0xc1, 0xe9, 0xb2, 0x23, 0x76, 0xce, 0xe9, 0x31, 0xac,
0x2a, 0xab, 0x7a, 0x91, 0x30, 0x3d, 0xf5, 0xf7, 0xca, 0xfe, 0x54, 0xde, 0x67, 0x6b, 0x4a, 0x5b,
0xcc, 0xe8, 0xae, 0xe4, 0x64, 0xa9, 0x0b, 0x44, 0x75, 0x3f, 0x09, 0xe3, 0x8c, 0x29, 0x86, 0x14,
0xba, 0xa3, 0x30, 0xce, 0xca, 0x21, 0xa0, 0x89, 0xa1, 0x7c, 0xb2, 0xe9, 0x68, 0x84, 0xd6, 0x28,
0x6f, 0x44, 0xdd, 0xa4, 0xbf, 0x74, 0x60, 0x4d, 0x70, 0xd3, 0xf6, 0x9f, 0x87, 0x16, 0xef, 0xbe,
0xcc, 0xee, 0xc8, 0x0c, 0x49, 0xdf, 0x53, 0xe9, 0x48, 0x18, 0x4c, 0x02, 0x7d, 0x29, 0xb6, 0x11,
0x39, 0x42, 0x00, 0x55, 0xf6, 0x3c, 0x4e, 0x47, 0x4c, 0x48, 0xac, 0xe5, 0xca, 0x06, 0xfd, 0x0f,
0x07, 0x56, 0xc5, 0x32, 0x4e, 0xb9, 0xc7, 0xa7, 0x99, 0xda, 0xda, 0x1f, 0x43, 0x0f, 0xb7, 0xc1,
0xb4, 0xba, 0xaa, 0x45, 0xac, 0xe7, 0x96, 0x25, 0x50, 0x49, 0x7c, 0x78, 0xcb, 0xb5, 0x89, 0xc9,
0xe7, 0xd0, 0x35, 0x93, 0x2d, 0x15, 0x5f, 0xdf, 0xd1, 0x3b, 0xa8, 0x68, 0xc5, 0xe1, 0x2d, 0xd7,
0x1a, 0x40, 0x3e, 0x03, 0x10, 0xb7, 0x98, 0x60, 0x2b, 0xd6, 0x6b, 0x0c, 0xaf, 0x1c, 0xc4, 0xe1,
0x2d, 0xd7, 0x20, 0xff, 0xa2, 0x05, 0x0b, 0xd2, 0xb9, 0xd3, 0x67, 0xd0, 0xb3, 0x56, 0x6a, 0x05,
0x78, 0x5d, 0x19, 0xe0, 0x55, 0x02, 0xef, 0x46, 0x4d, 0xe0, 0xfd, 0xbf, 0x0e, 0x10, 0xd4, 0xa4,
0xd2, 0x51, 0x7d, 0x08, 0x4b, 0xdc, 0x4b, 0xc7, 0x8c, 0x0f, 0xed, 0x38, 0xa6, 0x84, 0x8a, 0x5b,
0x28, 0xf6, 0xad, 0xdb, 0xbe, 0xeb, 0x9a, 0x10, 0xd9, 0x01, 0x62, 0x34, 0x75, 0x9a, 0x24, 0xfd,
0x77, 0x4d, 0x0f, 0x3a, 0x1a, 0x79, 0x55, 0xeb, 0x3c, 0x42, 0x45, 0x42, 0x4d, 0x71, 0xe8, 0xb5,
0x7d, 0xe8, 0xa2, 0x93, 0x29, 0xe6, 0x60, 0x1e, 0xd7, 0xf1, 0x80, 0x6e, 0x6b, 0x97, 0x22, 0xcc,
0x4a, 0x79, 0x8c, 0x02, 0xa0, 0xbf, 0x75, 0x60, 0x05, 0xb7, 0x6f, 0xa9, 0xc8, 0xa7, 0x20, 0xb4,
0xef, 0x1d, 0x35, 0xc4, 0xa2, 0xfd, 0xdd, 0x15, 0xe4, 0x31, 0xb4, 0x05, 0xc3, 0x38, 0x61, 0x91,
0xd2, 0x8f, 0xbe, 0xad, 0x1f, 0x85, 0xe1, 0x1f, 0xde, 0x72, 0x0b, 0x62, 0x43, 0x3b, 0x0e, 0xe0,
0xb6, 0x5a, 0x65, 0xe9, 0x58, 0x3f, 0x82, 0x85, 0x4c, 0xec, 0x54, 0x85, 0xf7, 0xeb, 0x36, 0x67,
0x29, 0x05, 0x57, 0xd1, 0xd0, 0xbf, 0x99, 0x83, 0x8d, 0x32, 0x1f, 0x75, 0x9d, 0xfc, 0x18, 0x56,
0x2a, 0x57, 0x81, 0xbc, 0xa2, 0x3e, 0xb2, 0xc5, 0x54, 0x1a, 0x58, 0x86, 0x2b, 0x5c, 0x06, 0xff,
0xd8, 0x80, 0x25, 0x9b, 0x08, 0xf5, 0x38, 0xbf, 0xa4, 0x8a, 0x8b, 0xcb, 0xc2, 0xaa, 0x21, 0x65,
0xa3, 0x2e, 0xa4, 0x34, 0x03, 0xc7, 0xb9, 0x6f, 0x0b, 0x1c, 0x9b, 0xef, 0x16, 0x38, 0xce, 0xd7,
0x06, 0x8e, 0x65, 0x0f, 0x2a, 0x73, 0x7d, 0xdb, 0x83, 0x16, 0xa7, 0xb1, 0xf8, 0x0e, 0xa7, 0xf1,
0x3d, 0x58, 0x7f, 0xe5, 0x85, 0x21, 0xe3, 0x5f, 0xc8, 0x29, 0xf4, 0x99, 0x7e, 0x00, 0xdd, 0x2b,
0x99, 0x22, 0x0d, 0xe3, 0x28, 0x9c, 0xa9, 0x80, 0xbc, 0xa3, 0xb0, 0x17, 0x51, 0x38, 0xa3, 0x1f,
0xc3, 0xed, 0xd2, 0xd0, 0x22, 0x4f, 0xd1, 0xdb, 0xc0, 0x61, 0x8e, 0xab, 0x9b, 0x74, 0x13, 0x6e,
0xab, 0x65, 0xd8, 0xd3, 0xd1, 0x3d, 0xd8, 0x28, 0x77, 0xd4, 0x33, 0x9b, 0x2b, 0x98, 0x7d, 0x0e,
0xe4, 0x47, 0x53, 0x96, 0xce, 0x44, 0xfd, 0x21, 0xcf, 0x34, 0x37, 0xcb, 0x21, 0x20, 0x26, 0xf8,
0x3f, 0x60, 0x33, 0x5d, 0x8f, 0x69, 0xe4, 0xf5, 0x18, 0xfa, 0x19, 0xac, 0x59, 0x0c, 0xd4, 0x8c,
0x0f, 0x60, 0x41, 0xd4, 0x30, 0xb4, 0xee, 0xd9, 0x75, 0x0e, 0xd5, 0x47, 0xff, 0x12, 0xe6, 0x0e,
0xe3, 0xc4, 0x4c, 0x27, 0x1c, 0x3b, 0x9d, 0x50, 0xba, 0x33, 0xcc, 0x55, 0x43, 0xce, 0x6c, 0x83,
0x78, 0xf2, 0xde, 0x84, 0x63, 0x7c, 0x70, 0x1e, 0xa7, 0x57, 0x5e, 0xea, 0x2b, 0x0d, 0x2a, 0xa1,
0xb8, 0xfa, 0x73, 0xa6, 0xb5, 0x07, 0xff, 0xd2, 0x5f, 0x39, 0x30, 0x2f, 0x96, 0x84, 0xd1, 0x87,
0x8c, 0xe7, 0xe5, 0x6d, 0x86, 0x69, 0x9c, 0x23, 0x5c, 0x52, 0x19, 0x2e, 0x15, 0xd8, 0x1a, 0xe5,
0x02, 0x1b, 0xba, 0x35, 0xd9, 0x2a, 0x2a, 0x57, 0x05, 0x40, 0xde, 0x87, 0xe6, 0x45, 0x9c, 0x60,
0xa8, 0x85, 0x62, 0x01, 0x1d, 0xf1, 0xc7, 0x89, 0x2b, 0x70, 0xba, 0x0d, 0xcb, 0xc7, 0xb1, 0xcf,
0x8c, 0xa0, 0xf1, 0xc6, 0xd3, 0xa0, 0x7f, 0xe5, 0x40, 0x4b, 0x13, 0x93, 0x2d, 0x68, 0xa2, 0xcf,
0x2e, 0xb9, 0xc4, 0x3c, 0x61, 0x46, 0x3a, 0x57, 0x50, 0xa0, 0x01, 0x08, 0x37, 0xab, 0xbd, 0x43,
0x23, 0x0f, 0x66, 0x8a, 0x70, 0x0f, 0x6f, 0x19, 0xb1, 0xe6, 0x92, 0x51, 0x96, 0x50, 0xfa, 0x16,
0x7a, 0xd6, 0x14, 0x78, 0xed, 0x84, 0x5e, 0xc6, 0x55, 0xaa, 0xa3, 0x64, 0x68, 0x42, 0x66, 0x7e,
0xd1, 0xa8, 0xe4, 0x17, 0x37, 0x64, 0x11, 0x79, 0xe4, 0xdb, 0x34, 0x22, 0x5f, 0xfa, 0x2f, 0x0e,
0xf4, 0xf0, 0xf4, 0x82, 0x68, 0x7c, 0x12, 0x87, 0xc1, 0x68, 0x26, 0x4e, 0x51, 0x1f, 0x14, 0x66,
0xc8, 0xdc, 0xcb, 0x4f, 0xd1, 0x86, 0xd1, 0xdf, 0x4c, 0x82, 0x48, 0x24, 0x57, 0xea, 0x0c, 0xf3,
0x36, 0x6a, 0xdd, 0x39, 0x43, 0x87, 0x91, 0xb1, 0xe1, 0x04, 0x6f, 0x2e, 0xb9, 0x77, 0x1b, 0xc4,
0x18, 0x1a, 0x81, 0xd4, 0xe3, 0x6c, 0x38, 0x09, 0xc2, 0x30, 0x90, 0xb4, 0x52, 0xbb, 0xea, 0xba,
0xe8, 0xbf, 0x35, 0xa0, 0xa3, 0x2c, 0xf4, 0xc0, 0x1f, 0x33, 0xd4, 0x24, 0xed, 0x04, 0x73, 0xd5,
0x37, 0x10, 0xdd, 0x6f, 0xb9, 0x4d, 0x03, 0x29, 0xcb, 0x7a, 0xae, 0x2a, 0x6b, 0xbc, 0x62, 0x63,
0x9f, 0x7d, 0x8c, 0x37, 0xb9, 0x92, 0x5d, 0x01, 0xe8, 0xde, 0x3d, 0xd1, 0x3b, 0x5f, 0xf4, 0x0a,
0xc0, 0xf2, 0xc8, 0x0b, 0x25, 0x8f, 0xfc, 0x18, 0xba, 0x8a, 0x8d, 0x90, 0xbb, 0xf0, 0x92, 0x85,
0xd2, 0x59, 0x67, 0xe2, 0x5a, 0x94, 0x7a, 0xe4, 0x9e, 0x1e, 0xd9, 0xfa, 0xb6, 0x91, 0x9a, 0x12,
0x33, 0x60, 0x25, 0xbc, 0x67, 0xa9, 0x97, 0x5c, 0x68, 0xaf, 0xe7, 0xe7, 0x35, 0x52, 0x01, 0x93,
0x6d, 0x98, 0xc7, 0x61, 0xda, 0xf1, 0xd4, 0x1b, 0x82, 0x24, 0x21, 0x5b, 0x30, 0xcf, 0xfc, 0xb1,
0xb0, 0x62, 0xb3, 0xa8, 0x6d, 0x9c, 0x91, 0x2b, 0x09, 0xd0, 0x2c, 0x11, 0x2d, 0x99, 0xa5, 0xed,
0xb5, 0x16, 0xb0, 0xf9, 0xdc, 0xa7, 0xeb, 0x40, 0x8e, 0x19, 0xbf, 0x8a, 0xd3, 0xd7, 0x66, 0xea,
0xf7, 0xd7, 0x73, 0xd0, 0x31, 0x60, 0xb4, 0xb0, 0x31, 0x2e, 0x78, 0xe8, 0x07, 0xde, 0x84, 0x71,
0x96, 0x2a, 0x4d, 0x2d, 0xa1, 0xc2, 0xb9, 0x5d, 0x8e, 0x87, 0xf1, 0x94, 0x0f, 0x7d, 0x36, 0x4e,
0x99, 0xac, 0x5f, 0x3a, 0x6e, 0x09, 0x45, 0xba, 0x89, 0xf7, 0xc6, 0xa4, 0x93, 0xfa, 0x50, 0x42,
0x75, 0xd4, 0x25, 0x65, 0xd4, 0x2c, 0xa2, 0x2e, 0x29, 0x91, 0xb2, 0x6f, 0x98, 0xaf, 0xf1, 0x0d,
0x9f, 0xc0, 0x86, 0xf4, 0x02, 0x91, 0xdc, 0xce, 0xb0, 0xa4, 0x26, 0x37, 0xf4, 0x92, 0x6d, 0x58,
0xc1, 0x35, 0x6b, 0x05, 0xcf, 0x82, 0x9f, 0xcb, 0xda, 0x8e, 0xe3, 0x56, 0x70, 0xa4, 0x45, 0x73,
0xb4, 0x68, 0x65, 0x71, 0xa7, 0x82, 0x0b, 0x5a, 0xef, 0x8d, 0x4d, 0xdb, 0x56, 0xb4, 0x25, 0x9c,
0xde, 0x85, 0x3b, 0x42, 0x4d, 0x5e, 0xc6, 0x49, 0x1c, 0xc6, 0xe3, 0xd9, 0xe9, 0xf4, 0x2c, 0x1b,
0xa5, 0x41, 0x82, 0x01, 0x1e, 0xfd, 0x77, 0x07, 0xd6, 0xac, 0x5e, 0x15, 0x75, 0xfe, 0xa1, 0xd4,
0xd9, 0xbc, 0xa2, 0x23, 0x35, 0x6b, 0x55, 0x17, 0x60, 0x63, 0x5f, 0xe5, 0x04, 0x32, 0xbc, 0xfe,
0x52, 0x15, 0x79, 0xf6, 0x61, 0x59, 0x4f, 0xad, 0x07, 0x4a, 0x35, 0xeb, 0x57, 0xd5, 0x4c, 0x8d,
0x5f, 0x52, 0x03, 0x34, 0x8b, 0x3f, 0x91, 0xa1, 0x0a, 0xf3, 0xc5, 0x26, 0xd0, 0x2b, 0xe2, 0xf8,
0x81, 0x1e, 0x2f, 0xba, 0x9e, 0x98, 0x43, 0xdc, 0xce, 0x28, 0x07, 0x33, 0xfa, 0xb7, 0x0e, 0x40,
0xb1, 0x3a, 0x3c, 0x79, 0xe5, 0x4f, 0xd5, 0x1e, 0xda, 0x6e, 0x01, 0x60, 0xb0, 0x62, 0x85, 0x72,
0xd2, 0xdd, 0x74, 0x34, 0x86, 0xb7, 0xff, 0x43, 0x58, 0x1e, 0x87, 0xf1, 0x99, 0xb8, 0xe8, 0x3c,
0x3e, 0x4d, 0x59, 0xa6, 0x4a, 0x9d, 0x4b, 0x12, 0xfe, 0xbe, 0x42, 0x6f, 0x70, 0xd7, 0x7f, 0xd7,
0xc8, 0x33, 0xe4, 0x62, 0xcf, 0x37, 0x9a, 0x11, 0xd9, 0xab, 0x78, 0xbf, 0x1b, 0x12, 0x52, 0x11,
0x68, 0x9f, 0x7c, 0x6b, 0x14, 0xf9, 0x19, 0x2c, 0xa5, 0xd2, 0xbd, 0x68, 0xdf, 0xd3, 0xfc, 0x06,
0xdf, 0xd3, 0x4b, 0xad, 0x8b, 0xe5, 0xf7, 0x60, 0xc5, 0xf3, 0x2f, 0x59, 0xca, 0x03, 0x11, 0x24,
0x8a, 0x9b, 0x56, 0x7a, 0xcc, 0x65, 0x03, 0x17, 0x37, 0xe0, 0x43, 0x58, 0x1e, 0xc9, 0xc2, 0x73,
0x4e, 0xa9, 0x9e, 0x93, 0x0a, 0x18, 0x09, 0xe9, 0x3f, 0xeb, 0x64, 0xdc, 0x3e, 0xc3, 0x9b, 0x25,
0x62, 0xee, 0xae, 0x51, 0xda, 0xdd, 0x77, 0x55, 0xf2, 0xec, 0xeb, 0x3a, 0x86, 0x2a, 0x51, 0x48,
0x50, 0x15, 0x32, 0x6c, 0x91, 0x36, 0xdf, 0x45, 0xa4, 0x74, 0x07, 0x96, 0x4f, 0x19, 0xdf, 0xc7,
0x13, 0xd4, 0x9e, 0xef, 0x2e, 0xb4, 0x23, 0x76, 0x35, 0x94, 0x47, 0x2c, 0x43, 0x92, 0x56, 0xc4,
0xae, 0x04, 0x0d, 0x25, 0xb0, 0x52, 0xd0, 0xcb, 0x68, 0x90, 0xfe, 0x7d, 0x03, 0x16, 0x9f, 0x47,
0x97, 0x71, 0x30, 0x12, 0xe9, 0xf0, 0x84, 0x4d, 0x62, 0xfd, 0xde, 0x81, 0xff, 0xf1, 0xe2, 0x17,
0xd5, 0xd3, 0x84, 0xab, 0x3c, 0x55, 0x37, 0xf1, 0x0a, 0x4c, 0x8b, 0xc7, 0x35, 0xa9, 0x6d, 0x06,
0x42, 0x36, 0x60, 0x21, 0x35, 0x1f, 0x02, 0x55, 0xab, 0x78, 0xec, 0x99, 0x37, 0x1e, 0x7b, 0x44,
0x61, 0x44, 0x16, 0x86, 0xc5, 0x91, 0xb4, 0x5c, 0xdd, 0x14, 0x81, 0x66, 0xca, 0x54, 0x65, 0x1d,
0x2f, 0xd3, 0x45, 0x15, 0x68, 0x9a, 0x20, 0x5e, 0xb8, 0x72, 0x80, 0xa4, 0x91, 0x0e, 0xc9, 0x84,
0x30, 0x00, 0x29, 0xbf, 0x25, 0xb6, 0xa5, 0x9a, 0x94, 0x60, 0xfa, 0x15, 0x90, 0x7d, 0xdf, 0x57,
0x52, 0xc9, 0xe3, 0xe6, 0x62, 0x3f, 0x8e, 0xb5, 0x9f, 0x1a, 0xbe, 0x8d, 0x7a, 0xbe, 0x07, 0xd0,
0x39, 0x31, 0x1e, 0x43, 0x85, 0x00, 0xf5, 0x33, 0xa8, 0x12, 0xba, 0x81, 0x18, 0x13, 0x36, 0xcc,
0x09, 0xe9, 0x1f, 0x01, 0x39, 0x0a, 0x32, 0x9e, 0xaf, 0x2f, 0xcf, 0x68, 0x74, 0x5a, 0x68, 0x66,
0x34, 0x0a, 0x13, 0x19, 0xcd, 0xbe, 0x2c, 0x54, 0x97, 0x37, 0xb6, 0x0d, 0xad, 0x40, 0x42, 0xda,
0x7f, 0x2e, 0x29, 0xc5, 0xd3, 0x94, 0x79, 0x3f, 0xde, 0xf4, 0x0a, 0xb4, 0xdc, 0xf3, 0xaf, 0x1c,
0x58, 0x54, 0x5b, 0xc3, 0x7b, 0xca, 0x7a, 0x06, 0x56, 0x89, 0xa7, 0x89, 0xd5, 0x3f, 0xf8, 0x55,
0x4f, 0x7a, 0xae, 0xee, 0xa4, 0x09, 0x34, 0x13, 0x8f, 0x5f, 0x88, 0x30, 0xbd, 0xed, 0x8a, 0xff,
0x3a, 0x7d, 0x98, 0x2f, 0xd2, 0x07, 0x55, 0x94, 0x57, 0x8b, 0xca, 0xeb, 0xc5, 0x5f, 0xc8, 0xa2,
0x7c, 0x01, 0x17, 0x32, 0x50, 0x0b, 0x2c, 0xcb, 0x40, 0x91, 0xba, 0x79, 0x3f, 0x1d, 0x40, 0xff,
0x29, 0x0b, 0x19, 0x67, 0xfb, 0x61, 0x58, 0xe6, 0x7f, 0x17, 0xee, 0xd4, 0xf4, 0x29, 0x5b, 0xfb,
0x3e, 0xac, 0x3e, 0x65, 0x67, 0xd3, 0xf1, 0x11, 0xbb, 0x2c, 0xaa, 0x0b, 0x04, 0x9a, 0xd9, 0x45,
0x7c, 0xa5, 0xce, 0x4b, 0xfc, 0x27, 0xef, 0x01, 0x84, 0x48, 0x33, 0xcc, 0x12, 0x36, 0x52, 0xda,
0xd4, 0x16, 0xc8, 0x69, 0xc2, 0x46, 0xf4, 0x13, 0x20, 0x26, 0x1f, 0xb5, 0x05, 0xb4, 0x80, 0xe9,
0xd9, 0x30, 0x9b, 0x65, 0x9c, 0x4d, 0xb4, 0xf1, 0x9b, 0x10, 0x7d, 0x08, 0xdd, 0x13, 0x6f, 0xe6,
0xb2, 0xaf, 0xd5, 0xeb, 0x3a, 0x66, 0x2f, 0xde, 0x0c, 0xd5, 0x33, 0xcf, 0x5e, 0x44, 0x37, 0x4d,
0x61, 0x41, 0x12, 0x22, 0x53, 0x9f, 0x65, 0x3c, 0x88, 0x64, 0x61, 0x46, 0x31, 0x35, 0xa0, 0xca,
0x71, 0x37, 0x6a, 0x8e, 0x5b, 0x85, 0x2e, 0xfa, 0x3d, 0x46, 0x9d, 0xab, 0x85, 0x6d, 0xef, 0x41,
0xcf, 0x4a, 0xe1, 0xc9, 0x22, 0xcc, 0xed, 0x1f, 0x1d, 0xad, 0xdc, 0x22, 0x1d, 0x58, 0x7c, 0x71,
0x72, 0x70, 0xfc, 0xfc, 0xf8, 0xd9, 0x8a, 0x83, 0x8d, 0x27, 0x47, 0x2f, 0x4e, 0xb1, 0xd1, 0xd8,
0xfb, 0xcd, 0x26, 0xb4, 0xf3, 0xe8, 0x91, 0xfc, 0x0c, 0x7a, 0x56, 0xc2, 0x4e, 0xee, 0xaa, 0x23,
0xac, 0xab, 0x00, 0x0c, 0xee, 0xd5, 0x77, 0xaa, 0xa3, 0x7a, 0xff, 0x17, 0xbf, 0xfd, 0xaf, 0x7f,
0x68, 0xf4, 0xc9, 0xc6, 0xee, 0xe5, 0xc7, 0xbb, 0x2a, 0x23, 0xdf, 0x15, 0x85, 0x67, 0x59, 0xe7,
0x7e, 0x0d, 0x4b, 0x76, 0x42, 0x4f, 0xee, 0xd9, 0xce, 0xba, 0x34, 0xdb, 0x7b, 0x37, 0xf4, 0xaa,
0xe9, 0xee, 0x89, 0xe9, 0x36, 0xc8, 0xba, 0x39, 0x5d, 0x1e, 0xd5, 0x31, 0xf1, 0x32, 0x61, 0x7e,
0x17, 0x42, 0x34, 0xbf, 0xfa, 0xef, 0x45, 0x06, 0x77, 0xaa, 0xdf, 0x80, 0xa8, 0x8f, 0x46, 0x68,
0x5f, 0x4c, 0x45, 0xc8, 0x0a, 0x4e, 0x65, 0x7e, 0x16, 0x42, 0x7e, 0x0a, 0xed, 0xfc, 0x0d, 0x9c,
0x6c, 0x1a, 0x2f, 0xfe, 0xe6, 0xab, 0xfa, 0xa0, 0x5f, 0xed, 0x50, 0x9b, 0xb8, 0x2b, 0x38, 0xdf,
0xa6, 0x15, 0xce, 0x9f, 0x3a, 0xdb, 0xe4, 0x08, 0x6e, 0x2b, 0x8f, 0x71, 0xc6, 0xfe, 0x3f, 0x3b,
0xa9, 0xf9, 0x9a, 0xe5, 0x91, 0x43, 0x3e, 0x83, 0x96, 0xfe, 0x2c, 0x80, 0x6c, 0xd4, 0x7f, 0x9b,
0x30, 0xd8, 0xac, 0xe0, 0xca, 0x50, 0xf6, 0x01, 0x8a, 0x57, 0x70, 0xd2, 0xbf, 0xe9, 0xb1, 0x3e,
0x17, 0x62, 0xcd, 0x93, 0xf9, 0x58, 0x7c, 0x04, 0x60, 0x3f, 0xb2, 0x93, 0xef, 0x14, 0xf4, 0xb5,
0xcf, 0xef, 0xdf, 0xc0, 0x90, 0x6e, 0x08, 0xd9, 0xad, 0x90, 0x25, 0x94, 0x5d, 0xc4, 0xae, 0x74,
0x76, 0xfd, 0x13, 0xe8, 0x18, 0x4f, 0xe5, 0xc4, 0x28, 0x89, 0x96, 0x5e, 0xe5, 0x07, 0x83, 0xba,
0x2e, 0xc5, 0x7d, 0x5d, 0x70, 0x5f, 0xa2, 0x6d, 0xe4, 0x2e, 0x9e, 0x85, 0xf0, 0x48, 0x7e, 0x84,
0xc6, 0xa3, 0xde, 0xce, 0x48, 0xf1, 0x8c, 0x6f, 0xbf, 0xb0, 0xe5, 0xe7, 0x5d, 0x79, 0x66, 0xa3,
0xab, 0x82, 0x6b, 0x87, 0x14, 0x5c, 0xc9, 0x0f, 0x61, 0x51, 0xbd, 0xa1, 0x91, 0xdb, 0xc5, 0xb9,
0x1a, 0xb9, 0xd6, 0x60, 0xa3, 0x0c, 0x2b, 0x66, 0x6b, 0x82, 0x59, 0x8f, 0x74, 0x90, 0xd9, 0x98,
0xf1, 0x00, 0x79, 0x84, 0xb0, 0x6c, 0x57, 0x35, 0xb3, 0xdc, 0xcc, 0x6a, 0x4b, 0xb5, 0xb9, 0x99,
0xd5, 0xd7, 0x51, 0x6d, 0x33, 0xd3, 0xe6, 0xb5, 0xab, 0xab, 0xd0, 0x7f, 0x0e, 0x5d, 0xf3, 0xc1,
0x96, 0x0c, 0x8c, 0x9d, 0x97, 0x1e, 0x77, 0x07, 0x77, 0x6b, 0xfb, 0x6c, 0x71, 0x93, 0xae, 0x39,
0x0d, 0xf9, 0x09, 0x2c, 0x1b, 0x6f, 0x06, 0xa7, 0xb3, 0x68, 0x94, 0x1f, 0x67, 0xf5, 0x2d, 0x61,
0x50, 0x17, 0xfb, 0xd1, 0x4d, 0xc1, 0x78, 0x95, 0x5a, 0x8c, 0xf1, 0x28, 0x9f, 0x40, 0xc7, 0xe0,
0xf1, 0x4d, 0x7c, 0x37, 0x8d, 0x2e, 0xb3, 0x7e, 0xff, 0xc8, 0x21, 0xbf, 0x76, 0xa0, 0x6b, 0xbe,
0x40, 0x11, 0x2b, 0x9b, 0x29, 0xf1, 0xe9, 0x9b, 0x7d, 0x26, 0x23, 0xfa, 0x95, 0x58, 0xe4, 0xc9,
0xf6, 0xb1, 0x25, 0xe4, 0xb7, 0x56, 0x4d, 0x79, 0xc7, 0xfc, 0xde, 0xe9, 0xba, 0xdc, 0x69, 0xbe,
0xb5, 0x5c, 0xef, 0xbe, 0x15, 0x0f, 0x53, 0xd7, 0x8f, 0x1c, 0xf2, 0xa9, 0xfc, 0x6c, 0x4d, 0x07,
0x1a, 0xc4, 0x30, 0xf0, 0xb2, 0xd8, 0xcc, 0x8f, 0xc1, 0xb6, 0x9c, 0x47, 0x0e, 0xf9, 0x0b, 0xf9,
0xa9, 0x93, 0x1a, 0x2b, 0xa4, 0xff, 0xae, 0xe3, 0xe9, 0x03, 0xb1, 0xa3, 0xf7, 0xe9, 0x1d, 0x6b,
0x47, 0x65, 0x0f, 0x77, 0x02, 0x50, 0x44, 0x8d, 0xa4, 0x14, 0x42, 0xe5, 0xb6, 0x5f, 0x0d, 0x2c,
0xed, 0x53, 0xd5, 0x91, 0x16, 0x72, 0xfc, 0x99, 0x54, 0x48, 0x45, 0x9f, 0xe5, 0xc7, 0x5a, 0x8d,
0xfe, 0x06, 0x83, 0xba, 0x2e, 0xc5, 0xff, 0xbb, 0x82, 0xff, 0x7b, 0xe4, 0xae, 0xc9, 0x7f, 0xf7,
0xad, 0x19, 0x2d, 0x5e, 0x93, 0xaf, 0xa0, 0x77, 0x14, 0xc7, 0xaf, 0xa7, 0x49, 0x9e, 0x0c, 0xd8,
0xf1, 0x0f, 0x46, 0xac, 0x83, 0xd2, 0xa6, 0xe8, 0x07, 0x82, 0xf3, 0x5d, 0x72, 0xc7, 0xe6, 0x5c,
0xc4, 0xb0, 0xd7, 0xc4, 0x83, 0xd5, 0xdc, 0xef, 0xe7, 0x1b, 0x19, 0xd8, 0x7c, 0xcc, 0x50, 0xb2,
0x32, 0x87, 0x75, 0x13, 0xe7, 0x73, 0x64, 0x9a, 0xe7, 0x23, 0x87, 0x9c, 0x40, 0xf7, 0x29, 0x1b,
0xc5, 0x3e, 0x53, 0x31, 0xcb, 0x5a, 0xb1, 0xf2, 0x3c, 0xd6, 0x19, 0xf4, 0x2c, 0xd0, 0xf6, 0x04,
0x89, 0x37, 0x4b, 0xd9, 0xd7, 0xbb, 0x6f, 0x55, 0x30, 0x74, 0xad, 0x3d, 0x81, 0x0e, 0xe0, 0x2c,
0x4f, 0x50, 0x8a, 0xf8, 0x2c, 0x4f, 0x50, 0x89, 0xf8, 0x2c, 0x4f, 0xa0, 0x03, 0x48, 0x12, 0x62,
0x1c, 0x58, 0x0a, 0x12, 0xf3, 0xdb, 0xe3, 0xa6, 0xd0, 0x72, 0x70, 0xff, 0x66, 0x02, 0x7b, 0xb6,
0x6d, 0x7b, 0xb6, 0x53, 0xe8, 0x3d, 0x65, 0x52, 0x58, 0xb2, 0x0c, 0x37, 0xb0, 0x5d, 0x8b, 0x59,
0xb2, 0x2b, 0xbb, 0x1d, 0xd1, 0x67, 0x3b, 0x7a, 0x51, 0x03, 0x23, 0x3f, 0x85, 0xce, 0x33, 0xc6,
0x75, 0xdd, 0x2d, 0xbf, 0x83, 0x4b, 0x85, 0xb8, 0x41, 0x4d, 0xd9, 0x8e, 0xde, 0x17, 0xdc, 0x06,
0xa4, 0x9f, 0x73, 0xdb, 0x65, 0xfe, 0x98, 0x49, 0x27, 0x30, 0x0c, 0xfc, 0x6b, 0xf2, 0x63, 0xc1,
0x3c, 0x2f, 0x9f, 0x6f, 0x18, 0xd5, 0x1c, 0x93, 0xf9, 0x72, 0x09, 0xaf, 0xe3, 0x8c, 0x39, 0xfe,
0xee, 0x5b, 0x55, 0xc5, 0xbe, 0x26, 0x11, 0x74, 0x8c, 0x27, 0x91, 0xdc, 0xa0, 0xaa, 0xef, 0x2c,
0xb9, 0x41, 0xd5, 0xbc, 0xa0, 0xd0, 0x2d, 0x31, 0x0f, 0x25, 0xf7, 0x8b, 0x79, 0xe4, 0xab, 0x49,
0x31, 0xd3, 0xee, 0x5b, 0x6f, 0xc2, 0xaf, 0xc9, 0x2b, 0xf1, 0x99, 0x89, 0x59, 0x5b, 0x2c, 0x62,
0x80, 0x72, 0x19, 0x32, 0x17, 0x96, 0xd1, 0x65, 0xc7, 0x05, 0x72, 0x2a, 0x71, 0x33, 0xbe, 0x32,
0xc2, 0x29, 0xab, 0xc6, 0xaa, 0xb5, 0xe4, 0xc6, 0x52, 0x5a, 0xbe, 0xb3, 0x9a, 0x72, 0x9a, 0x8e,
0xac, 0x64, 0x8d, 0xc0, 0x88, 0xac, 0xac, 0x22, 0x83, 0x11, 0x59, 0xd9, 0xc5, 0x04, 0x8c, 0xac,
0x8a, 0xc4, 0x24, 0x8f, 0xac, 0x2a, 0x39, 0x4f, 0xee, 0x0c, 0xab, 0x59, 0xcc, 0xd9, 0x82, 0xf8,
0xfc, 0xfb, 0x0f, 0xfe, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x2e, 0x7d, 0x20, 0xe1, 0x30, 0x2e, 0x00,
0x00,
0x73, 0x08, 0x5e, 0x7d, 0x74, 0x57, 0x75, 0x37, 0xb5, 0x0a, 0x72, 0x9a, 0xa9, 0x5f, 0xbd, 0x7a,
0x55, 0xf5, 0xea, 0x7d, 0xd5, 0xab, 0x86, 0x56, 0x12, 0x0f, 0x77, 0xe2, 0x24, 0xe2, 0x11, 0x99,
0x0b, 0xc2, 0x24, 0x1e, 0xf6, 0xef, 0x8e, 0xa3, 0x68, 0x1c, 0xb0, 0x5d, 0x2f, 0xf6, 0x77, 0xbd,
0x30, 0x8c, 0xb8, 0xc7, 0xfd, 0x28, 0x4c, 0x25, 0x11, 0xfd, 0x6f, 0x07, 0xda, 0x2f, 0x13, 0x2f,
0x4c, 0xbd, 0x21, 0xc2, 0xa4, 0x07, 0x0b, 0xfc, 0xcd, 0xe0, 0xc2, 0x4b, 0x2f, 0x7a, 0xce, 0x3d,
0x67, 0xab, 0xe5, 0xea, 0x26, 0x59, 0x87, 0x79, 0x6f, 0x12, 0x4d, 0x43, 0xde, 0xab, 0xdd, 0x73,
0xb6, 0xea, 0xae, 0x6a, 0x91, 0x4f, 0x60, 0x25, 0x9c, 0x4e, 0x06, 0xc3, 0x28, 0x3c, 0xf7, 0x93,
0x89, 0x64, 0xde, 0xab, 0xdf, 0x73, 0xb6, 0xe6, 0xdc, 0x72, 0x07, 0xf9, 0x10, 0xe0, 0x2c, 0x88,
0x86, 0xaf, 0xe5, 0x14, 0x0d, 0x31, 0x85, 0x81, 0x10, 0x0a, 0x1d, 0xd5, 0x62, 0xfe, 0xf8, 0x82,
0xf7, 0xe6, 0x04, 0x23, 0x0b, 0x43, 0x1e, 0xdc, 0x9f, 0xb0, 0x41, 0xca, 0xbd, 0x49, 0xdc, 0x9b,
0x17, 0xab, 0x31, 0x10, 0xd1, 0x1f, 0x71, 0x2f, 0x18, 0x9c, 0x33, 0x96, 0xf6, 0x16, 0x54, 0x7f,
0x86, 0xd0, 0x1e, 0xac, 0x3f, 0x63, 0xdc, 0xd8, 0x75, 0xea, 0xb2, 0x6f, 0xa6, 0x2c, 0xe5, 0xf4,
0x08, 0x88, 0x01, 0x3f, 0x65, 0xdc, 0xf3, 0x83, 0x94, 0x7c, 0x06, 0x1d, 0x6e, 0x10, 0xf7, 0x9c,
0x7b, 0xf5, 0xad, 0xf6, 0x1e, 0xd9, 0x11, 0xf2, 0xdd, 0x31, 0x06, 0xb8, 0x16, 0x1d, 0xfd, 0xad,
0x03, 0xed, 0x53, 0x16, 0x8e, 0x14, 0x77, 0x42, 0xa0, 0x31, 0x62, 0x29, 0x17, 0x82, 0xed, 0xb8,
0xe2, 0x3f, 0xf9, 0x0e, 0xb4, 0xf1, 0x77, 0x90, 0xf2, 0xc4, 0x0f, 0xc7, 0x42, 0xb4, 0x2d, 0x17,
0x10, 0x3a, 0x15, 0x08, 0x59, 0x86, 0xba, 0x37, 0xe1, 0x42, 0xa0, 0x75, 0x17, 0xff, 0x92, 0x8f,
0xa0, 0x13, 0x7b, 0xb3, 0x09, 0x0b, 0x79, 0x2e, 0xc4, 0x8e, 0xdb, 0x56, 0xd8, 0x21, 0x4a, 0x71,
0x07, 0x56, 0x4d, 0x12, 0xcd, 0x7d, 0x4e, 0x70, 0x5f, 0x31, 0x28, 0xd5, 0x24, 0x0f, 0x60, 0x49,
0xd3, 0x27, 0x72, 0xb1, 0x42, 0xac, 0x2d, 0x77, 0x51, 0xc1, 0x5a, 0x40, 0x21, 0x74, 0xe4, 0x8e,
0xd2, 0x38, 0x0a, 0x53, 0x46, 0xb6, 0x61, 0x59, 0x0f, 0x8c, 0x13, 0xe6, 0x4f, 0xbc, 0x31, 0x53,
0xdb, 0x2b, 0xe1, 0x64, 0x0f, 0xba, 0xd9, 0x24, 0xd1, 0x94, 0x33, 0xb1, 0xd9, 0xf6, 0x5e, 0x47,
0xc9, 0xd1, 0x45, 0xcc, 0xb5, 0x49, 0xe8, 0x2f, 0x1c, 0xe8, 0x3c, 0xb9, 0xf0, 0xc2, 0x90, 0x05,
0x27, 0x91, 0x1f, 0x72, 0xd4, 0x8f, 0xf3, 0x69, 0x38, 0xf2, 0xc3, 0xf1, 0x80, 0xbf, 0xf1, 0x47,
0x6a, 0x32, 0x0b, 0xc3, 0x45, 0x99, 0x6d, 0xdc, 0xbd, 0x12, 0x6c, 0x09, 0x47, 0x7e, 0xd1, 0x94,
0xc7, 0x53, 0x3e, 0xf0, 0xc3, 0x11, 0x7b, 0x23, 0xe4, 0xdc, 0x75, 0x2d, 0x8c, 0xfe, 0x29, 0x2c,
0x1f, 0xa1, 0xe2, 0x85, 0x7e, 0x38, 0xde, 0x1f, 0x8d, 0x12, 0x96, 0xa6, 0x68, 0x0d, 0xf1, 0xf4,
0xec, 0x35, 0x9b, 0x29, 0x33, 0x51, 0x2d, 0x3c, 0xe3, 0x8b, 0x28, 0xe5, 0x6a, 0x3e, 0xf1, 0x9f,
0xfe, 0xa3, 0x03, 0x4b, 0x28, 0xb5, 0x1f, 0x7a, 0xe1, 0x4c, 0xeb, 0xc2, 0x11, 0x74, 0x90, 0xd5,
0xcb, 0x68, 0x5f, 0xda, 0x94, 0xd4, 0xa9, 0x2d, 0x25, 0x8b, 0x02, 0xf5, 0x8e, 0x49, 0x7a, 0x10,
0xf2, 0x64, 0xe6, 0x76, 0x3c, 0x03, 0xea, 0x7f, 0x01, 0x2b, 0x25, 0x12, 0xd4, 0x9c, 0x7c, 0x7d,
0xf8, 0x97, 0xac, 0xc1, 0xdc, 0xa5, 0x17, 0x4c, 0x99, 0xb2, 0x60, 0xd9, 0xf8, 0xbc, 0xf6, 0xc8,
0xa1, 0x1f, 0xc3, 0x72, 0x3e, 0xa7, 0x3a, 0x5b, 0x02, 0x8d, 0x4c, 0xc4, 0x2d, 0x57, 0xfc, 0x47,
0x51, 0x20, 0xdd, 0x93, 0xc8, 0xcf, 0x8c, 0x06, 0xe9, 0x70, 0x31, 0x9a, 0x0e, 0xff, 0xdf, 0xe4,
0x2c, 0xe8, 0x03, 0x58, 0x31, 0xc6, 0xbf, 0x63, 0xa2, 0xdf, 0x38, 0xb0, 0x72, 0xcc, 0xae, 0x94,
0xb8, 0xf5, 0x54, 0x8f, 0xa0, 0xc1, 0x67, 0xb1, 0x54, 0xb1, 0xc5, 0xbd, 0xfb, 0x4a, 0x5a, 0x25,
0xba, 0x1d, 0xd5, 0x7c, 0x39, 0x8b, 0x99, 0x2b, 0x46, 0xd0, 0x17, 0xd0, 0x36, 0x40, 0xb2, 0x01,
0xab, 0xaf, 0x9e, 0xbf, 0x3c, 0x3e, 0x38, 0x3d, 0x1d, 0x9c, 0x7c, 0xf5, 0xe5, 0x0f, 0x0e, 0xfe,
0x6c, 0x70, 0xb8, 0x7f, 0x7a, 0xb8, 0x7c, 0x8b, 0xac, 0x03, 0x39, 0x3e, 0x38, 0x7d, 0x79, 0xf0,
0xd4, 0xc2, 0x1d, 0xb2, 0x04, 0x6d, 0x13, 0xa8, 0xd1, 0x3e, 0xf4, 0x8e, 0xd9, 0xd5, 0x2b, 0x9f,
0x87, 0x2c, 0x4d, 0xed, 0xe9, 0xe9, 0x0e, 0x10, 0x73, 0x4d, 0x6a, 0x9b, 0x3d, 0x58, 0xf0, 0x24,
0xa4, 0x5d, 0xab, 0x6a, 0xd2, 0xaf, 0x80, 0x3c, 0x89, 0xc2, 0x90, 0x0d, 0xf9, 0x09, 0x63, 0x89,
0xde, 0xec, 0xef, 0x1b, 0x72, 0x6d, 0xef, 0x6d, 0xa8, 0xcd, 0x16, 0x35, 0x51, 0x09, 0x9c, 0x40,
0x23, 0x66, 0xc9, 0x44, 0x88, 0xbb, 0xe9, 0x8a, 0xff, 0x74, 0x17, 0x56, 0x2d, 0xb6, 0xf9, 0x3a,
0x62, 0xc6, 0x92, 0x81, 0x92, 0xf8, 0x9c, 0xab, 0x9b, 0xf4, 0x5f, 0x1c, 0x68, 0x1c, 0xbe, 0x3c,
0x7a, 0x42, 0xfa, 0xd0, 0xf4, 0xc3, 0x61, 0x34, 0x41, 0xa7, 0xe1, 0x08, 0x8e, 0x59, 0xfb, 0xc6,
0x38, 0x70, 0x17, 0x5a, 0xc2, 0xd7, 0xa0, 0xa7, 0x16, 0x66, 0xd4, 0x71, 0x73, 0x00, 0xa3, 0x04,
0x7b, 0x13, 0xfb, 0x89, 0x08, 0x03, 0xda, 0xb9, 0x37, 0x84, 0xb1, 0x95, 0x3b, 0xd0, 0x82, 0x13,
0x76, 0x19, 0x0d, 0x25, 0x38, 0x62, 0x81, 0x37, 0x13, 0xce, 0xab, 0xeb, 0x96, 0x70, 0xfa, 0x5f,
0x75, 0xe8, 0xee, 0x0f, 0xb9, 0x7f, 0xc9, 0x94, 0xa3, 0x10, 0x2b, 0x14, 0x80, 0x5a, 0xbb, 0x6a,
0x91, 0xfb, 0xd0, 0x4d, 0xd8, 0x24, 0xe2, 0x6c, 0xa0, 0x4c, 0x57, 0x1a, 0xa9, 0x0d, 0x22, 0xd5,
0x50, 0x32, 0x1a, 0xc4, 0xe8, 0x72, 0xc4, 0x5e, 0x5a, 0xae, 0x0d, 0xa2, 0x10, 0x11, 0x40, 0x21,
0xe2, 0x2e, 0x1a, 0xae, 0x6e, 0xa2, 0xec, 0x86, 0x5e, 0xec, 0x0d, 0x7d, 0x2e, 0xd7, 0x5c, 0x77,
0xb3, 0x36, 0xf2, 0x0e, 0xa2, 0xa1, 0x17, 0x0c, 0xce, 0xbc, 0xc0, 0x0b, 0x87, 0x4c, 0x05, 0x2f,
0x1b, 0x24, 0x1f, 0xc3, 0xa2, 0x5a, 0x92, 0x26, 0x93, 0x31, 0xac, 0x80, 0xa2, 0x4c, 0xa7, 0x61,
0xca, 0x38, 0x0f, 0xd8, 0x28, 0x23, 0x6d, 0x0a, 0xd2, 0x72, 0x07, 0x79, 0x08, 0xab, 0x32, 0x06,
0xa6, 0x1e, 0x8f, 0xd2, 0x0b, 0x3f, 0x1d, 0xa4, 0x2c, 0xe4, 0xbd, 0x96, 0xa0, 0xaf, 0xea, 0x22,
0x8f, 0x60, 0xa3, 0x00, 0x27, 0x6c, 0xc8, 0xfc, 0x4b, 0x36, 0xea, 0x81, 0x18, 0x75, 0x53, 0x37,
0xb9, 0x07, 0x6d, 0x0c, 0xfd, 0xd3, 0x78, 0xe4, 0x71, 0x96, 0xf6, 0xda, 0x42, 0x42, 0x26, 0x44,
0x3e, 0x85, 0x6e, 0xcc, 0xa4, 0x2f, 0xbe, 0xe0, 0xc1, 0x30, 0xed, 0x75, 0x84, 0x03, 0x6c, 0x2b,
0x2d, 0x47, 0x2d, 0x74, 0x6d, 0x0a, 0x7a, 0x1b, 0x56, 0x8f, 0xfc, 0x94, 0xab, 0x53, 0xce, 0x8c,
0xed, 0x10, 0xd6, 0x6c, 0x58, 0xa9, 0xf9, 0x43, 0x68, 0xaa, 0x23, 0xc3, 0x05, 0x20, 0xf3, 0x35,
0xc5, 0xdc, 0xd2, 0x16, 0x37, 0xa3, 0xa2, 0xbf, 0xac, 0x41, 0x03, 0x2d, 0x45, 0x58, 0xc8, 0xf4,
0x6c, 0x90, 0x7b, 0x4f, 0xdd, 0x34, 0x6d, 0xa7, 0x66, 0xd9, 0x8e, 0x69, 0xdd, 0x75, 0xcb, 0xba,
0x45, 0xca, 0x33, 0xe3, 0x4c, 0xc9, 0x5b, 0x6a, 0x8b, 0x81, 0xe4, 0xfd, 0x09, 0x1b, 0x5e, 0x0a,
0x95, 0xc9, 0xfa, 0x11, 0x41, 0x85, 0x4a, 0x3d, 0x2e, 0x47, 0x4b, 0x7d, 0xc9, 0xda, 0xba, 0x4f,
0x8c, 0x5c, 0xc8, 0xfb, 0xc4, 0xb8, 0x1e, 0x2c, 0xf8, 0xe1, 0x59, 0x34, 0x0d, 0x47, 0x42, 0x29,
0x9a, 0xae, 0x6e, 0xa2, 0xa9, 0xc6, 0x22, 0x0a, 0xfa, 0x13, 0xa6, 0x14, 0x20, 0x07, 0x28, 0xc1,
0x70, 0x97, 0x0a, 0x9f, 0x91, 0x09, 0xf9, 0x33, 0x58, 0x31, 0x30, 0x25, 0xe1, 0x8f, 0x60, 0x0e,
0x77, 0xaf, 0x13, 0x22, 0x7d, 0x76, 0xc2, 0xd9, 0xc8, 0x1e, 0xba, 0x0c, 0x8b, 0xcf, 0x18, 0x7f,
0x1e, 0x9e, 0x47, 0x9a, 0xd3, 0x7f, 0xd4, 0x60, 0x29, 0x83, 0x14, 0xa3, 0x2d, 0x58, 0xf2, 0x47,
0x2c, 0xe4, 0x3e, 0x9f, 0x0d, 0xac, 0xa8, 0x5a, 0x84, 0x31, 0x82, 0x79, 0x81, 0xef, 0xa5, 0xca,
0x74, 0x65, 0x83, 0xec, 0xc1, 0x1a, 0xea, 0x96, 0x56, 0x97, 0xec, 0xd8, 0x65, 0x30, 0xaf, 0xec,
0x43, 0x73, 0x40, 0x5c, 0xba, 0x86, 0x7c, 0x88, 0x74, 0x49, 0x55, 0x5d, 0x28, 0x35, 0xc9, 0x09,
0xb7, 0x2c, 0xbd, 0x51, 0x0e, 0x94, 0x12, 0xd7, 0x79, 0x99, 0x48, 0x14, 0x13, 0x57, 0x23, 0xf9,
0x6d, 0x96, 0x92, 0xdf, 0x2d, 0x58, 0x4a, 0x67, 0xe1, 0x90, 0x8d, 0x06, 0x3c, 0xc2, 0x79, 0xfd,
0x50, 0x9c, 0x4e, 0xd3, 0x2d, 0xc2, 0x22, 0x4d, 0x67, 0x29, 0x0f, 0x19, 0x17, 0xa6, 0xd8, 0x74,
0x75, 0x93, 0xfe, 0x5c, 0xc4, 0x92, 0x2c, 0xe3, 0xfe, 0x4a, 0xd8, 0x1b, 0xd9, 0x84, 0x96, 0x9c,
0x27, 0xbd, 0xf0, 0x54, 0xce, 0xd4, 0x14, 0xc0, 0xe9, 0x85, 0x87, 0x09, 0xa5, 0xb5, 0x74, 0xa9,
0xd9, 0x6d, 0x81, 0x1d, 0xca, 0x95, 0xdf, 0x87, 0x45, 0x9d, 0xcb, 0xa7, 0x83, 0x80, 0x9d, 0x73,
0x9d, 0x28, 0x85, 0xd3, 0x09, 0x4e, 0x97, 0x1e, 0xb1, 0x73, 0x4e, 0x8f, 0x61, 0x45, 0x59, 0xd5,
0x8b, 0x98, 0xe9, 0xa9, 0xbf, 0x57, 0xf4, 0xa7, 0x32, 0x9e, 0xad, 0x2a, 0x6d, 0x31, 0xb3, 0xbb,
0x82, 0x93, 0xa5, 0x2e, 0x10, 0xd5, 0xfd, 0x24, 0x88, 0x52, 0xa6, 0x18, 0x52, 0xe8, 0x0c, 0x83,
0x28, 0x2d, 0xa6, 0x80, 0x26, 0x86, 0xf2, 0x49, 0xa7, 0xc3, 0x21, 0x5a, 0xa3, 0x8c, 0x88, 0xba,
0x49, 0x7f, 0xe9, 0xc0, 0xaa, 0xe0, 0xa6, 0xed, 0x3f, 0x4b, 0x2d, 0xde, 0x7f, 0x99, 0x9d, 0xa1,
0x99, 0x92, 0x7e, 0xa0, 0xae, 0x23, 0x81, 0x3f, 0xf1, 0x75, 0x50, 0x6c, 0x21, 0x72, 0x84, 0x00,
0xaa, 0xec, 0x79, 0x94, 0x0c, 0x99, 0x90, 0x58, 0xd3, 0x95, 0x0d, 0xfa, 0xef, 0x0e, 0xac, 0x88,
0x65, 0x9c, 0x72, 0x8f, 0x4f, 0x53, 0xb5, 0xb5, 0x3f, 0x86, 0x2e, 0x6e, 0x83, 0x69, 0x75, 0x55,
0x8b, 0x58, 0xcb, 0x2c, 0x4b, 0xa0, 0x92, 0xf8, 0xf0, 0x96, 0x6b, 0x13, 0x93, 0x2f, 0xa0, 0x63,
0x5e, 0xb6, 0x54, 0x7e, 0x7d, 0x47, 0xef, 0xa0, 0xa4, 0x15, 0x87, 0xb7, 0x5c, 0x6b, 0x00, 0x79,
0x0c, 0x20, 0xa2, 0x98, 0x60, 0x2b, 0xd6, 0x6b, 0x0c, 0x2f, 0x1d, 0xc4, 0xe1, 0x2d, 0xd7, 0x20,
0xff, 0xb2, 0x09, 0xf3, 0xd2, 0xb9, 0xd3, 0x67, 0xd0, 0xb5, 0x56, 0x6a, 0x25, 0x78, 0x1d, 0x99,
0xe0, 0x95, 0x12, 0xef, 0x5a, 0x45, 0xe2, 0xfd, 0x3f, 0x0e, 0x10, 0xd4, 0xa4, 0xc2, 0x51, 0x7d,
0x0c, 0x8b, 0xdc, 0x4b, 0xc6, 0x8c, 0x0f, 0xec, 0x3c, 0xa6, 0x80, 0x8a, 0x28, 0x14, 0x8d, 0xac,
0x68, 0xdf, 0x71, 0x4d, 0x88, 0xec, 0x00, 0x31, 0x9a, 0xfa, 0x9a, 0x24, 0xfd, 0x77, 0x45, 0x0f,
0x3a, 0x1a, 0x19, 0xaa, 0xf5, 0x3d, 0x42, 0x65, 0x42, 0x0d, 0x71, 0xe8, 0x95, 0x7d, 0xe8, 0xa2,
0xe3, 0x29, 0xde, 0xc1, 0x3c, 0xae, 0xf3, 0x01, 0xdd, 0xd6, 0x2e, 0x45, 0x98, 0x95, 0xf2, 0x18,
0x39, 0x40, 0x7f, 0xe7, 0xc0, 0x32, 0x6e, 0xdf, 0x52, 0x91, 0xcf, 0x41, 0x68, 0xdf, 0x7b, 0x6a,
0x88, 0x45, 0xfb, 0xff, 0x57, 0x90, 0x47, 0xd0, 0x12, 0x0c, 0xa3, 0x98, 0x85, 0x4a, 0x3f, 0x7a,
0xb6, 0x7e, 0xe4, 0x86, 0x7f, 0x78, 0xcb, 0xcd, 0x89, 0x0d, 0xed, 0x38, 0x80, 0xdb, 0x6a, 0x95,
0x85, 0x63, 0xfd, 0x04, 0xe6, 0x53, 0xb1, 0x53, 0x95, 0xde, 0xaf, 0xd9, 0x9c, 0xa5, 0x14, 0x5c,
0x45, 0x43, 0xff, 0xa6, 0x0e, 0xeb, 0x45, 0x3e, 0x2a, 0x9c, 0xfc, 0x18, 0x96, 0x4b, 0xa1, 0x40,
0x86, 0xa8, 0x4f, 0x6c, 0x31, 0x15, 0x06, 0x16, 0xe1, 0x12, 0x97, 0xfe, 0x3f, 0xd4, 0x60, 0xd1,
0x26, 0x42, 0x3d, 0xce, 0x82, 0x54, 0x1e, 0xb8, 0x2c, 0xac, 0x9c, 0x52, 0xd6, 0xaa, 0x52, 0x4a,
0x33, 0x71, 0xac, 0x7f, 0x5b, 0xe2, 0xd8, 0x78, 0xbf, 0xc4, 0x71, 0xae, 0x32, 0x71, 0x2c, 0x7a,
0x50, 0x79, 0xd7, 0xb7, 0x3d, 0x68, 0x7e, 0x1a, 0x0b, 0xef, 0x71, 0x1a, 0xdf, 0x83, 0xb5, 0x57,
0x5e, 0x10, 0x30, 0xfe, 0xa5, 0x9c, 0x42, 0x9f, 0xe9, 0x47, 0xd0, 0xb9, 0x92, 0x57, 0xa4, 0x41,
0x14, 0x06, 0x33, 0x95, 0x90, 0xb7, 0x15, 0xf6, 0x22, 0x0c, 0x66, 0xf4, 0x53, 0xb8, 0x5d, 0x18,
0x9a, 0xdf, 0x53, 0xf4, 0x36, 0x70, 0x98, 0xe3, 0xea, 0x26, 0xdd, 0x80, 0xdb, 0x6a, 0x19, 0xf6,
0x74, 0x74, 0x0f, 0xd6, 0x8b, 0x1d, 0xd5, 0xcc, 0xea, 0x39, 0xb3, 0x2f, 0x80, 0xfc, 0x68, 0xca,
0x92, 0x99, 0xa8, 0x3f, 0x64, 0x37, 0xcd, 0x8d, 0x62, 0x0a, 0x88, 0x17, 0xfc, 0x1f, 0xb0, 0x99,
0xae, 0xc7, 0xd4, 0xb2, 0x7a, 0x0c, 0x7d, 0x0c, 0xab, 0x16, 0x03, 0x35, 0xe3, 0x7d, 0x98, 0x17,
0x35, 0x0c, 0xad, 0x7b, 0x76, 0x9d, 0x43, 0xf5, 0xd1, 0xbf, 0x84, 0xfa, 0x61, 0x14, 0x9b, 0xd7,
0x09, 0xc7, 0xbe, 0x4e, 0x28, 0xdd, 0x19, 0x64, 0xaa, 0x21, 0x67, 0xb6, 0x41, 0x3c, 0x79, 0x6f,
0xc2, 0x31, 0x3f, 0x38, 0x8f, 0x92, 0x2b, 0x2f, 0x19, 0x29, 0x0d, 0x2a, 0xa0, 0xb8, 0xfa, 0x73,
0xa6, 0xb5, 0x07, 0xff, 0xd2, 0x5f, 0x39, 0x30, 0x27, 0x96, 0x84, 0xd9, 0x87, 0xcc, 0xe7, 0x65,
0x34, 0xc3, 0x6b, 0x9c, 0x23, 0x5c, 0x52, 0x11, 0x2e, 0x14, 0xd8, 0x6a, 0xc5, 0x02, 0x1b, 0xba,
0x35, 0xd9, 0xca, 0x2b, 0x57, 0x39, 0x40, 0x3e, 0x84, 0xc6, 0x45, 0x14, 0x63, 0xaa, 0x85, 0x62,
0x01, 0x9d, 0xf1, 0x47, 0xb1, 0x2b, 0x70, 0xba, 0x0d, 0x4b, 0xc7, 0xd1, 0x88, 0x19, 0x49, 0xe3,
0x8d, 0xa7, 0x41, 0xff, 0xca, 0x81, 0xa6, 0x26, 0x26, 0x5b, 0xd0, 0x40, 0x9f, 0x5d, 0x70, 0x89,
0xd9, 0x85, 0x19, 0xe9, 0x5c, 0x41, 0x81, 0x06, 0x20, 0xdc, 0xac, 0xf6, 0x0e, 0xb5, 0x2c, 0x99,
0xc9, 0xd3, 0x3d, 0x8c, 0x32, 0x62, 0xcd, 0x05, 0xa3, 0x2c, 0xa0, 0xf4, 0xd7, 0x0e, 0x74, 0xad,
0x39, 0x30, 0xee, 0x04, 0x5e, 0xca, 0xd5, 0x5d, 0x47, 0x09, 0xd1, 0x84, 0xcc, 0x0b, 0x46, 0xcd,
0xbe, 0x60, 0x64, 0x09, 0x6e, 0xdd, 0x4c, 0x70, 0x1f, 0x42, 0x4b, 0xdd, 0x26, 0x98, 0x96, 0x9b,
0x2e, 0x3f, 0xe2, 0x8c, 0xba, 0x14, 0x90, 0x13, 0xd1, 0xc7, 0xd0, 0x36, 0x7a, 0x70, 0xc2, 0x90,
0xf1, 0xab, 0x28, 0x79, 0xad, 0x6f, 0x34, 0xaa, 0x99, 0x55, 0x6f, 0x6a, 0x79, 0xf5, 0x86, 0xfe,
0xb3, 0x03, 0x5d, 0xd4, 0x09, 0x3f, 0x1c, 0x9f, 0x44, 0x81, 0x3f, 0x9c, 0x09, 0xdd, 0xd0, 0xc7,
0x8f, 0xf7, 0x6e, 0xee, 0x65, 0xba, 0x61, 0xc3, 0xe8, 0xc5, 0x26, 0x7e, 0x28, 0xae, 0x6c, 0x4a,
0x33, 0xb2, 0x36, 0xea, 0xf2, 0x39, 0x43, 0x37, 0x94, 0xb2, 0xc1, 0x04, 0xe3, 0xa1, 0x94, 0xa8,
0x0d, 0x62, 0x66, 0x8e, 0x40, 0xe2, 0x71, 0x36, 0x98, 0xf8, 0x41, 0xe0, 0x4b, 0x5a, 0xa9, 0xb3,
0x55, 0x5d, 0xf4, 0x5f, 0x6b, 0xd0, 0x56, 0x76, 0x7f, 0x30, 0x1a, 0x33, 0xd4, 0x4f, 0xed, 0x5a,
0x33, 0x83, 0x32, 0x10, 0xdd, 0x6f, 0x39, 0x63, 0x03, 0x29, 0x1e, 0x60, 0xbd, 0x7c, 0x80, 0x18,
0xb8, 0xa3, 0x11, 0xfb, 0x14, 0xf3, 0x03, 0x55, 0xc5, 0xce, 0x01, 0xdd, 0xbb, 0x27, 0x7a, 0xe7,
0xf2, 0x5e, 0x01, 0x58, 0x7e, 0x7e, 0xbe, 0xe0, 0xe7, 0x1f, 0x41, 0x47, 0xb1, 0x11, 0x72, 0x17,
0xbe, 0x37, 0x57, 0x65, 0xeb, 0x4c, 0x5c, 0x8b, 0x52, 0x8f, 0xdc, 0xd3, 0x23, 0x9b, 0xdf, 0x36,
0x52, 0x53, 0xe2, 0xbd, 0x5a, 0x09, 0xef, 0x59, 0xe2, 0xc5, 0x17, 0xda, 0x97, 0x8e, 0xb2, 0xca,
0xab, 0x80, 0xc9, 0x36, 0xcc, 0xe1, 0x30, 0xed, 0xce, 0xaa, 0xcd, 0x4b, 0x92, 0x90, 0x2d, 0x98,
0x63, 0xa3, 0xb1, 0xf0, 0x0d, 0xa6, 0xae, 0x1a, 0x67, 0xe4, 0x4a, 0x02, 0x34, 0x76, 0x44, 0x0b,
0xc6, 0x6e, 0xfb, 0xc2, 0x79, 0x6c, 0x3e, 0x1f, 0xd1, 0x35, 0x20, 0xc7, 0x52, 0x6b, 0xcd, 0x0b,
0xe5, 0x5f, 0xd7, 0xa1, 0x6d, 0xc0, 0x68, 0xb7, 0x63, 0x5c, 0xf0, 0x60, 0xe4, 0x7b, 0x13, 0xc6,
0x59, 0xa2, 0x34, 0xb5, 0x80, 0x0a, 0x97, 0x79, 0x39, 0x1e, 0x44, 0x53, 0x3e, 0x18, 0xb1, 0x71,
0xc2, 0x64, 0x55, 0xd4, 0x71, 0x0b, 0x28, 0xd2, 0x4d, 0xbc, 0x37, 0x26, 0x9d, 0xd4, 0x87, 0x02,
0xaa, 0x73, 0x39, 0x29, 0xa3, 0x46, 0x9e, 0xcb, 0x49, 0x89, 0x14, 0x3d, 0xce, 0x5c, 0x85, 0xc7,
0xf9, 0x0c, 0xd6, 0xa5, 0x6f, 0x51, 0xb6, 0x39, 0x28, 0xa8, 0xc9, 0x0d, 0xbd, 0x64, 0x1b, 0x96,
0x71, 0xcd, 0x5a, 0xc1, 0x53, 0xff, 0xe7, 0xb2, 0x62, 0xe4, 0xb8, 0x25, 0x1c, 0x69, 0xd1, 0x1c,
0x2d, 0x5a, 0x59, 0x32, 0x2a, 0xe1, 0x82, 0xd6, 0x7b, 0x63, 0xd3, 0xb6, 0x14, 0x6d, 0x01, 0xa7,
0x9b, 0x70, 0x47, 0xa8, 0xc9, 0xcb, 0x28, 0x8e, 0x82, 0x68, 0x3c, 0x3b, 0x9d, 0x9e, 0xa5, 0xc3,
0xc4, 0x8f, 0x31, 0x6d, 0xa4, 0xff, 0xe6, 0xc0, 0xaa, 0xd5, 0xab, 0x72, 0xd9, 0x3f, 0x94, 0x3a,
0x9b, 0xd5, 0x89, 0xa4, 0x66, 0xad, 0x18, 0x9e, 0x4d, 0x12, 0xca, 0xa4, 0xfd, 0x2b, 0x55, 0x3a,
0xda, 0x87, 0x25, 0x3d, 0xb5, 0x1e, 0x28, 0xd5, 0xac, 0x57, 0x56, 0x33, 0x35, 0x7e, 0x51, 0x0d,
0xd0, 0x2c, 0xfe, 0x44, 0x26, 0x40, 0x6c, 0x24, 0x36, 0x81, 0xce, 0x16, 0xc7, 0xf7, 0xf5, 0x78,
0xd1, 0xf5, 0xc4, 0x1c, 0xe2, 0xb6, 0x87, 0x19, 0x98, 0xd2, 0xbf, 0x75, 0x00, 0xf2, 0xd5, 0xe1,
0xc9, 0xe7, 0xde, 0x19, 0xf7, 0xd0, 0x32, 0x3c, 0x31, 0xa6, 0x40, 0x56, 0x82, 0x28, 0xdd, 0x4d,
0x5b, 0x63, 0x98, 0x53, 0x3c, 0x80, 0xa5, 0x71, 0x10, 0x9d, 0x89, 0xf0, 0xe9, 0xf1, 0x69, 0xc2,
0x52, 0x55, 0x40, 0x5d, 0x94, 0xf0, 0xf7, 0x15, 0x9a, 0x47, 0x87, 0x86, 0x11, 0x1d, 0xe8, 0xdf,
0xd5, 0xb2, 0x7b, 0x77, 0xbe, 0xe7, 0x1b, 0xcd, 0x88, 0xec, 0x95, 0xbc, 0xdf, 0x0d, 0xd7, 0x5c,
0x91, 0xbe, 0x9f, 0x7c, 0x6b, 0x6e, 0xfa, 0x18, 0x16, 0x13, 0xe9, 0x5e, 0xb4, 0xef, 0x69, 0xbc,
0xc3, 0xf7, 0x74, 0x13, 0x2b, 0xb0, 0xfc, 0x1e, 0x2c, 0x7b, 0xa3, 0x4b, 0x96, 0x70, 0x5f, 0xa4,
0x9e, 0x22, 0x7e, 0x4b, 0x8f, 0xb9, 0x64, 0xe0, 0x22, 0xac, 0x3e, 0x80, 0xa5, 0xa1, 0x2c, 0x67,
0x67, 0x94, 0xea, 0x91, 0x2a, 0x87, 0x91, 0x90, 0xfe, 0x93, 0xbe, 0xe2, 0xdb, 0x67, 0x78, 0xb3,
0x44, 0xcc, 0xdd, 0xd5, 0x0a, 0xbb, 0xfb, 0xae, 0xba, 0x92, 0x8f, 0x74, 0x75, 0x44, 0x15, 0x3e,
0x24, 0xa8, 0xca, 0x23, 0xb6, 0x48, 0x1b, 0xef, 0x23, 0x52, 0xba, 0x03, 0x4b, 0xa7, 0x8c, 0xef,
0xe3, 0x09, 0x6a, 0xcf, 0xb7, 0x09, 0xad, 0x90, 0x5d, 0x0d, 0xe4, 0x11, 0xcb, 0x38, 0xdd, 0x0c,
0xd9, 0x95, 0xa0, 0xa1, 0x04, 0x96, 0x73, 0x7a, 0x99, 0x63, 0xd2, 0xbf, 0xaf, 0xc1, 0xc2, 0xf3,
0xf0, 0x32, 0xf2, 0x87, 0xe2, 0x92, 0x3d, 0x61, 0x93, 0x48, 0xbf, 0xa2, 0xe0, 0x7f, 0x0c, 0xfb,
0xa2, 0x26, 0x1b, 0x73, 0x75, 0xfb, 0xd5, 0x4d, 0x0c, 0x81, 0x49, 0xfe, 0x64, 0x27, 0xb5, 0xcd,
0x40, 0xc8, 0x3a, 0xcc, 0x27, 0xe6, 0xf3, 0xa2, 0x6a, 0xe5, 0x4f, 0x48, 0x73, 0xc6, 0x13, 0x92,
0x28, 0xb7, 0xc8, 0x72, 0xb3, 0x38, 0x92, 0xa6, 0xab, 0x9b, 0x22, 0x7d, 0x4d, 0x98, 0xaa, 0xd7,
0x63, 0x30, 0x5d, 0x50, 0xe9, 0xab, 0x09, 0x62, 0xc0, 0x95, 0x03, 0x24, 0x8d, 0x74, 0x48, 0x26,
0x84, 0x09, 0x48, 0xf1, 0x85, 0xb2, 0x25, 0xd5, 0xa4, 0x00, 0xd3, 0xaf, 0x81, 0xec, 0x8f, 0x46,
0x4a, 0x2a, 0x59, 0x36, 0x9e, 0xef, 0xc7, 0xb1, 0xf6, 0x53, 0xc1, 0xb7, 0x56, 0xcd, 0xf7, 0x00,
0xda, 0x27, 0xc6, 0x13, 0xab, 0x10, 0xa0, 0x7e, 0x5c, 0x55, 0x42, 0x37, 0x10, 0x63, 0xc2, 0x9a,
0x39, 0x21, 0xfd, 0x23, 0x20, 0x47, 0x7e, 0xca, 0xb3, 0xf5, 0x65, 0xf7, 0x24, 0x7d, 0xd9, 0x34,
0xef, 0x49, 0x0a, 0x13, 0xf7, 0xa4, 0x7d, 0x59, 0xfe, 0x2e, 0x6e, 0x6c, 0x1b, 0x9a, 0xbe, 0x84,
0xb4, 0xff, 0x5c, 0x54, 0x8a, 0xa7, 0x29, 0xb3, 0x7e, 0x8c, 0xf4, 0x0a, 0xb4, 0xdc, 0xf3, 0xaf,
0x1c, 0x58, 0x50, 0x5b, 0xc3, 0x38, 0x65, 0x3d, 0x2e, 0xab, 0xeb, 0xac, 0x89, 0x55, 0x3f, 0x23,
0x96, 0x4f, 0xba, 0x5e, 0x75, 0xd2, 0x04, 0x1a, 0xb1, 0xc7, 0x2f, 0x44, 0x12, 0xdb, 0x72, 0xc5,
0x7f, 0x7d, 0x29, 0x99, 0xcb, 0x2f, 0x25, 0xaa, 0xd4, 0xaf, 0x16, 0x95, 0x55, 0xa1, 0xbf, 0x94,
0xa5, 0xfe, 0x1c, 0xce, 0x65, 0xa0, 0x16, 0x58, 0x94, 0x81, 0x22, 0x75, 0xb3, 0x7e, 0xda, 0x87,
0xde, 0x53, 0x16, 0x30, 0xce, 0xf6, 0x83, 0xa0, 0xc8, 0x7f, 0x13, 0xee, 0x54, 0xf4, 0x29, 0x5b,
0xfb, 0x3e, 0xac, 0x3c, 0x65, 0x67, 0xd3, 0xf1, 0x11, 0xbb, 0xcc, 0x6b, 0x16, 0x04, 0x1a, 0xe9,
0x45, 0x74, 0xa5, 0xce, 0x4b, 0xfc, 0x27, 0x1f, 0x00, 0x04, 0x48, 0x33, 0x48, 0x63, 0x36, 0x54,
0xda, 0xd4, 0x12, 0xc8, 0x69, 0xcc, 0x86, 0xf4, 0x33, 0x20, 0x26, 0x1f, 0xb5, 0x05, 0xb4, 0x80,
0xe9, 0xd9, 0x20, 0x9d, 0xa5, 0x9c, 0x4d, 0xb4, 0xf1, 0x9b, 0x10, 0x7d, 0x00, 0x9d, 0x13, 0x6f,
0xe6, 0xb2, 0x6f, 0xd4, 0x9b, 0x3d, 0xde, 0x89, 0xbc, 0x19, 0xaa, 0x67, 0x76, 0x27, 0x12, 0xdd,
0x34, 0x81, 0x79, 0x49, 0x88, 0x4c, 0x47, 0x2c, 0xe5, 0x7e, 0x28, 0xcb, 0x3d, 0x8a, 0xa9, 0x01,
0x95, 0x8e, 0xbb, 0x56, 0x71, 0xdc, 0x2a, 0x75, 0xd1, 0xaf, 0x3c, 0xea, 0x5c, 0x2d, 0x6c, 0x7b,
0x0f, 0xba, 0x56, 0x61, 0x80, 0x2c, 0x40, 0x7d, 0xff, 0xe8, 0x68, 0xf9, 0x16, 0x69, 0xc3, 0xc2,
0x8b, 0x93, 0x83, 0xe3, 0xe7, 0xc7, 0xcf, 0x96, 0x1d, 0x6c, 0x3c, 0x39, 0x7a, 0x71, 0x8a, 0x8d,
0xda, 0xde, 0x6f, 0x37, 0xa0, 0x95, 0x65, 0x8f, 0xe4, 0x67, 0xd0, 0xb5, 0xca, 0x00, 0x64, 0x53,
0x1d, 0x61, 0x55, 0x5d, 0xa1, 0x7f, 0xb7, 0xba, 0x53, 0x1d, 0xd5, 0x87, 0xbf, 0xf8, 0xdd, 0x7f,
0xfe, 0xba, 0xd6, 0x23, 0xeb, 0xbb, 0x97, 0x9f, 0xee, 0xaa, 0x7b, 0xfe, 0xae, 0x28, 0x67, 0xcb,
0xea, 0xf9, 0x6b, 0x58, 0xb4, 0xcb, 0x04, 0xe4, 0xae, 0xed, 0xac, 0x0b, 0xb3, 0x7d, 0x70, 0x43,
0xaf, 0x9a, 0xee, 0xae, 0x98, 0x6e, 0x9d, 0xac, 0x99, 0xd3, 0x65, 0x59, 0x1d, 0x13, 0xef, 0x1d,
0xe6, 0xd7, 0x26, 0x44, 0xf3, 0xab, 0xfe, 0x0a, 0xa5, 0x7f, 0xa7, 0xfc, 0x65, 0x89, 0xfa, 0x14,
0x85, 0xf6, 0xc4, 0x54, 0x84, 0x2c, 0xe3, 0x54, 0xe6, 0xc7, 0x26, 0xe4, 0xa7, 0xd0, 0xca, 0x5e,
0xd6, 0xc9, 0x86, 0xf1, 0x1d, 0x81, 0xf9, 0x56, 0xdf, 0xef, 0x95, 0x3b, 0xd4, 0x26, 0x36, 0x05,
0xe7, 0xdb, 0xb4, 0xc4, 0xf9, 0x73, 0x67, 0x9b, 0x1c, 0xc1, 0x6d, 0xe5, 0x31, 0xce, 0xd8, 0xff,
0x65, 0x27, 0x15, 0xdf, 0xc8, 0x3c, 0x74, 0xc8, 0x63, 0x68, 0xea, 0x8f, 0x0d, 0xc8, 0x7a, 0xf5,
0x17, 0x0f, 0xfd, 0x8d, 0x12, 0xae, 0x0c, 0x65, 0x1f, 0x20, 0x7f, 0x5b, 0x27, 0xbd, 0x9b, 0x3e,
0x01, 0xc8, 0x84, 0x58, 0xf1, 0x10, 0x3f, 0x16, 0x9f, 0x16, 0xd8, 0x4f, 0xf7, 0xe4, 0x3b, 0x39,
0x7d, 0xe5, 0xa3, 0xfe, 0x3b, 0x18, 0xd2, 0x75, 0x21, 0xbb, 0x65, 0xb2, 0x88, 0xb2, 0x0b, 0xd9,
0x95, 0x7e, 0xf9, 0xfb, 0x09, 0xb4, 0x8d, 0x07, 0x78, 0x62, 0x14, 0x5a, 0x0b, 0x6f, 0xfd, 0xfd,
0x7e, 0x55, 0x97, 0xe2, 0xbe, 0x26, 0xb8, 0x2f, 0xd2, 0x16, 0x72, 0x17, 0x8f, 0x4d, 0x78, 0x24,
0x3f, 0x42, 0xe3, 0x51, 0x2f, 0x72, 0x24, 0xff, 0x38, 0xc0, 0x7e, 0xb7, 0xcb, 0xce, 0xbb, 0xf4,
0x78, 0x47, 0x57, 0x04, 0xd7, 0x36, 0xc9, 0xb9, 0x92, 0x1f, 0xc2, 0x82, 0x7a, 0x99, 0x23, 0xb7,
0xf3, 0x73, 0x35, 0xee, 0x5a, 0xfd, 0xf5, 0x22, 0xac, 0x98, 0xad, 0x0a, 0x66, 0x5d, 0xd2, 0x46,
0x66, 0x63, 0xc6, 0x7d, 0xe4, 0x11, 0xc0, 0x92, 0x5d, 0x2b, 0x4d, 0x33, 0x33, 0xab, 0x2c, 0x00,
0x67, 0x66, 0x56, 0x5d, 0x9d, 0xb5, 0xcd, 0x4c, 0x9b, 0xd7, 0xae, 0xae, 0x6d, 0xff, 0x39, 0x74,
0xcc, 0x67, 0x60, 0xd2, 0x37, 0x76, 0x5e, 0x78, 0x32, 0xee, 0x6f, 0x56, 0xf6, 0xd9, 0xe2, 0x26,
0x1d, 0x73, 0x1a, 0xf2, 0x13, 0x58, 0x32, 0x5e, 0x22, 0x4e, 0x67, 0xe1, 0x30, 0x3b, 0xce, 0xf2,
0x0b, 0x45, 0xbf, 0x2a, 0xf7, 0xa3, 0x1b, 0x82, 0xf1, 0x0a, 0xb5, 0x18, 0xe3, 0x51, 0x3e, 0x81,
0xb6, 0xc1, 0xe3, 0x5d, 0x7c, 0x37, 0x8c, 0x2e, 0xf3, 0x55, 0xe0, 0xa1, 0x43, 0x7e, 0xe3, 0x40,
0xc7, 0x7c, 0xd7, 0x22, 0xd6, 0x6d, 0xa6, 0xc0, 0xa7, 0x67, 0xf6, 0x99, 0x8c, 0xe8, 0xd7, 0x62,
0x91, 0x27, 0xdb, 0xc7, 0x96, 0x90, 0xdf, 0x5a, 0x95, 0xea, 0x1d, 0xf3, 0x2b, 0xaa, 0xeb, 0x62,
0xa7, 0xf9, 0x82, 0x73, 0xbd, 0xfb, 0x56, 0x3c, 0x77, 0x5d, 0x3f, 0x74, 0xc8, 0xe7, 0xf2, 0x63,
0x38, 0x9d, 0x68, 0x10, 0xc3, 0xc0, 0x8b, 0x62, 0x33, 0x3f, 0x31, 0xdb, 0x72, 0x1e, 0x3a, 0xe4,
0x2f, 0xe4, 0x07, 0x54, 0x6a, 0xac, 0x90, 0xfe, 0xfb, 0x8e, 0xa7, 0xf7, 0xc5, 0x8e, 0x3e, 0xa4,
0x77, 0xac, 0x1d, 0x15, 0x3d, 0xdc, 0x09, 0x40, 0x9e, 0x35, 0x92, 0x42, 0x0a, 0x95, 0xd9, 0x7e,
0x39, 0xb1, 0xb4, 0x4f, 0x55, 0x67, 0x5a, 0xc8, 0xf1, 0x67, 0x52, 0x21, 0x15, 0x7d, 0x9a, 0x1d,
0x6b, 0x39, 0xfb, 0xeb, 0xf7, 0xab, 0xba, 0x14, 0xff, 0xef, 0x0a, 0xfe, 0x1f, 0x90, 0x4d, 0x93,
0xff, 0xee, 0x5b, 0x33, 0x5b, 0xbc, 0x26, 0x5f, 0x43, 0xf7, 0x28, 0x8a, 0x5e, 0x4f, 0xe3, 0xec,
0x32, 0x60, 0xe7, 0x3f, 0x98, 0xb1, 0xf6, 0x0b, 0x9b, 0xa2, 0x1f, 0x09, 0xce, 0x9b, 0xe4, 0x8e,
0xcd, 0x39, 0xcf, 0x61, 0xaf, 0x89, 0x07, 0x2b, 0x99, 0xdf, 0xcf, 0x36, 0xd2, 0xb7, 0xf9, 0x98,
0xa9, 0x64, 0x69, 0x0e, 0x2b, 0x12, 0x67, 0x73, 0xa4, 0x9a, 0xe7, 0x43, 0x87, 0x9c, 0x40, 0xe7,
0x29, 0x1b, 0x46, 0x23, 0xa6, 0x72, 0x96, 0xd5, 0x7c, 0xe5, 0x59, 0xae, 0xd3, 0xef, 0x5a, 0xa0,
0xed, 0x09, 0x62, 0x6f, 0x96, 0xb0, 0x6f, 0x76, 0xdf, 0xaa, 0x64, 0xe8, 0x5a, 0x7b, 0x02, 0x9d,
0xc0, 0x59, 0x9e, 0xa0, 0x90, 0xf1, 0x59, 0x9e, 0xa0, 0x94, 0xf1, 0x59, 0x9e, 0x40, 0x27, 0x90,
0x24, 0xc0, 0x3c, 0xb0, 0x90, 0x24, 0x66, 0xd1, 0xe3, 0xa6, 0xd4, 0xb2, 0x7f, 0xef, 0x66, 0x02,
0x7b, 0xb6, 0x6d, 0x7b, 0xb6, 0x53, 0xe8, 0x3e, 0x65, 0x52, 0x58, 0xb2, 0x0c, 0xd7, 0xb7, 0x5d,
0x8b, 0x59, 0xb2, 0x2b, 0xba, 0x1d, 0xd1, 0x67, 0x3b, 0x7a, 0x51, 0x03, 0x23, 0x3f, 0x85, 0xf6,
0x33, 0xc6, 0x75, 0xdd, 0x2d, 0x8b, 0xc1, 0x85, 0x42, 0x5c, 0xbf, 0xa2, 0x6c, 0x47, 0xef, 0x09,
0x6e, 0x7d, 0xd2, 0xcb, 0xb8, 0xed, 0xb2, 0xd1, 0x98, 0x49, 0x27, 0x30, 0xf0, 0x47, 0xd7, 0xe4,
0xc7, 0x82, 0x79, 0x56, 0x94, 0x5f, 0x37, 0xaa, 0x39, 0x26, 0xf3, 0xa5, 0x02, 0x5e, 0xc5, 0x19,
0xef, 0xf8, 0xbb, 0x6f, 0x55, 0x69, 0xfc, 0x9a, 0x84, 0xd0, 0x36, 0x1e, 0x5a, 0x32, 0x83, 0x2a,
0xbf, 0xde, 0x64, 0x06, 0x55, 0xf1, 0x2e, 0x43, 0xb7, 0xc4, 0x3c, 0x94, 0xdc, 0xcb, 0xe7, 0x91,
0x6f, 0x31, 0xf9, 0x4c, 0xbb, 0x6f, 0xbd, 0x09, 0xbf, 0x26, 0xaf, 0xc4, 0xc7, 0x2b, 0x66, 0x6d,
0x31, 0xcf, 0x01, 0x8a, 0x65, 0xc8, 0x4c, 0x58, 0x46, 0x97, 0x9d, 0x17, 0xc8, 0xa9, 0x44, 0x64,
0x7c, 0x65, 0xa4, 0x53, 0x56, 0x8d, 0x55, 0x6b, 0xc9, 0x8d, 0xa5, 0xb4, 0x6c, 0x67, 0x15, 0xe5,
0x34, 0x9d, 0x59, 0xc9, 0x1a, 0x81, 0x91, 0x59, 0x59, 0x45, 0x06, 0x23, 0xb3, 0xb2, 0x8b, 0x09,
0x98, 0x59, 0xe5, 0x17, 0x93, 0x2c, 0xb3, 0x2a, 0xdd, 0x79, 0x32, 0x67, 0x58, 0xbe, 0xc5, 0x9c,
0xcd, 0x8b, 0x8f, 0xca, 0xff, 0xe0, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x14, 0x4c, 0x36, 0x7a,
0x86, 0x2e, 0x00, 0x00,
}

@ -442,8 +442,13 @@ message NodeInfo {
message LightningNode {
uint32 last_update = 1 [ json_name = "last_update" ];
string pub_key = 2 [ json_name = "pub_key" ];
string address = 3 [ json_name = "address" ];
string alias = 4 [ json_name = "alias" ];
string alias = 3 [ json_name = "alias" ];
repeated NodeAddress addresses = 4 [ json_name = "addresses" ];
}
message NodeAddress {
string network = 1 [ json_name = "network" ];
string addr = 2 [ json_name = "addr" ];
}
message RoutingPolicy {

@ -1111,11 +1111,14 @@
"pub_key": {
"type": "string"
},
"address": {
"type": "string"
},
"alias": {
"type": "string"
},
"addresses": {
"type": "array",
"items": {
"$ref": "#/definitions/lnrpcNodeAddress"
}
}
}
},
@ -1244,6 +1247,17 @@
"lnrpcNewWitnessAddressRequest": {
"type": "object"
},
"lnrpcNodeAddress": {
"type": "object",
"properties": {
"network": {
"type": "string"
},
"addr": {
"type": "string"
}
}
},
"lnrpcNodeInfo": {
"type": "object",
"properties": {

@ -50,6 +50,16 @@ func (c CreditsAmount) ToSatoshi() int64 {
return int64(c / 1000)
}
// addressType specifies the network protocol and version that should be used
// when connecting to a node at a particular address.
type addressType uint8
const (
tcp4Addr addressType = 1
tcp6Addr addressType = 2
onionAddr addressType = 3
)
// writeElement is a one-stop shop to write the big endian representation of
// any element which is to be serialized for the wire protocol. The passed
// io.Writer should be backed by an appropriatly sized byte slice, or be able
@ -292,16 +302,46 @@ func writeElement(w io.Writer, element interface{}) error {
}
case *net.TCPAddr:
var ip [16]byte
copy(ip[:], e.IP.To16())
if _, err := w.Write(ip[:]); err != nil {
if e.IP.To4() != nil {
var descriptor [1]byte
descriptor[0] = uint8(tcp4Addr)
if _, err := w.Write(descriptor[:]); err != nil {
return err
}
var ip [4]byte
copy(ip[:], e.IP.To4())
if _, err := w.Write(ip[:]); err != nil {
return err
}
} else {
var descriptor [1]byte
descriptor[0] = uint8(tcp6Addr)
if _, err := w.Write(descriptor[:]); err != nil {
return err
}
var ip [16]byte
copy(ip[:], e.IP.To16())
if _, err := w.Write(ip[:]); err != nil {
return err
}
}
var port [2]byte
binary.BigEndian.PutUint16(port[:], uint16(e.Port))
if _, err := w.Write(port[:]); err != nil {
return err
}
case []net.Addr:
// Write out the number of addresses.
if err := writeElement(w, uint16(len(e))); err != nil {
return err
}
var port [4]byte
binary.BigEndian.PutUint32(port[:], uint32(e.Port))
if _, err := w.Write(port[:]); err != nil {
return err
// Append the actual addresses.
for _, address := range e {
if err := writeElement(w, address); err != nil {
return err
}
}
case RGB:
err := writeElements(w,
@ -578,21 +618,44 @@ func readElement(r io.Reader, element interface{}) error {
TxPosition: binary.BigEndian.Uint16(txPosition[:]),
}
case **net.TCPAddr:
var ip [16]byte
if _, err = io.ReadFull(r, ip[:]); err != nil {
case *[]net.Addr:
var addresses []net.Addr
var numAddrs [2]byte
if _, err = io.ReadFull(r, numAddrs[:]); err != nil {
return err
}
var port [4]byte
if _, err = io.ReadFull(r, port[:]); err != nil {
return err
}
for i := 0; i < int(binary.BigEndian.Uint16(numAddrs[:])); i++ {
var descriptor [1]byte
if _, err = io.ReadFull(r, descriptor[:]); err != nil {
return err
}
*e = &net.TCPAddr{
IP: (net.IP)(ip[:]),
Port: int(binary.BigEndian.Uint32(port[:])),
address := &net.TCPAddr{}
switch descriptor[0] {
case 1:
var ip [4]byte
if _, err = io.ReadFull(r, ip[:]); err != nil {
return err
}
address.IP = (net.IP)(ip[:])
case 2:
var ip [16]byte
if _, err = io.ReadFull(r, ip[:]); err != nil {
return err
}
address.IP = (net.IP)(ip[:])
}
var port [2]byte
if _, err = io.ReadFull(r, port[:]); err != nil {
return err
}
address.Port = int(binary.BigEndian.Uint16(port[:]))
addresses = append(addresses, address)
}
*e = addresses
case *RGB:
err := readElements(r,
&e.red,

@ -56,7 +56,9 @@ var (
someSig, _ = btcec.ParseSignature(sigStr, btcec.S256())
someSigBytes = someSig.Serialize()
someAddress = &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8333}
someAddress = &net.TCPAddr{IP: (net.IP)([]byte{0x7f, 0x0, 0x0, 0x1}), Port: 8333}
someOtherAddress, _ = net.ResolveTCPAddr("tcp", "[2001:db8:85a3:0:0:8a2e:370:7334]:80")
someAddresses = []net.Addr{someAddress, someOtherAddress}
maxUint32 uint32 = (1 << 32) - 1
maxUint24 uint32 = (1 << 24) - 1

@ -87,27 +87,19 @@ type NodeAnnouncement struct {
// announcements.
Timestamp uint32
// Address includes two specification fields: 'ipv6' and
// 'port' on which the node is accepting incoming connections.
Address *net.TCPAddr
// NodeID is a public key which is used as node
// identification.
// NodeID is a public key which is used as node identification.
NodeID *btcec.PublicKey
// RGBColor is used to customize their node's appearance in
// maps and graphs
RGBColor RGB
// TODO(roasbeef): add the global features here
// pad is used to reserve to additional bytes for future
// usage.
pad uint16
// Alias is used to customize their node's appearance in maps
// and graphs
// Alias is used to customize their node's appearance in maps and graphs
Alias Alias
// Address includes two specification fields: 'ipv6' and 'port' on which
// the node is accepting incoming connections.
Addresses []net.Addr
}
// A compile time check to ensure NodeAnnouncement implements the
@ -131,27 +123,24 @@ func (a *NodeAnnouncement) Decode(r io.Reader, pver uint32) error {
return readElements(r,
&a.Signature,
&a.Timestamp,
&a.Address,
&a.NodeID,
&a.RGBColor,
&a.pad,
&a.Alias,
&a.Addresses,
)
}
// Encode serializes the target NodeAnnouncement into the passed io.Writer
// observing the protocol version specified.
//
// This is part of the lnwire.Message interface.
func (a *NodeAnnouncement) Encode(w io.Writer, pver uint32) error {
return writeElements(w,
a.Signature,
a.Timestamp,
a.Address,
a.NodeID,
a.RGBColor,
a.pad,
a.Alias,
a.Addresses,
)
}
@ -168,34 +157,19 @@ func (a *NodeAnnouncement) Command() uint32 {
//
// This is part of the lnwire.Message interface.
func (a *NodeAnnouncement) MaxPayloadLength(pver uint32) uint32 {
var length uint32
// Signature - 64 bytes
length += 64
// Timestamp - 4 bytes
length += 4
// Ipv6 - 16 bytes
length += 16
// Port - 4 bytes
length += 4
// NodeID - 33 bytes
length += 33
// RGBColor - 3 bytes
length += 3
// pad - 2 bytes
length += 2
// Alias - 32 bytes
length += 32
// NumAddresses - 2 bytes
// AddressDescriptor - 1 byte
// Ipv4 - 4 bytes (optional)
// Ipv6 - 16 bytes (optional)
// Port - 2 bytes (optional)
// 158
return length
// Base size, 140, but can be variable due to multiple addresses
return 8192
}
// DataToSign returns the part of the message that should be signed.
@ -205,11 +179,10 @@ func (a *NodeAnnouncement) DataToSign() ([]byte, error) {
var w bytes.Buffer
err := writeElements(&w,
a.Timestamp,
a.Address,
a.NodeID,
a.RGBColor,
a.pad,
a.Alias,
a.Addresses,
)
if err != nil {
return nil, err

@ -13,11 +13,10 @@ func TestNodeAnnouncementEncodeDecode(t *testing.T) {
cua := &NodeAnnouncement{
Signature: someSig,
Timestamp: maxUint32,
Address: someAddress,
NodeID: pubKey,
RGBColor: someRGB,
pad: maxUint16,
Alias: someAlias,
Addresses: someAddresses,
}
// Next encode the NA message into an empty bytes buffer.
@ -39,7 +38,7 @@ func TestNodeAnnouncementEncodeDecode(t *testing.T) {
}
}
func TestNodeAnnoucementValidation(t *testing.T) {
func TestNodeAnnouncementValidation(t *testing.T) {
getKeys := func(s string) (*btcec.PrivateKey, *btcec.PublicKey) {
return btcec.PrivKeyFromBytes(btcec.S256(), []byte(s))
}
@ -47,13 +46,11 @@ func TestNodeAnnoucementValidation(t *testing.T) {
nodePrivKey, nodePubKey := getKeys("node-id-1")
var hash []byte
na := &NodeAnnouncement{
Timestamp: maxUint32,
Address: someAddress,
Addresses: someAddresses,
NodeID: nodePubKey,
RGBColor: someRGB,
pad: maxUint16,
Alias: someAlias,
}
@ -68,15 +65,14 @@ func TestNodeAnnoucementValidation(t *testing.T) {
}
}
func TestNodeAnnoucementPayloadLength(t *testing.T) {
func TestNodeAnnouncementPayloadLength(t *testing.T) {
na := &NodeAnnouncement{
Signature: someSig,
Timestamp: maxUint32,
Address: someAddress,
NodeID: pubKey,
RGBColor: someRGB,
pad: maxUint16,
Alias: someAlias,
Addresses: someAddresses,
}
var b bytes.Buffer
@ -85,8 +81,19 @@ func TestNodeAnnoucementPayloadLength(t *testing.T) {
}
serializedLength := uint32(b.Len())
if serializedLength != na.MaxPayloadLength(0) {
if serializedLength != 164 {
t.Fatalf("payload length estimate is incorrect: expected %v "+
"got %v", serializedLength, na.MaxPayloadLength(0))
"got %v", 164, serializedLength)
}
if na.MaxPayloadLength(0) != 8192 {
t.Fatalf("max payload length doesn't match: expected 8192, got %v",
na.MaxPayloadLength(0))
}
}
func TestValidateAlias(t *testing.T) {
if err := someAlias.Validate(); err != nil {
t.Fatalf("alias was invalid: %v", err)
}
}

@ -285,7 +285,7 @@ func addToTopologyChange(graph *channeldb.ChannelGraph, update *TopologyChange,
// No further data munging or db queries are required.
case *lnwire.NodeAnnouncement:
nodeUpdate := &NetworkNodeUpdate{
Addresses: []net.Addr{m.Address},
Addresses: m.Addresses,
IdentityKey: m.NodeID,
Alias: m.Alias.String(),
}

@ -20,7 +20,9 @@ import (
)
var (
testAddr, _ = net.ResolveTCPAddr("tcp", "10.0.0.1:9000")
testAddr = &net.TCPAddr{IP: (net.IP)([]byte{0xA, 0x0, 0x0, 0x1}),
Port: 9000}
testAddrs = []net.Addr{testAddr}
testHash = [32]byte{
0xb7, 0x94, 0x38, 0x5f, 0x2d, 0x1e, 0xf7, 0xab,
@ -41,7 +43,7 @@ func createGraphNode() (*channeldb.LightningNode, error) {
pub := priv.PubKey().SerializeCompressed()
return &channeldb.LightningNode{
LastUpdate: time.Unix(updateTime, 0),
Address: testAddr,
Addresses: testAddrs,
PubKey: priv.PubKey(),
Color: color.RGBA{1, 2, 3, 0},
Alias: "kek" + string(pub[:]),
@ -63,7 +65,7 @@ func createTestWireNode() (*lnwire.NodeAnnouncement, error) {
return &lnwire.NodeAnnouncement{
Timestamp: uint32(prand.Int31()),
Address: testAddr,
Addresses: testAddrs,
NodeID: priv.PubKey(),
Alias: alias,
}, nil
@ -444,9 +446,9 @@ func TestNodeUpdateNotification(t *testing.T) {
// The notification received should directly map the
// announcement originally sent.
nodeNtfn := ntfns[0]
if nodeNtfn.Addresses[0] != ann.Address {
if nodeNtfn.Addresses[0] != ann.Addresses[0] {
t.Fatalf("node address doesn't match: expected %v, got %v",
nodeNtfn.Addresses[0], ann.Address)
nodeNtfn.Addresses[0], ann.Addresses[0])
}
if !nodeNtfn.IdentityKey.IsEqual(ann.NodeID) {
t.Fatalf("node identity keys don't match: expected %x, "+

@ -135,10 +135,12 @@ func parseTestGraph(path string) (*channeldb.ChannelGraph, func(), aliasMap, err
// We'll use this fake address for the IP address of all the nodes in
// our tests. This value isn't needed for path finding so it doesn't
// need to be unique.
var testAddrs []net.Addr
testAddr, err := net.ResolveTCPAddr("tcp", "192.0.0.1:8888")
if err != nil {
return nil, nil, nil, err
}
testAddrs = append(testAddrs, testAddr)
// Next, create a temporary graph database for usage within the test.
graph, cleanUp, err := makeTestGraph()
@ -162,7 +164,7 @@ func parseTestGraph(path string) (*channeldb.ChannelGraph, func(), aliasMap, err
dbNode := &channeldb.LightningNode{
LastUpdate: time.Now(),
Address: testAddr,
Addresses: testAddrs,
PubKey: pub,
Alias: node.Alias,
}

@ -693,7 +693,7 @@ func (r *ChannelRouter) processNetworkAnnouncement(msg lnwire.Message) bool {
node := &channeldb.LightningNode{
LastUpdate: msgTimestamp,
Address: msg.Address,
Addresses: msg.Addresses,
PubKey: msg.NodeID,
Alias: msg.Alias.String(),
}
@ -945,7 +945,7 @@ func (r *ChannelRouter) syncChannelGraph(syncReq *syncRequest) error {
ann := &lnwire.NodeAnnouncement{
Signature: r.fakeSig,
Timestamp: uint32(node.LastUpdate.Unix()),
Address: node.Address,
Addresses: node.Addresses,
NodeID: node.PubKey,
Alias: alias,
}

@ -1381,12 +1381,21 @@ func (r *rpcServer) DescribeGraph(context.Context,
// within the graph), collating their current state into the RPC
// response.
err := graph.ForEachNode(func(node *channeldb.LightningNode) error {
nodeAddrs := make([]*lnrpc.NodeAddress, 0)
for _, addr := range node.Addresses {
nodeAddr := &lnrpc.NodeAddress{
Network: addr.Network(),
Addr: addr.String(),
}
nodeAddrs = append(nodeAddrs, nodeAddr)
}
resp.Nodes = append(resp.Nodes, &lnrpc.LightningNode{
LastUpdate: uint32(node.LastUpdate.Unix()),
PubKey: hex.EncodeToString(node.PubKey.SerializeCompressed()),
Address: node.Address.String(),
Addresses: nodeAddrs,
Alias: node.Alias,
})
return nil
})
if err != nil {
@ -1516,12 +1525,20 @@ func (r *rpcServer) GetNodeInfo(_ context.Context, in *lnrpc.NodeInfoRequest) (*
return nil, err
}
nodeAddrs := make([]*lnrpc.NodeAddress, 0)
for _, addr := range node.Addresses {
nodeAddr := &lnrpc.NodeAddress{
Network: addr.Network(),
Addr: addr.String(),
}
nodeAddrs = append(nodeAddrs, nodeAddr)
}
// TODO(roasbeef): list channels as well?
return &lnrpc.NodeInfo{
Node: &lnrpc.LightningNode{
LastUpdate: uint32(node.LastUpdate.Unix()),
PubKey: in.PubKey,
Address: node.Address.String(),
Addresses: nodeAddrs,
Alias: node.Alias,
},
NumChannels: numChannels,

@ -159,11 +159,12 @@ func newServer(listenAddrs []string, notifier chainntnfs.ChainNotifier,
if !ok {
return nil, fmt.Errorf("default listener must be TCP")
}
selfAddrs := []net.Addr{selfAddr}
chanGraph := chanDB.ChannelGraph()
self := &channeldb.LightningNode{
LastUpdate: time.Now(),
Address: selfAddr,
Addresses: selfAddrs,
PubKey: privKey.PubKey(),
// TODO(roasbeef): make alias configurable
Alias: hex.EncodeToString(serializedPubKey[:10]),