From 9bdb483757f3cf914a0e8484a6d1f3c83bba9022 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Fri, 15 Dec 2017 21:50:21 +0100 Subject: [PATCH 01/25] htlcswitch/link: make MinHTLC non-changable This commit specifies that the MinHTLC value for a link is static over the lifetime of a channel, and don't process the field during a policyUpdate. --- htlcswitch/link.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/htlcswitch/link.go b/htlcswitch/link.go index 10e8d91bf..f63a1a068 100644 --- a/htlcswitch/link.go +++ b/htlcswitch/link.go @@ -39,7 +39,9 @@ const ( // the error possibly carrying along a ChannelUpdate message that includes the // latest policy. type ForwardingPolicy struct { - // MinHTLC is the smallest HTLC that is to be forwarded. + // MinHTLC is the smallest HTLC that is to be forwarded. This is + // set when a channel is first opened, and will be static for the + // lifetime of the channel. MinHTLC lnwire.MilliSatoshi // BaseFee is the base fee, expressed in milli-satoshi that must be @@ -604,9 +606,6 @@ out: // with a "null" field in the new policy, we'll // only update to the set sub policy if the new // value isn't uninitialized. - if req.policy.MinHTLC != 0 { - l.cfg.FwrdingPolicy.MinHTLC = req.policy.MinHTLC - } if req.policy.BaseFee != 0 { l.cfg.FwrdingPolicy.BaseFee = req.policy.BaseFee } From 0b8e7ff83654b37a51b6f1611e4722f438bf9666 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Fri, 15 Dec 2017 21:54:07 +0100 Subject: [PATCH 02/25] routing: embed FeeSchema in ChannelPolicy This commit embeds the FeeSchema within the new struct ChannelPolicy, which also contains the TimeLockDelta for a channel. --- routing/router.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/routing/router.go b/routing/router.go index 5fae3c7fc..8ffebc842 100644 --- a/routing/router.go +++ b/routing/router.go @@ -94,6 +94,18 @@ type FeeSchema struct { FeeRate uint32 } +// ChannelPolicy holds the parameters that determine the policy we enforce +// when fowarding payments on a channel. These parameters are communicated +// to the rest of the network in ChannelUpdate messages. +type ChannelPolicy struct { + // FeeSchema holds the fee configuration for a channel. + FeeSchema + + // TimeLockDelta is the required HTLC timelock delta to be used + // when forwarding payments. + TimeLockDelta uint32 +} + // Config defines the configuration for the ChannelRouter. ALL elements within // the configuration MUST be non-nil for the ChannelRouter to carry out its // duties. From 8370fa2cde159329ee4aa97c3b89ca8efd49a8e7 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Fri, 15 Dec 2017 21:56:11 +0100 Subject: [PATCH 03/25] discovery/gossiper: apply TimeLockDelta to edge when processing policy update Also rename various instances of "FeeUpdate" to "PolicyUpdate" --- discovery/gossiper.go | 73 +++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/discovery/gossiper.go b/discovery/gossiper.go index 87ad835b9..bf8762574 100644 --- a/discovery/gossiper.go +++ b/discovery/gossiper.go @@ -42,13 +42,13 @@ type networkMsg struct { err chan error } -// feeUpdateRequest is a request that is sent to the server when a caller -// wishes to update the fees for a particular set of channels. New UpdateFee -// messages will be crafted to be sent out during the next broadcast epoch and -// the fee updates committed to the lower layer. -type feeUpdateRequest struct { +// chanPolicyUpdateRequest is a request that is sent to the server when a caller +// wishes to update the channel policy (fees e.g.) for a particular set of +// channels. New ChannelUpdate messages will be crafted to be sent out during +// the next broadcast epoch and the fee updates committed to the lower layer. +type chanPolicyUpdateRequest struct { targetChans []wire.OutPoint - newSchema routing.FeeSchema + newSchema routing.ChannelPolicy errResp chan error } @@ -175,9 +175,9 @@ type AuthenticatedGossiper struct { // networkHandler. networkMsgs chan *networkMsg - // feeUpdates is a channel that requests to update the fee schedule of - // a set of channels is sent over. - feeUpdates chan *feeUpdateRequest + // chanPolicyUpdates is a channel that requests to update the forwarding + // policy of a set of channels is sent over. + chanPolicyUpdates chan *chanPolicyUpdateRequest // bestHeight is the height of the block at the tip of the main chain // as we know it. @@ -202,7 +202,7 @@ func New(cfg Config, selfKey *btcec.PublicKey) (*AuthenticatedGossiper, error) { cfg: &cfg, networkMsgs: make(chan *networkMsg), quit: make(chan struct{}), - feeUpdates: make(chan *feeUpdateRequest), + chanPolicyUpdates: make(chan *chanPolicyUpdateRequest), prematureAnnouncements: make(map[uint32][]*networkMsg), prematureChannelUpdates: make(map[uint64][]*networkMsg), waitingProofs: storage, @@ -296,24 +296,24 @@ func (d *AuthenticatedGossiper) SynchronizeNode(pub *btcec.PublicKey) error { return d.cfg.SendToPeer(pub, announceMessages...) } -// PropagateFeeUpdate signals the AuthenticatedGossiper to update the fee -// schema for the specified channels. If no channels are specified, then the -// fee update will be applied to all outgoing channels from the source node. -// Fee updates are done in two stages: first, the AuthenticatedGossiper ensures -// the updated has been committed by dependant sub-systems, then it signs and -// broadcasts new updates to the network. -func (d *AuthenticatedGossiper) PropagateFeeUpdate(newSchema routing.FeeSchema, - chanPoints ...wire.OutPoint) error { +// PropagateChanPolicyUpdate signals the AuthenticatedGossiper to update the +// channel forwarding policies for the specified channels. If no channels are +// specified, then the update will be applied to all outgoing channels from the +// source node. Policy updates are done in two stages: first, the +// AuthenticatedGossiper ensures the update has been committed by dependant +// sub-systems, then it signs and broadcasts new updates to the network. +func (d *AuthenticatedGossiper) PropagateChanPolicyUpdate( + newSchema routing.ChannelPolicy, chanPoints ...wire.OutPoint) error { errChan := make(chan error, 1) - feeUpdate := &feeUpdateRequest{ + policyUpdate := &chanPolicyUpdateRequest{ targetChans: chanPoints, newSchema: newSchema, errResp: errChan, } select { - case d.feeUpdates <- feeUpdate: + case d.chanPolicyUpdates <- policyUpdate: return <-errChan case <-d.quit: return fmt.Errorf("AuthenticatedGossiper shutting down") @@ -823,17 +823,18 @@ func (d *AuthenticatedGossiper) networkHandler() { for { select { - // A new fee update has arrived. We'll commit it to the + // A new policy update has arrived. We'll commit it to the // sub-systems below us, then craft, sign, and broadcast a new // ChannelUpdate for the set of affected clients. - case feeUpdate := <-d.feeUpdates: + case policyUpdate := <-d.chanPolicyUpdates: // First, we'll now create new fully signed updates for // the affected channels and also update the underlying // graph with the new state. - newChanUpdates, err := d.processFeeChanUpdate(feeUpdate) + newChanUpdates, err := d.processChanPolicyUpdate(policyUpdate) if err != nil { - log.Errorf("Unable to craft fee updates: %v", err) - feeUpdate.errResp <- err + log.Errorf("Unable to craft policy updates: %v", + err) + policyUpdate.errResp <- err continue } @@ -842,7 +843,7 @@ func (d *AuthenticatedGossiper) networkHandler() { // start of the next epoch. announcements.AddMsgs(newChanUpdates...) - feeUpdate.errResp <- nil + policyUpdate.errResp <- nil case announcement := <-d.networkMsgs: // Channel annoucnement signatures are the only message @@ -1072,18 +1073,19 @@ func (d *AuthenticatedGossiper) retransmitStaleChannels() error { return nil } -// processFeeChanUpdate generates a new set of channel updates with the new fee -// schema applied for each specified channel identified by its channel point. -// In the case that no channel points are specified, then the fee update will +// processChanPolicyUpdate generates a new set of channel updates with the new +// channel policy applied for each specified channel identified by its channel +// point. In the case that no channel points are specified, then the update will // be applied to all channels. Finally, the backing ChannelGraphSource is -// updated with the latest information reflecting the applied fee updates. +// updated with the latest information reflecting the applied updates. // // TODO(roasbeef): generalize into generic for any channel update -func (d *AuthenticatedGossiper) processFeeChanUpdate(feeUpdate *feeUpdateRequest) ([]networkMsg, error) { +func (d *AuthenticatedGossiper) processChanPolicyUpdate( + policyUpdate *chanPolicyUpdateRequest) ([]networkMsg, error) { // First, we'll construct a set of all the channels that need to be // updated. chansToUpdate := make(map[wire.OutPoint]struct{}) - for _, chanPoint := range feeUpdate.targetChans { + for _, chanPoint := range policyUpdate.targetChans { chansToUpdate[chanPoint] = struct{}{} } @@ -1104,11 +1106,14 @@ func (d *AuthenticatedGossiper) processFeeChanUpdate(feeUpdate *feeUpdateRequest } // Apply the new fee schema to the edge. - edge.FeeBaseMSat = feeUpdate.newSchema.BaseFee + edge.FeeBaseMSat = policyUpdate.newSchema.BaseFee edge.FeeProportionalMillionths = lnwire.MilliSatoshi( - feeUpdate.newSchema.FeeRate, + policyUpdate.newSchema.FeeRate, ) + // Apply the new TimeLockDelta. + edge.TimeLockDelta = uint16(policyUpdate.newSchema.TimeLockDelta) + // Re-sign and update the backing ChannelGraphSource, and // retrieve our ChannelUpdate to broadcast. _, chanUpdate, err := d.updateChannel(info, edge) From 551326586c200f8d158dc485d9fb6b66e05a42cc Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Fri, 15 Dec 2017 22:11:23 +0100 Subject: [PATCH 04/25] lnrpc: rename UpdateFee -> UpdateChannelPolicy This commit renames the UpdateFee RPC call together with associated types to UpdateChannelPolicy. In addition to fees, now also timelock delta can be specified using this call. --- lnrpc/rpc.pb.go | 740 +++++++++++++++++++++-------------------- lnrpc/rpc.pb.gw.go | 16 +- lnrpc/rpc.proto | 19 +- lnrpc/rpc.swagger.json | 67 ++-- 4 files changed, 430 insertions(+), 412 deletions(-) diff --git a/lnrpc/rpc.pb.go b/lnrpc/rpc.pb.go index caf2a797b..442ad099e 100644 --- a/lnrpc/rpc.pb.go +++ b/lnrpc/rpc.pb.go @@ -98,8 +98,8 @@ It has these top-level messages: FeeReportRequest ChannelFeeReport FeeReportResponse - FeeUpdateRequest - FeeUpdateResponse + PolicyUpdateRequest + PolicyUpdateResponse */ package lnrpc @@ -3477,111 +3477,120 @@ func (m *FeeReportResponse) GetChannelFees() []*ChannelFeeReport { return nil } -type FeeUpdateRequest struct { +type PolicyUpdateRequest struct { // Types that are valid to be assigned to Scope: - // *FeeUpdateRequest_Global - // *FeeUpdateRequest_ChanPoint - Scope isFeeUpdateRequest_Scope `protobuf_oneof:"scope"` + // *PolicyUpdateRequest_Global + // *PolicyUpdateRequest_ChanPoint + Scope isPolicyUpdateRequest_Scope `protobuf_oneof:"scope"` // / The base fee charged regardless of the number of milli-satoshis sent. BaseFeeMsat int64 `protobuf:"varint,3,opt,name=base_fee_msat" json:"base_fee_msat,omitempty"` // / The effective fee rate in milli-satoshis. The precision of this value goes up to 6 decimal places, so 1e-6. FeeRate float64 `protobuf:"fixed64,4,opt,name=fee_rate" json:"fee_rate,omitempty"` + // / The required timelock delta for HTLCs forwarded over the channel. + TimeLockDelta uint32 `protobuf:"varint,5,opt,name=time_lock_delta" json:"time_lock_delta,omitempty"` } -func (m *FeeUpdateRequest) Reset() { *m = FeeUpdateRequest{} } -func (m *FeeUpdateRequest) String() string { return proto.CompactTextString(m) } -func (*FeeUpdateRequest) ProtoMessage() {} -func (*FeeUpdateRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{90} } +func (m *PolicyUpdateRequest) Reset() { *m = PolicyUpdateRequest{} } +func (m *PolicyUpdateRequest) String() string { return proto.CompactTextString(m) } +func (*PolicyUpdateRequest) ProtoMessage() {} +func (*PolicyUpdateRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{90} } -type isFeeUpdateRequest_Scope interface { - isFeeUpdateRequest_Scope() +type isPolicyUpdateRequest_Scope interface { + isPolicyUpdateRequest_Scope() } -type FeeUpdateRequest_Global struct { +type PolicyUpdateRequest_Global struct { Global bool `protobuf:"varint,1,opt,name=global,oneof"` } -type FeeUpdateRequest_ChanPoint struct { +type PolicyUpdateRequest_ChanPoint struct { ChanPoint *ChannelPoint `protobuf:"bytes,2,opt,name=chan_point,oneof"` } -func (*FeeUpdateRequest_Global) isFeeUpdateRequest_Scope() {} -func (*FeeUpdateRequest_ChanPoint) isFeeUpdateRequest_Scope() {} +func (*PolicyUpdateRequest_Global) isPolicyUpdateRequest_Scope() {} +func (*PolicyUpdateRequest_ChanPoint) isPolicyUpdateRequest_Scope() {} -func (m *FeeUpdateRequest) GetScope() isFeeUpdateRequest_Scope { +func (m *PolicyUpdateRequest) GetScope() isPolicyUpdateRequest_Scope { if m != nil { return m.Scope } return nil } -func (m *FeeUpdateRequest) GetGlobal() bool { - if x, ok := m.GetScope().(*FeeUpdateRequest_Global); ok { +func (m *PolicyUpdateRequest) GetGlobal() bool { + if x, ok := m.GetScope().(*PolicyUpdateRequest_Global); ok { return x.Global } return false } -func (m *FeeUpdateRequest) GetChanPoint() *ChannelPoint { - if x, ok := m.GetScope().(*FeeUpdateRequest_ChanPoint); ok { +func (m *PolicyUpdateRequest) GetChanPoint() *ChannelPoint { + if x, ok := m.GetScope().(*PolicyUpdateRequest_ChanPoint); ok { return x.ChanPoint } return nil } -func (m *FeeUpdateRequest) GetBaseFeeMsat() int64 { +func (m *PolicyUpdateRequest) GetBaseFeeMsat() int64 { if m != nil { return m.BaseFeeMsat } return 0 } -func (m *FeeUpdateRequest) GetFeeRate() float64 { +func (m *PolicyUpdateRequest) GetFeeRate() float64 { if m != nil { return m.FeeRate } return 0 } +func (m *PolicyUpdateRequest) GetTimeLockDelta() uint32 { + if m != nil { + return m.TimeLockDelta + } + return 0 +} + // XXX_OneofFuncs is for the internal use of the proto package. -func (*FeeUpdateRequest) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { - return _FeeUpdateRequest_OneofMarshaler, _FeeUpdateRequest_OneofUnmarshaler, _FeeUpdateRequest_OneofSizer, []interface{}{ - (*FeeUpdateRequest_Global)(nil), - (*FeeUpdateRequest_ChanPoint)(nil), +func (*PolicyUpdateRequest) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _PolicyUpdateRequest_OneofMarshaler, _PolicyUpdateRequest_OneofUnmarshaler, _PolicyUpdateRequest_OneofSizer, []interface{}{ + (*PolicyUpdateRequest_Global)(nil), + (*PolicyUpdateRequest_ChanPoint)(nil), } } -func _FeeUpdateRequest_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { - m := msg.(*FeeUpdateRequest) +func _PolicyUpdateRequest_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*PolicyUpdateRequest) // scope switch x := m.Scope.(type) { - case *FeeUpdateRequest_Global: + case *PolicyUpdateRequest_Global: t := uint64(0) if x.Global { t = 1 } b.EncodeVarint(1<<3 | proto.WireVarint) b.EncodeVarint(t) - case *FeeUpdateRequest_ChanPoint: + case *PolicyUpdateRequest_ChanPoint: b.EncodeVarint(2<<3 | proto.WireBytes) if err := b.EncodeMessage(x.ChanPoint); err != nil { return err } case nil: default: - return fmt.Errorf("FeeUpdateRequest.Scope has unexpected type %T", x) + return fmt.Errorf("PolicyUpdateRequest.Scope has unexpected type %T", x) } return nil } -func _FeeUpdateRequest_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { - m := msg.(*FeeUpdateRequest) +func _PolicyUpdateRequest_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*PolicyUpdateRequest) switch tag { case 1: // scope.global if wire != proto.WireVarint { return true, proto.ErrInternalBadWireType } x, err := b.DecodeVarint() - m.Scope = &FeeUpdateRequest_Global{x != 0} + m.Scope = &PolicyUpdateRequest_Global{x != 0} return true, err case 2: // scope.chan_point if wire != proto.WireBytes { @@ -3589,21 +3598,21 @@ func _FeeUpdateRequest_OneofUnmarshaler(msg proto.Message, tag, wire int, b *pro } msg := new(ChannelPoint) err := b.DecodeMessage(msg) - m.Scope = &FeeUpdateRequest_ChanPoint{msg} + m.Scope = &PolicyUpdateRequest_ChanPoint{msg} return true, err default: return false, nil } } -func _FeeUpdateRequest_OneofSizer(msg proto.Message) (n int) { - m := msg.(*FeeUpdateRequest) +func _PolicyUpdateRequest_OneofSizer(msg proto.Message) (n int) { + m := msg.(*PolicyUpdateRequest) // scope switch x := m.Scope.(type) { - case *FeeUpdateRequest_Global: + case *PolicyUpdateRequest_Global: n += proto.SizeVarint(1<<3 | proto.WireVarint) n += 1 - case *FeeUpdateRequest_ChanPoint: + case *PolicyUpdateRequest_ChanPoint: s := proto.Size(x.ChanPoint) n += proto.SizeVarint(2<<3 | proto.WireBytes) n += proto.SizeVarint(uint64(s)) @@ -3615,13 +3624,13 @@ func _FeeUpdateRequest_OneofSizer(msg proto.Message) (n int) { return n } -type FeeUpdateResponse struct { +type PolicyUpdateResponse struct { } -func (m *FeeUpdateResponse) Reset() { *m = FeeUpdateResponse{} } -func (m *FeeUpdateResponse) String() string { return proto.CompactTextString(m) } -func (*FeeUpdateResponse) ProtoMessage() {} -func (*FeeUpdateResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{91} } +func (m *PolicyUpdateResponse) Reset() { *m = PolicyUpdateResponse{} } +func (m *PolicyUpdateResponse) String() string { return proto.CompactTextString(m) } +func (*PolicyUpdateResponse) ProtoMessage() {} +func (*PolicyUpdateResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{91} } func init() { proto.RegisterType((*CreateWalletRequest)(nil), "lnrpc.CreateWalletRequest") @@ -3718,8 +3727,8 @@ func init() { proto.RegisterType((*FeeReportRequest)(nil), "lnrpc.FeeReportRequest") proto.RegisterType((*ChannelFeeReport)(nil), "lnrpc.ChannelFeeReport") proto.RegisterType((*FeeReportResponse)(nil), "lnrpc.FeeReportResponse") - proto.RegisterType((*FeeUpdateRequest)(nil), "lnrpc.FeeUpdateRequest") - proto.RegisterType((*FeeUpdateResponse)(nil), "lnrpc.FeeUpdateResponse") + proto.RegisterType((*PolicyUpdateRequest)(nil), "lnrpc.PolicyUpdateRequest") + proto.RegisterType((*PolicyUpdateResponse)(nil), "lnrpc.PolicyUpdateResponse") proto.RegisterEnum("lnrpc.NewAddressRequest_AddressType", NewAddressRequest_AddressType_name, NewAddressRequest_AddressType_value) } @@ -4033,10 +4042,10 @@ type LightningClient interface { // FeeReport allows the caller to obtain a report detailing the current fee // schedule enforced by the node globally for each channel. FeeReport(ctx context.Context, in *FeeReportRequest, opts ...grpc.CallOption) (*FeeReportResponse, error) - // * lncli: `updatefees` - // UpdateFees allows the caller to update the fee schedule for all channels - // globally, or a particular channel. - UpdateFees(ctx context.Context, in *FeeUpdateRequest, opts ...grpc.CallOption) (*FeeUpdateResponse, error) + // * lncli: `updatechanpolicy` + // UpdateChannelPolicy allows the caller to update the fee schedule and + // channel policies for all channels globally, or a particular channel. + UpdateChannelPolicy(ctx context.Context, in *PolicyUpdateRequest, opts ...grpc.CallOption) (*PolicyUpdateResponse, error) } type lightningClient struct { @@ -4517,9 +4526,9 @@ func (c *lightningClient) FeeReport(ctx context.Context, in *FeeReportRequest, o return out, nil } -func (c *lightningClient) UpdateFees(ctx context.Context, in *FeeUpdateRequest, opts ...grpc.CallOption) (*FeeUpdateResponse, error) { - out := new(FeeUpdateResponse) - err := grpc.Invoke(ctx, "/lnrpc.Lightning/UpdateFees", in, out, c.cc, opts...) +func (c *lightningClient) UpdateChannelPolicy(ctx context.Context, in *PolicyUpdateRequest, opts ...grpc.CallOption) (*PolicyUpdateResponse, error) { + out := new(PolicyUpdateResponse) + err := grpc.Invoke(ctx, "/lnrpc.Lightning/UpdateChannelPolicy", in, out, c.cc, opts...) if err != nil { return nil, err } @@ -4719,10 +4728,10 @@ type LightningServer interface { // FeeReport allows the caller to obtain a report detailing the current fee // schedule enforced by the node globally for each channel. FeeReport(context.Context, *FeeReportRequest) (*FeeReportResponse, error) - // * lncli: `updatefees` - // UpdateFees allows the caller to update the fee schedule for all channels - // globally, or a particular channel. - UpdateFees(context.Context, *FeeUpdateRequest) (*FeeUpdateResponse, error) + // * lncli: `updatechanpolicy` + // UpdateChannelPolicy allows the caller to update the fee schedule and + // channel policies for all channels globally, or a particular channel. + UpdateChannelPolicy(context.Context, *PolicyUpdateRequest) (*PolicyUpdateResponse, error) } func RegisterLightningServer(s *grpc.Server, srv LightningServer) { @@ -5418,20 +5427,20 @@ func _Lightning_FeeReport_Handler(srv interface{}, ctx context.Context, dec func return interceptor(ctx, in, info, handler) } -func _Lightning_UpdateFees_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(FeeUpdateRequest) +func _Lightning_UpdateChannelPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PolicyUpdateRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(LightningServer).UpdateFees(ctx, in) + return srv.(LightningServer).UpdateChannelPolicy(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/lnrpc.Lightning/UpdateFees", + FullMethod: "/lnrpc.Lightning/UpdateChannelPolicy", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(LightningServer).UpdateFees(ctx, req.(*FeeUpdateRequest)) + return srv.(LightningServer).UpdateChannelPolicy(ctx, req.(*PolicyUpdateRequest)) } return interceptor(ctx, in, info, handler) } @@ -5565,8 +5574,8 @@ var _Lightning_serviceDesc = grpc.ServiceDesc{ Handler: _Lightning_FeeReport_Handler, }, { - MethodName: "UpdateFees", - Handler: _Lightning_UpdateFees_Handler, + MethodName: "UpdateChannelPolicy", + Handler: _Lightning_UpdateChannelPolicy_Handler, }, }, Streams: []grpc.StreamDesc{ @@ -5608,309 +5617,310 @@ var _Lightning_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("rpc.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 4855 bytes of a gzipped FileDescriptorProto + // 4867 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x7b, 0xcd, 0x8f, 0x1c, 0x49, 0x56, 0xb8, 0xb3, 0xba, 0xfa, 0xa3, 0x5e, 0x55, 0xf5, 0x47, 0x74, 0xbb, 0xbb, 0x5c, 0xf6, 0x78, 0xed, 0xd8, 0xd1, 0x4c, 0xff, 0xfc, 0x1b, 0xdc, 0x76, 0x2f, 0x3b, 0xcc, 0x8e, 0x81, 0x91, 0xbf, 0x7b, 0xd8, 0x1e, 0x4f, 0x6f, 0xb6, 0x67, 0x06, 0x76, 0x85, 0x8a, 0xec, 0xaa, 0xe8, 0xea, 0x5c, 0x67, 0x65, 0xe6, 0x64, 0x46, 0x75, 0xbb, 0xd6, 0x58, 0x82, 0x05, 0x21, 0x21, 0x81, 0xf6, 0x00, - 0x02, 0xed, 0x61, 0xb9, 0x70, 0x81, 0x03, 0xfc, 0x03, 0x48, 0xfc, 0x01, 0x2b, 0x21, 0x90, 0xf6, - 0x84, 0xc4, 0x0d, 0x4e, 0xcb, 0x99, 0x3b, 0x7a, 0xf1, 0x95, 0x11, 0x99, 0xd9, 0xb6, 0x97, 0x5d, - 0xb8, 0x55, 0xbc, 0x78, 0xf9, 0x22, 0xe2, 0xc5, 0x8b, 0xf7, 0x5d, 0xd0, 0xca, 0xd2, 0xe1, 0xcd, - 0x34, 0x4b, 0x78, 0x42, 0xe6, 0xa3, 0x38, 0x4b, 0x87, 0xfd, 0x2b, 0xe3, 0x24, 0x19, 0x47, 0x6c, - 0x27, 0x48, 0xc3, 0x9d, 0x20, 0x8e, 0x13, 0x1e, 0xf0, 0x30, 0x89, 0x73, 0x89, 0x44, 0x6f, 0xc3, - 0xfa, 0xfd, 0x8c, 0x05, 0x9c, 0x7d, 0x11, 0x44, 0x11, 0xe3, 0x3e, 0xfb, 0x72, 0xca, 0x72, 0x4e, - 0xfa, 0xb0, 0x94, 0x06, 0x79, 0x7e, 0x96, 0x64, 0xa3, 0x9e, 0x77, 0xcd, 0xdb, 0xee, 0xf8, 0x66, - 0x4c, 0x37, 0x61, 0xc3, 0xfd, 0x24, 0x4f, 0x93, 0x38, 0x67, 0x48, 0xea, 0xb3, 0x38, 0x4a, 0x86, - 0xcf, 0x7e, 0x26, 0x52, 0xee, 0x27, 0x8a, 0xd4, 0x0f, 0x1b, 0xd0, 0x7e, 0x9a, 0x05, 0x71, 0x1e, - 0x0c, 0x71, 0xb3, 0xa4, 0x07, 0x8b, 0xfc, 0xf9, 0xe0, 0x24, 0xc8, 0x4f, 0x04, 0x89, 0x96, 0xaf, - 0x87, 0x64, 0x13, 0x16, 0x82, 0x49, 0x32, 0x8d, 0x79, 0xaf, 0x71, 0xcd, 0xdb, 0x9e, 0xf3, 0xd5, - 0x88, 0xbc, 0x07, 0x6b, 0xf1, 0x74, 0x32, 0x18, 0x26, 0xf1, 0x71, 0x98, 0x4d, 0xe4, 0x91, 0x7b, - 0x73, 0xd7, 0xbc, 0xed, 0x79, 0xbf, 0x3a, 0x41, 0xae, 0x02, 0x1c, 0xe1, 0x36, 0xe4, 0x12, 0x4d, - 0xb1, 0x84, 0x05, 0x21, 0x14, 0x3a, 0x6a, 0xc4, 0xc2, 0xf1, 0x09, 0xef, 0xcd, 0x0b, 0x42, 0x0e, - 0x0c, 0x69, 0xf0, 0x70, 0xc2, 0x06, 0x39, 0x0f, 0x26, 0x69, 0x6f, 0x41, 0xec, 0xc6, 0x82, 0x88, - 0xf9, 0x84, 0x07, 0xd1, 0xe0, 0x98, 0xb1, 0xbc, 0xb7, 0xa8, 0xe6, 0x0d, 0x84, 0xbc, 0x03, 0xcb, - 0x23, 0x96, 0xf3, 0x41, 0x30, 0x1a, 0x65, 0x2c, 0xcf, 0x59, 0xde, 0x5b, 0xba, 0x36, 0xb7, 0xdd, - 0xf2, 0x4b, 0x50, 0xda, 0x83, 0xcd, 0xc7, 0x8c, 0x5b, 0xdc, 0xc9, 0x15, 0xa7, 0xe9, 0x3e, 0x10, - 0x0b, 0xfc, 0x80, 0xf1, 0x20, 0x8c, 0x72, 0xf2, 0x3e, 0x74, 0xb8, 0x85, 0xdc, 0xf3, 0xae, 0xcd, - 0x6d, 0xb7, 0x77, 0xc9, 0x4d, 0x21, 0x1d, 0x37, 0xad, 0x0f, 0x7c, 0x07, 0x8f, 0xfe, 0x8b, 0x07, - 0xed, 0x43, 0x16, 0x8f, 0xf4, 0x3d, 0x12, 0x68, 0xe2, 0x4e, 0xd4, 0x1d, 0x8a, 0xdf, 0xe4, 0x2b, - 0xd0, 0x16, 0xbb, 0xcb, 0x79, 0x16, 0xc6, 0x63, 0x71, 0x05, 0x2d, 0x1f, 0x10, 0x74, 0x28, 0x20, - 0x64, 0x15, 0xe6, 0x82, 0x09, 0x17, 0x8c, 0x9f, 0xf3, 0xf1, 0x27, 0xb9, 0x0e, 0x9d, 0x34, 0x98, - 0x4d, 0x58, 0xcc, 0x0b, 0x66, 0x77, 0xfc, 0xb6, 0x82, 0xed, 0x21, 0xb7, 0x6f, 0xc2, 0xba, 0x8d, - 0xa2, 0xa9, 0xcf, 0x0b, 0xea, 0x6b, 0x16, 0xa6, 0x5a, 0xe4, 0x5d, 0x58, 0xd1, 0xf8, 0x99, 0xdc, - 0xac, 0x60, 0x7f, 0xcb, 0x5f, 0x56, 0x60, 0xcd, 0xa0, 0x3f, 0xf7, 0xa0, 0x23, 0x8f, 0x24, 0xe5, - 0x8c, 0xbc, 0x0d, 0x5d, 0xfd, 0x25, 0xcb, 0xb2, 0x24, 0x53, 0xd2, 0xe5, 0x02, 0xc9, 0x0d, 0x58, - 0xd5, 0x80, 0x34, 0x63, 0xe1, 0x24, 0x18, 0x33, 0x71, 0xd4, 0x8e, 0x5f, 0x81, 0x93, 0xdd, 0x82, - 0x62, 0x96, 0x4c, 0x39, 0x13, 0x47, 0x6f, 0xef, 0x76, 0x14, 0xbb, 0x7d, 0x84, 0xf9, 0x2e, 0x0a, - 0xfd, 0xbe, 0x07, 0x9d, 0xfb, 0x27, 0x41, 0x1c, 0xb3, 0xe8, 0x20, 0x09, 0x63, 0x8e, 0xe2, 0x76, - 0x3c, 0x8d, 0x47, 0x61, 0x3c, 0x1e, 0xf0, 0xe7, 0xa1, 0x7e, 0x36, 0x0e, 0x0c, 0x37, 0x65, 0x8f, - 0x91, 0x49, 0x8a, 0xff, 0x15, 0x38, 0xd2, 0x4b, 0xa6, 0x3c, 0x9d, 0xf2, 0x41, 0x18, 0x8f, 0xd8, - 0x73, 0xb1, 0xa7, 0xae, 0xef, 0xc0, 0xe8, 0xaf, 0xc3, 0xea, 0x3e, 0xca, 0x71, 0x1c, 0xc6, 0xe3, - 0xbb, 0x52, 0xd8, 0xf0, 0x71, 0xa5, 0xd3, 0xa3, 0x67, 0x6c, 0xa6, 0xf8, 0xa2, 0x46, 0x28, 0x0a, - 0x27, 0x49, 0xce, 0xd5, 0x7a, 0xe2, 0x37, 0xfd, 0x77, 0x0f, 0x56, 0x90, 0xb7, 0x9f, 0x04, 0xf1, - 0x4c, 0x8b, 0xcc, 0x3e, 0x74, 0x90, 0xd4, 0xd3, 0xe4, 0xae, 0x7c, 0xa2, 0x52, 0xf4, 0xb6, 0x15, - 0x2f, 0x4a, 0xd8, 0x37, 0x6d, 0xd4, 0x87, 0x31, 0xcf, 0x66, 0xbe, 0xf3, 0x35, 0x0a, 0x1b, 0x0f, - 0xb2, 0x31, 0xe3, 0xe2, 0xf1, 0xaa, 0xc7, 0x0c, 0x12, 0x74, 0x3f, 0x89, 0x8f, 0xc9, 0x35, 0xe8, - 0xe4, 0x01, 0x1f, 0xa4, 0x2c, 0x1b, 0x1c, 0xcd, 0x38, 0x13, 0x02, 0x33, 0xe7, 0x43, 0x1e, 0xf0, - 0x03, 0x96, 0xdd, 0x9b, 0x71, 0xd6, 0xff, 0x08, 0xd6, 0x2a, 0xab, 0xa0, 0x8c, 0x16, 0x47, 0xc4, - 0x9f, 0x64, 0x03, 0xe6, 0x4f, 0x83, 0x68, 0xca, 0x94, 0x4e, 0x91, 0x83, 0x0f, 0x1b, 0x1f, 0x78, - 0xf4, 0x1d, 0x58, 0x2d, 0xb6, 0xad, 0x84, 0x88, 0x40, 0xd3, 0xdc, 0x52, 0xcb, 0x17, 0xbf, 0xe9, - 0xef, 0x7b, 0x12, 0xf1, 0x7e, 0x12, 0x9a, 0xf7, 0x89, 0x88, 0xf8, 0x8c, 0x35, 0x22, 0xfe, 0x3e, - 0x57, 0x7f, 0xfd, 0xfc, 0x87, 0xa5, 0xef, 0xc2, 0x9a, 0xb5, 0x85, 0x57, 0x6c, 0xf6, 0xaf, 0x3c, - 0x58, 0x7b, 0xc2, 0xce, 0xd4, 0xad, 0xeb, 0xdd, 0x7e, 0x00, 0x4d, 0x3e, 0x4b, 0x99, 0xc0, 0x5c, - 0xde, 0x7d, 0x5b, 0x5d, 0x5a, 0x05, 0xef, 0xa6, 0x1a, 0x3e, 0x9d, 0xa5, 0xcc, 0x17, 0x5f, 0xd0, - 0x4f, 0xa1, 0x6d, 0x01, 0xc9, 0x16, 0xac, 0x7f, 0xf1, 0xf1, 0xd3, 0x27, 0x0f, 0x0f, 0x0f, 0x07, - 0x07, 0x9f, 0xdd, 0xfb, 0xe6, 0xc3, 0xdf, 0x1a, 0xec, 0xdd, 0x3d, 0xdc, 0x5b, 0xbd, 0x40, 0x36, - 0x81, 0x3c, 0x79, 0x78, 0xf8, 0xf4, 0xe1, 0x03, 0x07, 0xee, 0x91, 0x15, 0x68, 0xdb, 0x80, 0x06, - 0xed, 0x43, 0xef, 0x09, 0x3b, 0xfb, 0x22, 0xe4, 0x31, 0xcb, 0x73, 0x77, 0x79, 0x7a, 0x13, 0x88, - 0xbd, 0x27, 0x75, 0xcc, 0x1e, 0x2c, 0x2a, 0x8d, 0xa9, 0x0d, 0x86, 0x1a, 0xd2, 0x77, 0x80, 0x1c, - 0x86, 0xe3, 0xf8, 0x13, 0x96, 0xe7, 0xc1, 0x98, 0xe9, 0xc3, 0xae, 0xc2, 0xdc, 0x24, 0x1f, 0xab, - 0x87, 0x86, 0x3f, 0xe9, 0xd7, 0x60, 0xdd, 0xc1, 0x53, 0x84, 0xaf, 0x40, 0x2b, 0x0f, 0xc7, 0x71, - 0xc0, 0xa7, 0x19, 0x53, 0xa4, 0x0b, 0x00, 0x7d, 0x04, 0x1b, 0x9f, 0xb3, 0x2c, 0x3c, 0x9e, 0xbd, - 0x8e, 0xbc, 0x4b, 0xa7, 0x51, 0xa6, 0xf3, 0x10, 0x2e, 0x96, 0xe8, 0xa8, 0xe5, 0xa5, 0x64, 0xaa, - 0xfb, 0x5b, 0xf2, 0xe5, 0xc0, 0x7a, 0xa7, 0x0d, 0xfb, 0x9d, 0xd2, 0xcf, 0x80, 0xdc, 0x4f, 0xe2, - 0x98, 0x0d, 0xf9, 0x01, 0x63, 0x99, 0xde, 0xcc, 0xff, 0xb7, 0xc4, 0xb0, 0xbd, 0xbb, 0xa5, 0x2e, - 0xb6, 0xfc, 0xf8, 0x95, 0x7c, 0x12, 0x68, 0xa6, 0x2c, 0x9b, 0x08, 0xc2, 0x4b, 0xbe, 0xf8, 0x4d, - 0x77, 0x60, 0xdd, 0x21, 0x5b, 0xf0, 0x3c, 0x65, 0x2c, 0x1b, 0xa8, 0xdd, 0xcd, 0xfb, 0x7a, 0x48, - 0x6f, 0xc3, 0xc5, 0x07, 0x61, 0x3e, 0xac, 0x6e, 0x05, 0x3f, 0x99, 0x1e, 0x0d, 0x8a, 0xe7, 0xa7, - 0x87, 0x68, 0xe5, 0xca, 0x9f, 0x28, 0xdf, 0xe0, 0x8f, 0x3c, 0x68, 0xee, 0x3d, 0xdd, 0xbf, 0x8f, - 0x8e, 0x45, 0x18, 0x0f, 0x93, 0x09, 0xda, 0x06, 0xc9, 0x0e, 0x33, 0x3e, 0xf7, 0x59, 0x5d, 0x81, - 0x96, 0x30, 0x29, 0x68, 0xb8, 0xc5, 0xa3, 0xea, 0xf8, 0x05, 0x00, 0x9d, 0x06, 0xf6, 0x3c, 0x0d, - 0x33, 0xe1, 0x15, 0x68, 0x5b, 0xdf, 0x14, 0xca, 0xb2, 0x3a, 0x41, 0x7f, 0xda, 0x84, 0xee, 0xdd, - 0x21, 0x0f, 0x4f, 0x99, 0x52, 0xde, 0x62, 0x55, 0x01, 0x50, 0xfb, 0x51, 0x23, 0x34, 0x33, 0x19, - 0x9b, 0x24, 0x9c, 0x0d, 0x9c, 0x6b, 0x72, 0x81, 0x88, 0x35, 0x94, 0x84, 0x06, 0x29, 0x9a, 0x01, - 0xb1, 0xbf, 0x96, 0xef, 0x02, 0x91, 0x65, 0x08, 0x40, 0x2e, 0xe3, 0xce, 0x9a, 0xbe, 0x1e, 0x22, - 0x3f, 0x86, 0x41, 0x1a, 0x0c, 0x43, 0x3e, 0x53, 0xda, 0xc0, 0x8c, 0x91, 0x76, 0x94, 0x0c, 0x83, - 0x68, 0x70, 0x14, 0x44, 0x41, 0x3c, 0x64, 0xca, 0x3f, 0x71, 0x81, 0xe8, 0x82, 0xa8, 0x2d, 0x69, - 0x34, 0xe9, 0xa6, 0x94, 0xa0, 0xe8, 0xca, 0x0c, 0x93, 0xc9, 0x24, 0xe4, 0xe8, 0xb9, 0xf4, 0x96, - 0xa4, 0xe6, 0x29, 0x20, 0xe2, 0x24, 0x72, 0x74, 0x26, 0x79, 0xd8, 0x92, 0xab, 0x39, 0x40, 0xa4, - 0x72, 0xcc, 0x98, 0xd0, 0x60, 0xcf, 0xce, 0x7a, 0x20, 0xa9, 0x14, 0x10, 0xbc, 0x8d, 0x69, 0x9c, - 0x33, 0xce, 0x23, 0x36, 0x32, 0x1b, 0x6a, 0x0b, 0xb4, 0xea, 0x04, 0xb9, 0x05, 0xeb, 0xd2, 0x99, - 0xca, 0x03, 0x9e, 0xe4, 0x27, 0x61, 0x3e, 0xc8, 0x59, 0xcc, 0x7b, 0x1d, 0x81, 0x5f, 0x37, 0x45, - 0x3e, 0x80, 0xad, 0x12, 0x38, 0x63, 0x43, 0x16, 0x9e, 0xb2, 0x51, 0xaf, 0x2b, 0xbe, 0x3a, 0x6f, - 0x9a, 0x5c, 0x83, 0x36, 0xfa, 0x90, 0xd3, 0x74, 0x14, 0x70, 0x96, 0xf7, 0x96, 0xc5, 0x3d, 0xd8, - 0x20, 0x72, 0x1b, 0xba, 0x29, 0x93, 0x56, 0xf8, 0x84, 0x47, 0xc3, 0xbc, 0xb7, 0x22, 0x4c, 0x5f, - 0x5b, 0x3d, 0x36, 0x94, 0x5f, 0xdf, 0xc5, 0x40, 0xd1, 0x1c, 0xe6, 0xa7, 0x83, 0x11, 0x8b, 0x82, - 0x59, 0x6f, 0x55, 0x08, 0x5d, 0x01, 0xa0, 0x17, 0x61, 0x7d, 0x3f, 0xcc, 0xb9, 0x92, 0x34, 0xa3, - 0xfd, 0xf6, 0x60, 0xc3, 0x05, 0xab, 0xb7, 0x78, 0x0b, 0x96, 0x94, 0xd8, 0xe4, 0xbd, 0xb6, 0x58, - 0x7a, 0x43, 0x2d, 0xed, 0x48, 0xac, 0x6f, 0xb0, 0xe8, 0x1f, 0x36, 0xa0, 0x89, 0xef, 0xec, 0xfc, - 0x37, 0x69, 0x3f, 0xf0, 0x86, 0xf3, 0xc0, 0x6d, 0x75, 0x3b, 0xe7, 0xa8, 0x5b, 0xe1, 0x59, 0xcf, - 0x38, 0x53, 0xb7, 0x21, 0x25, 0xd6, 0x82, 0x14, 0xf3, 0x19, 0x1b, 0x9e, 0x0a, 0xb1, 0x35, 0xf3, - 0x08, 0x41, 0xa1, 0x46, 0x33, 0x27, 0xbe, 0x96, 0x32, 0x6b, 0xc6, 0x7a, 0x4e, 0x7c, 0xb9, 0x58, - 0xcc, 0x89, 0xef, 0x7a, 0xb0, 0x18, 0xc6, 0x47, 0xc9, 0x34, 0x1e, 0x09, 0xf9, 0x5c, 0xf2, 0xf5, - 0x10, 0xf9, 0x9c, 0x0a, 0xef, 0x28, 0x9c, 0x30, 0x25, 0x98, 0x05, 0x80, 0x12, 0x74, 0x83, 0x72, - 0xa1, 0x71, 0x0c, 0x93, 0xdf, 0x87, 0x35, 0x0b, 0xa6, 0x38, 0x7c, 0x1d, 0xe6, 0xf1, 0xf4, 0xda, - 0x9f, 0xd6, 0x37, 0x2b, 0x54, 0x95, 0x9c, 0xa1, 0xab, 0xb0, 0xfc, 0x98, 0xf1, 0x8f, 0xe3, 0xe3, - 0x44, 0x53, 0xfa, 0xe3, 0x39, 0x58, 0x31, 0x20, 0x45, 0x68, 0x1b, 0x56, 0xc2, 0x11, 0x8b, 0x79, - 0xc8, 0x67, 0x03, 0xc7, 0xdb, 0x2a, 0x83, 0x51, 0xf9, 0x07, 0x51, 0x18, 0xe4, 0x4a, 0x7d, 0xc8, - 0x01, 0xd9, 0x85, 0x0d, 0x94, 0x3c, 0x2d, 0x4c, 0xe6, 0xda, 0xa5, 0x93, 0x57, 0x3b, 0x87, 0x8f, - 0x05, 0xe1, 0x52, 0x3d, 0x15, 0x9f, 0x48, 0x55, 0x57, 0x37, 0x85, 0x5c, 0x93, 0x94, 0xf0, 0xc8, - 0xf3, 0x52, 0x3a, 0x0d, 0xa0, 0x12, 0x1f, 0x2d, 0x48, 0x07, 0xb3, 0x1c, 0x1f, 0x59, 0x31, 0xd6, - 0x52, 0x25, 0xc6, 0xda, 0x86, 0x95, 0x7c, 0x16, 0x0f, 0xd9, 0x68, 0xc0, 0x13, 0x5c, 0x37, 0x8c, - 0xc5, 0xed, 0x2c, 0xf9, 0x65, 0xb0, 0x88, 0x06, 0x59, 0xce, 0x63, 0xc6, 0x85, 0xd6, 0x58, 0xf2, - 0xf5, 0x10, 0x15, 0xb0, 0x40, 0x91, 0x42, 0xdf, 0xf2, 0xd5, 0x08, 0xad, 0xd8, 0x34, 0x0b, 0xf3, - 0x5e, 0x47, 0x40, 0xc5, 0x6f, 0xfa, 0x3d, 0x61, 0x1c, 0x4d, 0x10, 0xf8, 0x99, 0x78, 0xb9, 0xe4, - 0x32, 0xb4, 0xe4, 0x9e, 0xf2, 0x93, 0x40, 0x87, 0xab, 0x02, 0x70, 0x78, 0x12, 0x60, 0xec, 0xe2, - 0x1c, 0x53, 0xbe, 0x82, 0xb6, 0x80, 0xed, 0xc9, 0x53, 0xbe, 0x0d, 0xcb, 0x3a, 0xbc, 0xcc, 0x07, - 0x11, 0x3b, 0xe6, 0xda, 0xd9, 0x8e, 0xa7, 0x13, 0x5c, 0x2e, 0xdf, 0x67, 0xc7, 0x9c, 0x3e, 0x81, - 0x35, 0xf5, 0x02, 0x3f, 0x4d, 0x99, 0x5e, 0xfa, 0x1b, 0x65, 0xfd, 0x2f, 0x0d, 0xf4, 0xba, 0x92, - 0x2c, 0x3b, 0x42, 0x28, 0x19, 0x05, 0xea, 0x03, 0x51, 0xd3, 0xf7, 0xa3, 0x24, 0x67, 0x8a, 0x20, - 0x85, 0xce, 0x30, 0x4a, 0xf2, 0x72, 0x18, 0x61, 0xc3, 0x90, 0x97, 0xf9, 0x74, 0x38, 0xc4, 0x97, - 0x2b, 0x4d, 0xbc, 0x1e, 0xd2, 0xbf, 0xf1, 0x60, 0x5d, 0x50, 0xd3, 0xba, 0xc2, 0xf8, 0x85, 0x6f, - 0xbe, 0xcd, 0xce, 0xd0, 0x0e, 0x6b, 0x36, 0x60, 0xfe, 0x38, 0xc9, 0x86, 0x4c, 0xad, 0x24, 0x07, - 0xbf, 0x08, 0x4f, 0xf7, 0x5f, 0x3d, 0x58, 0x13, 0x5b, 0x3d, 0xe4, 0x01, 0x9f, 0xe6, 0xea, 0xf8, - 0xbf, 0x0a, 0x5d, 0x3c, 0x2a, 0xd3, 0xe2, 0xaf, 0x36, 0xba, 0x61, 0x5e, 0xaa, 0x80, 0x4a, 0xe4, - 0xbd, 0x0b, 0xbe, 0x8b, 0x4c, 0x3e, 0x82, 0x8e, 0x9d, 0x23, 0x10, 0x7b, 0x6e, 0xef, 0x5e, 0xd2, - 0xa7, 0xac, 0x48, 0xce, 0xde, 0x05, 0xdf, 0xf9, 0x80, 0xdc, 0x01, 0x10, 0x96, 0x59, 0x90, 0x55, - 0x61, 0xe0, 0x25, 0x97, 0x49, 0xd6, 0x65, 0xed, 0x5d, 0xf0, 0x2d, 0xf4, 0x7b, 0x4b, 0xb0, 0x20, - 0x4d, 0x09, 0x7d, 0x0c, 0x5d, 0x67, 0xa7, 0x8e, 0x07, 0xdf, 0x91, 0x1e, 0x7c, 0x25, 0xc0, 0x6b, - 0xd4, 0x04, 0x78, 0xff, 0xd0, 0x00, 0x82, 0xd2, 0x56, 0xba, 0xce, 0x77, 0x60, 0x59, 0xb1, 0xdf, - 0x75, 0xde, 0x4a, 0x50, 0x61, 0xf3, 0x92, 0x91, 0xe3, 0xc1, 0x74, 0x7c, 0x1b, 0x44, 0x6e, 0x02, - 0xb1, 0x86, 0x3a, 0x6a, 0x97, 0xf6, 0xa0, 0x66, 0x06, 0x15, 0x97, 0x74, 0x3f, 0x74, 0xbc, 0xaa, - 0x3c, 0xb6, 0xa6, 0xb8, 0xdf, 0xda, 0x39, 0x91, 0x4c, 0x9a, 0xe6, 0x27, 0x68, 0x93, 0xb5, 0x8f, - 0xa3, 0xc7, 0x65, 0x41, 0x5a, 0x78, 0xad, 0x20, 0x2d, 0x96, 0x05, 0x49, 0x58, 0xb8, 0x2c, 0x3c, - 0x0d, 0x38, 0xd3, 0x56, 0x43, 0x0d, 0xe9, 0x4f, 0x3c, 0x58, 0x45, 0xee, 0x39, 0x12, 0xf6, 0x21, - 0x08, 0x01, 0x7f, 0x43, 0x01, 0x73, 0x70, 0x7f, 0x7e, 0xf9, 0xfa, 0x00, 0x5a, 0x82, 0x60, 0x92, - 0xb2, 0x58, 0x89, 0x57, 0xcf, 0x15, 0xaf, 0x42, 0xb7, 0xec, 0x5d, 0xf0, 0x0b, 0x64, 0x4b, 0xb8, - 0xfe, 0xd9, 0x83, 0xb6, 0xda, 0xe6, 0xff, 0xd8, 0xa5, 0xee, 0xc3, 0x12, 0xca, 0x99, 0xe5, 0xb1, - 0x9a, 0x31, 0xea, 0xf4, 0x09, 0x46, 0x34, 0x68, 0xc4, 0x1c, 0x77, 0xba, 0x0c, 0x46, 0x8b, 0x24, - 0xd4, 0x68, 0x3e, 0xe0, 0x61, 0x34, 0xd0, 0xb3, 0x2a, 0xd1, 0x56, 0x37, 0x85, 0xda, 0x24, 0xe7, - 0xc1, 0x98, 0x29, 0x63, 0x23, 0x07, 0x18, 0x37, 0xa8, 0x03, 0x95, 0x5d, 0xa5, 0x1f, 0x03, 0x6c, - 0x55, 0xa6, 0x8c, 0xbb, 0xa4, 0x3c, 0xc4, 0x28, 0x9c, 0x1c, 0x25, 0xc6, 0xd9, 0xf4, 0x6c, 0xe7, - 0xd1, 0x99, 0x22, 0x63, 0xb8, 0xa8, 0xad, 0x2a, 0xf2, 0xb4, 0xb0, 0xa1, 0x0d, 0xe1, 0x0e, 0xdc, - 0x76, 0x65, 0xa0, 0xbc, 0xa0, 0x86, 0xdb, 0xef, 0xb1, 0x9e, 0x1e, 0x39, 0x81, 0x9e, 0x31, 0xdf, - 0x4a, 0x71, 0x5b, 0x26, 0x1e, 0xd7, 0x7a, 0xef, 0x35, 0x6b, 0x09, 0x2d, 0x33, 0xd2, 0xcb, 0x9c, - 0x4b, 0x8d, 0xcc, 0xe0, 0xaa, 0x9e, 0x13, 0x9a, 0xb9, 0xba, 0x5e, 0xf3, 0x8d, 0xce, 0xf6, 0x08, - 0x3f, 0x76, 0x17, 0x7d, 0x0d, 0xe1, 0xfe, 0x8f, 0x3d, 0x58, 0x76, 0xc9, 0xa1, 0xe8, 0xa8, 0xa8, - 0x43, 0xab, 0x0e, 0xed, 0x16, 0x95, 0xc0, 0xd5, 0xb8, 0xa9, 0x51, 0x17, 0x37, 0xd9, 0xd1, 0xd1, - 0xdc, 0xeb, 0xa2, 0xa3, 0xe6, 0x9b, 0x45, 0x47, 0xf3, 0x75, 0xd1, 0x51, 0xff, 0xbf, 0x3c, 0x20, - 0xd5, 0xfb, 0x25, 0x8f, 0x65, 0xe0, 0x16, 0xb3, 0x48, 0xe9, 0x89, 0x5f, 0x7a, 0x33, 0x19, 0xd1, - 0x3c, 0xd4, 0x5f, 0xa3, 0xb0, 0xda, 0x8a, 0xc0, 0x76, 0x46, 0xba, 0x7e, 0xdd, 0x54, 0x29, 0x5e, - 0x6b, 0xbe, 0x3e, 0x5e, 0x9b, 0x7f, 0x7d, 0xbc, 0xb6, 0x50, 0x8e, 0xd7, 0xfa, 0xbf, 0x0b, 0x5d, - 0xe7, 0xd6, 0x7f, 0x71, 0x27, 0x2e, 0x3b, 0x32, 0xf2, 0x82, 0x1d, 0x58, 0xff, 0x3f, 0x1b, 0x40, - 0xaa, 0x92, 0xf7, 0x7f, 0xba, 0x07, 0x21, 0x47, 0x8e, 0x02, 0x99, 0x53, 0x72, 0xe4, 0xa8, 0x8e, - 0xff, 0x4d, 0xa5, 0xf8, 0x1e, 0xac, 0x65, 0x6c, 0x98, 0x9c, 0xb2, 0xcc, 0x8a, 0x99, 0xe5, 0x55, - 0x55, 0x27, 0xd0, 0x95, 0x73, 0xa3, 0xd4, 0x25, 0xa7, 0x36, 0x60, 0x59, 0x86, 0x52, 0xb0, 0x4a, - 0xbf, 0x01, 0x1b, 0xb2, 0x64, 0x73, 0x4f, 0x92, 0xd2, 0xde, 0xc4, 0x75, 0xe8, 0x9c, 0xc9, 0x34, - 0xdd, 0x20, 0x89, 0xa3, 0x99, 0x32, 0x22, 0x6d, 0x05, 0xfb, 0x34, 0x8e, 0x66, 0xf4, 0x47, 0x1e, - 0x5c, 0x2c, 0x7d, 0x5b, 0x64, 0xe3, 0xa5, 0xaa, 0x75, 0xf5, 0xaf, 0x0b, 0xc4, 0x23, 0x2a, 0x19, - 0xb7, 0x8e, 0x28, 0x4d, 0x52, 0x75, 0x02, 0x59, 0x38, 0x8d, 0xab, 0xf8, 0xf2, 0x62, 0xea, 0xa6, - 0xe8, 0x16, 0x5c, 0x54, 0x97, 0xef, 0x9e, 0x8d, 0xee, 0xc2, 0x66, 0x79, 0xa2, 0xc8, 0x7c, 0xb9, - 0x5b, 0xd6, 0x43, 0xfa, 0x11, 0x90, 0x6f, 0x4d, 0x59, 0x36, 0x13, 0x79, 0x7f, 0x93, 0x5a, 0xdd, - 0x2a, 0x87, 0xd8, 0x0b, 0xe9, 0xf4, 0xe8, 0x9b, 0x6c, 0xa6, 0xcb, 0x25, 0x0d, 0x53, 0x2e, 0xa1, - 0x77, 0x60, 0xdd, 0x21, 0x60, 0x58, 0xb5, 0x20, 0x6a, 0x07, 0x3a, 0xfc, 0x74, 0xeb, 0x0b, 0x6a, - 0x8e, 0xfe, 0xa5, 0x07, 0x73, 0x7b, 0x49, 0x6a, 0xe7, 0x8c, 0x3c, 0x37, 0x67, 0xa4, 0x74, 0xe7, - 0xc0, 0xa8, 0xc6, 0x86, 0x7a, 0xf9, 0x36, 0x10, 0x35, 0x5f, 0x30, 0xe1, 0x18, 0x80, 0x1d, 0x27, - 0xd9, 0x59, 0x90, 0x8d, 0x14, 0xff, 0x4a, 0x50, 0xdc, 0x7e, 0xa1, 0x60, 0xf0, 0x27, 0x3a, 0x0d, - 0x22, 0x71, 0x36, 0x53, 0x31, 0xa3, 0x1a, 0xd1, 0x1f, 0x78, 0x30, 0x2f, 0xf6, 0x8a, 0xaf, 0x41, - 0xde, 0xaf, 0x28, 0x95, 0x89, 0xbc, 0x9c, 0x27, 0x5f, 0x43, 0x09, 0x5c, 0x2a, 0xa0, 0x35, 0x2a, - 0x05, 0xb4, 0x2b, 0xd0, 0x92, 0xa3, 0xa2, 0xe2, 0x54, 0x00, 0xc8, 0x55, 0x68, 0x9e, 0x24, 0xa9, - 0xb6, 0x61, 0xa0, 0x13, 0x31, 0x49, 0xea, 0x0b, 0x38, 0xbd, 0x01, 0x2b, 0x4f, 0x92, 0x11, 0xb3, - 0xa2, 0xf5, 0x73, 0xaf, 0x89, 0xfe, 0x9e, 0x07, 0x4b, 0x1a, 0x99, 0x6c, 0x43, 0x13, 0x4d, 0x51, - 0xc9, 0xf9, 0x33, 0xe9, 0x54, 0xc4, 0xf3, 0x05, 0x06, 0xaa, 0x10, 0x11, 0x1b, 0x16, 0xae, 0x82, - 0x8e, 0x0c, 0x0b, 0x23, 0x8c, 0xee, 0xb8, 0xd8, 0x73, 0xc9, 0x58, 0x95, 0xa0, 0xf4, 0x6f, 0x3d, - 0xe8, 0x3a, 0x6b, 0xa0, 0x83, 0x1e, 0x05, 0x39, 0x57, 0x29, 0x28, 0xc5, 0x44, 0x1b, 0x64, 0x67, - 0x76, 0x1a, 0x6e, 0x66, 0xc7, 0x64, 0x16, 0xe6, 0xec, 0xcc, 0xc2, 0x2d, 0x68, 0x15, 0xc5, 0xc8, - 0xa6, 0xa3, 0x1a, 0x70, 0x45, 0x9d, 0x28, 0x2e, 0x90, 0x90, 0xce, 0x30, 0x89, 0x92, 0x4c, 0xd5, - 0xea, 0xe4, 0x80, 0xde, 0x81, 0xb6, 0x85, 0x8f, 0xdb, 0x88, 0x19, 0x3f, 0x4b, 0xb2, 0x67, 0x3a, - 0xc1, 0xa4, 0x86, 0xa6, 0x40, 0xd2, 0x28, 0x0a, 0x24, 0xf4, 0xef, 0x3c, 0xe8, 0xa2, 0xa4, 0x84, - 0xf1, 0xf8, 0x20, 0x89, 0xc2, 0xe1, 0x4c, 0x48, 0x8c, 0x16, 0x8a, 0xc1, 0x88, 0x45, 0x3c, 0x30, - 0x12, 0xe3, 0x82, 0xd1, 0xe6, 0x4f, 0xc2, 0x58, 0xa8, 0x2c, 0x25, 0x2f, 0x66, 0x8c, 0x92, 0x8f, - 0xb6, 0xeb, 0x28, 0xc8, 0xd9, 0x60, 0x82, 0xe1, 0x84, 0xd2, 0xd5, 0x0e, 0x10, 0xd5, 0x07, 0x02, - 0xb2, 0x80, 0xb3, 0xc1, 0x24, 0x8c, 0xa2, 0x50, 0xe2, 0x4a, 0x09, 0xaf, 0x9b, 0xc2, 0x30, 0xab, - 0xad, 0xd4, 0xc4, 0xc3, 0xd1, 0x58, 0xe6, 0x4a, 0x95, 0x23, 0x62, 0x9e, 0x9f, 0x05, 0xd1, 0xf3, - 0x8e, 0xeb, 0x62, 0x41, 0xca, 0xd7, 0x3a, 0x57, 0xbd, 0xd6, 0x2b, 0xd0, 0x42, 0xf1, 0xba, 0x2d, - 0x7c, 0x24, 0x59, 0xbb, 0x2e, 0x00, 0x7a, 0x76, 0x57, 0xcc, 0xce, 0x17, 0xb3, 0x02, 0xe0, 0x78, - 0x45, 0x0b, 0x25, 0xaf, 0xe8, 0x03, 0xe8, 0x28, 0x32, 0x82, 0xef, 0x22, 0x5c, 0x2a, 0x04, 0xdc, - 0xb9, 0x13, 0xdf, 0xc1, 0xd4, 0x5f, 0xee, 0xea, 0x2f, 0x97, 0x5e, 0xf7, 0xa5, 0xc6, 0xa4, 0x17, - 0x61, 0x5d, 0x31, 0xef, 0x71, 0x16, 0xa4, 0x27, 0x5a, 0xf5, 0x8e, 0x4c, 0x81, 0x54, 0x80, 0xc9, - 0x0d, 0x98, 0xc7, 0xcf, 0xb4, 0xf6, 0xab, 0x7f, 0x74, 0x12, 0x85, 0x6c, 0xc3, 0x3c, 0x1b, 0x8d, - 0x99, 0xf6, 0xcc, 0x89, 0x1b, 0x23, 0xe1, 0x1d, 0xf9, 0x12, 0x01, 0x55, 0x00, 0x42, 0x4b, 0x2a, - 0xc0, 0xd5, 0x9c, 0x0b, 0x38, 0xfc, 0x78, 0x44, 0x37, 0x80, 0x3c, 0x91, 0x52, 0x6b, 0xe7, 0xf7, - 0xfe, 0x60, 0x0e, 0xda, 0x16, 0x18, 0x5f, 0xf3, 0x18, 0x37, 0x3c, 0x18, 0x85, 0xc1, 0x84, 0x71, - 0x96, 0x29, 0x49, 0x2d, 0x41, 0x85, 0x82, 0x3d, 0x1d, 0x0f, 0x92, 0x29, 0x1f, 0x8c, 0xd8, 0x38, - 0x63, 0xd2, 0xa0, 0x79, 0x7e, 0x09, 0x8a, 0x78, 0x93, 0xe0, 0xb9, 0x8d, 0x27, 0xe5, 0xa1, 0x04, - 0xd5, 0xd9, 0x3a, 0xc9, 0xa3, 0x66, 0x91, 0xad, 0x93, 0x1c, 0x29, 0xeb, 0xa1, 0xf9, 0x1a, 0x3d, - 0xf4, 0x3e, 0x6c, 0x4a, 0x8d, 0xa3, 0xde, 0xe6, 0xa0, 0x24, 0x26, 0xe7, 0xcc, 0x92, 0x1b, 0xb0, - 0x8a, 0x7b, 0xd6, 0x02, 0x9e, 0x87, 0xdf, 0x93, 0x71, 0xb6, 0xe7, 0x57, 0xe0, 0x88, 0x8b, 0xcf, - 0xd1, 0xc1, 0x95, 0xc5, 0x84, 0x0a, 0x5c, 0xe0, 0x06, 0xcf, 0x5d, 0xdc, 0x96, 0xc2, 0x2d, 0xc1, - 0x69, 0x17, 0xda, 0x87, 0x3c, 0x49, 0xf5, 0xa5, 0x2c, 0x43, 0x47, 0x0e, 0x55, 0x01, 0xe9, 0x32, - 0x5c, 0x12, 0x52, 0xf4, 0x34, 0x49, 0x93, 0x28, 0x19, 0xcf, 0x0e, 0xa7, 0x47, 0xf9, 0x30, 0x0b, - 0x53, 0xf4, 0x98, 0xe9, 0x3f, 0x79, 0xb0, 0xee, 0xcc, 0xaa, 0x50, 0xff, 0x97, 0xa5, 0x48, 0x9b, - 0x9c, 0xbf, 0x14, 0xbc, 0x35, 0x4b, 0x1d, 0x4a, 0x44, 0x99, 0x12, 0xf9, 0x4c, 0x95, 0x01, 0xee, - 0xc2, 0x8a, 0xde, 0x99, 0xfe, 0x50, 0x4a, 0x61, 0xaf, 0x2a, 0x85, 0xea, 0xfb, 0x65, 0xf5, 0x81, - 0x26, 0xf1, 0x6b, 0xd2, 0xef, 0x64, 0x23, 0x71, 0x46, 0x1d, 0xf3, 0xf5, 0xf5, 0xf7, 0xb6, 0xb3, - 0xab, 0x77, 0x30, 0x34, 0xc0, 0x9c, 0xfe, 0x89, 0x07, 0x50, 0xec, 0x0e, 0x05, 0xa3, 0x50, 0xe9, - 0x9e, 0xc8, 0x86, 0x5a, 0xea, 0xfb, 0x3a, 0x74, 0x4c, 0xce, 0xb9, 0xb0, 0x12, 0x6d, 0x0d, 0x43, - 0x0f, 0xe5, 0x5d, 0x58, 0x19, 0x47, 0xc9, 0x91, 0xb0, 0xb9, 0xa2, 0x56, 0x99, 0xab, 0x32, 0xda, - 0xb2, 0x04, 0x3f, 0x52, 0xd0, 0xc2, 0xa4, 0x34, 0x2d, 0x93, 0x42, 0xff, 0xb4, 0x61, 0x32, 0x9f, - 0xc5, 0x99, 0xcf, 0x7d, 0x65, 0x64, 0xb7, 0xa2, 0x1c, 0xcf, 0x49, 0x34, 0x8a, 0xec, 0xc6, 0xc1, - 0x6b, 0x03, 0xbd, 0x3b, 0xb0, 0x9c, 0x49, 0xed, 0xa3, 0x55, 0x53, 0xf3, 0x15, 0xaa, 0xa9, 0x9b, - 0x39, 0x76, 0xe7, 0xff, 0xc1, 0x6a, 0x30, 0x3a, 0x65, 0x19, 0x0f, 0x85, 0xc7, 0x2f, 0x8c, 0xbe, - 0x54, 0xa8, 0x2b, 0x16, 0x5c, 0xd8, 0xe2, 0x77, 0x61, 0x45, 0x95, 0x2e, 0x0d, 0xa6, 0xea, 0x48, - 0x29, 0xc0, 0x88, 0x48, 0xff, 0x5a, 0x27, 0x59, 0xdd, 0x3b, 0x3c, 0x9f, 0x23, 0xf6, 0xe9, 0x1a, - 0xa5, 0xd3, 0x7d, 0x55, 0x25, 0x3c, 0x47, 0x3a, 0xac, 0x50, 0xa9, 0x67, 0x09, 0x54, 0x09, 0x6a, - 0x97, 0xa5, 0xcd, 0x37, 0x61, 0x29, 0xfd, 0xd1, 0x1c, 0x2c, 0x7e, 0x1c, 0x9f, 0x26, 0xe1, 0x50, - 0xa4, 0x1f, 0x27, 0x6c, 0x92, 0xe8, 0x06, 0x02, 0xfc, 0x8d, 0x16, 0x5d, 0xd4, 0xc6, 0x52, 0xae, - 0xf2, 0x82, 0x7a, 0x88, 0xd6, 0x2d, 0x2b, 0x9a, 0x66, 0xa4, 0xa4, 0x58, 0x10, 0xf4, 0x0f, 0x33, - 0xbb, 0x0f, 0x48, 0x8d, 0x8a, 0x0e, 0x8c, 0x79, 0xab, 0x03, 0x43, 0x24, 0xab, 0x65, 0xd9, 0x4f, - 0xb0, 0x73, 0xc9, 0xd7, 0x43, 0xe1, 0xc7, 0x66, 0x4c, 0x06, 0xbd, 0xc2, 0x4e, 0x2e, 0x2a, 0x3f, - 0xd6, 0x06, 0xa2, 0x2d, 0x95, 0x1f, 0x48, 0x1c, 0xa9, 0x6b, 0x6c, 0x10, 0xfa, 0x16, 0xe5, 0x56, - 0xa2, 0x96, 0xbc, 0xe2, 0x12, 0x18, 0x15, 0xd2, 0x88, 0x19, 0xbd, 0x21, 0xcf, 0x00, 0xb2, 0x29, - 0xa8, 0x0c, 0xb7, 0xbc, 0x60, 0x59, 0xbe, 0x54, 0x23, 0xe1, 0x83, 0x04, 0x51, 0x74, 0x14, 0x0c, - 0x9f, 0x89, 0x06, 0x2f, 0x51, 0xad, 0x6c, 0xf9, 0x2e, 0x10, 0x77, 0x3d, 0x8c, 0xf8, 0xe9, 0x40, - 0x91, 0xe8, 0xca, 0x6a, 0xa3, 0x05, 0xa2, 0x9f, 0x03, 0xb9, 0x3b, 0x1a, 0xa9, 0x1b, 0x32, 0x31, - 0x42, 0xc1, 0x5b, 0xcf, 0xe1, 0x6d, 0xcd, 0x19, 0x1b, 0xb5, 0x67, 0xa4, 0x0f, 0xa1, 0x7d, 0x60, - 0xf5, 0x65, 0x89, 0xcb, 0xd4, 0x1d, 0x59, 0x4a, 0x00, 0x2c, 0x88, 0xb5, 0x60, 0xc3, 0x5e, 0x90, - 0xfe, 0x0a, 0x90, 0xfd, 0x30, 0xe7, 0x66, 0x7f, 0x26, 0x54, 0x34, 0x19, 0x2f, 0x2b, 0x54, 0x54, - 0x30, 0x11, 0x2a, 0xde, 0x95, 0x45, 0xcf, 0xf2, 0xc1, 0x6e, 0xc0, 0x52, 0x28, 0x41, 0x5a, 0x0f, - 0x2f, 0x2b, 0x01, 0xd6, 0x98, 0x66, 0x1e, 0x1d, 0x0a, 0x05, 0x74, 0xd4, 0xfc, 0x0f, 0x3c, 0x58, - 0x54, 0x47, 0x43, 0x73, 0xe8, 0x74, 0xa4, 0xc9, 0x83, 0x39, 0xb0, 0xfa, 0x8e, 0xa0, 0xaa, 0xd4, - 0xcd, 0xd5, 0x49, 0x1d, 0x81, 0x66, 0x1a, 0xf0, 0x13, 0xe1, 0x41, 0xb7, 0x7c, 0xf1, 0x5b, 0x47, - 0x4a, 0xf3, 0x26, 0x52, 0xd2, 0x05, 0x5e, 0xb5, 0x29, 0x93, 0xb5, 0xbc, 0x27, 0x0b, 0xbc, 0x05, - 0xb8, 0xe0, 0x81, 0xda, 0x60, 0x99, 0x07, 0x0a, 0xd5, 0x37, 0xf3, 0xb4, 0x0f, 0xbd, 0x07, 0x2c, - 0x62, 0x9c, 0xdd, 0x8d, 0xa2, 0x32, 0xfd, 0xcb, 0x70, 0xa9, 0x66, 0x4e, 0x59, 0xca, 0x47, 0xb0, - 0xf6, 0x80, 0x1d, 0x4d, 0xc7, 0xfb, 0xec, 0xb4, 0x28, 0x18, 0x10, 0x68, 0xe6, 0x27, 0xc9, 0x99, - 0xba, 0x2f, 0xf1, 0x9b, 0xbc, 0x05, 0x10, 0x21, 0xce, 0x20, 0x4f, 0xd9, 0x50, 0xb7, 0xb3, 0x08, - 0xc8, 0x61, 0xca, 0x86, 0xf4, 0x7d, 0x20, 0x36, 0x1d, 0x75, 0x04, 0x7c, 0x8d, 0xd3, 0xa3, 0x41, - 0x3e, 0xcb, 0x39, 0x9b, 0xe8, 0x3e, 0x1d, 0x1b, 0x44, 0xdf, 0x85, 0xce, 0x41, 0x30, 0xf3, 0xd9, - 0x97, 0xaa, 0xd1, 0x0f, 0x03, 0xb2, 0x60, 0x86, 0xe2, 0x69, 0x02, 0x32, 0x31, 0x4d, 0xff, 0xb1, - 0x01, 0x0b, 0x12, 0x13, 0xa9, 0x8e, 0x58, 0xce, 0xc3, 0x58, 0xa6, 0xd5, 0x15, 0x55, 0x0b, 0x54, - 0xb9, 0xef, 0x46, 0xcd, 0x7d, 0x2b, 0x17, 0x49, 0x97, 0xfe, 0xd5, 0xc5, 0x3a, 0x30, 0x11, 0x6f, - 0x86, 0x13, 0x26, 0xfb, 0x3d, 0x9b, 0x2a, 0xde, 0xd4, 0x80, 0x52, 0xe4, 0x5b, 0xbc, 0x79, 0xb9, - 0x3f, 0x2d, 0x88, 0xca, 0x2c, 0xd8, 0xa0, 0x5a, 0xcd, 0xb2, 0x28, 0x3b, 0xfb, 0x2a, 0x9a, 0xa5, - 0xa2, 0x41, 0x96, 0xde, 0x40, 0x83, 0x48, 0xbf, 0xc9, 0xd1, 0x20, 0x04, 0x56, 0x1f, 0x31, 0xe6, - 0xb3, 0x34, 0xc9, 0x4c, 0xb7, 0xe4, 0x0f, 0x3d, 0x58, 0x55, 0x16, 0xc1, 0xcc, 0x91, 0xeb, 0x8e, - 0xf9, 0xf0, 0xea, 0x32, 0xad, 0x6f, 0x43, 0x57, 0x04, 0x50, 0x18, 0x1d, 0x89, 0x68, 0x49, 0xe5, - 0x14, 0x1c, 0x20, 0xee, 0x49, 0xe7, 0x0e, 0x27, 0x61, 0xa4, 0x18, 0x6c, 0x83, 0xd0, 0xd4, 0xe9, - 0x00, 0x4b, 0xb0, 0xd7, 0xf3, 0xcd, 0x98, 0x1e, 0xc0, 0x9a, 0xb5, 0x5f, 0x25, 0x50, 0x77, 0x40, - 0xd7, 0x1b, 0x65, 0x8a, 0x40, 0xbe, 0x8b, 0x2d, 0xd7, 0xb8, 0x15, 0x9f, 0x39, 0xc8, 0xf4, 0xef, - 0x3d, 0xc1, 0x02, 0xe5, 0x43, 0x99, 0xfe, 0xa4, 0x05, 0xe9, 0xd6, 0x48, 0x69, 0xdf, 0xbb, 0xe0, - 0xab, 0x31, 0xf9, 0xfa, 0x1b, 0x7a, 0x26, 0xa6, 0xae, 0x77, 0x0e, 0x6f, 0xe6, 0xea, 0x78, 0xf3, - 0x8a, 0x93, 0xdf, 0x5b, 0x84, 0xf9, 0x7c, 0x98, 0xa4, 0x8c, 0xae, 0x0b, 0x16, 0xe8, 0xfd, 0x4a, - 0x16, 0xec, 0xfe, 0x9b, 0x07, 0xcb, 0x32, 0xb9, 0x26, 0xfb, 0xaa, 0x59, 0x46, 0x30, 0x76, 0xb2, - 0xda, 0xb5, 0x89, 0x71, 0x1d, 0xab, 0x6d, 0xdf, 0xfd, 0xcb, 0xb5, 0x73, 0xda, 0x6f, 0xfe, 0xfe, - 0x4f, 0xfe, 0xe3, 0xcf, 0x1a, 0x17, 0xe9, 0xea, 0xce, 0xe9, 0xed, 0x1d, 0xa1, 0xe2, 0xd8, 0x99, - 0xc0, 0xf8, 0xd0, 0xbb, 0x81, 0xab, 0xd8, 0x9d, 0xdc, 0x66, 0x95, 0x9a, 0x8e, 0x70, 0xb3, 0x4a, - 0x6d, 0xeb, 0xb7, 0xb3, 0xca, 0x54, 0x60, 0x98, 0x55, 0x76, 0x7f, 0xda, 0x87, 0x96, 0x09, 0xf2, - 0xc8, 0x77, 0xa1, 0xeb, 0x24, 0x12, 0x89, 0x26, 0x5c, 0x97, 0x9a, 0xec, 0x5f, 0xa9, 0x9f, 0x54, - 0xcb, 0x5e, 0x15, 0xcb, 0xf6, 0xc8, 0x26, 0x2e, 0xab, 0xb2, 0x77, 0x3b, 0x22, 0xc3, 0x2a, 0x7b, - 0x0e, 0x9e, 0xc1, 0xb2, 0x9b, 0xfc, 0x23, 0x57, 0xdc, 0xdb, 0x2e, 0xad, 0xf6, 0xd6, 0x39, 0xb3, - 0x6a, 0xb9, 0x2b, 0x62, 0xb9, 0x4d, 0xb2, 0x61, 0x2f, 0x67, 0x82, 0x2f, 0x26, 0xba, 0x44, 0xec, - 0x16, 0x6f, 0xa2, 0xe9, 0xd5, 0xb7, 0x7e, 0xf7, 0x2f, 0x55, 0xdb, 0xb9, 0x55, 0xff, 0x37, 0xed, - 0x89, 0xa5, 0x08, 0x11, 0x0c, 0xb5, 0x3b, 0xbc, 0xc9, 0x77, 0xa0, 0x65, 0x1a, 0x44, 0xc9, 0x96, - 0xd5, 0x95, 0x6b, 0x77, 0xad, 0xf6, 0x7b, 0xd5, 0x89, 0xba, 0xab, 0xb2, 0x29, 0xa3, 0x40, 0xec, - 0xc3, 0x45, 0x65, 0x71, 0x8f, 0xd8, 0xcf, 0x72, 0x92, 0x9a, 0xc6, 0xf4, 0x5b, 0x1e, 0xb9, 0x03, - 0x4b, 0xba, 0xef, 0x96, 0x6c, 0xd6, 0xf7, 0x0f, 0xf7, 0xb7, 0x2a, 0x70, 0xa5, 0x17, 0xee, 0x02, - 0x14, 0x2d, 0xa2, 0xa4, 0x77, 0x5e, 0x27, 0xab, 0x61, 0x62, 0x4d, 0x3f, 0xe9, 0x58, 0x74, 0xc8, - 0xba, 0x1d, 0xa8, 0xe4, 0x2b, 0x05, 0x7e, 0x6d, 0x6f, 0xea, 0x2b, 0x08, 0xd2, 0x4d, 0xc1, 0xbb, - 0x55, 0xb2, 0x8c, 0xbc, 0x8b, 0xd9, 0x99, 0xee, 0x97, 0x7a, 0x00, 0x6d, 0xab, 0xed, 0x94, 0x68, - 0x0a, 0xd5, 0x96, 0xd5, 0x7e, 0xbf, 0x6e, 0x4a, 0x6d, 0xf7, 0x37, 0xa0, 0xeb, 0xf4, 0x8f, 0x9a, - 0x97, 0x51, 0xd7, 0x9d, 0x6a, 0x5e, 0x46, 0x7d, 0xcb, 0xe9, 0xb7, 0xa1, 0x6d, 0x75, 0x7b, 0x12, - 0xab, 0x42, 0x5d, 0xea, 0xe6, 0x34, 0x3b, 0xaa, 0x69, 0x0e, 0xa5, 0x1b, 0xe2, 0xbc, 0xcb, 0xb4, - 0x85, 0xe7, 0x15, 0x4d, 0x43, 0x28, 0x24, 0xdf, 0x85, 0x65, 0xb7, 0xcb, 0xd3, 0xbc, 0xaa, 0xda, - 0x7e, 0x51, 0xf3, 0xaa, 0xce, 0x69, 0x0d, 0x55, 0x02, 0x79, 0x63, 0xdd, 0x2c, 0xb2, 0xf3, 0x42, - 0xa5, 0x38, 0x5f, 0x92, 0x6f, 0xa1, 0xea, 0x50, 0x5d, 0x5c, 0xa4, 0xe8, 0x7a, 0x75, 0x7b, 0xbd, - 0x8c, 0xb4, 0x57, 0x1a, 0xbe, 0xe8, 0x9a, 0x20, 0xde, 0x26, 0xc5, 0x09, 0xc8, 0x27, 0xb0, 0xa8, - 0xba, 0xb9, 0xc8, 0xc5, 0x42, 0xaa, 0xad, 0x84, 0x50, 0x7f, 0xb3, 0x0c, 0x56, 0xc4, 0xd6, 0x05, - 0xb1, 0x2e, 0x69, 0x23, 0xb1, 0x31, 0xe3, 0x21, 0xd2, 0x88, 0x61, 0xa5, 0x54, 0x95, 0x32, 0x8f, - 0xa5, 0xbe, 0xa6, 0xdd, 0xbf, 0xfa, 0xea, 0x62, 0x96, 0xab, 0x66, 0xb4, 0x7a, 0xd9, 0xd1, 0x2d, - 0x08, 0xbf, 0x0d, 0x1d, 0xbb, 0x79, 0xd0, 0xe8, 0xec, 0x9a, 0x46, 0x43, 0xa3, 0xb3, 0xeb, 0xba, - 0x0d, 0xf5, 0xe5, 0x92, 0x8e, 0xbd, 0x0c, 0xf9, 0x36, 0xac, 0x58, 0xf5, 0xcf, 0xc3, 0x59, 0x3c, - 0x34, 0xc2, 0x53, 0xed, 0x43, 0xe9, 0xd7, 0x19, 0x4f, 0xba, 0x25, 0x08, 0xaf, 0x51, 0x87, 0x30, - 0x0a, 0xce, 0x7d, 0x68, 0xdb, 0xb5, 0xd5, 0x57, 0xd0, 0xdd, 0xb2, 0xa6, 0xec, 0xe6, 0x8d, 0x5b, - 0x1e, 0xf9, 0x0b, 0x0f, 0x3a, 0x76, 0x87, 0x13, 0x71, 0xb2, 0x2a, 0x25, 0x3a, 0x3d, 0x7b, 0xce, - 0x26, 0x44, 0x9f, 0x88, 0x4d, 0xee, 0xdd, 0x78, 0xe4, 0x30, 0xf9, 0x85, 0xe3, 0x14, 0xdd, 0xb4, - 0xff, 0x93, 0xf1, 0xb2, 0x3c, 0x69, 0xf7, 0xe9, 0xbc, 0xbc, 0xe5, 0x91, 0x0f, 0xe5, 0x3f, 0x6f, - 0x74, 0x80, 0x42, 0x2c, 0xc5, 0x56, 0x66, 0x97, 0xfd, 0x77, 0x96, 0x6d, 0xef, 0x96, 0x47, 0x7e, - 0x47, 0xfe, 0x0d, 0x43, 0x7d, 0x2b, 0xb8, 0xfe, 0xa6, 0xdf, 0xd3, 0xb7, 0xc5, 0x49, 0xae, 0xd2, - 0x4b, 0xce, 0x49, 0xca, 0x9a, 0xfd, 0x00, 0xa0, 0x88, 0x36, 0x49, 0x29, 0xf4, 0x32, 0x3a, 0xaf, - 0x1a, 0x90, 0xba, 0xb7, 0xa9, 0x23, 0x34, 0xa9, 0x06, 0x3a, 0x56, 0x9c, 0x97, 0x9b, 0xeb, 0xac, - 0x46, 0x8d, 0xfd, 0x7e, 0xdd, 0x94, 0xa2, 0xff, 0x55, 0x41, 0xff, 0x2d, 0x72, 0xd9, 0xa6, 0xbf, - 0xf3, 0xc2, 0x8e, 0x32, 0x5f, 0x92, 0xcf, 0xa1, 0xbb, 0x9f, 0x24, 0xcf, 0xa6, 0xa9, 0x49, 0x68, - 0xb8, 0x71, 0x13, 0x46, 0xba, 0xfd, 0xd2, 0xa1, 0xe8, 0x75, 0x41, 0xf9, 0x32, 0xb9, 0xe4, 0x52, - 0x2e, 0x62, 0xdf, 0x97, 0x24, 0x80, 0x35, 0x63, 0xef, 0xcc, 0x41, 0xfa, 0x2e, 0x1d, 0x3b, 0x04, - 0xad, 0xac, 0xe1, 0x78, 0x20, 0x66, 0x8d, 0x5c, 0xd3, 0xbc, 0xe5, 0x91, 0x03, 0xe8, 0x3c, 0x60, - 0xc3, 0x64, 0xc4, 0x54, 0xa8, 0xb3, 0x5e, 0xec, 0xdc, 0xc4, 0x48, 0xfd, 0xae, 0x03, 0x74, 0x35, - 0x40, 0x1a, 0xcc, 0x32, 0xf6, 0xe5, 0xce, 0x0b, 0x15, 0x44, 0xbd, 0xd4, 0x1a, 0x40, 0x07, 0x7e, - 0x8e, 0x06, 0x28, 0x45, 0x8a, 0x8e, 0x06, 0xa8, 0x44, 0x8a, 0x8e, 0x06, 0xd0, 0x81, 0x27, 0x89, - 0x30, 0x7e, 0x2c, 0x05, 0x97, 0xc6, 0x6a, 0x9e, 0x17, 0x92, 0xf6, 0xaf, 0x9d, 0x8f, 0xe0, 0xae, - 0x76, 0xc3, 0x5d, 0xed, 0x10, 0xba, 0x0f, 0x98, 0x64, 0x96, 0xac, 0x12, 0xf4, 0x5d, 0x95, 0x62, - 0x57, 0x14, 0xca, 0xea, 0x46, 0xcc, 0xb9, 0x2a, 0x5e, 0xa4, 0xe8, 0xc9, 0x77, 0xa0, 0xfd, 0x98, - 0x71, 0x5d, 0x16, 0x30, 0xbe, 0x47, 0xa9, 0x4e, 0xd0, 0xaf, 0xa9, 0x2a, 0xd0, 0x6b, 0x82, 0x5a, - 0x9f, 0xf4, 0x0c, 0xb5, 0x1d, 0x36, 0x1a, 0x33, 0xf9, 0xf8, 0x07, 0xe1, 0xe8, 0x25, 0xf9, 0x4d, - 0x41, 0xdc, 0x54, 0x12, 0x37, 0xad, 0x6c, 0xb2, 0x4d, 0x7c, 0xa5, 0x04, 0xaf, 0xa3, 0x1c, 0x27, - 0x23, 0x66, 0x19, 0xbb, 0x18, 0xda, 0x56, 0xd9, 0xd8, 0x3c, 0xa8, 0x6a, 0x2d, 0xda, 0x3c, 0xa8, - 0x9a, 0x2a, 0x33, 0xdd, 0x16, 0xeb, 0x50, 0x72, 0xad, 0x58, 0x47, 0x56, 0x96, 0x8b, 0x95, 0x76, - 0x5e, 0x04, 0x13, 0xfe, 0x92, 0x7c, 0x21, 0x5a, 0x9d, 0xed, 0xd2, 0x47, 0xe1, 0xfb, 0x94, 0xab, - 0x24, 0x86, 0x59, 0xd6, 0x94, 0xeb, 0x0f, 0xc9, 0xa5, 0x84, 0x4d, 0xfc, 0x3a, 0xc0, 0x21, 0x4f, - 0xd2, 0x07, 0x01, 0x9b, 0x24, 0x71, 0xa1, 0xc9, 0x8a, 0xf4, 0x7e, 0xa1, 0xc9, 0xac, 0x1c, 0x3f, - 0xf9, 0xc2, 0xf2, 0x3e, 0x9d, 0xca, 0x91, 0x16, 0xae, 0x73, 0x2b, 0x00, 0x86, 0x21, 0x35, 0x55, - 0x80, 0x5b, 0x1e, 0xfa, 0x92, 0x45, 0x2a, 0xc3, 0xf8, 0x92, 0x95, 0x2c, 0x89, 0x51, 0x83, 0x35, - 0x79, 0x8f, 0x03, 0x68, 0x15, 0xf1, 0xb4, 0x36, 0x4f, 0xe5, 0xe8, 0xdb, 0xd8, 0x9b, 0x4a, 0x98, - 0x4b, 0x57, 0x05, 0xab, 0x80, 0x2c, 0x21, 0xab, 0x44, 0xe5, 0xfb, 0x29, 0x80, 0xdc, 0xe0, 0x23, - 0x1c, 0x59, 0x24, 0x9d, 0x68, 0xd6, 0x26, 0xe9, 0x86, 0x8d, 0xda, 0x1d, 0xa1, 0x86, 0xe4, 0x87, - 0xde, 0x8d, 0xa3, 0x05, 0xf1, 0x0f, 0xe1, 0xaf, 0xfd, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x6e, - 0x8c, 0x0d, 0xd9, 0x53, 0x3c, 0x00, 0x00, + 0x02, 0xed, 0x61, 0xb9, 0x70, 0x81, 0x03, 0x7f, 0x01, 0x12, 0x7f, 0xc0, 0x4a, 0x08, 0xa4, 0x3d, + 0x21, 0xb8, 0xc1, 0x09, 0xce, 0x1c, 0xb8, 0xa1, 0x17, 0x5f, 0x19, 0x91, 0x99, 0x6d, 0x7b, 0xd9, + 0x85, 0x5b, 0xc5, 0x8b, 0x97, 0x2f, 0x22, 0x5e, 0xbc, 0x78, 0xdf, 0x05, 0xad, 0x2c, 0x1d, 0xde, + 0x4c, 0xb3, 0x84, 0x27, 0x64, 0x3e, 0x8a, 0xb3, 0x74, 0xd8, 0xbf, 0x32, 0x4e, 0x92, 0x71, 0xc4, + 0x76, 0x82, 0x34, 0xdc, 0x09, 0xe2, 0x38, 0xe1, 0x01, 0x0f, 0x93, 0x38, 0x97, 0x48, 0xf4, 0x36, + 0xac, 0xdf, 0xcf, 0x58, 0xc0, 0xd9, 0x17, 0x41, 0x14, 0x31, 0xee, 0xb3, 0x2f, 0xa7, 0x2c, 0xe7, + 0xa4, 0x0f, 0x4b, 0x69, 0x90, 0xe7, 0x67, 0x49, 0x36, 0xea, 0x79, 0xd7, 0xbc, 0xed, 0x8e, 0x6f, + 0xc6, 0x74, 0x13, 0x36, 0xdc, 0x4f, 0xf2, 0x34, 0x89, 0x73, 0x86, 0xa4, 0x3e, 0x8b, 0xa3, 0x64, + 0xf8, 0xec, 0xa7, 0x22, 0xe5, 0x7e, 0xa2, 0x48, 0xfd, 0xb0, 0x01, 0xed, 0xa7, 0x59, 0x10, 0xe7, + 0xc1, 0x10, 0x37, 0x4b, 0x7a, 0xb0, 0xc8, 0x9f, 0x0f, 0x4e, 0x82, 0xfc, 0x44, 0x90, 0x68, 0xf9, + 0x7a, 0x48, 0x36, 0x61, 0x21, 0x98, 0x24, 0xd3, 0x98, 0xf7, 0x1a, 0xd7, 0xbc, 0xed, 0x39, 0x5f, + 0x8d, 0xc8, 0x7b, 0xb0, 0x16, 0x4f, 0x27, 0x83, 0x61, 0x12, 0x1f, 0x87, 0xd9, 0x44, 0x1e, 0xb9, + 0x37, 0x77, 0xcd, 0xdb, 0x9e, 0xf7, 0xab, 0x13, 0xe4, 0x2a, 0xc0, 0x11, 0x6e, 0x43, 0x2e, 0xd1, + 0x14, 0x4b, 0x58, 0x10, 0x42, 0xa1, 0xa3, 0x46, 0x2c, 0x1c, 0x9f, 0xf0, 0xde, 0xbc, 0x20, 0xe4, + 0xc0, 0x90, 0x06, 0x0f, 0x27, 0x6c, 0x90, 0xf3, 0x60, 0x92, 0xf6, 0x16, 0xc4, 0x6e, 0x2c, 0x88, + 0x98, 0x4f, 0x78, 0x10, 0x0d, 0x8e, 0x19, 0xcb, 0x7b, 0x8b, 0x6a, 0xde, 0x40, 0xc8, 0x3b, 0xb0, + 0x3c, 0x62, 0x39, 0x1f, 0x04, 0xa3, 0x51, 0xc6, 0xf2, 0x9c, 0xe5, 0xbd, 0xa5, 0x6b, 0x73, 0xdb, + 0x2d, 0xbf, 0x04, 0xa5, 0x3d, 0xd8, 0x7c, 0xcc, 0xb8, 0xc5, 0x9d, 0x5c, 0x71, 0x9a, 0xee, 0x03, + 0xb1, 0xc0, 0x0f, 0x18, 0x0f, 0xc2, 0x28, 0x27, 0xef, 0x43, 0x87, 0x5b, 0xc8, 0x3d, 0xef, 0xda, + 0xdc, 0x76, 0x7b, 0x97, 0xdc, 0x14, 0xd2, 0x71, 0xd3, 0xfa, 0xc0, 0x77, 0xf0, 0xe8, 0x3f, 0x7a, + 0xd0, 0x3e, 0x64, 0xf1, 0x48, 0xdf, 0x23, 0x81, 0x26, 0xee, 0x44, 0xdd, 0xa1, 0xf8, 0x4d, 0xbe, + 0x02, 0x6d, 0xb1, 0xbb, 0x9c, 0x67, 0x61, 0x3c, 0x16, 0x57, 0xd0, 0xf2, 0x01, 0x41, 0x87, 0x02, + 0x42, 0x56, 0x61, 0x2e, 0x98, 0x70, 0xc1, 0xf8, 0x39, 0x1f, 0x7f, 0x92, 0xeb, 0xd0, 0x49, 0x83, + 0xd9, 0x84, 0xc5, 0xbc, 0x60, 0x76, 0xc7, 0x6f, 0x2b, 0xd8, 0x1e, 0x72, 0xfb, 0x26, 0xac, 0xdb, + 0x28, 0x9a, 0xfa, 0xbc, 0xa0, 0xbe, 0x66, 0x61, 0xaa, 0x45, 0xde, 0x85, 0x15, 0x8d, 0x9f, 0xc9, + 0xcd, 0x0a, 0xf6, 0xb7, 0xfc, 0x65, 0x05, 0xd6, 0x0c, 0xfa, 0x53, 0x0f, 0x3a, 0xf2, 0x48, 0x52, + 0xce, 0xc8, 0xdb, 0xd0, 0xd5, 0x5f, 0xb2, 0x2c, 0x4b, 0x32, 0x25, 0x5d, 0x2e, 0x90, 0xdc, 0x80, + 0x55, 0x0d, 0x48, 0x33, 0x16, 0x4e, 0x82, 0x31, 0x13, 0x47, 0xed, 0xf8, 0x15, 0x38, 0xd9, 0x2d, + 0x28, 0x66, 0xc9, 0x94, 0x33, 0x71, 0xf4, 0xf6, 0x6e, 0x47, 0xb1, 0xdb, 0x47, 0x98, 0xef, 0xa2, + 0xd0, 0xef, 0x7b, 0xd0, 0xb9, 0x7f, 0x12, 0xc4, 0x31, 0x8b, 0x0e, 0x92, 0x30, 0xe6, 0x28, 0x6e, + 0xc7, 0xd3, 0x78, 0x14, 0xc6, 0xe3, 0x01, 0x7f, 0x1e, 0xea, 0x67, 0xe3, 0xc0, 0x70, 0x53, 0xf6, + 0x18, 0x99, 0xa4, 0xf8, 0x5f, 0x81, 0x23, 0xbd, 0x64, 0xca, 0xd3, 0x29, 0x1f, 0x84, 0xf1, 0x88, + 0x3d, 0x17, 0x7b, 0xea, 0xfa, 0x0e, 0x8c, 0xfe, 0x2a, 0xac, 0xee, 0xa3, 0x1c, 0xc7, 0x61, 0x3c, + 0xbe, 0x2b, 0x85, 0x0d, 0x1f, 0x57, 0x3a, 0x3d, 0x7a, 0xc6, 0x66, 0x8a, 0x2f, 0x6a, 0x84, 0xa2, + 0x70, 0x92, 0xe4, 0x5c, 0xad, 0x27, 0x7e, 0xd3, 0x7f, 0xf5, 0x60, 0x05, 0x79, 0xfb, 0x49, 0x10, + 0xcf, 0xb4, 0xc8, 0xec, 0x43, 0x07, 0x49, 0x3d, 0x4d, 0xee, 0xca, 0x27, 0x2a, 0x45, 0x6f, 0x5b, + 0xf1, 0xa2, 0x84, 0x7d, 0xd3, 0x46, 0x7d, 0x18, 0xf3, 0x6c, 0xe6, 0x3b, 0x5f, 0xa3, 0xb0, 0xf1, + 0x20, 0x1b, 0x33, 0x2e, 0x1e, 0xaf, 0x7a, 0xcc, 0x20, 0x41, 0xf7, 0x93, 0xf8, 0x98, 0x5c, 0x83, + 0x4e, 0x1e, 0xf0, 0x41, 0xca, 0xb2, 0xc1, 0xd1, 0x8c, 0x33, 0x21, 0x30, 0x73, 0x3e, 0xe4, 0x01, + 0x3f, 0x60, 0xd9, 0xbd, 0x19, 0x67, 0xfd, 0x8f, 0x60, 0xad, 0xb2, 0x0a, 0xca, 0x68, 0x71, 0x44, + 0xfc, 0x49, 0x36, 0x60, 0xfe, 0x34, 0x88, 0xa6, 0x4c, 0xe9, 0x14, 0x39, 0xf8, 0xb0, 0xf1, 0x81, + 0x47, 0xdf, 0x81, 0xd5, 0x62, 0xdb, 0x4a, 0x88, 0x08, 0x34, 0xcd, 0x2d, 0xb5, 0x7c, 0xf1, 0x9b, + 0xfe, 0xae, 0x27, 0x11, 0xef, 0x27, 0xa1, 0x79, 0x9f, 0x88, 0x88, 0xcf, 0x58, 0x23, 0xe2, 0xef, + 0x73, 0xf5, 0xd7, 0xcf, 0x7e, 0x58, 0xfa, 0x2e, 0xac, 0x59, 0x5b, 0x78, 0xc5, 0x66, 0xff, 0xc2, + 0x83, 0xb5, 0x27, 0xec, 0x4c, 0xdd, 0xba, 0xde, 0xed, 0x07, 0xd0, 0xe4, 0xb3, 0x94, 0x09, 0xcc, + 0xe5, 0xdd, 0xb7, 0xd5, 0xa5, 0x55, 0xf0, 0x6e, 0xaa, 0xe1, 0xd3, 0x59, 0xca, 0x7c, 0xf1, 0x05, + 0xfd, 0x14, 0xda, 0x16, 0x90, 0x6c, 0xc1, 0xfa, 0x17, 0x1f, 0x3f, 0x7d, 0xf2, 0xf0, 0xf0, 0x70, + 0x70, 0xf0, 0xd9, 0xbd, 0x6f, 0x3e, 0xfc, 0x8d, 0xc1, 0xde, 0xdd, 0xc3, 0xbd, 0xd5, 0x0b, 0x64, + 0x13, 0xc8, 0x93, 0x87, 0x87, 0x4f, 0x1f, 0x3e, 0x70, 0xe0, 0x1e, 0x59, 0x81, 0xb6, 0x0d, 0x68, + 0xd0, 0x3e, 0xf4, 0x9e, 0xb0, 0xb3, 0x2f, 0x42, 0x1e, 0xb3, 0x3c, 0x77, 0x97, 0xa7, 0x37, 0x81, + 0xd8, 0x7b, 0x52, 0xc7, 0xec, 0xc1, 0xa2, 0xd2, 0x98, 0xda, 0x60, 0xa8, 0x21, 0x7d, 0x07, 0xc8, + 0x61, 0x38, 0x8e, 0x3f, 0x61, 0x79, 0x1e, 0x8c, 0x99, 0x3e, 0xec, 0x2a, 0xcc, 0x4d, 0xf2, 0xb1, + 0x7a, 0x68, 0xf8, 0x93, 0x7e, 0x0d, 0xd6, 0x1d, 0x3c, 0x45, 0xf8, 0x0a, 0xb4, 0xf2, 0x70, 0x1c, + 0x07, 0x7c, 0x9a, 0x31, 0x45, 0xba, 0x00, 0xd0, 0x47, 0xb0, 0xf1, 0x39, 0xcb, 0xc2, 0xe3, 0xd9, + 0xeb, 0xc8, 0xbb, 0x74, 0x1a, 0x65, 0x3a, 0x0f, 0xe1, 0x62, 0x89, 0x8e, 0x5a, 0x5e, 0x4a, 0xa6, + 0xba, 0xbf, 0x25, 0x5f, 0x0e, 0xac, 0x77, 0xda, 0xb0, 0xdf, 0x29, 0xfd, 0x0c, 0xc8, 0xfd, 0x24, + 0x8e, 0xd9, 0x90, 0x1f, 0x30, 0x96, 0xe9, 0xcd, 0xfc, 0x7f, 0x4b, 0x0c, 0xdb, 0xbb, 0x5b, 0xea, + 0x62, 0xcb, 0x8f, 0x5f, 0xc9, 0x27, 0x81, 0x66, 0xca, 0xb2, 0x89, 0x20, 0xbc, 0xe4, 0x8b, 0xdf, + 0x74, 0x07, 0xd6, 0x1d, 0xb2, 0x05, 0xcf, 0x53, 0xc6, 0xb2, 0x81, 0xda, 0xdd, 0xbc, 0xaf, 0x87, + 0xf4, 0x36, 0x5c, 0x7c, 0x10, 0xe6, 0xc3, 0xea, 0x56, 0xf0, 0x93, 0xe9, 0xd1, 0xa0, 0x78, 0x7e, + 0x7a, 0x88, 0x56, 0xae, 0xfc, 0x89, 0xf2, 0x0d, 0xfe, 0xc0, 0x83, 0xe6, 0xde, 0xd3, 0xfd, 0xfb, + 0xe8, 0x58, 0x84, 0xf1, 0x30, 0x99, 0xa0, 0x6d, 0x90, 0xec, 0x30, 0xe3, 0x73, 0x9f, 0xd5, 0x15, + 0x68, 0x09, 0x93, 0x82, 0x86, 0x5b, 0x3c, 0xaa, 0x8e, 0x5f, 0x00, 0xd0, 0x69, 0x60, 0xcf, 0xd3, + 0x30, 0x13, 0x5e, 0x81, 0xb6, 0xf5, 0x4d, 0xa1, 0x2c, 0xab, 0x13, 0xf4, 0xdf, 0x9b, 0xd0, 0xbd, + 0x3b, 0xe4, 0xe1, 0x29, 0x53, 0xca, 0x5b, 0xac, 0x2a, 0x00, 0x6a, 0x3f, 0x6a, 0x84, 0x66, 0x26, + 0x63, 0x93, 0x84, 0xb3, 0x81, 0x73, 0x4d, 0x2e, 0x10, 0xb1, 0x86, 0x92, 0xd0, 0x20, 0x45, 0x33, + 0x20, 0xf6, 0xd7, 0xf2, 0x5d, 0x20, 0xb2, 0x0c, 0x01, 0xc8, 0x65, 0xdc, 0x59, 0xd3, 0xd7, 0x43, + 0xe4, 0xc7, 0x30, 0x48, 0x83, 0x61, 0xc8, 0x67, 0x4a, 0x1b, 0x98, 0x31, 0xd2, 0x8e, 0x92, 0x61, + 0x10, 0x0d, 0x8e, 0x82, 0x28, 0x88, 0x87, 0x4c, 0xf9, 0x27, 0x2e, 0x10, 0x5d, 0x10, 0xb5, 0x25, + 0x8d, 0x26, 0xdd, 0x94, 0x12, 0x14, 0x5d, 0x99, 0x61, 0x32, 0x99, 0x84, 0x1c, 0x3d, 0x97, 0xde, + 0x92, 0xd4, 0x3c, 0x05, 0x44, 0x9c, 0x44, 0x8e, 0xce, 0x24, 0x0f, 0x5b, 0x72, 0x35, 0x07, 0x88, + 0x54, 0x8e, 0x19, 0x13, 0x1a, 0xec, 0xd9, 0x59, 0x0f, 0x24, 0x95, 0x02, 0x82, 0xb7, 0x31, 0x8d, + 0x73, 0xc6, 0x79, 0xc4, 0x46, 0x66, 0x43, 0x6d, 0x81, 0x56, 0x9d, 0x20, 0xb7, 0x60, 0x5d, 0x3a, + 0x53, 0x79, 0xc0, 0x93, 0xfc, 0x24, 0xcc, 0x07, 0x39, 0x8b, 0x79, 0xaf, 0x23, 0xf0, 0xeb, 0xa6, + 0xc8, 0x07, 0xb0, 0x55, 0x02, 0x67, 0x6c, 0xc8, 0xc2, 0x53, 0x36, 0xea, 0x75, 0xc5, 0x57, 0xe7, + 0x4d, 0x93, 0x6b, 0xd0, 0x46, 0x1f, 0x72, 0x9a, 0x8e, 0x02, 0xce, 0xf2, 0xde, 0xb2, 0xb8, 0x07, + 0x1b, 0x44, 0x6e, 0x43, 0x37, 0x65, 0xd2, 0x0a, 0x9f, 0xf0, 0x68, 0x98, 0xf7, 0x56, 0x84, 0xe9, + 0x6b, 0xab, 0xc7, 0x86, 0xf2, 0xeb, 0xbb, 0x18, 0x28, 0x9a, 0xc3, 0xfc, 0x74, 0x30, 0x62, 0x51, + 0x30, 0xeb, 0xad, 0x0a, 0xa1, 0x2b, 0x00, 0xf4, 0x22, 0xac, 0xef, 0x87, 0x39, 0x57, 0x92, 0x66, + 0xb4, 0xdf, 0x1e, 0x6c, 0xb8, 0x60, 0xf5, 0x16, 0x6f, 0xc1, 0x92, 0x12, 0x9b, 0xbc, 0xd7, 0x16, + 0x4b, 0x6f, 0xa8, 0xa5, 0x1d, 0x89, 0xf5, 0x0d, 0x16, 0xfd, 0xfd, 0x06, 0x34, 0xf1, 0x9d, 0x9d, + 0xff, 0x26, 0xed, 0x07, 0xde, 0x70, 0x1e, 0xb8, 0xad, 0x6e, 0xe7, 0x1c, 0x75, 0x2b, 0x3c, 0xeb, + 0x19, 0x67, 0xea, 0x36, 0xa4, 0xc4, 0x5a, 0x90, 0x62, 0x3e, 0x63, 0xc3, 0x53, 0x21, 0xb6, 0x66, + 0x1e, 0x21, 0x28, 0xd4, 0x68, 0xe6, 0xc4, 0xd7, 0x52, 0x66, 0xcd, 0x58, 0xcf, 0x89, 0x2f, 0x17, + 0x8b, 0x39, 0xf1, 0x5d, 0x0f, 0x16, 0xc3, 0xf8, 0x28, 0x99, 0xc6, 0x23, 0x21, 0x9f, 0x4b, 0xbe, + 0x1e, 0x22, 0x9f, 0x53, 0xe1, 0x1d, 0x85, 0x13, 0xa6, 0x04, 0xb3, 0x00, 0x50, 0x82, 0x6e, 0x50, + 0x2e, 0x34, 0x8e, 0x61, 0xf2, 0xfb, 0xb0, 0x66, 0xc1, 0x14, 0x87, 0xaf, 0xc3, 0x3c, 0x9e, 0x5e, + 0xfb, 0xd3, 0xfa, 0x66, 0x85, 0xaa, 0x92, 0x33, 0x74, 0x15, 0x96, 0x1f, 0x33, 0xfe, 0x71, 0x7c, + 0x9c, 0x68, 0x4a, 0x7f, 0x38, 0x07, 0x2b, 0x06, 0xa4, 0x08, 0x6d, 0xc3, 0x4a, 0x38, 0x62, 0x31, + 0x0f, 0xf9, 0x6c, 0xe0, 0x78, 0x5b, 0x65, 0x30, 0x2a, 0xff, 0x20, 0x0a, 0x83, 0x5c, 0xa9, 0x0f, + 0x39, 0x20, 0xbb, 0xb0, 0x81, 0x92, 0xa7, 0x85, 0xc9, 0x5c, 0xbb, 0x74, 0xf2, 0x6a, 0xe7, 0xf0, + 0xb1, 0x20, 0x5c, 0xaa, 0xa7, 0xe2, 0x13, 0xa9, 0xea, 0xea, 0xa6, 0x90, 0x6b, 0x92, 0x12, 0x1e, + 0x79, 0x5e, 0x4a, 0xa7, 0x01, 0x54, 0xe2, 0xa3, 0x05, 0xe9, 0x60, 0x96, 0xe3, 0x23, 0x2b, 0xc6, + 0x5a, 0xaa, 0xc4, 0x58, 0xdb, 0xb0, 0x92, 0xcf, 0xe2, 0x21, 0x1b, 0x0d, 0x78, 0x82, 0xeb, 0x86, + 0xb1, 0xb8, 0x9d, 0x25, 0xbf, 0x0c, 0x16, 0xd1, 0x20, 0xcb, 0x79, 0xcc, 0xb8, 0xd0, 0x1a, 0x4b, + 0xbe, 0x1e, 0xa2, 0x02, 0x16, 0x28, 0x52, 0xe8, 0x5b, 0xbe, 0x1a, 0xa1, 0x15, 0x9b, 0x66, 0x61, + 0xde, 0xeb, 0x08, 0xa8, 0xf8, 0x4d, 0xbf, 0x27, 0x8c, 0xa3, 0x09, 0x02, 0x3f, 0x13, 0x2f, 0x97, + 0x5c, 0x86, 0x96, 0xdc, 0x53, 0x7e, 0x12, 0xe8, 0x70, 0x55, 0x00, 0x0e, 0x4f, 0x02, 0x8c, 0x5d, + 0x9c, 0x63, 0xca, 0x57, 0xd0, 0x16, 0xb0, 0x3d, 0x79, 0xca, 0xb7, 0x61, 0x59, 0x87, 0x97, 0xf9, + 0x20, 0x62, 0xc7, 0x5c, 0x3b, 0xdb, 0xf1, 0x74, 0x82, 0xcb, 0xe5, 0xfb, 0xec, 0x98, 0xd3, 0x27, + 0xb0, 0xa6, 0x5e, 0xe0, 0xa7, 0x29, 0xd3, 0x4b, 0x7f, 0xa3, 0xac, 0xff, 0xa5, 0x81, 0x5e, 0x57, + 0x92, 0x65, 0x47, 0x08, 0x25, 0xa3, 0x40, 0x7d, 0x20, 0x6a, 0xfa, 0x7e, 0x94, 0xe4, 0x4c, 0x11, + 0xa4, 0xd0, 0x19, 0x46, 0x49, 0x5e, 0x0e, 0x23, 0x6c, 0x18, 0xf2, 0x32, 0x9f, 0x0e, 0x87, 0xf8, + 0x72, 0xa5, 0x89, 0xd7, 0x43, 0xfa, 0x57, 0x1e, 0xac, 0x0b, 0x6a, 0x5a, 0x57, 0x18, 0xbf, 0xf0, + 0xcd, 0xb7, 0xd9, 0x19, 0xda, 0x61, 0xcd, 0x06, 0xcc, 0x1f, 0x27, 0xd9, 0x90, 0xa9, 0x95, 0xe4, + 0xe0, 0xe7, 0xe1, 0xe9, 0xfe, 0x93, 0x07, 0x6b, 0x62, 0xab, 0x87, 0x3c, 0xe0, 0xd3, 0x5c, 0x1d, + 0xff, 0x97, 0xa1, 0x8b, 0x47, 0x65, 0x5a, 0xfc, 0xd5, 0x46, 0x37, 0xcc, 0x4b, 0x15, 0x50, 0x89, + 0xbc, 0x77, 0xc1, 0x77, 0x91, 0xc9, 0x47, 0xd0, 0xb1, 0x73, 0x04, 0x62, 0xcf, 0xed, 0xdd, 0x4b, + 0xfa, 0x94, 0x15, 0xc9, 0xd9, 0xbb, 0xe0, 0x3b, 0x1f, 0x90, 0x3b, 0x00, 0xc2, 0x32, 0x0b, 0xb2, + 0x2a, 0x0c, 0xbc, 0xe4, 0x32, 0xc9, 0xba, 0xac, 0xbd, 0x0b, 0xbe, 0x85, 0x7e, 0x6f, 0x09, 0x16, + 0xa4, 0x29, 0xa1, 0x8f, 0xa1, 0xeb, 0xec, 0xd4, 0xf1, 0xe0, 0x3b, 0xd2, 0x83, 0xaf, 0x04, 0x78, + 0x8d, 0x9a, 0x00, 0xef, 0x6f, 0x1b, 0x40, 0x50, 0xda, 0x4a, 0xd7, 0xf9, 0x0e, 0x2c, 0x2b, 0xf6, + 0xbb, 0xce, 0x5b, 0x09, 0x2a, 0x6c, 0x5e, 0x32, 0x72, 0x3c, 0x98, 0x8e, 0x6f, 0x83, 0xc8, 0x4d, + 0x20, 0xd6, 0x50, 0x47, 0xed, 0xd2, 0x1e, 0xd4, 0xcc, 0xa0, 0xe2, 0x92, 0xee, 0x87, 0x8e, 0x57, + 0x95, 0xc7, 0xd6, 0x14, 0xf7, 0x5b, 0x3b, 0x27, 0x92, 0x49, 0xd3, 0xfc, 0x04, 0x6d, 0xb2, 0xf6, + 0x71, 0xf4, 0xb8, 0x2c, 0x48, 0x0b, 0xaf, 0x15, 0xa4, 0xc5, 0xb2, 0x20, 0x09, 0x0b, 0x97, 0x85, + 0xa7, 0x01, 0x67, 0xda, 0x6a, 0xa8, 0x21, 0xfd, 0x89, 0x07, 0xab, 0xc8, 0x3d, 0x47, 0xc2, 0x3e, + 0x04, 0x21, 0xe0, 0x6f, 0x28, 0x60, 0x0e, 0xee, 0xcf, 0x2e, 0x5f, 0x1f, 0x40, 0x4b, 0x10, 0x4c, + 0x52, 0x16, 0x2b, 0xf1, 0xea, 0xb9, 0xe2, 0x55, 0xe8, 0x96, 0xbd, 0x0b, 0x7e, 0x81, 0x6c, 0x09, + 0xd7, 0x3f, 0x78, 0xd0, 0x56, 0xdb, 0xfc, 0x1f, 0xbb, 0xd4, 0x7d, 0x58, 0x42, 0x39, 0xb3, 0x3c, + 0x56, 0x33, 0x46, 0x9d, 0x3e, 0xc1, 0x88, 0x06, 0x8d, 0x98, 0xe3, 0x4e, 0x97, 0xc1, 0x68, 0x91, + 0x84, 0x1a, 0xcd, 0x07, 0x3c, 0x8c, 0x06, 0x7a, 0x56, 0x25, 0xda, 0xea, 0xa6, 0x50, 0x9b, 0xe4, + 0x3c, 0x18, 0x33, 0x65, 0x6c, 0xe4, 0x00, 0xe3, 0x06, 0x75, 0xa0, 0xb2, 0xab, 0xf4, 0x63, 0x80, + 0xad, 0xca, 0x94, 0x71, 0x97, 0x94, 0x87, 0x18, 0x85, 0x93, 0xa3, 0xc4, 0x38, 0x9b, 0x9e, 0xed, + 0x3c, 0x3a, 0x53, 0x64, 0x0c, 0x17, 0xb5, 0x55, 0x45, 0x9e, 0x16, 0x36, 0xb4, 0x21, 0xdc, 0x81, + 0xdb, 0xae, 0x0c, 0x94, 0x17, 0xd4, 0x70, 0xfb, 0x3d, 0xd6, 0xd3, 0x23, 0x27, 0xd0, 0x33, 0xe6, + 0x5b, 0x29, 0x6e, 0xcb, 0xc4, 0xe3, 0x5a, 0xef, 0xbd, 0x66, 0x2d, 0xa1, 0x65, 0x46, 0x7a, 0x99, + 0x73, 0xa9, 0x91, 0x19, 0x5c, 0xd5, 0x73, 0x42, 0x33, 0x57, 0xd7, 0x6b, 0xbe, 0xd1, 0xd9, 0x1e, + 0xe1, 0xc7, 0xee, 0xa2, 0xaf, 0x21, 0xdc, 0xff, 0xb1, 0x07, 0xcb, 0x2e, 0x39, 0x14, 0x1d, 0x15, + 0x75, 0x68, 0xd5, 0xa1, 0xdd, 0xa2, 0x12, 0xb8, 0x1a, 0x37, 0x35, 0xea, 0xe2, 0x26, 0x3b, 0x3a, + 0x9a, 0x7b, 0x5d, 0x74, 0xd4, 0x7c, 0xb3, 0xe8, 0x68, 0xbe, 0x2e, 0x3a, 0xea, 0xff, 0xa7, 0x07, + 0xa4, 0x7a, 0xbf, 0xe4, 0xb1, 0x0c, 0xdc, 0x62, 0x16, 0x29, 0x3d, 0xf1, 0x0b, 0x6f, 0x26, 0x23, + 0x9a, 0x87, 0xfa, 0x6b, 0x14, 0x56, 0x5b, 0x11, 0xd8, 0xce, 0x48, 0xd7, 0xaf, 0x9b, 0x2a, 0xc5, + 0x6b, 0xcd, 0xd7, 0xc7, 0x6b, 0xf3, 0xaf, 0x8f, 0xd7, 0x16, 0xca, 0xf1, 0x5a, 0xff, 0xb7, 0xa1, + 0xeb, 0xdc, 0xfa, 0xcf, 0xef, 0xc4, 0x65, 0x47, 0x46, 0x5e, 0xb0, 0x03, 0xeb, 0xff, 0x47, 0x03, + 0x48, 0x55, 0xf2, 0xfe, 0x4f, 0xf7, 0x20, 0xe4, 0xc8, 0x51, 0x20, 0x73, 0x4a, 0x8e, 0x1c, 0xd5, + 0xf1, 0xbf, 0xa9, 0x14, 0xdf, 0x83, 0xb5, 0x8c, 0x0d, 0x93, 0x53, 0x96, 0x59, 0x31, 0xb3, 0xbc, + 0xaa, 0xea, 0x04, 0xba, 0x72, 0x6e, 0x94, 0xba, 0xe4, 0xd4, 0x06, 0x2c, 0xcb, 0x50, 0x0a, 0x56, + 0xe9, 0x37, 0x60, 0x43, 0x96, 0x6c, 0xee, 0x49, 0x52, 0xda, 0x9b, 0xb8, 0x0e, 0x9d, 0x33, 0x99, + 0xa6, 0x1b, 0x24, 0x71, 0x34, 0x53, 0x46, 0xa4, 0xad, 0x60, 0x9f, 0xc6, 0xd1, 0x8c, 0xfe, 0xc8, + 0x83, 0x8b, 0xa5, 0x6f, 0x8b, 0x6c, 0xbc, 0x54, 0xb5, 0xae, 0xfe, 0x75, 0x81, 0x78, 0x44, 0x25, + 0xe3, 0xd6, 0x11, 0xa5, 0x49, 0xaa, 0x4e, 0x20, 0x0b, 0xa7, 0x71, 0x15, 0x5f, 0x5e, 0x4c, 0xdd, + 0x14, 0xdd, 0x82, 0x8b, 0xea, 0xf2, 0xdd, 0xb3, 0xd1, 0x5d, 0xd8, 0x2c, 0x4f, 0x14, 0x99, 0x2f, + 0x77, 0xcb, 0x7a, 0x48, 0x3f, 0x02, 0xf2, 0xad, 0x29, 0xcb, 0x66, 0x22, 0xef, 0x6f, 0x52, 0xab, + 0x5b, 0xe5, 0x10, 0x7b, 0x21, 0x9d, 0x1e, 0x7d, 0x93, 0xcd, 0x74, 0xb9, 0xa4, 0x61, 0xca, 0x25, + 0xf4, 0x0e, 0xac, 0x3b, 0x04, 0x0c, 0xab, 0x16, 0x44, 0xed, 0x40, 0x87, 0x9f, 0x6e, 0x7d, 0x41, + 0xcd, 0xd1, 0x3f, 0xf7, 0x60, 0x6e, 0x2f, 0x49, 0xed, 0x9c, 0x91, 0xe7, 0xe6, 0x8c, 0x94, 0xee, + 0x1c, 0x18, 0xd5, 0xd8, 0x50, 0x2f, 0xdf, 0x06, 0xa2, 0xe6, 0x0b, 0x26, 0x1c, 0x03, 0xb0, 0xe3, + 0x24, 0x3b, 0x0b, 0xb2, 0x91, 0xe2, 0x5f, 0x09, 0x8a, 0xdb, 0x2f, 0x14, 0x0c, 0xfe, 0x44, 0xa7, + 0x41, 0x24, 0xce, 0x66, 0x2a, 0x66, 0x54, 0x23, 0xfa, 0x03, 0x0f, 0xe6, 0xc5, 0x5e, 0xf1, 0x35, + 0xc8, 0xfb, 0x15, 0xa5, 0x32, 0x91, 0x97, 0xf3, 0xe4, 0x6b, 0x28, 0x81, 0x4b, 0x05, 0xb4, 0x46, + 0xa5, 0x80, 0x76, 0x05, 0x5a, 0x72, 0x54, 0x54, 0x9c, 0x0a, 0x00, 0xb9, 0x0a, 0xcd, 0x93, 0x24, + 0xd5, 0x36, 0x0c, 0x74, 0x22, 0x26, 0x49, 0x7d, 0x01, 0xa7, 0x37, 0x60, 0xe5, 0x49, 0x32, 0x62, + 0x56, 0xb4, 0x7e, 0xee, 0x35, 0xd1, 0xdf, 0xf1, 0x60, 0x49, 0x23, 0x93, 0x6d, 0x68, 0xa2, 0x29, + 0x2a, 0x39, 0x7f, 0x26, 0x9d, 0x8a, 0x78, 0xbe, 0xc0, 0x40, 0x15, 0x22, 0x62, 0xc3, 0xc2, 0x55, + 0xd0, 0x91, 0x61, 0x61, 0x84, 0xd1, 0x1d, 0x17, 0x7b, 0x2e, 0x19, 0xab, 0x12, 0x94, 0xfe, 0xb5, + 0x07, 0x5d, 0x67, 0x0d, 0x74, 0xd0, 0xa3, 0x20, 0xe7, 0x2a, 0x05, 0xa5, 0x98, 0x68, 0x83, 0xec, + 0xcc, 0x4e, 0xc3, 0xcd, 0xec, 0x98, 0xcc, 0xc2, 0x9c, 0x9d, 0x59, 0xb8, 0x05, 0xad, 0xa2, 0x18, + 0xd9, 0x74, 0x54, 0x03, 0xae, 0xa8, 0x13, 0xc5, 0x05, 0x12, 0xd2, 0x19, 0x26, 0x51, 0x92, 0xa9, + 0x5a, 0x9d, 0x1c, 0xd0, 0x3b, 0xd0, 0xb6, 0xf0, 0x71, 0x1b, 0x31, 0xe3, 0x67, 0x49, 0xf6, 0x4c, + 0x27, 0x98, 0xd4, 0xd0, 0x14, 0x48, 0x1a, 0x45, 0x81, 0x84, 0xfe, 0x8d, 0x07, 0x5d, 0x94, 0x94, + 0x30, 0x1e, 0x1f, 0x24, 0x51, 0x38, 0x9c, 0x09, 0x89, 0xd1, 0x42, 0x31, 0x18, 0xb1, 0x88, 0x07, + 0x46, 0x62, 0x5c, 0x30, 0xda, 0xfc, 0x49, 0x18, 0x0b, 0x95, 0xa5, 0xe4, 0xc5, 0x8c, 0x51, 0xf2, + 0xd1, 0x76, 0x1d, 0x05, 0x39, 0x1b, 0x4c, 0x30, 0x9c, 0x50, 0xba, 0xda, 0x01, 0xa2, 0xfa, 0x40, + 0x40, 0x16, 0x70, 0x36, 0x98, 0x84, 0x51, 0x14, 0x4a, 0x5c, 0x29, 0xe1, 0x75, 0x53, 0x18, 0x66, + 0xb5, 0x95, 0x9a, 0x78, 0x38, 0x1a, 0xcb, 0x5c, 0xa9, 0x72, 0x44, 0xcc, 0xf3, 0xb3, 0x20, 0x7a, + 0xde, 0x71, 0x5d, 0x2c, 0x48, 0xf9, 0x5a, 0xe7, 0xaa, 0xd7, 0x7a, 0x05, 0x5a, 0x28, 0x5e, 0xb7, + 0x85, 0x8f, 0x24, 0x6b, 0xd7, 0x05, 0x40, 0xcf, 0xee, 0x8a, 0xd9, 0xf9, 0x62, 0x56, 0x00, 0x1c, + 0xaf, 0x68, 0xa1, 0xe4, 0x15, 0x7d, 0x00, 0x1d, 0x45, 0x46, 0xf0, 0x5d, 0x84, 0x4b, 0x85, 0x80, + 0x3b, 0x77, 0xe2, 0x3b, 0x98, 0xfa, 0xcb, 0x5d, 0xfd, 0xe5, 0xd2, 0xeb, 0xbe, 0xd4, 0x98, 0xf4, + 0x22, 0xac, 0x2b, 0xe6, 0x3d, 0xce, 0x82, 0xf4, 0x44, 0xab, 0xde, 0x91, 0x29, 0x90, 0x0a, 0x30, + 0xb9, 0x01, 0xf3, 0xf8, 0x99, 0xd6, 0x7e, 0xf5, 0x8f, 0x4e, 0xa2, 0x90, 0x6d, 0x98, 0x67, 0xa3, + 0x31, 0xd3, 0x9e, 0x39, 0x71, 0x63, 0x24, 0xbc, 0x23, 0x5f, 0x22, 0xa0, 0x0a, 0x40, 0x68, 0x49, + 0x05, 0xb8, 0x9a, 0x73, 0x01, 0x87, 0x1f, 0x8f, 0xe8, 0x06, 0x90, 0x27, 0x52, 0x6a, 0xed, 0xfc, + 0xde, 0xef, 0xcd, 0x41, 0xdb, 0x02, 0xe3, 0x6b, 0x1e, 0xe3, 0x86, 0x07, 0xa3, 0x30, 0x98, 0x30, + 0xce, 0x32, 0x25, 0xa9, 0x25, 0xa8, 0x50, 0xb0, 0xa7, 0xe3, 0x41, 0x32, 0xe5, 0x83, 0x11, 0x1b, + 0x67, 0x4c, 0x1a, 0x34, 0xcf, 0x2f, 0x41, 0x11, 0x6f, 0x12, 0x3c, 0xb7, 0xf1, 0xa4, 0x3c, 0x94, + 0xa0, 0x3a, 0x5b, 0x27, 0x79, 0xd4, 0x2c, 0xb2, 0x75, 0x92, 0x23, 0x65, 0x3d, 0x34, 0x5f, 0xa3, + 0x87, 0xde, 0x87, 0x4d, 0xa9, 0x71, 0xd4, 0xdb, 0x1c, 0x94, 0xc4, 0xe4, 0x9c, 0x59, 0x72, 0x03, + 0x56, 0x71, 0xcf, 0x5a, 0xc0, 0xf3, 0xf0, 0x7b, 0x32, 0xce, 0xf6, 0xfc, 0x0a, 0x1c, 0x71, 0xf1, + 0x39, 0x3a, 0xb8, 0xb2, 0x98, 0x50, 0x81, 0x0b, 0xdc, 0xe0, 0xb9, 0x8b, 0xdb, 0x52, 0xb8, 0x25, + 0x38, 0xed, 0x42, 0xfb, 0x90, 0x27, 0xa9, 0xbe, 0x94, 0x65, 0xe8, 0xc8, 0xa1, 0x2a, 0x20, 0x5d, + 0x86, 0x4b, 0x42, 0x8a, 0x9e, 0x26, 0x69, 0x12, 0x25, 0xe3, 0xd9, 0xe1, 0xf4, 0x28, 0x1f, 0x66, + 0x61, 0x8a, 0x1e, 0x33, 0xfd, 0x7b, 0x0f, 0xd6, 0x9d, 0x59, 0x15, 0xea, 0xff, 0xa2, 0x14, 0x69, + 0x93, 0xf3, 0x97, 0x82, 0xb7, 0x66, 0xa9, 0x43, 0x89, 0x28, 0x53, 0x22, 0x9f, 0xa9, 0x32, 0xc0, + 0x5d, 0x58, 0xd1, 0x3b, 0xd3, 0x1f, 0x4a, 0x29, 0xec, 0x55, 0xa5, 0x50, 0x7d, 0xbf, 0xac, 0x3e, + 0xd0, 0x24, 0x7e, 0x45, 0xfa, 0x9d, 0x6c, 0x24, 0xce, 0xa8, 0x63, 0xbe, 0xbe, 0xfe, 0xde, 0x76, + 0x76, 0xf5, 0x0e, 0x86, 0x06, 0x98, 0xd3, 0x3f, 0xf2, 0x00, 0x8a, 0xdd, 0xa1, 0x60, 0x14, 0x2a, + 0xdd, 0x13, 0xd9, 0x50, 0x4b, 0x7d, 0x5f, 0x87, 0x8e, 0xc9, 0x39, 0x17, 0x56, 0xa2, 0xad, 0x61, + 0xe8, 0xa1, 0xbc, 0x0b, 0x2b, 0xe3, 0x28, 0x39, 0x12, 0x36, 0x57, 0xd4, 0x2a, 0x73, 0x55, 0x46, + 0x5b, 0x96, 0xe0, 0x47, 0x0a, 0x5a, 0x98, 0x94, 0xa6, 0x65, 0x52, 0xe8, 0x1f, 0x37, 0x4c, 0xe6, + 0xb3, 0x38, 0xf3, 0xb9, 0xaf, 0x8c, 0xec, 0x56, 0x94, 0xe3, 0x39, 0x89, 0x46, 0x91, 0xdd, 0x38, + 0x78, 0x6d, 0xa0, 0x77, 0x07, 0x96, 0x33, 0xa9, 0x7d, 0xb4, 0x6a, 0x6a, 0xbe, 0x42, 0x35, 0x75, + 0x33, 0xc7, 0xee, 0xfc, 0x3f, 0x58, 0x0d, 0x46, 0xa7, 0x2c, 0xe3, 0xa1, 0xf0, 0xf8, 0x85, 0xd1, + 0x97, 0x0a, 0x75, 0xc5, 0x82, 0x0b, 0x5b, 0xfc, 0x2e, 0xac, 0xa8, 0xd2, 0xa5, 0xc1, 0x54, 0x1d, + 0x29, 0x05, 0x18, 0x11, 0xe9, 0x5f, 0xea, 0x24, 0xab, 0x7b, 0x87, 0xe7, 0x73, 0xc4, 0x3e, 0x5d, + 0xa3, 0x74, 0xba, 0xaf, 0xaa, 0x84, 0xe7, 0x48, 0x87, 0x15, 0x2a, 0xf5, 0x2c, 0x81, 0x2a, 0x41, + 0xed, 0xb2, 0xb4, 0xf9, 0x26, 0x2c, 0xa5, 0x3f, 0x9a, 0x83, 0xc5, 0x8f, 0xe3, 0xd3, 0x24, 0x1c, + 0x8a, 0xf4, 0xe3, 0x84, 0x4d, 0x12, 0xdd, 0x40, 0x80, 0xbf, 0xd1, 0xa2, 0x8b, 0xda, 0x58, 0xca, + 0x55, 0x5e, 0x50, 0x0f, 0xd1, 0xba, 0x65, 0x45, 0xd3, 0x8c, 0x94, 0x14, 0x0b, 0x82, 0xfe, 0x61, + 0x66, 0xf7, 0x01, 0xa9, 0x51, 0xd1, 0x81, 0x31, 0x6f, 0x75, 0x60, 0x88, 0x64, 0xb5, 0x2c, 0xfb, + 0x09, 0x76, 0x2e, 0xf9, 0x7a, 0x28, 0xfc, 0xd8, 0x8c, 0xc9, 0xa0, 0x57, 0xd8, 0xc9, 0x45, 0xe5, + 0xc7, 0xda, 0x40, 0xb4, 0xa5, 0xf2, 0x03, 0x89, 0x23, 0x75, 0x8d, 0x0d, 0x42, 0xdf, 0xa2, 0xdc, + 0x4a, 0xd4, 0x92, 0x57, 0x5c, 0x02, 0xa3, 0x42, 0x1a, 0x31, 0xa3, 0x37, 0xe4, 0x19, 0x40, 0x36, + 0x05, 0x95, 0xe1, 0x96, 0x17, 0x2c, 0xcb, 0x97, 0x6a, 0x24, 0x7c, 0x90, 0x20, 0x8a, 0x8e, 0x82, + 0xe1, 0x33, 0xd1, 0xe0, 0x25, 0xaa, 0x95, 0x2d, 0xdf, 0x05, 0xe2, 0xae, 0x87, 0x11, 0x3f, 0x1d, + 0x28, 0x12, 0x5d, 0x59, 0x6d, 0xb4, 0x40, 0xf4, 0x73, 0x20, 0x77, 0x47, 0x23, 0x75, 0x43, 0x26, + 0x46, 0x28, 0x78, 0xeb, 0x39, 0xbc, 0xad, 0x39, 0x63, 0xa3, 0xf6, 0x8c, 0xf4, 0x21, 0xb4, 0x0f, + 0xac, 0xbe, 0x2c, 0x71, 0x99, 0xba, 0x23, 0x4b, 0x09, 0x80, 0x05, 0xb1, 0x16, 0x6c, 0xd8, 0x0b, + 0xd2, 0x5f, 0x02, 0xb2, 0x1f, 0xe6, 0xdc, 0xec, 0xcf, 0x84, 0x8a, 0x26, 0xe3, 0x65, 0x85, 0x8a, + 0x0a, 0x26, 0x42, 0xc5, 0xbb, 0xb2, 0xe8, 0x59, 0x3e, 0xd8, 0x0d, 0x58, 0x0a, 0x25, 0x48, 0xeb, + 0xe1, 0x65, 0x25, 0xc0, 0x1a, 0xd3, 0xcc, 0xa3, 0x43, 0xa1, 0x80, 0x8e, 0x9a, 0xff, 0x81, 0x07, + 0x8b, 0xea, 0x68, 0x68, 0x0e, 0x9d, 0x8e, 0x34, 0x79, 0x30, 0x07, 0x56, 0xdf, 0x11, 0x54, 0x95, + 0xba, 0xb9, 0x3a, 0xa9, 0x23, 0xd0, 0x4c, 0x03, 0x7e, 0x22, 0x3c, 0xe8, 0x96, 0x2f, 0x7e, 0xeb, + 0x48, 0x69, 0xde, 0x44, 0x4a, 0xba, 0xc0, 0xab, 0x36, 0x65, 0xb2, 0x96, 0xf7, 0x64, 0x81, 0xb7, + 0x00, 0x17, 0x3c, 0x50, 0x1b, 0x2c, 0xf3, 0x40, 0xa1, 0xfa, 0x66, 0x9e, 0xf6, 0xa1, 0xf7, 0x80, + 0x45, 0x8c, 0xb3, 0xbb, 0x51, 0x54, 0xa6, 0x7f, 0x19, 0x2e, 0xd5, 0xcc, 0x29, 0x4b, 0xf9, 0x08, + 0xd6, 0x1e, 0xb0, 0xa3, 0xe9, 0x78, 0x9f, 0x9d, 0x16, 0x05, 0x03, 0x02, 0xcd, 0xfc, 0x24, 0x39, + 0x53, 0xf7, 0x25, 0x7e, 0x93, 0xb7, 0x00, 0x22, 0xc4, 0x19, 0xe4, 0x29, 0x1b, 0xea, 0x76, 0x16, + 0x01, 0x39, 0x4c, 0xd9, 0x90, 0xbe, 0x0f, 0xc4, 0xa6, 0xa3, 0x8e, 0x80, 0xaf, 0x71, 0x7a, 0x34, + 0xc8, 0x67, 0x39, 0x67, 0x13, 0xdd, 0xa7, 0x63, 0x83, 0xe8, 0xbb, 0xd0, 0x39, 0x08, 0x66, 0x3e, + 0xfb, 0x52, 0x35, 0xfa, 0x61, 0x40, 0x16, 0xcc, 0x50, 0x3c, 0x4d, 0x40, 0x26, 0xa6, 0xe9, 0xdf, + 0x35, 0x60, 0x41, 0x62, 0x22, 0xd5, 0x11, 0xcb, 0x79, 0x18, 0xcb, 0xb4, 0xba, 0xa2, 0x6a, 0x81, + 0x2a, 0xf7, 0xdd, 0xa8, 0xb9, 0x6f, 0xe5, 0x22, 0xe9, 0xd2, 0xbf, 0xba, 0x58, 0x07, 0x26, 0xe2, + 0xcd, 0x70, 0xc2, 0x64, 0xbf, 0x67, 0x53, 0xc5, 0x9b, 0x1a, 0x50, 0x8a, 0x7c, 0x8b, 0x37, 0x2f, + 0xf7, 0xa7, 0x05, 0x51, 0x99, 0x05, 0x1b, 0x54, 0xab, 0x59, 0x16, 0x65, 0x67, 0x5f, 0x45, 0xb3, + 0x54, 0x34, 0xc8, 0xd2, 0x1b, 0x68, 0x10, 0xe9, 0x37, 0x39, 0x1a, 0x84, 0xc0, 0xea, 0x23, 0xc6, + 0x7c, 0x96, 0x26, 0x99, 0xe9, 0x96, 0xfc, 0xa1, 0x07, 0xab, 0xca, 0x22, 0x98, 0x39, 0x72, 0xdd, + 0x31, 0x1f, 0x5e, 0x5d, 0xa6, 0xf5, 0x6d, 0xe8, 0x8a, 0x00, 0x0a, 0xa3, 0x23, 0x11, 0x2d, 0xa9, + 0x9c, 0x82, 0x03, 0xc4, 0x3d, 0xe9, 0xdc, 0xe1, 0x24, 0x8c, 0x14, 0x83, 0x6d, 0x10, 0x9a, 0x3a, + 0x1d, 0x60, 0x09, 0xf6, 0x7a, 0xbe, 0x19, 0xd3, 0x03, 0x58, 0xb3, 0xf6, 0xab, 0x04, 0xea, 0x0e, + 0xe8, 0x7a, 0xa3, 0x4c, 0x11, 0xc8, 0x77, 0xb1, 0xe5, 0x1a, 0xb7, 0xe2, 0x33, 0x07, 0x99, 0xfe, + 0xb3, 0x07, 0xeb, 0xd2, 0xd0, 0x2b, 0x37, 0xca, 0xb4, 0x28, 0x2d, 0x48, 0xcf, 0x46, 0x0a, 0xfc, + 0xde, 0x05, 0x5f, 0x8d, 0xc9, 0xd7, 0xdf, 0xd0, 0x39, 0x31, 0xa5, 0xbd, 0x73, 0xd8, 0x33, 0x57, + 0xc7, 0x9e, 0x57, 0x1c, 0xbe, 0x2e, 0x00, 0x9e, 0xaf, 0x0d, 0x80, 0xef, 0x2d, 0xc2, 0x7c, 0x3e, + 0x4c, 0x52, 0x46, 0x37, 0x61, 0xc3, 0x3d, 0x9c, 0x64, 0xd9, 0xee, 0xbf, 0x78, 0xb0, 0x2c, 0x93, + 0x71, 0xb2, 0x0f, 0x9b, 0x65, 0x04, 0x63, 0x2d, 0xab, 0xbd, 0x9b, 0x18, 0x57, 0xb3, 0xda, 0x26, + 0xde, 0xbf, 0x5c, 0x3b, 0xa7, 0xfd, 0xec, 0xef, 0xff, 0xe4, 0xdf, 0xfe, 0xa4, 0x71, 0x91, 0xae, + 0xee, 0x9c, 0xde, 0xde, 0x11, 0x2a, 0x91, 0x9d, 0x09, 0x8c, 0x0f, 0xbd, 0x1b, 0xb8, 0x8a, 0xdd, + 0xf9, 0x6d, 0x56, 0xa9, 0xe9, 0x20, 0x37, 0xab, 0xd4, 0xb6, 0x8a, 0x3b, 0xab, 0x4c, 0x05, 0x86, + 0x59, 0x65, 0xf7, 0xbf, 0xfa, 0xd0, 0x32, 0x41, 0x21, 0xf9, 0x2e, 0x74, 0x9d, 0xc4, 0x23, 0xd1, + 0x84, 0xeb, 0x52, 0x99, 0xfd, 0x2b, 0xf5, 0x93, 0x6a, 0xd9, 0xab, 0x62, 0xd9, 0x1e, 0xd9, 0xc4, + 0x65, 0x55, 0xb6, 0x6f, 0x47, 0x64, 0x64, 0x65, 0x8f, 0xc2, 0x33, 0x58, 0x76, 0x93, 0x85, 0xe4, + 0x8a, 0x2b, 0x1a, 0xa5, 0xd5, 0xde, 0x3a, 0x67, 0x56, 0x2d, 0x77, 0x45, 0x2c, 0xb7, 0x49, 0x36, + 0xec, 0xe5, 0x4c, 0xb0, 0xc6, 0x44, 0x57, 0x89, 0xdd, 0x12, 0x4e, 0x34, 0xbd, 0xfa, 0x56, 0xf1, + 0xfe, 0xa5, 0x6a, 0xfb, 0xb7, 0xea, 0x17, 0xa7, 0x3d, 0xb1, 0x14, 0x21, 0x82, 0xa1, 0x76, 0x47, + 0x38, 0xf9, 0x0e, 0xb4, 0x4c, 0x43, 0x29, 0xd9, 0xb2, 0xba, 0x78, 0xed, 0x2e, 0xd7, 0x7e, 0xaf, + 0x3a, 0x51, 0x77, 0x55, 0x36, 0x65, 0x14, 0x88, 0x7d, 0xb8, 0xa8, 0x2c, 0xf4, 0x11, 0xfb, 0x69, + 0x4e, 0x52, 0xd3, 0xc8, 0x7e, 0xcb, 0x23, 0x77, 0x60, 0x49, 0xf7, 0xe9, 0x92, 0xcd, 0xfa, 0x7e, + 0xe3, 0xfe, 0x56, 0x05, 0xae, 0xf4, 0xc8, 0x5d, 0x80, 0xa2, 0xa5, 0x94, 0xf4, 0xce, 0xeb, 0x7c, + 0x35, 0x4c, 0xac, 0xe9, 0x3f, 0x1d, 0x8b, 0x8e, 0x5a, 0xb7, 0x63, 0x95, 0x7c, 0xa5, 0xc0, 0xaf, + 0xed, 0x65, 0x7d, 0x05, 0x41, 0xba, 0x29, 0x78, 0xb7, 0x4a, 0x96, 0x91, 0x77, 0x31, 0x3b, 0xd3, + 0xfd, 0x55, 0x0f, 0xa0, 0x6d, 0xb5, 0xa9, 0x12, 0x4d, 0xa1, 0xda, 0xe2, 0xda, 0xef, 0xd7, 0x4d, + 0xa9, 0xed, 0xfe, 0x1a, 0x74, 0x9d, 0x7e, 0x53, 0xf3, 0x32, 0xea, 0xba, 0x59, 0xcd, 0xcb, 0xa8, + 0x6f, 0x51, 0xfd, 0x36, 0xb4, 0xad, 0xee, 0x50, 0x62, 0x55, 0xb4, 0x4b, 0xdd, 0x9f, 0x66, 0x47, + 0x35, 0xcd, 0xa4, 0x74, 0x43, 0x9c, 0x77, 0x99, 0xb6, 0xf0, 0xbc, 0xa2, 0xc9, 0x08, 0x85, 0xe4, + 0xbb, 0xb0, 0xec, 0x76, 0x85, 0x9a, 0x57, 0x55, 0xdb, 0x5f, 0x6a, 0x5e, 0xd5, 0x39, 0xad, 0xa4, + 0x4a, 0x20, 0x6f, 0xac, 0x9b, 0x45, 0x76, 0x5e, 0xa8, 0x94, 0xe8, 0x4b, 0xf2, 0x2d, 0x54, 0x1d, + 0xaa, 0xeb, 0x8b, 0x14, 0x5d, 0xb2, 0x6e, 0x6f, 0x98, 0x91, 0xf6, 0x4a, 0x83, 0x18, 0x5d, 0x13, + 0xc4, 0xdb, 0xa4, 0x38, 0x01, 0xf9, 0x04, 0x16, 0x55, 0xf7, 0x17, 0xb9, 0x58, 0x48, 0xb5, 0x95, + 0x40, 0xea, 0x6f, 0x96, 0xc1, 0x8a, 0xd8, 0xba, 0x20, 0xd6, 0x25, 0x6d, 0x24, 0x36, 0x66, 0x3c, + 0x44, 0x1a, 0x31, 0xac, 0x94, 0xaa, 0x58, 0xe6, 0xb1, 0xd4, 0xd7, 0xc0, 0xfb, 0x57, 0x5f, 0x5d, + 0xfc, 0x72, 0xd5, 0x8c, 0x56, 0x2f, 0x3b, 0xba, 0x65, 0xe1, 0x37, 0xa1, 0x63, 0x37, 0x1b, 0x1a, + 0x9d, 0x5d, 0xd3, 0x98, 0x68, 0x74, 0x76, 0x5d, 0x77, 0xa2, 0xbe, 0x5c, 0xd2, 0xb1, 0x97, 0x21, + 0xdf, 0x86, 0x15, 0xab, 0x5e, 0x7a, 0x38, 0x8b, 0x87, 0x46, 0x78, 0xaa, 0x7d, 0x2b, 0xfd, 0x3a, + 0x4b, 0x4b, 0xb7, 0x04, 0xe1, 0x35, 0xea, 0x10, 0x46, 0xc1, 0xb9, 0x0f, 0x6d, 0xbb, 0x16, 0xfb, + 0x0a, 0xba, 0x5b, 0xd6, 0x94, 0xdd, 0xec, 0x71, 0xcb, 0x23, 0x7f, 0xe6, 0x41, 0xc7, 0xee, 0x88, + 0x22, 0x4e, 0x16, 0xa6, 0x44, 0xa7, 0x67, 0xcf, 0xd9, 0x84, 0xe8, 0x13, 0xb1, 0xc9, 0xbd, 0x1b, + 0x8f, 0x1c, 0x26, 0xbf, 0x70, 0x9c, 0xa8, 0x9b, 0xf6, 0x7f, 0x38, 0x5e, 0x96, 0x27, 0xed, 0xbe, + 0x9e, 0x97, 0xb7, 0x3c, 0xf2, 0xa1, 0xfc, 0xa7, 0x8e, 0x0e, 0x68, 0x88, 0xa5, 0xd8, 0xca, 0xec, + 0xb2, 0xff, 0xfe, 0xb2, 0xed, 0xdd, 0xf2, 0xc8, 0x6f, 0xc9, 0xbf, 0x6d, 0xa8, 0x6f, 0x05, 0xd7, + 0xdf, 0xf4, 0x7b, 0xfa, 0xb6, 0x38, 0xc9, 0x55, 0x7a, 0xc9, 0x39, 0x49, 0x59, 0xb3, 0x1f, 0x00, + 0x14, 0xd1, 0x29, 0x29, 0x85, 0x6a, 0x46, 0xe7, 0x55, 0x03, 0x58, 0xf7, 0x36, 0x75, 0x44, 0x27, + 0xd5, 0x40, 0xc7, 0x8a, 0x0b, 0x73, 0x73, 0x9d, 0xd5, 0x28, 0xb3, 0xdf, 0xaf, 0x9b, 0x52, 0xf4, + 0xbf, 0x2a, 0xe8, 0xbf, 0x45, 0x2e, 0xdb, 0xf4, 0x77, 0x5e, 0xd8, 0x51, 0xe9, 0x4b, 0xf2, 0x39, + 0x74, 0xf7, 0x93, 0xe4, 0xd9, 0x34, 0x35, 0x09, 0x10, 0x37, 0xce, 0xc2, 0xc8, 0xb8, 0x5f, 0x3a, + 0x14, 0xbd, 0x2e, 0x28, 0x5f, 0x26, 0x97, 0x5c, 0xca, 0x45, 0xac, 0xfc, 0x92, 0x04, 0xb0, 0x66, + 0xec, 0x9d, 0x39, 0x48, 0xdf, 0xa5, 0x63, 0x87, 0xac, 0x95, 0x35, 0x1c, 0x0f, 0xc4, 0xac, 0x91, + 0x6b, 0x9a, 0xb7, 0x3c, 0x72, 0x00, 0x9d, 0x07, 0x6c, 0x98, 0x8c, 0x98, 0x0a, 0x8d, 0xd6, 0x8b, + 0x9d, 0x9b, 0x98, 0xaa, 0xdf, 0x75, 0x80, 0xae, 0x06, 0x48, 0x83, 0x59, 0xc6, 0xbe, 0xdc, 0x79, + 0xa1, 0x82, 0xae, 0x97, 0x5a, 0x03, 0xe8, 0x40, 0xd1, 0xd1, 0x00, 0xa5, 0xc8, 0xd2, 0xd1, 0x00, + 0x95, 0xc8, 0xd2, 0xd1, 0x00, 0x3a, 0x50, 0x25, 0x11, 0xc6, 0x9b, 0xa5, 0x60, 0xd4, 0x58, 0xcd, + 0xf3, 0x42, 0xd8, 0xfe, 0xb5, 0xf3, 0x11, 0xdc, 0xd5, 0x6e, 0xb8, 0xab, 0x1d, 0x42, 0xf7, 0x01, + 0x93, 0xcc, 0x92, 0x55, 0x85, 0xbe, 0xab, 0x52, 0xec, 0x0a, 0x44, 0x59, 0xdd, 0x88, 0x39, 0x57, + 0xc5, 0x8b, 0x94, 0x3e, 0xf9, 0x0e, 0xb4, 0x1f, 0x33, 0xae, 0xcb, 0x08, 0xc6, 0xf7, 0x28, 0xd5, + 0x15, 0xfa, 0x35, 0x55, 0x08, 0x7a, 0x4d, 0x50, 0xeb, 0x93, 0x9e, 0xa1, 0xb6, 0xc3, 0x46, 0x63, + 0x26, 0x1f, 0xff, 0x20, 0x1c, 0xbd, 0x24, 0xbf, 0x2e, 0x88, 0x9b, 0xca, 0xe3, 0xa6, 0x95, 0x7d, + 0xb6, 0x89, 0xaf, 0x94, 0xe0, 0x75, 0x94, 0xe3, 0x64, 0xc4, 0x2c, 0x63, 0x17, 0x43, 0xdb, 0x2a, + 0x33, 0x9b, 0x07, 0x55, 0xad, 0x5d, 0x9b, 0x07, 0x55, 0x53, 0x95, 0xa6, 0xdb, 0x62, 0x1d, 0x4a, + 0xae, 0x15, 0xeb, 0xc8, 0x4a, 0x74, 0xb1, 0xd2, 0xce, 0x8b, 0x60, 0xc2, 0x5f, 0x92, 0x2f, 0x44, + 0x6b, 0xb4, 0x5d, 0x2a, 0x29, 0x7c, 0x9f, 0x72, 0x55, 0xc5, 0x30, 0xcb, 0x9a, 0x72, 0xfd, 0x21, + 0xb9, 0x94, 0xb0, 0x89, 0x5f, 0x07, 0x38, 0xe4, 0x49, 0xfa, 0x20, 0x60, 0x93, 0x24, 0x2e, 0x34, + 0x59, 0x51, 0x0e, 0x28, 0x34, 0x99, 0x55, 0x13, 0x20, 0x5f, 0x58, 0xde, 0xa7, 0x53, 0x69, 0xd2, + 0xc2, 0x75, 0x6e, 0xc5, 0xc0, 0x30, 0xa4, 0xa6, 0x6a, 0x70, 0xcb, 0x43, 0x5f, 0xb2, 0x48, 0x7d, + 0x18, 0x5f, 0xb2, 0x92, 0x55, 0x31, 0x6a, 0xb0, 0x26, 0x4f, 0x72, 0x00, 0xad, 0x22, 0xfe, 0xd6, + 0xe6, 0xa9, 0x1c, 0xad, 0x1b, 0x7b, 0x53, 0x09, 0x8b, 0xe9, 0xaa, 0x60, 0x15, 0x90, 0x25, 0x64, + 0x95, 0xa8, 0x94, 0x0f, 0x61, 0x5d, 0x6e, 0xd0, 0x18, 0x4f, 0x91, 0xe0, 0xd6, 0x27, 0xa9, 0x09, + 0x83, 0xcd, 0x6b, 0xae, 0x8b, 0x22, 0xb5, 0x77, 0x42, 0xcd, 0x0a, 0x1f, 0x7a, 0x37, 0x8e, 0x16, + 0xc4, 0x1f, 0x8c, 0xbf, 0xf6, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x8e, 0x28, 0xc4, 0x0c, 0x92, + 0x3c, 0x00, 0x00, } diff --git a/lnrpc/rpc.pb.gw.go b/lnrpc/rpc.pb.gw.go index e4b65da3a..0c9fa72a8 100644 --- a/lnrpc/rpc.pb.gw.go +++ b/lnrpc/rpc.pb.gw.go @@ -523,15 +523,15 @@ func request_Lightning_FeeReport_0(ctx context.Context, marshaler runtime.Marsha } -func request_Lightning_UpdateFees_0(ctx context.Context, marshaler runtime.Marshaler, client LightningClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq FeeUpdateRequest +func request_Lightning_UpdateChannelPolicy_0(ctx context.Context, marshaler runtime.Marshaler, client LightningClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq PolicyUpdateRequest var metadata runtime.ServerMetadata if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := client.UpdateFees(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.UpdateChannelPolicy(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } @@ -1452,7 +1452,7 @@ func RegisterLightningHandler(ctx context.Context, mux *runtime.ServeMux, conn * }) - mux.Handle("POST", pattern_Lightning_UpdateFees_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("POST", pattern_Lightning_UpdateChannelPolicy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(ctx) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { @@ -1470,14 +1470,14 @@ func RegisterLightningHandler(ctx context.Context, mux *runtime.ServeMux, conn * runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_Lightning_UpdateFees_0(rctx, inboundMarshaler, client, req, pathParams) + resp, md, err := request_Lightning_UpdateChannelPolicy_0(rctx, inboundMarshaler, client, req, pathParams) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - forward_Lightning_UpdateFees_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Lightning_UpdateChannelPolicy_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -1539,7 +1539,7 @@ var ( pattern_Lightning_FeeReport_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "fees"}, "")) - pattern_Lightning_UpdateFees_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "fees"}, "")) + pattern_Lightning_UpdateChannelPolicy_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "fees"}, "")) ) var ( @@ -1597,5 +1597,5 @@ var ( forward_Lightning_FeeReport_0 = runtime.ForwardResponseMessage - forward_Lightning_UpdateFees_0 = runtime.ForwardResponseMessage + forward_Lightning_UpdateChannelPolicy_0 = runtime.ForwardResponseMessage ) diff --git a/lnrpc/rpc.proto b/lnrpc/rpc.proto index 1598a9dd8..6fca5c07f 100644 --- a/lnrpc/rpc.proto +++ b/lnrpc/rpc.proto @@ -441,11 +441,11 @@ service Lightning { }; } - /** lncli: `updatefees` - UpdateFees allows the caller to update the fee schedule for all channels - globally, or a particular channel. + /** lncli: `updatechanpolicy` + UpdateChannelPolicy allows the caller to update the fee schedule and + channel policies for all channels globally, or a particular channel. */ - rpc UpdateFees(FeeUpdateRequest) returns (FeeUpdateResponse) { + rpc UpdateChannelPolicy(PolicyUpdateRequest) returns (PolicyUpdateResponse) { option (google.api.http) = { post: "/v1/fees" body: "*" @@ -1401,12 +1401,12 @@ message FeeReportResponse { repeated ChannelFeeReport channel_fees = 1 [json_name = "channel_fees"]; } -message FeeUpdateRequest { +message PolicyUpdateRequest { oneof scope { - /// If set, then this fee update applies to all currently active channels. + /// If set, then this update applies to all currently active channels. bool global = 1 [json_name = "global"] ; - /// If set, this fee update will target a specific channel. + /// If set, this update will target a specific channel. ChannelPoint chan_point = 2 [json_name = "chan_point"]; } @@ -1415,6 +1415,9 @@ message FeeUpdateRequest { /// The effective fee rate in milli-satoshis. The precision of this value goes up to 6 decimal places, so 1e-6. double fee_rate = 4 [json_name = "fee_rate"]; + + /// The required timelock delta for HTLCs forwarded over the channel. + uint32 time_lock_delta = 5 [json_name = "time_lock_delta"]; } -message FeeUpdateResponse { +message PolicyUpdateResponse { } diff --git a/lnrpc/rpc.swagger.json b/lnrpc/rpc.swagger.json index 53e34d598..aecdc2cf7 100644 --- a/lnrpc/rpc.swagger.json +++ b/lnrpc/rpc.swagger.json @@ -222,13 +222,13 @@ ] }, "post": { - "summary": "* lncli: `updatefees`\nUpdateFees allows the caller to update the fee schedule for all channels\nglobally, or a particular channel.", - "operationId": "UpdateFees", + "summary": "* lncli: `updatechanpolicy`\nUpdateChannelPolicy allows the caller to update the fee schedule and\nchannel policies for all channels globally, or a particular channel.", + "operationId": "UpdateChannelPolicy", "responses": { "200": { "description": "", "schema": { - "$ref": "#/definitions/lnrpcFeeUpdateResponse" + "$ref": "#/definitions/lnrpcPolicyUpdateResponse" } } }, @@ -238,7 +238,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/lnrpcFeeUpdateRequest" + "$ref": "#/definitions/lnrpcPolicyUpdateRequest" } } ], @@ -1166,33 +1166,6 @@ } } }, - "lnrpcFeeUpdateRequest": { - "type": "object", - "properties": { - "global": { - "type": "boolean", - "format": "boolean", - "description": "/ If set, then this fee update applies to all currently active channels." - }, - "chan_point": { - "$ref": "#/definitions/lnrpcChannelPoint", - "description": "/ If set, this fee update will target a specific channel." - }, - "base_fee_msat": { - "type": "string", - "format": "int64", - "description": "/ The base fee charged regardless of the number of milli-satoshis sent." - }, - "fee_rate": { - "type": "number", - "format": "double", - "description": "/ The effective fee rate in milli-satoshis. The precision of this value goes up to 6 decimal places, so 1e-6." - } - } - }, - "lnrpcFeeUpdateResponse": { - "type": "object" - }, "lnrpcGetInfoResponse": { "type": "object", "properties": { @@ -1826,6 +1799,38 @@ } } }, + "lnrpcPolicyUpdateRequest": { + "type": "object", + "properties": { + "global": { + "type": "boolean", + "format": "boolean", + "description": "/ If set, then this update applies to all currently active channels." + }, + "chan_point": { + "$ref": "#/definitions/lnrpcChannelPoint", + "description": "/ If set, this update will target a specific channel." + }, + "base_fee_msat": { + "type": "string", + "format": "int64", + "description": "/ The base fee charged regardless of the number of milli-satoshis sent." + }, + "fee_rate": { + "type": "number", + "format": "double", + "description": "/ The effective fee rate in milli-satoshis. The precision of this value goes up to 6 decimal places, so 1e-6." + }, + "time_lock_delta": { + "type": "integer", + "format": "int64", + "description": "/ The required timelock delta for HTLCs forwarded over the channel." + } + } + }, + "lnrpcPolicyUpdateResponse": { + "type": "object" + }, "lnrpcQueryRoutesResponse": { "type": "object", "properties": { From 26421031e26056168afc350f4dfcb2ed8c68e86f Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Sat, 16 Dec 2017 23:13:17 +0100 Subject: [PATCH 05/25] lncli: rename updatefees to updatechanpolicy This commit renames the `lncli updatefees` command to `lncli updatechanpolicy` and adds `time_lock_delta` as one of the passed parameters. --- cmd/lncli/commands.go | 59 ++++++++++++++++++++++++++++++------------- cmd/lncli/main.go | 2 +- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/cmd/lncli/commands.go b/cmd/lncli/commands.go index 43a40a113..94d511ed5 100644 --- a/cmd/lncli/commands.go +++ b/cmd/lncli/commands.go @@ -1970,7 +1970,7 @@ var feeReportCommand = cli.Command{ Usage: "display the current fee policies of all active channels", Description: ` Returns the current fee policies of all active channels. - Fee policies can be updated using the updateFees command.`, + Fee policies can be updated using the updatechanpolicy command.`, Action: actionDecorator(feeReport), } @@ -1989,13 +1989,13 @@ func feeReport(ctx *cli.Context) error { return nil } -var updateFeesCommand = cli.Command{ - Name: "updatefees", - Usage: "update the fee policy for all channels, or a single channel", - ArgsUsage: "base_fee_msat fee_rate [channel_point]", +var updateChannelPolicyCommand = cli.Command{ + Name: "updatechanpolicy", + Usage: "update the channel policy for all channels, or a single channel", + ArgsUsage: "base_fee_msat fee_rate time_lock_delta [channel_point]", Description: ` - Updates the fee policy for all channels, or just a particular channel - identified by it's channel point. The fee update will be committed, and + Updates the channel policy for all channels, or just a particular channel + identified by its channel point. The update will be committed, and broadcast to the rest of the network within the next batch. Channel points are encoded as: funding_txid:output_index`, Flags: []cli.Flag{ @@ -2011,6 +2011,11 @@ var updateFeesCommand = cli.Command{ "proportionally based on the value of each " + "forwarded HTLC, the lowest possible rate is 0.000001", }, + cli.Int64Flag{ + Name: "time_lock_delta", + Usage: "the CLTV delta that will be applied to all " + + "forwarded HTLCs", + }, cli.StringFlag{ Name: "chan_point", Usage: "The channel whose fee policy should be " + @@ -2018,18 +2023,19 @@ var updateFeesCommand = cli.Command{ "will be updated. Takes the form of: txid:output_index", }, }, - Action: actionDecorator(updateFees), + Action: actionDecorator(updateChannelPolicy), } -func updateFees(ctx *cli.Context) error { +func updateChannelPolicy(ctx *cli.Context) error { ctxb := context.Background() client, cleanUp := getClient(ctx) defer cleanUp() var ( - baseFee int64 - feeRate float64 - err error + baseFee int64 + feeRate float64 + timeLockDelta int64 + err error ) args := ctx.Args() @@ -2060,10 +2066,26 @@ func updateFees(ctx *cli.Context) error { return fmt.Errorf("fee_rate argument missing") } + switch { + case ctx.IsSet("time_lock_delta"): + timeLockDelta = ctx.Int64("time_lock_delta") + case args.Present(): + timeLockDelta, err = strconv.ParseInt(args.First(), 10, 64) + if err != nil { + return fmt.Errorf("unable to decode time_lock_delta: %v", + err) + } + + args = args.Tail() + default: + return fmt.Errorf("time_lock_delta argument missing") + } + var ( chanPoint *lnrpc.ChannelPoint chanPointStr string ) + switch { case ctx.IsSet("chan_point"): chanPointStr = ctx.String("chan_point") @@ -2093,22 +2115,23 @@ func updateFees(ctx *cli.Context) error { } } - req := &lnrpc.FeeUpdateRequest{ - BaseFeeMsat: baseFee, - FeeRate: feeRate, + req := &lnrpc.PolicyUpdateRequest{ + BaseFeeMsat: baseFee, + FeeRate: feeRate, + TimeLockDelta: uint32(timeLockDelta), } if chanPoint != nil { - req.Scope = &lnrpc.FeeUpdateRequest_ChanPoint{ + req.Scope = &lnrpc.PolicyUpdateRequest_ChanPoint{ ChanPoint: chanPoint, } } else { - req.Scope = &lnrpc.FeeUpdateRequest_Global{ + req.Scope = &lnrpc.PolicyUpdateRequest_Global{ Global: true, } } - resp, err := client.UpdateFees(ctxb, req) + resp, err := client.UpdateChannelPolicy(ctxb, req) if err != nil { return err } diff --git a/cmd/lncli/main.go b/cmd/lncli/main.go index 4344a28b9..99a35b30f 100644 --- a/cmd/lncli/main.go +++ b/cmd/lncli/main.go @@ -193,7 +193,7 @@ func main() { signMessageCommand, verifyMessageCommand, feeReportCommand, - updateFeesCommand, + updateChannelPolicyCommand, } if err := app.Run(os.Args); err != nil { From c4139b9f893a7861156b77b21aee07f6833c9b1a Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Sat, 16 Dec 2017 23:14:58 +0100 Subject: [PATCH 06/25] rpcserver: rename UpdateFees -> UpdateChannelPolicy This commit changes the name of the UpdateFee method to UpdateChannelPolicy, to mimic the recent proto change. It also reads and validates the passed TimeLockDelta, and sends it to the gossiper for announcing it to the network, and to the switch for updating the forwarding policy of the links. --- rpcserver.go | 47 ++++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/rpcserver.go b/rpcserver.go index ac8b93ad9..0f6495b87 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -3192,13 +3192,13 @@ func (r *rpcServer) FeeReport(ctx context.Context, // 0.000001, or 0.0001%. const minFeeRate = 1e-6 -// UpdateFees allows the caller to update the fee schedule for all channels -// globally, or a particular channel. -func (r *rpcServer) UpdateFees(ctx context.Context, - req *lnrpc.FeeUpdateRequest) (*lnrpc.FeeUpdateResponse, error) { +// UpdateChannelPolicy allows the caller to update the channel forwarding policy +// for all channels globally, or a particular channel. +func (r *rpcServer) UpdateChannelPolicy(ctx context.Context, + req *lnrpc.PolicyUpdateRequest) (*lnrpc.PolicyUpdateResponse, error) { if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "udpatefees", + if err := macaroons.ValidateMacaroon(ctx, "updatechannelpolicy", r.authSvc); err != nil { return nil, err } @@ -3208,11 +3208,11 @@ func (r *rpcServer) UpdateFees(ctx context.Context, switch scope := req.Scope.(type) { // If the request is targeting all active channels, then we don't need // target any channels by their channel point. - case *lnrpc.FeeUpdateRequest_Global: + case *lnrpc.PolicyUpdateRequest_Global: // Otherwise, we're targeting an individual channel by its channel // point. - case *lnrpc.FeeUpdateRequest_ChanPoint: + case *lnrpc.PolicyUpdateRequest_ChanPoint: txid, err := chainhash.NewHash(scope.ChanPoint.FundingTxid) if err != nil { return nil, err @@ -3226,12 +3226,19 @@ func (r *rpcServer) UpdateFees(ctx context.Context, } // As a sanity check, we'll ensure that the passed fee rate is below - // 1e-6, or the lowest allowed fee rate. + // 1e-6, or the lowest allowed fee rate, and that the passed timelock + // is large enough. if req.FeeRate < minFeeRate { return nil, fmt.Errorf("fee rate of %v is too small, min fee "+ "rate is %v", req.FeeRate, minFeeRate) } + if req.TimeLockDelta < minTimeLockDelta { + return nil, fmt.Errorf("time lock delta of %v is too small, "+ + "minimum supported is %v", req.TimeLockDelta, + minTimeLockDelta) + } + // We'll also need to convert the floating point fee rate we accept // over RPC to the fixed point rate that we use within the protocol. We // do this by multiplying the passed fee rate by the fee base. This @@ -3244,16 +3251,21 @@ func (r *rpcServer) UpdateFees(ctx context.Context, FeeRate: feeRateFixed, } - rpcsLog.Tracef("[updatefees] updating fee schedule base_fee=%v, "+ - "rate_float=%v, rate_fixed=%v, targets=%v", - req.BaseFeeMsat, req.FeeRate, feeRateFixed, + chanPolicy := routing.ChannelPolicy{ + FeeSchema: feeSchema, + TimeLockDelta: req.TimeLockDelta, + } + + rpcsLog.Tracef("[updatechanpolicy] updating channel policy base_fee=%v, "+ + "rate_float=%v, rate_fixed=%v, time_lock_delta: %v, targets=%v", + req.BaseFeeMsat, req.FeeRate, feeRateFixed, req.TimeLockDelta, spew.Sdump(targetChans)) // With the scope resolved, we'll now send this to the - // AuthenticatedGossiper so it can propagate the new fee schema for out + // AuthenticatedGossiper so it can propagate the new policy for our // target channel(s). - err := r.server.authGossiper.PropagateFeeUpdate( - feeSchema, targetChans..., + err := r.server.authGossiper.PropagateChanPolicyUpdate( + chanPolicy, targetChans..., ) if err != nil { return nil, err @@ -3265,8 +3277,9 @@ func (r *rpcServer) UpdateFees(ctx context.Context, // We create a partially policy as the logic won't overwrite a valid // sub-policy with a "nil" one. p := htlcswitch.ForwardingPolicy{ - BaseFee: baseFeeMsat, - FeeRate: lnwire.MilliSatoshi(feeRateFixed), + BaseFee: baseFeeMsat, + FeeRate: lnwire.MilliSatoshi(feeRateFixed), + TimeLockDelta: req.TimeLockDelta, } err = r.server.htlcSwitch.UpdateForwardingPolicies(p, targetChans...) if err != nil { @@ -3276,5 +3289,5 @@ func (r *rpcServer) UpdateFees(ctx context.Context, rpcsLog.Warnf("Unable to update link fees: %v", err) } - return &lnrpc.FeeUpdateResponse{}, nil + return &lnrpc.PolicyUpdateResponse{}, nil } From e27f524309145615a9f94ee3af17ab33e939cd06 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Sat, 16 Dec 2017 23:58:08 +0100 Subject: [PATCH 07/25] lnrpc: add min_htlc_msat to OpenChanneRequest --- lnrpc/rpc.pb.go | 621 +++++++++++++++++++++-------------------- lnrpc/rpc.proto | 3 + lnrpc/rpc.swagger.json | 5 + 3 files changed, 323 insertions(+), 306 deletions(-) diff --git a/lnrpc/rpc.pb.go b/lnrpc/rpc.pb.go index 442ad099e..6b22e50ac 100644 --- a/lnrpc/rpc.pb.go +++ b/lnrpc/rpc.pb.go @@ -1555,6 +1555,8 @@ type OpenChannelRequest struct { SatPerByte int64 `protobuf:"varint,7,opt,name=sat_per_byte,json=satPerByte" json:"sat_per_byte,omitempty"` // / Whether this channel should be private, not announced to the greater network. Private bool `protobuf:"varint,8,opt,name=private" json:"private,omitempty"` + // / The minimum value in millisatoshi we will require for incoming HTLCs on the channel. + MinHtlcMsat int64 `protobuf:"varint,9,opt,name=min_htlc_msat" json:"min_htlc_msat,omitempty"` } func (m *OpenChannelRequest) Reset() { *m = OpenChannelRequest{} } @@ -1618,6 +1620,13 @@ func (m *OpenChannelRequest) GetPrivate() bool { return false } +func (m *OpenChannelRequest) GetMinHtlcMsat() int64 { + if m != nil { + return m.MinHtlcMsat + } + return 0 +} + type OpenStatusUpdate struct { // Types that are valid to be assigned to Update: // *OpenStatusUpdate_ChanPending @@ -5617,310 +5626,310 @@ var _Lightning_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("rpc.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 4867 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x7b, 0xcd, 0x8f, 0x1c, 0x49, - 0x56, 0xb8, 0xb3, 0xba, 0xfa, 0xa3, 0x5e, 0x55, 0xf5, 0x47, 0x74, 0xbb, 0xbb, 0x5c, 0xf6, 0x78, - 0xed, 0xd8, 0xd1, 0x4c, 0xff, 0xfc, 0x1b, 0xdc, 0x76, 0x2f, 0x3b, 0xcc, 0x8e, 0x81, 0x91, 0xbf, - 0x7b, 0xd8, 0x1e, 0x4f, 0x6f, 0xb6, 0x67, 0x06, 0x76, 0x85, 0x8a, 0xec, 0xaa, 0xe8, 0xea, 0x5c, - 0x67, 0x65, 0xe6, 0x64, 0x46, 0x75, 0xbb, 0xd6, 0x58, 0x82, 0x05, 0x21, 0x21, 0x81, 0xf6, 0x00, - 0x02, 0xed, 0x61, 0xb9, 0x70, 0x81, 0x03, 0x7f, 0x01, 0x12, 0x7f, 0xc0, 0x4a, 0x08, 0xa4, 0x3d, - 0x21, 0xb8, 0xc1, 0x09, 0xce, 0x1c, 0xb8, 0xa1, 0x17, 0x5f, 0x19, 0x91, 0x99, 0x6d, 0x7b, 0xd9, - 0x85, 0x5b, 0xc5, 0x8b, 0x97, 0x2f, 0x22, 0x5e, 0xbc, 0x78, 0xdf, 0x05, 0xad, 0x2c, 0x1d, 0xde, - 0x4c, 0xb3, 0x84, 0x27, 0x64, 0x3e, 0x8a, 0xb3, 0x74, 0xd8, 0xbf, 0x32, 0x4e, 0x92, 0x71, 0xc4, - 0x76, 0x82, 0x34, 0xdc, 0x09, 0xe2, 0x38, 0xe1, 0x01, 0x0f, 0x93, 0x38, 0x97, 0x48, 0xf4, 0x36, - 0xac, 0xdf, 0xcf, 0x58, 0xc0, 0xd9, 0x17, 0x41, 0x14, 0x31, 0xee, 0xb3, 0x2f, 0xa7, 0x2c, 0xe7, - 0xa4, 0x0f, 0x4b, 0x69, 0x90, 0xe7, 0x67, 0x49, 0x36, 0xea, 0x79, 0xd7, 0xbc, 0xed, 0x8e, 0x6f, - 0xc6, 0x74, 0x13, 0x36, 0xdc, 0x4f, 0xf2, 0x34, 0x89, 0x73, 0x86, 0xa4, 0x3e, 0x8b, 0xa3, 0x64, - 0xf8, 0xec, 0xa7, 0x22, 0xe5, 0x7e, 0xa2, 0x48, 0xfd, 0xb0, 0x01, 0xed, 0xa7, 0x59, 0x10, 0xe7, - 0xc1, 0x10, 0x37, 0x4b, 0x7a, 0xb0, 0xc8, 0x9f, 0x0f, 0x4e, 0x82, 0xfc, 0x44, 0x90, 0x68, 0xf9, - 0x7a, 0x48, 0x36, 0x61, 0x21, 0x98, 0x24, 0xd3, 0x98, 0xf7, 0x1a, 0xd7, 0xbc, 0xed, 0x39, 0x5f, - 0x8d, 0xc8, 0x7b, 0xb0, 0x16, 0x4f, 0x27, 0x83, 0x61, 0x12, 0x1f, 0x87, 0xd9, 0x44, 0x1e, 0xb9, - 0x37, 0x77, 0xcd, 0xdb, 0x9e, 0xf7, 0xab, 0x13, 0xe4, 0x2a, 0xc0, 0x11, 0x6e, 0x43, 0x2e, 0xd1, - 0x14, 0x4b, 0x58, 0x10, 0x42, 0xa1, 0xa3, 0x46, 0x2c, 0x1c, 0x9f, 0xf0, 0xde, 0xbc, 0x20, 0xe4, - 0xc0, 0x90, 0x06, 0x0f, 0x27, 0x6c, 0x90, 0xf3, 0x60, 0x92, 0xf6, 0x16, 0xc4, 0x6e, 0x2c, 0x88, - 0x98, 0x4f, 0x78, 0x10, 0x0d, 0x8e, 0x19, 0xcb, 0x7b, 0x8b, 0x6a, 0xde, 0x40, 0xc8, 0x3b, 0xb0, - 0x3c, 0x62, 0x39, 0x1f, 0x04, 0xa3, 0x51, 0xc6, 0xf2, 0x9c, 0xe5, 0xbd, 0xa5, 0x6b, 0x73, 0xdb, - 0x2d, 0xbf, 0x04, 0xa5, 0x3d, 0xd8, 0x7c, 0xcc, 0xb8, 0xc5, 0x9d, 0x5c, 0x71, 0x9a, 0xee, 0x03, - 0xb1, 0xc0, 0x0f, 0x18, 0x0f, 0xc2, 0x28, 0x27, 0xef, 0x43, 0x87, 0x5b, 0xc8, 0x3d, 0xef, 0xda, - 0xdc, 0x76, 0x7b, 0x97, 0xdc, 0x14, 0xd2, 0x71, 0xd3, 0xfa, 0xc0, 0x77, 0xf0, 0xe8, 0x3f, 0x7a, - 0xd0, 0x3e, 0x64, 0xf1, 0x48, 0xdf, 0x23, 0x81, 0x26, 0xee, 0x44, 0xdd, 0xa1, 0xf8, 0x4d, 0xbe, - 0x02, 0x6d, 0xb1, 0xbb, 0x9c, 0x67, 0x61, 0x3c, 0x16, 0x57, 0xd0, 0xf2, 0x01, 0x41, 0x87, 0x02, - 0x42, 0x56, 0x61, 0x2e, 0x98, 0x70, 0xc1, 0xf8, 0x39, 0x1f, 0x7f, 0x92, 0xeb, 0xd0, 0x49, 0x83, - 0xd9, 0x84, 0xc5, 0xbc, 0x60, 0x76, 0xc7, 0x6f, 0x2b, 0xd8, 0x1e, 0x72, 0xfb, 0x26, 0xac, 0xdb, - 0x28, 0x9a, 0xfa, 0xbc, 0xa0, 0xbe, 0x66, 0x61, 0xaa, 0x45, 0xde, 0x85, 0x15, 0x8d, 0x9f, 0xc9, - 0xcd, 0x0a, 0xf6, 0xb7, 0xfc, 0x65, 0x05, 0xd6, 0x0c, 0xfa, 0x53, 0x0f, 0x3a, 0xf2, 0x48, 0x52, - 0xce, 0xc8, 0xdb, 0xd0, 0xd5, 0x5f, 0xb2, 0x2c, 0x4b, 0x32, 0x25, 0x5d, 0x2e, 0x90, 0xdc, 0x80, - 0x55, 0x0d, 0x48, 0x33, 0x16, 0x4e, 0x82, 0x31, 0x13, 0x47, 0xed, 0xf8, 0x15, 0x38, 0xd9, 0x2d, - 0x28, 0x66, 0xc9, 0x94, 0x33, 0x71, 0xf4, 0xf6, 0x6e, 0x47, 0xb1, 0xdb, 0x47, 0x98, 0xef, 0xa2, - 0xd0, 0xef, 0x7b, 0xd0, 0xb9, 0x7f, 0x12, 0xc4, 0x31, 0x8b, 0x0e, 0x92, 0x30, 0xe6, 0x28, 0x6e, - 0xc7, 0xd3, 0x78, 0x14, 0xc6, 0xe3, 0x01, 0x7f, 0x1e, 0xea, 0x67, 0xe3, 0xc0, 0x70, 0x53, 0xf6, - 0x18, 0x99, 0xa4, 0xf8, 0x5f, 0x81, 0x23, 0xbd, 0x64, 0xca, 0xd3, 0x29, 0x1f, 0x84, 0xf1, 0x88, - 0x3d, 0x17, 0x7b, 0xea, 0xfa, 0x0e, 0x8c, 0xfe, 0x2a, 0xac, 0xee, 0xa3, 0x1c, 0xc7, 0x61, 0x3c, - 0xbe, 0x2b, 0x85, 0x0d, 0x1f, 0x57, 0x3a, 0x3d, 0x7a, 0xc6, 0x66, 0x8a, 0x2f, 0x6a, 0x84, 0xa2, - 0x70, 0x92, 0xe4, 0x5c, 0xad, 0x27, 0x7e, 0xd3, 0x7f, 0xf5, 0x60, 0x05, 0x79, 0xfb, 0x49, 0x10, - 0xcf, 0xb4, 0xc8, 0xec, 0x43, 0x07, 0x49, 0x3d, 0x4d, 0xee, 0xca, 0x27, 0x2a, 0x45, 0x6f, 0x5b, - 0xf1, 0xa2, 0x84, 0x7d, 0xd3, 0x46, 0x7d, 0x18, 0xf3, 0x6c, 0xe6, 0x3b, 0x5f, 0xa3, 0xb0, 0xf1, - 0x20, 0x1b, 0x33, 0x2e, 0x1e, 0xaf, 0x7a, 0xcc, 0x20, 0x41, 0xf7, 0x93, 0xf8, 0x98, 0x5c, 0x83, - 0x4e, 0x1e, 0xf0, 0x41, 0xca, 0xb2, 0xc1, 0xd1, 0x8c, 0x33, 0x21, 0x30, 0x73, 0x3e, 0xe4, 0x01, - 0x3f, 0x60, 0xd9, 0xbd, 0x19, 0x67, 0xfd, 0x8f, 0x60, 0xad, 0xb2, 0x0a, 0xca, 0x68, 0x71, 0x44, - 0xfc, 0x49, 0x36, 0x60, 0xfe, 0x34, 0x88, 0xa6, 0x4c, 0xe9, 0x14, 0x39, 0xf8, 0xb0, 0xf1, 0x81, - 0x47, 0xdf, 0x81, 0xd5, 0x62, 0xdb, 0x4a, 0x88, 0x08, 0x34, 0xcd, 0x2d, 0xb5, 0x7c, 0xf1, 0x9b, - 0xfe, 0xae, 0x27, 0x11, 0xef, 0x27, 0xa1, 0x79, 0x9f, 0x88, 0x88, 0xcf, 0x58, 0x23, 0xe2, 0xef, - 0x73, 0xf5, 0xd7, 0xcf, 0x7e, 0x58, 0xfa, 0x2e, 0xac, 0x59, 0x5b, 0x78, 0xc5, 0x66, 0xff, 0xc2, - 0x83, 0xb5, 0x27, 0xec, 0x4c, 0xdd, 0xba, 0xde, 0xed, 0x07, 0xd0, 0xe4, 0xb3, 0x94, 0x09, 0xcc, - 0xe5, 0xdd, 0xb7, 0xd5, 0xa5, 0x55, 0xf0, 0x6e, 0xaa, 0xe1, 0xd3, 0x59, 0xca, 0x7c, 0xf1, 0x05, - 0xfd, 0x14, 0xda, 0x16, 0x90, 0x6c, 0xc1, 0xfa, 0x17, 0x1f, 0x3f, 0x7d, 0xf2, 0xf0, 0xf0, 0x70, - 0x70, 0xf0, 0xd9, 0xbd, 0x6f, 0x3e, 0xfc, 0x8d, 0xc1, 0xde, 0xdd, 0xc3, 0xbd, 0xd5, 0x0b, 0x64, - 0x13, 0xc8, 0x93, 0x87, 0x87, 0x4f, 0x1f, 0x3e, 0x70, 0xe0, 0x1e, 0x59, 0x81, 0xb6, 0x0d, 0x68, - 0xd0, 0x3e, 0xf4, 0x9e, 0xb0, 0xb3, 0x2f, 0x42, 0x1e, 0xb3, 0x3c, 0x77, 0x97, 0xa7, 0x37, 0x81, - 0xd8, 0x7b, 0x52, 0xc7, 0xec, 0xc1, 0xa2, 0xd2, 0x98, 0xda, 0x60, 0xa8, 0x21, 0x7d, 0x07, 0xc8, - 0x61, 0x38, 0x8e, 0x3f, 0x61, 0x79, 0x1e, 0x8c, 0x99, 0x3e, 0xec, 0x2a, 0xcc, 0x4d, 0xf2, 0xb1, - 0x7a, 0x68, 0xf8, 0x93, 0x7e, 0x0d, 0xd6, 0x1d, 0x3c, 0x45, 0xf8, 0x0a, 0xb4, 0xf2, 0x70, 0x1c, - 0x07, 0x7c, 0x9a, 0x31, 0x45, 0xba, 0x00, 0xd0, 0x47, 0xb0, 0xf1, 0x39, 0xcb, 0xc2, 0xe3, 0xd9, - 0xeb, 0xc8, 0xbb, 0x74, 0x1a, 0x65, 0x3a, 0x0f, 0xe1, 0x62, 0x89, 0x8e, 0x5a, 0x5e, 0x4a, 0xa6, - 0xba, 0xbf, 0x25, 0x5f, 0x0e, 0xac, 0x77, 0xda, 0xb0, 0xdf, 0x29, 0xfd, 0x0c, 0xc8, 0xfd, 0x24, - 0x8e, 0xd9, 0x90, 0x1f, 0x30, 0x96, 0xe9, 0xcd, 0xfc, 0x7f, 0x4b, 0x0c, 0xdb, 0xbb, 0x5b, 0xea, - 0x62, 0xcb, 0x8f, 0x5f, 0xc9, 0x27, 0x81, 0x66, 0xca, 0xb2, 0x89, 0x20, 0xbc, 0xe4, 0x8b, 0xdf, - 0x74, 0x07, 0xd6, 0x1d, 0xb2, 0x05, 0xcf, 0x53, 0xc6, 0xb2, 0x81, 0xda, 0xdd, 0xbc, 0xaf, 0x87, - 0xf4, 0x36, 0x5c, 0x7c, 0x10, 0xe6, 0xc3, 0xea, 0x56, 0xf0, 0x93, 0xe9, 0xd1, 0xa0, 0x78, 0x7e, - 0x7a, 0x88, 0x56, 0xae, 0xfc, 0x89, 0xf2, 0x0d, 0xfe, 0xc0, 0x83, 0xe6, 0xde, 0xd3, 0xfd, 0xfb, - 0xe8, 0x58, 0x84, 0xf1, 0x30, 0x99, 0xa0, 0x6d, 0x90, 0xec, 0x30, 0xe3, 0x73, 0x9f, 0xd5, 0x15, - 0x68, 0x09, 0x93, 0x82, 0x86, 0x5b, 0x3c, 0xaa, 0x8e, 0x5f, 0x00, 0xd0, 0x69, 0x60, 0xcf, 0xd3, - 0x30, 0x13, 0x5e, 0x81, 0xb6, 0xf5, 0x4d, 0xa1, 0x2c, 0xab, 0x13, 0xf4, 0xdf, 0x9b, 0xd0, 0xbd, - 0x3b, 0xe4, 0xe1, 0x29, 0x53, 0xca, 0x5b, 0xac, 0x2a, 0x00, 0x6a, 0x3f, 0x6a, 0x84, 0x66, 0x26, - 0x63, 0x93, 0x84, 0xb3, 0x81, 0x73, 0x4d, 0x2e, 0x10, 0xb1, 0x86, 0x92, 0xd0, 0x20, 0x45, 0x33, - 0x20, 0xf6, 0xd7, 0xf2, 0x5d, 0x20, 0xb2, 0x0c, 0x01, 0xc8, 0x65, 0xdc, 0x59, 0xd3, 0xd7, 0x43, - 0xe4, 0xc7, 0x30, 0x48, 0x83, 0x61, 0xc8, 0x67, 0x4a, 0x1b, 0x98, 0x31, 0xd2, 0x8e, 0x92, 0x61, - 0x10, 0x0d, 0x8e, 0x82, 0x28, 0x88, 0x87, 0x4c, 0xf9, 0x27, 0x2e, 0x10, 0x5d, 0x10, 0xb5, 0x25, - 0x8d, 0x26, 0xdd, 0x94, 0x12, 0x14, 0x5d, 0x99, 0x61, 0x32, 0x99, 0x84, 0x1c, 0x3d, 0x97, 0xde, - 0x92, 0xd4, 0x3c, 0x05, 0x44, 0x9c, 0x44, 0x8e, 0xce, 0x24, 0x0f, 0x5b, 0x72, 0x35, 0x07, 0x88, - 0x54, 0x8e, 0x19, 0x13, 0x1a, 0xec, 0xd9, 0x59, 0x0f, 0x24, 0x95, 0x02, 0x82, 0xb7, 0x31, 0x8d, - 0x73, 0xc6, 0x79, 0xc4, 0x46, 0x66, 0x43, 0x6d, 0x81, 0x56, 0x9d, 0x20, 0xb7, 0x60, 0x5d, 0x3a, - 0x53, 0x79, 0xc0, 0x93, 0xfc, 0x24, 0xcc, 0x07, 0x39, 0x8b, 0x79, 0xaf, 0x23, 0xf0, 0xeb, 0xa6, - 0xc8, 0x07, 0xb0, 0x55, 0x02, 0x67, 0x6c, 0xc8, 0xc2, 0x53, 0x36, 0xea, 0x75, 0xc5, 0x57, 0xe7, - 0x4d, 0x93, 0x6b, 0xd0, 0x46, 0x1f, 0x72, 0x9a, 0x8e, 0x02, 0xce, 0xf2, 0xde, 0xb2, 0xb8, 0x07, - 0x1b, 0x44, 0x6e, 0x43, 0x37, 0x65, 0xd2, 0x0a, 0x9f, 0xf0, 0x68, 0x98, 0xf7, 0x56, 0x84, 0xe9, - 0x6b, 0xab, 0xc7, 0x86, 0xf2, 0xeb, 0xbb, 0x18, 0x28, 0x9a, 0xc3, 0xfc, 0x74, 0x30, 0x62, 0x51, - 0x30, 0xeb, 0xad, 0x0a, 0xa1, 0x2b, 0x00, 0xf4, 0x22, 0xac, 0xef, 0x87, 0x39, 0x57, 0x92, 0x66, - 0xb4, 0xdf, 0x1e, 0x6c, 0xb8, 0x60, 0xf5, 0x16, 0x6f, 0xc1, 0x92, 0x12, 0x9b, 0xbc, 0xd7, 0x16, - 0x4b, 0x6f, 0xa8, 0xa5, 0x1d, 0x89, 0xf5, 0x0d, 0x16, 0xfd, 0xfd, 0x06, 0x34, 0xf1, 0x9d, 0x9d, - 0xff, 0x26, 0xed, 0x07, 0xde, 0x70, 0x1e, 0xb8, 0xad, 0x6e, 0xe7, 0x1c, 0x75, 0x2b, 0x3c, 0xeb, - 0x19, 0x67, 0xea, 0x36, 0xa4, 0xc4, 0x5a, 0x90, 0x62, 0x3e, 0x63, 0xc3, 0x53, 0x21, 0xb6, 0x66, - 0x1e, 0x21, 0x28, 0xd4, 0x68, 0xe6, 0xc4, 0xd7, 0x52, 0x66, 0xcd, 0x58, 0xcf, 0x89, 0x2f, 0x17, - 0x8b, 0x39, 0xf1, 0x5d, 0x0f, 0x16, 0xc3, 0xf8, 0x28, 0x99, 0xc6, 0x23, 0x21, 0x9f, 0x4b, 0xbe, - 0x1e, 0x22, 0x9f, 0x53, 0xe1, 0x1d, 0x85, 0x13, 0xa6, 0x04, 0xb3, 0x00, 0x50, 0x82, 0x6e, 0x50, - 0x2e, 0x34, 0x8e, 0x61, 0xf2, 0xfb, 0xb0, 0x66, 0xc1, 0x14, 0x87, 0xaf, 0xc3, 0x3c, 0x9e, 0x5e, - 0xfb, 0xd3, 0xfa, 0x66, 0x85, 0xaa, 0x92, 0x33, 0x74, 0x15, 0x96, 0x1f, 0x33, 0xfe, 0x71, 0x7c, - 0x9c, 0x68, 0x4a, 0x7f, 0x38, 0x07, 0x2b, 0x06, 0xa4, 0x08, 0x6d, 0xc3, 0x4a, 0x38, 0x62, 0x31, - 0x0f, 0xf9, 0x6c, 0xe0, 0x78, 0x5b, 0x65, 0x30, 0x2a, 0xff, 0x20, 0x0a, 0x83, 0x5c, 0xa9, 0x0f, - 0x39, 0x20, 0xbb, 0xb0, 0x81, 0x92, 0xa7, 0x85, 0xc9, 0x5c, 0xbb, 0x74, 0xf2, 0x6a, 0xe7, 0xf0, - 0xb1, 0x20, 0x5c, 0xaa, 0xa7, 0xe2, 0x13, 0xa9, 0xea, 0xea, 0xa6, 0x90, 0x6b, 0x92, 0x12, 0x1e, - 0x79, 0x5e, 0x4a, 0xa7, 0x01, 0x54, 0xe2, 0xa3, 0x05, 0xe9, 0x60, 0x96, 0xe3, 0x23, 0x2b, 0xc6, - 0x5a, 0xaa, 0xc4, 0x58, 0xdb, 0xb0, 0x92, 0xcf, 0xe2, 0x21, 0x1b, 0x0d, 0x78, 0x82, 0xeb, 0x86, - 0xb1, 0xb8, 0x9d, 0x25, 0xbf, 0x0c, 0x16, 0xd1, 0x20, 0xcb, 0x79, 0xcc, 0xb8, 0xd0, 0x1a, 0x4b, - 0xbe, 0x1e, 0xa2, 0x02, 0x16, 0x28, 0x52, 0xe8, 0x5b, 0xbe, 0x1a, 0xa1, 0x15, 0x9b, 0x66, 0x61, - 0xde, 0xeb, 0x08, 0xa8, 0xf8, 0x4d, 0xbf, 0x27, 0x8c, 0xa3, 0x09, 0x02, 0x3f, 0x13, 0x2f, 0x97, - 0x5c, 0x86, 0x96, 0xdc, 0x53, 0x7e, 0x12, 0xe8, 0x70, 0x55, 0x00, 0x0e, 0x4f, 0x02, 0x8c, 0x5d, - 0x9c, 0x63, 0xca, 0x57, 0xd0, 0x16, 0xb0, 0x3d, 0x79, 0xca, 0xb7, 0x61, 0x59, 0x87, 0x97, 0xf9, - 0x20, 0x62, 0xc7, 0x5c, 0x3b, 0xdb, 0xf1, 0x74, 0x82, 0xcb, 0xe5, 0xfb, 0xec, 0x98, 0xd3, 0x27, - 0xb0, 0xa6, 0x5e, 0xe0, 0xa7, 0x29, 0xd3, 0x4b, 0x7f, 0xa3, 0xac, 0xff, 0xa5, 0x81, 0x5e, 0x57, - 0x92, 0x65, 0x47, 0x08, 0x25, 0xa3, 0x40, 0x7d, 0x20, 0x6a, 0xfa, 0x7e, 0x94, 0xe4, 0x4c, 0x11, - 0xa4, 0xd0, 0x19, 0x46, 0x49, 0x5e, 0x0e, 0x23, 0x6c, 0x18, 0xf2, 0x32, 0x9f, 0x0e, 0x87, 0xf8, - 0x72, 0xa5, 0x89, 0xd7, 0x43, 0xfa, 0x57, 0x1e, 0xac, 0x0b, 0x6a, 0x5a, 0x57, 0x18, 0xbf, 0xf0, - 0xcd, 0xb7, 0xd9, 0x19, 0xda, 0x61, 0xcd, 0x06, 0xcc, 0x1f, 0x27, 0xd9, 0x90, 0xa9, 0x95, 0xe4, - 0xe0, 0xe7, 0xe1, 0xe9, 0xfe, 0x93, 0x07, 0x6b, 0x62, 0xab, 0x87, 0x3c, 0xe0, 0xd3, 0x5c, 0x1d, - 0xff, 0x97, 0xa1, 0x8b, 0x47, 0x65, 0x5a, 0xfc, 0xd5, 0x46, 0x37, 0xcc, 0x4b, 0x15, 0x50, 0x89, - 0xbc, 0x77, 0xc1, 0x77, 0x91, 0xc9, 0x47, 0xd0, 0xb1, 0x73, 0x04, 0x62, 0xcf, 0xed, 0xdd, 0x4b, - 0xfa, 0x94, 0x15, 0xc9, 0xd9, 0xbb, 0xe0, 0x3b, 0x1f, 0x90, 0x3b, 0x00, 0xc2, 0x32, 0x0b, 0xb2, - 0x2a, 0x0c, 0xbc, 0xe4, 0x32, 0xc9, 0xba, 0xac, 0xbd, 0x0b, 0xbe, 0x85, 0x7e, 0x6f, 0x09, 0x16, - 0xa4, 0x29, 0xa1, 0x8f, 0xa1, 0xeb, 0xec, 0xd4, 0xf1, 0xe0, 0x3b, 0xd2, 0x83, 0xaf, 0x04, 0x78, - 0x8d, 0x9a, 0x00, 0xef, 0x6f, 0x1b, 0x40, 0x50, 0xda, 0x4a, 0xd7, 0xf9, 0x0e, 0x2c, 0x2b, 0xf6, - 0xbb, 0xce, 0x5b, 0x09, 0x2a, 0x6c, 0x5e, 0x32, 0x72, 0x3c, 0x98, 0x8e, 0x6f, 0x83, 0xc8, 0x4d, - 0x20, 0xd6, 0x50, 0x47, 0xed, 0xd2, 0x1e, 0xd4, 0xcc, 0xa0, 0xe2, 0x92, 0xee, 0x87, 0x8e, 0x57, - 0x95, 0xc7, 0xd6, 0x14, 0xf7, 0x5b, 0x3b, 0x27, 0x92, 0x49, 0xd3, 0xfc, 0x04, 0x6d, 0xb2, 0xf6, - 0x71, 0xf4, 0xb8, 0x2c, 0x48, 0x0b, 0xaf, 0x15, 0xa4, 0xc5, 0xb2, 0x20, 0x09, 0x0b, 0x97, 0x85, - 0xa7, 0x01, 0x67, 0xda, 0x6a, 0xa8, 0x21, 0xfd, 0x89, 0x07, 0xab, 0xc8, 0x3d, 0x47, 0xc2, 0x3e, - 0x04, 0x21, 0xe0, 0x6f, 0x28, 0x60, 0x0e, 0xee, 0xcf, 0x2e, 0x5f, 0x1f, 0x40, 0x4b, 0x10, 0x4c, - 0x52, 0x16, 0x2b, 0xf1, 0xea, 0xb9, 0xe2, 0x55, 0xe8, 0x96, 0xbd, 0x0b, 0x7e, 0x81, 0x6c, 0x09, - 0xd7, 0x3f, 0x78, 0xd0, 0x56, 0xdb, 0xfc, 0x1f, 0xbb, 0xd4, 0x7d, 0x58, 0x42, 0x39, 0xb3, 0x3c, - 0x56, 0x33, 0x46, 0x9d, 0x3e, 0xc1, 0x88, 0x06, 0x8d, 0x98, 0xe3, 0x4e, 0x97, 0xc1, 0x68, 0x91, - 0x84, 0x1a, 0xcd, 0x07, 0x3c, 0x8c, 0x06, 0x7a, 0x56, 0x25, 0xda, 0xea, 0xa6, 0x50, 0x9b, 0xe4, - 0x3c, 0x18, 0x33, 0x65, 0x6c, 0xe4, 0x00, 0xe3, 0x06, 0x75, 0xa0, 0xb2, 0xab, 0xf4, 0x63, 0x80, - 0xad, 0xca, 0x94, 0x71, 0x97, 0x94, 0x87, 0x18, 0x85, 0x93, 0xa3, 0xc4, 0x38, 0x9b, 0x9e, 0xed, - 0x3c, 0x3a, 0x53, 0x64, 0x0c, 0x17, 0xb5, 0x55, 0x45, 0x9e, 0x16, 0x36, 0xb4, 0x21, 0xdc, 0x81, - 0xdb, 0xae, 0x0c, 0x94, 0x17, 0xd4, 0x70, 0xfb, 0x3d, 0xd6, 0xd3, 0x23, 0x27, 0xd0, 0x33, 0xe6, - 0x5b, 0x29, 0x6e, 0xcb, 0xc4, 0xe3, 0x5a, 0xef, 0xbd, 0x66, 0x2d, 0xa1, 0x65, 0x46, 0x7a, 0x99, - 0x73, 0xa9, 0x91, 0x19, 0x5c, 0xd5, 0x73, 0x42, 0x33, 0x57, 0xd7, 0x6b, 0xbe, 0xd1, 0xd9, 0x1e, - 0xe1, 0xc7, 0xee, 0xa2, 0xaf, 0x21, 0xdc, 0xff, 0xb1, 0x07, 0xcb, 0x2e, 0x39, 0x14, 0x1d, 0x15, - 0x75, 0x68, 0xd5, 0xa1, 0xdd, 0xa2, 0x12, 0xb8, 0x1a, 0x37, 0x35, 0xea, 0xe2, 0x26, 0x3b, 0x3a, - 0x9a, 0x7b, 0x5d, 0x74, 0xd4, 0x7c, 0xb3, 0xe8, 0x68, 0xbe, 0x2e, 0x3a, 0xea, 0xff, 0xa7, 0x07, - 0xa4, 0x7a, 0xbf, 0xe4, 0xb1, 0x0c, 0xdc, 0x62, 0x16, 0x29, 0x3d, 0xf1, 0x0b, 0x6f, 0x26, 0x23, - 0x9a, 0x87, 0xfa, 0x6b, 0x14, 0x56, 0x5b, 0x11, 0xd8, 0xce, 0x48, 0xd7, 0xaf, 0x9b, 0x2a, 0xc5, - 0x6b, 0xcd, 0xd7, 0xc7, 0x6b, 0xf3, 0xaf, 0x8f, 0xd7, 0x16, 0xca, 0xf1, 0x5a, 0xff, 0xb7, 0xa1, - 0xeb, 0xdc, 0xfa, 0xcf, 0xef, 0xc4, 0x65, 0x47, 0x46, 0x5e, 0xb0, 0x03, 0xeb, 0xff, 0x47, 0x03, - 0x48, 0x55, 0xf2, 0xfe, 0x4f, 0xf7, 0x20, 0xe4, 0xc8, 0x51, 0x20, 0x73, 0x4a, 0x8e, 0x1c, 0xd5, - 0xf1, 0xbf, 0xa9, 0x14, 0xdf, 0x83, 0xb5, 0x8c, 0x0d, 0x93, 0x53, 0x96, 0x59, 0x31, 0xb3, 0xbc, - 0xaa, 0xea, 0x04, 0xba, 0x72, 0x6e, 0x94, 0xba, 0xe4, 0xd4, 0x06, 0x2c, 0xcb, 0x50, 0x0a, 0x56, - 0xe9, 0x37, 0x60, 0x43, 0x96, 0x6c, 0xee, 0x49, 0x52, 0xda, 0x9b, 0xb8, 0x0e, 0x9d, 0x33, 0x99, - 0xa6, 0x1b, 0x24, 0x71, 0x34, 0x53, 0x46, 0xa4, 0xad, 0x60, 0x9f, 0xc6, 0xd1, 0x8c, 0xfe, 0xc8, - 0x83, 0x8b, 0xa5, 0x6f, 0x8b, 0x6c, 0xbc, 0x54, 0xb5, 0xae, 0xfe, 0x75, 0x81, 0x78, 0x44, 0x25, - 0xe3, 0xd6, 0x11, 0xa5, 0x49, 0xaa, 0x4e, 0x20, 0x0b, 0xa7, 0x71, 0x15, 0x5f, 0x5e, 0x4c, 0xdd, - 0x14, 0xdd, 0x82, 0x8b, 0xea, 0xf2, 0xdd, 0xb3, 0xd1, 0x5d, 0xd8, 0x2c, 0x4f, 0x14, 0x99, 0x2f, - 0x77, 0xcb, 0x7a, 0x48, 0x3f, 0x02, 0xf2, 0xad, 0x29, 0xcb, 0x66, 0x22, 0xef, 0x6f, 0x52, 0xab, - 0x5b, 0xe5, 0x10, 0x7b, 0x21, 0x9d, 0x1e, 0x7d, 0x93, 0xcd, 0x74, 0xb9, 0xa4, 0x61, 0xca, 0x25, - 0xf4, 0x0e, 0xac, 0x3b, 0x04, 0x0c, 0xab, 0x16, 0x44, 0xed, 0x40, 0x87, 0x9f, 0x6e, 0x7d, 0x41, - 0xcd, 0xd1, 0x3f, 0xf7, 0x60, 0x6e, 0x2f, 0x49, 0xed, 0x9c, 0x91, 0xe7, 0xe6, 0x8c, 0x94, 0xee, - 0x1c, 0x18, 0xd5, 0xd8, 0x50, 0x2f, 0xdf, 0x06, 0xa2, 0xe6, 0x0b, 0x26, 0x1c, 0x03, 0xb0, 0xe3, - 0x24, 0x3b, 0x0b, 0xb2, 0x91, 0xe2, 0x5f, 0x09, 0x8a, 0xdb, 0x2f, 0x14, 0x0c, 0xfe, 0x44, 0xa7, - 0x41, 0x24, 0xce, 0x66, 0x2a, 0x66, 0x54, 0x23, 0xfa, 0x03, 0x0f, 0xe6, 0xc5, 0x5e, 0xf1, 0x35, - 0xc8, 0xfb, 0x15, 0xa5, 0x32, 0x91, 0x97, 0xf3, 0xe4, 0x6b, 0x28, 0x81, 0x4b, 0x05, 0xb4, 0x46, - 0xa5, 0x80, 0x76, 0x05, 0x5a, 0x72, 0x54, 0x54, 0x9c, 0x0a, 0x00, 0xb9, 0x0a, 0xcd, 0x93, 0x24, - 0xd5, 0x36, 0x0c, 0x74, 0x22, 0x26, 0x49, 0x7d, 0x01, 0xa7, 0x37, 0x60, 0xe5, 0x49, 0x32, 0x62, - 0x56, 0xb4, 0x7e, 0xee, 0x35, 0xd1, 0xdf, 0xf1, 0x60, 0x49, 0x23, 0x93, 0x6d, 0x68, 0xa2, 0x29, - 0x2a, 0x39, 0x7f, 0x26, 0x9d, 0x8a, 0x78, 0xbe, 0xc0, 0x40, 0x15, 0x22, 0x62, 0xc3, 0xc2, 0x55, - 0xd0, 0x91, 0x61, 0x61, 0x84, 0xd1, 0x1d, 0x17, 0x7b, 0x2e, 0x19, 0xab, 0x12, 0x94, 0xfe, 0xb5, - 0x07, 0x5d, 0x67, 0x0d, 0x74, 0xd0, 0xa3, 0x20, 0xe7, 0x2a, 0x05, 0xa5, 0x98, 0x68, 0x83, 0xec, - 0xcc, 0x4e, 0xc3, 0xcd, 0xec, 0x98, 0xcc, 0xc2, 0x9c, 0x9d, 0x59, 0xb8, 0x05, 0xad, 0xa2, 0x18, - 0xd9, 0x74, 0x54, 0x03, 0xae, 0xa8, 0x13, 0xc5, 0x05, 0x12, 0xd2, 0x19, 0x26, 0x51, 0x92, 0xa9, - 0x5a, 0x9d, 0x1c, 0xd0, 0x3b, 0xd0, 0xb6, 0xf0, 0x71, 0x1b, 0x31, 0xe3, 0x67, 0x49, 0xf6, 0x4c, - 0x27, 0x98, 0xd4, 0xd0, 0x14, 0x48, 0x1a, 0x45, 0x81, 0x84, 0xfe, 0x8d, 0x07, 0x5d, 0x94, 0x94, - 0x30, 0x1e, 0x1f, 0x24, 0x51, 0x38, 0x9c, 0x09, 0x89, 0xd1, 0x42, 0x31, 0x18, 0xb1, 0x88, 0x07, - 0x46, 0x62, 0x5c, 0x30, 0xda, 0xfc, 0x49, 0x18, 0x0b, 0x95, 0xa5, 0xe4, 0xc5, 0x8c, 0x51, 0xf2, - 0xd1, 0x76, 0x1d, 0x05, 0x39, 0x1b, 0x4c, 0x30, 0x9c, 0x50, 0xba, 0xda, 0x01, 0xa2, 0xfa, 0x40, - 0x40, 0x16, 0x70, 0x36, 0x98, 0x84, 0x51, 0x14, 0x4a, 0x5c, 0x29, 0xe1, 0x75, 0x53, 0x18, 0x66, - 0xb5, 0x95, 0x9a, 0x78, 0x38, 0x1a, 0xcb, 0x5c, 0xa9, 0x72, 0x44, 0xcc, 0xf3, 0xb3, 0x20, 0x7a, - 0xde, 0x71, 0x5d, 0x2c, 0x48, 0xf9, 0x5a, 0xe7, 0xaa, 0xd7, 0x7a, 0x05, 0x5a, 0x28, 0x5e, 0xb7, - 0x85, 0x8f, 0x24, 0x6b, 0xd7, 0x05, 0x40, 0xcf, 0xee, 0x8a, 0xd9, 0xf9, 0x62, 0x56, 0x00, 0x1c, - 0xaf, 0x68, 0xa1, 0xe4, 0x15, 0x7d, 0x00, 0x1d, 0x45, 0x46, 0xf0, 0x5d, 0x84, 0x4b, 0x85, 0x80, - 0x3b, 0x77, 0xe2, 0x3b, 0x98, 0xfa, 0xcb, 0x5d, 0xfd, 0xe5, 0xd2, 0xeb, 0xbe, 0xd4, 0x98, 0xf4, - 0x22, 0xac, 0x2b, 0xe6, 0x3d, 0xce, 0x82, 0xf4, 0x44, 0xab, 0xde, 0x91, 0x29, 0x90, 0x0a, 0x30, - 0xb9, 0x01, 0xf3, 0xf8, 0x99, 0xd6, 0x7e, 0xf5, 0x8f, 0x4e, 0xa2, 0x90, 0x6d, 0x98, 0x67, 0xa3, - 0x31, 0xd3, 0x9e, 0x39, 0x71, 0x63, 0x24, 0xbc, 0x23, 0x5f, 0x22, 0xa0, 0x0a, 0x40, 0x68, 0x49, - 0x05, 0xb8, 0x9a, 0x73, 0x01, 0x87, 0x1f, 0x8f, 0xe8, 0x06, 0x90, 0x27, 0x52, 0x6a, 0xed, 0xfc, - 0xde, 0xef, 0xcd, 0x41, 0xdb, 0x02, 0xe3, 0x6b, 0x1e, 0xe3, 0x86, 0x07, 0xa3, 0x30, 0x98, 0x30, - 0xce, 0x32, 0x25, 0xa9, 0x25, 0xa8, 0x50, 0xb0, 0xa7, 0xe3, 0x41, 0x32, 0xe5, 0x83, 0x11, 0x1b, - 0x67, 0x4c, 0x1a, 0x34, 0xcf, 0x2f, 0x41, 0x11, 0x6f, 0x12, 0x3c, 0xb7, 0xf1, 0xa4, 0x3c, 0x94, - 0xa0, 0x3a, 0x5b, 0x27, 0x79, 0xd4, 0x2c, 0xb2, 0x75, 0x92, 0x23, 0x65, 0x3d, 0x34, 0x5f, 0xa3, - 0x87, 0xde, 0x87, 0x4d, 0xa9, 0x71, 0xd4, 0xdb, 0x1c, 0x94, 0xc4, 0xe4, 0x9c, 0x59, 0x72, 0x03, - 0x56, 0x71, 0xcf, 0x5a, 0xc0, 0xf3, 0xf0, 0x7b, 0x32, 0xce, 0xf6, 0xfc, 0x0a, 0x1c, 0x71, 0xf1, - 0x39, 0x3a, 0xb8, 0xb2, 0x98, 0x50, 0x81, 0x0b, 0xdc, 0xe0, 0xb9, 0x8b, 0xdb, 0x52, 0xb8, 0x25, - 0x38, 0xed, 0x42, 0xfb, 0x90, 0x27, 0xa9, 0xbe, 0x94, 0x65, 0xe8, 0xc8, 0xa1, 0x2a, 0x20, 0x5d, - 0x86, 0x4b, 0x42, 0x8a, 0x9e, 0x26, 0x69, 0x12, 0x25, 0xe3, 0xd9, 0xe1, 0xf4, 0x28, 0x1f, 0x66, - 0x61, 0x8a, 0x1e, 0x33, 0xfd, 0x7b, 0x0f, 0xd6, 0x9d, 0x59, 0x15, 0xea, 0xff, 0xa2, 0x14, 0x69, - 0x93, 0xf3, 0x97, 0x82, 0xb7, 0x66, 0xa9, 0x43, 0x89, 0x28, 0x53, 0x22, 0x9f, 0xa9, 0x32, 0xc0, - 0x5d, 0x58, 0xd1, 0x3b, 0xd3, 0x1f, 0x4a, 0x29, 0xec, 0x55, 0xa5, 0x50, 0x7d, 0xbf, 0xac, 0x3e, - 0xd0, 0x24, 0x7e, 0x45, 0xfa, 0x9d, 0x6c, 0x24, 0xce, 0xa8, 0x63, 0xbe, 0xbe, 0xfe, 0xde, 0x76, - 0x76, 0xf5, 0x0e, 0x86, 0x06, 0x98, 0xd3, 0x3f, 0xf2, 0x00, 0x8a, 0xdd, 0xa1, 0x60, 0x14, 0x2a, - 0xdd, 0x13, 0xd9, 0x50, 0x4b, 0x7d, 0x5f, 0x87, 0x8e, 0xc9, 0x39, 0x17, 0x56, 0xa2, 0xad, 0x61, - 0xe8, 0xa1, 0xbc, 0x0b, 0x2b, 0xe3, 0x28, 0x39, 0x12, 0x36, 0x57, 0xd4, 0x2a, 0x73, 0x55, 0x46, - 0x5b, 0x96, 0xe0, 0x47, 0x0a, 0x5a, 0x98, 0x94, 0xa6, 0x65, 0x52, 0xe8, 0x1f, 0x37, 0x4c, 0xe6, - 0xb3, 0x38, 0xf3, 0xb9, 0xaf, 0x8c, 0xec, 0x56, 0x94, 0xe3, 0x39, 0x89, 0x46, 0x91, 0xdd, 0x38, - 0x78, 0x6d, 0xa0, 0x77, 0x07, 0x96, 0x33, 0xa9, 0x7d, 0xb4, 0x6a, 0x6a, 0xbe, 0x42, 0x35, 0x75, - 0x33, 0xc7, 0xee, 0xfc, 0x3f, 0x58, 0x0d, 0x46, 0xa7, 0x2c, 0xe3, 0xa1, 0xf0, 0xf8, 0x85, 0xd1, - 0x97, 0x0a, 0x75, 0xc5, 0x82, 0x0b, 0x5b, 0xfc, 0x2e, 0xac, 0xa8, 0xd2, 0xa5, 0xc1, 0x54, 0x1d, - 0x29, 0x05, 0x18, 0x11, 0xe9, 0x5f, 0xea, 0x24, 0xab, 0x7b, 0x87, 0xe7, 0x73, 0xc4, 0x3e, 0x5d, - 0xa3, 0x74, 0xba, 0xaf, 0xaa, 0x84, 0xe7, 0x48, 0x87, 0x15, 0x2a, 0xf5, 0x2c, 0x81, 0x2a, 0x41, - 0xed, 0xb2, 0xb4, 0xf9, 0x26, 0x2c, 0xa5, 0x3f, 0x9a, 0x83, 0xc5, 0x8f, 0xe3, 0xd3, 0x24, 0x1c, - 0x8a, 0xf4, 0xe3, 0x84, 0x4d, 0x12, 0xdd, 0x40, 0x80, 0xbf, 0xd1, 0xa2, 0x8b, 0xda, 0x58, 0xca, - 0x55, 0x5e, 0x50, 0x0f, 0xd1, 0xba, 0x65, 0x45, 0xd3, 0x8c, 0x94, 0x14, 0x0b, 0x82, 0xfe, 0x61, - 0x66, 0xf7, 0x01, 0xa9, 0x51, 0xd1, 0x81, 0x31, 0x6f, 0x75, 0x60, 0x88, 0x64, 0xb5, 0x2c, 0xfb, - 0x09, 0x76, 0x2e, 0xf9, 0x7a, 0x28, 0xfc, 0xd8, 0x8c, 0xc9, 0xa0, 0x57, 0xd8, 0xc9, 0x45, 0xe5, - 0xc7, 0xda, 0x40, 0xb4, 0xa5, 0xf2, 0x03, 0x89, 0x23, 0x75, 0x8d, 0x0d, 0x42, 0xdf, 0xa2, 0xdc, - 0x4a, 0xd4, 0x92, 0x57, 0x5c, 0x02, 0xa3, 0x42, 0x1a, 0x31, 0xa3, 0x37, 0xe4, 0x19, 0x40, 0x36, - 0x05, 0x95, 0xe1, 0x96, 0x17, 0x2c, 0xcb, 0x97, 0x6a, 0x24, 0x7c, 0x90, 0x20, 0x8a, 0x8e, 0x82, - 0xe1, 0x33, 0xd1, 0xe0, 0x25, 0xaa, 0x95, 0x2d, 0xdf, 0x05, 0xe2, 0xae, 0x87, 0x11, 0x3f, 0x1d, - 0x28, 0x12, 0x5d, 0x59, 0x6d, 0xb4, 0x40, 0xf4, 0x73, 0x20, 0x77, 0x47, 0x23, 0x75, 0x43, 0x26, - 0x46, 0x28, 0x78, 0xeb, 0x39, 0xbc, 0xad, 0x39, 0x63, 0xa3, 0xf6, 0x8c, 0xf4, 0x21, 0xb4, 0x0f, - 0xac, 0xbe, 0x2c, 0x71, 0x99, 0xba, 0x23, 0x4b, 0x09, 0x80, 0x05, 0xb1, 0x16, 0x6c, 0xd8, 0x0b, - 0xd2, 0x5f, 0x02, 0xb2, 0x1f, 0xe6, 0xdc, 0xec, 0xcf, 0x84, 0x8a, 0x26, 0xe3, 0x65, 0x85, 0x8a, - 0x0a, 0x26, 0x42, 0xc5, 0xbb, 0xb2, 0xe8, 0x59, 0x3e, 0xd8, 0x0d, 0x58, 0x0a, 0x25, 0x48, 0xeb, - 0xe1, 0x65, 0x25, 0xc0, 0x1a, 0xd3, 0xcc, 0xa3, 0x43, 0xa1, 0x80, 0x8e, 0x9a, 0xff, 0x81, 0x07, - 0x8b, 0xea, 0x68, 0x68, 0x0e, 0x9d, 0x8e, 0x34, 0x79, 0x30, 0x07, 0x56, 0xdf, 0x11, 0x54, 0x95, - 0xba, 0xb9, 0x3a, 0xa9, 0x23, 0xd0, 0x4c, 0x03, 0x7e, 0x22, 0x3c, 0xe8, 0x96, 0x2f, 0x7e, 0xeb, - 0x48, 0x69, 0xde, 0x44, 0x4a, 0xba, 0xc0, 0xab, 0x36, 0x65, 0xb2, 0x96, 0xf7, 0x64, 0x81, 0xb7, - 0x00, 0x17, 0x3c, 0x50, 0x1b, 0x2c, 0xf3, 0x40, 0xa1, 0xfa, 0x66, 0x9e, 0xf6, 0xa1, 0xf7, 0x80, - 0x45, 0x8c, 0xb3, 0xbb, 0x51, 0x54, 0xa6, 0x7f, 0x19, 0x2e, 0xd5, 0xcc, 0x29, 0x4b, 0xf9, 0x08, - 0xd6, 0x1e, 0xb0, 0xa3, 0xe9, 0x78, 0x9f, 0x9d, 0x16, 0x05, 0x03, 0x02, 0xcd, 0xfc, 0x24, 0x39, - 0x53, 0xf7, 0x25, 0x7e, 0x93, 0xb7, 0x00, 0x22, 0xc4, 0x19, 0xe4, 0x29, 0x1b, 0xea, 0x76, 0x16, - 0x01, 0x39, 0x4c, 0xd9, 0x90, 0xbe, 0x0f, 0xc4, 0xa6, 0xa3, 0x8e, 0x80, 0xaf, 0x71, 0x7a, 0x34, - 0xc8, 0x67, 0x39, 0x67, 0x13, 0xdd, 0xa7, 0x63, 0x83, 0xe8, 0xbb, 0xd0, 0x39, 0x08, 0x66, 0x3e, - 0xfb, 0x52, 0x35, 0xfa, 0x61, 0x40, 0x16, 0xcc, 0x50, 0x3c, 0x4d, 0x40, 0x26, 0xa6, 0xe9, 0xdf, - 0x35, 0x60, 0x41, 0x62, 0x22, 0xd5, 0x11, 0xcb, 0x79, 0x18, 0xcb, 0xb4, 0xba, 0xa2, 0x6a, 0x81, - 0x2a, 0xf7, 0xdd, 0xa8, 0xb9, 0x6f, 0xe5, 0x22, 0xe9, 0xd2, 0xbf, 0xba, 0x58, 0x07, 0x26, 0xe2, - 0xcd, 0x70, 0xc2, 0x64, 0xbf, 0x67, 0x53, 0xc5, 0x9b, 0x1a, 0x50, 0x8a, 0x7c, 0x8b, 0x37, 0x2f, - 0xf7, 0xa7, 0x05, 0x51, 0x99, 0x05, 0x1b, 0x54, 0xab, 0x59, 0x16, 0x65, 0x67, 0x5f, 0x45, 0xb3, - 0x54, 0x34, 0xc8, 0xd2, 0x1b, 0x68, 0x10, 0xe9, 0x37, 0x39, 0x1a, 0x84, 0xc0, 0xea, 0x23, 0xc6, - 0x7c, 0x96, 0x26, 0x99, 0xe9, 0x96, 0xfc, 0xa1, 0x07, 0xab, 0xca, 0x22, 0x98, 0x39, 0x72, 0xdd, - 0x31, 0x1f, 0x5e, 0x5d, 0xa6, 0xf5, 0x6d, 0xe8, 0x8a, 0x00, 0x0a, 0xa3, 0x23, 0x11, 0x2d, 0xa9, - 0x9c, 0x82, 0x03, 0xc4, 0x3d, 0xe9, 0xdc, 0xe1, 0x24, 0x8c, 0x14, 0x83, 0x6d, 0x10, 0x9a, 0x3a, - 0x1d, 0x60, 0x09, 0xf6, 0x7a, 0xbe, 0x19, 0xd3, 0x03, 0x58, 0xb3, 0xf6, 0xab, 0x04, 0xea, 0x0e, - 0xe8, 0x7a, 0xa3, 0x4c, 0x11, 0xc8, 0x77, 0xb1, 0xe5, 0x1a, 0xb7, 0xe2, 0x33, 0x07, 0x99, 0xfe, - 0xb3, 0x07, 0xeb, 0xd2, 0xd0, 0x2b, 0x37, 0xca, 0xb4, 0x28, 0x2d, 0x48, 0xcf, 0x46, 0x0a, 0xfc, - 0xde, 0x05, 0x5f, 0x8d, 0xc9, 0xd7, 0xdf, 0xd0, 0x39, 0x31, 0xa5, 0xbd, 0x73, 0xd8, 0x33, 0x57, - 0xc7, 0x9e, 0x57, 0x1c, 0xbe, 0x2e, 0x00, 0x9e, 0xaf, 0x0d, 0x80, 0xef, 0x2d, 0xc2, 0x7c, 0x3e, - 0x4c, 0x52, 0x46, 0x37, 0x61, 0xc3, 0x3d, 0x9c, 0x64, 0xd9, 0xee, 0xbf, 0x78, 0xb0, 0x2c, 0x93, - 0x71, 0xb2, 0x0f, 0x9b, 0x65, 0x04, 0x63, 0x2d, 0xab, 0xbd, 0x9b, 0x18, 0x57, 0xb3, 0xda, 0x26, - 0xde, 0xbf, 0x5c, 0x3b, 0xa7, 0xfd, 0xec, 0xef, 0xff, 0xe4, 0xdf, 0xfe, 0xa4, 0x71, 0x91, 0xae, - 0xee, 0x9c, 0xde, 0xde, 0x11, 0x2a, 0x91, 0x9d, 0x09, 0x8c, 0x0f, 0xbd, 0x1b, 0xb8, 0x8a, 0xdd, - 0xf9, 0x6d, 0x56, 0xa9, 0xe9, 0x20, 0x37, 0xab, 0xd4, 0xb6, 0x8a, 0x3b, 0xab, 0x4c, 0x05, 0x86, - 0x59, 0x65, 0xf7, 0xbf, 0xfa, 0xd0, 0x32, 0x41, 0x21, 0xf9, 0x2e, 0x74, 0x9d, 0xc4, 0x23, 0xd1, - 0x84, 0xeb, 0x52, 0x99, 0xfd, 0x2b, 0xf5, 0x93, 0x6a, 0xd9, 0xab, 0x62, 0xd9, 0x1e, 0xd9, 0xc4, - 0x65, 0x55, 0xb6, 0x6f, 0x47, 0x64, 0x64, 0x65, 0x8f, 0xc2, 0x33, 0x58, 0x76, 0x93, 0x85, 0xe4, - 0x8a, 0x2b, 0x1a, 0xa5, 0xd5, 0xde, 0x3a, 0x67, 0x56, 0x2d, 0x77, 0x45, 0x2c, 0xb7, 0x49, 0x36, - 0xec, 0xe5, 0x4c, 0xb0, 0xc6, 0x44, 0x57, 0x89, 0xdd, 0x12, 0x4e, 0x34, 0xbd, 0xfa, 0x56, 0xf1, - 0xfe, 0xa5, 0x6a, 0xfb, 0xb7, 0xea, 0x17, 0xa7, 0x3d, 0xb1, 0x14, 0x21, 0x82, 0xa1, 0x76, 0x47, - 0x38, 0xf9, 0x0e, 0xb4, 0x4c, 0x43, 0x29, 0xd9, 0xb2, 0xba, 0x78, 0xed, 0x2e, 0xd7, 0x7e, 0xaf, - 0x3a, 0x51, 0x77, 0x55, 0x36, 0x65, 0x14, 0x88, 0x7d, 0xb8, 0xa8, 0x2c, 0xf4, 0x11, 0xfb, 0x69, - 0x4e, 0x52, 0xd3, 0xc8, 0x7e, 0xcb, 0x23, 0x77, 0x60, 0x49, 0xf7, 0xe9, 0x92, 0xcd, 0xfa, 0x7e, - 0xe3, 0xfe, 0x56, 0x05, 0xae, 0xf4, 0xc8, 0x5d, 0x80, 0xa2, 0xa5, 0x94, 0xf4, 0xce, 0xeb, 0x7c, - 0x35, 0x4c, 0xac, 0xe9, 0x3f, 0x1d, 0x8b, 0x8e, 0x5a, 0xb7, 0x63, 0x95, 0x7c, 0xa5, 0xc0, 0xaf, - 0xed, 0x65, 0x7d, 0x05, 0x41, 0xba, 0x29, 0x78, 0xb7, 0x4a, 0x96, 0x91, 0x77, 0x31, 0x3b, 0xd3, - 0xfd, 0x55, 0x0f, 0xa0, 0x6d, 0xb5, 0xa9, 0x12, 0x4d, 0xa1, 0xda, 0xe2, 0xda, 0xef, 0xd7, 0x4d, - 0xa9, 0xed, 0xfe, 0x1a, 0x74, 0x9d, 0x7e, 0x53, 0xf3, 0x32, 0xea, 0xba, 0x59, 0xcd, 0xcb, 0xa8, - 0x6f, 0x51, 0xfd, 0x36, 0xb4, 0xad, 0xee, 0x50, 0x62, 0x55, 0xb4, 0x4b, 0xdd, 0x9f, 0x66, 0x47, - 0x35, 0xcd, 0xa4, 0x74, 0x43, 0x9c, 0x77, 0x99, 0xb6, 0xf0, 0xbc, 0xa2, 0xc9, 0x08, 0x85, 0xe4, - 0xbb, 0xb0, 0xec, 0x76, 0x85, 0x9a, 0x57, 0x55, 0xdb, 0x5f, 0x6a, 0x5e, 0xd5, 0x39, 0xad, 0xa4, - 0x4a, 0x20, 0x6f, 0xac, 0x9b, 0x45, 0x76, 0x5e, 0xa8, 0x94, 0xe8, 0x4b, 0xf2, 0x2d, 0x54, 0x1d, - 0xaa, 0xeb, 0x8b, 0x14, 0x5d, 0xb2, 0x6e, 0x6f, 0x98, 0x91, 0xf6, 0x4a, 0x83, 0x18, 0x5d, 0x13, - 0xc4, 0xdb, 0xa4, 0x38, 0x01, 0xf9, 0x04, 0x16, 0x55, 0xf7, 0x17, 0xb9, 0x58, 0x48, 0xb5, 0x95, - 0x40, 0xea, 0x6f, 0x96, 0xc1, 0x8a, 0xd8, 0xba, 0x20, 0xd6, 0x25, 0x6d, 0x24, 0x36, 0x66, 0x3c, - 0x44, 0x1a, 0x31, 0xac, 0x94, 0xaa, 0x58, 0xe6, 0xb1, 0xd4, 0xd7, 0xc0, 0xfb, 0x57, 0x5f, 0x5d, - 0xfc, 0x72, 0xd5, 0x8c, 0x56, 0x2f, 0x3b, 0xba, 0x65, 0xe1, 0x37, 0xa1, 0x63, 0x37, 0x1b, 0x1a, - 0x9d, 0x5d, 0xd3, 0x98, 0x68, 0x74, 0x76, 0x5d, 0x77, 0xa2, 0xbe, 0x5c, 0xd2, 0xb1, 0x97, 0x21, - 0xdf, 0x86, 0x15, 0xab, 0x5e, 0x7a, 0x38, 0x8b, 0x87, 0x46, 0x78, 0xaa, 0x7d, 0x2b, 0xfd, 0x3a, - 0x4b, 0x4b, 0xb7, 0x04, 0xe1, 0x35, 0xea, 0x10, 0x46, 0xc1, 0xb9, 0x0f, 0x6d, 0xbb, 0x16, 0xfb, - 0x0a, 0xba, 0x5b, 0xd6, 0x94, 0xdd, 0xec, 0x71, 0xcb, 0x23, 0x7f, 0xe6, 0x41, 0xc7, 0xee, 0x88, - 0x22, 0x4e, 0x16, 0xa6, 0x44, 0xa7, 0x67, 0xcf, 0xd9, 0x84, 0xe8, 0x13, 0xb1, 0xc9, 0xbd, 0x1b, - 0x8f, 0x1c, 0x26, 0xbf, 0x70, 0x9c, 0xa8, 0x9b, 0xf6, 0x7f, 0x38, 0x5e, 0x96, 0x27, 0xed, 0xbe, - 0x9e, 0x97, 0xb7, 0x3c, 0xf2, 0xa1, 0xfc, 0xa7, 0x8e, 0x0e, 0x68, 0x88, 0xa5, 0xd8, 0xca, 0xec, - 0xb2, 0xff, 0xfe, 0xb2, 0xed, 0xdd, 0xf2, 0xc8, 0x6f, 0xc9, 0xbf, 0x6d, 0xa8, 0x6f, 0x05, 0xd7, - 0xdf, 0xf4, 0x7b, 0xfa, 0xb6, 0x38, 0xc9, 0x55, 0x7a, 0xc9, 0x39, 0x49, 0x59, 0xb3, 0x1f, 0x00, - 0x14, 0xd1, 0x29, 0x29, 0x85, 0x6a, 0x46, 0xe7, 0x55, 0x03, 0x58, 0xf7, 0x36, 0x75, 0x44, 0x27, - 0xd5, 0x40, 0xc7, 0x8a, 0x0b, 0x73, 0x73, 0x9d, 0xd5, 0x28, 0xb3, 0xdf, 0xaf, 0x9b, 0x52, 0xf4, - 0xbf, 0x2a, 0xe8, 0xbf, 0x45, 0x2e, 0xdb, 0xf4, 0x77, 0x5e, 0xd8, 0x51, 0xe9, 0x4b, 0xf2, 0x39, - 0x74, 0xf7, 0x93, 0xe4, 0xd9, 0x34, 0x35, 0x09, 0x10, 0x37, 0xce, 0xc2, 0xc8, 0xb8, 0x5f, 0x3a, - 0x14, 0xbd, 0x2e, 0x28, 0x5f, 0x26, 0x97, 0x5c, 0xca, 0x45, 0xac, 0xfc, 0x92, 0x04, 0xb0, 0x66, - 0xec, 0x9d, 0x39, 0x48, 0xdf, 0xa5, 0x63, 0x87, 0xac, 0x95, 0x35, 0x1c, 0x0f, 0xc4, 0xac, 0x91, - 0x6b, 0x9a, 0xb7, 0x3c, 0x72, 0x00, 0x9d, 0x07, 0x6c, 0x98, 0x8c, 0x98, 0x0a, 0x8d, 0xd6, 0x8b, - 0x9d, 0x9b, 0x98, 0xaa, 0xdf, 0x75, 0x80, 0xae, 0x06, 0x48, 0x83, 0x59, 0xc6, 0xbe, 0xdc, 0x79, - 0xa1, 0x82, 0xae, 0x97, 0x5a, 0x03, 0xe8, 0x40, 0xd1, 0xd1, 0x00, 0xa5, 0xc8, 0xd2, 0xd1, 0x00, - 0x95, 0xc8, 0xd2, 0xd1, 0x00, 0x3a, 0x50, 0x25, 0x11, 0xc6, 0x9b, 0xa5, 0x60, 0xd4, 0x58, 0xcd, - 0xf3, 0x42, 0xd8, 0xfe, 0xb5, 0xf3, 0x11, 0xdc, 0xd5, 0x6e, 0xb8, 0xab, 0x1d, 0x42, 0xf7, 0x01, - 0x93, 0xcc, 0x92, 0x55, 0x85, 0xbe, 0xab, 0x52, 0xec, 0x0a, 0x44, 0x59, 0xdd, 0x88, 0x39, 0x57, - 0xc5, 0x8b, 0x94, 0x3e, 0xf9, 0x0e, 0xb4, 0x1f, 0x33, 0xae, 0xcb, 0x08, 0xc6, 0xf7, 0x28, 0xd5, - 0x15, 0xfa, 0x35, 0x55, 0x08, 0x7a, 0x4d, 0x50, 0xeb, 0x93, 0x9e, 0xa1, 0xb6, 0xc3, 0x46, 0x63, - 0x26, 0x1f, 0xff, 0x20, 0x1c, 0xbd, 0x24, 0xbf, 0x2e, 0x88, 0x9b, 0xca, 0xe3, 0xa6, 0x95, 0x7d, - 0xb6, 0x89, 0xaf, 0x94, 0xe0, 0x75, 0x94, 0xe3, 0x64, 0xc4, 0x2c, 0x63, 0x17, 0x43, 0xdb, 0x2a, - 0x33, 0x9b, 0x07, 0x55, 0xad, 0x5d, 0x9b, 0x07, 0x55, 0x53, 0x95, 0xa6, 0xdb, 0x62, 0x1d, 0x4a, - 0xae, 0x15, 0xeb, 0xc8, 0x4a, 0x74, 0xb1, 0xd2, 0xce, 0x8b, 0x60, 0xc2, 0x5f, 0x92, 0x2f, 0x44, - 0x6b, 0xb4, 0x5d, 0x2a, 0x29, 0x7c, 0x9f, 0x72, 0x55, 0xc5, 0x30, 0xcb, 0x9a, 0x72, 0xfd, 0x21, - 0xb9, 0x94, 0xb0, 0x89, 0x5f, 0x07, 0x38, 0xe4, 0x49, 0xfa, 0x20, 0x60, 0x93, 0x24, 0x2e, 0x34, - 0x59, 0x51, 0x0e, 0x28, 0x34, 0x99, 0x55, 0x13, 0x20, 0x5f, 0x58, 0xde, 0xa7, 0x53, 0x69, 0xd2, - 0xc2, 0x75, 0x6e, 0xc5, 0xc0, 0x30, 0xa4, 0xa6, 0x6a, 0x70, 0xcb, 0x43, 0x5f, 0xb2, 0x48, 0x7d, - 0x18, 0x5f, 0xb2, 0x92, 0x55, 0x31, 0x6a, 0xb0, 0x26, 0x4f, 0x72, 0x00, 0xad, 0x22, 0xfe, 0xd6, - 0xe6, 0xa9, 0x1c, 0xad, 0x1b, 0x7b, 0x53, 0x09, 0x8b, 0xe9, 0xaa, 0x60, 0x15, 0x90, 0x25, 0x64, - 0x95, 0xa8, 0x94, 0x0f, 0x61, 0x5d, 0x6e, 0xd0, 0x18, 0x4f, 0x91, 0xe0, 0xd6, 0x27, 0xa9, 0x09, - 0x83, 0xcd, 0x6b, 0xae, 0x8b, 0x22, 0xb5, 0x77, 0x42, 0xcd, 0x0a, 0x1f, 0x7a, 0x37, 0x8e, 0x16, - 0xc4, 0x1f, 0x8c, 0xbf, 0xf6, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x8e, 0x28, 0xc4, 0x0c, 0x92, - 0x3c, 0x00, 0x00, + // 4877 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x3b, 0x4d, 0x8f, 0x1c, 0x49, + 0x56, 0xce, 0xea, 0xea, 0x8f, 0x7a, 0x55, 0xd5, 0x1f, 0xd1, 0xed, 0xee, 0x72, 0xd9, 0xeb, 0xb5, + 0x63, 0x47, 0x33, 0x8d, 0x19, 0xdc, 0x76, 0x2f, 0x3b, 0xcc, 0x8e, 0x81, 0x91, 0xbf, 0x7b, 0xd8, + 0x1e, 0x4f, 0x6f, 0xb6, 0x67, 0x06, 0x76, 0x85, 0x8a, 0xec, 0xaa, 0xe8, 0xea, 0x5c, 0x67, 0x65, + 0xe6, 0x64, 0x46, 0x75, 0xbb, 0xd6, 0x58, 0x82, 0x05, 0x21, 0x21, 0x81, 0xf6, 0x00, 0x02, 0xed, + 0x61, 0xb9, 0x70, 0x81, 0x03, 0xbf, 0x00, 0x89, 0x1f, 0xb0, 0x12, 0x02, 0x69, 0x4f, 0x08, 0x2e, + 0x08, 0x4e, 0x70, 0xe6, 0xc0, 0x0d, 0xbd, 0xf8, 0xca, 0x88, 0xcc, 0x6c, 0xdb, 0xcb, 0x2e, 0xdc, + 0x2a, 0x5e, 0xbc, 0x7c, 0x11, 0xf1, 0xe2, 0xc5, 0xfb, 0x2e, 0x68, 0x65, 0xe9, 0xf0, 0x66, 0x9a, + 0x25, 0x3c, 0x21, 0xf3, 0x51, 0x9c, 0xa5, 0xc3, 0xfe, 0x95, 0x71, 0x92, 0x8c, 0x23, 0xb6, 0x13, + 0xa4, 0xe1, 0x4e, 0x10, 0xc7, 0x09, 0x0f, 0x78, 0x98, 0xc4, 0xb9, 0x44, 0xa2, 0xb7, 0x61, 0xfd, + 0x7e, 0xc6, 0x02, 0xce, 0x3e, 0x0f, 0xa2, 0x88, 0x71, 0x9f, 0x7d, 0x31, 0x65, 0x39, 0x27, 0x7d, + 0x58, 0x4a, 0x83, 0x3c, 0x3f, 0x4b, 0xb2, 0x51, 0xcf, 0xbb, 0xe6, 0x6d, 0x77, 0x7c, 0x33, 0xa6, + 0x9b, 0xb0, 0xe1, 0x7e, 0x92, 0xa7, 0x49, 0x9c, 0x33, 0x24, 0xf5, 0x69, 0x1c, 0x25, 0xc3, 0x67, + 0x3f, 0x11, 0x29, 0xf7, 0x13, 0x45, 0xea, 0x07, 0x0d, 0x68, 0x3f, 0xcd, 0x82, 0x38, 0x0f, 0x86, + 0xb8, 0x59, 0xd2, 0x83, 0x45, 0xfe, 0x7c, 0x70, 0x12, 0xe4, 0x27, 0x82, 0x44, 0xcb, 0xd7, 0x43, + 0xb2, 0x09, 0x0b, 0xc1, 0x24, 0x99, 0xc6, 0xbc, 0xd7, 0xb8, 0xe6, 0x6d, 0xcf, 0xf9, 0x6a, 0x44, + 0xde, 0x85, 0xb5, 0x78, 0x3a, 0x19, 0x0c, 0x93, 0xf8, 0x38, 0xcc, 0x26, 0xf2, 0xc8, 0xbd, 0xb9, + 0x6b, 0xde, 0xf6, 0xbc, 0x5f, 0x9d, 0x20, 0x57, 0x01, 0x8e, 0x70, 0x1b, 0x72, 0x89, 0xa6, 0x58, + 0xc2, 0x82, 0x10, 0x0a, 0x1d, 0x35, 0x62, 0xe1, 0xf8, 0x84, 0xf7, 0xe6, 0x05, 0x21, 0x07, 0x86, + 0x34, 0x78, 0x38, 0x61, 0x83, 0x9c, 0x07, 0x93, 0xb4, 0xb7, 0x20, 0x76, 0x63, 0x41, 0xc4, 0x7c, + 0xc2, 0x83, 0x68, 0x70, 0xcc, 0x58, 0xde, 0x5b, 0x54, 0xf3, 0x06, 0x42, 0xde, 0x86, 0xe5, 0x11, + 0xcb, 0xf9, 0x20, 0x18, 0x8d, 0x32, 0x96, 0xe7, 0x2c, 0xef, 0x2d, 0x5d, 0x9b, 0xdb, 0x6e, 0xf9, + 0x25, 0x28, 0xed, 0xc1, 0xe6, 0x63, 0xc6, 0x2d, 0xee, 0xe4, 0x8a, 0xd3, 0x74, 0x1f, 0x88, 0x05, + 0x7e, 0xc0, 0x78, 0x10, 0x46, 0x39, 0x79, 0x0f, 0x3a, 0xdc, 0x42, 0xee, 0x79, 0xd7, 0xe6, 0xb6, + 0xdb, 0xbb, 0xe4, 0xa6, 0x90, 0x8e, 0x9b, 0xd6, 0x07, 0xbe, 0x83, 0x47, 0xff, 0xd1, 0x83, 0xf6, + 0x21, 0x8b, 0x47, 0xfa, 0x1e, 0x09, 0x34, 0x71, 0x27, 0xea, 0x0e, 0xc5, 0x6f, 0xf2, 0x65, 0x68, + 0x8b, 0xdd, 0xe5, 0x3c, 0x0b, 0xe3, 0xb1, 0xb8, 0x82, 0x96, 0x0f, 0x08, 0x3a, 0x14, 0x10, 0xb2, + 0x0a, 0x73, 0xc1, 0x84, 0x0b, 0xc6, 0xcf, 0xf9, 0xf8, 0x93, 0x5c, 0x87, 0x4e, 0x1a, 0xcc, 0x26, + 0x2c, 0xe6, 0x05, 0xb3, 0x3b, 0x7e, 0x5b, 0xc1, 0xf6, 0x90, 0xdb, 0x37, 0x61, 0xdd, 0x46, 0xd1, + 0xd4, 0xe7, 0x05, 0xf5, 0x35, 0x0b, 0x53, 0x2d, 0xf2, 0x0e, 0xac, 0x68, 0xfc, 0x4c, 0x6e, 0x56, + 0xb0, 0xbf, 0xe5, 0x2f, 0x2b, 0xb0, 0x66, 0xd0, 0x9f, 0x7a, 0xd0, 0x91, 0x47, 0x92, 0x72, 0x46, + 0xde, 0x82, 0xae, 0xfe, 0x92, 0x65, 0x59, 0x92, 0x29, 0xe9, 0x72, 0x81, 0xe4, 0x06, 0xac, 0x6a, + 0x40, 0x9a, 0xb1, 0x70, 0x12, 0x8c, 0x99, 0x38, 0x6a, 0xc7, 0xaf, 0xc0, 0xc9, 0x6e, 0x41, 0x31, + 0x4b, 0xa6, 0x9c, 0x89, 0xa3, 0xb7, 0x77, 0x3b, 0x8a, 0xdd, 0x3e, 0xc2, 0x7c, 0x17, 0x85, 0x7e, + 0xcf, 0x83, 0xce, 0xfd, 0x93, 0x20, 0x8e, 0x59, 0x74, 0x90, 0x84, 0x31, 0x47, 0x71, 0x3b, 0x9e, + 0xc6, 0xa3, 0x30, 0x1e, 0x0f, 0xf8, 0xf3, 0x50, 0x3f, 0x1b, 0x07, 0x86, 0x9b, 0xb2, 0xc7, 0xc8, + 0x24, 0xc5, 0xff, 0x0a, 0x1c, 0xe9, 0x25, 0x53, 0x9e, 0x4e, 0xf9, 0x20, 0x8c, 0x47, 0xec, 0xb9, + 0xd8, 0x53, 0xd7, 0x77, 0x60, 0xf4, 0x57, 0x61, 0x75, 0x1f, 0xe5, 0x38, 0x0e, 0xe3, 0xf1, 0x5d, + 0x29, 0x6c, 0xf8, 0xb8, 0xd2, 0xe9, 0xd1, 0x33, 0x36, 0x53, 0x7c, 0x51, 0x23, 0x14, 0x85, 0x93, + 0x24, 0xe7, 0x6a, 0x3d, 0xf1, 0x9b, 0xfe, 0x9b, 0x07, 0x2b, 0xc8, 0xdb, 0x8f, 0x83, 0x78, 0xa6, + 0x45, 0x66, 0x1f, 0x3a, 0x48, 0xea, 0x69, 0x72, 0x57, 0x3e, 0x51, 0x29, 0x7a, 0xdb, 0x8a, 0x17, + 0x25, 0xec, 0x9b, 0x36, 0xea, 0xc3, 0x98, 0x67, 0x33, 0xdf, 0xf9, 0x1a, 0x85, 0x8d, 0x07, 0xd9, + 0x98, 0x71, 0xf1, 0x78, 0xd5, 0x63, 0x06, 0x09, 0xba, 0x9f, 0xc4, 0xc7, 0xe4, 0x1a, 0x74, 0xf2, + 0x80, 0x0f, 0x52, 0x96, 0x0d, 0x8e, 0x66, 0x9c, 0x09, 0x81, 0x99, 0xf3, 0x21, 0x0f, 0xf8, 0x01, + 0xcb, 0xee, 0xcd, 0x38, 0xeb, 0x7f, 0x08, 0x6b, 0x95, 0x55, 0x50, 0x46, 0x8b, 0x23, 0xe2, 0x4f, + 0xb2, 0x01, 0xf3, 0xa7, 0x41, 0x34, 0x65, 0x4a, 0xa7, 0xc8, 0xc1, 0x07, 0x8d, 0xf7, 0x3d, 0xfa, + 0x36, 0xac, 0x16, 0xdb, 0x56, 0x42, 0x44, 0xa0, 0x69, 0x6e, 0xa9, 0xe5, 0x8b, 0xdf, 0xf4, 0x77, + 0x3d, 0x89, 0x78, 0x3f, 0x09, 0xcd, 0xfb, 0x44, 0x44, 0x7c, 0xc6, 0x1a, 0x11, 0x7f, 0x9f, 0xab, + 0xbf, 0x7e, 0xfa, 0xc3, 0xd2, 0x77, 0x60, 0xcd, 0xda, 0xc2, 0x2b, 0x36, 0xfb, 0x17, 0x1e, 0xac, + 0x3d, 0x61, 0x67, 0xea, 0xd6, 0xf5, 0x6e, 0xdf, 0x87, 0x26, 0x9f, 0xa5, 0x4c, 0x60, 0x2e, 0xef, + 0xbe, 0xa5, 0x2e, 0xad, 0x82, 0x77, 0x53, 0x0d, 0x9f, 0xce, 0x52, 0xe6, 0x8b, 0x2f, 0xe8, 0x27, + 0xd0, 0xb6, 0x80, 0x64, 0x0b, 0xd6, 0x3f, 0xff, 0xe8, 0xe9, 0x93, 0x87, 0x87, 0x87, 0x83, 0x83, + 0x4f, 0xef, 0x7d, 0xe3, 0xe1, 0x6f, 0x0c, 0xf6, 0xee, 0x1e, 0xee, 0xad, 0x5e, 0x20, 0x9b, 0x40, + 0x9e, 0x3c, 0x3c, 0x7c, 0xfa, 0xf0, 0x81, 0x03, 0xf7, 0xc8, 0x0a, 0xb4, 0x6d, 0x40, 0x83, 0xf6, + 0xa1, 0xf7, 0x84, 0x9d, 0x7d, 0x1e, 0xf2, 0x98, 0xe5, 0xb9, 0xbb, 0x3c, 0xbd, 0x09, 0xc4, 0xde, + 0x93, 0x3a, 0x66, 0x0f, 0x16, 0x95, 0xc6, 0xd4, 0x06, 0x43, 0x0d, 0xe9, 0xdb, 0x40, 0x0e, 0xc3, + 0x71, 0xfc, 0x31, 0xcb, 0xf3, 0x60, 0xcc, 0xf4, 0x61, 0x57, 0x61, 0x6e, 0x92, 0x8f, 0xd5, 0x43, + 0xc3, 0x9f, 0xf4, 0xab, 0xb0, 0xee, 0xe0, 0x29, 0xc2, 0x57, 0xa0, 0x95, 0x87, 0xe3, 0x38, 0xe0, + 0xd3, 0x8c, 0x29, 0xd2, 0x05, 0x80, 0x3e, 0x82, 0x8d, 0xcf, 0x58, 0x16, 0x1e, 0xcf, 0x5e, 0x47, + 0xde, 0xa5, 0xd3, 0x28, 0xd3, 0x79, 0x08, 0x17, 0x4b, 0x74, 0xd4, 0xf2, 0x52, 0x32, 0xd5, 0xfd, + 0x2d, 0xf9, 0x72, 0x60, 0xbd, 0xd3, 0x86, 0xfd, 0x4e, 0xe9, 0xa7, 0x40, 0xee, 0x27, 0x71, 0xcc, + 0x86, 0xfc, 0x80, 0xb1, 0x4c, 0x6f, 0xe6, 0xe7, 0x2d, 0x31, 0x6c, 0xef, 0x6e, 0xa9, 0x8b, 0x2d, + 0x3f, 0x7e, 0x25, 0x9f, 0x04, 0x9a, 0x29, 0xcb, 0x26, 0x82, 0xf0, 0x92, 0x2f, 0x7e, 0xd3, 0x1d, + 0x58, 0x77, 0xc8, 0x16, 0x3c, 0x4f, 0x19, 0xcb, 0x06, 0x6a, 0x77, 0xf3, 0xbe, 0x1e, 0xd2, 0xdb, + 0x70, 0xf1, 0x41, 0x98, 0x0f, 0xab, 0x5b, 0xc1, 0x4f, 0xa6, 0x47, 0x83, 0xe2, 0xf9, 0xe9, 0x21, + 0x5a, 0xb9, 0xf2, 0x27, 0xca, 0x37, 0xf8, 0x03, 0x0f, 0x9a, 0x7b, 0x4f, 0xf7, 0xef, 0xa3, 0x63, + 0x11, 0xc6, 0xc3, 0x64, 0x82, 0xb6, 0x41, 0xb2, 0xc3, 0x8c, 0xcf, 0x7d, 0x56, 0x57, 0xa0, 0x25, + 0x4c, 0x0a, 0x1a, 0x6e, 0xf1, 0xa8, 0x3a, 0x7e, 0x01, 0x40, 0xa7, 0x81, 0x3d, 0x4f, 0xc3, 0x4c, + 0x78, 0x05, 0xda, 0xd6, 0x37, 0x85, 0xb2, 0xac, 0x4e, 0xd0, 0xff, 0x68, 0x42, 0xf7, 0xee, 0x90, + 0x87, 0xa7, 0x4c, 0x29, 0x6f, 0xb1, 0xaa, 0x00, 0xa8, 0xfd, 0xa8, 0x11, 0x9a, 0x99, 0x8c, 0x4d, + 0x12, 0xce, 0x06, 0xce, 0x35, 0xb9, 0x40, 0xc4, 0x1a, 0x4a, 0x42, 0x83, 0x14, 0xcd, 0x80, 0xd8, + 0x5f, 0xcb, 0x77, 0x81, 0xc8, 0x32, 0x04, 0x20, 0x97, 0x71, 0x67, 0x4d, 0x5f, 0x0f, 0x91, 0x1f, + 0xc3, 0x20, 0x0d, 0x86, 0x21, 0x9f, 0x29, 0x6d, 0x60, 0xc6, 0x48, 0x3b, 0x4a, 0x86, 0x41, 0x34, + 0x38, 0x0a, 0xa2, 0x20, 0x1e, 0x32, 0xe5, 0x9f, 0xb8, 0x40, 0x74, 0x41, 0xd4, 0x96, 0x34, 0x9a, + 0x74, 0x53, 0x4a, 0x50, 0x74, 0x65, 0x86, 0xc9, 0x64, 0x12, 0x72, 0xf4, 0x5c, 0x7a, 0x4b, 0x52, + 0xf3, 0x14, 0x10, 0x71, 0x12, 0x39, 0x3a, 0x93, 0x3c, 0x6c, 0xc9, 0xd5, 0x1c, 0x20, 0x52, 0x39, + 0x66, 0x4c, 0x68, 0xb0, 0x67, 0x67, 0x3d, 0x90, 0x54, 0x0a, 0x08, 0xde, 0xc6, 0x34, 0xce, 0x19, + 0xe7, 0x11, 0x1b, 0x99, 0x0d, 0xb5, 0x05, 0x5a, 0x75, 0x82, 0xdc, 0x82, 0x75, 0xe9, 0x4c, 0xe5, + 0x01, 0x4f, 0xf2, 0x93, 0x30, 0x1f, 0xe4, 0x2c, 0xe6, 0xbd, 0x8e, 0xc0, 0xaf, 0x9b, 0x22, 0xef, + 0xc3, 0x56, 0x09, 0x9c, 0xb1, 0x21, 0x0b, 0x4f, 0xd9, 0xa8, 0xd7, 0x15, 0x5f, 0x9d, 0x37, 0x4d, + 0xae, 0x41, 0x1b, 0x7d, 0xc8, 0x69, 0x3a, 0x0a, 0x38, 0xcb, 0x7b, 0xcb, 0xe2, 0x1e, 0x6c, 0x10, + 0xb9, 0x0d, 0xdd, 0x94, 0x49, 0x2b, 0x7c, 0xc2, 0xa3, 0x61, 0xde, 0x5b, 0x11, 0xa6, 0xaf, 0xad, + 0x1e, 0x1b, 0xca, 0xaf, 0xef, 0x62, 0xa0, 0x68, 0x0e, 0xf3, 0xd3, 0xc1, 0x88, 0x45, 0xc1, 0xac, + 0xb7, 0x2a, 0x84, 0xae, 0x00, 0xd0, 0x8b, 0xb0, 0xbe, 0x1f, 0xe6, 0x5c, 0x49, 0x9a, 0xd1, 0x7e, + 0x7b, 0xb0, 0xe1, 0x82, 0xd5, 0x5b, 0xbc, 0x05, 0x4b, 0x4a, 0x6c, 0xf2, 0x5e, 0x5b, 0x2c, 0xbd, + 0xa1, 0x96, 0x76, 0x24, 0xd6, 0x37, 0x58, 0xf4, 0xf7, 0x1b, 0xd0, 0xc4, 0x77, 0x76, 0xfe, 0x9b, + 0xb4, 0x1f, 0x78, 0xc3, 0x79, 0xe0, 0xb6, 0xba, 0x9d, 0x73, 0xd4, 0xad, 0xf0, 0xac, 0x67, 0x9c, + 0xa9, 0xdb, 0x90, 0x12, 0x6b, 0x41, 0x8a, 0xf9, 0x8c, 0x0d, 0x4f, 0x85, 0xd8, 0x9a, 0x79, 0x84, + 0xa0, 0x50, 0xa3, 0x99, 0x13, 0x5f, 0x4b, 0x99, 0x35, 0x63, 0x3d, 0x27, 0xbe, 0x5c, 0x2c, 0xe6, + 0xc4, 0x77, 0x3d, 0x58, 0x0c, 0xe3, 0xa3, 0x64, 0x1a, 0x8f, 0x84, 0x7c, 0x2e, 0xf9, 0x7a, 0x88, + 0x7c, 0x4e, 0x85, 0x77, 0x14, 0x4e, 0x98, 0x12, 0xcc, 0x02, 0x40, 0x09, 0xba, 0x41, 0xb9, 0xd0, + 0x38, 0x86, 0xc9, 0xef, 0xc1, 0x9a, 0x05, 0x53, 0x1c, 0xbe, 0x0e, 0xf3, 0x78, 0x7a, 0xed, 0x4f, + 0xeb, 0x9b, 0x15, 0xaa, 0x4a, 0xce, 0xd0, 0x55, 0x58, 0x7e, 0xcc, 0xf8, 0x47, 0xf1, 0x71, 0xa2, + 0x29, 0xfd, 0xe1, 0x1c, 0xac, 0x18, 0x90, 0x22, 0xb4, 0x0d, 0x2b, 0xe1, 0x88, 0xc5, 0x3c, 0xe4, + 0xb3, 0x81, 0xe3, 0x6d, 0x95, 0xc1, 0xa8, 0xfc, 0x83, 0x28, 0x0c, 0x72, 0xa5, 0x3e, 0xe4, 0x80, + 0xec, 0xc2, 0x06, 0x4a, 0x9e, 0x16, 0x26, 0x73, 0xed, 0xd2, 0xc9, 0xab, 0x9d, 0xc3, 0xc7, 0x82, + 0x70, 0xa9, 0x9e, 0x8a, 0x4f, 0xa4, 0xaa, 0xab, 0x9b, 0x42, 0xae, 0x49, 0x4a, 0x78, 0xe4, 0x79, + 0x29, 0x9d, 0x06, 0x50, 0x89, 0x8f, 0x16, 0xa4, 0x83, 0x59, 0x8e, 0x8f, 0xac, 0x18, 0x6b, 0xa9, + 0x12, 0x63, 0x6d, 0xc3, 0x4a, 0x3e, 0x8b, 0x87, 0x6c, 0x34, 0xe0, 0x09, 0xae, 0x1b, 0xc6, 0xe2, + 0x76, 0x96, 0xfc, 0x32, 0x58, 0x44, 0x83, 0x2c, 0xe7, 0x31, 0xe3, 0x42, 0x6b, 0x2c, 0xf9, 0x7a, + 0x88, 0x0a, 0x58, 0xa0, 0x48, 0xa1, 0x6f, 0xf9, 0x6a, 0x84, 0x56, 0x6c, 0x9a, 0x85, 0x79, 0xaf, + 0x23, 0xa0, 0xe2, 0x37, 0xfd, 0xae, 0x30, 0x8e, 0x26, 0x08, 0xfc, 0x54, 0xbc, 0x5c, 0x72, 0x19, + 0x5a, 0x72, 0x4f, 0xf9, 0x49, 0xa0, 0xc3, 0x55, 0x01, 0x38, 0x3c, 0x09, 0x30, 0x76, 0x71, 0x8e, + 0x29, 0x5f, 0x41, 0x5b, 0xc0, 0xf6, 0xe4, 0x29, 0xdf, 0x82, 0x65, 0x1d, 0x5e, 0xe6, 0x83, 0x88, + 0x1d, 0x73, 0xed, 0x6c, 0xc7, 0xd3, 0x09, 0x2e, 0x97, 0xef, 0xb3, 0x63, 0x4e, 0x9f, 0xc0, 0x9a, + 0x7a, 0x81, 0x9f, 0xa4, 0x4c, 0x2f, 0xfd, 0xf5, 0xb2, 0xfe, 0x97, 0x06, 0x7a, 0x5d, 0x49, 0x96, + 0x1d, 0x21, 0x94, 0x8c, 0x02, 0xf5, 0x81, 0xa8, 0xe9, 0xfb, 0x51, 0x92, 0x33, 0x45, 0x90, 0x42, + 0x67, 0x18, 0x25, 0x79, 0x39, 0x8c, 0xb0, 0x61, 0xc8, 0xcb, 0x7c, 0x3a, 0x1c, 0xe2, 0xcb, 0x95, + 0x26, 0x5e, 0x0f, 0xe9, 0x5f, 0x79, 0xb0, 0x2e, 0xa8, 0x69, 0x5d, 0x61, 0xfc, 0xc2, 0x37, 0xdf, + 0x66, 0x67, 0x68, 0x87, 0x35, 0x1b, 0x30, 0x7f, 0x9c, 0x64, 0x43, 0xa6, 0x56, 0x92, 0x83, 0x9f, + 0x85, 0xa7, 0xfb, 0x4f, 0x1e, 0xac, 0x89, 0xad, 0x1e, 0xf2, 0x80, 0x4f, 0x73, 0x75, 0xfc, 0x5f, + 0x86, 0x2e, 0x1e, 0x95, 0x69, 0xf1, 0x57, 0x1b, 0xdd, 0x30, 0x2f, 0x55, 0x40, 0x25, 0xf2, 0xde, + 0x05, 0xdf, 0x45, 0x26, 0x1f, 0x42, 0xc7, 0xce, 0x11, 0x88, 0x3d, 0xb7, 0x77, 0x2f, 0xe9, 0x53, + 0x56, 0x24, 0x67, 0xef, 0x82, 0xef, 0x7c, 0x40, 0xee, 0x00, 0x08, 0xcb, 0x2c, 0xc8, 0xaa, 0x30, + 0xf0, 0x92, 0xcb, 0x24, 0xeb, 0xb2, 0xf6, 0x2e, 0xf8, 0x16, 0xfa, 0xbd, 0x25, 0x58, 0x90, 0xa6, + 0x84, 0x3e, 0x86, 0xae, 0xb3, 0x53, 0xc7, 0x83, 0xef, 0x48, 0x0f, 0xbe, 0x12, 0xe0, 0x35, 0x6a, + 0x02, 0xbc, 0x7f, 0x6d, 0x00, 0x41, 0x69, 0x2b, 0x5d, 0xe7, 0xdb, 0xb0, 0xac, 0xd8, 0xef, 0x3a, + 0x6f, 0x25, 0xa8, 0xb0, 0x79, 0xc9, 0xc8, 0xf1, 0x60, 0x3a, 0xbe, 0x0d, 0x22, 0x37, 0x81, 0x58, + 0x43, 0x1d, 0xb5, 0x4b, 0x7b, 0x50, 0x33, 0x83, 0x8a, 0x4b, 0xba, 0x1f, 0x3a, 0x5e, 0x55, 0x1e, + 0x5b, 0x53, 0xdc, 0x6f, 0xed, 0x9c, 0x48, 0x26, 0x4d, 0xf3, 0x13, 0xb4, 0xc9, 0xda, 0xc7, 0xd1, + 0xe3, 0xb2, 0x20, 0x2d, 0xbc, 0x56, 0x90, 0x16, 0xcb, 0x82, 0x24, 0x2c, 0x5c, 0x16, 0x9e, 0x06, + 0x9c, 0x69, 0xab, 0xa1, 0x86, 0xe8, 0xd2, 0x4c, 0xc2, 0x58, 0x98, 0xea, 0xc1, 0x04, 0x57, 0x57, + 0x2e, 0x8d, 0x03, 0xa4, 0x3f, 0xf6, 0x60, 0x15, 0x79, 0xec, 0xc8, 0xe1, 0x07, 0x20, 0x9e, 0xc1, + 0x1b, 0x8a, 0xa1, 0x83, 0xfb, 0xd3, 0x4b, 0xe1, 0xfb, 0xd0, 0x12, 0x04, 0x93, 0x94, 0xc5, 0x4a, + 0x08, 0x7b, 0xae, 0x10, 0x16, 0x1a, 0x68, 0xef, 0x82, 0x5f, 0x20, 0x5b, 0x22, 0xf8, 0x0f, 0x1e, + 0xb4, 0xd5, 0x36, 0xff, 0xd7, 0x8e, 0x77, 0x1f, 0x96, 0x50, 0x1a, 0x2d, 0xbf, 0xd6, 0x8c, 0x51, + 0xf3, 0x4f, 0x30, 0xee, 0x41, 0x53, 0xe7, 0x38, 0xdd, 0x65, 0x30, 0xda, 0x2d, 0xa1, 0x6c, 0xf3, + 0x01, 0x0f, 0xa3, 0x81, 0x9e, 0x55, 0xe9, 0xb8, 0xba, 0x29, 0xd4, 0x39, 0x39, 0x0f, 0xc6, 0x4c, + 0x99, 0x24, 0x39, 0xc0, 0xe8, 0x42, 0x1d, 0xa8, 0xec, 0x50, 0xfd, 0x08, 0x60, 0xab, 0x32, 0x65, + 0x9c, 0x2a, 0xe5, 0x47, 0x46, 0xe1, 0xe4, 0x28, 0x31, 0x2e, 0xa9, 0x67, 0xbb, 0x98, 0xce, 0x14, + 0x19, 0xc3, 0x45, 0x6d, 0x7b, 0x91, 0xa7, 0x85, 0xa5, 0x6d, 0x08, 0xa7, 0xe1, 0xb6, 0x2b, 0x03, + 0xe5, 0x05, 0x35, 0xdc, 0x7e, 0xb5, 0xf5, 0xf4, 0xc8, 0x09, 0xf4, 0x8c, 0x91, 0x57, 0xea, 0xdd, + 0x72, 0x04, 0x70, 0xad, 0x77, 0x5f, 0xb3, 0x96, 0xd0, 0x45, 0x23, 0xbd, 0xcc, 0xb9, 0xd4, 0xc8, + 0x0c, 0xae, 0xea, 0x39, 0xa1, 0xbf, 0xab, 0xeb, 0x35, 0xdf, 0xe8, 0x6c, 0x8f, 0xf0, 0x63, 0x77, + 0xd1, 0xd7, 0x10, 0xee, 0xff, 0xc8, 0x83, 0x65, 0x97, 0x1c, 0x8a, 0x8e, 0x8a, 0x4d, 0xb4, 0x82, + 0xd1, 0xce, 0x53, 0x09, 0x5c, 0x8d, 0xae, 0x1a, 0x75, 0xd1, 0x95, 0x1d, 0x43, 0xcd, 0xbd, 0x2e, + 0x86, 0x6a, 0xbe, 0x59, 0x0c, 0x35, 0x5f, 0x17, 0x43, 0xf5, 0xff, 0xcb, 0x03, 0x52, 0xbd, 0x5f, + 0xf2, 0x58, 0x86, 0x77, 0x31, 0x8b, 0x94, 0x9e, 0xf8, 0x85, 0x37, 0x93, 0x11, 0xcd, 0x43, 0xfd, + 0x35, 0x0a, 0xab, 0xad, 0x08, 0x6c, 0x97, 0xa5, 0xeb, 0xd7, 0x4d, 0x95, 0xa2, 0xba, 0xe6, 0xeb, + 0xa3, 0xba, 0xf9, 0xd7, 0x47, 0x75, 0x0b, 0xe5, 0xa8, 0xae, 0xff, 0xdb, 0xd0, 0x75, 0x6e, 0xfd, + 0x67, 0x77, 0xe2, 0xb2, 0xbb, 0x23, 0x2f, 0xd8, 0x81, 0xf5, 0xff, 0xb3, 0x01, 0xa4, 0x2a, 0x79, + 0xff, 0xaf, 0x7b, 0x10, 0x72, 0xe4, 0x28, 0x90, 0x39, 0x25, 0x47, 0x8e, 0xea, 0xf8, 0xbf, 0x54, + 0x8a, 0xef, 0xc2, 0x5a, 0xc6, 0x86, 0xc9, 0x29, 0xcb, 0xac, 0xc8, 0x5a, 0x5e, 0x55, 0x75, 0x02, + 0x1d, 0x3e, 0x37, 0x96, 0x5d, 0x72, 0x2a, 0x08, 0x96, 0x65, 0x28, 0x85, 0xb4, 0xf4, 0xeb, 0xb0, + 0x21, 0x0b, 0x3b, 0xf7, 0x24, 0x29, 0xed, 0x73, 0x5c, 0x87, 0xce, 0x99, 0x4c, 0xe6, 0x0d, 0x92, + 0x38, 0x9a, 0x29, 0x23, 0xd2, 0x56, 0xb0, 0x4f, 0xe2, 0x68, 0x46, 0x7f, 0xe8, 0xc1, 0xc5, 0xd2, + 0xb7, 0x45, 0xce, 0x5e, 0xaa, 0x5a, 0x57, 0xff, 0xba, 0x40, 0x3c, 0xa2, 0x92, 0x71, 0xeb, 0x88, + 0xd2, 0x24, 0x55, 0x27, 0x90, 0x85, 0xd3, 0xb8, 0x8a, 0x2f, 0x2f, 0xa6, 0x6e, 0x8a, 0x6e, 0xc1, + 0x45, 0x75, 0xf9, 0xee, 0xd9, 0xe8, 0x2e, 0x6c, 0x96, 0x27, 0x8a, 0xfc, 0x98, 0xbb, 0x65, 0x3d, + 0xa4, 0x1f, 0x02, 0xf9, 0xe6, 0x94, 0x65, 0x33, 0x51, 0x1d, 0x30, 0x09, 0xd8, 0xad, 0x72, 0x20, + 0xbe, 0x90, 0x4e, 0x8f, 0xbe, 0xc1, 0x66, 0xba, 0xa8, 0xd2, 0x30, 0x45, 0x15, 0x7a, 0x07, 0xd6, + 0x1d, 0x02, 0x86, 0x55, 0x0b, 0xa2, 0xc2, 0xa0, 0x83, 0x54, 0xb7, 0x0a, 0xa1, 0xe6, 0xe8, 0x9f, + 0x7b, 0x30, 0xb7, 0x97, 0xa4, 0x76, 0x66, 0xc9, 0x73, 0x33, 0x4b, 0x4a, 0x77, 0x0e, 0x8c, 0x6a, + 0x6c, 0xa8, 0x97, 0x6f, 0x03, 0x51, 0xf3, 0x05, 0x13, 0x8e, 0x61, 0xda, 0x71, 0x92, 0x9d, 0x05, + 0xd9, 0x48, 0xf1, 0xaf, 0x04, 0xc5, 0xed, 0x17, 0x0a, 0x06, 0x7f, 0xa2, 0xd3, 0x20, 0xd2, 0x6b, + 0x33, 0x15, 0x59, 0xaa, 0x11, 0xfd, 0xbe, 0x07, 0xf3, 0x62, 0xaf, 0xf8, 0x1a, 0xe4, 0xfd, 0x8a, + 0x82, 0x9a, 0xc8, 0xde, 0x79, 0xf2, 0x35, 0x94, 0xc0, 0xa5, 0x32, 0x5b, 0xa3, 0x52, 0x66, 0xbb, + 0x02, 0x2d, 0x39, 0x2a, 0xea, 0x52, 0x05, 0x80, 0x5c, 0x85, 0xe6, 0x49, 0x92, 0x6a, 0x1b, 0x06, + 0x3a, 0x5d, 0x93, 0xa4, 0xbe, 0x80, 0xd3, 0x1b, 0xb0, 0xf2, 0x24, 0x19, 0x31, 0x2b, 0xa6, 0x3f, + 0xf7, 0x9a, 0xe8, 0xef, 0x78, 0xb0, 0xa4, 0x91, 0xc9, 0x36, 0x34, 0xd1, 0x14, 0x95, 0x9c, 0x3f, + 0x93, 0x74, 0x45, 0x3c, 0x5f, 0x60, 0xa0, 0x0a, 0x11, 0x11, 0x64, 0xe1, 0x2a, 0xe8, 0xf8, 0xb1, + 0x30, 0xc2, 0xe8, 0xb4, 0x8b, 0x3d, 0x97, 0x8c, 0x55, 0x09, 0x4a, 0xff, 0xda, 0x83, 0xae, 0xb3, + 0x06, 0xba, 0xf1, 0x51, 0x90, 0x73, 0x95, 0xa8, 0x52, 0x4c, 0xb4, 0x41, 0x76, 0xfe, 0xa7, 0xe1, + 0xe6, 0x7f, 0x4c, 0xfe, 0x61, 0xce, 0xce, 0x3f, 0xdc, 0x82, 0x56, 0x51, 0xb2, 0x6c, 0x3a, 0xaa, + 0x01, 0x57, 0xd4, 0xe9, 0xe4, 0x02, 0x09, 0xe9, 0x0c, 0x93, 0x28, 0xc9, 0x54, 0x45, 0x4f, 0x0e, + 0xe8, 0x1d, 0x68, 0x5b, 0xf8, 0xb8, 0x8d, 0x98, 0xf1, 0xb3, 0x24, 0x7b, 0xa6, 0xd3, 0x50, 0x6a, + 0x68, 0xca, 0x28, 0x8d, 0xa2, 0x8c, 0x42, 0xff, 0xc6, 0x83, 0x2e, 0x4a, 0x4a, 0x18, 0x8f, 0x0f, + 0x92, 0x28, 0x1c, 0xce, 0x84, 0xc4, 0x68, 0xa1, 0x18, 0x8c, 0x58, 0xc4, 0x03, 0x23, 0x31, 0x2e, + 0x18, 0x6d, 0xbe, 0xf6, 0xe2, 0x95, 0xbc, 0x98, 0x31, 0x4a, 0x3e, 0xda, 0xae, 0xa3, 0x20, 0x67, + 0xd2, 0xed, 0x57, 0xba, 0xda, 0x01, 0xa2, 0xfa, 0x40, 0x40, 0x16, 0x70, 0x36, 0x98, 0x84, 0x51, + 0x14, 0x4a, 0x5c, 0x29, 0xe1, 0x75, 0x53, 0xf4, 0x6f, 0x1b, 0xd0, 0x56, 0x6a, 0xe2, 0xe1, 0x68, + 0x2c, 0x33, 0xaa, 0xca, 0x11, 0x31, 0xcf, 0xcf, 0x82, 0xe8, 0x79, 0xc7, 0x75, 0xb1, 0x20, 0xe5, + 0x6b, 0x9d, 0xab, 0x5e, 0xeb, 0x15, 0x68, 0xa1, 0x78, 0xdd, 0x16, 0x3e, 0x92, 0xac, 0x70, 0x17, + 0x00, 0x3d, 0xbb, 0x2b, 0x66, 0xe7, 0x8b, 0x59, 0x01, 0x70, 0xbc, 0xa2, 0x85, 0x92, 0x57, 0xf4, + 0x3e, 0x74, 0x14, 0x19, 0xc1, 0x77, 0x11, 0x54, 0x15, 0x02, 0xee, 0xdc, 0x89, 0xef, 0x60, 0xea, + 0x2f, 0x77, 0xf5, 0x97, 0x4b, 0xaf, 0xfb, 0x52, 0x63, 0xd2, 0x8b, 0xb0, 0xae, 0x98, 0xf7, 0x38, + 0x0b, 0xd2, 0x13, 0xad, 0x7a, 0x47, 0xa6, 0x8c, 0x2a, 0xc0, 0xe4, 0x06, 0xcc, 0xe3, 0x67, 0x5a, + 0xfb, 0xd5, 0x3f, 0x3a, 0x89, 0x42, 0xb6, 0x61, 0x9e, 0x8d, 0xc6, 0x4c, 0x7b, 0xe6, 0xc4, 0x8d, + 0x91, 0xf0, 0x8e, 0x7c, 0x89, 0x80, 0x2a, 0x00, 0xa1, 0x25, 0x15, 0xe0, 0x6a, 0xce, 0x05, 0x1c, + 0x7e, 0x34, 0xa2, 0x1b, 0x40, 0x9e, 0x48, 0xa9, 0xb5, 0xb3, 0x80, 0xbf, 0x37, 0x07, 0x6d, 0x0b, + 0x8c, 0xaf, 0x79, 0x8c, 0x1b, 0x1e, 0x8c, 0xc2, 0x60, 0xc2, 0x38, 0xcb, 0x94, 0xa4, 0x96, 0xa0, + 0x42, 0xc1, 0x9e, 0x8e, 0x07, 0xc9, 0x94, 0x0f, 0x46, 0x6c, 0x9c, 0x31, 0x69, 0xd0, 0x3c, 0xbf, + 0x04, 0x45, 0xbc, 0x49, 0xf0, 0xdc, 0xc6, 0x93, 0xf2, 0x50, 0x82, 0xea, 0x9c, 0x9e, 0xe4, 0x51, + 0xb3, 0xc8, 0xe9, 0x49, 0x8e, 0x94, 0xf5, 0xd0, 0x7c, 0x8d, 0x1e, 0x7a, 0x0f, 0x36, 0xa5, 0xc6, + 0x51, 0x6f, 0x73, 0x50, 0x12, 0x93, 0x73, 0x66, 0xc9, 0x0d, 0x58, 0xc5, 0x3d, 0x6b, 0x01, 0xcf, + 0xc3, 0xef, 0xca, 0x68, 0xdc, 0xf3, 0x2b, 0x70, 0xc4, 0xc5, 0xe7, 0xe8, 0xe0, 0xca, 0x92, 0x43, + 0x05, 0x2e, 0x70, 0x83, 0xe7, 0x2e, 0x6e, 0x4b, 0xe1, 0x96, 0xe0, 0xb4, 0x0b, 0xed, 0x43, 0x9e, + 0xa4, 0xfa, 0x52, 0x96, 0xa1, 0x23, 0x87, 0xaa, 0xcc, 0x74, 0x19, 0x2e, 0x09, 0x29, 0x7a, 0x9a, + 0xa4, 0x49, 0x94, 0x8c, 0x67, 0x87, 0xd3, 0xa3, 0x7c, 0x98, 0x85, 0x29, 0x7a, 0xcc, 0xf4, 0xef, + 0x3d, 0x58, 0x77, 0x66, 0x55, 0xa8, 0xff, 0x8b, 0x52, 0xa4, 0x4d, 0x65, 0x40, 0x0a, 0xde, 0x9a, + 0xa5, 0x0e, 0x25, 0xa2, 0x4c, 0x9c, 0x7c, 0xaa, 0x8a, 0x05, 0x77, 0x61, 0x45, 0xef, 0x4c, 0x7f, + 0x28, 0xa5, 0xb0, 0x57, 0x95, 0x42, 0xf5, 0xfd, 0xb2, 0xfa, 0x40, 0x93, 0xf8, 0x15, 0xe9, 0x77, + 0xb2, 0x91, 0x38, 0xa3, 0x8e, 0xf9, 0xfa, 0xfa, 0x7b, 0xdb, 0xd9, 0xd5, 0x3b, 0x18, 0x1a, 0x60, + 0x4e, 0xff, 0xc8, 0x03, 0x28, 0x76, 0x87, 0x82, 0x51, 0xa8, 0x74, 0x4f, 0xe4, 0x4c, 0x2d, 0xf5, + 0x7d, 0x1d, 0x3a, 0x26, 0x33, 0x5d, 0x58, 0x89, 0xb6, 0x86, 0xa1, 0x87, 0xf2, 0x0e, 0xac, 0x8c, + 0xa3, 0xe4, 0x48, 0xd8, 0x5c, 0x51, 0xd1, 0xcc, 0x55, 0xb1, 0x6d, 0x59, 0x82, 0x1f, 0x29, 0x68, + 0x61, 0x52, 0x9a, 0x96, 0x49, 0xa1, 0x7f, 0xdc, 0x30, 0xf9, 0xd1, 0xe2, 0xcc, 0xe7, 0xbe, 0x32, + 0xb2, 0x5b, 0x51, 0x8e, 0xe7, 0xa4, 0x23, 0x45, 0x76, 0xe3, 0xe0, 0xb5, 0x81, 0xde, 0x1d, 0x58, + 0xce, 0xa4, 0xf6, 0xd1, 0xaa, 0xa9, 0xf9, 0x0a, 0xd5, 0xd4, 0xcd, 0x1c, 0xbb, 0xf3, 0x73, 0xb0, + 0x1a, 0x8c, 0x4e, 0x59, 0xc6, 0x43, 0xe1, 0xf1, 0x0b, 0xa3, 0x2f, 0x15, 0xea, 0x8a, 0x05, 0x17, + 0xb6, 0xf8, 0x1d, 0x58, 0x51, 0x05, 0x4e, 0x83, 0xa9, 0xfa, 0x56, 0x0a, 0x30, 0x22, 0xd2, 0xbf, + 0xd4, 0xa9, 0x58, 0xf7, 0x0e, 0xcf, 0xe7, 0x88, 0x7d, 0xba, 0x46, 0xe9, 0x74, 0x5f, 0x51, 0x69, + 0xd1, 0x91, 0x0e, 0x2b, 0x54, 0x82, 0x5a, 0x02, 0x55, 0x1a, 0xdb, 0x65, 0x69, 0xf3, 0x4d, 0x58, + 0x4a, 0x7f, 0x38, 0x07, 0x8b, 0x1f, 0xc5, 0xa7, 0x49, 0x38, 0x14, 0x49, 0xca, 0x09, 0x9b, 0x24, + 0xba, 0xcd, 0x00, 0x7f, 0xa3, 0x45, 0x17, 0x15, 0xb4, 0x94, 0xab, 0xec, 0xa1, 0x1e, 0xa2, 0x75, + 0xcb, 0x8a, 0xd6, 0x1a, 0x29, 0x29, 0x16, 0x04, 0xfd, 0xc3, 0xcc, 0xee, 0x16, 0x52, 0xa3, 0xa2, + 0x4f, 0x63, 0xde, 0xea, 0xd3, 0x10, 0x29, 0x6d, 0x59, 0x1c, 0x14, 0xec, 0x5c, 0xf2, 0xf5, 0x50, + 0xf8, 0xb1, 0x19, 0x93, 0x41, 0xaf, 0xb0, 0x93, 0x8b, 0xca, 0x8f, 0xb5, 0x81, 0x68, 0x4b, 0xe5, + 0x07, 0x12, 0x47, 0xea, 0x1a, 0x1b, 0x84, 0xbe, 0x45, 0xb9, 0xe1, 0xa8, 0x25, 0xaf, 0xb8, 0x04, + 0x46, 0x85, 0x34, 0x62, 0x46, 0x6f, 0xc8, 0x33, 0x80, 0x6c, 0x1d, 0x2a, 0xc3, 0x2d, 0x2f, 0x58, + 0x16, 0x39, 0xd5, 0x48, 0xf8, 0x20, 0x41, 0x14, 0x1d, 0x05, 0xc3, 0x67, 0xa2, 0x0d, 0x4c, 0xd4, + 0x34, 0x5b, 0xbe, 0x0b, 0xc4, 0x5d, 0x0f, 0x23, 0x7e, 0x3a, 0x50, 0x24, 0xba, 0xb2, 0x26, 0x69, + 0x81, 0xe8, 0x67, 0x40, 0xee, 0x8e, 0x46, 0xea, 0x86, 0x4c, 0x8c, 0x50, 0xf0, 0xd6, 0x73, 0x78, + 0x5b, 0x73, 0xc6, 0x46, 0xed, 0x19, 0xe9, 0x43, 0x68, 0x1f, 0x58, 0xdd, 0x5b, 0xe2, 0x32, 0x75, + 0xdf, 0x96, 0x12, 0x00, 0x0b, 0x62, 0x2d, 0xd8, 0xb0, 0x17, 0xa4, 0xbf, 0x04, 0x64, 0x3f, 0xcc, + 0xb9, 0xd9, 0x9f, 0x09, 0x15, 0x4d, 0xc6, 0xcb, 0x0a, 0x15, 0x15, 0x4c, 0x84, 0x8a, 0x77, 0x65, + 0x69, 0xb4, 0x7c, 0xb0, 0x1b, 0xb0, 0x14, 0x4a, 0x90, 0xd6, 0xc3, 0xcb, 0x4a, 0x80, 0x35, 0xa6, + 0x99, 0x47, 0x87, 0x42, 0x01, 0x1d, 0x35, 0xff, 0x7d, 0x0f, 0x16, 0xd5, 0xd1, 0xd0, 0x1c, 0x3a, + 0x7d, 0x6b, 0xf2, 0x60, 0x0e, 0xac, 0xbe, 0x6f, 0xa8, 0x2a, 0x75, 0x73, 0x75, 0x52, 0x47, 0xa0, + 0x99, 0x06, 0xfc, 0x44, 0x78, 0xd0, 0x2d, 0x5f, 0xfc, 0xd6, 0x91, 0xd2, 0xbc, 0x89, 0x94, 0x74, + 0x19, 0x58, 0x6d, 0xca, 0x64, 0x2d, 0xef, 0xc9, 0x32, 0x70, 0x01, 0x2e, 0x78, 0xa0, 0x36, 0x58, + 0xe6, 0x81, 0x42, 0xf5, 0xcd, 0x3c, 0xed, 0x43, 0xef, 0x01, 0x8b, 0x18, 0x67, 0x77, 0xa3, 0xa8, + 0x4c, 0xff, 0x32, 0x5c, 0xaa, 0x99, 0x53, 0x96, 0xf2, 0x11, 0xac, 0x3d, 0x60, 0x47, 0xd3, 0xf1, + 0x3e, 0x3b, 0x2d, 0xca, 0x0a, 0x04, 0x9a, 0xf9, 0x49, 0x72, 0xa6, 0xee, 0x4b, 0xfc, 0x26, 0x5f, + 0x02, 0x88, 0x10, 0x67, 0x90, 0xa7, 0x6c, 0xa8, 0x9b, 0x5e, 0x04, 0xe4, 0x30, 0x65, 0x43, 0xfa, + 0x1e, 0x10, 0x9b, 0x8e, 0x3a, 0x02, 0xbe, 0xc6, 0xe9, 0xd1, 0x20, 0x9f, 0xe5, 0x9c, 0x4d, 0x74, + 0x37, 0x8f, 0x0d, 0xa2, 0xef, 0x40, 0xe7, 0x20, 0x98, 0xf9, 0xec, 0x0b, 0xd5, 0x0e, 0x88, 0x01, + 0x59, 0x30, 0x43, 0xf1, 0x34, 0x01, 0x99, 0x98, 0xa6, 0x7f, 0xd7, 0x80, 0x05, 0x89, 0x89, 0x54, + 0x47, 0x2c, 0xe7, 0x61, 0x2c, 0xd3, 0xea, 0x8a, 0xaa, 0x05, 0xaa, 0xdc, 0x77, 0xa3, 0xe6, 0xbe, + 0x95, 0x8b, 0xa4, 0x1b, 0x04, 0xd4, 0xc5, 0x3a, 0x30, 0x11, 0x6f, 0x86, 0x13, 0x26, 0xbb, 0x42, + 0x9b, 0x2a, 0xde, 0xd4, 0x80, 0x52, 0xe4, 0x5b, 0xbc, 0x79, 0xb9, 0x3f, 0x2d, 0x88, 0xca, 0x2c, + 0xd8, 0xa0, 0x5a, 0xcd, 0xb2, 0x28, 0xfb, 0xff, 0x2a, 0x9a, 0xa5, 0xa2, 0x41, 0x96, 0xde, 0x40, + 0x83, 0x48, 0xbf, 0xc9, 0xd1, 0x20, 0x04, 0x56, 0x1f, 0x31, 0xe6, 0xb3, 0x34, 0xc9, 0x4c, 0x4f, + 0xe5, 0x0f, 0x3c, 0x58, 0x55, 0x16, 0xc1, 0xcc, 0x91, 0xeb, 0x8e, 0xf9, 0xf0, 0xea, 0x32, 0xad, + 0x6f, 0x41, 0x57, 0x04, 0x50, 0x18, 0x1d, 0x89, 0x68, 0x49, 0xe5, 0x14, 0x1c, 0x20, 0xee, 0x49, + 0xe7, 0x0e, 0x27, 0x61, 0xa4, 0x18, 0x6c, 0x83, 0xd0, 0xd4, 0xe9, 0x00, 0x4b, 0xb0, 0xd7, 0xf3, + 0xcd, 0x98, 0x1e, 0xc0, 0x9a, 0xb5, 0x5f, 0x25, 0x50, 0x77, 0x40, 0x57, 0x25, 0x65, 0x8a, 0x40, + 0xbe, 0x8b, 0x2d, 0xd7, 0xb8, 0x15, 0x9f, 0x39, 0xc8, 0xf4, 0x9f, 0x3d, 0x58, 0x97, 0x86, 0x5e, + 0xb9, 0x51, 0xa6, 0x91, 0x69, 0x41, 0x7a, 0x36, 0x52, 0xe0, 0xf7, 0x2e, 0xf8, 0x6a, 0x4c, 0xbe, + 0xf6, 0x86, 0xce, 0x89, 0x29, 0x00, 0x9e, 0xc3, 0x9e, 0xb9, 0x3a, 0xf6, 0xbc, 0xe2, 0xf0, 0x75, + 0x01, 0xf0, 0x7c, 0x6d, 0x00, 0x7c, 0x6f, 0x11, 0xe6, 0xf3, 0x61, 0x92, 0x32, 0xba, 0x09, 0x1b, + 0xee, 0xe1, 0x24, 0xcb, 0x76, 0xff, 0xc5, 0x83, 0x65, 0x99, 0x8c, 0x93, 0xdd, 0xda, 0x2c, 0x23, + 0x18, 0x6b, 0x59, 0x4d, 0xe0, 0xc4, 0xb8, 0x9a, 0xd5, 0x66, 0xf2, 0xfe, 0xe5, 0xda, 0x39, 0xed, + 0x67, 0x7f, 0xef, 0xc7, 0xff, 0xfe, 0x27, 0x8d, 0x8b, 0x74, 0x75, 0xe7, 0xf4, 0xf6, 0x8e, 0x50, + 0x89, 0xec, 0x4c, 0x60, 0x7c, 0xe0, 0xdd, 0xc0, 0x55, 0xec, 0xfe, 0x70, 0xb3, 0x4a, 0x4d, 0x9f, + 0xb9, 0x59, 0xa5, 0xb6, 0xa1, 0xdc, 0x59, 0x65, 0x2a, 0x30, 0xcc, 0x2a, 0xbb, 0xff, 0xdd, 0x87, + 0x96, 0x09, 0x0a, 0xc9, 0x77, 0xa0, 0xeb, 0x24, 0x1e, 0x89, 0x26, 0x5c, 0x97, 0xca, 0xec, 0x5f, + 0xa9, 0x9f, 0x54, 0xcb, 0x5e, 0x15, 0xcb, 0xf6, 0xc8, 0x26, 0x2e, 0xab, 0xb2, 0x7d, 0x3b, 0x22, + 0x23, 0x2b, 0x3b, 0x19, 0x9e, 0xc1, 0xb2, 0x9b, 0x2c, 0x24, 0x57, 0x5c, 0xd1, 0x28, 0xad, 0xf6, + 0xa5, 0x73, 0x66, 0xd5, 0x72, 0x57, 0xc4, 0x72, 0x9b, 0x64, 0xc3, 0x5e, 0xce, 0x04, 0x6b, 0x4c, + 0xf4, 0x9e, 0xd8, 0x8d, 0xe3, 0x44, 0xd3, 0xab, 0x6f, 0x28, 0xef, 0x5f, 0xaa, 0x36, 0x89, 0xab, + 0xae, 0x72, 0xda, 0x13, 0x4b, 0x11, 0x22, 0x18, 0x6a, 0xf7, 0x8d, 0x93, 0x6f, 0x43, 0xcb, 0xb4, + 0x9d, 0x92, 0x2d, 0xab, 0xd7, 0xd7, 0xee, 0x85, 0xed, 0xf7, 0xaa, 0x13, 0x75, 0x57, 0x65, 0x53, + 0x46, 0x81, 0xd8, 0x87, 0x8b, 0xca, 0x42, 0x1f, 0xb1, 0x9f, 0xe4, 0x24, 0x35, 0xed, 0xee, 0xb7, + 0x3c, 0x72, 0x07, 0x96, 0x74, 0x37, 0x2f, 0xd9, 0xac, 0xef, 0x4a, 0xee, 0x6f, 0x55, 0xe0, 0x4a, + 0x8f, 0xdc, 0x05, 0x28, 0x1a, 0x4f, 0x49, 0xef, 0xbc, 0xfe, 0x58, 0xc3, 0xc4, 0x9a, 0x2e, 0xd5, + 0xb1, 0xe8, 0xbb, 0x75, 0xfb, 0x5a, 0xc9, 0x97, 0x0b, 0xfc, 0xda, 0x8e, 0xd7, 0x57, 0x10, 0xa4, + 0x9b, 0x82, 0x77, 0xab, 0x64, 0x19, 0x79, 0x17, 0xb3, 0x33, 0xdd, 0x85, 0xf5, 0x00, 0xda, 0x56, + 0x33, 0x2b, 0xd1, 0x14, 0xaa, 0x8d, 0xb0, 0xfd, 0x7e, 0xdd, 0x94, 0xda, 0xee, 0xaf, 0x41, 0xd7, + 0xe9, 0x4a, 0x35, 0x2f, 0xa3, 0xae, 0xe7, 0xd5, 0xbc, 0x8c, 0xfa, 0x46, 0xd6, 0x6f, 0x41, 0xdb, + 0xea, 0x21, 0x25, 0x56, 0x45, 0xbb, 0xd4, 0x23, 0x6a, 0x76, 0x54, 0xd3, 0x72, 0x4a, 0x37, 0xc4, + 0x79, 0x97, 0x69, 0x0b, 0xcf, 0x2b, 0x5a, 0x91, 0x50, 0x48, 0xbe, 0x03, 0xcb, 0x6e, 0xef, 0xa8, + 0x79, 0x55, 0xb5, 0x5d, 0xa8, 0xe6, 0x55, 0x9d, 0xd3, 0x70, 0xaa, 0x04, 0xf2, 0xc6, 0xba, 0x59, + 0x64, 0xe7, 0x85, 0x4a, 0x89, 0xbe, 0x24, 0xdf, 0x44, 0xd5, 0xa1, 0x7a, 0xc3, 0x48, 0xd1, 0x4b, + 0xeb, 0x76, 0x90, 0x19, 0x69, 0xaf, 0xb4, 0x91, 0xd1, 0x35, 0x41, 0xbc, 0x4d, 0x8a, 0x13, 0x90, + 0x8f, 0x61, 0x51, 0xf5, 0x88, 0x91, 0x8b, 0x85, 0x54, 0x5b, 0x09, 0xa4, 0xfe, 0x66, 0x19, 0xac, + 0x88, 0xad, 0x0b, 0x62, 0x5d, 0xd2, 0x46, 0x62, 0x63, 0xc6, 0x43, 0xa4, 0x11, 0xc3, 0x4a, 0xa9, + 0x8a, 0x65, 0x1e, 0x4b, 0x7d, 0x0d, 0xbc, 0x7f, 0xf5, 0xd5, 0xc5, 0x2f, 0x57, 0xcd, 0x68, 0xf5, + 0xb2, 0xa3, 0x5b, 0x16, 0x7e, 0x13, 0x3a, 0x76, 0x4b, 0xa2, 0xd1, 0xd9, 0x35, 0xed, 0x8b, 0x46, + 0x67, 0xd7, 0xf5, 0x30, 0xea, 0xcb, 0x25, 0x1d, 0x7b, 0x19, 0xf2, 0x2d, 0x58, 0xb1, 0xea, 0xa5, + 0x87, 0xb3, 0x78, 0x68, 0x84, 0xa7, 0xda, 0xdd, 0xd2, 0xaf, 0xb3, 0xb4, 0x74, 0x4b, 0x10, 0x5e, + 0xa3, 0x0e, 0x61, 0x14, 0x9c, 0xfb, 0xd0, 0xb6, 0x6b, 0xb1, 0xaf, 0xa0, 0xbb, 0x65, 0x4d, 0xd9, + 0xcd, 0x1e, 0xb7, 0x3c, 0xf2, 0x67, 0x1e, 0x74, 0xec, 0xbe, 0x29, 0xe2, 0x64, 0x61, 0x4a, 0x74, + 0x7a, 0xf6, 0x9c, 0x4d, 0x88, 0x3e, 0x11, 0x9b, 0xdc, 0xbb, 0xf1, 0xc8, 0x61, 0xf2, 0x0b, 0xc7, + 0x89, 0xba, 0x69, 0xff, 0xd3, 0xe3, 0x65, 0x79, 0xd2, 0xee, 0xfe, 0x79, 0x79, 0xcb, 0x23, 0x1f, + 0xc8, 0xff, 0xf3, 0xe8, 0x80, 0x86, 0x58, 0x8a, 0xad, 0xcc, 0x2e, 0xfb, 0x4f, 0x32, 0xdb, 0xde, + 0x2d, 0x8f, 0xfc, 0x96, 0xfc, 0x73, 0x87, 0xfa, 0x56, 0x70, 0xfd, 0x4d, 0xbf, 0xa7, 0x6f, 0x89, + 0x93, 0x5c, 0xa5, 0x97, 0x9c, 0x93, 0x94, 0x35, 0xfb, 0x01, 0x40, 0x11, 0x9d, 0x92, 0x52, 0xa8, + 0x66, 0x74, 0x5e, 0x35, 0x80, 0x75, 0x6f, 0x53, 0x47, 0x74, 0x52, 0x0d, 0x74, 0xac, 0xb8, 0x30, + 0x37, 0xd7, 0x59, 0x8d, 0x32, 0xfb, 0xfd, 0xba, 0x29, 0x45, 0xff, 0x2b, 0x82, 0xfe, 0x97, 0xc8, + 0x65, 0x9b, 0xfe, 0xce, 0x0b, 0x3b, 0x2a, 0x7d, 0x49, 0x3e, 0x83, 0xee, 0x7e, 0x92, 0x3c, 0x9b, + 0xa6, 0x26, 0x01, 0xe2, 0xc6, 0x59, 0x18, 0x19, 0xf7, 0x4b, 0x87, 0xa2, 0xd7, 0x05, 0xe5, 0xcb, + 0xe4, 0x92, 0x4b, 0xb9, 0x88, 0x95, 0x5f, 0x92, 0x00, 0xd6, 0x8c, 0xbd, 0x33, 0x07, 0xe9, 0xbb, + 0x74, 0xec, 0x90, 0xb5, 0xb2, 0x86, 0xe3, 0x81, 0x98, 0x35, 0x72, 0x4d, 0xf3, 0x96, 0x47, 0x0e, + 0xa0, 0xf3, 0x80, 0x0d, 0x93, 0x11, 0x53, 0xa1, 0xd1, 0x7a, 0xb1, 0x73, 0x13, 0x53, 0xf5, 0xbb, + 0x0e, 0xd0, 0xd5, 0x00, 0x69, 0x30, 0xcb, 0xd8, 0x17, 0x3b, 0x2f, 0x54, 0xd0, 0xf5, 0x52, 0x6b, + 0x00, 0x1d, 0x28, 0x3a, 0x1a, 0xa0, 0x14, 0x59, 0x3a, 0x1a, 0xa0, 0x12, 0x59, 0x3a, 0x1a, 0x40, + 0x07, 0xaa, 0x24, 0xc2, 0x78, 0xb3, 0x14, 0x8c, 0x1a, 0xab, 0x79, 0x5e, 0x08, 0xdb, 0xbf, 0x76, + 0x3e, 0x82, 0xbb, 0xda, 0x0d, 0x77, 0xb5, 0x43, 0xe8, 0x3e, 0x60, 0x92, 0x59, 0xb2, 0xaa, 0xd0, + 0x77, 0x55, 0x8a, 0x5d, 0x81, 0x28, 0xab, 0x1b, 0x31, 0xe7, 0xaa, 0x78, 0x91, 0xd2, 0x27, 0xdf, + 0x86, 0xf6, 0x63, 0xc6, 0x75, 0x19, 0xc1, 0xf8, 0x1e, 0xa5, 0xba, 0x42, 0xbf, 0xa6, 0x0a, 0x41, + 0xaf, 0x09, 0x6a, 0x7d, 0xd2, 0x33, 0xd4, 0x76, 0xd8, 0x68, 0xcc, 0xe4, 0xe3, 0x1f, 0x84, 0xa3, + 0x97, 0xe4, 0xd7, 0x05, 0x71, 0x53, 0x79, 0xdc, 0xb4, 0xb2, 0xcf, 0x36, 0xf1, 0x95, 0x12, 0xbc, + 0x8e, 0x72, 0x9c, 0x8c, 0x98, 0x65, 0xec, 0x62, 0x68, 0x5b, 0x65, 0x66, 0xf3, 0xa0, 0xaa, 0xb5, + 0x6b, 0xf3, 0xa0, 0x6a, 0xaa, 0xd2, 0x74, 0x5b, 0xac, 0x43, 0xc9, 0xb5, 0x62, 0x1d, 0x59, 0x89, + 0x2e, 0x56, 0xda, 0x79, 0x11, 0x4c, 0xf8, 0x4b, 0xf2, 0xb9, 0x68, 0xa0, 0xb6, 0x4b, 0x25, 0x85, + 0xef, 0x53, 0xae, 0xaa, 0x18, 0x66, 0x59, 0x53, 0xae, 0x3f, 0x24, 0x97, 0x12, 0x36, 0xf1, 0x6b, + 0x00, 0x87, 0x3c, 0x49, 0x1f, 0x04, 0x6c, 0x92, 0xc4, 0x85, 0x26, 0x2b, 0xca, 0x01, 0x85, 0x26, + 0xb3, 0x6a, 0x02, 0xe4, 0x73, 0xcb, 0xfb, 0x74, 0x2a, 0x4d, 0x5a, 0xb8, 0xce, 0xad, 0x18, 0x18, + 0x86, 0xd4, 0x54, 0x0d, 0x6e, 0x79, 0xe8, 0x4b, 0x16, 0xa9, 0x0f, 0xe3, 0x4b, 0x56, 0xb2, 0x2a, + 0x46, 0x0d, 0xd6, 0xe4, 0x49, 0x0e, 0xa0, 0x55, 0xc4, 0xdf, 0xda, 0x3c, 0x95, 0xa3, 0x75, 0x63, + 0x6f, 0x2a, 0x61, 0x31, 0x5d, 0x15, 0xac, 0x02, 0xb2, 0x84, 0xac, 0x12, 0x95, 0xf2, 0x21, 0xac, + 0xcb, 0x0d, 0x1a, 0xe3, 0x29, 0x12, 0xdc, 0xfa, 0x24, 0x35, 0x61, 0xb0, 0x79, 0xcd, 0x75, 0x51, + 0xa4, 0xf6, 0x4e, 0xa8, 0x59, 0xe1, 0x03, 0xef, 0xc6, 0xd1, 0x82, 0xf8, 0x1b, 0xf2, 0x57, 0xff, + 0x27, 0x00, 0x00, 0xff, 0xff, 0x33, 0xf0, 0xc8, 0xda, 0xb8, 0x3c, 0x00, 0x00, } diff --git a/lnrpc/rpc.proto b/lnrpc/rpc.proto index 6fca5c07f..9acf51229 100644 --- a/lnrpc/rpc.proto +++ b/lnrpc/rpc.proto @@ -877,6 +877,9 @@ message OpenChannelRequest { /// Whether this channel should be private, not announced to the greater network. bool private = 8 [json_name = "private"]; + + /// The minimum value in millisatoshi we will require for incoming HTLCs on the channel. + int64 min_htlc_msat = 9 [json_name = "min_htlc_msat"]; } message OpenStatusUpdate { oneof update { diff --git a/lnrpc/rpc.swagger.json b/lnrpc/rpc.swagger.json index aecdc2cf7..a5cf060f3 100644 --- a/lnrpc/rpc.swagger.json +++ b/lnrpc/rpc.swagger.json @@ -1589,6 +1589,11 @@ "type": "boolean", "format": "boolean", "description": "/ Whether this channel should be private, not announced to the greater network." + }, + "min_htlc_msat": { + "type": "string", + "format": "int64", + "description": "/ The minimum value in millisatoshi we will require for incoming HTLCs on the channel." } } }, From 59b331c04d38b84c88992539397e9d8f851588cc Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Sat, 16 Dec 2017 23:57:31 +0100 Subject: [PATCH 08/25] lncli: add min_htlc_msat to openchannel --- cmd/lncli/commands.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cmd/lncli/commands.go b/cmd/lncli/commands.go index 94d511ed5..5e553b3d7 100644 --- a/cmd/lncli/commands.go +++ b/cmd/lncli/commands.go @@ -431,6 +431,11 @@ var openChannelCommand = cli.Command{ "must be explicitly told about it to be able " + "to route through it", }, + cli.Int64Flag{ + Name: "min_htlc_msat", + Usage: "(optional) the minimum value we will require " + + "for incoming HTLCs on the channel", + }, }, Action: actionDecorator(openChannel), } @@ -456,8 +461,9 @@ func openChannel(ctx *cli.Context) error { } req := &lnrpc.OpenChannelRequest{ - TargetConf: int32(ctx.Int64("conf_target")), - SatPerByte: ctx.Int64("sat_per_byte"), + TargetConf: int32(ctx.Int64("conf_target")), + SatPerByte: ctx.Int64("sat_per_byte"), + MinHtlcMsat: ctx.Int64("min_htlc_msat"), } switch { From 84e5adcdd070cd7cb5652f2f355132569bd3cc1d Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Sun, 17 Dec 2017 00:00:37 +0100 Subject: [PATCH 09/25] server: add min_htlc_msat parameter to OpenChannel method --- server.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server.go b/server.go index 7d9f1dd06..163c6c97b 100644 --- a/server.go +++ b/server.go @@ -1495,6 +1495,8 @@ type openChanReq struct { private bool + minHtlc lnwire.MilliSatoshi + // TODO(roasbeef): add ability to specify channel constraints as well updates chan *lnrpc.OpenStatusUpdate @@ -1612,6 +1614,7 @@ func (s *server) DisconnectPeer(pubKey *btcec.PublicKey) error { // NOTE: This function is safe for concurrent access. func (s *server) OpenChannel(peerID int32, nodeKey *btcec.PublicKey, localAmt btcutil.Amount, pushAmt lnwire.MilliSatoshi, + minHtlc lnwire.MilliSatoshi, fundingFeePerByte btcutil.Amount, private bool) (chan *lnrpc.OpenStatusUpdate, chan error) { @@ -1674,6 +1677,7 @@ func (s *server) OpenChannel(peerID int32, nodeKey *btcec.PublicKey, fundingFeePerWeight: fundingFeePerWeight, pushAmt: pushAmt, private: private, + minHtlc: minHtlc, updates: updateChan, err: errChan, } From f3dff2ae974f0616bc838d5f7140032aef0be8c3 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Sun, 17 Dec 2017 00:00:11 +0100 Subject: [PATCH 10/25] rpcserver: add min_htlc_msat parameter to OpenChannel and OpenChannelSync --- rpcserver.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rpcserver.go b/rpcserver.go index 0f6495b87..744690e06 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -551,6 +551,7 @@ func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest, localFundingAmt := btcutil.Amount(in.LocalFundingAmount) remoteInitialBalance := btcutil.Amount(in.PushSat) + minHtlc := lnwire.MilliSatoshi(in.MinHtlcMsat) // Ensure that the initial balance of the remote party (if pushing // satoshis) does not exceed the amount the local party has requested @@ -627,7 +628,7 @@ func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest, updateChan, errChan := r.server.OpenChannel( in.TargetPeerId, nodePubKey, localFundingAmt, lnwire.NewMSatFromSatoshis(remoteInitialBalance), - feePerByte, in.Private, + minHtlc, feePerByte, in.Private, ) var outpoint wire.OutPoint @@ -722,6 +723,7 @@ func (r *rpcServer) OpenChannelSync(ctx context.Context, localFundingAmt := btcutil.Amount(in.LocalFundingAmount) remoteInitialBalance := btcutil.Amount(in.PushSat) + minHtlc := lnwire.MilliSatoshi(in.MinHtlcMsat) // Ensure that the initial balance of the remote party (if pushing // satoshis) does not exceed the amount the local party has requested @@ -746,7 +748,7 @@ func (r *rpcServer) OpenChannelSync(ctx context.Context, updateChan, errChan := r.server.OpenChannel( in.TargetPeerId, nodepubKey, localFundingAmt, lnwire.NewMSatFromSatoshis(remoteInitialBalance), - feePerByte, in.Private, + minHtlc, feePerByte, in.Private, ) select { From 7805a53c34d15f46bd485e3b60c817a7232ffd7b Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Sun, 17 Dec 2017 00:01:08 +0100 Subject: [PATCH 11/25] pilot: pass minHtlc = 1 satoshi to OpenChannel --- pilot.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pilot.go b/pilot.go index ad239ef63..82abe7ef0 100644 --- a/pilot.go +++ b/pilot.go @@ -89,8 +89,12 @@ func (c *chanController) OpenChannel(target *btcec.PublicKey, if err != nil { return err } + + // TODO(halseth): make configurable? + minHtlc := lnwire.NewMSatFromSatoshis(1) + updateStream, errChan := c.server.OpenChannel(-1, target, amt, 0, - feePerWeight, false) + minHtlc, feePerWeight, false) select { case err := <-errChan: From 79a6efe33f6191936573cb692d97863a39ff81e4 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Sun, 17 Dec 2017 00:01:38 +0100 Subject: [PATCH 12/25] fundingmanager: use minHtlc from initFundingMsg This commit makes the fundingmanager read the minHtlc field of the initFundingMsg, and add it to the reservation as this node's htlc_minimum_msat for the open_channel message. If the field is not specified in the initFundingMsg, the default value found in the DefaultRoutingPolicy will be used. --- fundingmanager.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/fundingmanager.go b/fundingmanager.go index b64b8854f..75ba76d60 100644 --- a/fundingmanager.go +++ b/fundingmanager.go @@ -2101,6 +2101,8 @@ func (f *fundingManager) newChanAnnouncement(localPubKey, remotePubKey *btcec.Pu chanFlags = 1 } + // We announce the channel with the default values. Some of + // these values can later be changed by crafting a new ChannelUpdate. chanUpdateAnn := &lnwire.ChannelUpdate{ ShortChannelID: shortChanID, ChainHash: chainHash, @@ -2252,6 +2254,7 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) { remoteAmt = msg.remoteFundingAmt capacity = localAmt + remoteAmt ourDustLimit = lnwallet.DefaultDustLimit() + minHtlc = msg.minHtlc ) fndgLog.Infof("Initiating fundingRequest(localAmt=%v, remoteAmt=%v, "+ @@ -2321,9 +2324,14 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) { // delay we require given the total amount of funds within the channel. remoteCsvDelay := f.cfg.RequiredRemoteDelay(capacity) + // If no minimum HTLC value was specified, use the default one. + if minHtlc == 0 { + minHtlc = f.cfg.DefaultRoutingPolicy.MinHTLC + } + // Once the reservation has been created, and indexed, queue a funding // request to the remote peer, kicking off the funding workflow. - reservation.RegisterMinHTLC(f.cfg.DefaultRoutingPolicy.MinHTLC) + reservation.RegisterMinHTLC(minHtlc) ourContribution := reservation.OurContribution() // Finally, we'll use the current value of the channels and our default From f4feb1e6975d4da2632cf6918e4fc33ca7d77442 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Sun, 17 Dec 2017 14:31:38 +0100 Subject: [PATCH 13/25] config: add forwarding policy rules to config This commit moves the forwarding policy rules for Bitcoin and Litecoin, previously defined in the chainregistry, to config.go, making them possible to define by the user. We validate that the TimeLockDelta set is at least 4, the other rules we let the user specify arbitrarily, even 0. --- config.go | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/config.go b/config.go index d0751d1c1..985177527 100644 --- a/config.go +++ b/config.go @@ -41,6 +41,20 @@ const ( defaultNumChanConfs = 3 defaultNoEncryptWallet = false defaultTrickleDelay = 30 * 1000 + + // minTimeLockDelta is the minimum timelock we require for incoming + // HTLCs on our channels. + minTimeLockDelta = 4 + + defaultBitcoinMinHTLCMSat = 1000 + defaultBitcoinBaseFeeMSat = 1000 + defaultBitcoinFeeRate = 1 + defaultBitcoinTimeLockDelta = 144 + + defaultLitecoinMinHTLCMSat = 1000 + defaultLitecoinBaseFeeMSat = 1000 + defaultLitecoinFeeRate = 1 + defaultLitecoinTimeLockDelta = 576 ) var ( @@ -74,6 +88,11 @@ type chainConfig struct { TestNet3 bool `long:"testnet" description:"Use the test network"` SimNet bool `long:"simnet" description:"Use the simulation test network"` RegTest bool `long:"regtest" description:"Use the regression test network"` + + MinHTLC lnwire.MilliSatoshi `long:"minhtlc" description:"The smallest HTLC we are willing to forward on our channels, in millisatoshi"` + BaseFee lnwire.MilliSatoshi `long:"basefee" description:"The base fee in millisatoshi we will charge for forwarding payments on our channels"` + FeeRate lnwire.MilliSatoshi `long:"feerate" description:"The fee rate used when forwarding payments on our channels. The total fee charged is basefee + (amount * feerate / 1000000), where amount is the forwarded amount."` + TimeLockDelta uint32 `long:"timelockdelta" description:"The CLTV delta we will subtract from a forwarded HTLC's timelock value"` } type neutrinoConfig struct { @@ -165,12 +184,20 @@ func loadConfig() (*config, error) { DefaultNumChanConfs: defaultNumChanConfs, NoEncryptWallet: defaultNoEncryptWallet, Bitcoin: &chainConfig{ - RPCHost: defaultRPCHost, - RPCCert: defaultBtcdRPCCertFile, + RPCHost: defaultRPCHost, + RPCCert: defaultBtcdRPCCertFile, + MinHTLC: defaultBitcoinMinHTLCMSat, + BaseFee: defaultBitcoinBaseFeeMSat, + FeeRate: defaultBitcoinFeeRate, + TimeLockDelta: defaultBitcoinTimeLockDelta, }, Litecoin: &chainConfig{ - RPCHost: defaultRPCHost, - RPCCert: defaultLtcdRPCCertFile, + RPCHost: defaultRPCHost, + RPCCert: defaultLtcdRPCCertFile, + MinHTLC: defaultLitecoinMinHTLCMSat, + BaseFee: defaultLitecoinBaseFeeMSat, + FeeRate: defaultLitecoinFeeRate, + TimeLockDelta: defaultLitecoinTimeLockDelta, }, Autopilot: &autoPilotConfig{ MaxChannels: 5, @@ -256,6 +283,11 @@ func loadConfig() (*config, error) { return nil, fmt.Errorf(str, funcName) } + if cfg.Litecoin.TimeLockDelta < minTimeLockDelta { + return nil, fmt.Errorf("timelockdelta must be at least %v", + minTimeLockDelta) + } + // The litecoin chain is the current active chain. However // throughout the codebase we required chiancfg.Params. So as a // temporary hack, we'll mutate the default net params for @@ -305,6 +337,11 @@ func loadConfig() (*config, error) { return nil, err } + if cfg.Bitcoin.TimeLockDelta < minTimeLockDelta { + return nil, fmt.Errorf("timelockdelta must be at least %v", + minTimeLockDelta) + } + if !cfg.NeutrinoMode.Active { // If needed, we'll attempt to automatically configure // the RPC control plan for the target btcd node. From 1f6268cdde14873e9afeb3d25e0878373a455fe0 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Sun, 17 Dec 2017 14:33:09 +0100 Subject: [PATCH 14/25] rpcserver: use cfg.Bitcoin.TimeLockDelta as default CLTVExpiry for invoices --- rpcserver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcserver.go b/rpcserver.go index 744690e06..bf8e9908d 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -2085,7 +2085,7 @@ func (r *rpcServer) AddInvoice(ctx context.Context, zpay32.CLTVExpiry(invoice.CltvExpiry)) default: // TODO(roasbeef): assumes set delta between versions - defaultDelta := defaultBitcoinForwardingPolicy.TimeLockDelta + defaultDelta := cfg.Bitcoin.TimeLockDelta options = append(options, zpay32.CLTVExpiry(uint64(defaultDelta))) } From f1c6d40db85c4bba2427e974bcd114b7851f7856 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Wed, 20 Dec 2017 17:31:46 +0100 Subject: [PATCH 15/25] lnd_test: use defaultBitcoinTimeLockDelta instead of defaultBitcoinForwardingPolicy.TimeLockDelta --- lnd_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lnd_test.go b/lnd_test.go index 0292e278d..a9a0ab72f 100644 --- a/lnd_test.go +++ b/lnd_test.go @@ -1095,7 +1095,7 @@ func testChannelForceClosure(net *lntest.NetworkHarness, t *harnessTest) { // TODO(roasbeef): should check default value in config here // instead, or make delay a param defaultCSV := uint32(4) - defaultCLTV := defaultBitcoinForwardingPolicy.TimeLockDelta + defaultCLTV := uint32(defaultBitcoinTimeLockDelta) // Since we'd like to test failure scenarios with outstanding htlcs, // we'll introduce another node into our test network: Carol. From 10bd46ac72b91863903bcc519f5f23cc4f48a24a Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Sun, 17 Dec 2017 14:33:49 +0100 Subject: [PATCH 16/25] chainregistry: use forwarding policy rules from config This commit removes the definitions of defaultBitcoinForwardingPolicy and defaultLitecoinForwardingPolicy from the the chainregistry, and instead creates a routingPolicy from the values found in the config. --- chainregistry.go | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/chainregistry.go b/chainregistry.go index 93cc42bc0..675ad5cbd 100644 --- a/chainregistry.go +++ b/chainregistry.go @@ -18,7 +18,6 @@ import ( "github.com/lightningnetwork/lnd/htlcswitch" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwallet/btcwallet" - "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/chainview" "github.com/roasbeef/btcd/chaincfg/chainhash" "github.com/roasbeef/btcd/rpcclient" @@ -27,28 +26,11 @@ import ( "github.com/roasbeef/btcwallet/walletdb" ) -// defaultBitcoinForwardingPolicy is the default forwarding policy used for -// Bitcoin channels. -var defaultBitcoinForwardingPolicy = htlcswitch.ForwardingPolicy{ - MinHTLC: lnwire.NewMSatFromSatoshis(1), - BaseFee: lnwire.NewMSatFromSatoshis(1), - FeeRate: 1, - TimeLockDelta: 144, -} - -// defaultLitecoinForwardingPolicy is the default forwarding policy used for -// Litecoin channels. -var defaultLitecoinForwardingPolicy = htlcswitch.ForwardingPolicy{ - MinHTLC: lnwire.NewMSatFromSatoshis(1), - BaseFee: 1, - FeeRate: 1, - TimeLockDelta: 576, -} - // defaultChannelConstraints is the default set of channel constraints that are // meant to be used when initially funding a channel. // // TODO(roasbeef): have one for both chains +// TODO(halseth): make configurable at startup? var defaultChannelConstraints = channeldb.ChannelConstraints{ DustLimit: lnwallet.DefaultDustLimit(), MaxAcceptedHtlcs: lnwallet.MaxHTLCNumber / 2, @@ -119,12 +101,22 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB, switch registeredChains.PrimaryChain() { case bitcoinChain: - cc.routingPolicy = defaultBitcoinForwardingPolicy + cc.routingPolicy = htlcswitch.ForwardingPolicy{ + MinHTLC: cfg.Bitcoin.MinHTLC, + BaseFee: cfg.Bitcoin.BaseFee, + FeeRate: cfg.Bitcoin.FeeRate, + TimeLockDelta: cfg.Bitcoin.TimeLockDelta, + } cc.feeEstimator = lnwallet.StaticFeeEstimator{ FeeRate: 50, } case litecoinChain: - cc.routingPolicy = defaultLitecoinForwardingPolicy + cc.routingPolicy = htlcswitch.ForwardingPolicy{ + MinHTLC: cfg.Litecoin.MinHTLC, + BaseFee: cfg.Litecoin.BaseFee, + FeeRate: cfg.Litecoin.FeeRate, + TimeLockDelta: cfg.Litecoin.TimeLockDelta, + } cc.feeEstimator = lnwallet.StaticFeeEstimator{ FeeRate: 100, } From 633878d497bace5efb0c36ba176907864a49c671 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Tue, 19 Dec 2017 17:29:45 +0100 Subject: [PATCH 17/25] funding test: return static num conf instead of default value --- fundingmanager_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fundingmanager_test.go b/fundingmanager_test.go index 692bc8a99..d5ce818e8 100644 --- a/fundingmanager_test.go +++ b/fundingmanager_test.go @@ -264,8 +264,7 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey, }, NumRequiredConfs: func(chanAmt btcutil.Amount, pushAmt lnwire.MilliSatoshi) uint16 { - - return uint16(cfg.DefaultNumChanConfs) + return 3 }, RequiredRemoteDelay: func(amt btcutil.Amount) uint16 { return 4 From 0815bd4eb0c72b6104963622c038928dc1bb8941 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Sun, 17 Dec 2017 16:07:32 +0100 Subject: [PATCH 18/25] config: make DefaultNumChanConfs part of chainConfig This commit moves the definition of DefaultNumChanConfs into the chainConfig (such that it is set as e.g. "--bitcoin.defaultchanconfs"), making it possible to set individually for different chains. It also adds the flag DefaultRemoteDelay to the chainConfig, which can be used to set the CSV delay we will require the remote to wait before retrieving its own funds in case of an uncooperative close of the channel. Both these are set 0 by default (if not specified by the user), which in that case we will dynamically set the values, scaling them according to the channel size. --- config.go | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/config.go b/config.go index 985177527..4ce84bed9 100644 --- a/config.go +++ b/config.go @@ -38,7 +38,6 @@ const ( defaultPeerPort = 9735 defaultRPCHost = "localhost" defaultMaxPendingChannels = 1 - defaultNumChanConfs = 3 defaultNoEncryptWallet = false defaultTrickleDelay = 30 * 1000 @@ -89,10 +88,12 @@ type chainConfig struct { SimNet bool `long:"simnet" description:"Use the simulation test network"` RegTest bool `long:"regtest" description:"Use the regression test network"` - MinHTLC lnwire.MilliSatoshi `long:"minhtlc" description:"The smallest HTLC we are willing to forward on our channels, in millisatoshi"` - BaseFee lnwire.MilliSatoshi `long:"basefee" description:"The base fee in millisatoshi we will charge for forwarding payments on our channels"` - FeeRate lnwire.MilliSatoshi `long:"feerate" description:"The fee rate used when forwarding payments on our channels. The total fee charged is basefee + (amount * feerate / 1000000), where amount is the forwarded amount."` - TimeLockDelta uint32 `long:"timelockdelta" description:"The CLTV delta we will subtract from a forwarded HTLC's timelock value"` + DefaultNumChanConfs int `long:"defaultchanconfs" description:"The default number of confirmations a channel must have before it's considered open. If this is not set, we will scale the value according to the channel size."` + DefaultRemoteDelay int `long:"defaultremotedelay" description:"The default number of blocks we will require our channel counterparty to wait before accessing its funds in case of unilateral close. If this is not set, we will scale the value according to the channel size."` + MinHTLC lnwire.MilliSatoshi `long:"minhtlc" description:"The smallest HTLC we are willing to forward on our channels, in millisatoshi"` + BaseFee lnwire.MilliSatoshi `long:"basefee" description:"The base fee in millisatoshi we will charge for forwarding payments on our channels"` + FeeRate lnwire.MilliSatoshi `long:"feerate" description:"The fee rate used when forwarding payments on our channels. The total fee charged is basefee + (amount * feerate / 1000000), where amount is the forwarded amount."` + TimeLockDelta uint32 `long:"timelockdelta" description:"The CLTV delta we will subtract from a forwarded HTLC's timelock value"` } type neutrinoConfig struct { @@ -146,8 +147,6 @@ type config struct { Litecoin *chainConfig `group:"Litecoin" namespace:"litecoin"` Bitcoin *chainConfig `group:"Bitcoin" namespace:"bitcoin"` - DefaultNumChanConfs int `long:"defaultchanconfs" description:"The default number of confirmations a channel must have before it's considered open."` - NeutrinoMode *neutrinoConfig `group:"neutrino" namespace:"neutrino"` Autopilot *autoPilotConfig `group:"autopilot" namespace:"autopilot"` @@ -169,20 +168,19 @@ type config struct { // 4) Parse CLI options and overwrite/add any specified options func loadConfig() (*config, error) { defaultCfg := config{ - ConfigFile: defaultConfigFile, - DataDir: defaultDataDir, - DebugLevel: defaultLogLevel, - TLSCertPath: defaultTLSCertPath, - TLSKeyPath: defaultTLSKeyPath, - AdminMacPath: defaultAdminMacPath, - ReadMacPath: defaultReadMacPath, - LogDir: defaultLogDir, - PeerPort: defaultPeerPort, - RPCPort: defaultRPCPort, - RESTPort: defaultRESTPort, - MaxPendingChannels: defaultMaxPendingChannels, - DefaultNumChanConfs: defaultNumChanConfs, - NoEncryptWallet: defaultNoEncryptWallet, + ConfigFile: defaultConfigFile, + DataDir: defaultDataDir, + DebugLevel: defaultLogLevel, + TLSCertPath: defaultTLSCertPath, + TLSKeyPath: defaultTLSKeyPath, + AdminMacPath: defaultAdminMacPath, + ReadMacPath: defaultReadMacPath, + LogDir: defaultLogDir, + PeerPort: defaultPeerPort, + RPCPort: defaultRPCPort, + RESTPort: defaultRESTPort, + MaxPendingChannels: defaultMaxPendingChannels, + NoEncryptWallet: defaultNoEncryptWallet, Bitcoin: &chainConfig{ RPCHost: defaultRPCHost, RPCCert: defaultBtcdRPCCertFile, From 4ee3bff771b3b228a05585a73661f0882c22b82e Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Wed, 20 Dec 2017 16:17:51 +0100 Subject: [PATCH 19/25] lnd: use cfg.Bitcoin.DefaultNumChanConfs --- lnd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lnd.go b/lnd.go index 12fc9edf6..19a94b636 100644 --- a/lnd.go +++ b/lnd.go @@ -302,7 +302,7 @@ func lndMain() error { // TODO(roasbeef): add configurable mapping // * simple switch initially // * assign coefficient, etc - return uint16(cfg.DefaultNumChanConfs) + return uint16(cfg.Bitcoin.DefaultNumChanConfs) }, RequiredRemoteDelay: func(chanAmt btcutil.Amount) uint16 { // TODO(roasbeef): add additional hooks for From 53b0ee3765d036642027732d1fc3c10da4225295 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Tue, 19 Dec 2017 17:07:35 +0100 Subject: [PATCH 20/25] lntest/node: use --bitcoin.defaultchanconfs=1 and --bitcoin.defaultremotedelay=4 --- lntest/node.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lntest/node.go b/lntest/node.go index 1e2fd7b79..43f932923 100644 --- a/lntest/node.go +++ b/lntest/node.go @@ -122,7 +122,8 @@ func (cfg nodeConfig) genArgs() []string { args = append(args, "--nobootstrap") args = append(args, "--noencryptwallet") args = append(args, "--debuglevel=debug") - args = append(args, "--defaultchanconfs=1") + args = append(args, "--bitcoin.defaultchanconfs=1") + args = append(args, "--bitcoin.defaultremotedelay=4") args = append(args, fmt.Sprintf("--bitcoin.rpchost=%v", cfg.RPCConfig.Host)) args = append(args, fmt.Sprintf("--bitcoin.rpcuser=%v", cfg.RPCConfig.User)) args = append(args, fmt.Sprintf("--bitcoin.rpcpass=%v", cfg.RPCConfig.Pass)) From 3edc1a745611d1643e8915688bbe9cccde94d93b Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Sun, 17 Dec 2017 16:08:21 +0100 Subject: [PATCH 21/25] fundingmanager: define min and maxRemoteDelay This commit defines minRemoteDelay and maxRemoteDelay, which is the extremes of the CSV delay we will require the remote to use for its commitment transaction. The actual delay we will require will be somewhere between these values, depending on channel size. --- fundingmanager.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fundingmanager.go b/fundingmanager.go index 75ba76d60..65f411c23 100644 --- a/fundingmanager.go +++ b/fundingmanager.go @@ -32,8 +32,6 @@ const ( // TODO(roasbeef): tune msgBufferSize = 50 - defaultCsvDelay = 4 - // maxFundingAmount is a soft-limit of the maximum channel size // accepted within the Lightning Protocol Currently. This limit is // currently defined in BOLT-0002, and serves as an initial @@ -43,6 +41,13 @@ const ( // TODO(roasbeef): add command line param to modify maxFundingAmount = btcutil.Amount(1 << 24) + // minRemoteDelay and maxRemoteDelay is the extremes of the CSV delay + // we will require the remote to use for its commitment transaction. + // The actual delay we will require will be somewhere between these + // values, depending on channel size. + minRemoteDelay = 144 + maxRemoteDelay = 2016 + // maxWaitNumBlocksFundingConf is the maximum number of blocks to wait // for the funding transaction to be confirmed before forgetting about // the channel. 288 blocks is ~48 hrs From 43d7dd3d99b7cd9b889e8baa02f2d47670bff379 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Sun, 17 Dec 2017 16:13:23 +0100 Subject: [PATCH 22/25] lnd: make NumRequiredConfs and RequiredRemoteDelay scale with chanAmt This commit makes the value returned fomr NumRequiredConfs and RequiredRemoteDelay used during the funding process scale linearly with the channel size. This is done to ensure that in cases there are more at stake in a channel, we have more time to react to reorgs, or unilateral closes. If the user explicitly specified values for these two at startup, we return those instead, without doing the scaling. --- lnd.go | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 8 deletions(-) diff --git a/lnd.go b/lnd.go index 19a94b636..af9e0bb49 100644 --- a/lnd.go +++ b/lnd.go @@ -298,16 +298,71 @@ func lndMain() error { return nil, fmt.Errorf("unable to find channel") }, DefaultRoutingPolicy: activeChainControl.routingPolicy, - NumRequiredConfs: func(chanAmt btcutil.Amount, pushAmt lnwire.MilliSatoshi) uint16 { - // TODO(roasbeef): add configurable mapping - // * simple switch initially - // * assign coefficient, etc - return uint16(cfg.Bitcoin.DefaultNumChanConfs) + NumRequiredConfs: func(chanAmt btcutil.Amount, + pushAmt lnwire.MilliSatoshi) uint16 { + // For large channels we increase the number + // of confirmations we require for the + // channel to be considered open. As it is + // always the responder that gets to choose + // value, the pushAmt is value being pushed + // to us. This means we have more to lose + // in the case this gets re-orged out, and + // we will require more confirmations before + // we consider it open. + // TODO(halseth): Use Litecoin params in case + // of LTC channels. + + // In case the user has explicitly specified + // a default value for the number of + // confirmations, we use it. + defaultConf := uint16(cfg.Bitcoin.DefaultNumChanConfs) + if defaultConf != 0 { + return defaultConf + } + + // If not we return a value scaled linearly + // between 3 and 6, depending on channel size. + // TODO(halseth): Use 1 as minimum? + minConf := uint64(3) + maxConf := uint64(6) + maxChannelSize := uint64( + lnwire.NewMSatFromSatoshis(maxFundingAmount)) + stake := lnwire.NewMSatFromSatoshis(chanAmt) + pushAmt + conf := maxConf * uint64(stake) / maxChannelSize + if conf < minConf { + conf = minConf + } + if conf > maxConf { + conf = maxConf + } + return uint16(conf) }, RequiredRemoteDelay: func(chanAmt btcutil.Amount) uint16 { - // TODO(roasbeef): add additional hooks for - // configuration - return 4 + // We scale the remote CSV delay (the time the + // remote have to claim funds in case of a unilateral + // close) linearly from minRemoteDelay blocks + // for small channels, to maxRemoteDelay blocks + // for channels of size maxFundingAmount. + // TODO(halseth): Litecoin parameter for LTC. + + // In case the user has explicitly specified + // a default value for the remote delay, we + // use it. + defaultDelay := uint16(cfg.Bitcoin.DefaultRemoteDelay) + if defaultDelay > 0 { + return defaultDelay + } + + // If not we scale according to channel size. + delay := uint16(maxRemoteDelay * + chanAmt / maxFundingAmount) + if delay < minRemoteDelay { + delay = minRemoteDelay + } + if delay > maxRemoteDelay { + delay = maxRemoteDelay + } + return delay }, }) if err != nil { From 483abbee5b0097528957424389854c6dd358c700 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Wed, 20 Dec 2017 14:02:04 +0100 Subject: [PATCH 23/25] discovery: make sure ChannelUpdates always have incremented timestamp This commit ensures that we always increment the timestamp of ChannelUpdates we send telling the network about changes to our channel policy. We do this because it could happen (especially during tests) that we issued an update, but the ChannelUpdate would have the same timestamp as our last ChannelUpdate, and would be ignored by the network. --- discovery/gossiper.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/discovery/gossiper.go b/discovery/gossiper.go index bf8762574..4dedfae2f 100644 --- a/discovery/gossiper.go +++ b/discovery/gossiper.go @@ -1986,12 +1986,18 @@ func (d *AuthenticatedGossiper) sendAnnSigReliably( func (d *AuthenticatedGossiper) updateChannel(info *channeldb.ChannelEdgeInfo, edge *channeldb.ChannelEdgePolicy) (*lnwire.ChannelAnnouncement, *lnwire.ChannelUpdate, error) { - edge.LastUpdate = time.Now() + // Make sure timestamp is always increased, such that our update + // gets propagated. + timestamp := time.Now().Unix() + if timestamp <= edge.LastUpdate.Unix() { + timestamp = edge.LastUpdate.Unix() + 1 + } + edge.LastUpdate = time.Unix(timestamp, 0) chanUpdate := &lnwire.ChannelUpdate{ Signature: edge.Signature, ChainHash: info.ChainHash, ShortChannelID: lnwire.NewShortChanIDFromInt(edge.ChannelID), - Timestamp: uint32(edge.LastUpdate.Unix()), + Timestamp: uint32(timestamp), Flags: edge.Flags, TimeLockDelta: edge.TimeLockDelta, HtlcMinimumMsat: edge.MinHTLC, From f4f024aff2a62e726a7c29939762504fc2244d5e Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Fri, 22 Dec 2017 13:49:49 +0100 Subject: [PATCH 24/25] lnd_test: extract graph topology subscription into own method This commit extracts the launching of a goroutine subscribing to and forwarding graph topology notifications into its own utility method, such that it can be used in other tests as well. --- lnd_test.go | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/lnd_test.go b/lnd_test.go index a9a0ab72f..3cf28b4ec 100644 --- a/lnd_test.go +++ b/lnd_test.go @@ -3878,28 +3878,22 @@ out: } } -func testGraphTopologyNotifications(net *lntest.NetworkHarness, t *harnessTest) { - const chanAmt = maxFundingAmount - timeout := time.Duration(time.Second * 5) - ctxb := context.Background() - - // We'll first start by establishing a notification client to Alice which - // will send us notifications upon detected changes in the channel graph. +// subscribeGraphNotifications subscribes to channel graph updates and launches +// a goroutine that forwards these to the returned channel. +func subscribeGraphNotifications(t *harnessTest, ctxb context.Context, + node *lntest.HarnessNode) (chan *lnrpc.GraphTopologyUpdate, chan struct{}) { + // We'll first start by establishing a notification client which will + // send us notifications upon detected changes in the channel graph. req := &lnrpc.GraphTopologySubscription{} - topologyClient, err := net.Alice.SubscribeChannelGraph(ctxb, req) + topologyClient, err := node.SubscribeChannelGraph(ctxb, req) if err != nil { t.Fatalf("unable to create topology client: %v", err) } - // Open a new channel between Alice and Bob. - ctxt, _ := context.WithTimeout(ctxb, timeout) - chanPoint := openChannelAndAssert(ctxt, t, net, net.Alice, net.Bob, - chanAmt, 0) - // We'll launch a goroutine that'll be responsible for proxying all // notifications recv'd from the client into the channel below. quit := make(chan struct{}) - graphUpdates := make(chan *lnrpc.GraphTopologyUpdate, 4) + graphUpdates := make(chan *lnrpc.GraphTopologyUpdate, 20) go func() { for { select { @@ -3916,7 +3910,8 @@ func testGraphTopologyNotifications(net *lntest.NetworkHarness, t *harnessTest) if err == io.EOF { return } else if err != nil { - t.Fatalf("unable to recv graph update: %v", err) + t.Fatalf("unable to recv graph update: %v", + err) } select { @@ -3927,6 +3922,21 @@ func testGraphTopologyNotifications(net *lntest.NetworkHarness, t *harnessTest) } } }() + return graphUpdates, quit +} + +func testGraphTopologyNotifications(net *lntest.NetworkHarness, t *harnessTest) { + const chanAmt = maxFundingAmount + timeout := time.Duration(time.Second * 5) + ctxb := context.Background() + + // Let Alice subscribe to graph notifications. + graphUpdates, quit := subscribeGraphNotifications(t, ctxb, net.Alice) + + // Open a new channel between Alice and Bob. + ctxt, _ := context.WithTimeout(ctxb, timeout) + chanPoint := openChannelAndAssert(ctxt, t, net, net.Alice, net.Bob, + chanAmt, 0) // The channel opening above should've triggered a few notifications // sent to the notification client. We'll expect two channel updates, From d030773c8d2cede68bd2d265be2a5053f4b1b165 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Tue, 19 Dec 2017 17:10:00 +0100 Subject: [PATCH 25/25] lnd test: add testUpdateChannelPolicy This commit adds a new integration test, that checks that policy/fee updates get propagated properly in the network, such that the other nodes learn about the changes. --- lnd_test.go | 290 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 289 insertions(+), 1 deletion(-) diff --git a/lnd_test.go b/lnd_test.go index 3cf28b4ec..b87aced0b 100644 --- a/lnd_test.go +++ b/lnd_test.go @@ -467,6 +467,290 @@ func testBasicChannelFunding(net *lntest.NetworkHarness, t *harnessTest) { closeChannelAndAssert(ctxt, t, net, net.Alice, chanPoint, false) } +// testUpdateChannelPolicy tests that policy updates made to a channel +// gets propagated to other nodes in the network. +func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) { + timeout := time.Duration(time.Second * 5) + ctxb := context.Background() + + // Launch notification clients for all nodes, such that we can + // get notified when they discover new channels and updates + // in the graph. + aliceUpdates, aQuit := subscribeGraphNotifications(t, ctxb, net.Alice) + defer close(aQuit) + bobUpdates, bQuit := subscribeGraphNotifications(t, ctxb, net.Bob) + defer close(bQuit) + + chanAmt := maxFundingAmount + pushAmt := btcutil.Amount(100000) + + // Create a channel Alice->Bob. + ctxt, _ := context.WithTimeout(ctxb, timeout) + chanPoint := openChannelAndAssert(ctxt, t, net, net.Alice, net.Bob, + chanAmt, pushAmt) + + ctxt, _ = context.WithTimeout(ctxb, time.Second*15) + err := net.Alice.WaitForNetworkChannelOpen(ctxt, chanPoint) + if err != nil { + t.Fatalf("alice didn't report channel: %v", err) + } + err = net.Bob.WaitForNetworkChannelOpen(ctxt, chanPoint) + if err != nil { + t.Fatalf("bob didn't report channel: %v", err) + } + + // Create Carol and a new channel Bob->Carol. + carol, err := net.NewNode(nil) + if err != nil { + t.Fatalf("unable to create new nodes: %v", err) + } + carolUpdates, cQuit := subscribeGraphNotifications(t, ctxb, carol) + defer close(cQuit) + + if err := net.ConnectNodes(ctxb, carol, net.Bob); err != nil { + t.Fatalf("unable to connect dave to alice: %v", err) + } + + ctxt, _ = context.WithTimeout(ctxb, timeout) + chanPoint2 := openChannelAndAssert(ctxt, t, net, net.Bob, carol, + chanAmt, pushAmt) + + ctxt, _ = context.WithTimeout(ctxb, time.Second*15) + err = net.Bob.WaitForNetworkChannelOpen(ctxt, chanPoint2) + if err != nil { + t.Fatalf("bob didn't report channel: %v", err) + } + err = carol.WaitForNetworkChannelOpen(ctxt, chanPoint2) + if err != nil { + t.Fatalf("carol didn't report channel: %v", err) + } + + // Update the fees for the channel Alice->Bob, and make sure + // all nodes learn about it. + const feeBase = 1000000 + baseFee := int64(1500) + feeRate := int64(12) + timeLockDelta := uint32(66) + + req := &lnrpc.PolicyUpdateRequest{ + BaseFeeMsat: baseFee, + FeeRate: float64(feeRate), + TimeLockDelta: timeLockDelta, + } + req.Scope = &lnrpc.PolicyUpdateRequest_ChanPoint{ + ChanPoint: chanPoint, + } + + _, err = net.Alice.UpdateChannelPolicy(ctxb, req) + if err != nil { + t.Fatalf("unable to get alice's balance: %v", err) + } + + // txStr returns the string representation of the channel's + // funding tx. + txStr := func(chanPoint *lnrpc.ChannelPoint) string { + fundingTxID, err := chainhash.NewHash(chanPoint.FundingTxid) + if err != nil { + return "" + } + cp := wire.OutPoint{ + Hash: *fundingTxID, + Index: chanPoint.OutputIndex, + } + return cp.String() + } + + // A closure that is used to wait for a channel updates that matches + // the channel policy update done by Alice. + waitForChannelUpdate := func(graphUpdates chan *lnrpc.GraphTopologyUpdate, + chanPoints ...*lnrpc.ChannelPoint) { + // Create a map containing all the channel points we are + // waiting for updates for. + cps := make(map[string]bool) + for _, chanPoint := range chanPoints { + cps[txStr(chanPoint)] = true + } + Loop: + for { + select { + case graphUpdate := <-graphUpdates: + if len(graphUpdate.ChannelUpdates) == 0 { + continue + } + chanUpdate := graphUpdate.ChannelUpdates[0] + fundingTxStr := txStr(chanUpdate.ChanPoint) + if _, ok := cps[fundingTxStr]; !ok { + continue + } + + if chanUpdate.AdvertisingNode != net.Alice.PubKeyStr { + continue + } + + policy := chanUpdate.RoutingPolicy + if policy.FeeBaseMsat != baseFee { + continue + } + if policy.FeeRateMilliMsat != feeRate*feeBase { + continue + } + if policy.TimeLockDelta != timeLockDelta { + continue + } + + // We got a policy update that matched the + // values and channel point of what we + // expected, delete it from the map. + delete(cps, fundingTxStr) + + // If we have no more channel points we are + // waiting for, break out of the loop. + if len(cps) == 0 { + break Loop + } + case <-time.After(20 * time.Second): + t.Fatalf("did not receive channel update") + } + } + } + + // Wait for all nodes to have seen the policy update done by Alice. + waitForChannelUpdate(aliceUpdates, chanPoint) + waitForChannelUpdate(bobUpdates, chanPoint) + waitForChannelUpdate(carolUpdates, chanPoint) + + // assertChannelPolicy asserts that the passed node's known channel + // policy for the passed chanPoint is consistent with Alice's current + // expected policy values. + assertChannelPolicy := func(node *lntest.HarnessNode, + chanPoint *lnrpc.ChannelPoint) { + // Get a DescribeGraph from the node. + descReq := &lnrpc.ChannelGraphRequest{} + chanGraph, err := node.DescribeGraph(ctxb, descReq) + if err != nil { + t.Fatalf("unable to query for alice's routing table: %v", + err) + } + + edgeFound := false + for _, e := range chanGraph.Edges { + if e.ChanPoint == txStr(chanPoint) { + edgeFound = true + if e.Node1Pub == net.Alice.PubKeyStr { + if e.Node1Policy.FeeBaseMsat != baseFee { + t.Fatalf("expected base fee "+ + "%v, got %v", baseFee, + e.Node1Policy.FeeBaseMsat) + } + if e.Node1Policy.FeeRateMilliMsat != feeRate*feeBase { + t.Fatalf("expected fee rate "+ + "%v, got %v", feeRate*feeBase, + e.Node1Policy.FeeRateMilliMsat) + } + if e.Node1Policy.TimeLockDelta != timeLockDelta { + t.Fatalf("expected time lock "+ + "delta %v, got %v", + timeLockDelta, + e.Node1Policy.TimeLockDelta) + } + } else { + if e.Node2Policy.FeeBaseMsat != baseFee { + t.Fatalf("expected base fee "+ + "%v, got %v", baseFee, + e.Node2Policy.FeeBaseMsat) + } + if e.Node2Policy.FeeRateMilliMsat != feeRate*feeBase { + t.Fatalf("expected fee rate "+ + "%v, got %v", feeRate*feeBase, + e.Node2Policy.FeeRateMilliMsat) + } + if e.Node2Policy.TimeLockDelta != timeLockDelta { + t.Fatalf("expected time lock "+ + "delta %v, got %v", + timeLockDelta, + e.Node2Policy.TimeLockDelta) + } + } + } + } + + if !edgeFound { + t.Fatalf("did not find edge") + } + + } + + // Check that all nodes now know about Alice's updated policy. + assertChannelPolicy(net.Alice, chanPoint) + assertChannelPolicy(net.Bob, chanPoint) + assertChannelPolicy(carol, chanPoint) + + // Open channel to Carol. + if err := net.ConnectNodes(ctxb, net.Alice, carol); err != nil { + t.Fatalf("unable to connect dave to alice: %v", err) + } + ctxt, _ = context.WithTimeout(ctxb, timeout) + chanPoint3 := openChannelAndAssert(ctxt, t, net, net.Alice, carol, + chanAmt, pushAmt) + + ctxt, _ = context.WithTimeout(ctxb, time.Second*15) + err = net.Alice.WaitForNetworkChannelOpen(ctxt, chanPoint3) + if err != nil { + t.Fatalf("alice didn't report channel: %v", err) + } + err = carol.WaitForNetworkChannelOpen(ctxt, chanPoint3) + if err != nil { + t.Fatalf("bob didn't report channel: %v", err) + } + + // Make a global update, and check that both channels' + // new policies get propagated. + baseFee = int64(800) + feeRate = int64(123) + timeLockDelta = uint32(22) + + req = &lnrpc.PolicyUpdateRequest{ + BaseFeeMsat: baseFee, + FeeRate: float64(feeRate), + TimeLockDelta: timeLockDelta, + } + req.Scope = &lnrpc.PolicyUpdateRequest_Global{} + + _, err = net.Alice.UpdateChannelPolicy(ctxb, req) + if err != nil { + t.Fatalf("unable to get alice's balance: %v", err) + } + + // Wait for all nodes to have seen the policy updates + // for both of Alice's channels. + waitForChannelUpdate(aliceUpdates, chanPoint, chanPoint3) + waitForChannelUpdate(bobUpdates, chanPoint, chanPoint3) + waitForChannelUpdate(carolUpdates, chanPoint, chanPoint3) + + // And finally check that all nodes remembers the policy + // update they received. + assertChannelPolicy(net.Alice, chanPoint) + assertChannelPolicy(net.Bob, chanPoint) + assertChannelPolicy(carol, chanPoint) + + assertChannelPolicy(net.Alice, chanPoint3) + assertChannelPolicy(net.Bob, chanPoint3) + assertChannelPolicy(carol, chanPoint3) + + // Close the channels. + ctxt, _ = context.WithTimeout(ctxb, timeout) + closeChannelAndAssert(ctxt, t, net, net.Alice, chanPoint, false) + ctxt, _ = context.WithTimeout(ctxb, timeout) + closeChannelAndAssert(ctxt, t, net, net.Bob, chanPoint2, false) + closeChannelAndAssert(ctxt, t, net, net.Alice, chanPoint3, false) + ctxt, _ = context.WithTimeout(ctxb, timeout) + + // Clean up carol's node. + if err := net.ShutdownNode(carol); err != nil { + t.Fatalf("unable to shutdown carol: %v", err) + } +} + // testOpenChannelAfterReorg tests that in the case where we have an open // channel where the funding tx gets reorged out, the channel will no // longer be present in the node's routing table. @@ -793,7 +1077,7 @@ func testChannelFundingPersistence(net *lntest.NetworkHarness, t *harnessTest) { // confirmation before it's open, with the current set of defaults, // we'll need to create a new node instance. const numConfs = 5 - carolArgs := []string{fmt.Sprintf("--defaultchanconfs=%v", numConfs)} + carolArgs := []string{fmt.Sprintf("--bitcoin.defaultchanconfs=%v", numConfs)} carol, err := net.NewNode(carolArgs) if err != nil { t.Fatalf("unable to create new node: %v", err) @@ -4690,6 +4974,10 @@ var testsCases = []*testCase{ name: "basic funding flow", test: testBasicChannelFunding, }, + { + name: "update channel policy", + test: testUpdateChannelPolicy, + }, { name: "open channel reorg test", test: testOpenChannelAfterReorg,