Merge pull request #3442 from cfromknecht/router-registry

single-shot, sender-side mpp via sendtoroute
This commit is contained in:
Olaoluwa Osuntokun 2019-11-04 17:50:59 -08:00 committed by GitHub
commit 7ecb7136cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 1798 additions and 786 deletions

@ -14,6 +14,7 @@ import (
"github.com/coreos/bbolt"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/record"
"github.com/lightningnetwork/lnd/routing/route"
"github.com/lightningnetwork/lnd/tlv"
)
@ -508,7 +509,9 @@ func deserializePaymentAttemptInfo(r io.Reader) (*PaymentAttemptInfo, error) {
func serializeHop(w io.Writer, h *route.Hop) error {
if err := WriteElements(w,
h.PubKeyBytes[:], h.ChannelID, h.OutgoingTimeLock,
h.PubKeyBytes[:],
h.ChannelID,
h.OutgoingTimeLock,
h.AmtToForward,
); err != nil {
return err
@ -525,10 +528,23 @@ func serializeHop(w io.Writer, h *route.Hop) error {
return WriteElements(w, uint32(0))
}
// Gather all non-primitive TLV records so that they can be serialized
// as a single blob.
//
// TODO(conner): add migration to unify all fields in a single TLV
// blobs. The split approach will cause headaches down the road as more
// fields are added, which we can avoid by having a single TLV stream
// for all payload fields.
var records []tlv.Record
if h.MPP != nil {
records = append(records, h.MPP.Record())
}
records = append(records, h.TLVRecords...)
// Otherwise, we'll transform our slice of records into a map of the
// raw bytes, then serialize them in-line with a length (number of
// elements) prefix.
mapRecords, err := tlv.RecordsToMap(h.TLVRecords)
mapRecords, err := tlv.RecordsToMap(records)
if err != nil {
return err
}
@ -604,6 +620,29 @@ func deserializeHop(r io.Reader) (*route.Hop, error) {
tlvMap[tlvType] = rawRecordBytes
}
// If the MPP type is present, remove it from the generic TLV map and
// parse it back into a proper MPP struct.
//
// TODO(conner): add migration to unify all fields in a single TLV
// blobs. The split approach will cause headaches down the road as more
// fields are added, which we can avoid by having a single TLV stream
// for all payload fields.
mppType := uint64(record.MPPOnionType)
if mppBytes, ok := tlvMap[mppType]; ok {
delete(tlvMap, mppType)
var (
mpp = &record.MPP{}
mppRec = mpp.Record()
r = bytes.NewReader(mppBytes)
)
err := mppRec.Decode(r, uint64(len(mppBytes)))
if err != nil {
return nil, err
}
h.MPP = mpp
}
tlvRecords, err := tlv.MapToRecords(tlvMap)
if err != nil {
return nil, err

@ -12,6 +12,7 @@ import (
"github.com/btcsuite/btcd/btcec"
"github.com/davecgh/go-spew/spew"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/record"
"github.com/lightningnetwork/lnd/routing/route"
"github.com/lightningnetwork/lnd/tlv"
)
@ -31,6 +32,7 @@ var (
tlv.MakeStaticRecord(1, nil, 3, tlvEncoder, nil),
tlv.MakeStaticRecord(2, nil, 3, tlvEncoder, nil),
},
MPP: record.NewMPP(32, [32]byte{0x42}),
}
testHop2 = &route.Hop{
@ -46,8 +48,8 @@ var (
TotalAmount: 1234567,
SourcePubKey: route.NewVertex(pub),
Hops: []*route.Hop{
testHop1,
testHop2,
testHop1,
},
}
)

@ -21,7 +21,7 @@ type Registry interface {
NotifyExitHopHtlc(payHash lntypes.Hash, paidAmount lnwire.MilliSatoshi,
expiry uint32, currentHeight int32,
circuitKey channeldb.CircuitKey, hodlChan chan<- interface{},
eob []byte) (*invoices.HodlEvent, error)
payload invoices.Payload) (*invoices.HodlEvent, error)
// HodlUnsubscribeAll unsubscribes from all hodl events.
HodlUnsubscribeAll(subscriber chan<- interface{})

@ -24,7 +24,7 @@ type mockRegistry struct {
func (r *mockRegistry) NotifyExitHopHtlc(payHash lntypes.Hash,
paidAmount lnwire.MilliSatoshi, expiry uint32, currentHeight int32,
circuitKey channeldb.CircuitKey, hodlChan chan<- interface{},
eob []byte) (*invoices.HodlEvent, error) {
payload invoices.Payload) (*invoices.HodlEvent, error) {
r.notifyChan <- notifyExitHopData{
hodlChan: hodlChan,

@ -16,15 +16,13 @@ import (
// interpret the forwarding information encoded within the HTLC packet, and hop
// to encode the forwarding information for the _next_ hop.
type Iterator interface {
// ForwardingInstructions returns the set of fields that detail exactly
// _how_ this hop should forward the HTLC to the next hop.
// Additionally, the information encoded within the returned
// ForwardingInfo is to be used by each hop to authenticate the
// information given to it by the prior hop.
ForwardingInstructions() (ForwardingInfo, error)
// ExtraOnionBlob returns the additional EOB data (if available).
ExtraOnionBlob() []byte
// HopPayload returns the set of fields that detail exactly _how_ this
// hop should forward the HTLC to the next hop. Additionally, the
// information encoded within the returned ForwardingInfo is to be used
// by each hop to authenticate the information given to it by the prior
// hop. The payload will also contain any additional TLV fields provided
// by the sender.
HopPayload() (*Payload, error)
// EncodeNextHop encodes the onion packet destined for the next hop
// into the passed io.Writer.
@ -72,50 +70,35 @@ func (r *sphinxHopIterator) EncodeNextHop(w io.Writer) error {
return r.processedPacket.NextPacket.Encode(w)
}
// ForwardingInstructions returns the set of fields that detail exactly _how_
// this hop should forward the HTLC to the next hop. Additionally, the
// information encoded within the returned ForwardingInfo is to be used by each
// hop to authenticate the information given to it by the prior hop.
// HopPayload returns the set of fields that detail exactly _how_ this hop
// should forward the HTLC to the next hop. Additionally, the information
// encoded within the returned ForwardingInfo is to be used by each hop to
// authenticate the information given to it by the prior hop. The payload will
// also contain any additional TLV fields provided by the sender.
//
// NOTE: Part of the HopIterator interface.
func (r *sphinxHopIterator) ForwardingInstructions() (ForwardingInfo, error) {
func (r *sphinxHopIterator) HopPayload() (*Payload, error) {
switch r.processedPacket.Payload.Type {
// If this is the legacy payload, then we'll extract the information
// directly from the pre-populated ForwardingInstructions field.
case sphinx.PayloadLegacy:
fwdInst := r.processedPacket.ForwardingInstructions
p := NewLegacyPayload(fwdInst)
return p.ForwardingInfo(), nil
return NewLegacyPayload(fwdInst), nil
// Otherwise, if this is the TLV payload, then we'll make a new stream
// to decode only what we need to make routing decisions.
case sphinx.PayloadTLV:
p, err := NewPayloadFromReader(bytes.NewReader(
return NewPayloadFromReader(bytes.NewReader(
r.processedPacket.Payload.Payload,
))
if err != nil {
return ForwardingInfo{}, err
}
return p.ForwardingInfo(), nil
default:
return ForwardingInfo{}, fmt.Errorf("unknown "+
"sphinx payload type: %v",
return nil, fmt.Errorf("unknown sphinx payload type: %v",
r.processedPacket.Payload.Type)
}
}
// ExtraOnionBlob returns the additional EOB data (if available).
func (r *sphinxHopIterator) ExtraOnionBlob() []byte {
if r.processedPacket.Payload.Type == sphinx.PayloadLegacy {
return nil
}
return r.processedPacket.Payload.Payload
}
// ExtractErrorEncrypter decodes and returns the ErrorEncrypter for this hop,
// along with a failure code to signal if the decoding was successful. The
// ErrorEncrypter is used to encrypt errors back to the sender in the event that

@ -85,12 +85,13 @@ func TestSphinxHopIteratorForwardingInstructions(t *testing.T) {
for i, testCase := range testCases {
iterator.processedPacket = testCase.sphinxPacket
fwdInfo, err := iterator.ForwardingInstructions()
pld, err := iterator.HopPayload()
if err != nil {
t.Fatalf("#%v: unable to extract forwarding "+
"instructions: %v", i, err)
}
fwdInfo := pld.ForwardingInfo()
if fwdInfo != testCase.expectedFwdInfo {
t.Fatalf("#%v: wrong fwding info: expected %v, got %v",
i, spew.Sdump(testCase.expectedFwdInfo),

@ -81,6 +81,10 @@ type Payload struct {
// FwdInfo holds the basic parameters required for HTLC forwarding, e.g.
// amount, cltv, and next hop.
FwdInfo ForwardingInfo
// MPP holds the info provided in an option_mpp record when parsed from
// a TLV onion payload.
MPP *record.MPP
}
// NewLegacyPayload builds a Payload from the amount, cltv, and next hop
@ -105,12 +109,14 @@ func NewPayloadFromReader(r io.Reader) (*Payload, error) {
cid uint64
amt uint64
cltv uint32
mpp = &record.MPP{}
)
tlvStream, err := tlv.NewStream(
record.NewAmtToFwdRecord(&amt),
record.NewLockTimeRecord(&cltv),
record.NewNextHopIDRecord(&cid),
mpp.Record(),
)
if err != nil {
return nil, err
@ -151,6 +157,12 @@ func NewPayloadFromReader(r io.Reader) (*Payload, error) {
return nil, err
}
// If no MPP field was parsed, set the MPP field on the resulting
// payload to nil.
if _, ok := parsedTypes[record.MPPOnionType]; !ok {
mpp = nil
}
return &Payload{
FwdInfo: ForwardingInfo{
Network: BitcoinNetwork,
@ -158,6 +170,7 @@ func NewPayloadFromReader(r io.Reader) (*Payload, error) {
AmountToForward: lnwire.MilliSatoshi(amt),
OutgoingCTLV: cltv,
},
MPP: mpp,
}, nil
}
@ -179,6 +192,7 @@ func ValidateParsedPayloadTypes(parsedTypes tlv.TypeSet,
_, hasAmt := parsedTypes[record.AmtOnionType]
_, hasLockTime := parsedTypes[record.LockTimeOnionType]
_, hasNextHop := parsedTypes[record.NextHopOnionType]
_, hasMPP := parsedTypes[record.MPPOnionType]
switch {
@ -207,7 +221,21 @@ func ValidateParsedPayloadTypes(parsedTypes tlv.TypeSet,
Violation: IncludedViolation,
FinalHop: true,
}
// Intermediate nodes should never receive MPP fields.
case !isFinalHop && hasMPP:
return ErrInvalidPayload{
Type: record.MPPOnionType,
Violation: IncludedViolation,
FinalHop: isFinalHop,
}
}
return nil
}
// MultiPath returns the record corresponding the option_mpp parsed from the
// onion payload.
func (h *Payload) MultiPath() *record.MPP {
return h.MPP
}

@ -6,13 +6,15 @@ import (
"testing"
"github.com/lightningnetwork/lnd/htlcswitch/hop"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/record"
)
type decodePayloadTest struct {
name string
payload []byte
expErr error
name string
payload []byte
expErr error
shouldHaveMPP bool
}
var decodePayloadTests = []decodePayloadTest{
@ -79,9 +81,9 @@ var decodePayloadTests = []decodePayloadTest{
},
{
name: "required type after omitted hop id",
payload: []byte{0x02, 0x00, 0x04, 0x00, 0x08, 0x00},
payload: []byte{0x02, 0x00, 0x04, 0x00, 0x0a, 0x00},
expErr: hop.ErrInvalidPayload{
Type: 8,
Type: 10,
Violation: hop.RequiredViolation,
FinalHop: true,
},
@ -89,10 +91,10 @@ var decodePayloadTests = []decodePayloadTest{
{
name: "required type after included hop id",
payload: []byte{0x02, 0x00, 0x04, 0x00, 0x06, 0x08, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
},
expErr: hop.ErrInvalidPayload{
Type: 8,
Type: 10,
Violation: hop.RequiredViolation,
FinalHop: false,
},
@ -112,7 +114,7 @@ var decodePayloadTests = []decodePayloadTest{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
expErr: hop.ErrInvalidPayload{
Type: 6,
Type: record.NextHopOnionType,
Violation: hop.IncludedViolation,
FinalHop: true,
},
@ -128,6 +130,60 @@ var decodePayloadTests = []decodePayloadTest{
FinalHop: false,
},
},
{
name: "valid intermediate hop",
payload: []byte{0x02, 0x00, 0x04, 0x00, 0x06, 0x08, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
expErr: nil,
},
{
name: "valid final hop",
payload: []byte{0x02, 0x00, 0x04, 0x00},
expErr: nil,
},
{
name: "intermediate hop with mpp",
payload: []byte{
// amount
0x02, 0x00,
// cltv
0x04, 0x00,
// next hop id
0x06, 0x08,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// mpp
0x08, 0x21,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x08,
},
expErr: hop.ErrInvalidPayload{
Type: record.MPPOnionType,
Violation: hop.IncludedViolation,
FinalHop: false,
},
},
{
name: "final hop with mpp",
payload: []byte{
// amount
0x02, 0x00,
// cltv
0x04, 0x00,
// mpp
0x08, 0x21,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x08,
},
expErr: nil,
shouldHaveMPP: true,
},
}
// TestDecodeHopPayloadRecordValidation asserts that parsing the payloads in the
@ -142,9 +198,37 @@ func TestDecodeHopPayloadRecordValidation(t *testing.T) {
}
func testDecodeHopPayloadValidation(t *testing.T, test decodePayloadTest) {
_, err := hop.NewPayloadFromReader(bytes.NewReader(test.payload))
var (
testTotalMsat = lnwire.MilliSatoshi(8)
testAddr = [32]byte{
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
}
)
p, err := hop.NewPayloadFromReader(bytes.NewReader(test.payload))
if !reflect.DeepEqual(test.expErr, err) {
t.Fatalf("expected error mismatch, want: %v, got: %v",
test.expErr, err)
}
if err != nil {
return
}
// Assert MPP fields if we expect them.
if test.shouldHaveMPP {
if p.MPP == nil {
t.Fatalf("payload should have MPP record")
}
if p.MPP.TotalMsat() != testTotalMsat {
t.Fatalf("invalid total msat")
}
if p.MPP.PaymentAddr() != testAddr {
t.Fatalf("invalid payment addr")
}
} else if p.MPP != nil {
t.Fatalf("unexpected MPP payload")
}
}

@ -27,7 +27,7 @@ type InvoiceDatabase interface {
NotifyExitHopHtlc(payHash lntypes.Hash, paidAmount lnwire.MilliSatoshi,
expiry uint32, currentHeight int32,
circuitKey channeldb.CircuitKey, hodlChan chan<- interface{},
eob []byte) (*invoices.HodlEvent, error)
payload invoices.Payload) (*invoices.HodlEvent, error)
// CancelInvoice attempts to cancel the invoice corresponding to the
// passed payment hash.

@ -2642,7 +2642,7 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
heightNow := l.cfg.Switch.BestHeight()
fwdInfo, err := chanIterator.ForwardingInstructions()
pld, err := chanIterator.HopPayload()
if err != nil {
// If we're unable to process the onion payload, or we
// received invalid onion payload failure, then we
@ -2671,11 +2671,12 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
continue
}
fwdInfo := pld.ForwardingInfo()
switch fwdInfo.NextHop {
case hop.Exit:
updated, err := l.processExitHop(
pd, obfuscator, fwdInfo, heightNow,
chanIterator.ExtraOnionBlob(),
pd, obfuscator, fwdInfo, heightNow, pld,
)
if err != nil {
l.fail(LinkFailureError{code: ErrInternalError},
@ -2844,7 +2845,7 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg,
// returns a boolean indicating whether the commitment tx needs an update.
func (l *channelLink) processExitHop(pd *lnwallet.PaymentDescriptor,
obfuscator hop.ErrorEncrypter, fwdInfo hop.ForwardingInfo,
heightNow uint32, eob []byte) (bool, error) {
heightNow uint32, payload invoices.Payload) (bool, error) {
// If hodl.ExitSettle is requested, we will not validate the final hop's
// ADD, nor will we settle the corresponding invoice or respond with the
@ -2895,7 +2896,7 @@ func (l *channelLink) processExitHop(pd *lnwallet.PaymentDescriptor,
event, err := l.cfg.Registry.NotifyExitHopHtlc(
invoiceHash, pd.Amount, pd.Timeout, int32(heightNow),
circuitKey, l.hodlQueue.ChanIn(), eob,
circuitKey, l.hodlQueue.ChanIn(), payload,
)
switch err {

@ -22,6 +22,7 @@ import (
"github.com/coreos/bbolt"
"github.com/davecgh/go-spew/spew"
"github.com/go-errors/errors"
sphinx "github.com/lightningnetwork/lightning-onion"
"github.com/lightningnetwork/lnd/build"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/contractcourt"
@ -563,7 +564,7 @@ func TestExitNodeTimelockPayloadMismatch(t *testing.T) {
// per-hop payload for outgoing time lock to be the incorrect value.
// The proper value of the outgoing CLTV should be the policy set by
// the receiving node, instead we set it to be a random value.
hops[0].OutgoingCTLV = 500
hops[0].FwdInfo.OutgoingCTLV = 500
firstHop := n.firstBobChannelLink.ShortChanID()
_, err = makePayment(
n.aliceServer, n.bobServer, firstHop, hops, amount, htlcAmt,
@ -616,7 +617,7 @@ func TestExitNodeAmountPayloadMismatch(t *testing.T) {
// per-hop payload for amount to be the incorrect value. The proper
// value of the amount to forward should be the amount that the
// receiving node expects to receive.
hops[0].AmountToForward = 1
hops[0].FwdInfo.AmountToForward = 1
firstHop := n.firstBobChannelLink.ShortChanID()
_, err = makePayment(
n.aliceServer, n.bobServer, firstHop, hops, amount, htlcAmt,
@ -4354,13 +4355,13 @@ func generateHtlcAndInvoice(t *testing.T,
htlcAmt := lnwire.NewMSatFromSatoshis(10000)
htlcExpiry := testStartingHeight + testInvoiceCltvExpiry
hops := []hop.ForwardingInfo{
{
Network: hop.BitcoinNetwork,
NextHop: hop.Exit,
AmountToForward: htlcAmt,
OutgoingCTLV: uint32(htlcExpiry),
},
hops := []*hop.Payload{
hop.NewLegacyPayload(&sphinx.HopData{
Realm: [1]byte{}, // hop.BitcoinNetwork
NextAddress: [8]byte{}, // hop.Exit,
ForwardAmount: uint64(htlcAmt),
OutgoingCltv: uint32(htlcExpiry),
}),
}
blob, err := generateRoute(hops...)
if err != nil {

@ -265,16 +265,14 @@ func (s *mockServer) QuitSignal() <-chan struct{} {
// mockHopIterator represents the test version of hop iterator which instead
// of encrypting the path in onion blob just stores the path as a list of hops.
type mockHopIterator struct {
hops []hop.ForwardingInfo
hops []*hop.Payload
}
func newMockHopIterator(hops ...hop.ForwardingInfo) hop.Iterator {
func newMockHopIterator(hops ...*hop.Payload) hop.Iterator {
return &mockHopIterator{hops: hops}
}
func (r *mockHopIterator) ForwardingInstructions() (
hop.ForwardingInfo, error) {
func (r *mockHopIterator) HopPayload() (*hop.Payload, error) {
h := r.hops[0]
r.hops = r.hops[1:]
return h, nil
@ -300,7 +298,8 @@ func (r *mockHopIterator) EncodeNextHop(w io.Writer) error {
}
for _, hop := range r.hops {
if err := encodeFwdInfo(w, &hop); err != nil {
fwdInfo := hop.ForwardingInfo()
if err := encodeFwdInfo(w, &fwdInfo); err != nil {
return err
}
}
@ -434,14 +433,22 @@ func (p *mockIteratorDecoder) DecodeHopIterator(r io.Reader, rHash []byte,
}
hopLength := binary.BigEndian.Uint32(b[:])
hops := make([]hop.ForwardingInfo, hopLength)
hops := make([]*hop.Payload, hopLength)
for i := uint32(0); i < hopLength; i++ {
f := &hop.ForwardingInfo{}
if err := decodeFwdInfo(r, f); err != nil {
var f hop.ForwardingInfo
if err := decodeFwdInfo(r, &f); err != nil {
return nil, lnwire.CodeTemporaryChannelFailure
}
hops[i] = *f
var nextHopBytes [8]byte
binary.BigEndian.PutUint64(nextHopBytes[:], f.NextHop.ToUint64())
hops[i] = hop.NewLegacyPayload(&sphinx.HopData{
Realm: [1]byte{}, // hop.BitcoinNetwork
NextAddress: nextHopBytes,
ForwardAmount: uint64(f.AmountToForward),
OutgoingCltv: f.OutgoingCTLV,
})
}
return newMockHopIterator(hops...), lnwire.CodeNone
@ -807,10 +814,11 @@ func (i *mockInvoiceRegistry) SettleHodlInvoice(preimage lntypes.Preimage) error
func (i *mockInvoiceRegistry) NotifyExitHopHtlc(rhash lntypes.Hash,
amt lnwire.MilliSatoshi, expiry uint32, currentHeight int32,
circuitKey channeldb.CircuitKey, hodlChan chan<- interface{},
eob []byte) (*invoices.HodlEvent, error) {
payload invoices.Payload) (*invoices.HodlEvent, error) {
event, err := i.registry.NotifyExitHopHtlc(
rhash, amt, expiry, currentHeight, circuitKey, hodlChan, eob,
rhash, amt, expiry, currentHeight, circuitKey, hodlChan,
payload,
)
if err != nil {
return nil, err

@ -23,6 +23,7 @@ import (
"github.com/btcsuite/fastsha256"
"github.com/coreos/bbolt"
"github.com/go-errors/errors"
sphinx "github.com/lightningnetwork/lightning-onion"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/contractcourt"
"github.com/lightningnetwork/lnd/htlcswitch/hop"
@ -601,7 +602,7 @@ func generatePayment(invoiceAmt, htlcAmt lnwire.MilliSatoshi, timelock uint32,
}
// generateRoute generates the path blob by given array of peers.
func generateRoute(hops ...hop.ForwardingInfo) (
func generateRoute(hops ...*hop.Payload) (
[lnwire.OnionPacketSize]byte, error) {
var blob [lnwire.OnionPacketSize]byte
@ -642,13 +643,12 @@ type threeHopNetwork struct {
// also the time lock value needed to route an HTLC with the target amount over
// the specified path.
func generateHops(payAmt lnwire.MilliSatoshi, startingHeight uint32,
path ...*channelLink) (lnwire.MilliSatoshi, uint32,
[]hop.ForwardingInfo) {
path ...*channelLink) (lnwire.MilliSatoshi, uint32, []*hop.Payload) {
totalTimelock := startingHeight
runningAmt := payAmt
hops := make([]hop.ForwardingInfo, len(path))
hops := make([]*hop.Payload, len(path))
for i := len(path) - 1; i >= 0; i-- {
// If this is the last hop, then the next hop is the special
// "exit node". Otherwise, we look to the "prior" hop.
@ -676,7 +676,7 @@ func generateHops(payAmt lnwire.MilliSatoshi, startingHeight uint32,
amount := payAmt
if i != len(path)-1 {
prevHop := hops[i+1]
prevAmount := prevHop.AmountToForward
prevAmount := prevHop.ForwardingInfo().AmountToForward
fee := ExpectedFee(path[i].cfg.FwrdingPolicy, prevAmount)
runningAmt += fee
@ -687,12 +687,15 @@ func generateHops(payAmt lnwire.MilliSatoshi, startingHeight uint32,
amount = runningAmt - fee
}
hops[i] = hop.ForwardingInfo{
Network: hop.BitcoinNetwork,
NextHop: nextHop,
AmountToForward: amount,
OutgoingCTLV: timeLock,
}
var nextHopBytes [8]byte
binary.BigEndian.PutUint64(nextHopBytes[:], nextHop.ToUint64())
hops[i] = hop.NewLegacyPayload(&sphinx.HopData{
Realm: [1]byte{}, // hop.BitcoinNetwork
NextAddress: nextHopBytes,
ForwardAmount: uint64(amount),
OutgoingCltv: timeLock,
})
}
return runningAmt, totalTimelock, hops
@ -739,7 +742,7 @@ func waitForPayFuncResult(payFunc func() error, d time.Duration) error {
// * from Alice to Carol through the Bob
// * from Alice to some another peer through the Bob
func makePayment(sendingPeer, receivingPeer lnpeer.Peer,
firstHop lnwire.ShortChannelID, hops []hop.ForwardingInfo,
firstHop lnwire.ShortChannelID, hops []*hop.Payload,
invoiceAmt, htlcAmt lnwire.MilliSatoshi,
timelock uint32) *paymentResponse {
@ -773,7 +776,7 @@ func makePayment(sendingPeer, receivingPeer lnpeer.Peer,
// preparePayment creates an invoice at the receivingPeer and returns a function
// that, when called, launches the payment from the sendingPeer.
func preparePayment(sendingPeer, receivingPeer lnpeer.Peer,
firstHop lnwire.ShortChannelID, hops []hop.ForwardingInfo,
firstHop lnwire.ShortChannelID, hops []*hop.Payload,
invoiceAmt, htlcAmt lnwire.MilliSatoshi,
timelock uint32) (*channeldb.Invoice, func() error, error) {
@ -1265,7 +1268,7 @@ func (n *twoHopNetwork) stop() {
}
func (n *twoHopNetwork) makeHoldPayment(sendingPeer, receivingPeer lnpeer.Peer,
firstHop lnwire.ShortChannelID, hops []hop.ForwardingInfo,
firstHop lnwire.ShortChannelID, hops []*hop.Payload,
invoiceAmt, htlcAmt lnwire.MilliSatoshi,
timelock uint32, preimage lntypes.Preimage) chan error {

11
invoices/interface.go Normal file

@ -0,0 +1,11 @@
package invoices
import "github.com/lightningnetwork/lnd/record"
// Payload abstracts access to any additional fields provided in the final hop's
// TLV onion payload.
type Payload interface {
// MultiPath returns the record corresponding the option_mpp parsed from
// the onion payload.
MultiPath() *record.MPP
}

@ -429,7 +429,7 @@ func (i *InvoiceRegistry) LookupInvoice(rHash lntypes.Hash) (channeldb.Invoice,
func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash,
amtPaid lnwire.MilliSatoshi, expiry uint32, currentHeight int32,
circuitKey channeldb.CircuitKey, hodlChan chan<- interface{},
eob []byte) (*HodlEvent, error) {
payload Payload) (*HodlEvent, error) {
i.Lock()
defer i.Unlock()

@ -13,7 +13,9 @@ import (
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcutil"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/record"
"github.com/lightningnetwork/lnd/routing"
"github.com/lightningnetwork/lnd/routing/route"
"github.com/lightningnetwork/lnd/tlv"
@ -352,6 +354,17 @@ func (r *RouterBackend) MarshallRoute(route *route.Route) (*lnrpc.Route, error)
chanCapacity = incomingAmt.ToSatoshis()
}
// Extract the MPP fields if present on this hop.
var mpp *lnrpc.MPPRecord
if hop.MPP != nil {
addr := hop.MPP.PaymentAddr()
mpp = &lnrpc.MPPRecord{
PaymentAddr: addr[:],
TotalAmtMsat: int64(hop.MPP.TotalMsat()),
}
}
resp.Hops[i] = &lnrpc.Hop{
ChanId: hop.ChannelID,
ChanCapacity: int64(chanCapacity),
@ -364,6 +377,7 @@ func (r *RouterBackend) MarshallRoute(route *route.Route) (*lnrpc.Route, error)
hop.PubKeyBytes[:],
),
TlvPayload: !hop.LegacyPayload,
MppRecord: mpp,
}
incomingAmt = hop.AmtToForward
}
@ -396,6 +410,11 @@ func (r *RouterBackend) UnmarshallHopByChannelLookup(hop *lnrpc.Hop,
var tlvRecords []tlv.Record
mpp, err := UnmarshalMPP(hop.MppRecord)
if err != nil {
return nil, err
}
return &route.Hop{
OutgoingTimeLock: hop.Expiry,
AmtToForward: lnwire.MilliSatoshi(hop.AmtToForwardMsat),
@ -403,6 +422,7 @@ func (r *RouterBackend) UnmarshallHopByChannelLookup(hop *lnrpc.Hop,
ChannelID: hop.ChanId,
TLVRecords: tlvRecords,
LegacyPayload: !hop.TlvPayload,
MPP: mpp,
}, nil
}
@ -420,6 +440,11 @@ func UnmarshallKnownPubkeyHop(hop *lnrpc.Hop) (*route.Hop, error) {
var tlvRecords []tlv.Record
mpp, err := UnmarshalMPP(hop.MppRecord)
if err != nil {
return nil, err
}
return &route.Hop{
OutgoingTimeLock: hop.Expiry,
AmtToForward: lnwire.MilliSatoshi(hop.AmtToForwardMsat),
@ -427,6 +452,7 @@ func UnmarshallKnownPubkeyHop(hop *lnrpc.Hop) (*route.Hop, error) {
ChannelID: hop.ChanId,
TLVRecords: tlvRecords,
LegacyPayload: !hop.TlvPayload,
MPP: mpp,
}, nil
}
@ -712,3 +738,45 @@ func ValidateCLTVLimit(val, max uint32) (uint32, error) {
return val, nil
}
}
// UnmarshalMPP accepts the mpp_total_amt_msat and mpp_payment_addr fields from
// an RPC request and converts into an record.MPP object. An error is returned
// if the payment address is not 0 or 32 bytes. If the total amount and payment
// address are zero-value, the return value will be nil signaling there is no
// MPP record to attach to this hop. Otherwise, a non-nil reocrd will be
// contained combining the provided values.
func UnmarshalMPP(reqMPP *lnrpc.MPPRecord) (*record.MPP, error) {
// If no MPP record was submitted, assume the user wants to send a
// regular payment.
if reqMPP == nil {
return nil, nil
}
reqTotal := reqMPP.TotalAmtMsat
reqAddr := reqMPP.PaymentAddr
switch {
// No MPP fields were provided.
case reqTotal == 0 && len(reqAddr) == 0:
return nil, fmt.Errorf("missing total_msat and payment_addr")
// Total is present, but payment address is missing.
case reqTotal > 0 && len(reqAddr) == 0:
return nil, fmt.Errorf("missing payment_addr")
// Payment address is present, but total is missing.
case reqTotal == 0 && len(reqAddr) > 0:
return nil, fmt.Errorf("missing total_msat")
}
addr, err := lntypes.MakeHash(reqAddr)
if err != nil {
return nil, fmt.Errorf("unable to parse "+
"payment_addr: %v", err)
}
total := lnwire.MilliSatoshi(reqTotal)
return record.NewMPP(total, addr), nil
}

@ -180,3 +180,123 @@ func (m *mockMissionControl) GetPairHistorySnapshot(fromNode,
return routing.TimedPairResult{}
}
type mppOutcome byte
const (
valid mppOutcome = iota
invalid
nompp
)
type unmarshalMPPTest struct {
name string
mpp *lnrpc.MPPRecord
outcome mppOutcome
}
// TestUnmarshalMPP checks both positive and negative cases of UnmarshalMPP to
// assert that an MPP record is only returned when both fields are properly
// specified. It also asserts that zero-values for both inputs is also valid,
// but returns a nil record.
func TestUnmarshalMPP(t *testing.T) {
tests := []unmarshalMPPTest{
{
name: "nil record",
mpp: nil,
outcome: nompp,
},
{
name: "invalid total or addr",
mpp: &lnrpc.MPPRecord{
PaymentAddr: nil,
TotalAmtMsat: 0,
},
outcome: invalid,
},
{
name: "valid total only",
mpp: &lnrpc.MPPRecord{
PaymentAddr: nil,
TotalAmtMsat: 8,
},
outcome: invalid,
},
{
name: "valid addr only",
mpp: &lnrpc.MPPRecord{
PaymentAddr: bytes.Repeat([]byte{0x02}, 32),
TotalAmtMsat: 0,
},
outcome: invalid,
},
{
name: "valid total and invalid addr",
mpp: &lnrpc.MPPRecord{
PaymentAddr: []byte{0x02},
TotalAmtMsat: 8,
},
outcome: invalid,
},
{
name: "valid total and valid addr",
mpp: &lnrpc.MPPRecord{
PaymentAddr: bytes.Repeat([]byte{0x02}, 32),
TotalAmtMsat: 8,
},
outcome: valid,
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
testUnmarshalMPP(t, test)
})
}
}
func testUnmarshalMPP(t *testing.T, test unmarshalMPPTest) {
mpp, err := UnmarshalMPP(test.mpp)
switch test.outcome {
// Valid arguments should result in no error, a non-nil MPP record, and
// the fields should be set correctly.
case valid:
if err != nil {
t.Fatalf("unable to parse mpp record: %v", err)
}
if mpp == nil {
t.Fatalf("mpp payload should be non-nil")
}
if int64(mpp.TotalMsat()) != test.mpp.TotalAmtMsat {
t.Fatalf("incorrect total msat")
}
addr := mpp.PaymentAddr()
if !bytes.Equal(addr[:], test.mpp.PaymentAddr) {
t.Fatalf("incorrect payment addr")
}
// Invalid arguments should produce a failure and nil MPP record.
case invalid:
if err == nil {
t.Fatalf("expected failure for invalid mpp")
}
if mpp != nil {
t.Fatalf("mpp payload should be nil for failure")
}
// Arguments that produce no MPP field should return no error and no MPP
// record.
case nompp:
if err != nil {
t.Fatalf("failure for args resulting for no-mpp")
}
if mpp != nil {
t.Fatalf("mpp payload should be nil for no-mpp")
}
default:
t.Fatalf("test case has non-standard outcome")
}
}

@ -217,7 +217,7 @@ func (x Invoice_InvoiceState) String() string {
}
func (Invoice_InvoiceState) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{95, 0}
return fileDescriptor_77a6da22d6a3feb1, []int{96, 0}
}
type Payment_PaymentStatus int32
@ -248,7 +248,7 @@ func (x Payment_PaymentStatus) String() string {
}
func (Payment_PaymentStatus) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{102, 0}
return fileDescriptor_77a6da22d6a3feb1, []int{103, 0}
}
type GenSeedRequest struct {
@ -5374,10 +5374,16 @@ type Hop struct {
//*
//If set to true, then this hop will be encoded using the new variable length
//TLV format.
TlvPayload bool `protobuf:"varint,9,opt,name=tlv_payload,proto3" json:"tlv_payload,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
TlvPayload bool `protobuf:"varint,9,opt,name=tlv_payload,proto3" json:"tlv_payload,omitempty"`
//*
//An optional TLV record tha singals the use of an MPP payment. If present,
//the receiver will enforce that that the same mpp_record is included in the
//final hop payload of all non-zero payments in the HTLC set. If empty, a
//regular single-shot payment is or was attempted.
MppRecord *MPPRecord `protobuf:"bytes,10,opt,name=mpp_record,proto3" json:"mpp_record,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Hop) Reset() { *m = Hop{} }
@ -5470,6 +5476,70 @@ func (m *Hop) GetTlvPayload() bool {
return false
}
func (m *Hop) GetMppRecord() *MPPRecord {
if m != nil {
return m.MppRecord
}
return nil
}
type MPPRecord struct {
//*
//A unique, random identifier used to authenticate the sender as the intended
//payer of a multi-path payment. The payment_addr must be the same for all
//subpayments, and match the payment_addr provided in the receiver's invoice.
//The same payment_addr must be used on all subpayments.
PaymentAddr []byte `protobuf:"bytes,11,opt,name=payment_addr,proto3" json:"payment_addr,omitempty"`
//*
//The total amount in milli-satoshis being sent as part of a larger multi-path
//payment. The caller is responsible for ensuring subpayments to the same node
//and payment_hash sum exactly to total_amt_msat. The same
//total_amt_msat must be used on all subpayments.
TotalAmtMsat int64 `protobuf:"varint,10,opt,name=total_amt_msat,proto3" json:"total_amt_msat,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *MPPRecord) Reset() { *m = MPPRecord{} }
func (m *MPPRecord) String() string { return proto.CompactTextString(m) }
func (*MPPRecord) ProtoMessage() {}
func (*MPPRecord) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{74}
}
func (m *MPPRecord) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_MPPRecord.Unmarshal(m, b)
}
func (m *MPPRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_MPPRecord.Marshal(b, m, deterministic)
}
func (m *MPPRecord) XXX_Merge(src proto.Message) {
xxx_messageInfo_MPPRecord.Merge(m, src)
}
func (m *MPPRecord) XXX_Size() int {
return xxx_messageInfo_MPPRecord.Size(m)
}
func (m *MPPRecord) XXX_DiscardUnknown() {
xxx_messageInfo_MPPRecord.DiscardUnknown(m)
}
var xxx_messageInfo_MPPRecord proto.InternalMessageInfo
func (m *MPPRecord) GetPaymentAddr() []byte {
if m != nil {
return m.PaymentAddr
}
return nil
}
func (m *MPPRecord) GetTotalAmtMsat() int64 {
if m != nil {
return m.TotalAmtMsat
}
return 0
}
//*
//A path through the channel graph which runs over one or more channels in
//succession. This struct carries all the information required to craft the
@ -5513,7 +5583,7 @@ func (m *Route) Reset() { *m = Route{} }
func (m *Route) String() string { return proto.CompactTextString(m) }
func (*Route) ProtoMessage() {}
func (*Route) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{74}
return fileDescriptor_77a6da22d6a3feb1, []int{75}
}
func (m *Route) XXX_Unmarshal(b []byte) error {
@ -5592,7 +5662,7 @@ func (m *NodeInfoRequest) Reset() { *m = NodeInfoRequest{} }
func (m *NodeInfoRequest) String() string { return proto.CompactTextString(m) }
func (*NodeInfoRequest) ProtoMessage() {}
func (*NodeInfoRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{75}
return fileDescriptor_77a6da22d6a3feb1, []int{76}
}
func (m *NodeInfoRequest) XXX_Unmarshal(b []byte) error {
@ -5649,7 +5719,7 @@ func (m *NodeInfo) Reset() { *m = NodeInfo{} }
func (m *NodeInfo) String() string { return proto.CompactTextString(m) }
func (*NodeInfo) ProtoMessage() {}
func (*NodeInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{76}
return fileDescriptor_77a6da22d6a3feb1, []int{77}
}
func (m *NodeInfo) XXX_Unmarshal(b []byte) error {
@ -5718,7 +5788,7 @@ func (m *LightningNode) Reset() { *m = LightningNode{} }
func (m *LightningNode) String() string { return proto.CompactTextString(m) }
func (*LightningNode) ProtoMessage() {}
func (*LightningNode) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{77}
return fileDescriptor_77a6da22d6a3feb1, []int{78}
}
func (m *LightningNode) XXX_Unmarshal(b []byte) error {
@ -5786,7 +5856,7 @@ func (m *NodeAddress) Reset() { *m = NodeAddress{} }
func (m *NodeAddress) String() string { return proto.CompactTextString(m) }
func (*NodeAddress) ProtoMessage() {}
func (*NodeAddress) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{78}
return fileDescriptor_77a6da22d6a3feb1, []int{79}
}
func (m *NodeAddress) XXX_Unmarshal(b []byte) error {
@ -5838,7 +5908,7 @@ func (m *RoutingPolicy) Reset() { *m = RoutingPolicy{} }
func (m *RoutingPolicy) String() string { return proto.CompactTextString(m) }
func (*RoutingPolicy) ProtoMessage() {}
func (*RoutingPolicy) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{79}
return fileDescriptor_77a6da22d6a3feb1, []int{80}
}
func (m *RoutingPolicy) XXX_Unmarshal(b []byte) error {
@ -5936,7 +6006,7 @@ func (m *ChannelEdge) Reset() { *m = ChannelEdge{} }
func (m *ChannelEdge) String() string { return proto.CompactTextString(m) }
func (*ChannelEdge) ProtoMessage() {}
func (*ChannelEdge) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{80}
return fileDescriptor_77a6da22d6a3feb1, []int{81}
}
func (m *ChannelEdge) XXX_Unmarshal(b []byte) error {
@ -6029,7 +6099,7 @@ func (m *ChannelGraphRequest) Reset() { *m = ChannelGraphRequest{} }
func (m *ChannelGraphRequest) String() string { return proto.CompactTextString(m) }
func (*ChannelGraphRequest) ProtoMessage() {}
func (*ChannelGraphRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{81}
return fileDescriptor_77a6da22d6a3feb1, []int{82}
}
func (m *ChannelGraphRequest) XXX_Unmarshal(b []byte) error {
@ -6072,7 +6142,7 @@ func (m *ChannelGraph) Reset() { *m = ChannelGraph{} }
func (m *ChannelGraph) String() string { return proto.CompactTextString(m) }
func (*ChannelGraph) ProtoMessage() {}
func (*ChannelGraph) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{82}
return fileDescriptor_77a6da22d6a3feb1, []int{83}
}
func (m *ChannelGraph) XXX_Unmarshal(b []byte) error {
@ -6122,7 +6192,7 @@ func (m *ChanInfoRequest) Reset() { *m = ChanInfoRequest{} }
func (m *ChanInfoRequest) String() string { return proto.CompactTextString(m) }
func (*ChanInfoRequest) ProtoMessage() {}
func (*ChanInfoRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{83}
return fileDescriptor_77a6da22d6a3feb1, []int{84}
}
func (m *ChanInfoRequest) XXX_Unmarshal(b []byte) error {
@ -6160,7 +6230,7 @@ func (m *NetworkInfoRequest) Reset() { *m = NetworkInfoRequest{} }
func (m *NetworkInfoRequest) String() string { return proto.CompactTextString(m) }
func (*NetworkInfoRequest) ProtoMessage() {}
func (*NetworkInfoRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{84}
return fileDescriptor_77a6da22d6a3feb1, []int{85}
}
func (m *NetworkInfoRequest) XXX_Unmarshal(b []byte) error {
@ -6203,7 +6273,7 @@ func (m *NetworkInfo) Reset() { *m = NetworkInfo{} }
func (m *NetworkInfo) String() string { return proto.CompactTextString(m) }
func (*NetworkInfo) ProtoMessage() {}
func (*NetworkInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{85}
return fileDescriptor_77a6da22d6a3feb1, []int{86}
}
func (m *NetworkInfo) XXX_Unmarshal(b []byte) error {
@ -6311,7 +6381,7 @@ func (m *StopRequest) Reset() { *m = StopRequest{} }
func (m *StopRequest) String() string { return proto.CompactTextString(m) }
func (*StopRequest) ProtoMessage() {}
func (*StopRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{86}
return fileDescriptor_77a6da22d6a3feb1, []int{87}
}
func (m *StopRequest) XXX_Unmarshal(b []byte) error {
@ -6342,7 +6412,7 @@ func (m *StopResponse) Reset() { *m = StopResponse{} }
func (m *StopResponse) String() string { return proto.CompactTextString(m) }
func (*StopResponse) ProtoMessage() {}
func (*StopResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{87}
return fileDescriptor_77a6da22d6a3feb1, []int{88}
}
func (m *StopResponse) XXX_Unmarshal(b []byte) error {
@ -6373,7 +6443,7 @@ func (m *GraphTopologySubscription) Reset() { *m = GraphTopologySubscrip
func (m *GraphTopologySubscription) String() string { return proto.CompactTextString(m) }
func (*GraphTopologySubscription) ProtoMessage() {}
func (*GraphTopologySubscription) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{88}
return fileDescriptor_77a6da22d6a3feb1, []int{89}
}
func (m *GraphTopologySubscription) XXX_Unmarshal(b []byte) error {
@ -6407,7 +6477,7 @@ func (m *GraphTopologyUpdate) Reset() { *m = GraphTopologyUpdate{} }
func (m *GraphTopologyUpdate) String() string { return proto.CompactTextString(m) }
func (*GraphTopologyUpdate) ProtoMessage() {}
func (*GraphTopologyUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{89}
return fileDescriptor_77a6da22d6a3feb1, []int{90}
}
func (m *GraphTopologyUpdate) XXX_Unmarshal(b []byte) error {
@ -6464,7 +6534,7 @@ func (m *NodeUpdate) Reset() { *m = NodeUpdate{} }
func (m *NodeUpdate) String() string { return proto.CompactTextString(m) }
func (*NodeUpdate) ProtoMessage() {}
func (*NodeUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{90}
return fileDescriptor_77a6da22d6a3feb1, []int{91}
}
func (m *NodeUpdate) XXX_Unmarshal(b []byte) error {
@ -6540,7 +6610,7 @@ func (m *ChannelEdgeUpdate) Reset() { *m = ChannelEdgeUpdate{} }
func (m *ChannelEdgeUpdate) String() string { return proto.CompactTextString(m) }
func (*ChannelEdgeUpdate) ProtoMessage() {}
func (*ChannelEdgeUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{91}
return fileDescriptor_77a6da22d6a3feb1, []int{92}
}
func (m *ChannelEdgeUpdate) XXX_Unmarshal(b []byte) error {
@ -6621,7 +6691,7 @@ func (m *ClosedChannelUpdate) Reset() { *m = ClosedChannelUpdate{} }
func (m *ClosedChannelUpdate) String() string { return proto.CompactTextString(m) }
func (*ClosedChannelUpdate) ProtoMessage() {}
func (*ClosedChannelUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{92}
return fileDescriptor_77a6da22d6a3feb1, []int{93}
}
func (m *ClosedChannelUpdate) XXX_Unmarshal(b []byte) error {
@ -6692,7 +6762,7 @@ func (m *HopHint) Reset() { *m = HopHint{} }
func (m *HopHint) String() string { return proto.CompactTextString(m) }
func (*HopHint) ProtoMessage() {}
func (*HopHint) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{93}
return fileDescriptor_77a6da22d6a3feb1, []int{94}
}
func (m *HopHint) XXX_Unmarshal(b []byte) error {
@ -6762,7 +6832,7 @@ func (m *RouteHint) Reset() { *m = RouteHint{} }
func (m *RouteHint) String() string { return proto.CompactTextString(m) }
func (*RouteHint) ProtoMessage() {}
func (*RouteHint) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{94}
return fileDescriptor_77a6da22d6a3feb1, []int{95}
}
func (m *RouteHint) XXX_Unmarshal(b []byte) error {
@ -6880,7 +6950,7 @@ func (m *Invoice) Reset() { *m = Invoice{} }
func (m *Invoice) String() string { return proto.CompactTextString(m) }
func (*Invoice) ProtoMessage() {}
func (*Invoice) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{95}
return fileDescriptor_77a6da22d6a3feb1, []int{96}
}
func (m *Invoice) XXX_Unmarshal(b []byte) error {
@ -7085,7 +7155,7 @@ func (m *InvoiceHTLC) Reset() { *m = InvoiceHTLC{} }
func (m *InvoiceHTLC) String() string { return proto.CompactTextString(m) }
func (*InvoiceHTLC) ProtoMessage() {}
func (*InvoiceHTLC) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{96}
return fileDescriptor_77a6da22d6a3feb1, []int{97}
}
func (m *InvoiceHTLC) XXX_Unmarshal(b []byte) error {
@ -7184,7 +7254,7 @@ func (m *AddInvoiceResponse) Reset() { *m = AddInvoiceResponse{} }
func (m *AddInvoiceResponse) String() string { return proto.CompactTextString(m) }
func (*AddInvoiceResponse) ProtoMessage() {}
func (*AddInvoiceResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{97}
return fileDescriptor_77a6da22d6a3feb1, []int{98}
}
func (m *AddInvoiceResponse) XXX_Unmarshal(b []byte) error {
@ -7242,7 +7312,7 @@ func (m *PaymentHash) Reset() { *m = PaymentHash{} }
func (m *PaymentHash) String() string { return proto.CompactTextString(m) }
func (*PaymentHash) ProtoMessage() {}
func (*PaymentHash) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{98}
return fileDescriptor_77a6da22d6a3feb1, []int{99}
}
func (m *PaymentHash) XXX_Unmarshal(b []byte) error {
@ -7299,7 +7369,7 @@ func (m *ListInvoiceRequest) Reset() { *m = ListInvoiceRequest{} }
func (m *ListInvoiceRequest) String() string { return proto.CompactTextString(m) }
func (*ListInvoiceRequest) ProtoMessage() {}
func (*ListInvoiceRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{99}
return fileDescriptor_77a6da22d6a3feb1, []int{100}
}
func (m *ListInvoiceRequest) XXX_Unmarshal(b []byte) error {
@ -7370,7 +7440,7 @@ func (m *ListInvoiceResponse) Reset() { *m = ListInvoiceResponse{} }
func (m *ListInvoiceResponse) String() string { return proto.CompactTextString(m) }
func (*ListInvoiceResponse) ProtoMessage() {}
func (*ListInvoiceResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{100}
return fileDescriptor_77a6da22d6a3feb1, []int{101}
}
func (m *ListInvoiceResponse) XXX_Unmarshal(b []byte) error {
@ -7434,7 +7504,7 @@ func (m *InvoiceSubscription) Reset() { *m = InvoiceSubscription{} }
func (m *InvoiceSubscription) String() string { return proto.CompactTextString(m) }
func (*InvoiceSubscription) ProtoMessage() {}
func (*InvoiceSubscription) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{101}
return fileDescriptor_77a6da22d6a3feb1, []int{102}
}
func (m *InvoiceSubscription) XXX_Unmarshal(b []byte) error {
@ -7503,7 +7573,7 @@ func (m *Payment) Reset() { *m = Payment{} }
func (m *Payment) String() string { return proto.CompactTextString(m) }
func (*Payment) ProtoMessage() {}
func (*Payment) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{102}
return fileDescriptor_77a6da22d6a3feb1, []int{103}
}
func (m *Payment) XXX_Unmarshal(b []byte) error {
@ -7625,7 +7695,7 @@ func (m *ListPaymentsRequest) Reset() { *m = ListPaymentsRequest{} }
func (m *ListPaymentsRequest) String() string { return proto.CompactTextString(m) }
func (*ListPaymentsRequest) ProtoMessage() {}
func (*ListPaymentsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{103}
return fileDescriptor_77a6da22d6a3feb1, []int{104}
}
func (m *ListPaymentsRequest) XXX_Unmarshal(b []byte) error {
@ -7665,7 +7735,7 @@ func (m *ListPaymentsResponse) Reset() { *m = ListPaymentsResponse{} }
func (m *ListPaymentsResponse) String() string { return proto.CompactTextString(m) }
func (*ListPaymentsResponse) ProtoMessage() {}
func (*ListPaymentsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{104}
return fileDescriptor_77a6da22d6a3feb1, []int{105}
}
func (m *ListPaymentsResponse) XXX_Unmarshal(b []byte) error {
@ -7703,7 +7773,7 @@ func (m *DeleteAllPaymentsRequest) Reset() { *m = DeleteAllPaymentsReque
func (m *DeleteAllPaymentsRequest) String() string { return proto.CompactTextString(m) }
func (*DeleteAllPaymentsRequest) ProtoMessage() {}
func (*DeleteAllPaymentsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{105}
return fileDescriptor_77a6da22d6a3feb1, []int{106}
}
func (m *DeleteAllPaymentsRequest) XXX_Unmarshal(b []byte) error {
@ -7734,7 +7804,7 @@ func (m *DeleteAllPaymentsResponse) Reset() { *m = DeleteAllPaymentsResp
func (m *DeleteAllPaymentsResponse) String() string { return proto.CompactTextString(m) }
func (*DeleteAllPaymentsResponse) ProtoMessage() {}
func (*DeleteAllPaymentsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{106}
return fileDescriptor_77a6da22d6a3feb1, []int{107}
}
func (m *DeleteAllPaymentsResponse) XXX_Unmarshal(b []byte) error {
@ -7766,7 +7836,7 @@ func (m *AbandonChannelRequest) Reset() { *m = AbandonChannelRequest{} }
func (m *AbandonChannelRequest) String() string { return proto.CompactTextString(m) }
func (*AbandonChannelRequest) ProtoMessage() {}
func (*AbandonChannelRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{107}
return fileDescriptor_77a6da22d6a3feb1, []int{108}
}
func (m *AbandonChannelRequest) XXX_Unmarshal(b []byte) error {
@ -7804,7 +7874,7 @@ func (m *AbandonChannelResponse) Reset() { *m = AbandonChannelResponse{}
func (m *AbandonChannelResponse) String() string { return proto.CompactTextString(m) }
func (*AbandonChannelResponse) ProtoMessage() {}
func (*AbandonChannelResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{108}
return fileDescriptor_77a6da22d6a3feb1, []int{109}
}
func (m *AbandonChannelResponse) XXX_Unmarshal(b []byte) error {
@ -7837,7 +7907,7 @@ func (m *DebugLevelRequest) Reset() { *m = DebugLevelRequest{} }
func (m *DebugLevelRequest) String() string { return proto.CompactTextString(m) }
func (*DebugLevelRequest) ProtoMessage() {}
func (*DebugLevelRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{109}
return fileDescriptor_77a6da22d6a3feb1, []int{110}
}
func (m *DebugLevelRequest) XXX_Unmarshal(b []byte) error {
@ -7883,7 +7953,7 @@ func (m *DebugLevelResponse) Reset() { *m = DebugLevelResponse{} }
func (m *DebugLevelResponse) String() string { return proto.CompactTextString(m) }
func (*DebugLevelResponse) ProtoMessage() {}
func (*DebugLevelResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{110}
return fileDescriptor_77a6da22d6a3feb1, []int{111}
}
func (m *DebugLevelResponse) XXX_Unmarshal(b []byte) error {
@ -7923,7 +7993,7 @@ func (m *PayReqString) Reset() { *m = PayReqString{} }
func (m *PayReqString) String() string { return proto.CompactTextString(m) }
func (*PayReqString) ProtoMessage() {}
func (*PayReqString) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{111}
return fileDescriptor_77a6da22d6a3feb1, []int{112}
}
func (m *PayReqString) XXX_Unmarshal(b []byte) error {
@ -7971,7 +8041,7 @@ func (m *PayReq) Reset() { *m = PayReq{} }
func (m *PayReq) String() string { return proto.CompactTextString(m) }
func (*PayReq) ProtoMessage() {}
func (*PayReq) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{112}
return fileDescriptor_77a6da22d6a3feb1, []int{113}
}
func (m *PayReq) XXX_Unmarshal(b []byte) error {
@ -8072,7 +8142,7 @@ func (m *FeeReportRequest) Reset() { *m = FeeReportRequest{} }
func (m *FeeReportRequest) String() string { return proto.CompactTextString(m) }
func (*FeeReportRequest) ProtoMessage() {}
func (*FeeReportRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{113}
return fileDescriptor_77a6da22d6a3feb1, []int{114}
}
func (m *FeeReportRequest) XXX_Unmarshal(b []byte) error {
@ -8111,7 +8181,7 @@ func (m *ChannelFeeReport) Reset() { *m = ChannelFeeReport{} }
func (m *ChannelFeeReport) String() string { return proto.CompactTextString(m) }
func (*ChannelFeeReport) ProtoMessage() {}
func (*ChannelFeeReport) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{114}
return fileDescriptor_77a6da22d6a3feb1, []int{115}
}
func (m *ChannelFeeReport) XXX_Unmarshal(b []byte) error {
@ -8178,7 +8248,7 @@ func (m *FeeReportResponse) Reset() { *m = FeeReportResponse{} }
func (m *FeeReportResponse) String() string { return proto.CompactTextString(m) }
func (*FeeReportResponse) ProtoMessage() {}
func (*FeeReportResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{115}
return fileDescriptor_77a6da22d6a3feb1, []int{116}
}
func (m *FeeReportResponse) XXX_Unmarshal(b []byte) error {
@ -8249,7 +8319,7 @@ func (m *PolicyUpdateRequest) Reset() { *m = PolicyUpdateRequest{} }
func (m *PolicyUpdateRequest) String() string { return proto.CompactTextString(m) }
func (*PolicyUpdateRequest) ProtoMessage() {}
func (*PolicyUpdateRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{116}
return fileDescriptor_77a6da22d6a3feb1, []int{117}
}
func (m *PolicyUpdateRequest) XXX_Unmarshal(b []byte) error {
@ -8353,7 +8423,7 @@ func (m *PolicyUpdateResponse) Reset() { *m = PolicyUpdateResponse{} }
func (m *PolicyUpdateResponse) String() string { return proto.CompactTextString(m) }
func (*PolicyUpdateResponse) ProtoMessage() {}
func (*PolicyUpdateResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{117}
return fileDescriptor_77a6da22d6a3feb1, []int{118}
}
func (m *PolicyUpdateResponse) XXX_Unmarshal(b []byte) error {
@ -8392,7 +8462,7 @@ func (m *ForwardingHistoryRequest) Reset() { *m = ForwardingHistoryReque
func (m *ForwardingHistoryRequest) String() string { return proto.CompactTextString(m) }
func (*ForwardingHistoryRequest) ProtoMessage() {}
func (*ForwardingHistoryRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{118}
return fileDescriptor_77a6da22d6a3feb1, []int{119}
}
func (m *ForwardingHistoryRequest) XXX_Unmarshal(b []byte) error {
@ -8469,7 +8539,7 @@ func (m *ForwardingEvent) Reset() { *m = ForwardingEvent{} }
func (m *ForwardingEvent) String() string { return proto.CompactTextString(m) }
func (*ForwardingEvent) ProtoMessage() {}
func (*ForwardingEvent) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{119}
return fileDescriptor_77a6da22d6a3feb1, []int{120}
}
func (m *ForwardingEvent) XXX_Unmarshal(b []byte) error {
@ -8567,7 +8637,7 @@ func (m *ForwardingHistoryResponse) Reset() { *m = ForwardingHistoryResp
func (m *ForwardingHistoryResponse) String() string { return proto.CompactTextString(m) }
func (*ForwardingHistoryResponse) ProtoMessage() {}
func (*ForwardingHistoryResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{120}
return fileDescriptor_77a6da22d6a3feb1, []int{121}
}
func (m *ForwardingHistoryResponse) XXX_Unmarshal(b []byte) error {
@ -8614,7 +8684,7 @@ func (m *ExportChannelBackupRequest) Reset() { *m = ExportChannelBackupR
func (m *ExportChannelBackupRequest) String() string { return proto.CompactTextString(m) }
func (*ExportChannelBackupRequest) ProtoMessage() {}
func (*ExportChannelBackupRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{121}
return fileDescriptor_77a6da22d6a3feb1, []int{122}
}
func (m *ExportChannelBackupRequest) XXX_Unmarshal(b []byte) error {
@ -8660,7 +8730,7 @@ func (m *ChannelBackup) Reset() { *m = ChannelBackup{} }
func (m *ChannelBackup) String() string { return proto.CompactTextString(m) }
func (*ChannelBackup) ProtoMessage() {}
func (*ChannelBackup) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{122}
return fileDescriptor_77a6da22d6a3feb1, []int{123}
}
func (m *ChannelBackup) XXX_Unmarshal(b []byte) error {
@ -8713,7 +8783,7 @@ func (m *MultiChanBackup) Reset() { *m = MultiChanBackup{} }
func (m *MultiChanBackup) String() string { return proto.CompactTextString(m) }
func (*MultiChanBackup) ProtoMessage() {}
func (*MultiChanBackup) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{123}
return fileDescriptor_77a6da22d6a3feb1, []int{124}
}
func (m *MultiChanBackup) XXX_Unmarshal(b []byte) error {
@ -8758,7 +8828,7 @@ func (m *ChanBackupExportRequest) Reset() { *m = ChanBackupExportRequest
func (m *ChanBackupExportRequest) String() string { return proto.CompactTextString(m) }
func (*ChanBackupExportRequest) ProtoMessage() {}
func (*ChanBackupExportRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{124}
return fileDescriptor_77a6da22d6a3feb1, []int{125}
}
func (m *ChanBackupExportRequest) XXX_Unmarshal(b []byte) error {
@ -8797,7 +8867,7 @@ func (m *ChanBackupSnapshot) Reset() { *m = ChanBackupSnapshot{} }
func (m *ChanBackupSnapshot) String() string { return proto.CompactTextString(m) }
func (*ChanBackupSnapshot) ProtoMessage() {}
func (*ChanBackupSnapshot) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{125}
return fileDescriptor_77a6da22d6a3feb1, []int{126}
}
func (m *ChanBackupSnapshot) XXX_Unmarshal(b []byte) error {
@ -8845,7 +8915,7 @@ func (m *ChannelBackups) Reset() { *m = ChannelBackups{} }
func (m *ChannelBackups) String() string { return proto.CompactTextString(m) }
func (*ChannelBackups) ProtoMessage() {}
func (*ChannelBackups) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{126}
return fileDescriptor_77a6da22d6a3feb1, []int{127}
}
func (m *ChannelBackups) XXX_Unmarshal(b []byte) error {
@ -8887,7 +8957,7 @@ func (m *RestoreChanBackupRequest) Reset() { *m = RestoreChanBackupReque
func (m *RestoreChanBackupRequest) String() string { return proto.CompactTextString(m) }
func (*RestoreChanBackupRequest) ProtoMessage() {}
func (*RestoreChanBackupRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{127}
return fileDescriptor_77a6da22d6a3feb1, []int{128}
}
func (m *RestoreChanBackupRequest) XXX_Unmarshal(b []byte) error {
@ -8963,7 +9033,7 @@ func (m *RestoreBackupResponse) Reset() { *m = RestoreBackupResponse{} }
func (m *RestoreBackupResponse) String() string { return proto.CompactTextString(m) }
func (*RestoreBackupResponse) ProtoMessage() {}
func (*RestoreBackupResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{128}
return fileDescriptor_77a6da22d6a3feb1, []int{129}
}
func (m *RestoreBackupResponse) XXX_Unmarshal(b []byte) error {
@ -8994,7 +9064,7 @@ func (m *ChannelBackupSubscription) Reset() { *m = ChannelBackupSubscrip
func (m *ChannelBackupSubscription) String() string { return proto.CompactTextString(m) }
func (*ChannelBackupSubscription) ProtoMessage() {}
func (*ChannelBackupSubscription) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{129}
return fileDescriptor_77a6da22d6a3feb1, []int{130}
}
func (m *ChannelBackupSubscription) XXX_Unmarshal(b []byte) error {
@ -9025,7 +9095,7 @@ func (m *VerifyChanBackupResponse) Reset() { *m = VerifyChanBackupRespon
func (m *VerifyChanBackupResponse) String() string { return proto.CompactTextString(m) }
func (*VerifyChanBackupResponse) ProtoMessage() {}
func (*VerifyChanBackupResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{130}
return fileDescriptor_77a6da22d6a3feb1, []int{131}
}
func (m *VerifyChanBackupResponse) XXX_Unmarshal(b []byte) error {
@ -9060,7 +9130,7 @@ func (m *MacaroonPermission) Reset() { *m = MacaroonPermission{} }
func (m *MacaroonPermission) String() string { return proto.CompactTextString(m) }
func (*MacaroonPermission) ProtoMessage() {}
func (*MacaroonPermission) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{131}
return fileDescriptor_77a6da22d6a3feb1, []int{132}
}
func (m *MacaroonPermission) XXX_Unmarshal(b []byte) error {
@ -9107,7 +9177,7 @@ func (m *BakeMacaroonRequest) Reset() { *m = BakeMacaroonRequest{} }
func (m *BakeMacaroonRequest) String() string { return proto.CompactTextString(m) }
func (*BakeMacaroonRequest) ProtoMessage() {}
func (*BakeMacaroonRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{132}
return fileDescriptor_77a6da22d6a3feb1, []int{133}
}
func (m *BakeMacaroonRequest) XXX_Unmarshal(b []byte) error {
@ -9147,7 +9217,7 @@ func (m *BakeMacaroonResponse) Reset() { *m = BakeMacaroonResponse{} }
func (m *BakeMacaroonResponse) String() string { return proto.CompactTextString(m) }
func (*BakeMacaroonResponse) ProtoMessage() {}
func (*BakeMacaroonResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{133}
return fileDescriptor_77a6da22d6a3feb1, []int{134}
}
func (m *BakeMacaroonResponse) XXX_Unmarshal(b []byte) error {
@ -9265,6 +9335,7 @@ func init() {
proto.RegisterType((*EdgeLocator)(nil), "lnrpc.EdgeLocator")
proto.RegisterType((*QueryRoutesResponse)(nil), "lnrpc.QueryRoutesResponse")
proto.RegisterType((*Hop)(nil), "lnrpc.Hop")
proto.RegisterType((*MPPRecord)(nil), "lnrpc.MPPRecord")
proto.RegisterType((*Route)(nil), "lnrpc.Route")
proto.RegisterType((*NodeInfoRequest)(nil), "lnrpc.NodeInfoRequest")
proto.RegisterType((*NodeInfo)(nil), "lnrpc.NodeInfo")
@ -9330,547 +9401,550 @@ func init() {
func init() { proto.RegisterFile("rpc.proto", fileDescriptor_77a6da22d6a3feb1) }
var fileDescriptor_77a6da22d6a3feb1 = []byte{
// 8631 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x7d, 0x5d, 0x6c, 0x1c, 0x5b,
0xb6, 0x56, 0xfa, 0xcf, 0xee, 0x5e, 0xdd, 0xb6, 0xdb, 0xdb, 0x8e, 0xdd, 0xe9, 0xe4, 0x24, 0x3e,
0x35, 0xb9, 0x27, 0x99, 0xcc, 0x19, 0x27, 0x27, 0x33, 0x73, 0xc8, 0x3d, 0xe1, 0x72, 0xf1, 0x5f,
0xe2, 0xcc, 0x38, 0x8e, 0xa7, 0x9c, 0x4c, 0x98, 0x99, 0x7b, 0xd5, 0x53, 0xee, 0xde, 0xb6, 0x6b,
0xd2, 0x5d, 0xd5, 0x53, 0x55, 0x6d, 0xc7, 0x73, 0x38, 0x48, 0x20, 0x84, 0x10, 0x2f, 0xe8, 0xc0,
0x0b, 0x20, 0xd0, 0x95, 0xe6, 0x22, 0x71, 0x2f, 0x08, 0x01, 0x0f, 0x48, 0x80, 0xae, 0xc4, 0x03,
0x0f, 0x48, 0x48, 0x88, 0x07, 0x1e, 0x90, 0x78, 0xe0, 0x0a, 0x81, 0x84, 0xae, 0x10, 0x2f, 0x48,
0xbc, 0xa3, 0xb5, 0xf6, 0x4f, 0xed, 0x5d, 0x55, 0x1d, 0xe7, 0xcc, 0x0c, 0x3c, 0xb9, 0xf7, 0xb7,
0x77, 0xed, 0xdf, 0xb5, 0xd6, 0x5e, 0x6b, 0xed, 0xb5, 0xb7, 0xa1, 0x11, 0x8d, 0xfb, 0xeb, 0xe3,
0x28, 0x4c, 0x42, 0x56, 0x1b, 0x06, 0xd1, 0xb8, 0xdf, 0xbd, 0x71, 0x12, 0x86, 0x27, 0x43, 0x7e,
0xdf, 0x1b, 0xfb, 0xf7, 0xbd, 0x20, 0x08, 0x13, 0x2f, 0xf1, 0xc3, 0x20, 0x16, 0x85, 0x9c, 0x9f,
0xc0, 0xfc, 0x53, 0x1e, 0x1c, 0x72, 0x3e, 0x70, 0xf9, 0xcf, 0x26, 0x3c, 0x4e, 0xd8, 0x37, 0x60,
0xd1, 0xe3, 0x3f, 0xe7, 0x7c, 0xd0, 0x1b, 0x7b, 0x71, 0x3c, 0x3e, 0x8d, 0xbc, 0x98, 0x77, 0x4a,
0x6b, 0xa5, 0xbb, 0x2d, 0xb7, 0x2d, 0x32, 0x0e, 0x34, 0xce, 0x3e, 0x84, 0x56, 0x8c, 0x45, 0x79,
0x90, 0x44, 0xe1, 0xf8, 0xa2, 0x53, 0xa6, 0x72, 0x4d, 0xc4, 0x76, 0x04, 0xe4, 0x0c, 0x61, 0x41,
0xb7, 0x10, 0x8f, 0xc3, 0x20, 0xe6, 0xec, 0x01, 0x2c, 0xf7, 0xfd, 0xf1, 0x29, 0x8f, 0x7a, 0xf4,
0xf1, 0x28, 0xe0, 0xa3, 0x30, 0xf0, 0xfb, 0x9d, 0xd2, 0x5a, 0xe5, 0x6e, 0xc3, 0x65, 0x22, 0x0f,
0xbf, 0x78, 0x2e, 0x73, 0xd8, 0x1d, 0x58, 0xe0, 0x81, 0xc0, 0xf9, 0x80, 0xbe, 0x92, 0x4d, 0xcd,
0xa7, 0x30, 0x7e, 0xe0, 0xfc, 0xd5, 0x32, 0x2c, 0x3e, 0x0b, 0xfc, 0xe4, 0xb5, 0x37, 0x1c, 0xf2,
0x44, 0x8d, 0xe9, 0x0e, 0x2c, 0x9c, 0x13, 0x40, 0x63, 0x3a, 0x0f, 0xa3, 0x81, 0x1c, 0xd1, 0xbc,
0x80, 0x0f, 0x24, 0x3a, 0xb5, 0x67, 0xe5, 0xa9, 0x3d, 0x2b, 0x9c, 0xae, 0xca, 0x94, 0xe9, 0xba,
0x03, 0x0b, 0x11, 0xef, 0x87, 0x67, 0x3c, 0xba, 0xe8, 0x9d, 0xfb, 0xc1, 0x20, 0x3c, 0xef, 0x54,
0xd7, 0x4a, 0x77, 0x6b, 0xee, 0xbc, 0x82, 0x5f, 0x13, 0xca, 0x36, 0x61, 0xa1, 0x7f, 0xea, 0x05,
0x01, 0x1f, 0xf6, 0x8e, 0xbc, 0xfe, 0x9b, 0xc9, 0x38, 0xee, 0xd4, 0xd6, 0x4a, 0x77, 0x9b, 0x0f,
0xaf, 0xad, 0xd3, 0xaa, 0xae, 0x6f, 0x9d, 0x7a, 0xc1, 0x26, 0xe5, 0x1c, 0x06, 0xde, 0x38, 0x3e,
0x0d, 0x13, 0x77, 0x5e, 0x7e, 0x21, 0xe0, 0xd8, 0x59, 0x06, 0x66, 0xce, 0x84, 0x98, 0x7b, 0xe7,
0x1f, 0x95, 0x60, 0xe9, 0x55, 0x30, 0x0c, 0xfb, 0x6f, 0x7e, 0xc9, 0x29, 0x2a, 0x18, 0x43, 0xf9,
0x7d, 0xc7, 0x50, 0xf9, 0xaa, 0x63, 0x58, 0x81, 0x65, 0xbb, 0xb3, 0x72, 0x14, 0x1c, 0xae, 0xe2,
0xd7, 0x27, 0x5c, 0x75, 0x4b, 0x0d, 0xe3, 0xeb, 0xd0, 0xee, 0x4f, 0xa2, 0x88, 0x07, 0xb9, 0x71,
0x2c, 0x48, 0x5c, 0x0f, 0xe4, 0x43, 0x68, 0x05, 0xfc, 0x3c, 0x2d, 0x26, 0x69, 0x37, 0xe0, 0xe7,
0xaa, 0x88, 0xd3, 0x81, 0x95, 0x6c, 0x33, 0xb2, 0x03, 0xff, 0xb5, 0x04, 0xd5, 0x57, 0xc9, 0xdb,
0x90, 0xad, 0x43, 0x35, 0xb9, 0x18, 0x0b, 0x0e, 0x99, 0x7f, 0xc8, 0xe4, 0xd0, 0x36, 0x06, 0x83,
0x88, 0xc7, 0xf1, 0xcb, 0x8b, 0x31, 0x77, 0x5b, 0x9e, 0x48, 0xf4, 0xb0, 0x1c, 0xeb, 0xc0, 0xac,
0x4c, 0x53, 0x83, 0x0d, 0x57, 0x25, 0xd9, 0x4d, 0x00, 0x6f, 0x14, 0x4e, 0x82, 0xa4, 0x17, 0x7b,
0x09, 0x4d, 0x55, 0xc5, 0x35, 0x10, 0x76, 0x03, 0x1a, 0xe3, 0x37, 0xbd, 0xb8, 0x1f, 0xf9, 0xe3,
0x84, 0xc8, 0xa6, 0xe1, 0xa6, 0x00, 0xfb, 0x06, 0xd4, 0xc3, 0x49, 0x32, 0x0e, 0xfd, 0x20, 0x91,
0xa4, 0xb2, 0x20, 0xfb, 0xf2, 0x62, 0x92, 0x1c, 0x20, 0xec, 0xea, 0x02, 0xec, 0x36, 0xcc, 0xf5,
0xc3, 0xe0, 0xd8, 0x8f, 0x46, 0x42, 0x18, 0x74, 0x66, 0xa8, 0x35, 0x1b, 0x74, 0xfe, 0x65, 0x19,
0x9a, 0x2f, 0x23, 0x2f, 0x88, 0xbd, 0x3e, 0x02, 0xd8, 0xf5, 0xe4, 0x6d, 0xef, 0xd4, 0x8b, 0x4f,
0x69, 0xb4, 0x0d, 0x57, 0x25, 0xd9, 0x0a, 0xcc, 0x88, 0x8e, 0xd2, 0x98, 0x2a, 0xae, 0x4c, 0xb1,
0x8f, 0x61, 0x31, 0x98, 0x8c, 0x7a, 0x76, 0x5b, 0x15, 0xa2, 0x96, 0x7c, 0x06, 0x4e, 0xc0, 0x11,
0xae, 0xb5, 0x68, 0x42, 0x8c, 0xd0, 0x40, 0x98, 0x03, 0x2d, 0x99, 0xe2, 0xfe, 0xc9, 0xa9, 0x18,
0x66, 0xcd, 0xb5, 0x30, 0xac, 0x23, 0xf1, 0x47, 0xbc, 0x17, 0x27, 0xde, 0x68, 0x2c, 0x87, 0x65,
0x20, 0x94, 0x1f, 0x26, 0xde, 0xb0, 0x77, 0xcc, 0x79, 0xdc, 0x99, 0x95, 0xf9, 0x1a, 0x61, 0x1f,
0xc1, 0xfc, 0x80, 0xc7, 0x49, 0x4f, 0x2e, 0x0a, 0x8f, 0x3b, 0x75, 0x62, 0xfd, 0x0c, 0x8a, 0xf5,
0x44, 0xde, 0x79, 0x0f, 0x27, 0x80, 0xbf, 0xed, 0x34, 0x44, 0x5f, 0x53, 0x04, 0x29, 0xe7, 0x29,
0x4f, 0x8c, 0xd9, 0x8b, 0x25, 0x85, 0x3a, 0x7b, 0xc0, 0x0c, 0x78, 0x9b, 0x27, 0x9e, 0x3f, 0x8c,
0xd9, 0xa7, 0xd0, 0x4a, 0x8c, 0xc2, 0x24, 0x0a, 0x9b, 0x9a, 0x9c, 0x8c, 0x0f, 0x5c, 0xab, 0x9c,
0xf3, 0x14, 0xea, 0x4f, 0x38, 0xdf, 0xf3, 0x47, 0x7e, 0xc2, 0x56, 0xa0, 0x76, 0xec, 0xbf, 0xe5,
0x82, 0xe0, 0x2b, 0xbb, 0x57, 0x5c, 0x91, 0x64, 0x5d, 0x98, 0x1d, 0xf3, 0xa8, 0xcf, 0xd5, 0xf2,
0xec, 0x5e, 0x71, 0x15, 0xb0, 0x39, 0x0b, 0xb5, 0x21, 0x7e, 0xec, 0xfc, 0xaf, 0x0a, 0x34, 0x0f,
0x79, 0xa0, 0x19, 0x89, 0x41, 0x15, 0x87, 0x2c, 0x99, 0x87, 0x7e, 0xb3, 0x5b, 0xd0, 0xa4, 0x69,
0x88, 0x93, 0xc8, 0x0f, 0x4e, 0x24, 0xfd, 0x02, 0x42, 0x87, 0x84, 0xb0, 0x36, 0x54, 0xbc, 0x91,
0xa2, 0x5d, 0xfc, 0x89, 0x4c, 0x36, 0xf6, 0x2e, 0x46, 0xc8, 0x8f, 0x7a, 0x55, 0x5b, 0x6e, 0x53,
0x62, 0xbb, 0xb8, 0xac, 0xeb, 0xb0, 0x64, 0x16, 0x51, 0xb5, 0xd7, 0xa8, 0xf6, 0x45, 0xa3, 0xa4,
0x6c, 0xe4, 0x0e, 0x2c, 0xa8, 0xf2, 0x91, 0xe8, 0x2c, 0xad, 0x73, 0xc3, 0x9d, 0x97, 0xb0, 0x1a,
0xc2, 0x5d, 0x68, 0x1f, 0xfb, 0x81, 0x37, 0xec, 0xf5, 0x87, 0xc9, 0x59, 0x6f, 0xc0, 0x87, 0x89,
0x47, 0x2b, 0x5e, 0x73, 0xe7, 0x09, 0xdf, 0x1a, 0x26, 0x67, 0xdb, 0x88, 0xb2, 0x8f, 0xa1, 0x71,
0xcc, 0x79, 0x8f, 0x66, 0xa2, 0x53, 0xb7, 0xb8, 0x47, 0xcd, 0xae, 0x5b, 0x3f, 0x56, 0xf3, 0xfc,
0x31, 0xb4, 0xc3, 0x49, 0x72, 0x12, 0xfa, 0xc1, 0x49, 0x0f, 0xe5, 0x55, 0xcf, 0x1f, 0x10, 0x05,
0x54, 0x37, 0xcb, 0x0f, 0x4a, 0xee, 0xbc, 0xca, 0x43, 0xc9, 0xf1, 0x6c, 0xc0, 0x3e, 0x00, 0xa0,
0xf6, 0x45, 0xe5, 0xb0, 0x56, 0xba, 0x3b, 0xe7, 0x36, 0x10, 0x11, 0x95, 0x7d, 0x06, 0x75, 0x9a,
0xd3, 0x64, 0x78, 0xd6, 0x69, 0xd2, 0xa2, 0xdf, 0x92, 0x2d, 0x1b, 0xab, 0xb1, 0xbe, 0xcd, 0xe3,
0xe4, 0xe5, 0xf0, 0x0c, 0xf7, 0xd4, 0x0b, 0x77, 0x76, 0x20, 0x52, 0xdd, 0xcf, 0xa0, 0x65, 0x66,
0xe0, 0xf4, 0xbf, 0xe1, 0x17, 0xb4, 0x64, 0x55, 0x17, 0x7f, 0xb2, 0x65, 0xa8, 0x9d, 0x79, 0xc3,
0x09, 0x97, 0xc2, 0x4d, 0x24, 0x3e, 0x2b, 0x3f, 0x2a, 0x39, 0xff, 0xa2, 0x04, 0x2d, 0xd1, 0x82,
0xdc, 0x94, 0x6f, 0xc3, 0x9c, 0x9a, 0x56, 0x1e, 0x45, 0x61, 0x24, 0x79, 0xdc, 0x06, 0xd9, 0x3d,
0x68, 0x2b, 0x60, 0x1c, 0x71, 0x7f, 0xe4, 0x9d, 0xa8, 0xba, 0x73, 0x38, 0x7b, 0x98, 0xd6, 0x18,
0x85, 0x93, 0x84, 0x4b, 0xf1, 0xdf, 0x92, 0xe3, 0x73, 0x11, 0x73, 0xed, 0x22, 0xc8, 0xe3, 0x05,
0xf4, 0x62, 0x61, 0xce, 0x97, 0x25, 0x60, 0xd8, 0xf5, 0x97, 0xa1, 0xa8, 0x42, 0x2e, 0x77, 0x96,
0xd4, 0x4a, 0xef, 0x4d, 0x6a, 0xe5, 0x69, 0xa4, 0xe6, 0x40, 0x4d, 0xf4, 0xbc, 0x5a, 0xd0, 0x73,
0x91, 0xf5, 0xdd, 0x6a, 0xbd, 0xd2, 0xae, 0x3a, 0xff, 0xb9, 0x02, 0xcb, 0x5b, 0x62, 0xef, 0xda,
0xe8, 0xf7, 0xf9, 0x58, 0x13, 0xe1, 0x2d, 0x68, 0x06, 0xe1, 0x80, 0xf7, 0xc6, 0x93, 0x23, 0xb5,
0x36, 0x2d, 0x17, 0x10, 0x3a, 0x20, 0x84, 0xe8, 0xe3, 0xd4, 0xf3, 0x03, 0xd1, 0x69, 0x31, 0x97,
0x0d, 0x42, 0xa8, 0xcb, 0x1f, 0xc1, 0xc2, 0x98, 0x07, 0x03, 0x93, 0xd6, 0x84, 0x76, 0x31, 0x27,
0x61, 0x49, 0x66, 0xb7, 0xa0, 0x79, 0x3c, 0x11, 0xe5, 0x90, 0x05, 0xab, 0x44, 0x03, 0x20, 0xa1,
0x8d, 0x51, 0xc2, 0xae, 0x41, 0x7d, 0x3c, 0x89, 0x4f, 0x29, 0xb7, 0x46, 0xb9, 0xb3, 0x98, 0xc6,
0xac, 0x0f, 0x00, 0x06, 0x93, 0x38, 0x91, 0x24, 0x3a, 0x43, 0x99, 0x0d, 0x44, 0x04, 0x89, 0x7e,
0x13, 0x96, 0x46, 0xde, 0xdb, 0x1e, 0xd1, 0x4e, 0xcf, 0x0f, 0x7a, 0xc7, 0x43, 0x12, 0xbf, 0xb3,
0x54, 0xae, 0x3d, 0xf2, 0xde, 0xfe, 0x00, 0x73, 0x9e, 0x05, 0x4f, 0x08, 0x47, 0xfe, 0x54, 0xfb,
0x7e, 0xc4, 0x63, 0x1e, 0x9d, 0x71, 0x62, 0xa9, 0xaa, 0xde, 0xdc, 0x5d, 0x81, 0x62, 0x8f, 0x46,
0x38, 0xee, 0x64, 0xd8, 0x17, 0xfc, 0xe3, 0xce, 0x8e, 0xfc, 0x60, 0x37, 0x19, 0xf6, 0xd9, 0x0d,
0x00, 0x64, 0xc8, 0x31, 0x8f, 0x7a, 0x6f, 0xce, 0x89, 0x69, 0xaa, 0xc4, 0x80, 0x07, 0x3c, 0xfa,
0xde, 0x39, 0xbb, 0x0e, 0x8d, 0x7e, 0x4c, 0x1c, 0xed, 0x5d, 0x74, 0x9a, 0xc4, 0x51, 0xf5, 0x7e,
0x8c, 0xbc, 0xec, 0x5d, 0xb0, 0x8f, 0x81, 0x61, 0x6f, 0x3d, 0x5a, 0x05, 0x3e, 0xa0, 0xea, 0xe3,
0x4e, 0x8b, 0x4a, 0x61, 0x67, 0x37, 0x64, 0x06, 0xb6, 0x13, 0xb3, 0xaf, 0xc1, 0x9c, 0xea, 0xec,
0xf1, 0xd0, 0x3b, 0x89, 0x3b, 0x73, 0x54, 0xb0, 0x25, 0xc1, 0x27, 0x88, 0x39, 0xaf, 0x85, 0xb6,
0x61, 0xac, 0xad, 0xe4, 0x19, 0xdc, 0xf7, 0x08, 0xa1, 0x75, 0xad, 0xbb, 0x32, 0x55, 0xb4, 0x68,
0xe5, 0x82, 0x45, 0x73, 0x7e, 0x51, 0x82, 0x96, 0xac, 0x99, 0xb6, 0x68, 0xf6, 0x00, 0x98, 0x5a,
0xc5, 0xe4, 0xad, 0x3f, 0xe8, 0x1d, 0x5d, 0x24, 0x3c, 0x16, 0x44, 0xb3, 0x7b, 0xc5, 0x2d, 0xc8,
0x43, 0x61, 0x64, 0xa1, 0x71, 0x12, 0x09, 0x7a, 0xde, 0xbd, 0xe2, 0xe6, 0x72, 0x90, 0xbd, 0x50,
0x09, 0x98, 0x24, 0x3d, 0x3f, 0x18, 0xf0, 0xb7, 0x44, 0x4a, 0x73, 0xae, 0x85, 0x6d, 0xce, 0x43,
0xcb, 0xfc, 0xce, 0xf9, 0x29, 0xd4, 0x95, 0x0a, 0x41, 0xdb, 0x67, 0xa6, 0x5f, 0xae, 0x81, 0xb0,
0x2e, 0xd4, 0xed, 0x5e, 0xb8, 0xf5, 0xaf, 0xd2, 0xb6, 0xf3, 0x67, 0xa0, 0xbd, 0x87, 0x44, 0x14,
0x20, 0xd1, 0x4a, 0xbd, 0x68, 0x05, 0x66, 0x0c, 0xe6, 0x69, 0xb8, 0x32, 0x85, 0x3b, 0xd4, 0x69,
0x18, 0x27, 0xb2, 0x1d, 0xfa, 0xed, 0xfc, 0xdb, 0x12, 0xb0, 0x9d, 0x38, 0xf1, 0x47, 0x5e, 0xc2,
0x9f, 0x70, 0x2d, 0x1a, 0x5e, 0x40, 0x0b, 0x6b, 0x7b, 0x19, 0x6e, 0x08, 0x2d, 0x45, 0xec, 0xae,
0xdf, 0x90, 0xec, 0x9c, 0xff, 0x60, 0xdd, 0x2c, 0x2d, 0x84, 0xae, 0x55, 0x01, 0x72, 0x5b, 0xe2,
0x45, 0x27, 0x3c, 0x21, 0x15, 0x46, 0x2a, 0xc0, 0x20, 0xa0, 0xad, 0x30, 0x38, 0xee, 0xfe, 0x36,
0x2c, 0xe6, 0xea, 0x30, 0xe5, 0x73, 0xa3, 0x40, 0x3e, 0x57, 0x4c, 0xf9, 0xdc, 0x87, 0x25, 0xab,
0x5f, 0x92, 0xe2, 0x3a, 0x30, 0x8b, 0x8c, 0x81, 0x1a, 0x22, 0xed, 0xf2, 0xae, 0x4a, 0xb2, 0x87,
0xb0, 0x7c, 0xcc, 0x79, 0xe4, 0x25, 0x94, 0x24, 0xd6, 0xc1, 0x35, 0x91, 0x35, 0x17, 0xe6, 0x39,
0xff, 0xad, 0x04, 0x0b, 0x28, 0x49, 0x9f, 0x7b, 0xc1, 0x85, 0x9a, 0xab, 0xbd, 0xc2, 0xb9, 0xba,
0x6b, 0x6c, 0x4a, 0x46, 0xe9, 0xaf, 0x3a, 0x51, 0x95, 0xec, 0x44, 0xb1, 0x35, 0x68, 0x59, 0xdd,
0xad, 0x09, 0x95, 0x2c, 0xf6, 0x92, 0x03, 0x1e, 0x6d, 0x5e, 0x24, 0xfc, 0x57, 0x9f, 0xca, 0x8f,
0xa0, 0x9d, 0x76, 0x5b, 0xce, 0x23, 0x83, 0x2a, 0x12, 0xa6, 0xac, 0x80, 0x7e, 0x3b, 0x7f, 0xb7,
0x24, 0x0a, 0x6e, 0x85, 0xbe, 0x56, 0xd7, 0xb0, 0x20, 0x6a, 0x7d, 0xaa, 0x20, 0xfe, 0x9e, 0xaa,
0xee, 0xfe, 0xea, 0x83, 0x45, 0x99, 0x18, 0xf3, 0x60, 0xd0, 0xf3, 0x86, 0x43, 0x12, 0xc4, 0x75,
0x77, 0x16, 0xd3, 0x1b, 0xc3, 0xa1, 0x73, 0x07, 0x16, 0x8d, 0xde, 0xbd, 0x63, 0x1c, 0xfb, 0xc0,
0xf6, 0xfc, 0x38, 0x79, 0x15, 0xc4, 0x63, 0x43, 0x1b, 0xba, 0x0e, 0x0d, 0x94, 0xb6, 0xd8, 0x33,
0xc1, 0xb9, 0x35, 0x17, 0xc5, 0x2f, 0xf6, 0x2b, 0xa6, 0x4c, 0xef, 0xad, 0xcc, 0x2c, 0xcb, 0x4c,
0xef, 0x2d, 0x65, 0x3a, 0x8f, 0x60, 0xc9, 0xaa, 0x4f, 0x36, 0xfd, 0x21, 0xd4, 0x26, 0xc9, 0xdb,
0x50, 0xe9, 0xaa, 0x4d, 0x49, 0x21, 0x68, 0x15, 0xb9, 0x22, 0xc7, 0x79, 0x0c, 0x8b, 0xfb, 0xfc,
0x5c, 0x32, 0xb2, 0xea, 0xc8, 0x47, 0x97, 0x5a, 0x4c, 0x94, 0xef, 0xac, 0x03, 0x33, 0x3f, 0x4e,
0x19, 0x40, 0xd9, 0x4f, 0x25, 0xcb, 0x7e, 0x72, 0x3e, 0x02, 0x76, 0xe8, 0x9f, 0x04, 0xcf, 0x79,
0x1c, 0x7b, 0x27, 0x9a, 0xf5, 0xdb, 0x50, 0x19, 0xc5, 0x27, 0x52, 0x54, 0xe1, 0x4f, 0xe7, 0x5b,
0xb0, 0x64, 0x95, 0x93, 0x15, 0xdf, 0x80, 0x46, 0xec, 0x9f, 0x04, 0x5e, 0x32, 0x89, 0xb8, 0xac,
0x3a, 0x05, 0x9c, 0x27, 0xb0, 0xfc, 0x03, 0x1e, 0xf9, 0xc7, 0x17, 0x97, 0x55, 0x6f, 0xd7, 0x53,
0xce, 0xd6, 0xb3, 0x03, 0x57, 0x33, 0xf5, 0xc8, 0xe6, 0x05, 0xf9, 0xca, 0x95, 0xac, 0xbb, 0x22,
0x61, 0xc8, 0xbe, 0xb2, 0x29, 0xfb, 0x9c, 0x57, 0xc0, 0xb6, 0xc2, 0x20, 0xe0, 0xfd, 0xe4, 0x80,
0xf3, 0x28, 0x75, 0xdd, 0xa4, 0xb4, 0xda, 0x7c, 0xb8, 0x2a, 0x67, 0x36, 0x2b, 0x50, 0x25, 0x11,
0x33, 0xa8, 0x8e, 0x79, 0x34, 0xa2, 0x8a, 0xeb, 0x2e, 0xfd, 0x76, 0xae, 0xc2, 0x92, 0x55, 0xad,
0x34, 0x76, 0x3f, 0x81, 0xab, 0xdb, 0x7e, 0xdc, 0xcf, 0x37, 0xd8, 0x81, 0xd9, 0xf1, 0xe4, 0xa8,
0x97, 0x72, 0xa2, 0x4a, 0xa2, 0xfd, 0x93, 0xfd, 0x44, 0x56, 0xf6, 0x57, 0x4a, 0x50, 0xdd, 0x7d,
0xb9, 0xb7, 0x85, 0x7b, 0x85, 0x1f, 0xf4, 0xc3, 0x11, 0x6a, 0x60, 0x62, 0xd0, 0x3a, 0x3d, 0x95,
0xc3, 0x6e, 0x40, 0x83, 0x14, 0x37, 0x34, 0xf9, 0xa4, 0x1e, 0x94, 0x02, 0x68, 0x6e, 0xf2, 0xb7,
0x63, 0x3f, 0x22, 0x7b, 0x52, 0x59, 0x89, 0x55, 0xda, 0x66, 0xf2, 0x19, 0xce, 0x2f, 0x66, 0x61,
0x56, 0x6e, 0xbe, 0x62, 0x23, 0x4f, 0xfc, 0x33, 0x9e, 0x6e, 0xe4, 0x98, 0x42, 0xa5, 0x38, 0xe2,
0xa3, 0x30, 0xd1, 0xfa, 0x9b, 0x58, 0x06, 0x1b, 0x24, 0x73, 0x5a, 0x2a, 0x11, 0xc2, 0x00, 0xaf,
0x88, 0x52, 0x16, 0xc8, 0x6e, 0xc0, 0xac, 0x52, 0x06, 0xaa, 0xda, 0x5a, 0x50, 0x10, 0xce, 0x46,
0xdf, 0x1b, 0x7b, 0x7d, 0x3f, 0xb9, 0x90, 0x62, 0x41, 0xa7, 0xb1, 0xfe, 0x61, 0xd8, 0xf7, 0x86,
0xbd, 0x23, 0x6f, 0xe8, 0x05, 0x7d, 0xae, 0xcc, 0x75, 0x0b, 0x44, 0xd3, 0x55, 0x76, 0x4b, 0x15,
0x13, 0xe6, 0x6d, 0x06, 0xc5, 0x3d, 0xbc, 0x1f, 0x8e, 0x46, 0x7e, 0x82, 0x16, 0x2f, 0xa9, 0x66,
0x15, 0xd7, 0x40, 0x84, 0x73, 0x80, 0x52, 0xe7, 0x62, 0x06, 0x1b, 0xca, 0x39, 0x60, 0x80, 0x58,
0x4b, 0x46, 0x43, 0xab, 0xb8, 0x06, 0x82, 0x6b, 0x31, 0x09, 0x62, 0x9e, 0x24, 0x43, 0x3e, 0xd0,
0x1d, 0x6a, 0x52, 0xb1, 0x7c, 0x06, 0x7b, 0x00, 0x4b, 0xc2, 0x08, 0x8f, 0xbd, 0x24, 0x8c, 0x4f,
0xfd, 0xb8, 0x17, 0xa3, 0xb9, 0xda, 0xa2, 0xf2, 0x45, 0x59, 0xec, 0x11, 0xac, 0x66, 0xe0, 0x88,
0xf7, 0xb9, 0x7f, 0xc6, 0x07, 0xa4, 0xc2, 0x55, 0xdc, 0x69, 0xd9, 0x6c, 0x0d, 0x9a, 0xc1, 0x64,
0xd4, 0x9b, 0x8c, 0x07, 0x1e, 0x2a, 0x31, 0xf3, 0xa4, 0x5c, 0x9a, 0x10, 0xfb, 0x04, 0x94, 0x9e,
0x26, 0xb5, 0xc7, 0x05, 0x4b, 0xc2, 0x21, 0xf5, 0xba, 0x76, 0x09, 0x24, 0xcc, 0x54, 0x25, 0x6d,
0x4b, 0x23, 0x4f, 0x01, 0xc4, 0x27, 0x91, 0x7f, 0xe6, 0x25, 0xbc, 0xb3, 0x28, 0x84, 0xba, 0x4c,
0xe2, 0x77, 0x7e, 0xe0, 0x27, 0xbe, 0x97, 0x84, 0x51, 0x87, 0x51, 0x5e, 0x0a, 0xe0, 0x24, 0x12,
0x7d, 0xc4, 0x89, 0x97, 0x4c, 0x62, 0xa9, 0xa1, 0x2e, 0x09, 0x6b, 0x25, 0x97, 0xc1, 0x3e, 0x85,
0x15, 0x41, 0x11, 0x94, 0x25, 0x75, 0x6f, 0x52, 0x15, 0x96, 0x69, 0x46, 0xa6, 0xe4, 0xe2, 0x54,
0x4a, 0x12, 0xc9, 0x7d, 0x78, 0x55, 0x4c, 0xe5, 0x94, 0x6c, 0xec, 0x1f, 0xf6, 0xc0, 0xef, 0xf7,
0x64, 0x09, 0x64, 0x91, 0x15, 0x1a, 0x45, 0x3e, 0x03, 0x49, 0x7c, 0xe8, 0x1f, 0xf3, 0xc4, 0x1f,
0xf1, 0xce, 0xaa, 0x20, 0x71, 0x95, 0x46, 0x06, 0x9c, 0x8c, 0x29, 0xa7, 0x23, 0x18, 0x5e, 0xa4,
0x9c, 0xdf, 0x2b, 0x89, 0xcd, 0x47, 0x32, 0x6a, 0x6c, 0x98, 0x55, 0x82, 0x45, 0x7b, 0x61, 0x30,
0xbc, 0x90, 0x5c, 0x0b, 0x02, 0x7a, 0x11, 0x0c, 0x2f, 0x50, 0xb1, 0xf7, 0x03, 0xb3, 0x88, 0x90,
0x73, 0x2d, 0x05, 0x52, 0xa1, 0x5b, 0xd0, 0x1c, 0x4f, 0x8e, 0x86, 0x7e, 0x5f, 0x14, 0xa9, 0x88,
0x5a, 0x04, 0x44, 0x05, 0xd0, 0xa6, 0x14, 0x2b, 0x25, 0x4a, 0x54, 0xa9, 0x44, 0x53, 0x62, 0x58,
0xc4, 0xd9, 0x84, 0x65, 0xbb, 0x83, 0x52, 0xa0, 0xdf, 0x83, 0xba, 0xe4, 0xff, 0x58, 0x1a, 0xf6,
0xf3, 0x86, 0xdf, 0x13, 0xcd, 0x20, 0x9d, 0xef, 0xfc, 0xab, 0x2a, 0x2c, 0x49, 0x74, 0x6b, 0x18,
0xc6, 0xfc, 0x70, 0x32, 0x1a, 0x79, 0x51, 0x81, 0x60, 0x29, 0x5d, 0x22, 0x58, 0xca, 0x79, 0xc1,
0x72, 0xd3, 0xb2, 0x2f, 0x85, 0x64, 0x32, 0x10, 0x76, 0x17, 0x16, 0xfa, 0xc3, 0x30, 0x16, 0xea,
0xbe, 0xe9, 0x7a, 0xcb, 0xc2, 0x79, 0x61, 0x58, 0x2b, 0x12, 0x86, 0xa6, 0x20, 0x9b, 0xc9, 0x08,
0x32, 0x07, 0x5a, 0x58, 0x29, 0x57, 0xb2, 0x79, 0x56, 0x1a, 0x5b, 0x06, 0x86, 0xfd, 0xc9, 0x8a,
0x0d, 0x21, 0xa3, 0x16, 0x8a, 0x84, 0x86, 0x3f, 0xe2, 0x24, 0xfb, 0x8d, 0xd2, 0x0d, 0x29, 0x34,
0xf2, 0x59, 0xec, 0x09, 0x80, 0x68, 0x8b, 0x14, 0x10, 0x20, 0x05, 0xe4, 0x23, 0x7b, 0x55, 0xcc,
0xf9, 0x5f, 0xc7, 0xc4, 0x24, 0xe2, 0xa4, 0x94, 0x18, 0x5f, 0x3a, 0x7f, 0xad, 0x04, 0x4d, 0x23,
0x8f, 0x5d, 0x85, 0xc5, 0xad, 0x17, 0x2f, 0x0e, 0x76, 0xdc, 0x8d, 0x97, 0xcf, 0x7e, 0xb0, 0xd3,
0xdb, 0xda, 0x7b, 0x71, 0xb8, 0xd3, 0xbe, 0x82, 0xf0, 0xde, 0x8b, 0xad, 0x8d, 0xbd, 0xde, 0x93,
0x17, 0xee, 0x96, 0x82, 0x4b, 0x6c, 0x05, 0x98, 0xbb, 0xf3, 0xfc, 0xc5, 0xcb, 0x1d, 0x0b, 0x2f,
0xb3, 0x36, 0xb4, 0x36, 0xdd, 0x9d, 0x8d, 0xad, 0x5d, 0x89, 0x54, 0xd8, 0x32, 0xb4, 0x9f, 0xbc,
0xda, 0xdf, 0x7e, 0xb6, 0xff, 0xb4, 0xb7, 0xb5, 0xb1, 0xbf, 0xb5, 0xb3, 0xb7, 0xb3, 0xdd, 0xae,
0xb2, 0x39, 0x68, 0x6c, 0x6c, 0x6e, 0xec, 0x6f, 0xbf, 0xd8, 0xdf, 0xd9, 0x6e, 0xd7, 0x9c, 0xff,
0x52, 0x82, 0xab, 0xd4, 0xeb, 0x41, 0x96, 0x49, 0xd6, 0xa0, 0xd9, 0x0f, 0xc3, 0x31, 0x2a, 0xfe,
0xe9, 0xd6, 0x66, 0x42, 0xc8, 0x00, 0x42, 0x28, 0x1c, 0x87, 0x51, 0x9f, 0x4b, 0x1e, 0x01, 0x82,
0x9e, 0x20, 0x82, 0x0c, 0x20, 0x97, 0x57, 0x94, 0x10, 0x2c, 0xd2, 0x14, 0x98, 0x28, 0xb2, 0x02,
0x33, 0x47, 0x11, 0xf7, 0xfa, 0xa7, 0x92, 0x3b, 0x64, 0x8a, 0x7d, 0x3d, 0xb5, 0x4c, 0xfb, 0x38,
0xfb, 0x43, 0x3e, 0x20, 0x8a, 0xa9, 0xbb, 0x0b, 0x12, 0xdf, 0x92, 0x30, 0x4a, 0x41, 0xef, 0xc8,
0x0b, 0x06, 0x61, 0xc0, 0x07, 0x52, 0xed, 0x4d, 0x01, 0xe7, 0x00, 0x56, 0xb2, 0xe3, 0x93, 0x3c,
0xf6, 0xa9, 0xc1, 0x63, 0x42, 0x0b, 0xed, 0x4e, 0x5f, 0x4d, 0x83, 0xdf, 0xfe, 0xb8, 0x0c, 0x55,
0x54, 0x4a, 0xa6, 0x2b, 0x30, 0xa6, 0x9e, 0x59, 0xc9, 0xf9, 0xe9, 0xc9, 0xd8, 0x15, 0x5b, 0x94,
0x74, 0xb4, 0xa4, 0x48, 0x9a, 0x1f, 0xf1, 0xfe, 0x99, 0x74, 0xb5, 0x18, 0x08, 0x32, 0x08, 0x1a,
0x01, 0xf4, 0xb5, 0x64, 0x10, 0x95, 0x56, 0x79, 0xf4, 0xe5, 0x6c, 0x9a, 0x47, 0xdf, 0x75, 0x60,
0xd6, 0x0f, 0x8e, 0xc2, 0x49, 0x30, 0x20, 0x86, 0xa8, 0xbb, 0x2a, 0x49, 0x27, 0x03, 0xc4, 0xa8,
0x28, 0x3f, 0x05, 0xf9, 0xa7, 0x00, 0x7b, 0x08, 0x8d, 0xf8, 0x22, 0xe8, 0x9b, 0x34, 0xbf, 0x2c,
0x67, 0x09, 0xe7, 0x60, 0xfd, 0xf0, 0x22, 0xe8, 0x13, 0x85, 0xa7, 0xc5, 0x9c, 0xdf, 0x86, 0xba,
0x82, 0x91, 0x2c, 0x5f, 0xed, 0x7f, 0x6f, 0xff, 0xc5, 0xeb, 0xfd, 0xde, 0xe1, 0x0f, 0xf7, 0xb7,
0xda, 0x57, 0xd8, 0x02, 0x34, 0x37, 0xb6, 0x88, 0xd2, 0x09, 0x28, 0x61, 0x91, 0x83, 0x8d, 0xc3,
0x43, 0x8d, 0x94, 0x1d, 0x86, 0x86, 0x7c, 0x4c, 0x9a, 0x9f, 0xf6, 0x7c, 0x7f, 0x0a, 0x8b, 0x06,
0x96, 0x5a, 0x11, 0x63, 0x04, 0x32, 0x56, 0x04, 0xa9, 0x8c, 0x22, 0xc7, 0x69, 0xc3, 0xfc, 0x53,
0x9e, 0x3c, 0x0b, 0x8e, 0x43, 0x55, 0xd3, 0xff, 0xa8, 0xc2, 0x82, 0x86, 0x64, 0x45, 0x77, 0x61,
0xc1, 0x1f, 0xf0, 0x20, 0xf1, 0x93, 0x8b, 0x9e, 0xe5, 0x2f, 0xc8, 0xc2, 0xa8, 0x6a, 0x7b, 0x43,
0xdf, 0x53, 0x07, 0x30, 0x22, 0x81, 0xf6, 0x33, 0xea, 0x00, 0xa6, 0xdf, 0x86, 0xe8, 0x4a, 0xb8,
0x29, 0x0a, 0xf3, 0x50, 0x02, 0x21, 0x2e, 0xb7, 0x19, 0xfd, 0x89, 0x50, 0x39, 0x8b, 0xb2, 0x70,
0xa9, 0x44, 0x4d, 0x38, 0xe4, 0x9a, 0xd0, 0x13, 0x34, 0x90, 0x3b, 0xe1, 0x98, 0x11, 0xf2, 0x31,
0x7b, 0xc2, 0x61, 0x9c, 0x92, 0xd4, 0x73, 0xa7, 0x24, 0x28, 0x3f, 0x2f, 0x82, 0x3e, 0x1f, 0xf4,
0x92, 0xb0, 0x47, 0x72, 0x9e, 0x48, 0xa2, 0xee, 0x66, 0x61, 0xdc, 0x37, 0x12, 0x1e, 0x27, 0x01,
0x17, 0x6e, 0xe9, 0xfa, 0x66, 0xb9, 0x53, 0x72, 0x15, 0x84, 0xf6, 0xc1, 0x24, 0xf2, 0xe3, 0x4e,
0x8b, 0xce, 0x3f, 0xe8, 0x37, 0xfb, 0x36, 0x5c, 0x3d, 0xe2, 0x71, 0xd2, 0x3b, 0xe5, 0xde, 0x80,
0x47, 0x44, 0x5e, 0xe2, 0xa0, 0x45, 0xa8, 0x5c, 0xc5, 0x99, 0x48, 0xb8, 0x67, 0x3c, 0x8a, 0xfd,
0x30, 0x20, 0x65, 0xab, 0xe1, 0xaa, 0x24, 0xd6, 0x87, 0x83, 0xd7, 0x1b, 0xb5, 0x9e, 0xc1, 0x05,
0x1a, 0x78, 0x71, 0x26, 0xbb, 0x0d, 0x33, 0x34, 0x80, 0xb8, 0xd3, 0x26, 0x9a, 0x69, 0xa5, 0x3c,
0xef, 0x07, 0xae, 0xcc, 0xc3, 0x55, 0xee, 0x87, 0xc3, 0x30, 0x22, 0x8d, 0xab, 0xe1, 0x8a, 0x84,
0x3d, 0x3b, 0x27, 0x91, 0x37, 0x3e, 0x95, 0x5a, 0x57, 0x16, 0xfe, 0x6e, 0xb5, 0xde, 0x6c, 0xb7,
0x9c, 0x3f, 0x05, 0x35, 0xaa, 0x96, 0xaa, 0xa3, 0xc9, 0x2c, 0xc9, 0xea, 0x08, 0xed, 0xc0, 0x6c,
0xc0, 0x93, 0xf3, 0x30, 0x7a, 0xa3, 0x4e, 0xf3, 0x64, 0xd2, 0xf9, 0x39, 0x59, 0x68, 0xfa, 0x74,
0xeb, 0x15, 0xa9, 0x96, 0x68, 0x67, 0x8b, 0xa5, 0x8a, 0x4f, 0x3d, 0x69, 0x34, 0xd6, 0x09, 0x38,
0x3c, 0xf5, 0x50, 0xd6, 0x5a, 0xab, 0x2f, 0xec, 0xf0, 0x26, 0x61, 0xbb, 0x62, 0xf1, 0x6f, 0xc3,
0xbc, 0x3a, 0x37, 0x8b, 0x7b, 0x43, 0x7e, 0x9c, 0x28, 0x2f, 0x5a, 0x30, 0x19, 0x91, 0xb1, 0xbe,
0xc7, 0x8f, 0x13, 0x67, 0x1f, 0x16, 0xa5, 0xfc, 0x7b, 0x31, 0xe6, 0xaa, 0xe9, 0xdf, 0x2c, 0xd2,
0x25, 0x9a, 0x0f, 0x97, 0x6c, 0x81, 0x29, 0x4e, 0x0a, 0xed, 0x92, 0x8e, 0x0b, 0xcc, 0x94, 0xa7,
0xb2, 0x42, 0xb9, 0x99, 0x2b, 0x3f, 0xa1, 0x1c, 0x8e, 0x85, 0xe1, 0xfc, 0xc4, 0x93, 0x7e, 0x5f,
0x9d, 0x76, 0xd6, 0x5d, 0x95, 0x74, 0xfe, 0xa0, 0x04, 0x4b, 0x54, 0x9b, 0xd2, 0x86, 0xe4, 0x9e,
0xf5, 0xe8, 0x2b, 0x74, 0x53, 0x79, 0x69, 0x85, 0x6f, 0x72, 0x19, 0x6a, 0xe6, 0x2e, 0x26, 0x12,
0x5f, 0xdd, 0x27, 0x53, 0xcd, 0xfa, 0x64, 0x9c, 0xbf, 0x55, 0x82, 0x45, 0xb1, 0x91, 0x90, 0xb6,
0x2d, 0x87, 0xff, 0xa7, 0x61, 0x4e, 0x68, 0x04, 0x52, 0x2a, 0xc8, 0x8e, 0xa6, 0xa2, 0x95, 0x50,
0x51, 0x78, 0xf7, 0x8a, 0x6b, 0x17, 0x66, 0x8f, 0x49, 0x2b, 0x0b, 0x7a, 0x84, 0x16, 0x9c, 0x8b,
0xdb, 0x73, 0xbd, 0x7b, 0xc5, 0x35, 0x8a, 0x6f, 0xd6, 0x51, 0x59, 0x46, 0xdc, 0x79, 0x0a, 0x73,
0x56, 0x43, 0x96, 0x3f, 0xa8, 0x25, 0xfc, 0x41, 0x39, 0xc7, 0x6b, 0xb9, 0xc0, 0xf1, 0xfa, 0xcf,
0x2a, 0xc0, 0x90, 0x58, 0x32, 0xab, 0xb1, 0x66, 0x9f, 0x5e, 0xa8, 0x23, 0xf2, 0x14, 0x62, 0xeb,
0xc0, 0x8c, 0xa4, 0x3a, 0x51, 0x11, 0x5b, 0x66, 0x41, 0x0e, 0x8a, 0x59, 0xa9, 0x71, 0xe8, 0xd3,
0x0a, 0xb2, 0xf3, 0xc5, 0xb4, 0x17, 0xe6, 0xe1, 0xae, 0x48, 0x47, 0x17, 0x68, 0x91, 0x48, 0xdb,
0x58, 0xa5, 0xb3, 0xeb, 0x3b, 0x73, 0xe9, 0xfa, 0xce, 0xe6, 0x7c, 0x6e, 0x86, 0x75, 0x56, 0xb7,
0xad, 0xb3, 0xdb, 0x30, 0xa7, 0x4e, 0x28, 0x7a, 0x23, 0x6c, 0x5d, 0x9a, 0xc2, 0x16, 0xc8, 0xee,
0x41, 0x5b, 0x19, 0x48, 0xda, 0x04, 0x14, 0xe7, 0x7c, 0x39, 0x1c, 0xe5, 0x7f, 0xea, 0x85, 0x6b,
0x52, 0x67, 0x53, 0x80, 0xec, 0x29, 0xa4, 0x90, 0xde, 0x24, 0x90, 0x47, 0xe3, 0x7c, 0x40, 0x46,
0x30, 0xda, 0x53, 0xd9, 0x0c, 0xe7, 0x6f, 0x94, 0xa0, 0x8d, 0x6b, 0x66, 0x91, 0xe5, 0x67, 0x40,
0x5c, 0xf1, 0x9e, 0x54, 0x69, 0x95, 0x65, 0x8f, 0xa0, 0x41, 0xe9, 0x70, 0xcc, 0x03, 0x49, 0x93,
0x1d, 0x9b, 0x26, 0x53, 0x79, 0xb2, 0x7b, 0xc5, 0x4d, 0x0b, 0x1b, 0x14, 0xf9, 0x1f, 0x4a, 0xd0,
0x94, 0xad, 0xfc, 0xd2, 0x5e, 0x9e, 0xae, 0x11, 0xcb, 0x20, 0x28, 0x29, 0x0d, 0x5d, 0xb8, 0x0b,
0x0b, 0x23, 0x2f, 0x99, 0x44, 0xb8, 0x9f, 0x5b, 0x1e, 0x9e, 0x2c, 0x8c, 0x9b, 0x33, 0x89, 0xce,
0xb8, 0x97, 0xf8, 0xc3, 0x9e, 0xca, 0x95, 0x51, 0x03, 0x45, 0x59, 0x28, 0x41, 0xe2, 0xc4, 0x3b,
0xe1, 0x72, 0xdf, 0x15, 0x09, 0xa7, 0x03, 0x2b, 0x07, 0xe9, 0xa9, 0x8d, 0xa1, 0x5f, 0x3b, 0xff,
0x64, 0x0e, 0x56, 0x73, 0x59, 0x3a, 0xc6, 0x49, 0xba, 0x2d, 0x86, 0xfe, 0xe8, 0x28, 0xd4, 0xc6,
0x49, 0xc9, 0xf4, 0x68, 0x58, 0x59, 0xec, 0x04, 0xae, 0x2a, 0x05, 0x03, 0xe7, 0x34, 0xdd, 0x0c,
0xcb, 0xb4, 0xcb, 0x7d, 0x62, 0x2f, 0x61, 0xb6, 0x41, 0x85, 0x9b, 0x4c, 0x5c, 0x5c, 0x1f, 0x3b,
0x85, 0x8e, 0xd6, 0x64, 0xa4, 0xb0, 0x36, 0xb4, 0x1d, 0x6c, 0xeb, 0xe3, 0x4b, 0xda, 0xb2, 0xd4,
0x71, 0x77, 0x6a, 0x6d, 0xec, 0x02, 0x6e, 0xaa, 0x3c, 0x92, 0xc6, 0xf9, 0xf6, 0xaa, 0xef, 0x35,
0x36, 0x32, 0x34, 0xec, 0x46, 0x2f, 0xa9, 0x98, 0xfd, 0x14, 0x56, 0xce, 0x3d, 0x3f, 0x51, 0xdd,
0x32, 0x74, 0x8b, 0x1a, 0x35, 0xf9, 0xf0, 0x92, 0x26, 0x5f, 0x8b, 0x8f, 0xad, 0x2d, 0x6a, 0x4a,
0x8d, 0xdd, 0x3f, 0x2a, 0xc3, 0xbc, 0x5d, 0x0f, 0x92, 0xa9, 0xe4, 0x7d, 0x25, 0x03, 0x95, 0x36,
0x9a, 0x81, 0xf3, 0x36, 0x7e, 0xb9, 0xc8, 0xc6, 0x37, 0xad, 0xea, 0xca, 0x65, 0xee, 0xc1, 0xea,
0xfb, 0xb9, 0x07, 0x6b, 0x85, 0xee, 0xc1, 0xe9, 0x5e, 0xa4, 0x99, 0x5f, 0xd6, 0x8b, 0x34, 0xfb,
0x4e, 0x2f, 0x52, 0xf7, 0xff, 0x94, 0x80, 0xe5, 0xa9, 0x97, 0x3d, 0x15, 0x6e, 0x8d, 0x80, 0x0f,
0xa5, 0x10, 0xfb, 0xe6, 0xfb, 0x71, 0x80, 0x5a, 0x2d, 0xf5, 0x35, 0xb2, 0xa2, 0x19, 0x68, 0x64,
0xaa, 0x57, 0x73, 0x6e, 0x51, 0x56, 0xc6, 0x45, 0x5a, 0xbd, 0xdc, 0x45, 0x5a, 0xbb, 0xdc, 0x45,
0x3a, 0x93, 0x75, 0x91, 0x76, 0xff, 0x72, 0x09, 0x96, 0x0a, 0xc8, 0xec, 0xd7, 0x37, 0x70, 0x24,
0x0c, 0x4b, 0xfa, 0x94, 0x25, 0x61, 0x98, 0x60, 0xf7, 0xcf, 0xc3, 0x9c, 0xc5, 0x5a, 0xbf, 0xbe,
0xf6, 0xb3, 0x1a, 0xa2, 0xa0, 0x6c, 0x0b, 0xeb, 0xfe, 0xcf, 0x32, 0xb0, 0x3c, 0x7b, 0xff, 0x7f,
0xed, 0x43, 0x7e, 0x9e, 0x2a, 0x05, 0xf3, 0xf4, 0xff, 0x74, 0xe7, 0xf9, 0x18, 0x16, 0x65, 0xf4,
0xa4, 0xe1, 0xc8, 0x12, 0x14, 0x93, 0xcf, 0x40, 0x1d, 0xd9, 0xf6, 0x4f, 0xd7, 0xad, 0x68, 0x31,
0x63, 0xfb, 0xcd, 0xb8, 0xa9, 0x9d, 0x2e, 0x74, 0xe4, 0x0c, 0xed, 0x9c, 0xf1, 0x20, 0x39, 0x9c,
0x1c, 0x89, 0xf0, 0x41, 0x3f, 0x0c, 0x9c, 0x7f, 0x5e, 0xd1, 0x6a, 0x3e, 0x65, 0x4a, 0x85, 0xe2,
0xdb, 0xd0, 0x32, 0xb7, 0x0f, 0xb9, 0x1c, 0x19, 0x5f, 0x26, 0xaa, 0x12, 0x66, 0x29, 0xb6, 0x0d,
0xf3, 0x24, 0x24, 0x07, 0xfa, 0xbb, 0x32, 0x7d, 0xf7, 0x0e, 0xff, 0xcc, 0xee, 0x15, 0x37, 0xf3,
0x0d, 0xfb, 0x2d, 0x98, 0xb7, 0x8d, 0x3f, 0xa9, 0x95, 0x14, 0x59, 0x03, 0xf8, 0xb9, 0x5d, 0x98,
0x6d, 0x40, 0x3b, 0x6b, 0x3d, 0xca, 0x48, 0x9e, 0x29, 0x15, 0xe4, 0x8a, 0xb3, 0x47, 0xf2, 0xb0,
0xb2, 0x46, 0x7e, 0x93, 0xdb, 0xf6, 0x67, 0xc6, 0x34, 0xad, 0x8b, 0x3f, 0xc6, 0xf1, 0xe5, 0xef,
0x00, 0xa4, 0x18, 0x6b, 0x43, 0xeb, 0xc5, 0xc1, 0xce, 0x7e, 0x6f, 0x6b, 0x77, 0x63, 0x7f, 0x7f,
0x67, 0xaf, 0x7d, 0x85, 0x31, 0x98, 0x27, 0x37, 0xdf, 0xb6, 0xc6, 0x4a, 0x88, 0x49, 0xc7, 0x8a,
0xc2, 0xca, 0x6c, 0x19, 0xda, 0xcf, 0xf6, 0x33, 0x68, 0x65, 0xb3, 0xa1, 0xf9, 0xc3, 0x59, 0x81,
0x65, 0x11, 0x1d, 0xbb, 0x29, 0xc8, 0x43, 0x69, 0x27, 0x7f, 0xaf, 0x04, 0x57, 0x33, 0x19, 0x69,
0xa8, 0x97, 0x50, 0x40, 0x6c, 0xad, 0xc4, 0x06, 0xe9, 0xf0, 0x41, 0xe9, 0x9a, 0x19, 0x09, 0x92,
0xcf, 0x40, 0x9a, 0x37, 0x74, 0xd3, 0x0c, 0x27, 0x15, 0x65, 0x39, 0xab, 0x3a, 0xaa, 0x26, 0xd3,
0xf1, 0x63, 0x11, 0x75, 0x6b, 0x66, 0xa4, 0x87, 0xbf, 0x76, 0x97, 0x55, 0x12, 0xcd, 0x0a, 0x4b,
0xd9, 0xb1, 0xfb, 0x5b, 0x98, 0xe7, 0xfc, 0xc3, 0x0a, 0xb0, 0xef, 0x4f, 0x78, 0x74, 0x41, 0xf1,
0x5c, 0xda, 0x6b, 0xba, 0x9a, 0xf5, 0x09, 0xce, 0x8c, 0x27, 0x47, 0xdf, 0xe3, 0x17, 0x2a, 0xba,
0xb1, 0x9c, 0x46, 0x37, 0x16, 0x45, 0x18, 0x56, 0x2f, 0x8f, 0x30, 0xac, 0x5d, 0x16, 0x61, 0xf8,
0x35, 0x98, 0xf3, 0x4f, 0x82, 0x10, 0x79, 0x1e, 0xf5, 0x84, 0xb8, 0x33, 0xb3, 0x56, 0x41, 0xdb,
0x5a, 0x82, 0xfb, 0x88, 0xb1, 0xc7, 0x69, 0x21, 0x3e, 0x38, 0xa1, 0x68, 0x56, 0x53, 0x0a, 0xec,
0x0c, 0x4e, 0xf8, 0x5e, 0xd8, 0xf7, 0x92, 0x30, 0x22, 0xc7, 0x8e, 0xfa, 0x18, 0xf1, 0x98, 0xdd,
0x86, 0xf9, 0x38, 0x9c, 0xa0, 0xe6, 0xa4, 0xc6, 0x2a, 0x3c, 0x49, 0x2d, 0x81, 0x1e, 0x88, 0x11,
0xaf, 0xc3, 0xd2, 0x24, 0xe6, 0xbd, 0x91, 0x1f, 0xc7, 0xb8, 0x3b, 0xf6, 0xc3, 0x20, 0x89, 0xc2,
0xa1, 0xf4, 0x27, 0x2d, 0x4e, 0x62, 0xfe, 0x5c, 0xe4, 0x6c, 0x89, 0x0c, 0xf6, 0xed, 0xb4, 0x4b,
0x63, 0xcf, 0x8f, 0xe2, 0x0e, 0x50, 0x97, 0xd4, 0x48, 0xb1, 0xdf, 0x07, 0x9e, 0x1f, 0xe9, 0xbe,
0x60, 0x22, 0xce, 0x44, 0x48, 0x36, 0x33, 0x11, 0x92, 0x32, 0xc0, 0x6e, 0x1d, 0xea, 0xea, 0x73,
0x34, 0x72, 0x8f, 0xa3, 0x70, 0xa4, 0x8c, 0x5c, 0xfc, 0xcd, 0xe6, 0xa1, 0x9c, 0x84, 0xd2, 0x40,
0x2d, 0x27, 0xa1, 0xf3, 0xbb, 0xd0, 0x34, 0x66, 0x80, 0x7d, 0x28, 0xec, 0x6d, 0x54, 0xa8, 0xa4,
0x75, 0x2c, 0x8e, 0x49, 0x1a, 0x12, 0x7d, 0x36, 0x60, 0xdf, 0x80, 0xc5, 0x81, 0x1f, 0x71, 0x0a,
0xac, 0xed, 0x45, 0xfc, 0x8c, 0x47, 0xb1, 0xf2, 0x25, 0xb4, 0x75, 0x86, 0x2b, 0x70, 0xa7, 0x07,
0x4b, 0x16, 0xe9, 0x68, 0xce, 0x9a, 0xa1, 0xa8, 0x40, 0xe5, 0xce, 0xb4, 0x23, 0x06, 0x65, 0x1e,
0xee, 0x49, 0xd2, 0x0d, 0xd2, 0x1b, 0x47, 0xe1, 0x11, 0x35, 0x52, 0x72, 0x2d, 0xcc, 0xf9, 0xc7,
0x65, 0xa8, 0xec, 0x86, 0x63, 0xf3, 0x70, 0xa7, 0x94, 0x3f, 0xdc, 0x91, 0xca, 0x63, 0x4f, 0xeb,
0x86, 0x72, 0x87, 0xb7, 0x40, 0x76, 0x0f, 0xe6, 0xbd, 0x51, 0xd2, 0x4b, 0x42, 0x54, 0x96, 0xcf,
0xbd, 0x48, 0x84, 0x10, 0x56, 0x88, 0x2c, 0x32, 0x39, 0x6c, 0x19, 0x2a, 0x5a, 0xe7, 0xa1, 0x02,
0x98, 0x44, 0x4b, 0x8d, 0x0e, 0xd0, 0x2f, 0xa4, 0xcf, 0x52, 0xa6, 0x90, 0xeb, 0xed, 0xef, 0x85,
0x99, 0x2c, 0x76, 0xae, 0xa2, 0x2c, 0x54, 0x64, 0x91, 0x11, 0x46, 0xa9, 0x5e, 0xa8, 0xd3, 0xa6,
0x37, 0xbe, 0x6e, 0x7b, 0xe3, 0xd7, 0xa0, 0x99, 0x0c, 0xcf, 0x7a, 0x63, 0xef, 0x62, 0x18, 0x7a,
0x03, 0x49, 0x80, 0x26, 0xe4, 0xfc, 0x49, 0x09, 0x6a, 0x34, 0xcb, 0xb8, 0x4f, 0x0b, 0x41, 0xa6,
0x4f, 0x80, 0x68, 0xe6, 0xe6, 0xdc, 0x2c, 0xcc, 0x1c, 0x2b, 0x18, 0xbc, 0xac, 0x87, 0x6c, 0x06,
0x84, 0xaf, 0x41, 0x43, 0xa4, 0x74, 0x60, 0x33, 0x15, 0x49, 0x41, 0x76, 0x13, 0xaa, 0xa7, 0xe1,
0x58, 0x99, 0x32, 0xa0, 0x0e, 0x89, 0xc3, 0xb1, 0x4b, 0x78, 0xda, 0x1f, 0xac, 0x4f, 0x0c, 0x5c,
0xa8, 0x8b, 0x59, 0x18, 0x55, 0x74, 0x5d, 0xad, 0x39, 0x91, 0x19, 0xd4, 0x79, 0x05, 0x0b, 0xc8,
0x0b, 0x86, 0x47, 0x7c, 0xba, 0xd0, 0xfa, 0x3a, 0xee, 0x81, 0xfd, 0xe1, 0x64, 0xc0, 0x4d, 0x83,
0x92, 0x3c, 0x9e, 0x12, 0x57, 0xaa, 0x94, 0xf3, 0x4f, 0x4b, 0x82, 0xc7, 0xb0, 0x5e, 0x76, 0x17,
0xaa, 0x28, 0x7a, 0x32, 0xfe, 0x03, 0x1d, 0x4b, 0x82, 0xe5, 0x5c, 0x2a, 0x81, 0xd4, 0x4c, 0x3e,
0x49, 0xb3, 0x76, 0xe1, 0x91, 0x4c, 0xad, 0x31, 0x3d, 0xb2, 0x8c, 0x11, 0x93, 0x41, 0xd9, 0xba,
0x71, 0xa0, 0x53, 0xb5, 0xc4, 0x99, 0xda, 0x72, 0x07, 0x27, 0xdc, 0x38, 0xc8, 0xf9, 0xc3, 0x12,
0xcc, 0x59, 0x7d, 0x42, 0x4a, 0x19, 0x7a, 0x71, 0x22, 0xcf, 0xf2, 0xe5, 0xca, 0x9b, 0x90, 0x49,
0x65, 0x65, 0x9b, 0xca, 0xf4, 0xc1, 0x40, 0xc5, 0x3c, 0x18, 0x78, 0x00, 0x8d, 0xf4, 0x36, 0x80,
0xdd, 0x29, 0x6c, 0x51, 0x45, 0xd5, 0xa4, 0x85, 0x52, 0xd7, 0x73, 0xcd, 0x70, 0x3d, 0x3b, 0x8f,
0xa1, 0x69, 0x94, 0x37, 0x5d, 0xc7, 0x25, 0xcb, 0x75, 0xac, 0x43, 0xce, 0xca, 0x69, 0xc8, 0x99,
0xf3, 0x65, 0x19, 0xe6, 0x90, 0xbc, 0xfd, 0xe0, 0xe4, 0x20, 0x1c, 0xfa, 0xfd, 0x0b, 0x22, 0x2b,
0x45, 0xc9, 0x72, 0xeb, 0x51, 0x64, 0x6e, 0xc3, 0xc8, 0x72, 0x3a, 0xce, 0x56, 0xc8, 0x07, 0x9d,
0x46, 0x01, 0x82, 0xec, 0x77, 0xe4, 0xc5, 0x92, 0x27, 0xa5, 0xea, 0x6b, 0x81, 0xc8, 0xe6, 0x08,
0x50, 0x00, 0xe1, 0xc8, 0x1f, 0x0e, 0x7d, 0x51, 0x56, 0x18, 0x46, 0x45, 0x59, 0xd8, 0xe6, 0xc0,
0x8f, 0xbd, 0xa3, 0xf4, 0xd0, 0x4f, 0xa7, 0xc9, 0xab, 0xe6, 0xbd, 0x35, 0xbc, 0x6a, 0x22, 0xe2,
0xd8, 0x06, 0xb3, 0x0b, 0x39, 0x9b, 0x5b, 0x48, 0xe7, 0xdf, 0x94, 0xa1, 0x69, 0x90, 0x05, 0xb2,
0x73, 0xa1, 0x8c, 0x37, 0x50, 0x79, 0x1a, 0x1e, 0x58, 0xa6, 0xb6, 0x81, 0xb0, 0xdb, 0x76, 0xab,
0xe4, 0x5d, 0x27, 0x86, 0xb7, 0x48, 0xe8, 0x06, 0x34, 0x90, 0xf4, 0x3f, 0x21, 0xbb, 0x5e, 0x5e,
0xc5, 0xd1, 0x80, 0xca, 0x7d, 0x48, 0xb9, 0xb5, 0x34, 0x97, 0x80, 0x77, 0x9e, 0x8f, 0x3f, 0x82,
0x96, 0xac, 0x86, 0xd6, 0x98, 0x06, 0x9d, 0x32, 0x9f, 0xb5, 0xfe, 0xae, 0x55, 0x52, 0x7d, 0xf9,
0x50, 0x7d, 0x59, 0xbf, 0xec, 0x4b, 0x55, 0xd2, 0x79, 0xaa, 0x43, 0x0f, 0x9e, 0x46, 0xde, 0xf8,
0x54, 0x09, 0x94, 0x07, 0xb0, 0xa4, 0xe4, 0xc6, 0x24, 0xf0, 0x82, 0x20, 0x9c, 0x04, 0x7d, 0xae,
0xa2, 0xd3, 0x8a, 0xb2, 0x9c, 0x81, 0x8e, 0x65, 0xa6, 0x8a, 0xd8, 0x3d, 0xa8, 0x09, 0xe5, 0x45,
0x6c, 0x85, 0xc5, 0x22, 0x44, 0x14, 0x61, 0x77, 0xa1, 0x26, 0x74, 0x98, 0xf2, 0x54, 0xa6, 0x17,
0x05, 0x9c, 0x75, 0x58, 0xa0, 0xe0, 0x69, 0x43, 0xf6, 0x5d, 0x2f, 0xda, 0x22, 0x67, 0xfa, 0x22,
0xc4, 0x7a, 0x19, 0xd8, 0xbe, 0xe0, 0x2b, 0xf3, 0x00, 0xf1, 0x4f, 0x2a, 0xd0, 0x34, 0x60, 0x94,
0x4f, 0x74, 0xea, 0xd3, 0x1b, 0xf8, 0xde, 0x88, 0x27, 0x3c, 0x92, 0xbc, 0x94, 0x41, 0xb1, 0x9c,
0x77, 0x76, 0xd2, 0x0b, 0x27, 0x49, 0x6f, 0xc0, 0x4f, 0x22, 0xce, 0xe5, 0xde, 0x9d, 0x41, 0xb1,
0x1c, 0x52, 0xb3, 0x51, 0x4e, 0x9c, 0xd3, 0x64, 0x50, 0x75, 0x1c, 0x28, 0xe6, 0xa9, 0x9a, 0x1e,
0x07, 0x8a, 0x59, 0xc9, 0x4a, 0xd6, 0x5a, 0x81, 0x64, 0xfd, 0x14, 0x56, 0x84, 0x0c, 0x95, 0xd2,
0xa3, 0x97, 0x21, 0xae, 0x29, 0xb9, 0xec, 0x1e, 0xb4, 0xb1, 0xcf, 0x8a, 0x35, 0x62, 0xff, 0xe7,
0x82, 0xc7, 0x4a, 0x6e, 0x0e, 0xc7, 0xb2, 0xe4, 0xa3, 0x36, 0xcb, 0x8a, 0x98, 0x8c, 0x1c, 0x4e,
0x65, 0xbd, 0xb7, 0x76, 0xd9, 0x86, 0x2c, 0x9b, 0xc1, 0xd9, 0x23, 0x58, 0x1d, 0xf1, 0x81, 0xef,
0xd9, 0x55, 0x90, 0xcb, 0x48, 0x04, 0x94, 0x4d, 0xcb, 0xc6, 0x56, 0x70, 0x16, 0x7e, 0x1e, 0x8e,
0x8e, 0x7c, 0xb1, 0xb1, 0x09, 0x6f, 0x7a, 0xd5, 0xcd, 0xe1, 0xce, 0x1c, 0x34, 0x0f, 0x93, 0x70,
0xac, 0x96, 0x7e, 0x1e, 0x5a, 0x22, 0x29, 0xe3, 0x11, 0xaf, 0xc3, 0x35, 0xa2, 0xd7, 0x97, 0xe1,
0x38, 0x1c, 0x86, 0x27, 0x17, 0x96, 0x4d, 0xfc, 0xef, 0x4b, 0xb0, 0x64, 0xe5, 0xa6, 0x46, 0x31,
0x39, 0xf0, 0x54, 0x10, 0x99, 0x20, 0xf1, 0x45, 0x63, 0x5b, 0x10, 0x05, 0xc5, 0x59, 0xc9, 0x2b,
0x19, 0x57, 0xb6, 0x91, 0xde, 0x8c, 0x50, 0x1f, 0x0a, 0x7a, 0xef, 0xe4, 0xe9, 0x5d, 0x7e, 0xaf,
0xee, 0x4c, 0xa8, 0x2a, 0x7e, 0x4b, 0x46, 0xd0, 0x0c, 0xe4, 0xa0, 0x2b, 0x76, 0xd4, 0x83, 0xe9,
0x43, 0x51, 0x3d, 0xe8, 0x6b, 0x30, 0x76, 0x7e, 0x51, 0x02, 0x48, 0x7b, 0x47, 0x71, 0x17, 0x7a,
0x6b, 0x13, 0xb7, 0x6f, 0x8d, 0x6d, 0xec, 0x43, 0x68, 0xe9, 0xa3, 0xf3, 0x74, 0xb7, 0x6c, 0x2a,
0x0c, 0xb5, 0x8b, 0x3b, 0xb0, 0x70, 0x32, 0x0c, 0x8f, 0x48, 0x8b, 0xa1, 0x00, 0xd7, 0x58, 0x46,
0x65, 0xce, 0x0b, 0xf8, 0x89, 0x44, 0xd3, 0xad, 0xb5, 0x6a, 0x6e, 0xad, 0xc5, 0x1b, 0xe5, 0x97,
0x65, 0x7d, 0x7e, 0x99, 0xce, 0xc4, 0x3b, 0xb9, 0x9c, 0x3d, 0xcc, 0x89, 0xf5, 0x29, 0x47, 0x86,
0xa4, 0xef, 0x1f, 0x5c, 0xea, 0x52, 0x7d, 0x0c, 0xf3, 0x91, 0x90, 0x99, 0x4a, 0xa0, 0x56, 0xdf,
0x21, 0x50, 0xe7, 0x22, 0x6b, 0x67, 0xfe, 0x3a, 0xb4, 0xbd, 0xc1, 0x19, 0x8f, 0x12, 0x9f, 0x5c,
0x4c, 0xa4, 0x46, 0x89, 0x01, 0x2e, 0x18, 0x38, 0x69, 0x2b, 0x77, 0x60, 0x41, 0xc6, 0xc8, 0xea,
0x92, 0xf2, 0x2e, 0x5b, 0x0a, 0x63, 0x41, 0xe7, 0x1f, 0xa8, 0xe3, 0x52, 0x7b, 0x75, 0xdf, 0x3d,
0x2b, 0xe6, 0x08, 0xcb, 0x99, 0x11, 0x7e, 0x4d, 0x1e, 0x5f, 0x0e, 0x94, 0x2f, 0xab, 0x62, 0xc4,
0x62, 0x0d, 0xe4, 0x71, 0xb3, 0x3d, 0xad, 0xd5, 0xf7, 0x99, 0x56, 0xe7, 0x3f, 0x95, 0x60, 0x76,
0x37, 0x1c, 0xef, 0xe2, 0x14, 0xa3, 0x8e, 0x83, 0x6c, 0xa2, 0x03, 0xd4, 0x55, 0xf2, 0x92, 0x98,
0xb5, 0x42, 0xad, 0x64, 0x2e, 0xab, 0x95, 0xfc, 0x59, 0xb8, 0x4e, 0xde, 0xd4, 0x28, 0x1c, 0x87,
0x11, 0xb2, 0xab, 0x37, 0x14, 0x2a, 0x48, 0x18, 0x24, 0xa7, 0x4a, 0x9c, 0xbe, 0xab, 0x08, 0xb9,
0x38, 0xd0, 0xf2, 0x14, 0xd6, 0x8c, 0xd4, 0xa2, 0x84, 0x94, 0xcd, 0x67, 0x38, 0xbf, 0x09, 0x0d,
0xb2, 0x30, 0x68, 0x68, 0x1f, 0x43, 0xe3, 0x34, 0x1c, 0xf7, 0x4e, 0xfd, 0x20, 0x51, 0xec, 0x3f,
0x9f, 0xaa, 0xfe, 0xbb, 0x34, 0x29, 0xba, 0x80, 0xf3, 0xaf, 0x67, 0x60, 0xf6, 0x59, 0x70, 0x16,
0xfa, 0x7d, 0x3a, 0xa2, 0x1d, 0xf1, 0x51, 0xa8, 0x42, 0xf6, 0xf1, 0x37, 0x4e, 0x07, 0xc5, 0xa7,
0x8e, 0x05, 0xf1, 0xb6, 0x44, 0x28, 0x86, 0x84, 0xe8, 0xb2, 0x69, 0x7a, 0xdd, 0x4e, 0x30, 0x98,
0x81, 0xa0, 0x75, 0x16, 0x99, 0xd7, 0xe5, 0x64, 0x2a, 0xbd, 0x12, 0x51, 0x33, 0xae, 0x44, 0x60,
0x5b, 0x32, 0x92, 0x4e, 0x84, 0x5a, 0x89, 0xb6, 0x24, 0x44, 0x16, 0x65, 0xc4, 0x85, 0x37, 0x5c,
0x2b, 0x5e, 0x68, 0x51, 0x9a, 0x20, 0x2a, 0x67, 0xe2, 0x03, 0x51, 0x46, 0x6c, 0x06, 0x26, 0x84,
0xea, 0x69, 0xf6, 0x96, 0xa6, 0xb8, 0x25, 0x9b, 0x85, 0x51, 0x96, 0x0f, 0xb8, 0x16, 0xb9, 0x62,
0x1c, 0x20, 0xae, 0x14, 0x66, 0x71, 0xc3, 0x0e, 0x15, 0xa1, 0xc4, 0xca, 0x0e, 0x45, 0x82, 0xf1,
0x86, 0xc3, 0x23, 0xaf, 0xff, 0x86, 0x2e, 0xe9, 0xd2, 0xa1, 0x69, 0xc3, 0xb5, 0x41, 0x8a, 0x87,
0x4b, 0x57, 0x95, 0x82, 0x56, 0xaa, 0xae, 0x09, 0xb1, 0x87, 0xd0, 0x24, 0x1b, 0x5d, 0xae, 0xeb,
0x3c, 0xad, 0x6b, 0xdb, 0x34, 0xe2, 0x69, 0x65, 0xcd, 0x42, 0xe6, 0xf1, 0xf1, 0x42, 0x2e, 0xb8,
0xd7, 0x1b, 0x0c, 0xe4, 0xa9, 0x7b, 0x5b, 0x5c, 0xab, 0xd3, 0x00, 0x79, 0x01, 0xc4, 0x84, 0x89,
0x02, 0x8b, 0x54, 0xc0, 0xc2, 0xd8, 0x4d, 0xa8, 0xa3, 0xd5, 0x37, 0xf6, 0xfc, 0x01, 0xc5, 0xa9,
0x08, 0xe3, 0x53, 0x63, 0x58, 0x87, 0xfa, 0x4d, 0xdb, 0xe6, 0x12, 0xcd, 0x8a, 0x85, 0xe1, 0xdc,
0xe8, 0xf4, 0x28, 0x8d, 0x06, 0xb6, 0x41, 0xf6, 0x09, 0x9d, 0x7d, 0x26, 0x9c, 0x42, 0x7e, 0xe7,
0x1f, 0x5e, 0x97, 0x63, 0x96, 0x44, 0xab, 0xfe, 0x1e, 0x62, 0x11, 0x57, 0x94, 0x44, 0xa5, 0x4d,
0xb8, 0x9f, 0x57, 0x2c, 0xa5, 0x4d, 0x16, 0x25, 0xf7, 0xb3, 0x28, 0xe0, 0x6c, 0x40, 0xcb, 0xac,
0x80, 0xd5, 0xa1, 0xfa, 0xe2, 0x60, 0x67, 0xbf, 0x7d, 0x85, 0x35, 0x61, 0xf6, 0x70, 0xe7, 0xe5,
0xcb, 0xbd, 0x9d, 0xed, 0x76, 0x89, 0xb5, 0xa0, 0xae, 0xc3, 0x1c, 0xcb, 0x98, 0xda, 0xd8, 0xda,
0xda, 0x39, 0x78, 0xb9, 0xb3, 0xdd, 0xae, 0x38, 0x7f, 0x50, 0x86, 0xa6, 0x51, 0xf3, 0x25, 0x7e,
0x91, 0x9b, 0x00, 0x64, 0x49, 0xa4, 0x01, 0x0f, 0x55, 0xd7, 0x40, 0x50, 0x32, 0x6a, 0x1b, 0xbb,
0x22, 0x6e, 0x17, 0xaa, 0x34, 0xcd, 0x17, 0x5d, 0xe3, 0x33, 0xbd, 0xfc, 0x35, 0xd7, 0x06, 0x91,
0x96, 0x24, 0x40, 0x51, 0x77, 0x82, 0xc3, 0x4c, 0x08, 0xd7, 0x26, 0xe2, 0x71, 0x38, 0x3c, 0xe3,
0xa2, 0x88, 0xd0, 0xc7, 0x2c, 0x0c, 0xdb, 0x92, 0x22, 0xc6, 0x88, 0x88, 0xad, 0xb9, 0x36, 0xc8,
0xbe, 0xa9, 0xd6, 0xa6, 0x4e, 0x6b, 0xb3, 0x9a, 0x9f, 0x68, 0x73, 0x5d, 0x9c, 0x04, 0xd8, 0xc6,
0x60, 0x20, 0x73, 0xcd, 0xbb, 0x8a, 0x91, 0x79, 0x31, 0x56, 0x09, 0x89, 0x02, 0x46, 0x2d, 0x17,
0x33, 0xea, 0x3b, 0xc9, 0xd9, 0xd9, 0x81, 0xe6, 0x81, 0x71, 0xd5, 0x96, 0x64, 0x96, 0xba, 0x64,
0x2b, 0x65, 0x9d, 0x81, 0x18, 0xdd, 0x29, 0x9b, 0xdd, 0x71, 0xfe, 0x7e, 0x49, 0xdc, 0x5e, 0xd2,
0xdd, 0x17, 0x6d, 0x3b, 0xd0, 0xd2, 0x3e, 0xdc, 0x34, 0xe0, 0xdb, 0xc2, 0xb0, 0x0c, 0x75, 0xa5,
0x17, 0x1e, 0x1f, 0xc7, 0x5c, 0x85, 0x66, 0x5a, 0x98, 0x52, 0x1c, 0x51, 0x15, 0xf5, 0x45, 0x0b,
0xb1, 0x0c, 0xd1, 0xcc, 0xe1, 0x48, 0x24, 0xd2, 0x0d, 0xa8, 0x82, 0x52, 0x75, 0x5a, 0xc7, 0xa5,
0x67, 0x67, 0xf9, 0x1e, 0xd4, 0x75, 0xbd, 0xf6, 0xae, 0xa0, 0x4a, 0xea, 0x7c, 0xdc, 0x7d, 0xc8,
0xa8, 0xb4, 0x3a, 0x2d, 0x68, 0x35, 0x9f, 0xc1, 0xd6, 0x81, 0x1d, 0xfb, 0x51, 0xb6, 0xb8, 0x20,
0xde, 0x82, 0x1c, 0xe7, 0x35, 0x2c, 0x29, 0x9e, 0x33, 0x34, 0x5a, 0x7b, 0x11, 0x4b, 0x97, 0xc9,
0xa4, 0x72, 0x5e, 0x26, 0x39, 0x7f, 0x5c, 0x81, 0x59, 0xb9, 0xd2, 0xb9, 0xeb, 0xda, 0x62, 0x9d,
0x2d, 0x8c, 0x75, 0xac, 0x8b, 0x79, 0x24, 0xc0, 0xe4, 0x4e, 0x94, 0xdb, 0x6b, 0x2a, 0x45, 0x7b,
0x0d, 0x83, 0xea, 0xd8, 0x4b, 0x4e, 0xc9, 0xf5, 0xd2, 0x70, 0xe9, 0xb7, 0xf2, 0x52, 0xd6, 0x6c,
0x2f, 0x65, 0xd1, 0xe5, 0x74, 0xa1, 0x4e, 0xe5, 0x2f, 0xa7, 0xdf, 0x80, 0x86, 0xb8, 0xd0, 0x9c,
0x3a, 0x22, 0x53, 0x00, 0xa9, 0x57, 0x24, 0x48, 0x42, 0xc8, 0x3b, 0x32, 0x29, 0xf2, 0x15, 0x76,
0xb7, 0x6f, 0xc3, 0x8c, 0xb8, 0xa4, 0x21, 0x43, 0x6f, 0x6f, 0xa8, 0x43, 0x3a, 0x51, 0x4e, 0xfd,
0x15, 0x31, 0x3c, 0xae, 0x2c, 0x6b, 0x5e, 0xf3, 0x6c, 0xda, 0xd7, 0x3c, 0x4d, 0xff, 0x69, 0xcb,
0xf6, 0x9f, 0x3a, 0x4f, 0x60, 0xce, 0xaa, 0x0e, 0xa5, 0xab, 0x0c, 0xdd, 0x6d, 0x5f, 0x61, 0x73,
0xd0, 0x78, 0xb6, 0xdf, 0x7b, 0xb2, 0xf7, 0xec, 0xe9, 0xee, 0xcb, 0x76, 0x09, 0x93, 0x87, 0xaf,
0xb6, 0xb6, 0x76, 0x76, 0xb6, 0x49, 0xda, 0x02, 0xcc, 0x3c, 0xd9, 0x78, 0xb6, 0x47, 0xb2, 0x76,
0x5b, 0xd0, 0xb6, 0xac, 0x4b, 0x1f, 0x8c, 0x7c, 0x13, 0x98, 0xb2, 0xfb, 0x29, 0x84, 0x67, 0x3c,
0xe4, 0x89, 0x8a, 0x2a, 0x5f, 0x94, 0x39, 0xcf, 0x74, 0x86, 0xba, 0x18, 0x91, 0xd6, 0x92, 0xb2,
0x88, 0x9c, 0xa4, 0x2c, 0x8b, 0xc8, 0xa2, 0xae, 0xce, 0x77, 0xba, 0xd0, 0xd9, 0xe6, 0x58, 0xdb,
0xc6, 0x70, 0x98, 0xe9, 0x0e, 0x1a, 0x6e, 0x05, 0x79, 0xd2, 0xaa, 0xfb, 0x3e, 0x5c, 0xdd, 0x10,
0x01, 0xe4, 0xbf, 0xae, 0xf8, 0x42, 0xa7, 0x03, 0x2b, 0xd9, 0x2a, 0x65, 0x63, 0x4f, 0x60, 0x71,
0x9b, 0x1f, 0x4d, 0x4e, 0xf6, 0xf8, 0x59, 0xda, 0x10, 0x83, 0x6a, 0x7c, 0x1a, 0x9e, 0xcb, 0xf9,
0xa1, 0xdf, 0xec, 0x03, 0x80, 0x21, 0x96, 0xe9, 0xc5, 0x63, 0xde, 0x57, 0x97, 0x03, 0x09, 0x39,
0x1c, 0xf3, 0xbe, 0xf3, 0x29, 0x30, 0xb3, 0x1e, 0x39, 0x5f, 0xa8, 0x6b, 0x4d, 0x8e, 0x7a, 0xf1,
0x45, 0x9c, 0xf0, 0x91, 0xba, 0xf5, 0x68, 0x42, 0xce, 0x1d, 0x68, 0x1d, 0x78, 0x17, 0x2e, 0xff,
0x99, 0x7c, 0xb6, 0x60, 0x15, 0x66, 0xc7, 0xde, 0x05, 0x92, 0xa0, 0x76, 0x06, 0x53, 0xb6, 0xf3,
0xbf, 0xcb, 0x30, 0x23, 0x4a, 0x62, 0xad, 0x03, 0x1e, 0x27, 0x7e, 0x40, 0x9c, 0xa6, 0x6a, 0x35,
0xa0, 0x1c, 0x6f, 0x97, 0x0b, 0x78, 0x5b, 0x7a, 0x28, 0xd4, 0x25, 0x2b, 0xc9, 0xc0, 0x16, 0x86,
0x9c, 0x96, 0x06, 0x0a, 0x0b, 0x97, 0x61, 0x0a, 0x64, 0x4e, 0x16, 0x52, 0x8d, 0x4e, 0xf4, 0x4f,
0x89, 0x2d, 0xc9, 0xc6, 0x26, 0x54, 0xa8, 0x37, 0xce, 0x0a, 0x6e, 0xcf, 0xe9, 0x8d, 0x39, 0xfd,
0xb0, 0xfe, 0x1e, 0xfa, 0xa1, 0x70, 0x5b, 0xbc, 0x4b, 0x3f, 0x84, 0xf7, 0xd0, 0x0f, 0x1d, 0x06,
0x6d, 0xba, 0xc1, 0x8d, 0x16, 0x88, 0xa2, 0xdd, 0xbf, 0x5d, 0x82, 0xb6, 0xa4, 0x22, 0x9d, 0xa7,
0xce, 0xa8, 0xde, 0x75, 0xd5, 0xe7, 0x36, 0xcc, 0x91, 0xfd, 0xa3, 0x45, 0x80, 0x3c, 0xef, 0xb1,
0x40, 0x1c, 0x87, 0x0a, 0x33, 0x19, 0xf9, 0x43, 0xb9, 0x28, 0x26, 0xa4, 0xa4, 0x48, 0xe4, 0xc9,
0x80, 0xd7, 0x92, 0xab, 0xd3, 0xce, 0x1f, 0x95, 0x60, 0xd1, 0xe8, 0xb0, 0xa4, 0xc2, 0xc7, 0xd0,
0xd2, 0x0f, 0x25, 0x70, 0xbd, 0xb9, 0xad, 0xda, 0x6c, 0x93, 0x7e, 0x66, 0x15, 0xa6, 0xc5, 0xf4,
0x2e, 0xa8, 0x83, 0xf1, 0x64, 0x24, 0x77, 0x15, 0x13, 0x42, 0x42, 0x3a, 0xe7, 0xfc, 0x8d, 0x2e,
0x22, 0xf6, 0x35, 0x0b, 0x23, 0xbf, 0x31, 0xda, 0x6d, 0xba, 0x50, 0x55, 0xfa, 0x8d, 0x4d, 0xd0,
0xf9, 0x8b, 0x65, 0x58, 0x12, 0x86, 0xb8, 0x74, 0x80, 0xe8, 0xbb, 0xaa, 0x33, 0xc2, 0x27, 0x21,
0x38, 0x72, 0xf7, 0x8a, 0x2b, 0xd3, 0xec, 0x3b, 0xef, 0xe9, 0x3c, 0xd0, 0x51, 0xb8, 0x53, 0xd6,
0xa2, 0x52, 0xb4, 0x16, 0xef, 0x98, 0xe9, 0x22, 0x17, 0x7e, 0xad, 0xd8, 0x85, 0xff, 0x5e, 0x2e,
0xf3, 0xcd, 0x59, 0xa8, 0xc5, 0xfd, 0x70, 0xcc, 0x9d, 0x15, 0x58, 0xb6, 0xa7, 0x40, 0x0a, 0xaa,
0x5f, 0x94, 0xa0, 0xf3, 0x44, 0x9c, 0xc6, 0xf9, 0xc1, 0xc9, 0xae, 0x1f, 0x27, 0x61, 0xa4, 0x2f,
0xfe, 0xdf, 0x04, 0x88, 0x13, 0x2f, 0x92, 0x0a, 0xad, 0x50, 0x0d, 0x0c, 0x04, 0x47, 0xc2, 0x83,
0x81, 0xc8, 0x15, 0x2b, 0xa8, 0xd3, 0x39, 0xd5, 0x4b, 0x3a, 0x13, 0x2c, 0x05, 0xe6, 0x23, 0x11,
0xbb, 0x8e, 0x5d, 0xe6, 0x67, 0x24, 0xfd, 0x85, 0x85, 0x9e, 0x41, 0x9d, 0xdf, 0x2b, 0xc3, 0x42,
0xda, 0x49, 0x8a, 0xb1, 0xb0, 0x65, 0x88, 0xd4, 0x5a, 0x52, 0x19, 0x22, 0x1d, 0xff, 0x3d, 0x1f,
0xd5, 0x18, 0xc3, 0x9f, 0x60, 0xa0, 0xec, 0x36, 0x34, 0x55, 0x2a, 0x9c, 0x24, 0xc6, 0x0d, 0x5c,
0x13, 0x16, 0x11, 0xa9, 0xa8, 0x48, 0x49, 0xa5, 0x50, 0xa6, 0xe8, 0x36, 0xd0, 0x28, 0xa1, 0x2f,
0xc5, 0xcc, 0xab, 0x24, 0x6b, 0x0b, 0x4d, 0x44, 0x3c, 0x86, 0x42, 0x5a, 0x88, 0xb9, 0x43, 0xd7,
0xf5, 0xcb, 0x25, 0x9a, 0x33, 0x45, 0x8d, 0x69, 0x38, 0x71, 0xd5, 0x35, 0x21, 0x65, 0xd1, 0x85,
0x13, 0x69, 0x9d, 0x88, 0xb7, 0x4f, 0x2c, 0xcc, 0xf9, 0xeb, 0x25, 0xb8, 0x56, 0xb0, 0x8c, 0x92,
0x53, 0xb7, 0x61, 0xf1, 0x58, 0x67, 0xaa, 0xa9, 0x16, 0xec, 0xba, 0xa2, 0x42, 0x0e, 0xec, 0xe9,
0x75, 0xf3, 0x1f, 0x68, 0xe5, 0x54, 0x2c, 0x9e, 0x15, 0x39, 0x9e, 0xcf, 0x70, 0x0e, 0xa0, 0xbb,
0xf3, 0x16, 0x19, 0x7f, 0xcb, 0x7c, 0xbf, 0x4d, 0x51, 0xd6, 0xc3, 0x9c, 0x60, 0xbb, 0xdc, 0x8d,
0x74, 0x0c, 0x73, 0x56, 0x5d, 0xec, 0x5b, 0xef, 0x5b, 0x89, 0xc9, 0xa3, 0x6b, 0x72, 0xd5, 0xc5,
0x03, 0x74, 0x2a, 0x7e, 0xdd, 0x80, 0x9c, 0x33, 0x58, 0x78, 0x3e, 0x19, 0x26, 0x7e, 0xfa, 0x18,
0x1d, 0xfb, 0x8e, 0xfc, 0x88, 0xaa, 0x50, 0x53, 0x57, 0xd8, 0x94, 0x59, 0x0e, 0x67, 0x6c, 0x84,
0x35, 0xf5, 0xf2, 0x2d, 0xe6, 0x33, 0x9c, 0x6b, 0xb0, 0x9a, 0x36, 0x29, 0xe6, 0x4e, 0x6d, 0x0e,
0xbf, 0x5f, 0x12, 0x81, 0x58, 0xf6, 0xdb, 0x78, 0xec, 0x29, 0x2c, 0xc5, 0x7e, 0x70, 0x32, 0xe4,
0x66, 0x3d, 0xb1, 0x9c, 0x89, 0xab, 0x76, 0xf7, 0xe4, 0xfb, 0x79, 0x6e, 0xd1, 0x17, 0x48, 0x20,
0xc5, 0x1d, 0x4d, 0x09, 0x24, 0x33, 0x25, 0x45, 0x03, 0xf8, 0x2e, 0xcc, 0xdb, 0x8d, 0xb1, 0x47,
0x32, 0xf4, 0x3c, 0xed, 0x99, 0x79, 0xee, 0x63, 0x53, 0x86, 0x55, 0xd2, 0xf9, 0xb2, 0x04, 0x1d,
0x97, 0x23, 0x19, 0x73, 0xa3, 0x51, 0x49, 0x3d, 0x8f, 0x73, 0xd5, 0x4e, 0x1f, 0xb0, 0x0e, 0x69,
0x57, 0x63, 0x5d, 0x9f, 0xba, 0x28, 0xbb, 0x57, 0x0a, 0x46, 0xb5, 0x59, 0x87, 0x19, 0x39, 0xbe,
0x55, 0xb8, 0x2a, 0xbb, 0xa4, 0xba, 0x93, 0x1e, 0x18, 0x58, 0x8d, 0x5a, 0x07, 0x06, 0x5d, 0xe8,
0x88, 0xf7, 0x1d, 0xcc, 0x71, 0xc8, 0x0f, 0xb7, 0x81, 0x3d, 0xf7, 0xfa, 0x5e, 0x14, 0x86, 0xc1,
0x01, 0x8f, 0x64, 0x50, 0x0d, 0x29, 0x40, 0xe4, 0x4f, 0x57, 0xba, 0x9a, 0x48, 0xa9, 0x27, 0x09,
0xc2, 0x40, 0x3d, 0xfd, 0x20, 0x52, 0x8e, 0x0b, 0x4b, 0x9b, 0xde, 0x1b, 0xae, 0x6a, 0x4a, 0x67,
0xa9, 0x39, 0xd6, 0x95, 0xaa, 0xb9, 0x57, 0x37, 0x4a, 0xf2, 0xcd, 0xba, 0x66, 0x69, 0xe7, 0x21,
0x2c, 0xdb, 0x75, 0x4a, 0x51, 0xd2, 0x85, 0xfa, 0x48, 0x62, 0xb2, 0x77, 0x3a, 0x7d, 0xef, 0x0b,
0x68, 0x1a, 0x6f, 0x76, 0xb0, 0x55, 0x58, 0x7a, 0xfd, 0xec, 0xe5, 0xfe, 0xce, 0xe1, 0x61, 0xef,
0xe0, 0xd5, 0xe6, 0xf7, 0x76, 0x7e, 0xd8, 0xdb, 0xdd, 0x38, 0xdc, 0x6d, 0x5f, 0x61, 0x2b, 0xc0,
0xf6, 0x77, 0x0e, 0x5f, 0xee, 0x6c, 0x5b, 0x78, 0x89, 0xdd, 0x84, 0xee, 0xab, 0xfd, 0x57, 0x87,
0x3b, 0xdb, 0xbd, 0xa2, 0xef, 0xca, 0xec, 0x03, 0xb8, 0x26, 0xf3, 0x0b, 0x3e, 0xaf, 0xdc, 0x7b,
0x0c, 0xed, 0xac, 0xff, 0xc3, 0xf2, 0x18, 0xbd, 0xcb, 0xb5, 0xf4, 0xf0, 0xcb, 0x0a, 0xcc, 0x8b,
0xd0, 0x38, 0xf1, 0xba, 0x24, 0x8f, 0xd8, 0x73, 0x98, 0x95, 0xcf, 0x94, 0x32, 0x45, 0x5a, 0xf6,
0xc3, 0xa8, 0xdd, 0x95, 0x2c, 0x2c, 0x97, 0x75, 0xe9, 0x2f, 0xfd, 0xc7, 0xff, 0xfe, 0x37, 0xcb,
0x73, 0xac, 0x79, 0xff, 0xec, 0x93, 0xfb, 0x27, 0x3c, 0x88, 0xb1, 0x8e, 0xdf, 0x01, 0x48, 0x1f,
0xdf, 0x64, 0x1d, 0xed, 0x03, 0xc8, 0xbc, 0x4c, 0xda, 0xbd, 0x56, 0x90, 0x23, 0xeb, 0xbd, 0x46,
0xf5, 0x2e, 0x39, 0xf3, 0x58, 0xaf, 0x1f, 0xf8, 0x89, 0x78, 0x88, 0xf3, 0xb3, 0xd2, 0x3d, 0x36,
0x80, 0x96, 0xf9, 0x2c, 0x26, 0x53, 0xe7, 0x3f, 0x05, 0x0f, 0x7b, 0x76, 0xaf, 0x17, 0xe6, 0x29,
0x5a, 0xa6, 0x36, 0xae, 0x3a, 0x6d, 0x6c, 0x63, 0x42, 0x25, 0xd2, 0x56, 0x86, 0x82, 0xc3, 0xd3,
0xd7, 0x2f, 0xd9, 0x0d, 0x83, 0xe9, 0x72, 0x6f, 0x6f, 0x76, 0x3f, 0x98, 0x92, 0x2b, 0xdb, 0xfa,
0x80, 0xda, 0x5a, 0x75, 0x18, 0xb6, 0xd5, 0xa7, 0x32, 0xea, 0xed, 0xcd, 0xcf, 0x4a, 0xf7, 0x1e,
0xfe, 0xbb, 0x3b, 0xd0, 0xd0, 0x67, 0xc3, 0xec, 0xa7, 0x30, 0x67, 0xc5, 0x2e, 0x32, 0x35, 0x8c,
0xa2, 0x50, 0xc7, 0xee, 0x8d, 0xe2, 0x4c, 0xd9, 0xf0, 0x4d, 0x6a, 0xb8, 0xc3, 0x56, 0xb0, 0x61,
0x19, 0xfc, 0x77, 0x9f, 0xa2, 0x70, 0xc5, 0x25, 0xbe, 0x37, 0x86, 0x24, 0x13, 0x8d, 0xdd, 0xc8,
0x0a, 0x17, 0xab, 0xb5, 0x0f, 0xa6, 0xe4, 0xca, 0xe6, 0x6e, 0x50, 0x73, 0x2b, 0x6c, 0xd9, 0x6c,
0x4e, 0x9f, 0xd7, 0x72, 0xba, 0xb9, 0x6a, 0x3e, 0x0c, 0xc9, 0x3e, 0xd0, 0x84, 0x55, 0xf4, 0x60,
0xa4, 0x26, 0x91, 0xfc, 0xab, 0x91, 0x4e, 0x87, 0x9a, 0x62, 0x8c, 0x96, 0xcf, 0x7c, 0x17, 0x92,
0x1d, 0x41, 0xd3, 0x78, 0x3e, 0x8a, 0x5d, 0x9b, 0xfa, 0xd4, 0x55, 0xb7, 0x5b, 0x94, 0x55, 0x34,
0x14, 0xb3, 0xfe, 0xfb, 0xa8, 0xe8, 0xfc, 0x18, 0x1a, 0xfa, 0x41, 0x22, 0xb6, 0x6a, 0x3c, 0x10,
0x65, 0x3e, 0xa0, 0xd4, 0xed, 0xe4, 0x33, 0x8a, 0x88, 0xcf, 0xac, 0x1d, 0x89, 0xef, 0x35, 0x34,
0x8d, 0x47, 0x87, 0xf4, 0x00, 0xf2, 0x0f, 0x1b, 0xe9, 0x01, 0x14, 0xbc, 0x51, 0xe4, 0x2c, 0x52,
0x13, 0x4d, 0xd6, 0x20, 0xfa, 0x4e, 0xde, 0x86, 0x31, 0xdb, 0x83, 0xab, 0x52, 0x62, 0x1f, 0xf1,
0xaf, 0xb2, 0x0c, 0x05, 0x6f, 0x71, 0x3e, 0x28, 0xb1, 0xc7, 0x50, 0x57, 0x6f, 0x4b, 0xb1, 0x95,
0xe2, 0x37, 0xb2, 0xba, 0xab, 0x39, 0x5c, 0x8a, 0xd7, 0x1f, 0x02, 0xa4, 0x2f, 0x1c, 0x69, 0x21,
0x91, 0x7b, 0x31, 0x49, 0x53, 0x40, 0xfe, 0x39, 0x24, 0x67, 0x85, 0x06, 0xd8, 0x66, 0x24, 0x24,
0x02, 0x7e, 0xae, 0x2e, 0xa9, 0xff, 0x04, 0x9a, 0xc6, 0x23, 0x47, 0x7a, 0xfa, 0xf2, 0x0f, 0x24,
0xe9, 0xe9, 0x2b, 0x78, 0x13, 0xc9, 0xe9, 0x52, 0xed, 0xcb, 0xce, 0x02, 0xd6, 0x1e, 0xfb, 0x27,
0xc1, 0x48, 0x14, 0xc0, 0x05, 0x3a, 0x85, 0x39, 0xeb, 0x25, 0x23, 0xcd, 0xa1, 0x45, 0xef, 0x24,
0x69, 0x0e, 0x2d, 0x7c, 0xfc, 0x48, 0xd1, 0x99, 0xb3, 0x88, 0xed, 0x9c, 0x51, 0x11, 0xa3, 0xa5,
0x1f, 0x41, 0xd3, 0x78, 0x95, 0x48, 0x8f, 0x25, 0xff, 0x00, 0x92, 0x1e, 0x4b, 0xd1, 0x23, 0x46,
0xcb, 0xd4, 0xc6, 0xbc, 0x43, 0xa4, 0x40, 0xd7, 0xad, 0xb1, 0xee, 0x9f, 0xc2, 0xbc, 0xfd, 0x4e,
0x91, 0xe6, 0xfd, 0xc2, 0x17, 0x8f, 0x34, 0xef, 0x4f, 0x79, 0xdc, 0x48, 0x92, 0xf4, 0xbd, 0x25,
0xdd, 0xc8, 0xfd, 0xcf, 0x65, 0x74, 0xd9, 0x17, 0xec, 0xfb, 0x28, 0xe0, 0xe4, 0xfd, 0x77, 0xb6,
0x6a, 0x50, 0xad, 0x79, 0x4b, 0x5e, 0xf3, 0x4b, 0xee, 0xaa, 0xbc, 0x4d, 0xcc, 0xe2, 0xc2, 0x38,
0xed, 0x5a, 0x74, 0x0f, 0xde, 0xd8, 0xb5, 0xcc, 0xab, 0xf2, 0xc6, 0xae, 0x65, 0x5d, 0x97, 0xcf,
0xee, 0x5a, 0x89, 0x8f, 0x75, 0x04, 0xb0, 0x90, 0xb9, 0x5f, 0xa1, 0xb9, 0xa2, 0xf8, 0x0a, 0x5c,
0xf7, 0xe6, 0xbb, 0xaf, 0x65, 0xd8, 0x12, 0x44, 0x09, 0xc1, 0xfb, 0xea, 0xc2, 0xe1, 0xef, 0x42,
0xcb, 0x7c, 0x3b, 0x85, 0x99, 0xac, 0x9c, 0x6d, 0xe9, 0x7a, 0x61, 0x9e, 0xbd, 0xb8, 0xac, 0x65,
0x36, 0xc3, 0x7e, 0x00, 0x2b, 0x9a, 0xd5, 0xcd, 0x90, 0xfd, 0x98, 0xdd, 0x2a, 0x08, 0xe4, 0x37,
0xf5, 0xb8, 0xee, 0xb5, 0xa9, 0x91, 0xfe, 0x0f, 0x4a, 0x48, 0x34, 0xf6, 0x83, 0x14, 0xe9, 0x86,
0x51, 0xf4, 0x0e, 0x47, 0xba, 0x61, 0x14, 0xbe, 0x62, 0xa1, 0x88, 0x86, 0x2d, 0x59, 0x73, 0x24,
0x0e, 0xe2, 0xd9, 0x8f, 0x60, 0xc1, 0xb8, 0x14, 0x75, 0x78, 0x11, 0xf4, 0x35, 0x03, 0xe4, 0xef,
0xeb, 0x76, 0x8b, 0xac, 0x14, 0x67, 0x95, 0xea, 0x5f, 0x74, 0xac, 0xc9, 0x41, 0xe2, 0xdf, 0x82,
0xa6, 0x79, 0xe1, 0xea, 0x1d, 0xf5, 0xae, 0x1a, 0x59, 0xe6, 0x75, 0xd3, 0x07, 0x25, 0x76, 0x20,
0x02, 0xb2, 0xf4, 0xe3, 0x98, 0x61, 0x94, 0xdd, 0x3e, 0xed, 0x47, 0x33, 0xf5, 0x42, 0x16, 0x3d,
0x97, 0x7a, 0xb7, 0xf4, 0xa0, 0xc4, 0xfe, 0x4e, 0x09, 0x5a, 0xd6, 0x85, 0x28, 0x2b, 0xbc, 0x25,
0xd3, 0xb3, 0x8e, 0x99, 0x67, 0x76, 0xcd, 0x71, 0x69, 0xd8, 0x7b, 0xf7, 0xbe, 0x6b, 0x4d, 0xeb,
0xe7, 0x96, 0x43, 0x6d, 0x3d, 0xfb, 0x42, 0xe6, 0x17, 0xd9, 0x02, 0xe6, 0x2d, 0xe9, 0x2f, 0x1e,
0x94, 0xd8, 0x1f, 0x96, 0x60, 0xde, 0x76, 0x03, 0xeb, 0xe1, 0x16, 0x3a, 0x9c, 0xf5, 0xe2, 0x4f,
0xf1, 0x1d, 0xff, 0x88, 0x7a, 0xf9, 0xf2, 0x9e, 0x6b, 0xf5, 0x52, 0x3e, 0x7e, 0xf2, 0xab, 0xf5,
0x96, 0x7d, 0x26, 0x9e, 0x74, 0x56, 0x87, 0x35, 0x2c, 0xff, 0xb0, 0xb0, 0x26, 0x18, 0xf3, 0x29,
0x60, 0x5a, 0x84, 0x9f, 0x88, 0x97, 0x21, 0xd5, 0x79, 0x02, 0xd2, 0xdd, 0xfb, 0x7e, 0xef, 0xdc,
0xa6, 0x31, 0xdd, 0x74, 0xae, 0x59, 0x63, 0xca, 0xee, 0xf0, 0x1b, 0xa2, 0x77, 0xf2, 0x15, 0xdf,
0x74, 0x8b, 0xca, 0xbd, 0xec, 0x3b, 0xbd, 0x93, 0x23, 0xd1, 0x49, 0x59, 0xdc, 0x62, 0x8e, 0xf7,
0xac, 0xc6, 0xb9, 0x47, 0x7d, 0xbd, 0xed, 0xdc, 0x9a, 0xda, 0xd7, 0xfb, 0xe4, 0xcc, 0xc5, 0x1e,
0x1f, 0x00, 0xa4, 0x07, 0xab, 0x2c, 0x73, 0xb0, 0xa7, 0x45, 0x46, 0xfe, 0xec, 0xd5, 0xe6, 0x40,
0x75, 0xfe, 0x87, 0x35, 0xfe, 0x58, 0x08, 0xc0, 0x67, 0xea, 0x48, 0xd0, 0x54, 0x73, 0xec, 0x13,
0x50, 0x4b, 0xcd, 0xc9, 0xd6, 0x6f, 0x89, 0x3f, 0x7d, 0xbe, 0xf8, 0x0a, 0xe6, 0xf6, 0xc2, 0xf0,
0xcd, 0x64, 0xac, 0x23, 0x4f, 0xec, 0x73, 0x96, 0x5d, 0x2f, 0x3e, 0xed, 0x66, 0x46, 0xe1, 0xac,
0x51, 0x55, 0x5d, 0xd6, 0x31, 0xaa, 0xba, 0xff, 0x79, 0x7a, 0x70, 0xfb, 0x05, 0xf3, 0x60, 0x51,
0x4b, 0x55, 0xdd, 0xf1, 0xae, 0x5d, 0x8d, 0x25, 0x4b, 0xb3, 0x4d, 0x58, 0xfa, 0xb8, 0xea, 0xed,
0xfd, 0x58, 0xd5, 0x49, 0x32, 0xa5, 0xb5, 0xcd, 0xfb, 0x74, 0xdd, 0x83, 0x0e, 0x2b, 0x96, 0xd2,
0x8e, 0xeb, 0x53, 0x8e, 0xee, 0x9c, 0x05, 0xda, 0x3b, 0xcd, 0xd8, 0xbb, 0x88, 0xf8, 0xcf, 0xee,
0x7f, 0x2e, 0x8f, 0x41, 0xbe, 0x50, 0x3b, 0x8d, 0x3a, 0x27, 0xb2, 0x76, 0x9a, 0xcc, 0xc1, 0x92,
0xb5, 0xd3, 0xe4, 0x0e, 0x96, 0xac, 0xa9, 0x56, 0xe7, 0x54, 0x6c, 0x08, 0x8b, 0xb9, 0xb3, 0x28,
0xbd, 0xc9, 0x4c, 0x3b, 0xc1, 0xea, 0xae, 0x4d, 0x2f, 0x60, 0xb7, 0x76, 0xcf, 0x6e, 0xed, 0x10,
0xe6, 0xb6, 0xb9, 0x98, 0x2c, 0x11, 0x6a, 0x9b, 0xb9, 0x55, 0x67, 0x06, 0xf2, 0x66, 0xb7, 0x04,
0xca, 0xb3, 0x55, 0x09, 0x8a, 0x71, 0x65, 0x3f, 0x86, 0xe6, 0x53, 0x9e, 0xa8, 0xd8, 0x5a, 0xad,
0xcc, 0x66, 0x82, 0x6d, 0xbb, 0x05, 0xa1, 0xb9, 0x36, 0xcd, 0x50, 0x6d, 0xf7, 0xf9, 0xe0, 0x84,
0x0b, 0xe1, 0xd4, 0xf3, 0x07, 0x5f, 0xb0, 0x3f, 0x47, 0x95, 0xeb, 0xcb, 0x05, 0x2b, 0x46, 0xa0,
0xa4, 0x59, 0xf9, 0x42, 0x06, 0x2f, 0xaa, 0x39, 0x08, 0x07, 0xdc, 0x50, 0xaa, 0x02, 0x68, 0x1a,
0x17, 0x71, 0x34, 0x03, 0xe5, 0xef, 0x75, 0x69, 0x06, 0x2a, 0xb8, 0xb7, 0xe3, 0xdc, 0xa5, 0x76,
0x1c, 0xb6, 0x96, 0xb6, 0x23, 0xee, 0xea, 0xa4, 0x2d, 0xdd, 0xff, 0xdc, 0x1b, 0x25, 0x5f, 0xb0,
0xd7, 0xf4, 0x18, 0x91, 0x19, 0x3b, 0x9c, 0x6a, 0xe7, 0xd9, 0x30, 0x63, 0x3d, 0x59, 0x46, 0x96,
0xad, 0xb1, 0x8b, 0xa6, 0x48, 0xf7, 0xfa, 0x0e, 0xc0, 0x61, 0x12, 0x8e, 0xb7, 0x3d, 0x3e, 0x0a,
0x83, 0x54, 0xd6, 0xa6, 0x91, 0xab, 0xa9, 0xfc, 0x32, 0xc2, 0x57, 0xd9, 0x6b, 0xc3, 0x9c, 0xb1,
0xc2, 0xaf, 0x15, 0x71, 0x4d, 0x0d, 0x6e, 0xd5, 0x13, 0x52, 0x10, 0xe0, 0xfa, 0xa0, 0xc4, 0x36,
0x00, 0xd2, 0xc3, 0x48, 0x6d, 0x9c, 0xe4, 0xce, 0x39, 0xb5, 0xd8, 0x2b, 0x38, 0xb9, 0x3c, 0x80,
0x46, 0x7a, 0xba, 0xb5, 0x9a, 0x5e, 0x77, 0xb3, 0xce, 0xc2, 0xf4, 0x0e, 0x9e, 0x3b, 0x73, 0x72,
0xda, 0x34, 0x55, 0xc0, 0xea, 0x38, 0x55, 0x74, 0x90, 0xe4, 0xc3, 0x92, 0xe8, 0xa0, 0x56, 0x70,
0x28, 0xe2, 0x52, 0x8d, 0xa4, 0xe0, 0xdc, 0x47, 0x73, 0x73, 0xe1, 0x81, 0x88, 0xe5, 0x63, 0x41,
0x6a, 0x15, 0xd1, 0x9e, 0x28, 0x9a, 0x47, 0xb0, 0x98, 0xf3, 0xb1, 0x6b, 0x96, 0x9e, 0x76, 0x88,
0xa2, 0x59, 0x7a, 0xaa, 0x7b, 0xde, 0xb9, 0x4a, 0x4d, 0x2e, 0x38, 0x40, 0x36, 0xd5, 0xb9, 0x9f,
0xf4, 0x4f, 0xb1, 0xb9, 0xdf, 0x2f, 0xc1, 0x52, 0x81, 0x0b, 0x9d, 0x7d, 0xa8, 0xcc, 0xf3, 0xa9,
0xee, 0xf5, 0x6e, 0xa1, 0x87, 0xd5, 0x39, 0xa4, 0x76, 0x9e, 0xb3, 0xef, 0x59, 0x1b, 0x9b, 0x70,
0x6e, 0x4a, 0xce, 0x7c, 0xa7, 0x52, 0x51, 0xa8, 0x51, 0xfc, 0x0c, 0x56, 0x45, 0x47, 0x36, 0x86,
0xc3, 0x8c, 0xf7, 0xf7, 0x66, 0xee, 0xbf, 0xba, 0x58, 0x5e, 0xed, 0xee, 0xf4, 0xff, 0xfa, 0x32,
0x45, 0x01, 0x16, 0x5d, 0x65, 0x13, 0x68, 0x67, 0x3d, 0xaa, 0x6c, 0x7a, 0x5d, 0xdd, 0x5b, 0x96,
0xa1, 0x59, 0xe0, 0x85, 0xfd, 0x0d, 0x6a, 0xec, 0x96, 0xd3, 0x2d, 0x9a, 0x17, 0x61, 0x7b, 0xe2,
0x7a, 0xfc, 0x05, 0xed, 0xfe, 0xcd, 0x8c, 0x53, 0x35, 0x30, 0xcd, 0x5f, 0xad, 0x4d, 0xdd, 0x62,
0xef, 0xf1, 0x47, 0xd4, 0xfc, 0x9a, 0x73, 0xbd, 0xa8, 0xf9, 0x48, 0x7c, 0x22, 0x8c, 0xde, 0xd5,
0x2c, 0x5f, 0xab, 0x1e, 0xac, 0x15, 0xad, 0xf7, 0x54, 0xeb, 0x25, 0x33, 0xd7, 0x57, 0x48, 0xb7,
0x6b, 0x99, 0xee, 0x5e, 0xcd, 0x3e, 0x05, 0x7e, 0x65, 0xcd, 0x3e, 0x45, 0xfe, 0x61, 0x5b, 0xaf,
0x51, 0x9e, 0xe1, 0xcf, 0x4a, 0xf7, 0x36, 0xef, 0xfc, 0xe8, 0x37, 0x4e, 0xfc, 0xe4, 0x74, 0x72,
0xb4, 0xde, 0x0f, 0x47, 0xf7, 0x87, 0xca, 0xad, 0x27, 0x6f, 0x21, 0xdc, 0x1f, 0x06, 0x83, 0xfb,
0x54, 0xed, 0xd1, 0x0c, 0xfd, 0x1b, 0xaa, 0x6f, 0xfd, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8b,
0x4e, 0x52, 0x4c, 0xb8, 0x6a, 0x00, 0x00,
// 8678 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x7d, 0x5d, 0x6c, 0x24, 0x49,
0xb6, 0x56, 0xd7, 0x9f, 0x5d, 0x75, 0xaa, 0x6c, 0x97, 0xc3, 0x6e, 0xbb, 0xba, 0xa6, 0xa7, 0xc7,
0x93, 0xdb, 0x77, 0xba, 0xb7, 0x77, 0xd6, 0xdd, 0xe3, 0xdd, 0x1d, 0xe6, 0x4e, 0x73, 0xb9, 0xf8,
0xaf, 0xdb, 0xbd, 0xe3, 0x76, 0x7b, 0xd3, 0xdd, 0xdb, 0xec, 0xee, 0xbd, 0xaa, 0x4d, 0x57, 0x85,
0xed, 0xdc, 0xae, 0xca, 0xac, 0xcd, 0xcc, 0xb2, 0xdb, 0x3b, 0x0c, 0x12, 0x08, 0x21, 0xc4, 0x0b,
0x1a, 0x78, 0x01, 0x04, 0xba, 0xd2, 0x5e, 0x24, 0xee, 0x85, 0x07, 0xe0, 0x01, 0x09, 0xd0, 0x95,
0x78, 0xe0, 0x01, 0x09, 0x09, 0xf1, 0xc0, 0x03, 0x12, 0x0f, 0xac, 0x10, 0x48, 0x68, 0x85, 0x78,
0x41, 0xe2, 0x1d, 0x9d, 0x13, 0x3f, 0x19, 0x91, 0x99, 0xd5, 0xee, 0xd9, 0x5d, 0xee, 0x93, 0x2b,
0xbe, 0x88, 0x8c, 0xdf, 0x73, 0x4e, 0x9c, 0x73, 0xe2, 0x44, 0x18, 0x1a, 0xd1, 0xb8, 0xbf, 0x3e,
0x8e, 0xc2, 0x24, 0x64, 0xb5, 0x61, 0x10, 0x8d, 0xfb, 0xdd, 0x9b, 0xa7, 0x61, 0x78, 0x3a, 0xe4,
0xf7, 0xbd, 0xb1, 0x7f, 0xdf, 0x0b, 0x82, 0x30, 0xf1, 0x12, 0x3f, 0x0c, 0x62, 0x51, 0xc8, 0xf9,
0x31, 0xcc, 0x3f, 0xe6, 0xc1, 0x11, 0xe7, 0x03, 0x97, 0xff, 0x74, 0xc2, 0xe3, 0x84, 0x7d, 0x03,
0x16, 0x3d, 0xfe, 0x33, 0xce, 0x07, 0xbd, 0xb1, 0x17, 0xc7, 0xe3, 0xb3, 0xc8, 0x8b, 0x79, 0xa7,
0xb4, 0x56, 0xba, 0xdb, 0x72, 0xdb, 0x22, 0xe3, 0x50, 0xe3, 0xec, 0x7d, 0x68, 0xc5, 0x58, 0x94,
0x07, 0x49, 0x14, 0x8e, 0x2f, 0x3b, 0x65, 0x2a, 0xd7, 0x44, 0x6c, 0x57, 0x40, 0xce, 0x10, 0x16,
0x74, 0x0b, 0xf1, 0x38, 0x0c, 0x62, 0xce, 0x1e, 0xc0, 0x72, 0xdf, 0x1f, 0x9f, 0xf1, 0xa8, 0x47,
0x1f, 0x8f, 0x02, 0x3e, 0x0a, 0x03, 0xbf, 0xdf, 0x29, 0xad, 0x55, 0xee, 0x36, 0x5c, 0x26, 0xf2,
0xf0, 0x8b, 0xa7, 0x32, 0x87, 0xdd, 0x81, 0x05, 0x1e, 0x08, 0x9c, 0x0f, 0xe8, 0x2b, 0xd9, 0xd4,
0x7c, 0x0a, 0xe3, 0x07, 0xce, 0x5f, 0x2f, 0xc3, 0xe2, 0x93, 0xc0, 0x4f, 0x5e, 0x7a, 0xc3, 0x21,
0x4f, 0xd4, 0x98, 0xee, 0xc0, 0xc2, 0x05, 0x01, 0x34, 0xa6, 0x8b, 0x30, 0x1a, 0xc8, 0x11, 0xcd,
0x0b, 0xf8, 0x50, 0xa2, 0x53, 0x7b, 0x56, 0x9e, 0xda, 0xb3, 0xc2, 0xe9, 0xaa, 0x4c, 0x99, 0xae,
0x3b, 0xb0, 0x10, 0xf1, 0x7e, 0x78, 0xce, 0xa3, 0xcb, 0xde, 0x85, 0x1f, 0x0c, 0xc2, 0x8b, 0x4e,
0x75, 0xad, 0x74, 0xb7, 0xe6, 0xce, 0x2b, 0xf8, 0x25, 0xa1, 0x6c, 0x0b, 0x16, 0xfa, 0x67, 0x5e,
0x10, 0xf0, 0x61, 0xef, 0xd8, 0xeb, 0xbf, 0x9a, 0x8c, 0xe3, 0x4e, 0x6d, 0xad, 0x74, 0xb7, 0xb9,
0x71, 0x63, 0x9d, 0x56, 0x75, 0x7d, 0xfb, 0xcc, 0x0b, 0xb6, 0x28, 0xe7, 0x28, 0xf0, 0xc6, 0xf1,
0x59, 0x98, 0xb8, 0xf3, 0xf2, 0x0b, 0x01, 0xc7, 0xce, 0x32, 0x30, 0x73, 0x26, 0xc4, 0xdc, 0x3b,
0xff, 0xa4, 0x04, 0x4b, 0x2f, 0x82, 0x61, 0xd8, 0x7f, 0xf5, 0x2b, 0x4e, 0x51, 0xc1, 0x18, 0xca,
0x6f, 0x3b, 0x86, 0xca, 0x57, 0x1d, 0xc3, 0x0a, 0x2c, 0xdb, 0x9d, 0x95, 0xa3, 0xe0, 0x70, 0x1d,
0xbf, 0x3e, 0xe5, 0xaa, 0x5b, 0x6a, 0x18, 0x5f, 0x87, 0x76, 0x7f, 0x12, 0x45, 0x3c, 0xc8, 0x8d,
0x63, 0x41, 0xe2, 0x7a, 0x20, 0xef, 0x43, 0x2b, 0xe0, 0x17, 0x69, 0x31, 0x49, 0xbb, 0x01, 0xbf,
0x50, 0x45, 0x9c, 0x0e, 0xac, 0x64, 0x9b, 0x91, 0x1d, 0xf8, 0x6f, 0x25, 0xa8, 0xbe, 0x48, 0x5e,
0x87, 0x6c, 0x1d, 0xaa, 0xc9, 0xe5, 0x58, 0x70, 0xc8, 0xfc, 0x06, 0x93, 0x43, 0xdb, 0x1c, 0x0c,
0x22, 0x1e, 0xc7, 0xcf, 0x2f, 0xc7, 0xdc, 0x6d, 0x79, 0x22, 0xd1, 0xc3, 0x72, 0xac, 0x03, 0xb3,
0x32, 0x4d, 0x0d, 0x36, 0x5c, 0x95, 0x64, 0xb7, 0x00, 0xbc, 0x51, 0x38, 0x09, 0x92, 0x5e, 0xec,
0x25, 0x34, 0x55, 0x15, 0xd7, 0x40, 0xd8, 0x4d, 0x68, 0x8c, 0x5f, 0xf5, 0xe2, 0x7e, 0xe4, 0x8f,
0x13, 0x22, 0x9b, 0x86, 0x9b, 0x02, 0xec, 0x1b, 0x50, 0x0f, 0x27, 0xc9, 0x38, 0xf4, 0x83, 0x44,
0x92, 0xca, 0x82, 0xec, 0xcb, 0xb3, 0x49, 0x72, 0x88, 0xb0, 0xab, 0x0b, 0xb0, 0xdb, 0x30, 0xd7,
0x0f, 0x83, 0x13, 0x3f, 0x1a, 0x09, 0x61, 0xd0, 0x99, 0xa1, 0xd6, 0x6c, 0xd0, 0xf9, 0x57, 0x65,
0x68, 0x3e, 0x8f, 0xbc, 0x20, 0xf6, 0xfa, 0x08, 0x60, 0xd7, 0x93, 0xd7, 0xbd, 0x33, 0x2f, 0x3e,
0xa3, 0xd1, 0x36, 0x5c, 0x95, 0x64, 0x2b, 0x30, 0x23, 0x3a, 0x4a, 0x63, 0xaa, 0xb8, 0x32, 0xc5,
0x3e, 0x84, 0xc5, 0x60, 0x32, 0xea, 0xd9, 0x6d, 0x55, 0x88, 0x5a, 0xf2, 0x19, 0x38, 0x01, 0xc7,
0xb8, 0xd6, 0xa2, 0x09, 0x31, 0x42, 0x03, 0x61, 0x0e, 0xb4, 0x64, 0x8a, 0xfb, 0xa7, 0x67, 0x62,
0x98, 0x35, 0xd7, 0xc2, 0xb0, 0x8e, 0xc4, 0x1f, 0xf1, 0x5e, 0x9c, 0x78, 0xa3, 0xb1, 0x1c, 0x96,
0x81, 0x50, 0x7e, 0x98, 0x78, 0xc3, 0xde, 0x09, 0xe7, 0x71, 0x67, 0x56, 0xe6, 0x6b, 0x84, 0x7d,
0x00, 0xf3, 0x03, 0x1e, 0x27, 0x3d, 0xb9, 0x28, 0x3c, 0xee, 0xd4, 0x89, 0xf5, 0x33, 0x28, 0xd6,
0x13, 0x79, 0x17, 0x3d, 0x9c, 0x00, 0xfe, 0xba, 0xd3, 0x10, 0x7d, 0x4d, 0x11, 0xa4, 0x9c, 0xc7,
0x3c, 0x31, 0x66, 0x2f, 0x96, 0x14, 0xea, 0xec, 0x03, 0x33, 0xe0, 0x1d, 0x9e, 0x78, 0xfe, 0x30,
0x66, 0x1f, 0x43, 0x2b, 0x31, 0x0a, 0x93, 0x28, 0x6c, 0x6a, 0x72, 0x32, 0x3e, 0x70, 0xad, 0x72,
0xce, 0x63, 0xa8, 0x3f, 0xe2, 0x7c, 0xdf, 0x1f, 0xf9, 0x09, 0x5b, 0x81, 0xda, 0x89, 0xff, 0x9a,
0x0b, 0x82, 0xaf, 0xec, 0x5d, 0x73, 0x45, 0x92, 0x75, 0x61, 0x76, 0xcc, 0xa3, 0x3e, 0x57, 0xcb,
0xb3, 0x77, 0xcd, 0x55, 0xc0, 0xd6, 0x2c, 0xd4, 0x86, 0xf8, 0xb1, 0xf3, 0xbf, 0x2b, 0xd0, 0x3c,
0xe2, 0x81, 0x66, 0x24, 0x06, 0x55, 0x1c, 0xb2, 0x64, 0x1e, 0xfa, 0xcd, 0xde, 0x83, 0x26, 0x4d,
0x43, 0x9c, 0x44, 0x7e, 0x70, 0x2a, 0xe9, 0x17, 0x10, 0x3a, 0x22, 0x84, 0xb5, 0xa1, 0xe2, 0x8d,
0x14, 0xed, 0xe2, 0x4f, 0x64, 0xb2, 0xb1, 0x77, 0x39, 0x42, 0x7e, 0xd4, 0xab, 0xda, 0x72, 0x9b,
0x12, 0xdb, 0xc3, 0x65, 0x5d, 0x87, 0x25, 0xb3, 0x88, 0xaa, 0xbd, 0x46, 0xb5, 0x2f, 0x1a, 0x25,
0x65, 0x23, 0x77, 0x60, 0x41, 0x95, 0x8f, 0x44, 0x67, 0x69, 0x9d, 0x1b, 0xee, 0xbc, 0x84, 0xd5,
0x10, 0xee, 0x42, 0xfb, 0xc4, 0x0f, 0xbc, 0x61, 0xaf, 0x3f, 0x4c, 0xce, 0x7b, 0x03, 0x3e, 0x4c,
0x3c, 0x5a, 0xf1, 0x9a, 0x3b, 0x4f, 0xf8, 0xf6, 0x30, 0x39, 0xdf, 0x41, 0x94, 0x7d, 0x08, 0x8d,
0x13, 0xce, 0x7b, 0x34, 0x13, 0x9d, 0xba, 0xc5, 0x3d, 0x6a, 0x76, 0xdd, 0xfa, 0x89, 0x9a, 0xe7,
0x0f, 0xa1, 0x1d, 0x4e, 0x92, 0xd3, 0xd0, 0x0f, 0x4e, 0x7b, 0x28, 0xaf, 0x7a, 0xfe, 0x80, 0x28,
0xa0, 0xba, 0x55, 0x7e, 0x50, 0x72, 0xe7, 0x55, 0x1e, 0x4a, 0x8e, 0x27, 0x03, 0xf6, 0x2e, 0x00,
0xb5, 0x2f, 0x2a, 0x87, 0xb5, 0xd2, 0xdd, 0x39, 0xb7, 0x81, 0x88, 0xa8, 0xec, 0x53, 0xa8, 0xd3,
0x9c, 0x26, 0xc3, 0xf3, 0x4e, 0x93, 0x16, 0xfd, 0x3d, 0xd9, 0xb2, 0xb1, 0x1a, 0xeb, 0x3b, 0x3c,
0x4e, 0x9e, 0x0f, 0xcf, 0x71, 0x4f, 0xbd, 0x74, 0x67, 0x07, 0x22, 0xd5, 0xfd, 0x14, 0x5a, 0x66,
0x06, 0x4e, 0xff, 0x2b, 0x7e, 0x49, 0x4b, 0x56, 0x75, 0xf1, 0x27, 0x5b, 0x86, 0xda, 0xb9, 0x37,
0x9c, 0x70, 0x29, 0xdc, 0x44, 0xe2, 0xd3, 0xf2, 0x27, 0x25, 0xe7, 0x5f, 0x96, 0xa0, 0x25, 0x5a,
0x90, 0x9b, 0xf2, 0x6d, 0x98, 0x53, 0xd3, 0xca, 0xa3, 0x28, 0x8c, 0x24, 0x8f, 0xdb, 0x20, 0xbb,
0x07, 0x6d, 0x05, 0x8c, 0x23, 0xee, 0x8f, 0xbc, 0x53, 0x55, 0x77, 0x0e, 0x67, 0x1b, 0x69, 0x8d,
0x51, 0x38, 0x49, 0xb8, 0x14, 0xff, 0x2d, 0x39, 0x3e, 0x17, 0x31, 0xd7, 0x2e, 0x82, 0x3c, 0x5e,
0x40, 0x2f, 0x16, 0xe6, 0x7c, 0x59, 0x02, 0x86, 0x5d, 0x7f, 0x1e, 0x8a, 0x2a, 0xe4, 0x72, 0x67,
0x49, 0xad, 0xf4, 0xd6, 0xa4, 0x56, 0x9e, 0x46, 0x6a, 0x0e, 0xd4, 0x44, 0xcf, 0xab, 0x05, 0x3d,
0x17, 0x59, 0xdf, 0xad, 0xd6, 0x2b, 0xed, 0xaa, 0xf3, 0x5f, 0x2a, 0xb0, 0xbc, 0x2d, 0xf6, 0xae,
0xcd, 0x7e, 0x9f, 0x8f, 0x35, 0x11, 0xbe, 0x07, 0xcd, 0x20, 0x1c, 0xf0, 0xde, 0x78, 0x72, 0xac,
0xd6, 0xa6, 0xe5, 0x02, 0x42, 0x87, 0x84, 0x10, 0x7d, 0x9c, 0x79, 0x7e, 0x20, 0x3a, 0x2d, 0xe6,
0xb2, 0x41, 0x08, 0x75, 0xf9, 0x03, 0x58, 0x18, 0xf3, 0x60, 0x60, 0xd2, 0x9a, 0xd0, 0x2e, 0xe6,
0x24, 0x2c, 0xc9, 0xec, 0x3d, 0x68, 0x9e, 0x4c, 0x44, 0x39, 0x64, 0xc1, 0x2a, 0xd1, 0x00, 0x48,
0x68, 0x73, 0x94, 0xb0, 0x1b, 0x50, 0x1f, 0x4f, 0xe2, 0x33, 0xca, 0xad, 0x51, 0xee, 0x2c, 0xa6,
0x31, 0xeb, 0x5d, 0x80, 0xc1, 0x24, 0x4e, 0x24, 0x89, 0xce, 0x50, 0x66, 0x03, 0x11, 0x41, 0xa2,
0xdf, 0x84, 0xa5, 0x91, 0xf7, 0xba, 0x47, 0xb4, 0xd3, 0xf3, 0x83, 0xde, 0xc9, 0x90, 0xc4, 0xef,
0x2c, 0x95, 0x6b, 0x8f, 0xbc, 0xd7, 0xdf, 0xc7, 0x9c, 0x27, 0xc1, 0x23, 0xc2, 0x91, 0x3f, 0xd5,
0xbe, 0x1f, 0xf1, 0x98, 0x47, 0xe7, 0x9c, 0x58, 0xaa, 0xaa, 0x37, 0x77, 0x57, 0xa0, 0xd8, 0xa3,
0x11, 0x8e, 0x3b, 0x19, 0xf6, 0x05, 0xff, 0xb8, 0xb3, 0x23, 0x3f, 0xd8, 0x4b, 0x86, 0x7d, 0x76,
0x13, 0x00, 0x19, 0x72, 0xcc, 0xa3, 0xde, 0xab, 0x0b, 0x62, 0x9a, 0x2a, 0x31, 0xe0, 0x21, 0x8f,
0x3e, 0xbb, 0x60, 0xef, 0x40, 0xa3, 0x1f, 0x13, 0x47, 0x7b, 0x97, 0x9d, 0x26, 0x71, 0x54, 0xbd,
0x1f, 0x23, 0x2f, 0x7b, 0x97, 0xec, 0x43, 0x60, 0xd8, 0x5b, 0x8f, 0x56, 0x81, 0x0f, 0xa8, 0xfa,
0xb8, 0xd3, 0xa2, 0x52, 0xd8, 0xd9, 0x4d, 0x99, 0x81, 0xed, 0xc4, 0xec, 0x6b, 0x30, 0xa7, 0x3a,
0x7b, 0x32, 0xf4, 0x4e, 0xe3, 0xce, 0x1c, 0x15, 0x6c, 0x49, 0xf0, 0x11, 0x62, 0xce, 0x4b, 0xa1,
0x6d, 0x18, 0x6b, 0x2b, 0x79, 0x06, 0xf7, 0x3d, 0x42, 0x68, 0x5d, 0xeb, 0xae, 0x4c, 0x15, 0x2d,
0x5a, 0xb9, 0x60, 0xd1, 0x9c, 0x9f, 0x97, 0xa0, 0x25, 0x6b, 0xa6, 0x2d, 0x9a, 0x3d, 0x00, 0xa6,
0x56, 0x31, 0x79, 0xed, 0x0f, 0x7a, 0xc7, 0x97, 0x09, 0x8f, 0x05, 0xd1, 0xec, 0x5d, 0x73, 0x0b,
0xf2, 0x50, 0x18, 0x59, 0x68, 0x9c, 0x44, 0x82, 0x9e, 0xf7, 0xae, 0xb9, 0xb9, 0x1c, 0x64, 0x2f,
0x54, 0x02, 0x26, 0x49, 0xcf, 0x0f, 0x06, 0xfc, 0x35, 0x91, 0xd2, 0x9c, 0x6b, 0x61, 0x5b, 0xf3,
0xd0, 0x32, 0xbf, 0x73, 0x7e, 0x02, 0x75, 0xa5, 0x42, 0xd0, 0xf6, 0x99, 0xe9, 0x97, 0x6b, 0x20,
0xac, 0x0b, 0x75, 0xbb, 0x17, 0x6e, 0xfd, 0xab, 0xb4, 0xed, 0xfc, 0x39, 0x68, 0xef, 0x23, 0x11,
0x05, 0x48, 0xb4, 0x52, 0x2f, 0x5a, 0x81, 0x19, 0x83, 0x79, 0x1a, 0xae, 0x4c, 0xe1, 0x0e, 0x75,
0x16, 0xc6, 0x89, 0x6c, 0x87, 0x7e, 0x3b, 0xff, 0xae, 0x04, 0x6c, 0x37, 0x4e, 0xfc, 0x91, 0x97,
0xf0, 0x47, 0x5c, 0x8b, 0x86, 0x67, 0xd0, 0xc2, 0xda, 0x9e, 0x87, 0x9b, 0x42, 0x4b, 0x11, 0xbb,
0xeb, 0x37, 0x24, 0x3b, 0xe7, 0x3f, 0x58, 0x37, 0x4b, 0x0b, 0xa1, 0x6b, 0x55, 0x80, 0xdc, 0x96,
0x78, 0xd1, 0x29, 0x4f, 0x48, 0x85, 0x91, 0x0a, 0x30, 0x08, 0x68, 0x3b, 0x0c, 0x4e, 0xba, 0xbf,
0x0b, 0x8b, 0xb9, 0x3a, 0x4c, 0xf9, 0xdc, 0x28, 0x90, 0xcf, 0x15, 0x53, 0x3e, 0xf7, 0x61, 0xc9,
0xea, 0x97, 0xa4, 0xb8, 0x0e, 0xcc, 0x22, 0x63, 0xa0, 0x86, 0x48, 0xbb, 0xbc, 0xab, 0x92, 0x6c,
0x03, 0x96, 0x4f, 0x38, 0x8f, 0xbc, 0x84, 0x92, 0xc4, 0x3a, 0xb8, 0x26, 0xb2, 0xe6, 0xc2, 0x3c,
0xe7, 0xbf, 0x97, 0x60, 0x01, 0x25, 0xe9, 0x53, 0x2f, 0xb8, 0x54, 0x73, 0xb5, 0x5f, 0x38, 0x57,
0x77, 0x8d, 0x4d, 0xc9, 0x28, 0xfd, 0x55, 0x27, 0xaa, 0x92, 0x9d, 0x28, 0xb6, 0x06, 0x2d, 0xab,
0xbb, 0x35, 0xa1, 0x92, 0xc5, 0x5e, 0x72, 0xc8, 0xa3, 0xad, 0xcb, 0x84, 0xff, 0xfa, 0x53, 0xf9,
0x01, 0xb4, 0xd3, 0x6e, 0xcb, 0x79, 0x64, 0x50, 0x45, 0xc2, 0x94, 0x15, 0xd0, 0x6f, 0xe7, 0xef,
0x97, 0x44, 0xc1, 0xed, 0xd0, 0xd7, 0xea, 0x1a, 0x16, 0x44, 0xad, 0x4f, 0x15, 0xc4, 0xdf, 0x53,
0xd5, 0xdd, 0x5f, 0x7f, 0xb0, 0x28, 0x13, 0x63, 0x1e, 0x0c, 0x7a, 0xde, 0x70, 0x48, 0x82, 0xb8,
0xee, 0xce, 0x62, 0x7a, 0x73, 0x38, 0x74, 0xee, 0xc0, 0xa2, 0xd1, 0xbb, 0x37, 0x8c, 0xe3, 0x00,
0xd8, 0xbe, 0x1f, 0x27, 0x2f, 0x82, 0x78, 0x6c, 0x68, 0x43, 0xef, 0x40, 0x03, 0xa5, 0x2d, 0xf6,
0x4c, 0x70, 0x6e, 0xcd, 0x45, 0xf1, 0x8b, 0xfd, 0x8a, 0x29, 0xd3, 0x7b, 0x2d, 0x33, 0xcb, 0x32,
0xd3, 0x7b, 0x4d, 0x99, 0xce, 0x27, 0xb0, 0x64, 0xd5, 0x27, 0x9b, 0x7e, 0x1f, 0x6a, 0x93, 0xe4,
0x75, 0xa8, 0x74, 0xd5, 0xa6, 0xa4, 0x10, 0xb4, 0x8a, 0x5c, 0x91, 0xe3, 0x3c, 0x84, 0xc5, 0x03,
0x7e, 0x21, 0x19, 0x59, 0x75, 0xe4, 0x83, 0x2b, 0x2d, 0x26, 0xca, 0x77, 0xd6, 0x81, 0x99, 0x1f,
0xa7, 0x0c, 0xa0, 0xec, 0xa7, 0x92, 0x65, 0x3f, 0x39, 0x1f, 0x00, 0x3b, 0xf2, 0x4f, 0x83, 0xa7,
0x3c, 0x8e, 0xbd, 0x53, 0xcd, 0xfa, 0x6d, 0xa8, 0x8c, 0xe2, 0x53, 0x29, 0xaa, 0xf0, 0xa7, 0xf3,
0x2d, 0x58, 0xb2, 0xca, 0xc9, 0x8a, 0x6f, 0x42, 0x23, 0xf6, 0x4f, 0x03, 0x2f, 0x99, 0x44, 0x5c,
0x56, 0x9d, 0x02, 0xce, 0x23, 0x58, 0xfe, 0x3e, 0x8f, 0xfc, 0x93, 0xcb, 0xab, 0xaa, 0xb7, 0xeb,
0x29, 0x67, 0xeb, 0xd9, 0x85, 0xeb, 0x99, 0x7a, 0x64, 0xf3, 0x82, 0x7c, 0xe5, 0x4a, 0xd6, 0x5d,
0x91, 0x30, 0x64, 0x5f, 0xd9, 0x94, 0x7d, 0xce, 0x0b, 0x60, 0xdb, 0x61, 0x10, 0xf0, 0x7e, 0x72,
0xc8, 0x79, 0x94, 0xba, 0x6e, 0x52, 0x5a, 0x6d, 0x6e, 0xac, 0xca, 0x99, 0xcd, 0x0a, 0x54, 0x49,
0xc4, 0x0c, 0xaa, 0x63, 0x1e, 0x8d, 0xa8, 0xe2, 0xba, 0x4b, 0xbf, 0x9d, 0xeb, 0xb0, 0x64, 0x55,
0x2b, 0x8d, 0xdd, 0x8f, 0xe0, 0xfa, 0x8e, 0x1f, 0xf7, 0xf3, 0x0d, 0x76, 0x60, 0x76, 0x3c, 0x39,
0xee, 0xa5, 0x9c, 0xa8, 0x92, 0x68, 0xff, 0x64, 0x3f, 0x91, 0x95, 0xfd, 0xb5, 0x12, 0x54, 0xf7,
0x9e, 0xef, 0x6f, 0xe3, 0x5e, 0xe1, 0x07, 0xfd, 0x70, 0x84, 0x1a, 0x98, 0x18, 0xb4, 0x4e, 0x4f,
0xe5, 0xb0, 0x9b, 0xd0, 0x20, 0xc5, 0x0d, 0x4d, 0x3e, 0xa9, 0x07, 0xa5, 0x00, 0x9a, 0x9b, 0xfc,
0xf5, 0xd8, 0x8f, 0xc8, 0x9e, 0x54, 0x56, 0x62, 0x95, 0xb6, 0x99, 0x7c, 0x86, 0xf3, 0xf3, 0x59,
0x98, 0x95, 0x9b, 0xaf, 0xd8, 0xc8, 0x13, 0xff, 0x9c, 0xa7, 0x1b, 0x39, 0xa6, 0x50, 0x29, 0x8e,
0xf8, 0x28, 0x4c, 0xb4, 0xfe, 0x26, 0x96, 0xc1, 0x06, 0xc9, 0x9c, 0x96, 0x4a, 0x84, 0x30, 0xc0,
0x2b, 0xa2, 0x94, 0x05, 0xb2, 0x9b, 0x30, 0xab, 0x94, 0x81, 0xaa, 0xb6, 0x16, 0x14, 0x84, 0xb3,
0xd1, 0xf7, 0xc6, 0x5e, 0xdf, 0x4f, 0x2e, 0xa5, 0x58, 0xd0, 0x69, 0xac, 0x7f, 0x18, 0xf6, 0xbd,
0x61, 0xef, 0xd8, 0x1b, 0x7a, 0x41, 0x9f, 0x2b, 0x73, 0xdd, 0x02, 0xd1, 0x74, 0x95, 0xdd, 0x52,
0xc5, 0x84, 0x79, 0x9b, 0x41, 0x71, 0x0f, 0xef, 0x87, 0xa3, 0x91, 0x9f, 0xa0, 0xc5, 0x4b, 0xaa,
0x59, 0xc5, 0x35, 0x10, 0xe1, 0x1c, 0xa0, 0xd4, 0x85, 0x98, 0xc1, 0x86, 0x72, 0x0e, 0x18, 0x20,
0xd6, 0x92, 0xd1, 0xd0, 0x2a, 0xae, 0x81, 0xe0, 0x5a, 0x4c, 0x82, 0x98, 0x27, 0xc9, 0x90, 0x0f,
0x74, 0x87, 0x9a, 0x54, 0x2c, 0x9f, 0xc1, 0x1e, 0xc0, 0x92, 0x30, 0xc2, 0x63, 0x2f, 0x09, 0xe3,
0x33, 0x3f, 0xee, 0xc5, 0x68, 0xae, 0xb6, 0xa8, 0x7c, 0x51, 0x16, 0xfb, 0x04, 0x56, 0x33, 0x70,
0xc4, 0xfb, 0xdc, 0x3f, 0xe7, 0x03, 0x52, 0xe1, 0x2a, 0xee, 0xb4, 0x6c, 0xb6, 0x06, 0xcd, 0x60,
0x32, 0xea, 0x4d, 0xc6, 0x03, 0x0f, 0x95, 0x98, 0x79, 0x52, 0x2e, 0x4d, 0x88, 0x7d, 0x04, 0x4a,
0x4f, 0x93, 0xda, 0xe3, 0x82, 0x25, 0xe1, 0x90, 0x7a, 0x5d, 0xbb, 0x04, 0x12, 0x66, 0xaa, 0x92,
0xb6, 0xa5, 0x91, 0xa7, 0x00, 0xe2, 0x93, 0xc8, 0x3f, 0xf7, 0x12, 0xde, 0x59, 0x14, 0x42, 0x5d,
0x26, 0xf1, 0x3b, 0x3f, 0xf0, 0x13, 0xdf, 0x4b, 0xc2, 0xa8, 0xc3, 0x28, 0x2f, 0x05, 0x70, 0x12,
0x89, 0x3e, 0xe2, 0xc4, 0x4b, 0x26, 0xb1, 0xd4, 0x50, 0x97, 0x84, 0xb5, 0x92, 0xcb, 0x60, 0x1f,
0xc3, 0x8a, 0xa0, 0x08, 0xca, 0x92, 0xba, 0x37, 0xa9, 0x0a, 0xcb, 0x34, 0x23, 0x53, 0x72, 0x71,
0x2a, 0x25, 0x89, 0xe4, 0x3e, 0xbc, 0x2e, 0xa6, 0x72, 0x4a, 0x36, 0xf6, 0x0f, 0x7b, 0xe0, 0xf7,
0x7b, 0xb2, 0x04, 0xb2, 0xc8, 0x0a, 0x8d, 0x22, 0x9f, 0x81, 0x24, 0x3e, 0xf4, 0x4f, 0x78, 0xe2,
0x8f, 0x78, 0x67, 0x55, 0x90, 0xb8, 0x4a, 0x23, 0x03, 0x4e, 0xc6, 0x94, 0xd3, 0x11, 0x0c, 0x2f,
0x52, 0xce, 0x1f, 0x94, 0xc4, 0xe6, 0x23, 0x19, 0x35, 0x36, 0xcc, 0x2a, 0xc1, 0xa2, 0xbd, 0x30,
0x18, 0x5e, 0x4a, 0xae, 0x05, 0x01, 0x3d, 0x0b, 0x86, 0x97, 0xa8, 0xd8, 0xfb, 0x81, 0x59, 0x44,
0xc8, 0xb9, 0x96, 0x02, 0xa9, 0xd0, 0x7b, 0xd0, 0x1c, 0x4f, 0x8e, 0x87, 0x7e, 0x5f, 0x14, 0xa9,
0x88, 0x5a, 0x04, 0x44, 0x05, 0xd0, 0xa6, 0x14, 0x2b, 0x25, 0x4a, 0x54, 0xa9, 0x44, 0x53, 0x62,
0x58, 0xc4, 0xd9, 0x82, 0x65, 0xbb, 0x83, 0x52, 0xa0, 0xdf, 0x83, 0xba, 0xe4, 0xff, 0x58, 0x1a,
0xf6, 0xf3, 0x86, 0xdf, 0x13, 0xcd, 0x20, 0x9d, 0xef, 0xfc, 0xeb, 0x2a, 0x2c, 0x49, 0x74, 0x7b,
0x18, 0xc6, 0xfc, 0x68, 0x32, 0x1a, 0x79, 0x51, 0x81, 0x60, 0x29, 0x5d, 0x21, 0x58, 0xca, 0x79,
0xc1, 0x72, 0xcb, 0xb2, 0x2f, 0x85, 0x64, 0x32, 0x10, 0x76, 0x17, 0x16, 0xfa, 0xc3, 0x30, 0x16,
0xea, 0xbe, 0xe9, 0x7a, 0xcb, 0xc2, 0x79, 0x61, 0x58, 0x2b, 0x12, 0x86, 0xa6, 0x20, 0x9b, 0xc9,
0x08, 0x32, 0x07, 0x5a, 0x58, 0x29, 0x57, 0xb2, 0x79, 0x56, 0x1a, 0x5b, 0x06, 0x86, 0xfd, 0xc9,
0x8a, 0x0d, 0x21, 0xa3, 0x16, 0x8a, 0x84, 0x86, 0x3f, 0xe2, 0x24, 0xfb, 0x8d, 0xd2, 0x0d, 0x29,
0x34, 0xf2, 0x59, 0xec, 0x11, 0x80, 0x68, 0x8b, 0x14, 0x10, 0x20, 0x05, 0xe4, 0x03, 0x7b, 0x55,
0xcc, 0xf9, 0x5f, 0xc7, 0xc4, 0x24, 0xe2, 0xa4, 0x94, 0x18, 0x5f, 0x3a, 0x7f, 0xa3, 0x04, 0x4d,
0x23, 0x8f, 0x5d, 0x87, 0xc5, 0xed, 0x67, 0xcf, 0x0e, 0x77, 0xdd, 0xcd, 0xe7, 0x4f, 0xbe, 0xbf,
0xdb, 0xdb, 0xde, 0x7f, 0x76, 0xb4, 0xdb, 0xbe, 0x86, 0xf0, 0xfe, 0xb3, 0xed, 0xcd, 0xfd, 0xde,
0xa3, 0x67, 0xee, 0xb6, 0x82, 0x4b, 0x6c, 0x05, 0x98, 0xbb, 0xfb, 0xf4, 0xd9, 0xf3, 0x5d, 0x0b,
0x2f, 0xb3, 0x36, 0xb4, 0xb6, 0xdc, 0xdd, 0xcd, 0xed, 0x3d, 0x89, 0x54, 0xd8, 0x32, 0xb4, 0x1f,
0xbd, 0x38, 0xd8, 0x79, 0x72, 0xf0, 0xb8, 0xb7, 0xbd, 0x79, 0xb0, 0xbd, 0xbb, 0xbf, 0xbb, 0xd3,
0xae, 0xb2, 0x39, 0x68, 0x6c, 0x6e, 0x6d, 0x1e, 0xec, 0x3c, 0x3b, 0xd8, 0xdd, 0x69, 0xd7, 0x9c,
0xff, 0x5a, 0x82, 0xeb, 0xd4, 0xeb, 0x41, 0x96, 0x49, 0xd6, 0xa0, 0xd9, 0x0f, 0xc3, 0x31, 0x2a,
0xfe, 0xe9, 0xd6, 0x66, 0x42, 0xc8, 0x00, 0x42, 0x28, 0x9c, 0x84, 0x51, 0x9f, 0x4b, 0x1e, 0x01,
0x82, 0x1e, 0x21, 0x82, 0x0c, 0x20, 0x97, 0x57, 0x94, 0x10, 0x2c, 0xd2, 0x14, 0x98, 0x28, 0xb2,
0x02, 0x33, 0xc7, 0x11, 0xf7, 0xfa, 0x67, 0x92, 0x3b, 0x64, 0x8a, 0x7d, 0x3d, 0xb5, 0x4c, 0xfb,
0x38, 0xfb, 0x43, 0x3e, 0x20, 0x8a, 0xa9, 0xbb, 0x0b, 0x12, 0xdf, 0x96, 0x30, 0x4a, 0x41, 0xef,
0xd8, 0x0b, 0x06, 0x61, 0xc0, 0x07, 0x52, 0xed, 0x4d, 0x01, 0xe7, 0x10, 0x56, 0xb2, 0xe3, 0x93,
0x3c, 0xf6, 0xb1, 0xc1, 0x63, 0x42, 0x0b, 0xed, 0x4e, 0x5f, 0x4d, 0x83, 0xdf, 0x7e, 0x51, 0x86,
0x2a, 0x2a, 0x25, 0xd3, 0x15, 0x18, 0x53, 0xcf, 0xac, 0xe4, 0xfc, 0xf4, 0x64, 0xec, 0x8a, 0x2d,
0x4a, 0x3a, 0x5a, 0x52, 0x24, 0xcd, 0x8f, 0x78, 0xff, 0x5c, 0xba, 0x5a, 0x0c, 0x04, 0x19, 0x04,
0x8d, 0x00, 0xfa, 0x5a, 0x32, 0x88, 0x4a, 0xab, 0x3c, 0xfa, 0x72, 0x36, 0xcd, 0xa3, 0xef, 0x3a,
0x30, 0xeb, 0x07, 0xc7, 0xe1, 0x24, 0x18, 0x10, 0x43, 0xd4, 0x5d, 0x95, 0xa4, 0x93, 0x01, 0x62,
0x54, 0x94, 0x9f, 0x82, 0xfc, 0x53, 0x80, 0x6d, 0x40, 0x23, 0xbe, 0x0c, 0xfa, 0x26, 0xcd, 0x2f,
0xcb, 0x59, 0xc2, 0x39, 0x58, 0x3f, 0xba, 0x0c, 0xfa, 0x44, 0xe1, 0x69, 0x31, 0xe7, 0x77, 0xa1,
0xae, 0x60, 0x24, 0xcb, 0x17, 0x07, 0x9f, 0x1d, 0x3c, 0x7b, 0x79, 0xd0, 0x3b, 0xfa, 0xc1, 0xc1,
0x76, 0xfb, 0x1a, 0x5b, 0x80, 0xe6, 0xe6, 0x36, 0x51, 0x3a, 0x01, 0x25, 0x2c, 0x72, 0xb8, 0x79,
0x74, 0xa4, 0x91, 0xb2, 0xc3, 0xd0, 0x90, 0x8f, 0x49, 0xf3, 0xd3, 0x9e, 0xef, 0x8f, 0x61, 0xd1,
0xc0, 0x52, 0x2b, 0x62, 0x8c, 0x40, 0xc6, 0x8a, 0x20, 0x95, 0x51, 0xe4, 0x38, 0x6d, 0x98, 0x7f,
0xcc, 0x93, 0x27, 0xc1, 0x49, 0xa8, 0x6a, 0xfa, 0x9f, 0x55, 0x58, 0xd0, 0x90, 0xac, 0xe8, 0x2e,
0x2c, 0xf8, 0x03, 0x1e, 0x24, 0x7e, 0x72, 0xd9, 0xb3, 0xfc, 0x05, 0x59, 0x18, 0x55, 0x6d, 0x6f,
0xe8, 0x7b, 0xea, 0x00, 0x46, 0x24, 0xd0, 0x7e, 0x46, 0x1d, 0xc0, 0xf4, 0xdb, 0x10, 0x5d, 0x09,
0x37, 0x45, 0x61, 0x1e, 0x4a, 0x20, 0xc4, 0xe5, 0x36, 0xa3, 0x3f, 0x11, 0x2a, 0x67, 0x51, 0x16,
0x2e, 0x95, 0xa8, 0x09, 0x87, 0x5c, 0x13, 0x7a, 0x82, 0x06, 0x72, 0x27, 0x1c, 0x33, 0x42, 0x3e,
0x66, 0x4f, 0x38, 0x8c, 0x53, 0x92, 0x7a, 0xee, 0x94, 0x04, 0xe5, 0xe7, 0x65, 0xd0, 0xe7, 0x83,
0x5e, 0x12, 0xf6, 0x48, 0xce, 0x13, 0x49, 0xd4, 0xdd, 0x2c, 0x8c, 0xfb, 0x46, 0xc2, 0xe3, 0x24,
0xe0, 0xc2, 0x2d, 0x5d, 0xdf, 0x2a, 0x77, 0x4a, 0xae, 0x82, 0xd0, 0x3e, 0x98, 0x44, 0x7e, 0xdc,
0x69, 0xd1, 0xf9, 0x07, 0xfd, 0x66, 0xdf, 0x86, 0xeb, 0xc7, 0x3c, 0x4e, 0x7a, 0x67, 0xdc, 0x1b,
0xf0, 0x88, 0xc8, 0x4b, 0x1c, 0xb4, 0x08, 0x95, 0xab, 0x38, 0x13, 0x09, 0xf7, 0x9c, 0x47, 0xb1,
0x1f, 0x06, 0xa4, 0x6c, 0x35, 0x5c, 0x95, 0xc4, 0xfa, 0x70, 0xf0, 0x7a, 0xa3, 0xd6, 0x33, 0xb8,
0x40, 0x03, 0x2f, 0xce, 0x64, 0xb7, 0x61, 0x86, 0x06, 0x10, 0x77, 0xda, 0x44, 0x33, 0xad, 0x94,
0xe7, 0xfd, 0xc0, 0x95, 0x79, 0xb8, 0xca, 0xfd, 0x70, 0x18, 0x46, 0xa4, 0x71, 0x35, 0x5c, 0x91,
0xb0, 0x67, 0xe7, 0x34, 0xf2, 0xc6, 0x67, 0x52, 0xeb, 0xca, 0xc2, 0xdf, 0xad, 0xd6, 0x9b, 0xed,
0x96, 0xf3, 0x67, 0xa0, 0x46, 0xd5, 0x52, 0x75, 0x34, 0x99, 0x25, 0x59, 0x1d, 0xa1, 0x1d, 0x98,
0x0d, 0x78, 0x72, 0x11, 0x46, 0xaf, 0xd4, 0x69, 0x9e, 0x4c, 0x3a, 0x3f, 0x23, 0x0b, 0x4d, 0x9f,
0x6e, 0xbd, 0x20, 0xd5, 0x12, 0xed, 0x6c, 0xb1, 0x54, 0xf1, 0x99, 0x27, 0x8d, 0xc6, 0x3a, 0x01,
0x47, 0x67, 0x1e, 0xca, 0x5a, 0x6b, 0xf5, 0x85, 0x1d, 0xde, 0x24, 0x6c, 0x4f, 0x2c, 0xfe, 0x6d,
0x98, 0x57, 0xe7, 0x66, 0x71, 0x6f, 0xc8, 0x4f, 0x12, 0xe5, 0x45, 0x0b, 0x26, 0x23, 0x32, 0xd6,
0xf7, 0xf9, 0x49, 0xe2, 0x1c, 0xc0, 0xa2, 0x94, 0x7f, 0xcf, 0xc6, 0x5c, 0x35, 0xfd, 0xdb, 0x45,
0xba, 0x44, 0x73, 0x63, 0xc9, 0x16, 0x98, 0xe2, 0xa4, 0xd0, 0x2e, 0xe9, 0xb8, 0xc0, 0x4c, 0x79,
0x2a, 0x2b, 0x94, 0x9b, 0xb9, 0xf2, 0x13, 0xca, 0xe1, 0x58, 0x18, 0xce, 0x4f, 0x3c, 0xe9, 0xf7,
0xd5, 0x69, 0x67, 0xdd, 0x55, 0x49, 0xe7, 0x8f, 0x4a, 0xb0, 0x44, 0xb5, 0x29, 0x6d, 0x48, 0xee,
0x59, 0x9f, 0x7c, 0x85, 0x6e, 0x2a, 0x2f, 0xad, 0xf0, 0x4d, 0x2e, 0x43, 0xcd, 0xdc, 0xc5, 0x44,
0xe2, 0xab, 0xfb, 0x64, 0xaa, 0x59, 0x9f, 0x8c, 0xf3, 0x77, 0x4a, 0xb0, 0x28, 0x36, 0x12, 0xd2,
0xb6, 0xe5, 0xf0, 0xff, 0x2c, 0xcc, 0x09, 0x8d, 0x40, 0x4a, 0x05, 0xd9, 0xd1, 0x54, 0xb4, 0x12,
0x2a, 0x0a, 0xef, 0x5d, 0x73, 0xed, 0xc2, 0xec, 0x21, 0x69, 0x65, 0x41, 0x8f, 0xd0, 0x82, 0x73,
0x71, 0x7b, 0xae, 0xf7, 0xae, 0xb9, 0x46, 0xf1, 0xad, 0x3a, 0x2a, 0xcb, 0x88, 0x3b, 0x8f, 0x61,
0xce, 0x6a, 0xc8, 0xf2, 0x07, 0xb5, 0x84, 0x3f, 0x28, 0xe7, 0x78, 0x2d, 0x17, 0x38, 0x5e, 0xff,
0x79, 0x05, 0x18, 0x12, 0x4b, 0x66, 0x35, 0xd6, 0xec, 0xd3, 0x0b, 0x75, 0x44, 0x9e, 0x42, 0x6c,
0x1d, 0x98, 0x91, 0x54, 0x27, 0x2a, 0x62, 0xcb, 0x2c, 0xc8, 0x41, 0x31, 0x2b, 0x35, 0x0e, 0x7d,
0x5a, 0x41, 0x76, 0xbe, 0x98, 0xf6, 0xc2, 0x3c, 0xdc, 0x15, 0xe9, 0xe8, 0x02, 0x2d, 0x12, 0x69,
0x1b, 0xab, 0x74, 0x76, 0x7d, 0x67, 0xae, 0x5c, 0xdf, 0xd9, 0x9c, 0xcf, 0xcd, 0xb0, 0xce, 0xea,
0xb6, 0x75, 0x76, 0x1b, 0xe6, 0xd4, 0x09, 0x45, 0x6f, 0x84, 0xad, 0x4b, 0x53, 0xd8, 0x02, 0xd9,
0x3d, 0x68, 0x2b, 0x03, 0x49, 0x9b, 0x80, 0xe2, 0x9c, 0x2f, 0x87, 0xa3, 0xfc, 0x4f, 0xbd, 0x70,
0x4d, 0xea, 0x6c, 0x0a, 0x90, 0x3d, 0x85, 0x14, 0xd2, 0x9b, 0x04, 0xf2, 0x68, 0x9c, 0x0f, 0xc8,
0x08, 0x46, 0x7b, 0x2a, 0x9b, 0xe1, 0xfc, 0xad, 0x12, 0xb4, 0x71, 0xcd, 0x2c, 0xb2, 0xfc, 0x14,
0x88, 0x2b, 0xde, 0x92, 0x2a, 0xad, 0xb2, 0xec, 0x13, 0x68, 0x50, 0x3a, 0x1c, 0xf3, 0x40, 0xd2,
0x64, 0xc7, 0xa6, 0xc9, 0x54, 0x9e, 0xec, 0x5d, 0x73, 0xd3, 0xc2, 0x06, 0x45, 0xfe, 0xc7, 0x12,
0x34, 0x65, 0x2b, 0xbf, 0xb2, 0x97, 0xa7, 0x6b, 0xc4, 0x32, 0x08, 0x4a, 0x4a, 0x43, 0x17, 0xee,
0xc2, 0xc2, 0xc8, 0x4b, 0x26, 0x11, 0xee, 0xe7, 0x96, 0x87, 0x27, 0x0b, 0xe3, 0xe6, 0x4c, 0xa2,
0x33, 0xee, 0x25, 0xfe, 0xb0, 0xa7, 0x72, 0x65, 0xd4, 0x40, 0x51, 0x16, 0x4a, 0x90, 0x38, 0xf1,
0x4e, 0xb9, 0xdc, 0x77, 0x45, 0xc2, 0xe9, 0xc0, 0xca, 0x61, 0x7a, 0x6a, 0x63, 0xe8, 0xd7, 0xce,
0x3f, 0x9d, 0x83, 0xd5, 0x5c, 0x96, 0x8e, 0x71, 0x92, 0x6e, 0x8b, 0xa1, 0x3f, 0x3a, 0x0e, 0xb5,
0x71, 0x52, 0x32, 0x3d, 0x1a, 0x56, 0x16, 0x3b, 0x85, 0xeb, 0x4a, 0xc1, 0xc0, 0x39, 0x4d, 0x37,
0xc3, 0x32, 0xed, 0x72, 0x1f, 0xd9, 0x4b, 0x98, 0x6d, 0x50, 0xe1, 0x26, 0x13, 0x17, 0xd7, 0xc7,
0xce, 0xa0, 0xa3, 0x35, 0x19, 0x29, 0xac, 0x0d, 0x6d, 0x07, 0xdb, 0xfa, 0xf0, 0x8a, 0xb6, 0x2c,
0x75, 0xdc, 0x9d, 0x5a, 0x1b, 0xbb, 0x84, 0x5b, 0x2a, 0x8f, 0xa4, 0x71, 0xbe, 0xbd, 0xea, 0x5b,
0x8d, 0x8d, 0x0c, 0x0d, 0xbb, 0xd1, 0x2b, 0x2a, 0x66, 0x3f, 0x81, 0x95, 0x0b, 0xcf, 0x4f, 0x54,
0xb7, 0x0c, 0xdd, 0xa2, 0x46, 0x4d, 0x6e, 0x5c, 0xd1, 0xe4, 0x4b, 0xf1, 0xb1, 0xb5, 0x45, 0x4d,
0xa9, 0xb1, 0xfb, 0x27, 0x65, 0x98, 0xb7, 0xeb, 0x41, 0x32, 0x95, 0xbc, 0xaf, 0x64, 0xa0, 0xd2,
0x46, 0x33, 0x70, 0xde, 0xc6, 0x2f, 0x17, 0xd9, 0xf8, 0xa6, 0x55, 0x5d, 0xb9, 0xca, 0x3d, 0x58,
0x7d, 0x3b, 0xf7, 0x60, 0xad, 0xd0, 0x3d, 0x38, 0xdd, 0x8b, 0x34, 0xf3, 0xab, 0x7a, 0x91, 0x66,
0xdf, 0xe8, 0x45, 0xea, 0xfe, 0xdf, 0x12, 0xb0, 0x3c, 0xf5, 0xb2, 0xc7, 0xc2, 0xad, 0x11, 0xf0,
0xa1, 0x14, 0x62, 0xdf, 0x7c, 0x3b, 0x0e, 0x50, 0xab, 0xa5, 0xbe, 0x46, 0x56, 0x34, 0x03, 0x8d,
0x4c, 0xf5, 0x6a, 0xce, 0x2d, 0xca, 0xca, 0xb8, 0x48, 0xab, 0x57, 0xbb, 0x48, 0x6b, 0x57, 0xbb,
0x48, 0x67, 0xb2, 0x2e, 0xd2, 0xee, 0x5f, 0x2d, 0xc1, 0x52, 0x01, 0x99, 0xfd, 0xe6, 0x06, 0x8e,
0x84, 0x61, 0x49, 0x9f, 0xb2, 0x24, 0x0c, 0x13, 0xec, 0xfe, 0x45, 0x98, 0xb3, 0x58, 0xeb, 0x37,
0xd7, 0x7e, 0x56, 0x43, 0x14, 0x94, 0x6d, 0x61, 0xdd, 0xff, 0x55, 0x06, 0x96, 0x67, 0xef, 0x3f,
0xd5, 0x3e, 0xe4, 0xe7, 0xa9, 0x52, 0x30, 0x4f, 0xff, 0x5f, 0x77, 0x9e, 0x0f, 0x61, 0x51, 0x46,
0x4f, 0x1a, 0x8e, 0x2c, 0x41, 0x31, 0xf9, 0x0c, 0xd4, 0x91, 0x6d, 0xff, 0x74, 0xdd, 0x8a, 0x16,
0x33, 0xb6, 0xdf, 0x8c, 0x9b, 0xda, 0xe9, 0x42, 0x47, 0xce, 0xd0, 0xee, 0x39, 0x0f, 0x92, 0xa3,
0xc9, 0xb1, 0x08, 0x1f, 0xf4, 0xc3, 0xc0, 0xf9, 0x17, 0x15, 0xad, 0xe6, 0x53, 0xa6, 0x54, 0x28,
0xbe, 0x0d, 0x2d, 0x73, 0xfb, 0x90, 0xcb, 0x91, 0xf1, 0x65, 0xa2, 0x2a, 0x61, 0x96, 0x62, 0x3b,
0x30, 0x4f, 0x42, 0x72, 0xa0, 0xbf, 0x2b, 0xd3, 0x77, 0x6f, 0xf0, 0xcf, 0xec, 0x5d, 0x73, 0x33,
0xdf, 0xb0, 0xdf, 0x81, 0x79, 0xdb, 0xf8, 0x93, 0x5a, 0x49, 0x91, 0x35, 0x80, 0x9f, 0xdb, 0x85,
0xd9, 0x26, 0xb4, 0xb3, 0xd6, 0xa3, 0x8c, 0xe4, 0x99, 0x52, 0x41, 0xae, 0x38, 0xfb, 0x44, 0x1e,
0x56, 0xd6, 0xc8, 0x6f, 0x72, 0xdb, 0xfe, 0xcc, 0x98, 0xa6, 0x75, 0xf1, 0xc7, 0x38, 0xbe, 0xfc,
0x3d, 0x80, 0x14, 0x63, 0x6d, 0x68, 0x3d, 0x3b, 0xdc, 0x3d, 0xe8, 0x6d, 0xef, 0x6d, 0x1e, 0x1c,
0xec, 0xee, 0xb7, 0xaf, 0x31, 0x06, 0xf3, 0xe4, 0xe6, 0xdb, 0xd1, 0x58, 0x09, 0x31, 0xe9, 0x58,
0x51, 0x58, 0x99, 0x2d, 0x43, 0xfb, 0xc9, 0x41, 0x06, 0xad, 0x6c, 0x35, 0x34, 0x7f, 0x38, 0x2b,
0xb0, 0x2c, 0xa2, 0x63, 0xb7, 0x04, 0x79, 0x28, 0xed, 0xe4, 0x1f, 0x94, 0xe0, 0x7a, 0x26, 0x23,
0x0d, 0xf5, 0x12, 0x0a, 0x88, 0xad, 0x95, 0xd8, 0x20, 0x1d, 0x3e, 0x28, 0x5d, 0x33, 0x23, 0x41,
0xf2, 0x19, 0x48, 0xf3, 0x86, 0x6e, 0x9a, 0xe1, 0xa4, 0xa2, 0x2c, 0x67, 0x55, 0x47, 0xd5, 0x64,
0x3a, 0x7e, 0x22, 0xa2, 0x6e, 0xcd, 0x8c, 0xf4, 0xf0, 0xd7, 0xee, 0xb2, 0x4a, 0xa2, 0x59, 0x61,
0x29, 0x3b, 0x76, 0x7f, 0x0b, 0xf3, 0x9c, 0x7f, 0x5c, 0x01, 0xf6, 0xbd, 0x09, 0x8f, 0x2e, 0x29,
0x9e, 0x4b, 0x7b, 0x4d, 0x57, 0xb3, 0x3e, 0xc1, 0x99, 0xf1, 0xe4, 0xf8, 0x33, 0x7e, 0xa9, 0xa2,
0x1b, 0xcb, 0x69, 0x74, 0x63, 0x51, 0x84, 0x61, 0xf5, 0xea, 0x08, 0xc3, 0xda, 0x55, 0x11, 0x86,
0x5f, 0x83, 0x39, 0xff, 0x34, 0x08, 0x91, 0xe7, 0x51, 0x4f, 0x88, 0x3b, 0x33, 0x6b, 0x15, 0xb4,
0xad, 0x25, 0x78, 0x80, 0x18, 0x7b, 0x98, 0x16, 0xe2, 0x83, 0x53, 0x8a, 0x66, 0x35, 0xa5, 0xc0,
0xee, 0xe0, 0x94, 0xef, 0x87, 0x7d, 0x2f, 0x09, 0x23, 0x72, 0xec, 0xa8, 0x8f, 0x11, 0x8f, 0xd9,
0x6d, 0x98, 0x8f, 0xc3, 0x09, 0x6a, 0x4e, 0x6a, 0xac, 0xc2, 0x93, 0xd4, 0x12, 0xe8, 0xa1, 0x18,
0xf1, 0x3a, 0x2c, 0x4d, 0x62, 0xde, 0x1b, 0xf9, 0x71, 0x8c, 0xbb, 0x63, 0x3f, 0x0c, 0x92, 0x28,
0x1c, 0x4a, 0x7f, 0xd2, 0xe2, 0x24, 0xe6, 0x4f, 0x45, 0xce, 0xb6, 0xc8, 0x60, 0xdf, 0x4e, 0xbb,
0x34, 0xf6, 0xfc, 0x28, 0xee, 0x00, 0x75, 0x49, 0x8d, 0x14, 0xfb, 0x7d, 0xe8, 0xf9, 0x91, 0xee,
0x0b, 0x26, 0xe2, 0x4c, 0x84, 0x64, 0x33, 0x13, 0x21, 0x29, 0x03, 0xec, 0xd6, 0xa1, 0xae, 0x3e,
0x47, 0x23, 0xf7, 0x24, 0x0a, 0x47, 0xca, 0xc8, 0xc5, 0xdf, 0x6c, 0x1e, 0xca, 0x49, 0x28, 0x0d,
0xd4, 0x72, 0x12, 0x3a, 0xbf, 0x0f, 0x4d, 0x63, 0x06, 0xd8, 0xfb, 0xc2, 0xde, 0x46, 0x85, 0x4a,
0x5a, 0xc7, 0xe2, 0x98, 0xa4, 0x21, 0xd1, 0x27, 0x03, 0xf6, 0x0d, 0x58, 0x1c, 0xf8, 0x11, 0xa7,
0xc0, 0xda, 0x5e, 0xc4, 0xcf, 0x79, 0x14, 0x2b, 0x5f, 0x42, 0x5b, 0x67, 0xb8, 0x02, 0x77, 0x7a,
0xb0, 0x64, 0x91, 0x8e, 0xe6, 0xac, 0x19, 0x8a, 0x0a, 0x54, 0xee, 0x4c, 0x3b, 0x62, 0x50, 0xe6,
0xe1, 0x9e, 0x24, 0xdd, 0x20, 0xbd, 0x71, 0x14, 0x1e, 0x53, 0x23, 0x25, 0xd7, 0xc2, 0x9c, 0x5f,
0x94, 0xa1, 0xb2, 0x17, 0x8e, 0xcd, 0xc3, 0x9d, 0x52, 0xfe, 0x70, 0x47, 0x2a, 0x8f, 0x3d, 0xad,
0x1b, 0xca, 0x1d, 0xde, 0x02, 0xd9, 0x3d, 0x98, 0xf7, 0x46, 0x49, 0x2f, 0x09, 0x51, 0x59, 0xbe,
0xf0, 0x22, 0x11, 0x42, 0x58, 0x21, 0xb2, 0xc8, 0xe4, 0xb0, 0x65, 0xa8, 0x68, 0x9d, 0x87, 0x0a,
0x60, 0x12, 0x2d, 0x35, 0x3a, 0x40, 0xbf, 0x94, 0x3e, 0x4b, 0x99, 0x42, 0xae, 0xb7, 0xbf, 0x17,
0x66, 0xb2, 0xd8, 0xb9, 0x8a, 0xb2, 0x50, 0x91, 0x45, 0x46, 0x18, 0xa5, 0x7a, 0xa1, 0x4e, 0x9b,
0xde, 0xf8, 0xba, 0xed, 0x8d, 0x5f, 0x83, 0x66, 0x32, 0x3c, 0xef, 0x8d, 0xbd, 0xcb, 0x61, 0xe8,
0x0d, 0x24, 0x01, 0x9a, 0x10, 0x7b, 0x00, 0x30, 0x1a, 0x8f, 0x7b, 0xb8, 0x59, 0x46, 0x03, 0x32,
0xbf, 0x9b, 0x1b, 0x6d, 0x39, 0xfb, 0x4f, 0x0f, 0x0f, 0x5d, 0xc2, 0x5d, 0xa3, 0x8c, 0xf3, 0x12,
0x1a, 0x3a, 0xc3, 0x8c, 0x3b, 0xa5, 0x10, 0x8a, 0xa6, 0x1d, 0x77, 0x4a, 0x11, 0x13, 0x1f, 0xc0,
0xbc, 0x90, 0x90, 0x38, 0x2e, 0x1a, 0x80, 0x38, 0xf6, 0xce, 0xa0, 0xce, 0x2f, 0x4b, 0x50, 0xa3,
0x05, 0x47, 0x95, 0x41, 0xe4, 0xe9, 0xc3, 0x28, 0x5a, 0xc4, 0x39, 0x37, 0x0b, 0x33, 0xc7, 0x8a,
0x4b, 0x2f, 0xeb, 0xd9, 0x37, 0x63, 0xd3, 0xd7, 0xa0, 0xa1, 0x5b, 0x32, 0x56, 0x30, 0x05, 0xd9,
0x2d, 0xa8, 0x9e, 0x85, 0x63, 0x65, 0x55, 0x81, 0x3a, 0xaf, 0x0e, 0xc7, 0x2e, 0xe1, 0x69, 0x7f,
0xb0, 0x3e, 0x31, 0x04, 0xa1, 0xb9, 0x66, 0xe1, 0x82, 0xb1, 0xce, 0x14, 0x8e, 0xf5, 0x05, 0x2c,
0x20, 0x5b, 0x1a, 0xce, 0xf9, 0xe9, 0xf2, 0xf3, 0xeb, 0xb8, 0x1d, 0xf7, 0x87, 0x93, 0x01, 0x37,
0x6d, 0x5b, 0x72, 0xbe, 0x4a, 0x5c, 0x69, 0x75, 0xce, 0x3f, 0x2b, 0x09, 0x76, 0xc7, 0x7a, 0xd9,
0x5d, 0xa8, 0xa2, 0x14, 0xcc, 0xb8, 0x32, 0x74, 0x58, 0x0b, 0x96, 0x73, 0xa9, 0x04, 0xae, 0x22,
0xb9, 0x47, 0xcd, 0xda, 0x85, 0x73, 0x34, 0x35, 0x0c, 0xf5, 0xc8, 0x32, 0xf6, 0x54, 0x06, 0x65,
0xeb, 0xc6, 0xd9, 0x52, 0xd5, 0x92, 0xac, 0x6a, 0xf7, 0x1f, 0x9c, 0x72, 0xe3, 0x4c, 0xe9, 0x8f,
0x4b, 0x30, 0x67, 0xf5, 0x09, 0x89, 0x76, 0xe8, 0xc5, 0x89, 0x0c, 0x2b, 0x90, 0x2b, 0x6f, 0x42,
0x26, 0xc1, 0x97, 0x6d, 0x82, 0xd7, 0x67, 0x14, 0x15, 0xf3, 0x8c, 0xe2, 0x01, 0x34, 0xd2, 0x8b,
0x09, 0x76, 0xa7, 0xb0, 0x45, 0x15, 0xe0, 0x93, 0x16, 0x4a, 0xbd, 0xe0, 0x35, 0xc3, 0x0b, 0xee,
0x3c, 0x84, 0xa6, 0x51, 0xde, 0xf4, 0x62, 0x97, 0x2c, 0x2f, 0xb6, 0x8e, 0x7e, 0x2b, 0xa7, 0xd1,
0x6f, 0xce, 0x97, 0x65, 0x98, 0x43, 0xf2, 0xf6, 0x83, 0xd3, 0xc3, 0x70, 0xe8, 0xf7, 0x2f, 0x89,
0xac, 0x14, 0x25, 0xcb, 0x5d, 0x50, 0x91, 0xb9, 0x0d, 0x23, 0xf7, 0xeb, 0x90, 0x5f, 0x21, 0xaa,
0x74, 0x1a, 0x65, 0x19, 0x4a, 0x82, 0x63, 0x2f, 0x96, 0xe2, 0x41, 0x6a, 0xe1, 0x16, 0x88, 0x12,
0x07, 0x01, 0x8a, 0x65, 0x1c, 0xf9, 0xc3, 0xa1, 0x2f, 0xca, 0x0a, 0x1b, 0xad, 0x28, 0x0b, 0xdb,
0x1c, 0xf8, 0xb1, 0x77, 0x9c, 0x9e, 0x3f, 0xea, 0x34, 0x39, 0xf8, 0xbc, 0xd7, 0x86, 0x83, 0x4f,
0x04, 0x3f, 0xdb, 0x60, 0x76, 0x21, 0x67, 0x73, 0x0b, 0xe9, 0xfc, 0xdb, 0x32, 0x34, 0x0d, 0xb2,
0x40, 0x76, 0x2e, 0xdc, 0x6e, 0x0c, 0x54, 0x1e, 0xcc, 0x07, 0x96, 0xd5, 0x6f, 0x20, 0xec, 0xb6,
0xdd, 0x2a, 0x39, 0xfa, 0x89, 0xe1, 0x2d, 0x12, 0xba, 0x09, 0x0d, 0x24, 0xfd, 0x8f, 0xc8, 0xc5,
0x20, 0x6f, 0x05, 0x69, 0x40, 0xe5, 0x6e, 0x50, 0x6e, 0x2d, 0xcd, 0x25, 0xe0, 0x8d, 0x47, 0xf5,
0x9f, 0x40, 0x4b, 0x56, 0x43, 0x6b, 0x4c, 0x83, 0x4e, 0x99, 0xcf, 0x5a, 0x7f, 0xd7, 0x2a, 0xa9,
0xbe, 0xdc, 0x50, 0x5f, 0xd6, 0xaf, 0xfa, 0x52, 0x95, 0x74, 0x1e, 0xeb, 0x28, 0x88, 0xc7, 0x91,
0x37, 0x3e, 0x53, 0x02, 0xe5, 0x01, 0x2c, 0x29, 0xb9, 0x31, 0x09, 0xbc, 0x20, 0x08, 0x27, 0x41,
0x9f, 0xab, 0x40, 0xb9, 0xa2, 0x2c, 0x67, 0xa0, 0xc3, 0xaa, 0xa9, 0x22, 0x76, 0x0f, 0x6a, 0x42,
0x8f, 0x12, 0xbb, 0x72, 0xb1, 0x08, 0x11, 0x45, 0xd8, 0x5d, 0xa8, 0x09, 0x75, 0xaa, 0x3c, 0x95,
0xe9, 0x45, 0x01, 0x67, 0x1d, 0x16, 0x28, 0x8e, 0xdb, 0x90, 0x7d, 0xef, 0x14, 0xed, 0xd6, 0x33,
0x7d, 0x11, 0xed, 0xbd, 0x0c, 0xec, 0x40, 0xf0, 0x95, 0x79, 0x96, 0xf9, 0xcb, 0x0a, 0x34, 0x0d,
0x18, 0xe5, 0x13, 0x1d, 0x40, 0xf5, 0x06, 0xbe, 0x37, 0xe2, 0x09, 0x8f, 0x24, 0x2f, 0x65, 0x50,
0x2c, 0xe7, 0x9d, 0x9f, 0xf6, 0xc2, 0x49, 0xd2, 0x1b, 0xf0, 0xd3, 0x88, 0x73, 0xa9, 0x46, 0x64,
0x50, 0x2c, 0x87, 0xd4, 0x6c, 0x94, 0x13, 0x47, 0x46, 0x19, 0x54, 0x9d, 0x4c, 0x8a, 0x79, 0xaa,
0xa6, 0x27, 0x93, 0x62, 0x56, 0xb2, 0x92, 0xb5, 0x56, 0x20, 0x59, 0x3f, 0x86, 0x15, 0x21, 0x43,
0xa5, 0xf4, 0xe8, 0x65, 0x88, 0x6b, 0x4a, 0x2e, 0xbb, 0x07, 0x6d, 0xec, 0xb3, 0x62, 0x8d, 0xd8,
0xff, 0x99, 0xe0, 0xb1, 0x92, 0x9b, 0xc3, 0xb1, 0x2c, 0xb9, 0xcb, 0xcd, 0xb2, 0x22, 0x3c, 0x24,
0x87, 0x53, 0x59, 0xef, 0xb5, 0x5d, 0xb6, 0x21, 0xcb, 0x66, 0x70, 0xf6, 0x09, 0xac, 0x8e, 0xf8,
0xc0, 0xf7, 0xec, 0x2a, 0x7a, 0xe9, 0x26, 0x3f, 0x2d, 0x1b, 0x5b, 0xc1, 0x59, 0xf8, 0x59, 0x38,
0x3a, 0xf6, 0xc5, 0xc6, 0x26, 0x1c, 0xfb, 0x55, 0x37, 0x87, 0x3b, 0x73, 0xd0, 0x3c, 0x4a, 0xc2,
0xb1, 0x5a, 0xfa, 0x79, 0x68, 0x89, 0xa4, 0x0c, 0x8d, 0x7c, 0x07, 0x6e, 0x10, 0xbd, 0x3e, 0x0f,
0xc7, 0xe1, 0x30, 0x3c, 0xbd, 0xb4, 0xcc, 0xf3, 0xff, 0x50, 0x82, 0x25, 0x2b, 0x37, 0xb5, 0xcf,
0xc9, 0x97, 0xa8, 0xe2, 0xd9, 0x04, 0x89, 0x2f, 0x1a, 0xdb, 0x82, 0x28, 0x28, 0x8e, 0x6d, 0x5e,
0xc8, 0x10, 0xb7, 0xcd, 0xf4, 0x92, 0x86, 0xfa, 0x50, 0xd0, 0x7b, 0x27, 0x4f, 0xef, 0xf2, 0x7b,
0x75, 0x7d, 0x43, 0x55, 0xf1, 0x3b, 0x32, 0x98, 0x67, 0x20, 0x07, 0x5d, 0xb1, 0x03, 0x30, 0x4c,
0x77, 0x8e, 0xea, 0x41, 0x5f, 0x83, 0xb1, 0xf3, 0xf3, 0x12, 0x40, 0xda, 0x3b, 0x0a, 0x01, 0xd1,
0x5b, 0x9b, 0xb8, 0x08, 0x6c, 0x6c, 0x63, 0xef, 0x43, 0x4b, 0x9f, 0xe2, 0xa7, 0xbb, 0x65, 0x53,
0x61, 0xa8, 0x5d, 0xdc, 0x81, 0x85, 0xd3, 0x61, 0x78, 0x4c, 0x5a, 0x0c, 0xc5, 0xda, 0xc6, 0x32,
0x40, 0x74, 0x5e, 0xc0, 0x8f, 0x24, 0x9a, 0x6e, 0xad, 0x55, 0x73, 0x6b, 0x2d, 0xde, 0x28, 0xbf,
0x2c, 0xeb, 0xa3, 0xd4, 0x74, 0x26, 0xde, 0xc8, 0xe5, 0x6c, 0x23, 0x27, 0xd6, 0xa7, 0x9c, 0x5e,
0x92, 0xe9, 0x71, 0x78, 0xa5, 0x77, 0xf7, 0x21, 0xcc, 0x47, 0x42, 0x66, 0x2a, 0x81, 0x5a, 0x7d,
0x83, 0x40, 0x9d, 0x8b, 0xac, 0x9d, 0xf9, 0xeb, 0xd0, 0xf6, 0x06, 0xe7, 0x3c, 0x4a, 0x7c, 0xf2,
0x76, 0x91, 0x1a, 0x25, 0x06, 0xb8, 0x60, 0xe0, 0xa4, 0xad, 0xdc, 0x81, 0x05, 0x19, 0xae, 0xab,
0x4b, 0xca, 0x6b, 0x75, 0x29, 0x8c, 0x05, 0x9d, 0x7f, 0xa4, 0x4e, 0x6e, 0xed, 0xd5, 0x7d, 0xf3,
0xac, 0x98, 0x23, 0x2c, 0x67, 0x46, 0xf8, 0x35, 0x79, 0x92, 0x3a, 0x50, 0x6e, 0xb5, 0x8a, 0x11,
0x16, 0x36, 0x90, 0x27, 0xdf, 0xf6, 0xb4, 0x56, 0xdf, 0x66, 0x5a, 0x9d, 0xff, 0x5c, 0x82, 0xd9,
0xbd, 0x70, 0xbc, 0x87, 0x53, 0x8c, 0x3a, 0x0e, 0xb2, 0x89, 0x8e, 0x95, 0x57, 0xc9, 0x2b, 0xc2,
0xe7, 0x0a, 0xb5, 0x92, 0xb9, 0xac, 0x56, 0xf2, 0xe7, 0xe1, 0x1d, 0x72, 0xec, 0x46, 0xe1, 0x38,
0x8c, 0x90, 0x5d, 0xbd, 0xa1, 0x50, 0x41, 0xc2, 0x20, 0x39, 0x53, 0xe2, 0xf4, 0x4d, 0x45, 0xc8,
0xdb, 0x82, 0x46, 0xb0, 0x30, 0xac, 0xa4, 0x16, 0x25, 0xa4, 0x6c, 0x3e, 0xc3, 0xf9, 0x6d, 0x68,
0x90, 0x85, 0x41, 0x43, 0xfb, 0x10, 0x1a, 0x67, 0xe1, 0xb8, 0x77, 0xe6, 0x07, 0x89, 0x62, 0xff,
0xf9, 0x54, 0xf5, 0xdf, 0xa3, 0x49, 0xd1, 0x05, 0x9c, 0x7f, 0x33, 0x03, 0xb3, 0x4f, 0x82, 0xf3,
0xd0, 0xef, 0xd3, 0x69, 0xf1, 0x88, 0x8f, 0x42, 0x75, 0x7b, 0x00, 0x7f, 0xe3, 0x74, 0x50, 0xa8,
0xec, 0x58, 0x10, 0x6f, 0x4b, 0x44, 0x85, 0x48, 0x88, 0xee, 0xbd, 0xa6, 0x37, 0xff, 0x04, 0x83,
0x19, 0x08, 0x1a, 0x8a, 0x91, 0x79, 0x73, 0x4f, 0xa6, 0xd2, 0xdb, 0x19, 0x35, 0xe3, 0x76, 0x06,
0xb6, 0x25, 0x83, 0xfa, 0x44, 0xd4, 0x97, 0x68, 0x4b, 0x42, 0x64, 0xdc, 0x46, 0x5c, 0x38, 0xe6,
0xb5, 0xe2, 0x85, 0xc6, 0xad, 0x09, 0xa2, 0x72, 0x26, 0x3e, 0x10, 0x65, 0xc4, 0x66, 0x60, 0x42,
0xa8, 0x9e, 0x66, 0x2f, 0x8c, 0x8a, 0x0b, 0xbb, 0x59, 0x18, 0x65, 0xf9, 0x80, 0x6b, 0x91, 0x2b,
0xc6, 0x01, 0xe2, 0x76, 0x63, 0x16, 0x37, 0x4c, 0x62, 0x11, 0xd5, 0xac, 0x4c, 0x62, 0x24, 0x18,
0x6f, 0x38, 0x3c, 0xf6, 0xfa, 0xaf, 0x84, 0x29, 0xd9, 0x12, 0xe7, 0x39, 0x16, 0x48, 0xa1, 0x79,
0xe9, 0xaa, 0x52, 0xfc, 0x4c, 0xd5, 0x35, 0x21, 0xb6, 0x01, 0x4d, 0x72, 0x17, 0xc8, 0x75, 0x9d,
0xa7, 0x75, 0x6d, 0x9b, 0xfe, 0x04, 0x5a, 0x59, 0xb3, 0x90, 0x79, 0x92, 0xbd, 0x90, 0x8b, 0x33,
0xf6, 0x06, 0x03, 0x19, 0x00, 0xd0, 0x16, 0x37, 0xfc, 0x34, 0x40, 0x0e, 0x09, 0x31, 0x61, 0xa2,
0xc0, 0x22, 0x15, 0xb0, 0x30, 0x76, 0x0b, 0xea, 0x68, 0xf5, 0x8d, 0x3d, 0x7f, 0x40, 0x21, 0x33,
0xc2, 0xf8, 0xd4, 0x18, 0xd6, 0xa1, 0x7e, 0xd3, 0xb6, 0xb9, 0x44, 0xb3, 0x62, 0x61, 0x38, 0x37,
0x3a, 0x3d, 0x4a, 0x03, 0x93, 0x6d, 0x90, 0x7d, 0x44, 0xc7, 0xb0, 0x09, 0xa7, 0xe8, 0xe3, 0xf9,
0x8d, 0x77, 0xe4, 0x98, 0x25, 0xd1, 0xaa, 0xbf, 0x47, 0x58, 0xc4, 0x15, 0x25, 0x51, 0x69, 0x13,
0x9e, 0xf0, 0x15, 0x4b, 0x69, 0x93, 0x45, 0xc9, 0x13, 0x2e, 0x0a, 0x38, 0x9b, 0xd0, 0x32, 0x2b,
0x60, 0x75, 0xa8, 0x3e, 0x3b, 0xdc, 0x3d, 0x68, 0x5f, 0x63, 0x4d, 0x98, 0x3d, 0xda, 0x7d, 0xfe,
0x7c, 0x7f, 0x77, 0xa7, 0x5d, 0x62, 0x2d, 0xa8, 0xeb, 0x88, 0xcb, 0x32, 0xa6, 0x36, 0xb7, 0xb7,
0x77, 0x0f, 0x9f, 0xef, 0xee, 0xb4, 0x2b, 0xce, 0x1f, 0x95, 0xa1, 0x69, 0xd4, 0x7c, 0x85, 0x8b,
0xe6, 0x16, 0x00, 0x59, 0x12, 0x69, 0xec, 0x45, 0xd5, 0x35, 0x10, 0x94, 0x8c, 0xda, 0xc6, 0xae,
0x88, 0x8b, 0x8e, 0x2a, 0x4d, 0xf3, 0x45, 0x37, 0x0a, 0xcd, 0x03, 0x87, 0x9a, 0x6b, 0x83, 0x48,
0x4b, 0x12, 0xa0, 0x00, 0x40, 0xc1, 0x61, 0x26, 0x84, 0x6b, 0x13, 0xf1, 0x38, 0x1c, 0x9e, 0x73,
0x51, 0x44, 0xe8, 0x63, 0x16, 0x86, 0x6d, 0x49, 0x11, 0x63, 0x04, 0xe7, 0xd6, 0x5c, 0x1b, 0x64,
0xdf, 0x54, 0x6b, 0x53, 0xa7, 0xb5, 0x59, 0xcd, 0x4f, 0xb4, 0xb9, 0x2e, 0x4e, 0x02, 0x6c, 0x73,
0x30, 0x90, 0xb9, 0xe6, 0xb5, 0xc9, 0xc8, 0xbc, 0xa3, 0xab, 0x84, 0x44, 0x01, 0xa3, 0x96, 0x8b,
0x19, 0xf5, 0x8d, 0xe4, 0xec, 0xec, 0x42, 0xf3, 0xd0, 0xb8, 0xf5, 0x4b, 0x32, 0x4b, 0xdd, 0xf7,
0x95, 0xb2, 0xce, 0x40, 0x8c, 0xee, 0x94, 0xcd, 0xee, 0x38, 0xff, 0xb0, 0x24, 0x2e, 0x52, 0xe9,
0xee, 0x8b, 0xb6, 0x1d, 0x68, 0x69, 0x77, 0x72, 0x1a, 0x7b, 0x6e, 0x61, 0x58, 0x86, 0xba, 0xd2,
0x0b, 0x4f, 0x4e, 0x62, 0xae, 0xa2, 0x44, 0x2d, 0x4c, 0x29, 0x8e, 0xa8, 0x8a, 0xfa, 0xa2, 0x85,
0x58, 0x46, 0x8b, 0xe6, 0x70, 0x24, 0x12, 0xe9, 0x91, 0x54, 0xf1, 0xb1, 0x3a, 0xad, 0x43, 0xe4,
0xb3, 0xb3, 0x7c, 0x0f, 0xea, 0xba, 0x5e, 0x7b, 0x57, 0x50, 0x25, 0x75, 0x3e, 0xee, 0x3e, 0x64,
0x54, 0x5a, 0x9d, 0x16, 0xb4, 0x9a, 0xcf, 0x60, 0xeb, 0xc0, 0x4e, 0xfc, 0x28, 0x5b, 0x5c, 0x10,
0x6f, 0x41, 0x8e, 0xf3, 0x12, 0x96, 0x14, 0xcf, 0x19, 0x1a, 0xad, 0xbd, 0x88, 0xa5, 0xab, 0x64,
0x52, 0x39, 0x2f, 0x93, 0x9c, 0x5f, 0x54, 0x60, 0x56, 0xae, 0x74, 0xee, 0xe6, 0xb8, 0x58, 0x67,
0x0b, 0x63, 0x1d, 0xeb, 0x8e, 0x20, 0x09, 0x30, 0xb9, 0x13, 0xe5, 0xf6, 0x9a, 0x4a, 0xd1, 0x5e,
0xc3, 0xa0, 0x3a, 0xf6, 0x92, 0x33, 0x72, 0xbd, 0x34, 0x5c, 0xfa, 0xad, 0x1c, 0xa6, 0x35, 0xdb,
0x61, 0x5a, 0x74, 0x4f, 0x5e, 0xa8, 0x53, 0xf9, 0x7b, 0xf2, 0x37, 0xa1, 0x21, 0xee, 0x56, 0xa7,
0x3e, 0xd1, 0x14, 0x40, 0xea, 0x15, 0x09, 0x92, 0x10, 0xf2, 0xba, 0x4e, 0x8a, 0x7c, 0x85, 0xdd,
0xed, 0xdb, 0x30, 0x23, 0xee, 0x8b, 0xc8, 0x28, 0xe0, 0x9b, 0xea, 0xbc, 0x50, 0x94, 0x53, 0x7f,
0x45, 0x38, 0x91, 0x2b, 0xcb, 0x9a, 0x37, 0x4e, 0x9b, 0xf6, 0x8d, 0x53, 0xd3, 0x95, 0xdb, 0xb2,
0x5d, 0xb9, 0xce, 0x23, 0x98, 0xb3, 0xaa, 0x43, 0xe9, 0x2a, 0xa3, 0x88, 0xdb, 0xd7, 0xd8, 0x1c,
0x34, 0x9e, 0x1c, 0xf4, 0x1e, 0xed, 0x3f, 0x79, 0xbc, 0xf7, 0xbc, 0x5d, 0xc2, 0xe4, 0xd1, 0x8b,
0xed, 0xed, 0xdd, 0xdd, 0x1d, 0x92, 0xb6, 0x00, 0x33, 0x8f, 0x36, 0x9f, 0xec, 0x93, 0xac, 0xdd,
0x11, 0xb4, 0x2d, 0xeb, 0xd2, 0x67, 0x34, 0xdf, 0x04, 0xa6, 0xec, 0x7e, 0x8a, 0x26, 0x1a, 0x0f,
0x79, 0xa2, 0x02, 0xdc, 0x17, 0x65, 0xce, 0x13, 0x9d, 0xa1, 0xee, 0x68, 0xa4, 0xb5, 0xa4, 0x2c,
0x22, 0x27, 0x29, 0xcb, 0x22, 0xb2, 0xa8, 0xab, 0xf3, 0x9d, 0x2e, 0x74, 0x76, 0x38, 0xd6, 0xb6,
0x39, 0x1c, 0x66, 0xba, 0x83, 0x86, 0x5b, 0x41, 0x9e, 0xb4, 0xea, 0xbe, 0x07, 0xd7, 0x37, 0x45,
0x2c, 0xfb, 0x6f, 0x2a, 0xd4, 0xd1, 0xe9, 0xc0, 0x4a, 0xb6, 0x4a, 0xd9, 0xd8, 0x23, 0x58, 0xdc,
0xe1, 0xc7, 0x93, 0xd3, 0x7d, 0x7e, 0x9e, 0x36, 0xc4, 0xa0, 0x1a, 0x9f, 0x85, 0x17, 0x72, 0x7e,
0xe8, 0x37, 0x7b, 0x17, 0x60, 0x88, 0x65, 0x7a, 0xf1, 0x98, 0xf7, 0xd5, 0x3d, 0x45, 0x42, 0x8e,
0xc6, 0xbc, 0xef, 0x7c, 0x0c, 0xcc, 0xac, 0x47, 0xce, 0x17, 0xea, 0x5a, 0x93, 0xe3, 0x5e, 0x7c,
0x19, 0x27, 0x7c, 0xa4, 0x2e, 0x60, 0x9a, 0x90, 0x73, 0x07, 0x5a, 0x87, 0xde, 0xa5, 0xcb, 0x7f,
0x2a, 0x5f, 0x50, 0x58, 0x85, 0xd9, 0xb1, 0x77, 0x89, 0x24, 0xa8, 0x9d, 0xc1, 0x94, 0xed, 0xfc,
0x9f, 0x32, 0xcc, 0x88, 0x92, 0x58, 0xeb, 0x80, 0xc7, 0x89, 0x1f, 0x10, 0xa7, 0xa9, 0x5a, 0x0d,
0x28, 0xc7, 0xdb, 0xe5, 0x02, 0xde, 0x96, 0x1e, 0x0a, 0x75, 0xdf, 0x4b, 0x32, 0xb0, 0x85, 0x21,
0xa7, 0xa5, 0x31, 0xcb, 0xc2, 0x65, 0x98, 0x02, 0x99, 0x43, 0x8e, 0x54, 0xa3, 0x13, 0xfd, 0x53,
0x62, 0x4b, 0xb2, 0xb1, 0x09, 0x15, 0xea, 0x8d, 0xb3, 0x82, 0xdb, 0x73, 0x7a, 0x63, 0x4e, 0x3f,
0xac, 0xbf, 0x85, 0x7e, 0x28, 0xdc, 0x16, 0x6f, 0xd2, 0x0f, 0xe1, 0x2d, 0xf4, 0x43, 0x87, 0x41,
0x9b, 0x2e, 0x93, 0xa3, 0x05, 0xa2, 0x68, 0xf7, 0xef, 0x96, 0xa0, 0x2d, 0xa9, 0x48, 0xe7, 0xa9,
0xe3, 0xb2, 0x37, 0xdd, 0x3a, 0xba, 0x0d, 0x73, 0x64, 0xff, 0x68, 0x11, 0x20, 0x8f, 0x9e, 0x2c,
0x10, 0xc7, 0xa1, 0x22, 0x5e, 0x46, 0xfe, 0x50, 0x2e, 0x8a, 0x09, 0x29, 0x29, 0x12, 0x79, 0x32,
0xf6, 0xb6, 0xe4, 0xea, 0xb4, 0xf3, 0x27, 0x25, 0x58, 0x34, 0x3a, 0x2c, 0xa9, 0xf0, 0x21, 0xb4,
0xf4, 0x9b, 0x0d, 0x5c, 0x6f, 0x6e, 0xab, 0x36, 0xdb, 0xa4, 0x9f, 0x59, 0x85, 0x69, 0x31, 0xbd,
0x4b, 0xea, 0x60, 0x3c, 0x19, 0xc9, 0x5d, 0xc5, 0x84, 0x90, 0x90, 0x2e, 0x38, 0x7f, 0xa5, 0x8b,
0x88, 0x7d, 0xcd, 0xc2, 0xc8, 0x6f, 0x8c, 0x76, 0x9b, 0x2e, 0x54, 0x95, 0x7e, 0x63, 0x13, 0x74,
0xfe, 0x72, 0x19, 0x96, 0x84, 0x21, 0x2e, 0x1d, 0x20, 0xfa, 0xda, 0xec, 0x8c, 0xf0, 0x49, 0x08,
0x8e, 0xdc, 0xbb, 0xe6, 0xca, 0x34, 0xfb, 0xce, 0x5b, 0x3a, 0x0f, 0x74, 0x40, 0xf0, 0x94, 0xb5,
0xa8, 0x14, 0xad, 0xc5, 0x1b, 0x66, 0xba, 0xc8, 0x85, 0x5f, 0x2b, 0x76, 0xe1, 0xbf, 0x95, 0xcb,
0x7c, 0x6b, 0x16, 0x6a, 0x71, 0x3f, 0x1c, 0x73, 0x67, 0x05, 0x96, 0xed, 0x29, 0x90, 0x82, 0xea,
0xe7, 0x25, 0xe8, 0x3c, 0x12, 0x07, 0x83, 0x7e, 0x70, 0xba, 0xe7, 0xc7, 0x49, 0x18, 0xe9, 0x37,
0x08, 0x6e, 0x01, 0xc4, 0x89, 0x17, 0x49, 0x85, 0x56, 0xa8, 0x06, 0x06, 0x82, 0x23, 0xe1, 0xc1,
0x40, 0xe4, 0x8a, 0x15, 0xd4, 0xe9, 0x9c, 0xea, 0x25, 0x9d, 0x09, 0x96, 0x02, 0xf3, 0x81, 0x08,
0xa3, 0xc7, 0x2e, 0xf3, 0x73, 0x92, 0xfe, 0xc2, 0x42, 0xcf, 0xa0, 0xce, 0x1f, 0x94, 0x61, 0x21,
0xed, 0x24, 0x85, 0x7b, 0xd8, 0x32, 0x44, 0x6a, 0x2d, 0xa9, 0x0c, 0x91, 0x8e, 0xff, 0x9e, 0x8f,
0x6a, 0x8c, 0xe1, 0x4f, 0x30, 0x50, 0x76, 0x1b, 0x9a, 0x2a, 0x15, 0x4e, 0x12, 0xe3, 0x32, 0xb0,
0x09, 0x8b, 0xe0, 0x58, 0x54, 0xa4, 0xa4, 0x52, 0x28, 0x53, 0x74, 0x31, 0x69, 0x94, 0xd0, 0x97,
0x62, 0xe6, 0x55, 0x92, 0xb5, 0x85, 0x26, 0x22, 0xde, 0x65, 0x21, 0x2d, 0xc4, 0xdc, 0xa1, 0xeb,
0xfa, 0x11, 0x15, 0xcd, 0x99, 0xa2, 0xc6, 0x34, 0xb2, 0xb9, 0xea, 0x9a, 0x90, 0xb2, 0xe8, 0xc2,
0x89, 0x71, 0xda, 0x59, 0x75, 0x2d, 0xcc, 0xf9, 0x9b, 0x25, 0xb8, 0x51, 0xb0, 0x8c, 0x92, 0x53,
0x77, 0x60, 0xf1, 0x44, 0x67, 0xaa, 0xa9, 0x16, 0xec, 0xba, 0xa2, 0xa2, 0x1f, 0xec, 0xe9, 0x75,
0xf3, 0x1f, 0x68, 0xe5, 0x54, 0x2c, 0x9e, 0x15, 0xc4, 0x9e, 0xcf, 0x70, 0x0e, 0xa1, 0xbb, 0xfb,
0x1a, 0x19, 0x7f, 0xdb, 0x7c, 0x4a, 0x4e, 0x51, 0xd6, 0x46, 0x4e, 0xb0, 0x5d, 0xed, 0x46, 0x3a,
0x81, 0x39, 0xab, 0x2e, 0xf6, 0xad, 0xb7, 0xad, 0xc4, 0xe4, 0xd1, 0x35, 0xb9, 0xea, 0xe2, 0x2d,
0x3c, 0x15, 0x4a, 0x6f, 0x40, 0xce, 0x39, 0x2c, 0x3c, 0x9d, 0x0c, 0x13, 0x3f, 0x7d, 0x17, 0x8f,
0x7d, 0x47, 0x7e, 0x44, 0x55, 0xa8, 0xa9, 0x2b, 0x6c, 0xca, 0x2c, 0x87, 0x33, 0x36, 0xc2, 0x9a,
0x7a, 0xf9, 0x16, 0xf3, 0x19, 0xce, 0x0d, 0x58, 0x4d, 0x9b, 0x14, 0x73, 0xa7, 0x36, 0x87, 0x3f,
0x2c, 0x89, 0x98, 0x30, 0xfb, 0x99, 0x3e, 0xf6, 0x18, 0x96, 0x62, 0x3f, 0x38, 0x1d, 0x72, 0xb3,
0x9e, 0x58, 0xce, 0xc4, 0x75, 0xbb, 0x7b, 0xf2, 0x29, 0x3f, 0xb7, 0xe8, 0x0b, 0x24, 0x90, 0xe2,
0x8e, 0xa6, 0x04, 0x92, 0x99, 0x92, 0xa2, 0x01, 0x7c, 0x17, 0xe6, 0xed, 0xc6, 0xd8, 0x27, 0x32,
0x0a, 0x3e, 0xed, 0x99, 0x79, 0xee, 0x63, 0x53, 0x86, 0x55, 0xd2, 0xf9, 0xb2, 0x04, 0x1d, 0x97,
0x23, 0x19, 0x73, 0xa3, 0x51, 0x49, 0x3d, 0x0f, 0x73, 0xd5, 0x4e, 0x1f, 0xb0, 0x8e, 0xae, 0x57,
0x63, 0x5d, 0x9f, 0xba, 0x28, 0x7b, 0xd7, 0x0a, 0x46, 0xb5, 0x55, 0x87, 0x19, 0x39, 0xbe, 0x55,
0xb8, 0x2e, 0xbb, 0xa4, 0xba, 0x93, 0x1e, 0x18, 0x58, 0x8d, 0x5a, 0x07, 0x06, 0x5d, 0xe8, 0x88,
0xa7, 0x26, 0xcc, 0x71, 0xc8, 0x0f, 0x77, 0x80, 0x3d, 0xf5, 0xfa, 0x5e, 0x14, 0x86, 0xc1, 0x21,
0x8f, 0x64, 0x7c, 0x0f, 0x29, 0x40, 0xe4, 0x4f, 0x57, 0xba, 0x9a, 0x48, 0xa9, 0xd7, 0x11, 0xc2,
0x40, 0xbd, 0x42, 0x21, 0x52, 0x8e, 0x0b, 0x4b, 0x5b, 0xde, 0x2b, 0xae, 0x6a, 0x4a, 0x67, 0xa9,
0x39, 0xd6, 0x95, 0xaa, 0xb9, 0x57, 0x97, 0x5b, 0xf2, 0xcd, 0xba, 0x66, 0x69, 0x67, 0x03, 0x96,
0xed, 0x3a, 0xa5, 0x28, 0xe9, 0x42, 0x7d, 0x24, 0x31, 0xd9, 0x3b, 0x9d, 0xbe, 0xf7, 0x05, 0x34,
0x8d, 0xe7, 0x43, 0xd8, 0x2a, 0x2c, 0xbd, 0x7c, 0xf2, 0xfc, 0x60, 0xf7, 0xe8, 0xa8, 0x77, 0xf8,
0x62, 0xeb, 0xb3, 0xdd, 0x1f, 0xf4, 0xf6, 0x36, 0x8f, 0xf6, 0xda, 0xd7, 0xd8, 0x0a, 0xb0, 0x83,
0xdd, 0xa3, 0xe7, 0xbb, 0x3b, 0x16, 0x5e, 0x62, 0xb7, 0xa0, 0xfb, 0xe2, 0xe0, 0xc5, 0xd1, 0xee,
0x4e, 0xaf, 0xe8, 0xbb, 0x32, 0x7b, 0x17, 0x6e, 0xc8, 0xfc, 0x82, 0xcf, 0x2b, 0xf7, 0x1e, 0x42,
0x3b, 0xeb, 0xff, 0xb0, 0x3c, 0x46, 0x6f, 0x72, 0x2d, 0x6d, 0x7c, 0x59, 0x81, 0x79, 0x11, 0xa5,
0x27, 0x1e, 0xba, 0xe4, 0x11, 0x7b, 0x0a, 0xb3, 0xf2, 0xc5, 0x54, 0xa6, 0x48, 0xcb, 0x7e, 0xa3,
0xb5, 0xbb, 0x92, 0x85, 0xe5, 0xb2, 0x2e, 0xfd, 0x95, 0xff, 0xf4, 0x3f, 0xfe, 0x76, 0x79, 0x8e,
0x35, 0xef, 0x9f, 0x7f, 0x74, 0xff, 0x94, 0x07, 0x31, 0xd6, 0xf1, 0x7b, 0x00, 0xe9, 0x3b, 0xa0,
0xac, 0xa3, 0x7d, 0x00, 0x99, 0x47, 0x52, 0xbb, 0x37, 0x0a, 0x72, 0x64, 0xbd, 0x37, 0xa8, 0xde,
0x25, 0x67, 0x1e, 0xeb, 0xf5, 0x03, 0x3f, 0x11, 0x6f, 0x82, 0x7e, 0x5a, 0xba, 0xc7, 0x06, 0xd0,
0x32, 0x5f, 0xe8, 0x64, 0xea, 0xfc, 0xa7, 0xe0, 0x8d, 0xd1, 0xee, 0x3b, 0x85, 0x79, 0x8a, 0x96,
0xa9, 0x8d, 0xeb, 0x4e, 0x1b, 0xdb, 0x98, 0x50, 0x89, 0xb4, 0x95, 0xa1, 0xe0, 0xf0, 0xf4, 0x21,
0x4e, 0x76, 0xd3, 0x60, 0xba, 0xdc, 0x33, 0xa0, 0xdd, 0x77, 0xa7, 0xe4, 0xca, 0xb6, 0xde, 0xa5,
0xb6, 0x56, 0x1d, 0x86, 0x6d, 0xf5, 0xa9, 0x8c, 0x7a, 0x06, 0xf4, 0xd3, 0xd2, 0xbd, 0x8d, 0x7f,
0x7f, 0x07, 0x1a, 0xfa, 0x6c, 0x98, 0xfd, 0x04, 0xe6, 0xac, 0x30, 0x4a, 0xa6, 0x86, 0x51, 0x14,
0x75, 0xd9, 0xbd, 0x59, 0x9c, 0x29, 0x1b, 0xbe, 0x45, 0x0d, 0x77, 0xd8, 0x0a, 0x36, 0x2c, 0xe3,
0x10, 0xef, 0x53, 0x40, 0xb0, 0xb8, 0x4f, 0xf8, 0xca, 0x90, 0x64, 0xa2, 0xb1, 0x9b, 0x59, 0xe1,
0x62, 0xb5, 0xf6, 0xee, 0x94, 0x5c, 0xd9, 0xdc, 0x4d, 0x6a, 0x6e, 0x85, 0x2d, 0x9b, 0xcd, 0xe9,
0xf3, 0x5a, 0x4e, 0x97, 0x68, 0xcd, 0x37, 0x2a, 0xd9, 0xbb, 0x9a, 0xb0, 0x8a, 0xde, 0xae, 0xd4,
0x24, 0x92, 0x7f, 0xc0, 0xd2, 0xe9, 0x50, 0x53, 0x8c, 0xd1, 0xf2, 0x99, 0x4f, 0x54, 0xb2, 0x63,
0x68, 0x1a, 0x2f, 0x59, 0xb1, 0x1b, 0x53, 0x5f, 0xdd, 0xea, 0x76, 0x8b, 0xb2, 0x8a, 0x86, 0x62,
0xd6, 0x7f, 0x1f, 0x15, 0x9d, 0x1f, 0x41, 0x43, 0xbf, 0x8d, 0xc4, 0x56, 0x8d, 0xb7, 0xaa, 0xcc,
0xb7, 0x9c, 0xba, 0x9d, 0x7c, 0x46, 0x11, 0xf1, 0x99, 0xb5, 0x23, 0xf1, 0xbd, 0x84, 0xa6, 0xf1,
0xfe, 0x91, 0x1e, 0x40, 0xfe, 0x8d, 0x25, 0x3d, 0x80, 0x82, 0xe7, 0x92, 0x9c, 0x45, 0x6a, 0xa2,
0xc9, 0x1a, 0x44, 0xdf, 0xc9, 0xeb, 0x30, 0x66, 0xfb, 0x70, 0x5d, 0x4a, 0xec, 0x63, 0xfe, 0x55,
0x96, 0xa1, 0xe0, 0x59, 0xd0, 0x07, 0x25, 0xf6, 0x10, 0xea, 0xea, 0x99, 0x2b, 0xb6, 0x52, 0xfc,
0x5c, 0x57, 0x77, 0x35, 0x87, 0x4b, 0xf1, 0xfa, 0x03, 0x80, 0xf4, 0xb1, 0x25, 0x2d, 0x24, 0x72,
0x8f, 0x37, 0x69, 0x0a, 0xc8, 0xbf, 0xcc, 0xe4, 0xac, 0xd0, 0x00, 0xdb, 0x8c, 0x84, 0x44, 0xc0,
0x2f, 0xd4, 0x7d, 0xf9, 0x1f, 0x43, 0xd3, 0x78, 0x6f, 0x49, 0x4f, 0x5f, 0xfe, 0xad, 0x26, 0x3d,
0x7d, 0x05, 0xcf, 0x33, 0x39, 0x5d, 0xaa, 0x7d, 0xd9, 0x59, 0xc0, 0xda, 0x63, 0xff, 0x34, 0x18,
0x89, 0x02, 0xb8, 0x40, 0x67, 0x30, 0x67, 0x3d, 0xaa, 0xa4, 0x39, 0xb4, 0xe8, 0xc9, 0x26, 0xcd,
0xa1, 0x85, 0xef, 0x30, 0x29, 0x3a, 0x73, 0x16, 0xb1, 0x9d, 0x73, 0x2a, 0x62, 0xb4, 0xf4, 0x43,
0x68, 0x1a, 0x0f, 0x24, 0xe9, 0xb1, 0xe4, 0xdf, 0x62, 0xd2, 0x63, 0x29, 0x7a, 0x4f, 0x69, 0x99,
0xda, 0x98, 0x77, 0x88, 0x14, 0xe8, 0xe6, 0x37, 0xd6, 0xfd, 0x13, 0x98, 0xb7, 0x9f, 0x4c, 0xd2,
0xbc, 0x5f, 0xf8, 0xf8, 0x92, 0xe6, 0xfd, 0x29, 0xef, 0x2c, 0x49, 0x92, 0xbe, 0xb7, 0xa4, 0x1b,
0xb9, 0xff, 0xb9, 0x8c, 0x2e, 0xfb, 0x82, 0x7d, 0x0f, 0x05, 0x9c, 0xbc, 0x8a, 0xcf, 0x56, 0x0d,
0xaa, 0x35, 0x2f, 0xec, 0x6b, 0x7e, 0xc9, 0xdd, 0xda, 0xb7, 0x89, 0x59, 0xdc, 0x5d, 0xa7, 0x5d,
0x8b, 0xae, 0xe4, 0x1b, 0xbb, 0x96, 0x79, 0x6b, 0xdf, 0xd8, 0xb5, 0xac, 0x9b, 0xfb, 0xd9, 0x5d,
0x2b, 0xf1, 0xb1, 0x8e, 0x00, 0x16, 0x32, 0x57, 0x3d, 0x34, 0x57, 0x14, 0xdf, 0xc6, 0xeb, 0xde,
0x7a, 0xf3, 0x0d, 0x11, 0x5b, 0x82, 0x28, 0x21, 0x78, 0x5f, 0xdd, 0x7d, 0xfc, 0x7d, 0x68, 0x99,
0xcf, 0xb8, 0x30, 0x93, 0x95, 0xb3, 0x2d, 0xbd, 0x53, 0x98, 0x67, 0x2f, 0x2e, 0x6b, 0x99, 0xcd,
0xb0, 0xef, 0xc3, 0x8a, 0x66, 0x75, 0xf3, 0xf6, 0x40, 0xcc, 0xde, 0x2b, 0xb8, 0x53, 0x60, 0xea,
0x71, 0xdd, 0x1b, 0x53, 0x2f, 0x1d, 0x3c, 0x28, 0x21, 0xd1, 0xd8, 0x6f, 0x63, 0xa4, 0x1b, 0x46,
0xd1, 0x93, 0x20, 0xe9, 0x86, 0x51, 0xf8, 0xa0, 0x86, 0x22, 0x1a, 0xb6, 0x64, 0xcd, 0x91, 0x38,
0x88, 0x67, 0x3f, 0x84, 0x05, 0xe3, 0x7e, 0xd6, 0xd1, 0x65, 0xd0, 0xd7, 0x0c, 0x90, 0xbf, 0x3a,
0xdc, 0x2d, 0xb2, 0x52, 0x9c, 0x55, 0xaa, 0x7f, 0xd1, 0xb1, 0x26, 0x07, 0x89, 0x7f, 0x1b, 0x9a,
0xe6, 0xdd, 0xaf, 0x37, 0xd4, 0xbb, 0x6a, 0x64, 0x99, 0x37, 0x5f, 0x1f, 0x94, 0xd8, 0xa1, 0x08,
0xc8, 0xd2, 0xef, 0x74, 0x86, 0x51, 0x76, 0xfb, 0xb4, 0xdf, 0xef, 0xd4, 0x0b, 0x59, 0xf4, 0x72,
0xeb, 0xdd, 0xd2, 0x83, 0x12, 0xfb, 0x7b, 0x25, 0x68, 0x59, 0x77, 0xb3, 0xac, 0xf0, 0x96, 0x4c,
0xcf, 0x3a, 0x66, 0x9e, 0xd9, 0x35, 0xc7, 0xa5, 0x61, 0xef, 0xdf, 0xfb, 0xae, 0x35, 0xad, 0x9f,
0x5b, 0x0e, 0xb5, 0xf5, 0xec, 0x63, 0x9d, 0x5f, 0x64, 0x0b, 0x98, 0x17, 0xb6, 0xbf, 0x78, 0x50,
0x62, 0x7f, 0x5c, 0x82, 0x79, 0xdb, 0x0d, 0xac, 0x87, 0x5b, 0xe8, 0x70, 0xd6, 0x8b, 0x3f, 0xc5,
0x77, 0xfc, 0x43, 0xea, 0xe5, 0xf3, 0x7b, 0xae, 0xd5, 0x4b, 0xf9, 0x0e, 0xcb, 0xaf, 0xd7, 0x5b,
0xf6, 0xa9, 0x78, 0x5d, 0x5a, 0x1d, 0xd6, 0xb0, 0xfc, 0x1b, 0xc7, 0x9a, 0x60, 0xcc, 0x57, 0x89,
0x69, 0x11, 0x7e, 0x2c, 0x1e, 0xa9, 0x54, 0xe7, 0x09, 0x48, 0x77, 0x6f, 0xfb, 0xbd, 0x73, 0x9b,
0xc6, 0x74, 0xcb, 0xb9, 0x61, 0x8d, 0x29, 0xbb, 0xc3, 0x6f, 0x8a, 0xde, 0xc9, 0x07, 0x85, 0xd3,
0x2d, 0x2a, 0xf7, 0xc8, 0xf0, 0xf4, 0x4e, 0x8e, 0x44, 0x27, 0x65, 0x71, 0x8b, 0x39, 0xde, 0xb2,
0x1a, 0xe7, 0x1e, 0xf5, 0xf5, 0xb6, 0xf3, 0xde, 0xd4, 0xbe, 0xde, 0x27, 0x67, 0x2e, 0xf6, 0xf8,
0x10, 0x20, 0x3d, 0x58, 0x65, 0x99, 0x83, 0x3d, 0x2d, 0x32, 0xf2, 0x67, 0xaf, 0x36, 0x07, 0xaa,
0xf3, 0x3f, 0xac, 0xf1, 0x47, 0x42, 0x00, 0x3e, 0x51, 0x47, 0x82, 0xa6, 0x9a, 0x63, 0x9f, 0x80,
0x5a, 0x6a, 0x4e, 0xb6, 0x7e, 0x4b, 0xfc, 0xe9, 0xf3, 0xc5, 0x17, 0x30, 0xb7, 0x1f, 0x86, 0xaf,
0x26, 0x63, 0x1d, 0x79, 0x62, 0x9f, 0xb3, 0xec, 0x79, 0xf1, 0x59, 0x37, 0x33, 0x0a, 0x67, 0x8d,
0xaa, 0xea, 0xb2, 0x8e, 0x51, 0xd5, 0xfd, 0xcf, 0xd3, 0x83, 0xdb, 0x2f, 0x98, 0x07, 0x8b, 0x5a,
0xaa, 0xea, 0x8e, 0x77, 0xed, 0x6a, 0x2c, 0x59, 0x9a, 0x6d, 0xc2, 0xd2, 0xc7, 0x55, 0x6f, 0xef,
0xc7, 0xaa, 0x4e, 0x92, 0x29, 0xad, 0x1d, 0xde, 0xa7, 0x9b, 0x27, 0x74, 0x58, 0xb1, 0x94, 0x76,
0x5c, 0x9f, 0x72, 0x74, 0xe7, 0x2c, 0xd0, 0xde, 0x69, 0xc6, 0xde, 0x65, 0xc4, 0x7f, 0x7a, 0xff,
0x73, 0x79, 0x0c, 0xf2, 0x85, 0xda, 0x69, 0xd4, 0x39, 0x91, 0xb5, 0xd3, 0x64, 0x0e, 0x96, 0xac,
0x9d, 0x26, 0x77, 0xb0, 0x64, 0x4d, 0xb5, 0x3a, 0xa7, 0x62, 0x43, 0x58, 0xcc, 0x9d, 0x45, 0xe9,
0x4d, 0x66, 0xda, 0x09, 0x56, 0x77, 0x6d, 0x7a, 0x01, 0xbb, 0xb5, 0x7b, 0x76, 0x6b, 0x47, 0x30,
0xb7, 0xc3, 0xc5, 0x64, 0x89, 0x50, 0xdb, 0xcc, 0x05, 0x3f, 0x33, 0x90, 0x37, 0xbb, 0x25, 0x50,
0x9e, 0xad, 0x4a, 0x50, 0x8c, 0x2b, 0xfb, 0x11, 0x34, 0x1f, 0xf3, 0x44, 0xc5, 0xd6, 0x6a, 0x65,
0x36, 0x13, 0x6c, 0xdb, 0x2d, 0x08, 0xcd, 0xb5, 0x69, 0x86, 0x6a, 0xbb, 0xcf, 0x07, 0xa7, 0x5c,
0x08, 0xa7, 0x9e, 0x3f, 0xf8, 0x82, 0xfd, 0x05, 0xaa, 0x5c, 0x5f, 0x2e, 0x58, 0x31, 0x02, 0x25,
0xcd, 0xca, 0x17, 0x32, 0x78, 0x51, 0xcd, 0x41, 0x38, 0xe0, 0x86, 0x52, 0x15, 0x40, 0xd3, 0xb8,
0x13, 0xa4, 0x19, 0x28, 0x7f, 0xc5, 0x4c, 0x33, 0x50, 0xc1, 0x15, 0x22, 0xe7, 0x2e, 0xb5, 0xe3,
0xb0, 0xb5, 0xb4, 0x1d, 0x71, 0x6d, 0x28, 0x6d, 0xe9, 0xfe, 0xe7, 0xde, 0x28, 0xf9, 0x82, 0xbd,
0xa4, 0x77, 0x91, 0xcc, 0xd8, 0xe1, 0x54, 0x3b, 0xcf, 0x86, 0x19, 0xeb, 0xc9, 0x32, 0xb2, 0x6c,
0x8d, 0x5d, 0x34, 0x45, 0xba, 0xd7, 0x77, 0x00, 0x8e, 0x92, 0x70, 0xbc, 0xe3, 0xf1, 0x51, 0x18,
0xa4, 0xb2, 0x36, 0x8d, 0x5c, 0x4d, 0xe5, 0x97, 0x11, 0xbe, 0xca, 0x5e, 0x1a, 0xe6, 0x8c, 0x15,
0x7e, 0xad, 0x88, 0x6b, 0x6a, 0x70, 0xab, 0x9e, 0x90, 0x82, 0x00, 0xd7, 0x07, 0x25, 0xb6, 0x09,
0x90, 0x1e, 0x46, 0x6a, 0xe3, 0x24, 0x77, 0xce, 0xa9, 0xc5, 0x5e, 0xc1, 0xc9, 0xe5, 0x21, 0x34,
0xd2, 0xd3, 0xad, 0xd5, 0xf4, 0xe6, 0x9d, 0x75, 0x16, 0xa6, 0x77, 0xf0, 0xdc, 0x99, 0x93, 0xd3,
0xa6, 0xa9, 0x02, 0x56, 0xc7, 0xa9, 0xa2, 0x83, 0x24, 0x1f, 0x96, 0x44, 0x07, 0xb5, 0x82, 0x43,
0x11, 0x97, 0x6a, 0x24, 0x05, 0xe7, 0x3e, 0x9a, 0x9b, 0x0b, 0x0f, 0x44, 0x2c, 0x1f, 0x0b, 0x52,
0xab, 0x88, 0xf6, 0x44, 0xd1, 0x3c, 0x82, 0xc5, 0x9c, 0x8f, 0x5d, 0xb3, 0xf4, 0xb4, 0x43, 0x14,
0xcd, 0xd2, 0x53, 0xdd, 0xf3, 0xce, 0x75, 0x6a, 0x72, 0xc1, 0x01, 0xb2, 0xa9, 0x2e, 0xfc, 0xa4,
0x7f, 0x86, 0xcd, 0xfd, 0x61, 0x09, 0x96, 0x0a, 0x5c, 0xe8, 0xec, 0x7d, 0x65, 0x9e, 0x4f, 0x75,
0xaf, 0x77, 0x0b, 0x3d, 0xac, 0xce, 0x11, 0xb5, 0xf3, 0x94, 0x7d, 0x66, 0x6d, 0x6c, 0xc2, 0xb9,
0x29, 0x39, 0xf3, 0x8d, 0x4a, 0x45, 0xa1, 0x46, 0xf1, 0x53, 0x58, 0x15, 0x1d, 0xd9, 0x1c, 0x0e,
0x33, 0xde, 0xdf, 0x5b, 0xb9, 0x7f, 0x30, 0x63, 0x79, 0xb5, 0xbb, 0xd3, 0xff, 0x01, 0xcd, 0x14,
0x05, 0x58, 0x74, 0x95, 0x4d, 0xa0, 0x9d, 0xf5, 0xa8, 0xb2, 0xe9, 0x75, 0x75, 0xdf, 0xb3, 0x0c,
0xcd, 0x02, 0x2f, 0xec, 0x6f, 0x51, 0x63, 0xef, 0x39, 0xdd, 0xa2, 0x79, 0x11, 0xb6, 0x27, 0xae,
0xc7, 0x5f, 0xd2, 0xee, 0xdf, 0xcc, 0x38, 0x55, 0x03, 0xd3, 0xfc, 0xd5, 0xda, 0xd4, 0x2d, 0xf6,
0x1e, 0x7f, 0x40, 0xcd, 0xaf, 0x39, 0xef, 0x14, 0x35, 0x1f, 0x89, 0x4f, 0x84, 0xd1, 0xbb, 0x9a,
0xe5, 0x6b, 0xd5, 0x83, 0xb5, 0xa2, 0xf5, 0x9e, 0x6a, 0xbd, 0x64, 0xe6, 0xfa, 0x1a, 0xe9, 0x76,
0x2d, 0xd3, 0xdd, 0xab, 0xd9, 0xa7, 0xc0, 0xaf, 0xac, 0xd9, 0xa7, 0xc8, 0x3f, 0x6c, 0xeb, 0x35,
0xca, 0x33, 0xfc, 0x69, 0xe9, 0xde, 0xd6, 0x9d, 0x1f, 0xfe, 0xd6, 0xa9, 0x9f, 0x9c, 0x4d, 0x8e,
0xd7, 0xfb, 0xe1, 0xe8, 0xfe, 0x50, 0xb9, 0xf5, 0xe4, 0x2d, 0x84, 0xfb, 0xc3, 0x60, 0x70, 0x9f,
0xaa, 0x3d, 0x9e, 0xa1, 0xff, 0x88, 0xf5, 0xad, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0x95, 0x82,
0x58, 0xe9, 0x43, 0x6b, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.

@ -1836,6 +1836,32 @@ message Hop {
TLV format.
*/
bool tlv_payload = 9 [json_name = "tlv_payload"];
/**
An optional TLV record tha singals the use of an MPP payment. If present,
the receiver will enforce that that the same mpp_record is included in the
final hop payload of all non-zero payments in the HTLC set. If empty, a
regular single-shot payment is or was attempted.
*/
MPPRecord mpp_record = 10 [json_name = "mpp_record"];
}
message MPPRecord {
/**
A unique, random identifier used to authenticate the sender as the intended
payer of a multi-path payment. The payment_addr must be the same for all
subpayments, and match the payment_addr provided in the receiver's invoice.
The same payment_addr must be used on all subpayments.
*/
bytes payment_addr = 11 [json_name = "payment_addr"];
/**
The total amount in milli-satoshis being sent as part of a larger multi-path
payment. The caller is responsible for ensuring subpayments to the same node
and payment_hash sum exactly to total_amt_msat. The same
total_amt_msat must be used on all subpayments.
*/
int64 total_amt_msat = 10 [json_name = "total_amt_msat"];
}
/**

@ -2530,6 +2530,10 @@
"type": "boolean",
"format": "boolean",
"description": "* \nIf set to true, then this hop will be encoded using the new variable length\nTLV format."
},
"mpp_record": {
"$ref": "#/definitions/lnrpcMPPRecord",
"description": "*\nAn optional TLV record tha singals the use of an MPP payment. If present,\nthe receiver will enforce that that the same mpp_record is included in the\nfinal hop payload of all non-zero payments in the HTLC set. If empty, a\nregular single-shot payment is or was attempted."
}
}
},
@ -2873,6 +2877,21 @@
}
}
},
"lnrpcMPPRecord": {
"type": "object",
"properties": {
"payment_addr": {
"type": "string",
"format": "byte",
"description": "*\nA unique, random identifier used to authenticate the sender as the intended\npayer of a multi-path payment. The payment_addr must be the same for all\nsubpayments, and match the payment_addr provided in the receiver's invoice.\nThe same payment_addr must be used on all subpayments."
},
"total_amt_msat": {
"type": "string",
"format": "int64",
"description": "*\nThe total amount in milli-satoshis being sent as part of a larger multi-path\npayment. The caller is responsible for ensuring subpayments to the same node\nand payment_hash sum exactly to total_amt_msat. The same\ntotal_amt_msat must be used on all subpayments."
}
}
},
"lnrpcMacaroonPermission": {
"type": "object",
"properties": {

@ -106,7 +106,6 @@ func (h *harnessTest) Fatalf(format string, a ...interface{}) {
// RunTestCase executes a harness test case. Any errors or panics will be
// represented as fatal.
func (h *harnessTest) RunTestCase(testCase *testCase) {
h.testCase = testCase
defer func() {
h.testCase = nil
@ -4406,43 +4405,135 @@ func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) {
closeChannelAndAssert(ctxt, t, net, carol, chanPointCarol, false)
}
// testSingleHopSendToRoute tests that payments are properly processed
// through a provided route with a single hop. We'll create the
// following network topology:
// Alice --100k--> Bob
// We'll query the daemon for routes from Alice to Bob and then
// send payments through the route.
type singleHopSendToRouteCase struct {
name string
// streaming tests streaming SendToRoute if true, otherwise tests
// synchronous SenToRoute.
streaming bool
// routerrpc submits the request to the routerrpc subserver if true,
// otherwise submits to the main rpc server.
routerrpc bool
// mpp sets the MPP fields on the request if true, otherwise submits a
// regular payment.
mpp bool
}
var singleHopSendToRouteCases = []singleHopSendToRouteCase{
{
name: "regular main sync",
},
{
name: "regular main stream",
streaming: true,
},
{
name: "regular routerrpc sync",
routerrpc: true,
},
{
name: "mpp main sync",
mpp: true,
},
{
name: "mpp main stream",
streaming: true,
mpp: true,
},
{
name: "mpp routerrpc sync",
routerrpc: true,
mpp: true,
},
}
// testSingleHopSendToRoute tests that payments are properly processed through a
// provided route with a single hop. We'll create the following network
// topology:
// Carol --100k--> Dave
// We'll query the daemon for routes from Carol to Dave and then send payments
// by feeding the route back into the various SendToRoute RPC methods. Here we
// test all three SendToRoute endpoints, forcing each to perform both a regular
// payment and an MPP payment.
func testSingleHopSendToRoute(net *lntest.NetworkHarness, t *harnessTest) {
ctxb := context.Background()
for _, test := range singleHopSendToRouteCases {
test := test
t.t.Run(test.name, func(t1 *testing.T) {
ht := newHarnessTest(t1, t.lndHarness)
ht.RunTestCase(&testCase{
name: test.name,
test: func(_ *lntest.NetworkHarness, tt *harnessTest) {
testSingleHopSendToRouteCase(net, tt, test)
},
})
})
}
}
func testSingleHopSendToRouteCase(net *lntest.NetworkHarness, t *harnessTest,
test singleHopSendToRouteCase) {
const chanAmt = btcutil.Amount(100000)
const paymentAmtSat = 1000
const numPayments = 5
const amountPaid = int64(numPayments * paymentAmtSat)
ctxb := context.Background()
var networkChans []*lnrpc.ChannelPoint
// Open a channel with 100k satoshis between Alice and Bob with Alice
// Create Carol and Dave, then establish a channel between them. Carol
// is the sole funder of the channel with 100k satoshis. The network
// topology should look like:
// Carol -> 100k -> Dave
carol, err := net.NewNode("Carol", nil)
if err != nil {
t.Fatalf("unable to create new nodes: %v", err)
}
defer shutdownAndAssert(net, t, carol)
dave, err := net.NewNode("Dave", nil)
if err != nil {
t.Fatalf("unable to create new nodes: %v", err)
}
defer shutdownAndAssert(net, t, dave)
ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)
if err := net.ConnectNodes(ctxt, carol, dave); err != nil {
t.Fatalf("unable to connect carol to dave: %v", err)
}
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = net.SendCoins(ctxt, btcutil.SatoshiPerBitcoin, carol)
if err != nil {
t.Fatalf("unable to send coins to carol: %v", err)
}
// Open a channel with 100k satoshis between Carol and Dave with Carol
// being the sole funder of the channel.
ctxt, _ := context.WithTimeout(ctxb, channelOpenTimeout)
chanPointAlice := openChannelAndAssert(
ctxt, t, net, net.Alice, net.Bob,
ctxt, _ = context.WithTimeout(ctxb, channelOpenTimeout)
chanPointCarol := openChannelAndAssert(
ctxt, t, net, carol, dave,
lntest.OpenChannelParams{
Amt: chanAmt,
},
)
networkChans = append(networkChans, chanPointAlice)
networkChans = append(networkChans, chanPointCarol)
aliceChanTXID, err := lnd.GetChanPointFundingTxid(chanPointAlice)
carolChanTXID, err := lnd.GetChanPointFundingTxid(chanPointCarol)
if err != nil {
t.Fatalf("unable to get txid: %v", err)
}
aliceFundPoint := wire.OutPoint{
Hash: *aliceChanTXID,
Index: chanPointAlice.OutputIndex,
carolFundPoint := wire.OutPoint{
Hash: *carolChanTXID,
Index: chanPointCarol.OutputIndex,
}
// Wait for all nodes to have seen all channels.
nodes := []*lntest.HarnessNode{net.Alice, net.Bob}
nodeNames := []string{"Alice", "Bob"}
nodes := []*lntest.HarnessNode{carol, dave}
for _, chanPoint := range networkChans {
for i, node := range nodes {
for _, node := range nodes {
txid, err := lnd.GetChanPointFundingTxid(chanPoint)
if err != nil {
t.Fatalf("unable to get txid: %v", err)
@ -4456,111 +4547,241 @@ func testSingleHopSendToRoute(net *lntest.NetworkHarness, t *harnessTest) {
err = node.WaitForNetworkChannelOpen(ctxt, chanPoint)
if err != nil {
t.Fatalf("%s(%d): timeout waiting for "+
"channel(%s) open: %v", nodeNames[i],
"channel(%s) open: %v", node.Name(),
node.NodeID, point, err)
}
}
}
// Query for routes to pay from Alice to Bob.
// We set FinalCltvDelta to 40 since by default QueryRoutes returns
// the last hop with a final cltv delta of 9 where as the default in
// htlcswitch is 40.
const paymentAmt = 1000
routesReq := &lnrpc.QueryRoutesRequest{
PubKey: net.Bob.PubKeyStr,
Amt: paymentAmt,
FinalCltvDelta: lnd.DefaultBitcoinTimeLockDelta,
}
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
routes, err := net.Alice.QueryRoutes(ctxt, routesReq)
if err != nil {
t.Fatalf("unable to get route: %v", err)
}
// Create 5 invoices for Bob, which expect a payment from Alice for 1k
// satoshis with a different preimage each time.
const numPayments = 5
// Create invoices for Dave, which expect a payment from Carol.
_, rHashes, _, err := createPayReqs(
net.Bob, paymentAmt, numPayments,
dave, paymentAmtSat, numPayments,
)
if err != nil {
t.Fatalf("unable to create pay reqs: %v", err)
}
// We'll wait for all parties to recognize the new channels within the
// network.
// Query for routes to pay from Carol to Dave.
// We set FinalCltvDelta to 40 since by default QueryRoutes returns
// the last hop with a final cltv delta of 9 where as the default in
// htlcswitch is 40.
routesReq := &lnrpc.QueryRoutesRequest{
PubKey: dave.PubKeyStr,
Amt: paymentAmtSat,
FinalCltvDelta: lnd.DefaultBitcoinTimeLockDelta,
}
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = net.Bob.WaitForNetworkChannelOpen(ctxt, chanPointAlice)
routes, err := carol.QueryRoutes(ctxt, routesReq)
if err != nil {
t.Fatalf("alice didn't advertise her channel in time: %v", err)
t.Fatalf("unable to get route from %s: %v",
carol.Name(), err)
}
time.Sleep(time.Millisecond * 50)
// There should only be one route to try, so take the first item.
r := routes.Routes[0]
// Using Alice as the source, pay to the 5 invoices from Carol created
// above.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
alicePayStream, err := net.Alice.SendToRoute(ctxt)
if err != nil {
t.Fatalf("unable to create payment stream for alice: %v", err)
}
// Construct a closure that will set MPP fields on the route, which
// allows us to test MPP payments.
setMPPFields := func(i int) {
addr := [32]byte{byte(i)}
for _, rHash := range rHashes {
sendReq := &lnrpc.SendToRouteRequest{
PaymentHash: rHash,
Route: routes.Routes[0],
hop := r.Hops[len(r.Hops)-1]
hop.TlvPayload = true
hop.MppRecord = &lnrpc.MPPRecord{
PaymentAddr: addr[:],
TotalAmtMsat: paymentAmtSat * 1000,
}
err := alicePayStream.Send(sendReq)
}
// Construct closures for each of the payment types covered:
// - main rpc server sync
// - main rpc server streaming
// - routerrpc server sync
sendToRouteSync := func() {
for i, rHash := range rHashes {
// Populate the MPP fields for the final hop if we are
// testing MPP payments.
if test.mpp {
setMPPFields(i)
}
sendReq := &lnrpc.SendToRouteRequest{
PaymentHash: rHash,
Route: r,
}
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
resp, err := carol.SendToRouteSync(
ctxt, sendReq,
)
if err != nil {
t.Fatalf("unable to send to route for "+
"%s: %v", carol.Name(), err)
}
if resp.PaymentError != "" {
t.Fatalf("received payment error from %s: %v",
carol.Name(), resp.PaymentError)
}
}
}
sendToRouteStream := func() {
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
alicePayStream, err := carol.SendToRoute(ctxt)
if err != nil {
t.Fatalf("unable to send payment: %v", err)
t.Fatalf("unable to create payment stream for "+
"carol: %v", err)
}
for i, rHash := range rHashes {
// Populate the MPP fields for the final hop if we are
// testing MPP payments.
if test.mpp {
setMPPFields(i)
}
sendReq := &lnrpc.SendToRouteRequest{
PaymentHash: rHash,
Route: routes.Routes[0],
}
err := alicePayStream.Send(sendReq)
if err != nil {
t.Fatalf("unable to send payment: %v", err)
}
resp, err := alicePayStream.Recv()
if err != nil {
t.Fatalf("unable to send payment: %v", err)
}
if resp.PaymentError != "" {
t.Fatalf("received payment error: %v",
resp.PaymentError)
}
}
}
sendToRouteRouterRPC := func() {
for i, rHash := range rHashes {
// Populate the MPP fields for the final hop if we are
// testing MPP payments.
if test.mpp {
setMPPFields(i)
}
sendReq := &routerrpc.SendToRouteRequest{
PaymentHash: rHash,
Route: r,
}
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
resp, err := carol.RouterClient.SendToRoute(
ctxt, sendReq,
)
if err != nil {
t.Fatalf("unable to send to route for "+
"%s: %v", carol.Name(), err)
}
if resp.Failure != nil {
t.Fatalf("received payment error from %s: %v",
carol.Name(), resp.Failure)
}
}
}
for range rHashes {
resp, err := alicePayStream.Recv()
if err != nil {
t.Fatalf("unable to send payment: %v", err)
}
if resp.PaymentError != "" {
t.Fatalf("received payment error: %v", resp.PaymentError)
}
// Using Carol as the node as the source, send the payments
// synchronously via the the routerrpc's SendToRoute, or via the main RPC
// server's SendToRoute streaming or sync calls.
switch {
case !test.routerrpc && test.streaming:
sendToRouteStream()
case !test.routerrpc && !test.streaming:
sendToRouteSync()
case test.routerrpc && !test.streaming:
sendToRouteRouterRPC()
default:
t.Fatalf("routerrpc does not support streaming send_to_route")
}
req := &lnrpc.ListPaymentsRequest{}
// Verify that the payment's from Carol's PoV have the correct payment
// hash and amount.
ctxt, _ = context.WithTimeout(ctxt, defaultTimeout)
paymentsResp, err := net.Alice.ListPayments(ctxt, req)
paymentsResp, err := carol.ListPayments(
ctxt, &lnrpc.ListPaymentsRequest{},
)
if err != nil {
t.Fatalf("error when obtaining Alice payments: %v", err)
t.Fatalf("error when obtaining %s payments: %v",
carol.Name(), err)
}
if len(paymentsResp.Payments) != 5 {
if len(paymentsResp.Payments) != numPayments {
t.Fatalf("incorrect number of payments, got %v, want %v",
len(paymentsResp.Payments), 5)
len(paymentsResp.Payments), numPayments)
}
// Verify that the ListPayments displays the payment without an invoice
// since the payment was completed with SendToRoute.
for _, p := range paymentsResp.Payments {
for i, p := range paymentsResp.Payments {
// Assert that the payment hashes for each payment match up.
rHashHex := hex.EncodeToString(rHashes[i])
if p.PaymentHash != rHashHex {
t.Fatalf("incorrect payment hash for payment %d, "+
"want: %s got: %s",
i, rHashHex, p.PaymentHash)
}
// Assert that each payment has no invoice since the payment was
// completed using SendToRoute.
if p.PaymentRequest != "" {
t.Fatalf("incorrect payreq, want: \"\", got: %v",
p.PaymentRequest)
t.Fatalf("incorrect payment request for payment: %d, "+
"want: \"\", got: %s",
i, p.PaymentRequest)
}
// Assert the payment ammount is correct.
if p.ValueSat != paymentAmtSat {
t.Fatalf("incorrect payment amt for payment %d, "+
"want: %d, got: %d",
i, paymentAmtSat, p.ValueSat)
}
}
// Verify that the invoices's from Dave's PoV have the correct payment
// hash and amount.
ctxt, _ = context.WithTimeout(ctxt, defaultTimeout)
invoicesResp, err := dave.ListInvoices(
ctxt, &lnrpc.ListInvoiceRequest{},
)
if err != nil {
t.Fatalf("error when obtaining %s payments: %v",
dave.Name(), err)
}
if len(invoicesResp.Invoices) != numPayments {
t.Fatalf("incorrect number of invoices, got %v, want %v",
len(invoicesResp.Invoices), numPayments)
}
for i, inv := range invoicesResp.Invoices {
// Assert that the payment hashes match up.
if !bytes.Equal(inv.RHash, rHashes[i]) {
t.Fatalf("incorrect payment hash for invoice %d, "+
"want: %x got: %x",
i, rHashes[i], inv.RHash)
}
// Assert that the amount paid to the invoice is correct.
if inv.AmtPaidSat != paymentAmtSat {
t.Fatalf("incorrect payment amt for invoice %d, "+
"want: %d, got %d",
i, paymentAmtSat, inv.AmtPaidSat)
}
}
// At this point all the channels within our proto network should be
// shifted by 5k satoshis in the direction of Bob, the sink within the
// shifted by 5k satoshis in the direction of Dave, the sink within the
// payment flow generated above. The order of asserts corresponds to
// increasing of time is needed to embed the HTLC in commitment
// transaction, in channel Alice->Bob, order is Bob and then Alice.
const amountPaid = int64(5000)
assertAmountPaid(t, "Alice(local) => Bob(remote)", net.Bob,
aliceFundPoint, int64(0), amountPaid)
assertAmountPaid(t, "Alice(local) => Bob(remote)", net.Alice,
aliceFundPoint, amountPaid, int64(0))
// transaction, in channel Carol->Dave, order is Dave and then Carol.
assertAmountPaid(t, "Carol(local) => Dave(remote)", dave,
carolFundPoint, int64(0), amountPaid)
assertAmountPaid(t, "Carol(local) => Dave(remote)", carol,
carolFundPoint, amountPaid, int64(0))
ctxt, _ = context.WithTimeout(ctxb, channelCloseTimeout)
closeChannelAndAssert(ctxt, t, net, net.Alice, chanPointAlice, false)
closeChannelAndAssert(ctxt, t, net, carol, chanPointCarol, false)
}
// testMultiHopSendToRoute tests that payments are properly processed

98
record/mpp.go Normal file

@ -0,0 +1,98 @@
package record
import (
"io"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/tlv"
)
// MPPOnionType is the type used in the onion to reference the MPP fields:
// total_amt and payment_addr.
const MPPOnionType tlv.Type = 8
// MPP is a record that encodes the fields necessary for multi-path payments.
type MPP struct {
// paymentAddr is a random, receiver-generated value used to avoid
// collisions with concurrent payers.
paymentAddr [32]byte
// totalMsat is the total value of the payment, potentially spread
// across more than one HTLC.
totalMsat lnwire.MilliSatoshi
}
// NewMPP generates a new MPP record with the given total and payment address.
func NewMPP(total lnwire.MilliSatoshi, addr [32]byte) *MPP {
return &MPP{
paymentAddr: addr,
totalMsat: total,
}
}
// PaymentAddr returns the payment address contained in the MPP record.
func (r *MPP) PaymentAddr() [32]byte {
return r.paymentAddr
}
// TotalMsat returns the total value of an MPP payment in msats.
func (r *MPP) TotalMsat() lnwire.MilliSatoshi {
return r.totalMsat
}
// MPPEncoder writes the MPP record to the provided io.Writer.
func MPPEncoder(w io.Writer, val interface{}, buf *[8]byte) error {
if v, ok := val.(*MPP); ok {
err := tlv.EBytes32(w, &v.paymentAddr, buf)
if err != nil {
return err
}
return tlv.ETUint64T(w, uint64(v.totalMsat), buf)
}
return tlv.NewTypeForEncodingErr(val, "MPP")
}
const (
// minMPPLength is the minimum length of a serialized MPP TLV record,
// which occurs when the truncated encoding of total_amt_msat takes 0
// bytes, leaving only the payment_addr.
minMPPLength = 32
// maxMPPLength is the maximum length of a serialized MPP TLV record,
// which occurs when the truncated encoding of total_amt_msat takes 8
// bytes.
maxMPPLength = 40
)
// MPPDecoder reads the MPP record to the provided io.Reader.
func MPPDecoder(r io.Reader, val interface{}, buf *[8]byte, l uint64) error {
if v, ok := val.(*MPP); ok && minMPPLength <= l && l <= maxMPPLength {
if err := tlv.DBytes32(r, &v.paymentAddr, buf, 32); err != nil {
return err
}
var total uint64
if err := tlv.DTUint64(r, &total, buf, l-32); err != nil {
return err
}
v.totalMsat = lnwire.MilliSatoshi(total)
return nil
}
return tlv.NewTypeForDecodingErr(val, "MPP", l, maxMPPLength)
}
// Record returns a tlv.Record that can be used to encode or decode this record.
func (r *MPP) Record() tlv.Record {
// Fixed-size, 32 byte payment address followed by truncated 64-bit
// total msat.
size := func() uint64 {
return 32 + tlv.SizeTUint64(uint64(r.totalMsat))
}
return tlv.MakeDynamicRecord(
MPPOnionType, r, size, MPPEncoder, MPPDecoder,
)
}

73
record/record_test.go Normal file

@ -0,0 +1,73 @@
package record_test
import (
"bytes"
"testing"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/record"
"github.com/lightningnetwork/lnd/tlv"
)
type recordEncDecTest struct {
name string
encRecord func() tlv.RecordProducer
decRecord func() tlv.RecordProducer
assert func(*testing.T, interface{})
}
var (
testTotal = lnwire.MilliSatoshi(45)
testAddr = [32]byte{0x01, 0x02}
)
var recordEncDecTests = []recordEncDecTest{
{
name: "mpp",
encRecord: func() tlv.RecordProducer {
return record.NewMPP(testTotal, testAddr)
},
decRecord: func() tlv.RecordProducer {
return new(record.MPP)
},
assert: func(t *testing.T, r interface{}) {
mpp := r.(*record.MPP)
if mpp.TotalMsat() != testTotal {
t.Fatal("incorrect total msat")
}
if mpp.PaymentAddr() != testAddr {
t.Fatal("incorrect payment addr")
}
},
},
}
// TestRecordEncodeDecode is a generic test framework for custom TLV records. It
// asserts that records can encode and decode themselves, and that the value of
// the original record matches the decoded record.
func TestRecordEncodeDecode(t *testing.T) {
for _, test := range recordEncDecTests {
test := test
t.Run(test.name, func(t *testing.T) {
r := test.encRecord()
r2 := test.decRecord()
encStream := tlv.MustNewStream(r.Record())
decStream := tlv.MustNewStream(r2.Record())
test.assert(t, r)
var b bytes.Buffer
err := encStream.Encode(&b)
if err != nil {
t.Fatalf("unable to encode record: %v", err)
}
err = decStream.Decode(bytes.NewReader(b.Bytes()))
if err != nil {
t.Fatalf("unable to decode record: %v", err)
}
test.assert(t, r2)
})
}
}

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/binary"
"encoding/hex"
"errors"
"fmt"
"io"
"strconv"
@ -19,9 +20,17 @@ import (
// VertexSize is the size of the array to store a vertex.
const VertexSize = 33
// ErrNoRouteHopsProvided is returned when a caller attempts to construct a new
// sphinx packet, but provides an empty set of hops for each route.
var ErrNoRouteHopsProvided = fmt.Errorf("empty route hops provided")
var (
// ErrNoRouteHopsProvided is returned when a caller attempts to
// construct a new sphinx packet, but provides an empty set of hops for
// each route.
ErrNoRouteHopsProvided = fmt.Errorf("empty route hops provided")
// ErrIntermediateMPPHop is returned when a hop tries to deliver an MPP
// record to an intermediate hop, only final hops can receive MPP
// records.
ErrIntermediateMPPHop = errors.New("cannot send MPP to intermediate")
)
// Vertex is a simple alias for the serialization of a compressed Bitcoin
// public key.
@ -94,6 +103,10 @@ type Hop struct {
// carries as a fee will be subtracted by the hop.
AmtToForward lnwire.MilliSatoshi
// MPP encapsulates the data required for option_mpp. This field should
// only be set for the final hop.
MPP *record.MPP
// TLVRecords if non-nil are a set of additional TLV records that
// should be included in the forwarding instructions for this node.
TLVRecords []tlv.Record
@ -140,6 +153,17 @@ func (h *Hop) PackHopPayload(w io.Writer, nextChanID uint64) error {
)
}
// If an MPP record is destined for this hop, ensure that we only ever
// attach it to the final hop. Otherwise the route was constructed
// incorrectly.
if h.MPP != nil {
if nextChanID == 0 {
records = append(records, h.MPP.Record())
} else {
return ErrIntermediateMPPHop
}
}
// Append any custom types destined for this hop.
records = append(records, h.TLVRecords...)

@ -1,9 +1,11 @@
package route
import (
"bytes"
"testing"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/record"
)
// TestRouteTotalFees checks that a route reports the expected total fee.
@ -56,3 +58,38 @@ func TestRouteTotalFees(t *testing.T) {
}
}
var (
testAmt = lnwire.MilliSatoshi(1000)
testAddr = [32]byte{0x01, 0x02}
)
// TestMPPHop asserts that a Hop will encode a non-nil to final nodes, and fail
// when trying to send to intermediaries.
func TestMPPHop(t *testing.T) {
t.Parallel()
hop := Hop{
ChannelID: 1,
OutgoingTimeLock: 44,
AmtToForward: testAmt,
LegacyPayload: false,
MPP: record.NewMPP(testAmt, testAddr),
}
// Encoding an MPP record to an intermediate hop should result in a
// failure.
var b bytes.Buffer
err := hop.PackHopPayload(&b, 2)
if err != ErrIntermediateMPPHop {
t.Fatalf("expected err: %v, got: %v",
ErrIntermediateMPPHop, err)
}
// Encoding an MPP record to a final hop should be successful.
b.Reset()
err = hop.PackHopPayload(&b, 0)
if err != nil {
t.Fatalf("expected err: %v, got: %v", nil, err)
}
}

@ -43,6 +43,14 @@ func SizeVarBytes(e *[]byte) SizeFunc {
}
}
// RecorderProducer is an interface for objects that can produce a Record object
// capable of encoding and/or decoding the RecordProducer as a Record.
type RecordProducer interface {
// Record returns a Record that can be used to encode or decode the
// backing object.
Record() Record
}
// Record holds the required information to encode or decode a TLV record.
type Record struct {
value interface{}
@ -77,6 +85,14 @@ func (f *Record) Encode(w io.Writer) error {
return f.encoder(w, f.value, &b)
}
// Decode read in the TLV record from the passed reader. This is useful when a
// caller wants decode a *single* TLV record, outside the context of the Stream
// struct.
func (f *Record) Decode(r io.Reader, l uint64) error {
var b [8]byte
return f.decoder(r, f.value, &b, l)
}
// MakePrimitiveRecord creates a record for common types.
func MakePrimitiveRecord(typ Type, val interface{}) Record {
var (

@ -40,6 +40,15 @@ func ETUint16(w io.Writer, val interface{}, buf *[8]byte) error {
return NewTypeForEncodingErr(val, "uint16")
}
// ETUint16T is an Encoder for truncated uint16 values, where leading zeros will
// be omitted. An error is returned if val is not a *uint16.
func ETUint16T(w io.Writer, val uint16, buf *[8]byte) error {
binary.BigEndian.PutUint16(buf[:2], val)
numZeros := numLeadingZeroBytes16(val)
_, err := w.Write(buf[numZeros:2])
return err
}
// DTUint16 is an Decoder for truncated uint16 values, where leading zeros will
// be resurrected. An error is returned if val is not a *uint16.
func DTUint16(r io.Reader, val interface{}, buf *[8]byte, l uint64) error {
@ -92,6 +101,15 @@ func ETUint32(w io.Writer, val interface{}, buf *[8]byte) error {
return NewTypeForEncodingErr(val, "uint32")
}
// ETUint32T is an Encoder for truncated uint32 values, where leading zeros will
// be omitted. An error is returned if val is not a *uint32.
func ETUint32T(w io.Writer, val uint32, buf *[8]byte) error {
binary.BigEndian.PutUint32(buf[:4], val)
numZeros := numLeadingZeroBytes32(val)
_, err := w.Write(buf[numZeros:4])
return err
}
// DTUint32 is an Decoder for truncated uint32 values, where leading zeros will
// be resurrected. An error is returned if val is not a *uint32.
func DTUint32(r io.Reader, val interface{}, buf *[8]byte, l uint64) error {
@ -154,6 +172,15 @@ func ETUint64(w io.Writer, val interface{}, buf *[8]byte) error {
return NewTypeForEncodingErr(val, "uint64")
}
// ETUint64T is an Encoder for truncated uint64 values, where leading zeros will
// be omitted. An error is returned if val is not a *uint64.
func ETUint64T(w io.Writer, val uint64, buf *[8]byte) error {
binary.BigEndian.PutUint64(buf[:], val)
numZeros := numLeadingZeroBytes64(val)
_, err := w.Write(buf[numZeros:])
return err
}
// DTUint64 is an Decoder for truncated uint64 values, where leading zeros will
// be resurrected. An error is returned if val is not a *uint64.
func DTUint64(r io.Reader, val interface{}, buf *[8]byte, l uint64) error {

@ -60,6 +60,8 @@ func TestSizeTUint16(t *testing.T) {
func TestTUint16(t *testing.T) {
var buf [8]byte
for _, test := range tuint16Tests {
test := test
if len(test.bytes) != int(test.size) {
t.Fatalf("invalid test case, "+
"len(bytes)[%d] != size[%d]",
@ -68,6 +70,7 @@ func TestTUint16(t *testing.T) {
name := fmt.Sprintf("0x%x", test.value)
t.Run(name, func(t *testing.T) {
// Test generic encoder.
var b bytes.Buffer
err := tlv.ETUint16(&b, &test.value, &buf)
if err != nil {
@ -80,6 +83,19 @@ func TestTUint16(t *testing.T) {
test.bytes, b.Bytes())
}
// Test non-generic encoder.
var b2 bytes.Buffer
err = tlv.ETUint16T(&b2, test.value, &buf)
if err != nil {
t.Fatalf("unable to encode tuint16: %v", err)
}
if !bytes.Equal(b2.Bytes(), test.bytes) {
t.Fatalf("encoding mismatch, "+
"expected: %x, got: %x",
test.bytes, b2.Bytes())
}
var value uint16
r := bytes.NewReader(b.Bytes())
err = tlv.DTUint16(r, &value, &buf, test.size)
@ -168,6 +184,8 @@ func TestSizeTUint32(t *testing.T) {
func TestTUint32(t *testing.T) {
var buf [8]byte
for _, test := range tuint32Tests {
test := test
if len(test.bytes) != int(test.size) {
t.Fatalf("invalid test case, "+
"len(bytes)[%d] != size[%d]",
@ -176,6 +194,7 @@ func TestTUint32(t *testing.T) {
name := fmt.Sprintf("0x%x", test.value)
t.Run(name, func(t *testing.T) {
// Test generic encoder.
var b bytes.Buffer
err := tlv.ETUint32(&b, &test.value, &buf)
if err != nil {
@ -188,6 +207,19 @@ func TestTUint32(t *testing.T) {
test.bytes, b.Bytes())
}
// Test non-generic encoder.
var b2 bytes.Buffer
err = tlv.ETUint32T(&b2, test.value, &buf)
if err != nil {
t.Fatalf("unable to encode tuint32: %v", err)
}
if !bytes.Equal(b2.Bytes(), test.bytes) {
t.Fatalf("encoding mismatch, "+
"expected: %x, got: %x",
test.bytes, b2.Bytes())
}
var value uint32
r := bytes.NewReader(b.Bytes())
err = tlv.DTUint32(r, &value, &buf, test.size)
@ -322,6 +354,8 @@ func TestSizeTUint64(t *testing.T) {
func TestTUint64(t *testing.T) {
var buf [8]byte
for _, test := range tuint64Tests {
test := test
if len(test.bytes) != int(test.size) {
t.Fatalf("invalid test case, "+
"len(bytes)[%d] != size[%d]",
@ -330,6 +364,7 @@ func TestTUint64(t *testing.T) {
name := fmt.Sprintf("0x%x", test.value)
t.Run(name, func(t *testing.T) {
// Test generic encoder.
var b bytes.Buffer
err := tlv.ETUint64(&b, &test.value, &buf)
if err != nil {
@ -342,6 +377,19 @@ func TestTUint64(t *testing.T) {
test.bytes, b.Bytes())
}
// Test non-generic encoder.
var b2 bytes.Buffer
err = tlv.ETUint64T(&b2, test.value, &buf)
if err != nil {
t.Fatalf("unable to encode tuint64: %v", err)
}
if !bytes.Equal(b2.Bytes(), test.bytes) {
t.Fatalf("encoding mismatch, "+
"expected: %x, got: %x",
test.bytes, b2.Bytes())
}
var value uint64
r := bytes.NewReader(b.Bytes())
err = tlv.DTUint64(r, &value, &buf, test.size)