Merge pull request #5108 from cfromknecht/sendtoroute-amp

channeldb+invoices: add spontaneous AMP receiving + sending via SendToRoute
This commit is contained in:
Olaoluwa Osuntokun 2021-04-07 16:37:23 -07:00 committed by GitHub
commit c998264578
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 3186 additions and 1182 deletions

View File

@ -8,6 +8,7 @@ import (
"time" "time"
"github.com/lightningnetwork/lnd/clock" "github.com/lightningnetwork/lnd/clock"
"github.com/lightningnetwork/lnd/feature"
"github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/record" "github.com/lightningnetwork/lnd/record"
@ -16,7 +17,15 @@ import (
var ( var (
emptyFeatures = lnwire.NewFeatureVector(nil, lnwire.Features) emptyFeatures = lnwire.NewFeatureVector(nil, lnwire.Features)
testNow = time.Unix(1, 0) ampFeatures = lnwire.NewFeatureVector(
lnwire.NewRawFeatureVector(
lnwire.TLVOnionPayloadOptional,
lnwire.PaymentAddrOptional,
lnwire.AMPRequired,
),
lnwire.Features,
)
testNow = time.Unix(1, 0)
) )
func randInvoice(value lnwire.MilliSatoshi) (*Invoice, error) { func randInvoice(value lnwire.MilliSatoshi) (*Invoice, error) {
@ -1208,23 +1217,30 @@ func TestInvoiceRef(t *testing.T) {
// An InvoiceRef by hash should return the provided hash and a nil // An InvoiceRef by hash should return the provided hash and a nil
// payment addr. // payment addr.
refByHash := InvoiceRefByHash(payHash) refByHash := InvoiceRefByHash(payHash)
require.Equal(t, payHash, refByHash.PayHash()) require.Equal(t, &payHash, refByHash.PayHash())
require.Equal(t, (*[32]byte)(nil), refByHash.PayAddr()) require.Equal(t, (*[32]byte)(nil), refByHash.PayAddr())
require.Equal(t, (*[32]byte)(nil), refByHash.SetID()) require.Equal(t, (*[32]byte)(nil), refByHash.SetID())
// An InvoiceRef by hash and addr should return the payment hash and // An InvoiceRef by hash and addr should return the payment hash and
// payment addr passed to the constructor. // payment addr passed to the constructor.
refByHashAndAddr := InvoiceRefByHashAndAddr(payHash, payAddr) refByHashAndAddr := InvoiceRefByHashAndAddr(payHash, payAddr)
require.Equal(t, payHash, refByHashAndAddr.PayHash()) require.Equal(t, &payHash, refByHashAndAddr.PayHash())
require.Equal(t, &payAddr, refByHashAndAddr.PayAddr()) require.Equal(t, &payAddr, refByHashAndAddr.PayAddr())
require.Equal(t, (*[32]byte)(nil), refByHashAndAddr.SetID()) require.Equal(t, (*[32]byte)(nil), refByHashAndAddr.SetID())
// An InvoiceRef by set id should return an empty pay hash, a nil pay // An InvoiceRef by set id should return an empty pay hash, a nil pay
// addr, and a reference to the given set id. // addr, and a reference to the given set id.
refBySetID := InvoiceRefBySetID(setID) refBySetID := InvoiceRefBySetID(setID)
require.Equal(t, lntypes.Hash{}, refBySetID.PayHash()) require.Equal(t, (*lntypes.Hash)(nil), refBySetID.PayHash())
require.Equal(t, (*[32]byte)(nil), refBySetID.PayAddr()) require.Equal(t, (*[32]byte)(nil), refBySetID.PayAddr())
require.Equal(t, &setID, refBySetID.SetID()) require.Equal(t, &setID, refBySetID.SetID())
// An InvoiceRef by pay addr should only return a pay addr, but nil for
// pay hash and set id.
refByAddr := InvoiceRefByAddr(payAddr)
require.Equal(t, (*lntypes.Hash)(nil), refByAddr.PayHash())
require.Equal(t, &payAddr, refByAddr.PayAddr())
require.Equal(t, (*[32]byte)(nil), refByAddr.SetID())
} }
// TestHTLCSet asserts that HTLCSet returns the proper set of accepted HTLCs // TestHTLCSet asserts that HTLCSet returns the proper set of accepted HTLCs
@ -1366,7 +1382,7 @@ func TestSetIDIndex(t *testing.T) {
invoice.AmtPaid = amt invoice.AmtPaid = amt
invoice.SettleDate = dbInvoice.SettleDate invoice.SettleDate = dbInvoice.SettleDate
invoice.Htlcs = map[CircuitKey]*InvoiceHTLC{ invoice.Htlcs = map[CircuitKey]*InvoiceHTLC{
{HtlcID: 0}: makeAMPInvoiceHTLC(amt, *setID, preimage), {HtlcID: 0}: makeAMPInvoiceHTLC(amt, *setID, payHash, &preimage),
} }
// We should get back the exact same invoice that we just inserted. // We should get back the exact same invoice that we just inserted.
@ -1406,9 +1422,9 @@ func TestSetIDIndex(t *testing.T) {
invoice.AmtPaid += 2 * amt invoice.AmtPaid += 2 * amt
invoice.SettleDate = dbInvoice.SettleDate invoice.SettleDate = dbInvoice.SettleDate
invoice.Htlcs = map[CircuitKey]*InvoiceHTLC{ invoice.Htlcs = map[CircuitKey]*InvoiceHTLC{
{HtlcID: 0}: makeAMPInvoiceHTLC(amt, *setID, preimage), {HtlcID: 0}: makeAMPInvoiceHTLC(amt, *setID, payHash, &preimage),
{HtlcID: 1}: makeAMPInvoiceHTLC(amt, *setID2, preimage), {HtlcID: 1}: makeAMPInvoiceHTLC(amt, *setID2, payHash, nil),
{HtlcID: 2}: makeAMPInvoiceHTLC(amt, *setID2, preimage), {HtlcID: 2}: makeAMPInvoiceHTLC(amt, *setID2, payHash, nil),
} }
// We should get back the exact same invoice that we just inserted. // We should get back the exact same invoice that we just inserted.
@ -1452,7 +1468,7 @@ func TestSetIDIndex(t *testing.T) {
} }
func makeAMPInvoiceHTLC(amt lnwire.MilliSatoshi, setID [32]byte, func makeAMPInvoiceHTLC(amt lnwire.MilliSatoshi, setID [32]byte,
preimage lntypes.Preimage) *InvoiceHTLC { hash lntypes.Hash, preimage *lntypes.Preimage) *InvoiceHTLC {
return &InvoiceHTLC{ return &InvoiceHTLC{
Amt: amt, Amt: amt,
@ -1462,8 +1478,8 @@ func makeAMPInvoiceHTLC(amt lnwire.MilliSatoshi, setID [32]byte,
CustomRecords: make(record.CustomSet), CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{ AMP: &InvoiceHtlcAMPData{
Record: *record.NewAMP([32]byte{}, setID, 0), Record: *record.NewAMP([32]byte{}, setID, 0),
Hash: preimage.Hash(), Hash: hash,
Preimage: &preimage, Preimage: preimage,
}, },
} }
} }
@ -1480,18 +1496,23 @@ func updateAcceptAMPHtlc(id uint64, amt lnwire.MilliSatoshi,
noRecords := make(record.CustomSet) noRecords := make(record.CustomSet)
var state *InvoiceStateUpdateDesc var (
state *InvoiceStateUpdateDesc
preimage *lntypes.Preimage
)
if accept { if accept {
state = &InvoiceStateUpdateDesc{ state = &InvoiceStateUpdateDesc{
NewState: ContractAccepted, NewState: ContractAccepted,
SetID: setID, SetID: setID,
} }
pre := *invoice.Terms.PaymentPreimage
preimage = &pre
} }
ampData := &InvoiceHtlcAMPData{ ampData := &InvoiceHtlcAMPData{
Record: *record.NewAMP([32]byte{}, *setID, 0), Record: *record.NewAMP([32]byte{}, *setID, 0),
Hash: invoice.Terms.PaymentPreimage.Hash(), Hash: invoice.Terms.PaymentPreimage.Hash(),
Preimage: invoice.Terms.PaymentPreimage, Preimage: preimage,
} }
update := &InvoiceUpdateDesc{ update := &InvoiceUpdateDesc{
State: state, State: state,
@ -1526,6 +1547,792 @@ func getUpdateInvoiceAMPSettle(setID *[32]byte) InvoiceUpdateCallback {
} }
} }
// TestUnexpectedInvoicePreimage asserts that legacy or MPP invoices cannot be
// settled when referenced by payment address only. Since regular or MPP
// payments do not store the payment hash explicitly (it is stored in the
// index), this enforces that they can only be updated using a InvoiceRefByHash
// or InvoiceRefByHashOrAddr.
func TestUnexpectedInvoicePreimage(t *testing.T) {
t.Parallel()
db, cleanup, err := MakeTestDB()
defer cleanup()
require.NoError(t, err, "unable to make test db")
invoice, err := randInvoice(lnwire.MilliSatoshi(100))
require.NoError(t, err)
// Add a random invoice indexed by payment hash and payment addr.
paymentHash := invoice.Terms.PaymentPreimage.Hash()
_, err = db.AddInvoice(invoice, paymentHash)
require.NoError(t, err)
// Attempt to update the invoice by pay addr only. This will fail since,
// in order to settle an MPP invoice, the InvoiceRef must present a
// payment hash against which to validate the preimage.
_, err = db.UpdateInvoice(
InvoiceRefByAddr(invoice.Terms.PaymentAddr),
getUpdateInvoice(invoice.Terms.Value),
)
//Assert that we get ErrUnexpectedInvoicePreimage.
require.Error(t, ErrUnexpectedInvoicePreimage, err)
}
type updateHTLCPreimageTestCase struct {
name string
settleSamePreimage bool
expError error
}
// TestUpdateHTLCPreimages asserts various properties of setting HTLC-level
// preimages on invoice state transitions.
func TestUpdateHTLCPreimages(t *testing.T) {
t.Parallel()
tests := []updateHTLCPreimageTestCase{
{
name: "same preimage on settle",
settleSamePreimage: true,
expError: nil,
},
{
name: "diff preimage on settle",
settleSamePreimage: false,
expError: ErrHTLCPreimageAlreadyExists,
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
testUpdateHTLCPreimages(t, test)
})
}
}
func testUpdateHTLCPreimages(t *testing.T, test updateHTLCPreimageTestCase) {
db, cleanup, err := MakeTestDB()
defer cleanup()
require.NoError(t, err, "unable to make test db")
// We'll start out by creating an invoice and writing it to the DB.
amt := lnwire.NewMSatFromSatoshis(1000)
invoice, err := randInvoice(amt)
require.Nil(t, err)
preimage := *invoice.Terms.PaymentPreimage
payHash := preimage.Hash()
// Set AMP-specific features so that we can settle with HTLC-level
// preimages.
invoice.Terms.Features = ampFeatures
_, err = db.AddInvoice(invoice, payHash)
require.Nil(t, err)
setID := &[32]byte{1}
// Update the invoice with an accepted HTLC that also accepts the
// invoice.
ref := InvoiceRefByAddr(invoice.Terms.PaymentAddr)
dbInvoice, err := db.UpdateInvoice(ref, updateAcceptAMPHtlc(0, amt, setID, true))
require.Nil(t, err)
htlcPreimages := make(map[CircuitKey]lntypes.Preimage)
for key := range dbInvoice.Htlcs {
// Set the either the same preimage used to accept above, or a
// blank preimage depending on the test case.
var pre lntypes.Preimage
if test.settleSamePreimage {
pre = preimage
}
htlcPreimages[key] = pre
}
updateInvoice := func(invoice *Invoice) (*InvoiceUpdateDesc, error) {
update := &InvoiceUpdateDesc{
State: &InvoiceStateUpdateDesc{
Preimage: nil,
NewState: ContractSettled,
HTLCPreimages: htlcPreimages,
SetID: setID,
},
}
return update, nil
}
// Now settle the HTLC set and assert the resulting error.
_, err = db.UpdateInvoice(ref, updateInvoice)
require.Equal(t, test.expError, err)
}
type updateHTLCTest struct {
name string
input InvoiceHTLC
invState ContractState
setID *[32]byte
output InvoiceHTLC
expErr error
}
// TestUpdateHTLC asserts the behavior of the updateHTLC method in various
// scenarios for MPP and AMP.
func TestUpdateHTLC(t *testing.T) {
t.Parallel()
setID := [32]byte{0x01}
ampRecord := record.NewAMP([32]byte{0x02}, setID, 3)
preimage := lntypes.Preimage{0x04}
hash := preimage.Hash()
diffSetID := [32]byte{0x05}
fakePreimage := lntypes.Preimage{0x06}
testAlreadyNow := time.Now()
tests := []updateHTLCTest{
{
name: "MPP accept",
input: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: time.Time{},
Expiry: 40,
State: HtlcStateAccepted,
CustomRecords: make(record.CustomSet),
AMP: nil,
},
invState: ContractAccepted,
setID: nil,
output: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: time.Time{},
Expiry: 40,
State: HtlcStateAccepted,
CustomRecords: make(record.CustomSet),
AMP: nil,
},
expErr: nil,
},
{
name: "MPP settle",
input: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: time.Time{},
Expiry: 40,
State: HtlcStateAccepted,
CustomRecords: make(record.CustomSet),
AMP: nil,
},
invState: ContractSettled,
setID: nil,
output: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: testNow,
Expiry: 40,
State: HtlcStateSettled,
CustomRecords: make(record.CustomSet),
AMP: nil,
},
expErr: nil,
},
{
name: "MPP cancel",
input: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: time.Time{},
Expiry: 40,
State: HtlcStateAccepted,
CustomRecords: make(record.CustomSet),
AMP: nil,
},
invState: ContractCanceled,
setID: nil,
output: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: testNow,
Expiry: 40,
State: HtlcStateCanceled,
CustomRecords: make(record.CustomSet),
AMP: nil,
},
expErr: nil,
},
{
name: "AMP accept missing preimage",
input: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: time.Time{},
Expiry: 40,
State: HtlcStateAccepted,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: nil,
},
},
invState: ContractAccepted,
setID: &setID,
output: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: time.Time{},
Expiry: 40,
State: HtlcStateAccepted,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: nil,
},
},
expErr: ErrHTLCPreimageMissing,
},
{
name: "AMP accept invalid preimage",
input: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: time.Time{},
Expiry: 40,
State: HtlcStateAccepted,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &fakePreimage,
},
},
invState: ContractAccepted,
setID: &setID,
output: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: time.Time{},
Expiry: 40,
State: HtlcStateAccepted,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &fakePreimage,
},
},
expErr: ErrHTLCPreimageMismatch,
},
{
name: "AMP accept valid preimage",
input: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: time.Time{},
Expiry: 40,
State: HtlcStateAccepted,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
invState: ContractAccepted,
setID: &setID,
output: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: time.Time{},
Expiry: 40,
State: HtlcStateAccepted,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
expErr: nil,
},
{
name: "AMP accept valid preimage different htlc set",
input: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: time.Time{},
Expiry: 40,
State: HtlcStateAccepted,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
invState: ContractAccepted,
setID: &diffSetID,
output: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: time.Time{},
Expiry: 40,
State: HtlcStateAccepted,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
expErr: nil,
},
{
name: "AMP settle missing preimage",
input: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: time.Time{},
Expiry: 40,
State: HtlcStateAccepted,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: nil,
},
},
invState: ContractSettled,
setID: &setID,
output: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: time.Time{},
Expiry: 40,
State: HtlcStateAccepted,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: nil,
},
},
expErr: ErrHTLCPreimageMissing,
},
{
name: "AMP settle invalid preimage",
input: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: time.Time{},
Expiry: 40,
State: HtlcStateAccepted,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &fakePreimage,
},
},
invState: ContractSettled,
setID: &setID,
output: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: time.Time{},
Expiry: 40,
State: HtlcStateAccepted,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &fakePreimage,
},
},
expErr: ErrHTLCPreimageMismatch,
},
{
name: "AMP settle valid preimage",
input: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: time.Time{},
Expiry: 40,
State: HtlcStateAccepted,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
invState: ContractSettled,
setID: &setID,
output: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: testNow,
Expiry: 40,
State: HtlcStateSettled,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
expErr: nil,
},
{
name: "AMP settle valid preimage different htlc set",
input: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: time.Time{},
Expiry: 40,
State: HtlcStateAccepted,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
invState: ContractSettled,
setID: &diffSetID,
output: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: testNow,
Expiry: 40,
State: HtlcStateCanceled,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
expErr: nil,
},
{
name: "accept invoice htlc already settled",
input: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: testAlreadyNow,
Expiry: 40,
State: HtlcStateSettled,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
invState: ContractAccepted,
setID: &setID,
output: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: testAlreadyNow,
Expiry: 40,
State: HtlcStateSettled,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
expErr: ErrHTLCAlreadySettled,
},
{
name: "cancel invoice htlc already settled",
input: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: testAlreadyNow,
Expiry: 40,
State: HtlcStateSettled,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
invState: ContractCanceled,
setID: &setID,
output: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: testAlreadyNow,
Expiry: 40,
State: HtlcStateSettled,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
expErr: ErrHTLCAlreadySettled,
},
{
name: "settle invoice htlc already settled",
input: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: testAlreadyNow,
Expiry: 40,
State: HtlcStateSettled,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
invState: ContractSettled,
setID: &setID,
output: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: testAlreadyNow,
Expiry: 40,
State: HtlcStateSettled,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
expErr: nil,
},
{
name: "cancel invoice",
input: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: time.Time{},
Expiry: 40,
State: HtlcStateAccepted,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
invState: ContractCanceled,
setID: &setID,
output: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: testNow,
Expiry: 40,
State: HtlcStateCanceled,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
expErr: nil,
},
{
name: "accept invoice htlc already canceled",
input: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: testAlreadyNow,
Expiry: 40,
State: HtlcStateCanceled,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
invState: ContractAccepted,
setID: &setID,
output: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: testAlreadyNow,
Expiry: 40,
State: HtlcStateCanceled,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
expErr: nil,
},
{
name: "cancel invoice htlc already canceled",
input: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: testAlreadyNow,
Expiry: 40,
State: HtlcStateCanceled,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
invState: ContractCanceled,
setID: &setID,
output: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: testAlreadyNow,
Expiry: 40,
State: HtlcStateCanceled,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
expErr: nil,
},
{
name: "settle invoice htlc already canceled",
input: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: testAlreadyNow,
Expiry: 40,
State: HtlcStateCanceled,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
invState: ContractSettled,
setID: &setID,
output: InvoiceHTLC{
Amt: 5000,
MppTotalAmt: 5000,
AcceptHeight: 100,
AcceptTime: testNow,
ResolveTime: testAlreadyNow,
Expiry: 40,
State: HtlcStateCanceled,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *ampRecord,
Hash: hash,
Preimage: &preimage,
},
},
expErr: nil,
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
testUpdateHTLC(t, test)
})
}
}
func testUpdateHTLC(t *testing.T, test updateHTLCTest) {
htlc := test.input.Copy()
err := updateHtlc(testNow, htlc, test.invState, test.setID)
require.Equal(t, test.expErr, err)
require.Equal(t, test.output, *htlc)
}
// TestDeleteInvoices tests that deleting a list of invoices will succeed // TestDeleteInvoices tests that deleting a list of invoices will succeed
// if all delete references are valid, or will fail otherwise. // if all delete references are valid, or will fail otherwise.
func TestDeleteInvoices(t *testing.T) { func TestDeleteInvoices(t *testing.T) {
@ -1619,3 +2426,30 @@ func TestDeleteInvoices(t *testing.T) {
assertInvoiceCount(0) assertInvoiceCount(0)
} }
// TestAddInvoiceInvalidFeatureDeps asserts that inserting an invoice with
// invalid transitive feature dependencies fails with the appropriate error.
func TestAddInvoiceInvalidFeatureDeps(t *testing.T) {
t.Parallel()
db, cleanup, err := MakeTestDB()
require.NoError(t, err, "unable to make test db")
defer cleanup()
invoice, err := randInvoice(500)
require.NoError(t, err)
invoice.Terms.Features = lnwire.NewFeatureVector(
lnwire.NewRawFeatureVector(
lnwire.TLVOnionPayloadOptional,
lnwire.MPPOptional,
),
lnwire.Features,
)
hash := invoice.Terms.PaymentPreimage.Hash()
_, err = db.AddInvoice(invoice, hash)
require.Error(t, err, feature.NewErrMissingFeatureDep(
lnwire.PaymentAddrOptional,
))
}

View File

@ -6,9 +6,11 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"strings"
"time" "time"
"github.com/lightningnetwork/lnd/channeldb/kvdb" "github.com/lightningnetwork/lnd/channeldb/kvdb"
"github.com/lightningnetwork/lnd/feature"
"github.com/lightningnetwork/lnd/htlcswitch/hop" "github.com/lightningnetwork/lnd/htlcswitch/hop"
"github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
@ -115,6 +117,19 @@ var (
// match the invoice hash. // match the invoice hash.
ErrInvoicePreimageMismatch = errors.New("preimage does not match") ErrInvoicePreimageMismatch = errors.New("preimage does not match")
// ErrHTLCPreimageMissing is returned when trying to accept/settle an
// AMP HTLC but the HTLC-level preimage has not been set.
ErrHTLCPreimageMissing = errors.New("AMP htlc missing preimage")
// ErrHTLCPreimageMismatch is returned when trying to accept/settle an
// AMP HTLC but the HTLC-level preimage does not satisfying the
// HTLC-level payment hash.
ErrHTLCPreimageMismatch = errors.New("htlc preimage mismatch")
// ErrHTLCAlreadySettled is returned when trying to settle an invoice
// but HTLC already exists in the settled state.
ErrHTLCAlreadySettled = errors.New("htlc already settled")
// ErrInvoiceHasHtlcs is returned when attempting to insert an invoice // ErrInvoiceHasHtlcs is returned when attempting to insert an invoice
// that already has HTLCs. // that already has HTLCs.
ErrInvoiceHasHtlcs = errors.New("cannot add invoice with htlcs") ErrInvoiceHasHtlcs = errors.New("cannot add invoice with htlcs")
@ -122,6 +137,19 @@ var (
// ErrEmptyHTLCSet is returned when attempting to accept or settle and // ErrEmptyHTLCSet is returned when attempting to accept or settle and
// HTLC set that has no HTLCs. // HTLC set that has no HTLCs.
ErrEmptyHTLCSet = errors.New("cannot settle/accept empty HTLC set") ErrEmptyHTLCSet = errors.New("cannot settle/accept empty HTLC set")
// ErrUnexpectedInvoicePreimage is returned when an invoice-level
// preimage is provided when trying to settle an invoice that shouldn't
// have one, e.g. an AMP invoice.
ErrUnexpectedInvoicePreimage = errors.New(
"unexpected invoice preimage provided on settle",
)
// ErrHTLCPreimageAlreadyExists is returned when trying to set an
// htlc-level preimage but one is already known.
ErrHTLCPreimageAlreadyExists = errors.New(
"htlc-level preimage already exists",
)
) )
// ErrDuplicateSetID is an error returned when attempting to adding an AMP HTLC // ErrDuplicateSetID is an error returned when attempting to adding an AMP HTLC
@ -198,7 +226,7 @@ type InvoiceRef struct {
// payHash is the payment hash of the target invoice. All invoices are // payHash is the payment hash of the target invoice. All invoices are
// currently indexed by payment hash. This value will be used as a // currently indexed by payment hash. This value will be used as a
// fallback when no payment address is known. // fallback when no payment address is known.
payHash lntypes.Hash payHash *lntypes.Hash
// payAddr is the payment addr of the target invoice. Newer invoices // payAddr is the payment addr of the target invoice. Newer invoices
// (0.11 and up) are indexed by payment address in addition to payment // (0.11 and up) are indexed by payment address in addition to payment
@ -220,7 +248,7 @@ type InvoiceRef struct {
// its payment hash. // its payment hash.
func InvoiceRefByHash(payHash lntypes.Hash) InvoiceRef { func InvoiceRefByHash(payHash lntypes.Hash) InvoiceRef {
return InvoiceRef{ return InvoiceRef{
payHash: payHash, payHash: &payHash,
} }
} }
@ -231,11 +259,19 @@ func InvoiceRefByHashAndAddr(payHash lntypes.Hash,
payAddr [32]byte) InvoiceRef { payAddr [32]byte) InvoiceRef {
return InvoiceRef{ return InvoiceRef{
payHash: payHash, payHash: &payHash,
payAddr: &payAddr, payAddr: &payAddr,
} }
} }
// InvoiceRefByAddr creates an InvoiceRef that queries the payment addr index
// for an invoice with the provided payment address.
func InvoiceRefByAddr(addr [32]byte) InvoiceRef {
return InvoiceRef{
payAddr: &addr,
}
}
// InvoiceRefBySetID creates an InvoiceRef that queries the set id index for an // InvoiceRefBySetID creates an InvoiceRef that queries the set id index for an
// invoice with the provided setID. If the invoice is not found, the query will // invoice with the provided setID. If the invoice is not found, the query will
// not fallback to payHash or payAddr. // not fallback to payHash or payAddr.
@ -245,9 +281,15 @@ func InvoiceRefBySetID(setID [32]byte) InvoiceRef {
} }
} }
// PayHash returns the target invoice's payment hash. // PayHash returns the optional payment hash of the target invoice.
func (r InvoiceRef) PayHash() lntypes.Hash { //
return r.payHash // NOTE: This value may be nil.
func (r InvoiceRef) PayHash() *lntypes.Hash {
if r.payHash != nil {
hash := *r.payHash
return &hash
}
return nil
} }
// PayAddr returns the optional payment address of the target invoice. // PayAddr returns the optional payment address of the target invoice.
@ -274,10 +316,17 @@ func (r InvoiceRef) SetID() *[32]byte {
// String returns a human-readable representation of an InvoiceRef. // String returns a human-readable representation of an InvoiceRef.
func (r InvoiceRef) String() string { func (r InvoiceRef) String() string {
if r.payAddr != nil { var ids []string
return fmt.Sprintf("(pay_hash=%v, pay_addr=%x)", r.payHash, *r.payAddr) if r.payHash != nil {
ids = append(ids, fmt.Sprintf("pay_hash=%v", *r.payHash))
} }
return fmt.Sprintf("(pay_hash=%v)", r.payHash) if r.payAddr != nil {
ids = append(ids, fmt.Sprintf("pay_addr=%x", *r.payAddr))
}
if r.setID != nil {
ids = append(ids, fmt.Sprintf("set_id=%x", *r.setID))
}
return fmt.Sprintf("(%s)", strings.Join(ids, ", "))
} }
// ContractState describes the state the invoice is in. // ContractState describes the state the invoice is in.
@ -499,6 +548,21 @@ type InvoiceHTLC struct {
AMP *InvoiceHtlcAMPData AMP *InvoiceHtlcAMPData
} }
// Copy makes a deep copy of the target InvoiceHTLC.
func (h *InvoiceHTLC) Copy() *InvoiceHTLC {
result := *h
// Make a copy of the CustomSet map.
result.CustomRecords = make(record.CustomSet)
for k, v := range h.CustomRecords {
result.CustomRecords[k] = v
}
result.AMP = h.AMP.Copy()
return &result
}
// IsInHTLCSet returns true if this HTLC is part an HTLC set. If nil is passed, // IsInHTLCSet returns true if this HTLC is part an HTLC set. If nil is passed,
// this method returns true if this is an MPP HTLC. Otherwise, it only returns // this method returns true if this is an MPP HTLC. Otherwise, it only returns
// true if the AMP HTLC's set id matches the populated setID. // true if the AMP HTLC's set id matches the populated setID.
@ -616,6 +680,11 @@ type InvoiceStateUpdateDesc struct {
// Preimage must be set to the preimage when NewState is settled. // Preimage must be set to the preimage when NewState is settled.
Preimage *lntypes.Preimage Preimage *lntypes.Preimage
// HTLCPreimages set the HTLC-level preimages stored for AMP HTLCs.
// These are only learned when settling the invoice as a whole. Must be
// set when settling an invoice with non-nil SetID.
HTLCPreimages map[CircuitKey]lntypes.Preimage
// SetID identifies a specific set of HTLCs destined for the same // SetID identifies a specific set of HTLCs destined for the same
// invoice as part of a larger AMP payment. This value will be nil for // invoice as part of a larger AMP payment. This value will be nil for
// legacy or MPP payments. // legacy or MPP payments.
@ -645,7 +714,17 @@ func validateInvoice(i *Invoice, paymentHash lntypes.Hash) error {
return errors.New("invoice must have a feature vector") return errors.New("invoice must have a feature vector")
} }
if i.Terms.PaymentPreimage == nil && !i.HodlInvoice { err := feature.ValidateDeps(i.Terms.Features)
if err != nil {
return err
}
// AMP invoices and hodl invoices are allowed to have no preimage
// specified.
isAMP := i.Terms.Features.HasFeature(
lnwire.AMPOptional,
)
if i.Terms.PaymentPreimage == nil && !(i.HodlInvoice || isAMP) {
return errors.New("non-hodl invoices must have a preimage") return errors.New("non-hodl invoices must have a preimage")
} }
@ -879,19 +958,27 @@ func fetchInvoiceNumByRef(invoiceIndex, payAddrIndex, setIDIndex kvdb.RBucket,
payHash := ref.PayHash() payHash := ref.PayHash()
payAddr := ref.PayAddr() payAddr := ref.PayAddr()
var ( getInvoiceNumByHash := func() []byte {
invoiceNumByHash = invoiceIndex.Get(payHash[:]) if payHash != nil {
invoiceNumByAddr []byte return invoiceIndex.Get(payHash[:])
)
if payAddr != nil {
// Only allow lookups for payment address if it is not a blank
// payment address, which is a special-cased value for legacy
// keysend invoices.
if *payAddr != BlankPayAddr {
invoiceNumByAddr = payAddrIndex.Get(payAddr[:])
} }
return nil
} }
getInvoiceNumByAddr := func() []byte {
if payAddr != nil {
// Only allow lookups for payment address if it is not a
// blank payment address, which is a special-cased value
// for legacy keysend invoices.
if *payAddr != BlankPayAddr {
return payAddrIndex.Get(payAddr[:])
}
}
return nil
}
invoiceNumByHash := getInvoiceNumByHash()
invoiceNumByAddr := getInvoiceNumByAddr()
switch { switch {
// If payment address and payment hash both reference an existing // If payment address and payment hash both reference an existing
@ -903,6 +990,10 @@ func fetchInvoiceNumByRef(invoiceIndex, payAddrIndex, setIDIndex kvdb.RBucket,
return invoiceNumByAddr, nil return invoiceNumByAddr, nil
// Return invoices by payment addr only.
case invoiceNumByAddr != nil:
return invoiceNumByAddr, nil
// If we were only able to reference the invoice by hash, return the // If we were only able to reference the invoice by hash, return the
// corresponding invoice number. This can happen when no payment address // corresponding invoice number. This can happen when no payment address
// was provided, or if it didn't match anything in our records. // was provided, or if it didn't match anything in our records.
@ -1684,21 +1775,6 @@ func copySlice(src []byte) []byte {
return dest return dest
} }
// copyInvoiceHTLC makes a deep copy of the supplied invoice HTLC.
func copyInvoiceHTLC(src *InvoiceHTLC) *InvoiceHTLC {
result := *src
// Make a copy of the CustomSet map.
result.CustomRecords = make(record.CustomSet)
for k, v := range src.CustomRecords {
result.CustomRecords[k] = v
}
result.AMP = src.AMP.Copy()
return &result
}
// copyInvoice makes a deep copy of the supplied invoice. // copyInvoice makes a deep copy of the supplied invoice.
func copyInvoice(src *Invoice) *Invoice { func copyInvoice(src *Invoice) *Invoice {
dest := Invoice{ dest := Invoice{
@ -1725,7 +1801,7 @@ func copyInvoice(src *Invoice) *Invoice {
} }
for k, v := range src.Htlcs { for k, v := range src.Htlcs {
dest.Htlcs[k] = copyInvoiceHTLC(v) dest.Htlcs[k] = v.Copy()
} }
return &dest return &dest
@ -1733,7 +1809,7 @@ func copyInvoice(src *Invoice) *Invoice {
// updateInvoice fetches the invoice, obtains the update descriptor from the // updateInvoice fetches the invoice, obtains the update descriptor from the
// callback and applies the updates in a single db transaction. // callback and applies the updates in a single db transaction.
func (d *DB) updateInvoice(hash lntypes.Hash, invoices, func (d *DB) updateInvoice(hash *lntypes.Hash, invoices,
settleIndex, setIDIndex kvdb.RwBucket, invoiceNum []byte, settleIndex, setIDIndex kvdb.RwBucket, invoiceNum []byte,
callback InvoiceUpdateCallback) (*Invoice, error) { callback InvoiceUpdateCallback) (*Invoice, error) {
@ -1867,7 +1943,25 @@ func (d *DB) updateInvoice(hash lntypes.Hash, invoices,
// the process by updating the state transitions for individual HTLCs // the process by updating the state transitions for individual HTLCs
// and recalculate the total amount paid to the invoice. // and recalculate the total amount paid to the invoice.
var amtPaid lnwire.MilliSatoshi var amtPaid lnwire.MilliSatoshi
for _, htlc := range invoice.Htlcs { for key, htlc := range invoice.Htlcs {
// Set the HTLC preimage for any AMP HTLCs.
if setID != nil {
preimage, ok := update.State.HTLCPreimages[key]
switch {
// If we don't already have a preiamge for this HTLC, we
// can set it now.
case ok && htlc.AMP.Preimage == nil:
htlc.AMP.Preimage = &preimage
// Otherwise, prevent over-writing an existing preimage.
// Ignore the case where the preimage is identical.
case ok && *htlc.AMP.Preimage != preimage:
return nil, ErrHTLCPreimageAlreadyExists
}
}
// The invoice state may have changed and this could have // The invoice state may have changed and this could have
// implications for the states of the individual htlcs. Align // implications for the states of the individual htlcs. Align
// the htlc state with the current invoice state. // the htlc state with the current invoice state.
@ -1901,7 +1995,7 @@ func (d *DB) updateInvoice(hash lntypes.Hash, invoices,
} }
// updateInvoiceState validates and processes an invoice state update. // updateInvoiceState validates and processes an invoice state update.
func updateInvoiceState(invoice *Invoice, hash lntypes.Hash, func updateInvoiceState(invoice *Invoice, hash *lntypes.Hash,
update InvoiceStateUpdateDesc) error { update InvoiceStateUpdateDesc) error {
// Returning to open is never allowed from any state. // Returning to open is never allowed from any state.
@ -1950,9 +2044,14 @@ func updateInvoiceState(invoice *Invoice, hash lntypes.Hash,
switch { switch {
// If an invoice-level preimage was supplied, but the InvoiceRef
// doesn't specify a hash (e.g. AMP invoices) we fail.
case update.Preimage != nil && hash == nil:
return ErrUnexpectedInvoicePreimage
// Validate the supplied preimage for non-AMP invoices. // Validate the supplied preimage for non-AMP invoices.
case update.Preimage != nil: case update.Preimage != nil:
if update.Preimage.Hash() != hash { if update.Preimage.Hash() != *hash {
return ErrInvoicePreimageMismatch return ErrInvoicePreimageMismatch
} }
invoice.Terms.PaymentPreimage = update.Preimage invoice.Terms.PaymentPreimage = update.Preimage
@ -2027,10 +2126,25 @@ func updateHtlc(resolveTime time.Time, htlc *InvoiceHTLC,
// already know the preimage is valid due to checks at // already know the preimage is valid due to checks at
// the invoice level. For AMP HTLCs, verify that the // the invoice level. For AMP HTLCs, verify that the
// per-HTLC preimage-hash pair is valid. // per-HTLC preimage-hash pair is valid.
if setID != nil && !htlc.AMP.Preimage.Matches(htlc.AMP.Hash) { switch {
return fmt.Errorf("AMP preimage mismatch, "+
"preimage=%v hash=%v", *htlc.AMP.Preimage, // Non-AMP HTLCs can be settle immediately since we
htlc.AMP.Hash) // already know the preimage is valid due to checks at
// the invoice level.
case setID == nil:
// At this popint, the setID is non-nil, meaning this is
// an AMP HTLC. We know that htlc.AMP cannot be nil,
// otherwise IsInHTLCSet would have returned false.
//
// Fail if an accepted AMP HTLC has no preimage.
case htlc.AMP.Preimage == nil:
return ErrHTLCPreimageMissing
// Fail if the accepted AMP HTLC has an invalid
// preimage.
case !htlc.AMP.Preimage.Matches(htlc.AMP.Hash):
return ErrHTLCPreimageMismatch
} }
htlcState = HtlcStateSettled htlcState = HtlcStateSettled
@ -2059,8 +2173,7 @@ func updateHtlc(resolveTime time.Time, htlc *InvoiceHTLC,
// We should never find a settled HTLC on an invoice that isn't in // We should never find a settled HTLC on an invoice that isn't in
// ContractSettled. // ContractSettled.
if htlc.State == HtlcStateSettled { if htlc.State == HtlcStateSettled {
return fmt.Errorf("cannot have a settled htlc with "+ return ErrHTLCAlreadySettled
"invoice in state %v", invState)
} }
switch invState { switch invState {

View File

@ -51,4 +51,9 @@ var defaultSetDesc = setDesc{
SetInit: {}, // I SetInit: {}, // I
SetNodeAnn: {}, // N SetNodeAnn: {}, // N
}, },
lnwire.AMPOptional: {
SetInit: {}, // I
SetNodeAnn: {}, // N
SetInvoice: {}, // 9
},
} }

View File

@ -58,6 +58,9 @@ var deps = depDesc{
lnwire.AnchorsOptional: { lnwire.AnchorsOptional: {
lnwire.StaticRemoteKeyOptional: {}, lnwire.StaticRemoteKeyOptional: {},
}, },
lnwire.AMPOptional: {
lnwire.PaymentAddrOptional: {},
},
} }
// ValidateDeps asserts that a feature vector sets all features and their // ValidateDeps asserts that a feature vector sets all features and their

View File

@ -77,6 +77,8 @@ func newManager(cfg Config, desc setDesc) (*Manager, error) {
raw.Unset(lnwire.PaymentAddrRequired) raw.Unset(lnwire.PaymentAddrRequired)
raw.Unset(lnwire.MPPOptional) raw.Unset(lnwire.MPPOptional)
raw.Unset(lnwire.MPPRequired) raw.Unset(lnwire.MPPRequired)
raw.Unset(lnwire.AMPOptional)
raw.Unset(lnwire.AMPRequired)
} }
if cfg.NoStaticRemoteKey { if cfg.NoStaticRemoteKey {
raw.Unset(lnwire.StaticRemoteKeyOptional) raw.Unset(lnwire.StaticRemoteKeyOptional)

View File

@ -119,6 +119,7 @@ func NewPayloadFromReader(r io.Reader) (*Payload, error) {
amt uint64 amt uint64
cltv uint32 cltv uint32
mpp = &record.MPP{} mpp = &record.MPP{}
amp = &record.AMP{}
) )
tlvStream, err := tlv.NewStream( tlvStream, err := tlv.NewStream(
@ -126,6 +127,7 @@ func NewPayloadFromReader(r io.Reader) (*Payload, error) {
record.NewLockTimeRecord(&cltv), record.NewLockTimeRecord(&cltv),
record.NewNextHopIDRecord(&cid), record.NewNextHopIDRecord(&cid),
mpp.Record(), mpp.Record(),
amp.Record(),
) )
if err != nil { if err != nil {
return nil, err return nil, err
@ -160,6 +162,12 @@ func NewPayloadFromReader(r io.Reader) (*Payload, error) {
mpp = nil mpp = nil
} }
// If no AMP field was parsed, set the MPP field on the resulting
// payload to nil.
if _, ok := parsedTypes[record.AMPOnionType]; !ok {
amp = nil
}
// Filter out the custom records. // Filter out the custom records.
customRecords := NewCustomRecords(parsedTypes) customRecords := NewCustomRecords(parsedTypes)
@ -171,6 +179,7 @@ func NewPayloadFromReader(r io.Reader) (*Payload, error) {
OutgoingCTLV: cltv, OutgoingCTLV: cltv,
}, },
MPP: mpp, MPP: mpp,
AMP: amp,
customRecords: customRecords, customRecords: customRecords,
}, nil }, nil
} }
@ -207,6 +216,7 @@ func ValidateParsedPayloadTypes(parsedTypes tlv.TypeMap,
_, hasLockTime := parsedTypes[record.LockTimeOnionType] _, hasLockTime := parsedTypes[record.LockTimeOnionType]
_, hasNextHop := parsedTypes[record.NextHopOnionType] _, hasNextHop := parsedTypes[record.NextHopOnionType]
_, hasMPP := parsedTypes[record.MPPOnionType] _, hasMPP := parsedTypes[record.MPPOnionType]
_, hasAMP := parsedTypes[record.AMPOnionType]
switch { switch {
@ -243,6 +253,14 @@ func ValidateParsedPayloadTypes(parsedTypes tlv.TypeMap,
Violation: IncludedViolation, Violation: IncludedViolation,
FinalHop: isFinalHop, FinalHop: isFinalHop,
} }
// Intermediate nodes should never receive AMP fields.
case !isFinalHop && hasAMP:
return ErrInvalidPayload{
Type: record.AMPOnionType,
Violation: IncludedViolation,
FinalHop: isFinalHop,
}
} }
return nil return nil

View File

@ -8,14 +8,18 @@ import (
"github.com/lightningnetwork/lnd/htlcswitch/hop" "github.com/lightningnetwork/lnd/htlcswitch/hop"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/record" "github.com/lightningnetwork/lnd/record"
"github.com/stretchr/testify/require"
) )
const testUnknownRequiredType = 0x10
type decodePayloadTest struct { type decodePayloadTest struct {
name string name string
payload []byte payload []byte
expErr error expErr error
expCustomRecords map[uint64][]byte expCustomRecords map[uint64][]byte
shouldHaveMPP bool shouldHaveMPP bool
shouldHaveAMP bool
} }
var decodePayloadTests = []decodePayloadTest{ var decodePayloadTests = []decodePayloadTest{
@ -81,21 +85,26 @@ var decodePayloadTests = []decodePayloadTest{
}, },
}, },
{ {
name: "required type after omitted hop id", name: "required type after omitted hop id",
payload: []byte{0x02, 0x00, 0x04, 0x00, 0x0a, 0x00}, payload: []byte{
0x02, 0x00, 0x04, 0x00,
testUnknownRequiredType, 0x00,
},
expErr: hop.ErrInvalidPayload{ expErr: hop.ErrInvalidPayload{
Type: 10, Type: testUnknownRequiredType,
Violation: hop.RequiredViolation, Violation: hop.RequiredViolation,
FinalHop: true, FinalHop: true,
}, },
}, },
{ {
name: "required type after included hop id", name: "required type after included hop id",
payload: []byte{0x02, 0x00, 0x04, 0x00, 0x06, 0x08, 0x01, 0x00, payload: []byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x04, 0x00, 0x06, 0x08, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
testUnknownRequiredType, 0x00,
}, },
expErr: hop.ErrInvalidPayload{ expErr: hop.ErrInvalidPayload{
Type: 10, Type: testUnknownRequiredType,
Violation: hop.RequiredViolation, Violation: hop.RequiredViolation,
FinalHop: false, FinalHop: false,
}, },
@ -176,6 +185,37 @@ var decodePayloadTests = []decodePayloadTest{
FinalHop: false, FinalHop: false,
}, },
}, },
{
name: "intermediate hop with amp",
payload: []byte{
// amount
0x02, 0x00,
// cltv
0x04, 0x00,
// next hop id
0x06, 0x08,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// amp
0x0e, 0x41,
// amp.root_share
0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
// amp.set_id
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
// amp.child_index
0x09,
},
expErr: hop.ErrInvalidPayload{
Type: record.AMPOnionType,
Violation: hop.IncludedViolation,
FinalHop: false,
},
},
{ {
name: "final hop with mpp", name: "final hop with mpp",
payload: []byte{ payload: []byte{
@ -194,6 +234,30 @@ var decodePayloadTests = []decodePayloadTest{
expErr: nil, expErr: nil,
shouldHaveMPP: true, shouldHaveMPP: true,
}, },
{
name: "final hop with amp",
payload: []byte{
// amount
0x02, 0x00,
// cltv
0x04, 0x00,
// amp
0x0e, 0x41,
// amp.root_share
0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
// amp.set_id
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
// amp.child_index
0x09,
},
shouldHaveAMP: true,
},
} }
// TestDecodeHopPayloadRecordValidation asserts that parsing the payloads in the // TestDecodeHopPayloadRecordValidation asserts that parsing the payloads in the
@ -216,6 +280,20 @@ func testDecodeHopPayloadValidation(t *testing.T, test decodePayloadTest) {
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,
} }
testRootShare = [32]byte{
0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
}
testSetID = [32]byte{
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
}
testChildIndex = uint32(9)
) )
p, err := hop.NewPayloadFromReader(bytes.NewReader(test.payload)) p, err := hop.NewPayloadFromReader(bytes.NewReader(test.payload))
@ -242,6 +320,17 @@ func testDecodeHopPayloadValidation(t *testing.T, test decodePayloadTest) {
t.Fatalf("unexpected MPP payload") t.Fatalf("unexpected MPP payload")
} }
if test.shouldHaveAMP {
if p.AMP == nil {
t.Fatalf("payload should have AMP record")
}
require.Equal(t, testRootShare, p.AMP.RootShare())
require.Equal(t, testSetID, p.AMP.SetID())
require.Equal(t, testChildIndex, p.AMP.ChildIndex())
} else if p.AMP != nil {
t.Fatalf("unexpected AMP payload")
}
// Convert expected nil map to empty map, because we always expect an // Convert expected nil map to empty map, because we always expect an
// initiated map from the payload. // initiated map from the payload.
expCustomRecords := make(record.CustomSet) expCustomRecords := make(record.CustomSet)

View File

@ -377,7 +377,8 @@ func (i *InvoiceRegistry) invoiceEventLoop() {
func (i *InvoiceRegistry) dispatchToSingleClients(event *invoiceEvent) { func (i *InvoiceRegistry) dispatchToSingleClients(event *invoiceEvent) {
// Dispatch to single invoice subscribers. // Dispatch to single invoice subscribers.
for _, client := range i.singleNotificationClients { for _, client := range i.singleNotificationClients {
if client.invoiceRef.PayHash() != event.hash { payHash := client.invoiceRef.PayHash()
if payHash == nil || *payHash != event.hash {
continue continue
} }
@ -524,8 +525,13 @@ func (i *InvoiceRegistry) deliverSingleBacklogEvents(
return err return err
} }
payHash := client.invoiceRef.PayHash()
if payHash == nil {
return nil
}
err = client.notify(&invoiceEvent{ err = client.notify(&invoiceEvent{
hash: client.invoiceRef.PayHash(), hash: *payHash,
invoice: &invoice, invoice: &invoice,
}) })
if err != nil { if err != nil {
@ -775,6 +781,67 @@ func (i *InvoiceRegistry) processKeySend(ctx invoiceUpdateCtx) error {
return nil return nil
} }
// processAMP just-in-time inserts an invoice if this htlc is a keysend
// htlc.
func (i *InvoiceRegistry) processAMP(ctx invoiceUpdateCtx) error {
// AMP payments MUST also include an MPP record.
if ctx.mpp == nil {
return errors.New("no MPP record for AMP")
}
// Create an invoice for the total amount expected, provided in the MPP
// record.
amt := ctx.mpp.TotalMsat()
// Set the TLV and MPP optional features on the invoice. We'll also make
// the AMP features required so that it can't be paid by legacy or MPP
// htlcs.
rawFeatures := lnwire.NewRawFeatureVector(
lnwire.TLVOnionPayloadOptional,
lnwire.PaymentAddrOptional,
lnwire.AMPRequired,
)
features := lnwire.NewFeatureVector(rawFeatures, lnwire.Features)
// Use the minimum block delta that we require for settling htlcs.
finalCltvDelta := i.cfg.FinalCltvRejectDelta
// Pre-check expiry here to prevent inserting an invoice that will not
// be settled.
if ctx.expiry < uint32(ctx.currentHeight+finalCltvDelta) {
return errors.New("final expiry too soon")
}
// We'll use the sender-generated payment address provided in the HTLC
// to create our AMP invoice.
payAddr := ctx.mpp.PaymentAddr()
// Create placeholder invoice.
invoice := &channeldb.Invoice{
CreationDate: i.cfg.Clock.Now(),
Terms: channeldb.ContractTerm{
FinalCltvDelta: finalCltvDelta,
Value: amt,
PaymentPreimage: nil,
PaymentAddr: payAddr,
Features: features,
},
}
// Insert invoice into database. Ignore duplicates payment hashes and
// payment addrs, this may be a replay or a different HTLC for the AMP
// invoice.
_, err := i.AddInvoice(invoice, ctx.hash)
switch {
case err == channeldb.ErrDuplicateInvoice:
return nil
case err == channeldb.ErrDuplicatePayAddr:
return nil
default:
return err
}
}
// NotifyExitHopHtlc attempts to mark an invoice as settled. The return value // NotifyExitHopHtlc attempts to mark an invoice as settled. The return value
// describes how the htlc should be resolved. // describes how the htlc should be resolved.
// //
@ -813,13 +880,24 @@ func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash,
// AddInvoice obtains its own lock. This is no problem, because the // AddInvoice obtains its own lock. This is no problem, because the
// operation is idempotent. // operation is idempotent.
if i.cfg.AcceptKeySend { if i.cfg.AcceptKeySend {
err := i.processKeySend(ctx) if ctx.amp != nil {
if err != nil { err := i.processAMP(ctx)
ctx.log(fmt.Sprintf("keysend error: %v", err)) if err != nil {
ctx.log(fmt.Sprintf("amp error: %v", err))
return NewFailResolution( return NewFailResolution(
circuitKey, currentHeight, ResultKeySendError, circuitKey, currentHeight, ResultAmpError,
), nil ), nil
}
} else {
err := i.processKeySend(ctx)
if err != nil {
ctx.log(fmt.Sprintf("keysend error: %v", err))
return NewFailResolution(
circuitKey, currentHeight, ResultKeySendError,
), nil
}
} }
} }
@ -926,6 +1004,31 @@ func (i *InvoiceRegistry) notifyExitHopHtlcLocked(
"outcome: %v, at accept height: %v", "outcome: %v, at accept height: %v",
res.Outcome, res.AcceptHeight)) res.Outcome, res.AcceptHeight))
// Some failures apply to the entire HTLC set. Break here if
// this isn't one of them.
if !res.Outcome.IsSetFailure() {
break
}
// Also cancel any HTLCs in the HTLC set that are also in the
// canceled state with the same failure result.
setID := ctx.setID()
for key, htlc := range invoice.Htlcs {
if htlc.State != channeldb.HtlcStateCanceled {
continue
}
if !htlc.IsInHTLCSet(setID) {
continue
}
htlcFailResolution := NewFailResolution(
key, int32(htlc.AcceptHeight), res.Outcome,
)
i.notifyHodlSubscribers(htlcFailResolution)
}
// If the htlc was settled, we will settle any previously accepted // If the htlc was settled, we will settle any previously accepted
// htlcs and notify our peer to settle them. // htlcs and notify our peer to settle them.
case *HtlcSettleResolution: case *HtlcSettleResolution:
@ -941,13 +1044,18 @@ func (i *InvoiceRegistry) notifyExitHopHtlcLocked(
continue continue
} }
preimage := res.Preimage
if htlc.AMP != nil && htlc.AMP.Preimage != nil {
preimage = *htlc.AMP.Preimage
}
// Notify subscribers that the htlcs should be settled // Notify subscribers that the htlcs should be settled
// with our peer. Note that the outcome of the // with our peer. Note that the outcome of the
// resolution is set based on the outcome of the single // resolution is set based on the outcome of the single
// htlc that we just settled, so may not be accurate // htlc that we just settled, so may not be accurate
// for all htlcs. // for all htlcs.
htlcSettleResolution := NewSettleResolution( htlcSettleResolution := NewSettleResolution(
res.Preimage, key, preimage, key,
int32(htlc.AcceptHeight), res.Outcome, int32(htlc.AcceptHeight), res.Outcome,
) )

View File

@ -1,10 +1,12 @@
package invoices package invoices
import ( import (
"crypto/rand"
"math" "math"
"testing" "testing"
"time" "time"
"github.com/lightningnetwork/lnd/amp"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/clock" "github.com/lightningnetwork/lnd/clock"
"github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lntypes"
@ -29,9 +31,7 @@ func TestSettleInvoice(t *testing.T) {
} }
defer subscription.Cancel() defer subscription.Cancel()
if subscription.invoiceRef.PayHash() != testInvoicePaymentHash { require.Equal(t, subscription.invoiceRef.PayHash(), &testInvoicePaymentHash)
t.Fatalf("expected subscription for provided hash")
}
// Add the invoice. // Add the invoice.
addIdx, err := ctx.registry.AddInvoice(testInvoice, testInvoicePaymentHash) addIdx, err := ctx.registry.AddInvoice(testInvoice, testInvoicePaymentHash)
@ -77,19 +77,11 @@ func TestSettleInvoice(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
failResolution, ok := resolution.(*HtlcFailResolution) require.NotNil(t, resolution)
if !ok { failResolution := checkFailResolution(
t.Fatalf("expected fail resolution, got: %T", t, resolution, ResultExpiryTooSoon,
resolution) )
} require.Equal(t, testCurrentHeight, failResolution.AcceptHeight)
if failResolution.AcceptHeight != testCurrentHeight {
t.Fatalf("expected acceptHeight %v, but got %v",
testCurrentHeight, failResolution.AcceptHeight)
}
if failResolution.Outcome != ResultExpiryTooSoon {
t.Fatalf("expected expiry too soon, got: %v",
failResolution.Outcome)
}
// Settle invoice with a slightly higher amount. // Settle invoice with a slightly higher amount.
amtPaid := lnwire.MilliSatoshi(100500) amtPaid := lnwire.MilliSatoshi(100500)
@ -101,15 +93,11 @@ func TestSettleInvoice(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
settleResolution, ok := resolution.(*HtlcSettleResolution) require.NotNil(t, resolution)
if !ok { settleResolution := checkSettleResolution(
t.Fatalf("expected settle resolution, got: %T", t, resolution, testInvoicePreimage,
resolution) )
} require.Equal(t, ResultSettled, settleResolution.Outcome)
if settleResolution.Outcome != ResultSettled {
t.Fatalf("expected settled, got: %v",
settleResolution.Outcome)
}
// We expect the settled state to be sent to the single invoice // We expect the settled state to be sent to the single invoice
// subscriber. // subscriber.
@ -146,15 +134,11 @@ func TestSettleInvoice(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err) t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err)
} }
settleResolution, ok = resolution.(*HtlcSettleResolution) require.NotNil(t, resolution)
if !ok { settleResolution = checkSettleResolution(
t.Fatalf("expected settle resolution, got: %T", t, resolution, testInvoicePreimage,
resolution) )
} require.Equal(t, ResultReplayToSettled, settleResolution.Outcome)
if settleResolution.Outcome != ResultReplayToSettled {
t.Fatalf("expected replay settled, got: %v",
settleResolution.Outcome)
}
// Try to settle again with a new higher-valued htlc. This payment // Try to settle again with a new higher-valued htlc. This payment
// should also be accepted, to prevent any change in behaviour for a // should also be accepted, to prevent any change in behaviour for a
@ -166,15 +150,11 @@ func TestSettleInvoice(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err) t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err)
} }
settleResolution, ok = resolution.(*HtlcSettleResolution) require.NotNil(t, resolution)
if !ok { settleResolution = checkSettleResolution(
t.Fatalf("expected settle resolution, got: %T", t, resolution, testInvoicePreimage,
resolution) )
} require.Equal(t, ResultDuplicateToSettled, settleResolution.Outcome)
if settleResolution.Outcome != ResultDuplicateToSettled {
t.Fatalf("expected duplicate settled, got: %v",
settleResolution.Outcome)
}
// Try to settle again with a lower amount. This should fail just as it // Try to settle again with a lower amount. This should fail just as it
// would have failed if it were the first payment. // would have failed if it were the first payment.
@ -185,15 +165,8 @@ func TestSettleInvoice(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err) t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err)
} }
failResolution, ok = resolution.(*HtlcFailResolution) require.NotNil(t, resolution)
if !ok { checkFailResolution(t, resolution, ResultAmountTooLow)
t.Fatalf("expected fail resolution, got: %T",
resolution)
}
if failResolution.Outcome != ResultAmountTooLow {
t.Fatalf("expected amount too low, got: %v",
failResolution.Outcome)
}
// Check that settled amount is equal to the sum of values of the htlcs // Check that settled amount is equal to the sum of values of the htlcs
// 0 and 1. // 0 and 1.
@ -244,9 +217,7 @@ func testCancelInvoice(t *testing.T, gc bool) {
} }
defer subscription.Cancel() defer subscription.Cancel()
if subscription.invoiceRef.PayHash() != testInvoicePaymentHash { require.Equal(t, subscription.invoiceRef.PayHash(), &testInvoicePaymentHash)
t.Fatalf("expected subscription for provided hash")
}
// Add the invoice. // Add the invoice.
amt := lnwire.MilliSatoshi(100000) amt := lnwire.MilliSatoshi(100000)
@ -333,27 +304,23 @@ func testCancelInvoice(t *testing.T, gc bool) {
if err != nil { if err != nil {
t.Fatal("expected settlement of a canceled invoice to succeed") t.Fatal("expected settlement of a canceled invoice to succeed")
} }
failResolution, ok := resolution.(*HtlcFailResolution) require.NotNil(t, resolution)
if !ok {
t.Fatalf("expected fail resolution, got: %T",
resolution)
}
if failResolution.AcceptHeight != testCurrentHeight {
t.Fatalf("expected acceptHeight %v, but got %v",
testCurrentHeight, failResolution.AcceptHeight)
}
// If the invoice has been deleted (or not present) then we expect the // If the invoice has been deleted (or not present) then we expect the
// outcome to be ResultInvoiceNotFound instead of when the invoice is // outcome to be ResultInvoiceNotFound instead of when the invoice is
// in our database in which case we expect ResultInvoiceAlreadyCanceled. // in our database in which case we expect ResultInvoiceAlreadyCanceled.
var failResolution *HtlcFailResolution
if gc { if gc {
require.Equal(t, failResolution.Outcome, ResultInvoiceNotFound) failResolution = checkFailResolution(
t, resolution, ResultInvoiceNotFound,
)
} else { } else {
require.Equal(t, failResolution = checkFailResolution(
failResolution.Outcome, t, resolution, ResultInvoiceAlreadyCanceled,
ResultInvoiceAlreadyCanceled,
) )
} }
require.Equal(t, testCurrentHeight, failResolution.AcceptHeight)
} }
// TestCancelInvoice tests cancelation of an invoice and related notifications. // TestCancelInvoice tests cancelation of an invoice and related notifications.
@ -404,9 +371,7 @@ func TestSettleHoldInvoice(t *testing.T) {
} }
defer subscription.Cancel() defer subscription.Cancel()
if subscription.invoiceRef.PayHash() != testInvoicePaymentHash { require.Equal(t, subscription.invoiceRef.PayHash(), &testInvoicePaymentHash)
t.Fatalf("expected subscription for provided hash")
}
// Add the invoice. // Add the invoice.
_, err = registry.AddInvoice(testHodlInvoice, testInvoicePaymentHash) _, err = registry.AddInvoice(testHodlInvoice, testInvoicePaymentHash)
@ -480,15 +445,8 @@ func TestSettleHoldInvoice(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("expected settle to succeed but got %v", err) t.Fatalf("expected settle to succeed but got %v", err)
} }
failResolution, ok := resolution.(*HtlcFailResolution) require.NotNil(t, resolution)
if !ok { checkFailResolution(t, resolution, ResultExpiryTooSoon)
t.Fatalf("expected fail resolution, got: %T",
resolution)
}
if failResolution.Outcome != ResultExpiryTooSoon {
t.Fatalf("expected expiry too soon, got: %v",
failResolution.Outcome)
}
// We expect the accepted state to be sent to the single invoice // We expect the accepted state to be sent to the single invoice
// subscriber. For all invoice subscribers, we don't expect an update. // subscriber. For all invoice subscribers, we don't expect an update.
@ -509,22 +467,12 @@ func TestSettleHoldInvoice(t *testing.T) {
} }
htlcResolution := (<-hodlChan).(HtlcResolution) htlcResolution := (<-hodlChan).(HtlcResolution)
settleResolution, ok := htlcResolution.(*HtlcSettleResolution) require.NotNil(t, htlcResolution)
if !ok { settleResolution := checkSettleResolution(
t.Fatalf("expected settle resolution, got: %T", t, htlcResolution, testInvoicePreimage,
htlcResolution) )
} require.Equal(t, testCurrentHeight, settleResolution.AcceptHeight)
if settleResolution.Preimage != testInvoicePreimage { require.Equal(t, ResultSettled, settleResolution.Outcome)
t.Fatal("unexpected preimage in hodl resolution")
}
if settleResolution.AcceptHeight != testCurrentHeight {
t.Fatalf("expected acceptHeight %v, but got %v",
testCurrentHeight, settleResolution.AcceptHeight)
}
if settleResolution.Outcome != ResultSettled {
t.Fatalf("expected result settled, got: %v",
settleResolution.Outcome)
}
// We expect a settled notification to be sent out for both all and // We expect a settled notification to be sent out for both all and
// single invoice subscribers. // single invoice subscribers.
@ -610,11 +558,8 @@ func TestCancelHoldInvoice(t *testing.T) {
} }
htlcResolution := (<-hodlChan).(HtlcResolution) htlcResolution := (<-hodlChan).(HtlcResolution)
_, ok := htlcResolution.(*HtlcFailResolution) require.NotNil(t, htlcResolution)
if !ok { checkFailResolution(t, htlcResolution, ResultCanceled)
t.Fatalf("expected fail resolution, got: %T",
htlcResolution)
}
// Offering the same htlc again at a higher height should still result // Offering the same htlc again at a higher height should still result
// in a rejection. The accept height is expected to be the original // in a rejection. The accept height is expected to be the original
@ -626,19 +571,11 @@ func TestCancelHoldInvoice(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("expected settle to succeed but got %v", err) t.Fatalf("expected settle to succeed but got %v", err)
} }
failResolution, ok := resolution.(*HtlcFailResolution) require.NotNil(t, resolution)
if !ok { failResolution := checkFailResolution(
t.Fatalf("expected fail resolution, got: %T", t, resolution, ResultReplayToCanceled,
resolution) )
} require.Equal(t, testCurrentHeight, failResolution.AcceptHeight)
if failResolution.AcceptHeight != testCurrentHeight {
t.Fatalf("expected acceptHeight %v, but got %v",
testCurrentHeight, failResolution.AcceptHeight)
}
if failResolution.Outcome != ResultReplayToCanceled {
t.Fatalf("expected replay to canceled, got %v",
failResolution.Outcome)
}
} }
// TestUnknownInvoice tests that invoice registry returns an error when the // TestUnknownInvoice tests that invoice registry returns an error when the
@ -661,15 +598,8 @@ func TestUnknownInvoice(t *testing.T) {
if err != nil { if err != nil {
t.Fatal("unexpected error") t.Fatal("unexpected error")
} }
failResolution, ok := resolution.(*HtlcFailResolution) require.NotNil(t, resolution)
if !ok { checkFailResolution(t, resolution, ResultInvoiceNotFound)
t.Fatalf("expected fail resolution, got: %T",
resolution)
}
if failResolution.Outcome != ResultInvoiceNotFound {
t.Fatalf("expected ResultInvoiceNotFound, got: %v",
failResolution.Outcome)
}
} }
// TestKeySend tests receiving a spontaneous payment with and without keysend // TestKeySend tests receiving a spontaneous payment with and without keysend
@ -721,18 +651,12 @@ func testKeySend(t *testing.T, keySendEnabled bool) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
failResolution, ok := resolution.(*HtlcFailResolution) require.NotNil(t, resolution)
if !ok {
t.Fatalf("expected fail resolution, got: %T",
resolution)
}
switch { if !keySendEnabled {
case !keySendEnabled && failResolution.Outcome != ResultInvoiceNotFound: checkFailResolution(t, resolution, ResultInvoiceNotFound)
t.Fatal("expected invoice not found outcome") } else {
checkFailResolution(t, resolution, ResultKeySendError)
case keySendEnabled && failResolution.Outcome != ResultKeySendError:
t.Fatal("expected keysend error")
} }
// Try to settle invoice with a valid keysend htlc. // Try to settle invoice with a valid keysend htlc.
@ -752,23 +676,10 @@ func testKeySend(t *testing.T, keySendEnabled bool) {
// Expect a cancel resolution if keysend is disabled. // Expect a cancel resolution if keysend is disabled.
if !keySendEnabled { if !keySendEnabled {
failResolution, ok = resolution.(*HtlcFailResolution) checkFailResolution(t, resolution, ResultInvoiceNotFound)
if !ok {
t.Fatalf("expected fail resolution, got: %T",
resolution)
}
if failResolution.Outcome != ResultInvoiceNotFound {
t.Fatal("expected keysend payment not to be accepted")
}
return return
} }
checkResolution := func(res HtlcResolution, pimg lntypes.Preimage) {
// Otherwise we expect no error and a settle res for the htlc.
settleResolution, ok := res.(*HtlcSettleResolution)
require.True(t, ok)
require.Equal(t, settleResolution.Preimage, pimg)
}
checkSubscription := func() { checkSubscription := func() {
// We expect a new invoice notification to be sent out. // We expect a new invoice notification to be sent out.
newInvoice := <-allSubscriptions.NewInvoices newInvoice := <-allSubscriptions.NewInvoices
@ -779,7 +690,7 @@ func testKeySend(t *testing.T, keySendEnabled bool) {
require.Equal(t, settledInvoice.State, channeldb.ContractSettled) require.Equal(t, settledInvoice.State, channeldb.ContractSettled)
} }
checkResolution(resolution, preimage) checkSettleResolution(t, resolution, preimage)
checkSubscription() checkSubscription()
// Replay the same keysend payment. We expect an identical resolution, // Replay the same keysend payment. We expect an identical resolution,
@ -789,7 +700,7 @@ func testKeySend(t *testing.T, keySendEnabled bool) {
testCurrentHeight, getCircuitKey(10), hodlChan, keySendPayload, testCurrentHeight, getCircuitKey(10), hodlChan, keySendPayload,
) )
require.Nil(t, err) require.Nil(t, err)
checkResolution(resolution, preimage) checkSettleResolution(t, resolution, preimage)
select { select {
case <-allSubscriptions.NewInvoices: case <-allSubscriptions.NewInvoices:
@ -814,7 +725,7 @@ func testKeySend(t *testing.T, keySendEnabled bool) {
) )
require.Nil(t, err) require.Nil(t, err)
checkResolution(resolution, preimage2) checkSettleResolution(t, resolution, preimage2)
checkSubscription() checkSubscription()
} }
@ -1211,7 +1122,7 @@ func TestSettleInvoicePaymentAddrRequired(t *testing.T) {
defer subscription.Cancel() defer subscription.Cancel()
require.Equal( require.Equal(
t, subscription.invoiceRef.PayHash(), testInvoicePaymentHash, t, subscription.invoiceRef.PayHash(), &testInvoicePaymentHash,
) )
// Add the invoice, which requires the MPP payload to always be // Add the invoice, which requires the MPP payload to always be
@ -1287,7 +1198,7 @@ func TestSettleInvoicePaymentAddrRequiredOptionalGrace(t *testing.T) {
defer subscription.Cancel() defer subscription.Cancel()
require.Equal( require.Equal(
t, subscription.invoiceRef.PayHash(), testInvoicePaymentHash, t, subscription.invoiceRef.PayHash(), &testInvoicePaymentHash,
) )
// Add the invoice, which requires the MPP payload to always be // Add the invoice, which requires the MPP payload to always be
@ -1364,3 +1275,254 @@ func TestSettleInvoicePaymentAddrRequiredOptionalGrace(t *testing.T) {
t.Fatal("no update received") t.Fatal("no update received")
} }
} }
// TestAMPWithoutMPPPayload asserts that we correctly reject an AMP HTLC that
// does not include an MPP record.
func TestAMPWithoutMPPPayload(t *testing.T) {
defer timeout()()
ctx := newTestContext(t)
defer ctx.cleanup()
ctx.registry.cfg.AcceptKeySend = true
const (
shardAmt = lnwire.MilliSatoshi(10)
expiry = uint32(testCurrentHeight + 20)
)
// Create payload with missing MPP field.
payload := &mockPayload{
amp: record.NewAMP([32]byte{}, [32]byte{}, 0),
}
hodlChan := make(chan interface{}, 1)
resolution, err := ctx.registry.NotifyExitHopHtlc(
lntypes.Hash{}, shardAmt, expiry,
testCurrentHeight, getCircuitKey(uint64(10)), hodlChan,
payload,
)
require.NoError(t, err)
// We should receive the ResultAmpError failure.
require.NotNil(t, resolution)
checkFailResolution(t, resolution, ResultAmpError)
}
// TestSpontaneousAmpPayment tests receiving a spontaneous AMP payment with both
// valid and invalid reconstructions.
func TestSpontaneousAmpPayment(t *testing.T) {
tests := []struct {
name string
keySendEnabled bool
failReconstruction bool
numShards int
}{
{
name: "enabled valid one shard",
keySendEnabled: true,
failReconstruction: false,
numShards: 1,
},
{
name: "enabled valid multiple shards",
keySendEnabled: true,
failReconstruction: false,
numShards: 3,
},
{
name: "enabled invalid one shard",
keySendEnabled: true,
failReconstruction: true,
numShards: 1,
},
{
name: "enabled invalid multiple shards",
keySendEnabled: true,
failReconstruction: true,
numShards: 3,
},
{
name: "disabled valid multiple shards",
keySendEnabled: false,
failReconstruction: false,
numShards: 3,
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
testSpontaneousAmpPayment(
t, test.keySendEnabled, test.failReconstruction,
test.numShards,
)
})
}
}
// testSpontaneousAmpPayment runs a specific spontaneous AMP test case.
func testSpontaneousAmpPayment(
t *testing.T, keySendEnabled, failReconstruction bool, numShards int) {
defer timeout()()
ctx := newTestContext(t)
defer ctx.cleanup()
ctx.registry.cfg.AcceptKeySend = keySendEnabled
allSubscriptions, err := ctx.registry.SubscribeNotifications(0, 0)
require.Nil(t, err)
defer allSubscriptions.Cancel()
const (
totalAmt = lnwire.MilliSatoshi(360)
expiry = uint32(testCurrentHeight + 20)
)
var (
shardAmt = totalAmt / lnwire.MilliSatoshi(numShards)
payAddr [32]byte
setID [32]byte
)
_, err = rand.Read(payAddr[:])
require.NoError(t, err)
_, err = rand.Read(setID[:])
require.NoError(t, err)
var sharer amp.Sharer
sharer, err = amp.NewSeedSharer()
require.NoError(t, err)
// Asserts that a new invoice is published on the NewInvoices channel.
checkOpenSubscription := func() {
t.Helper()
newInvoice := <-allSubscriptions.NewInvoices
require.Equal(t, newInvoice.State, channeldb.ContractOpen)
}
// Asserts that a settled invoice is published on the SettledInvoices
// channel.
checkSettleSubscription := func() {
t.Helper()
settledInvoice := <-allSubscriptions.SettledInvoices
require.Equal(t, settledInvoice.State, channeldb.ContractSettled)
}
// Asserts that no invoice is published on the SettledInvoices channel
// w/in two seconds.
checkNoSettleSubscription := func() {
t.Helper()
select {
case <-allSubscriptions.SettledInvoices:
t.Fatal("no settle ntfn expected")
case <-time.After(2 * time.Second):
}
}
// Record the hodl channels of all HTLCs but the last one, which
// received its resolution directly from NotifyExistHopHtlc.
hodlChans := make(map[lntypes.Preimage]chan interface{})
for i := 0; i < numShards; i++ {
isFinalShard := i == numShards-1
hodlChan := make(chan interface{}, 1)
var child *amp.Child
if !isFinalShard {
var left amp.Sharer
left, sharer, err = sharer.Split()
require.NoError(t, err)
child = left.Child(uint32(i))
// Only store the first numShards-1 hodlChans.
hodlChans[child.Preimage] = hodlChan
} else {
child = sharer.Child(uint32(i))
}
// Send a blank share when the set should fail reconstruction,
// otherwise send the derived share.
var share [32]byte
if !failReconstruction {
share = child.Share
}
payload := &mockPayload{
mpp: record.NewMPP(totalAmt, payAddr),
amp: record.NewAMP(share, setID, uint32(i)),
}
resolution, err := ctx.registry.NotifyExitHopHtlc(
child.Hash, shardAmt, expiry,
testCurrentHeight, getCircuitKey(uint64(i)), hodlChan,
payload,
)
require.NoError(t, err)
// When keysend is disabled all HTLC should fail with invoice
// not found, since one is not inserted before executing
// UpdateInvoice.
if !keySendEnabled {
require.NotNil(t, resolution)
checkFailResolution(t, resolution, ResultInvoiceNotFound)
continue
}
// Check that resolutions are properly formed.
if !isFinalShard {
// Non-final shares should always return a nil
// resolution, theirs will be delivered via the
// hodlChan.
require.Nil(t, resolution)
} else {
// The final share should receive a non-nil resolution.
// Also assert that it is the proper type based on the
// test case.
require.NotNil(t, resolution)
if failReconstruction {
checkFailResolution(t, resolution, ResultAmpReconstruction)
} else {
checkSettleResolution(t, resolution, child.Preimage)
}
}
// Assert the behavior of the Open and Settle notifications.
// There should always be an open (keysend is enabled) followed
// by settle for valid AMP payments.
//
// NOTE: The cases are split in separate if conditions, rather
// than else-if, to properly handle the case when there is only
// one shard.
if i == 0 {
checkOpenSubscription()
}
if isFinalShard {
if failReconstruction {
checkNoSettleSubscription()
} else {
checkSettleSubscription()
}
}
}
// No need to check the hodl chans when keysend is not enabled.
if !keySendEnabled {
return
}
// For the non-final hodl chans, assert that they receive the expected
// failure or preimage.
for preimage, hodlChan := range hodlChans {
resolution, ok := (<-hodlChan).(HtlcResolution)
require.True(t, ok)
require.NotNil(t, resolution)
if failReconstruction {
checkFailResolution(t, resolution, ResultAmpReconstruction)
} else {
checkSettleResolution(t, resolution, preimage)
}
}
}

View File

@ -105,6 +105,13 @@ const (
// ResultMppInProgress is returned when we are busy receiving a mpp // ResultMppInProgress is returned when we are busy receiving a mpp
// payment. // payment.
ResultMppInProgress ResultMppInProgress
// ResultAmpError is returned when we receive invalid AMP parameters.
ResultAmpError
// ResultAmpReconstruction is returned when the derived child
// hash/preimage pairs were invalid for at least one HTLC in the set.
ResultAmpReconstruction
) )
// String returns a string representation of the result. // String returns a string representation of the result.
@ -162,11 +169,34 @@ func (f FailResolutionResult) FailureString() string {
case ResultMppInProgress: case ResultMppInProgress:
return "mpp reception in progress" return "mpp reception in progress"
case ResultAmpError:
return "invalid amp parameters"
case ResultAmpReconstruction:
return "amp reconstruction failed"
default: default:
return "unknown failure resolution result" return "unknown failure resolution result"
} }
} }
// IsSetFailure returns true if this failure should result in the entire HTLC
// set being failed with the same result.
func (f FailResolutionResult) IsSetFailure() bool {
switch f {
case
ResultAmpReconstruction,
ResultHtlcSetTotalTooLow,
ResultHtlcSetTotalMismatch,
ResultHtlcSetOverpayment:
return true
default:
return false
}
}
// SettleResolutionResult provides metadata which about a htlc that was failed // SettleResolutionResult provides metadata which about a htlc that was failed
// by the registry. It can be used to take custom actions on resolution of the // by the registry. It can be used to take custom actions on resolution of the
// htlc. // htlc.

View File

@ -19,6 +19,7 @@ import (
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/record" "github.com/lightningnetwork/lnd/record"
"github.com/lightningnetwork/lnd/zpay32" "github.com/lightningnetwork/lnd/zpay32"
"github.com/stretchr/testify/require"
) )
type mockPayload struct { type mockPayload struct {
@ -45,6 +46,16 @@ func (p *mockPayload) CustomRecords() record.CustomSet {
return p.customRecords return p.customRecords
} }
const (
testHtlcExpiry = uint32(5)
testInvoiceCltvDelta = uint32(4)
testFinalCltvRejectDelta = int32(4)
testCurrentHeight = int32(1)
)
var ( var (
testTimeout = 5 * time.Second testTimeout = 5 * time.Second
@ -54,14 +65,6 @@ var (
testInvoicePaymentHash = testInvoicePreimage.Hash() testInvoicePaymentHash = testInvoicePreimage.Hash()
testHtlcExpiry = uint32(5)
testInvoiceCltvDelta = uint32(4)
testFinalCltvRejectDelta = int32(4)
testCurrentHeight = int32(1)
testPrivKeyBytes, _ = hex.DecodeString( testPrivKeyBytes, _ = hex.DecodeString(
"e126f68f7eafcc8b74f54d269fe206be715000f94dac067d1c04a8ca3b2db734") "e126f68f7eafcc8b74f54d269fe206be715000f94dac067d1c04a8ca3b2db734")
@ -111,7 +114,10 @@ var (
Value: testInvoiceAmt, Value: testInvoiceAmt,
Expiry: time.Hour, Expiry: time.Hour,
Features: lnwire.NewFeatureVector( Features: lnwire.NewFeatureVector(
lnwire.NewRawFeatureVector(lnwire.PaymentAddrRequired), lnwire.NewRawFeatureVector(
lnwire.TLVOnionPayloadOptional,
lnwire.PaymentAddrRequired,
),
lnwire.Features, lnwire.Features,
), ),
}, },
@ -124,7 +130,10 @@ var (
Value: testInvoiceAmt, Value: testInvoiceAmt,
Expiry: time.Hour, Expiry: time.Hour,
Features: lnwire.NewFeatureVector( Features: lnwire.NewFeatureVector(
lnwire.NewRawFeatureVector(lnwire.PaymentAddrOptional), lnwire.NewRawFeatureVector(
lnwire.TLVOnionPayloadOptional,
lnwire.PaymentAddrOptional,
),
lnwire.Features, lnwire.Features,
), ),
}, },
@ -325,3 +334,32 @@ func generateInvoiceExpiryTestData(
return testData return testData
} }
// checkSettleResolution asserts the resolution is a settle with the correct
// preimage. If successful, the HtlcSettleResolution is returned in case further
// checks are desired.
func checkSettleResolution(t *testing.T, res HtlcResolution,
expPreimage lntypes.Preimage) *HtlcSettleResolution {
t.Helper()
settleResolution, ok := res.(*HtlcSettleResolution)
require.True(t, ok)
require.Equal(t, expPreimage, settleResolution.Preimage)
return settleResolution
}
// checkFailResolution asserts the resolution is a fail with the correct reason.
// If successful, the HtlcFailResolutionis returned in case further checks are
// desired.
func checkFailResolution(t *testing.T, res HtlcResolution,
expOutcome FailResolutionResult) *HtlcFailResolution {
t.Helper()
failResolution, ok := res.(*HtlcFailResolution)
require.True(t, ok)
require.Equal(t, expOutcome, failResolution.Outcome)
return failResolution
}

View File

@ -3,6 +3,7 @@ package invoices
import ( import (
"errors" "errors"
"github.com/lightningnetwork/lnd/amp"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
@ -26,11 +27,16 @@ type invoiceUpdateCtx struct {
// invoiceRef returns an identifier that can be used to lookup or update the // invoiceRef returns an identifier that can be used to lookup or update the
// invoice this HTLC is targeting. // invoice this HTLC is targeting.
func (i *invoiceUpdateCtx) invoiceRef() channeldb.InvoiceRef { func (i *invoiceUpdateCtx) invoiceRef() channeldb.InvoiceRef {
if i.mpp != nil { switch {
case i.amp != nil && i.mpp != nil:
payAddr := i.mpp.PaymentAddr()
return channeldb.InvoiceRefByAddr(payAddr)
case i.mpp != nil:
payAddr := i.mpp.PaymentAddr() payAddr := i.mpp.PaymentAddr()
return channeldb.InvoiceRefByHashAndAddr(i.hash, payAddr) return channeldb.InvoiceRefByHashAndAddr(i.hash, payAddr)
default:
return channeldb.InvoiceRefByHash(i.hash)
} }
return channeldb.InvoiceRefByHash(i.hash)
} }
// setID returns an identifier that identifies other possible HTLCs that this // setID returns an identifier that identifies other possible HTLCs that this
@ -47,7 +53,7 @@ func (i invoiceUpdateCtx) setID() *[32]byte {
// log logs a message specific to this update context. // log logs a message specific to this update context.
func (i *invoiceUpdateCtx) log(s string) { func (i *invoiceUpdateCtx) log(s string) {
log.Debugf("Invoice%v: %v, amt=%v, expiry=%v, circuit=%v, mpp=%v, "+ log.Debugf("Invoice%v: %v, amt=%v, expiry=%v, circuit=%v, mpp=%v, "+
"amp=%v", i.hash[:], s, i.amtPaid, i.expiry, i.circuitKey, "amp=%v", i.invoiceRef(), s, i.amtPaid, i.expiry, i.circuitKey,
i.mpp, i.amp) i.mpp, i.amp)
} }
@ -130,6 +136,14 @@ func updateMpp(ctx *invoiceUpdateCtx,
CustomRecords: ctx.customRecords, CustomRecords: ctx.customRecords,
} }
if ctx.amp != nil {
acceptDesc.AMP = &channeldb.InvoiceHtlcAMPData{
Record: *ctx.amp,
Hash: ctx.hash,
Preimage: nil,
}
}
// Only accept payments to open invoices. This behaviour differs from // Only accept payments to open invoices. This behaviour differs from
// non-mpp payments that are accepted even after the invoice is settled. // non-mpp payments that are accepted even after the invoice is settled.
// Because non-mpp payments don't have a payment address, this is needed // Because non-mpp payments don't have a payment address, this is needed
@ -154,9 +168,18 @@ func updateMpp(ctx *invoiceUpdateCtx,
return nil, ctx.failRes(ResultHtlcSetTotalTooLow), nil return nil, ctx.failRes(ResultHtlcSetTotalTooLow), nil
} }
htlcSet := inv.HTLCSet(setID)
// Check whether total amt matches other htlcs in the set. // Check whether total amt matches other htlcs in the set.
var newSetTotal lnwire.MilliSatoshi var newSetTotal lnwire.MilliSatoshi
for _, htlc := range inv.HTLCSet(setID) { for _, htlc := range htlcSet {
// Only consider accepted mpp htlcs. It is possible that there
// are htlcs registered in the invoice database that previously
// timed out and are in the canceled state now.
if htlc.State != channeldb.HtlcStateAccepted {
continue
}
if ctx.mpp.TotalMsat() != htlc.MppTotalAmt { if ctx.mpp.TotalMsat() != htlc.MppTotalAmt {
return nil, ctx.failRes(ResultHtlcSetTotalMismatch), nil return nil, ctx.failRes(ResultHtlcSetTotalMismatch), nil
} }
@ -206,15 +229,107 @@ func updateMpp(ctx *invoiceUpdateCtx,
return &update, ctx.acceptRes(resultAccepted), nil return &update, ctx.acceptRes(resultAccepted), nil
} }
update.State = &channeldb.InvoiceStateUpdateDesc{ var (
NewState: channeldb.ContractSettled, htlcPreimages map[channeldb.CircuitKey]lntypes.Preimage
Preimage: inv.Terms.PaymentPreimage, htlcPreimage lntypes.Preimage
SetID: setID, )
if ctx.amp != nil {
var failRes *HtlcFailResolution
htlcPreimages, failRes = reconstructAMPPreimages(ctx, htlcSet)
if failRes != nil {
update.State = &channeldb.InvoiceStateUpdateDesc{
NewState: channeldb.ContractCanceled,
SetID: setID,
}
return &update, failRes, nil
}
// The preimage for _this_ HTLC will be the one with context's
// circuit key.
htlcPreimage = htlcPreimages[ctx.circuitKey]
} else {
htlcPreimage = *inv.Terms.PaymentPreimage
} }
return &update, ctx.settleRes( update.State = &channeldb.InvoiceStateUpdateDesc{
*inv.Terms.PaymentPreimage, ResultSettled, NewState: channeldb.ContractSettled,
), nil Preimage: inv.Terms.PaymentPreimage,
HTLCPreimages: htlcPreimages,
SetID: setID,
}
return &update, ctx.settleRes(htlcPreimage, ResultSettled), nil
}
// HTLCSet is a map of CircuitKey to InvoiceHTLC.
type HTLCSet = map[channeldb.CircuitKey]*channeldb.InvoiceHTLC
// HTLCPreimages is a map of CircuitKey to preimage.
type HTLCPreimages = map[channeldb.CircuitKey]lntypes.Preimage
// reconstructAMPPreimages reconstructs the root seed for an AMP HTLC set and
// verifies that all derived child hashes match the payment hashes of the HTLCs
// in the set. This method is meant to be called after receiving the full amount
// committed to via mpp_total_msat. This method will return a fail resolution if
// any of the child hashes fail to matche theire corresponding HTLCs.
func reconstructAMPPreimages(ctx *invoiceUpdateCtx,
htlcSet HTLCSet) (HTLCPreimages, *HtlcFailResolution) {
// Create a slice containing all the child descriptors to be used for
// reconstruction. This should include all HTLCs currently in the HTLC
// set, plus the incoming HTLC.
childDescs := make([]amp.ChildDesc, 0, 1+len(htlcSet))
// Add the new HTLC's child descriptor at index 0.
childDescs = append(childDescs, amp.ChildDesc{
Share: ctx.amp.RootShare(),
Index: ctx.amp.ChildIndex(),
})
// Next, construct an index mapping the position in childDescs to a
// circuit key for all preexisting HTLCs.
indexToCircuitKey := make(map[int]channeldb.CircuitKey)
// Add the child descriptor for each HTLC in the HTLC set, recording
// it's position within the slice.
var htlcSetIndex int
for circuitKey, htlc := range htlcSet {
childDescs = append(childDescs, amp.ChildDesc{
Share: htlc.AMP.Record.RootShare(),
Index: htlc.AMP.Record.ChildIndex(),
})
indexToCircuitKey[htlcSetIndex] = circuitKey
htlcSetIndex++
}
// Using the child descriptors, reconstruct the root seed and derive the
// child hash/preimage pairs for each of the HTLCs.
children := amp.ReconstructChildren(childDescs...)
// Validate that the derived child preimages match the hash of each
// HTLC's respective hash.
if ctx.hash != children[0].Hash {
return nil, ctx.failRes(ResultAmpReconstruction)
}
for idx, child := range children[1:] {
circuitKey := indexToCircuitKey[idx]
htlc := htlcSet[circuitKey]
if htlc.AMP.Hash != child.Hash {
return nil, ctx.failRes(ResultAmpReconstruction)
}
}
// Finally, construct the map of learned preimages indexed by circuit
// key, so that they can be persisted along with each HTLC when updating
// the invoice.
htlcPreimages := make(map[channeldb.CircuitKey]lntypes.Preimage)
htlcPreimages[ctx.circuitKey] = children[0].Preimage
for idx, child := range children[1:] {
circuitKey := indexToCircuitKey[idx]
htlcPreimages[circuitKey] = child.Preimage
}
return htlcPreimages, nil
} }
// updateLegacy is a callback for DB.UpdateInvoice that contains the invoice // updateLegacy is a callback for DB.UpdateInvoice that contains the invoice

View File

@ -2,7 +2,6 @@ package invoicesrpc
import ( import (
"encoding/hex" "encoding/hex"
"errors"
"fmt" "fmt"
"github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/btcec"
@ -24,7 +23,7 @@ func decodePayReq(invoice *channeldb.Invoice,
if paymentRequest == "" { if paymentRequest == "" {
preimage := invoice.Terms.PaymentPreimage preimage := invoice.Terms.PaymentPreimage
if preimage == nil { if preimage == nil {
return nil, errors.New("cannot reconstruct pay req") return &zpay32.Invoice{}, nil
} }
hash := [32]byte(preimage.Hash()) hash := [32]byte(preimage.Hash())
return &zpay32.Invoice{ return &zpay32.Invoice{
@ -51,6 +50,11 @@ func CreateRPCInvoice(invoice *channeldb.Invoice,
return nil, err return nil, err
} }
var rHash []byte
if decoded.PaymentHash != nil {
rHash = decoded.PaymentHash[:]
}
var descHash []byte var descHash []byte
if decoded.DescriptionHash != nil { if decoded.DescriptionHash != nil {
descHash = decoded.DescriptionHash[:] descHash = decoded.DescriptionHash[:]
@ -129,7 +133,7 @@ func CreateRPCInvoice(invoice *channeldb.Invoice,
rpcHtlc.Amp = &lnrpc.AMP{ rpcHtlc.Amp = &lnrpc.AMP{
RootShare: rootShare[:], RootShare: rootShare[:],
SetId: setID[:], SetId: setID[:],
ChildIndex: uint32(htlc.AMP.Record.ChildIndex()), ChildIndex: htlc.AMP.Record.ChildIndex(),
Hash: htlc.AMP.Hash[:], Hash: htlc.AMP.Hash[:],
Preimage: preimage, Preimage: preimage,
} }
@ -144,8 +148,8 @@ func CreateRPCInvoice(invoice *channeldb.Invoice,
} }
rpcInvoice := &lnrpc.Invoice{ rpcInvoice := &lnrpc.Invoice{
Memo: string(invoice.Memo[:]), Memo: string(invoice.Memo),
RHash: decoded.PaymentHash[:], RHash: rHash,
Value: int64(satAmt), Value: int64(satAmt),
ValueMsat: int64(invoice.Terms.Value), ValueMsat: int64(invoice.Terms.Value),
CreationDate: invoice.CreationDate.Unix(), CreationDate: invoice.CreationDate.Unix(),

View File

@ -441,6 +441,23 @@
], ],
"default": "IN_FLIGHT" "default": "IN_FLIGHT"
}, },
"lnrpcAMPRecord": {
"type": "object",
"properties": {
"root_share": {
"type": "string",
"format": "byte"
},
"set_id": {
"type": "string",
"format": "byte"
},
"child_index": {
"type": "integer",
"format": "int64"
}
}
},
"lnrpcChannelPoint": { "lnrpcChannelPoint": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -677,7 +694,11 @@
}, },
"mpp_record": { "mpp_record": {
"$ref": "#/definitions/lnrpcMPPRecord", "$ref": "#/definitions/lnrpcMPPRecord",
"description": "An optional TLV record that signals 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." "description": "An optional TLV record that signals the use of an MPP payment. If present,\nthe receiver will enforce that the same mpp_record is included in the final\nhop payload of all non-zero payments in the HTLC set. If empty, a regular\nsingle-shot payment is or was attempted."
},
"amp_record": {
"$ref": "#/definitions/lnrpcAMPRecord",
"description": "An optional TLV record that signals the use of an AMP payment. If present,\nthe receiver will treat all received payments including the same\n(payment_addr, set_id) pair as being part of one logical payment. The\npayment will be settled by XORing the root_share's together and deriving the\nchild hashes and preimages according to BOLT XX. Must be used in conjunction\nwith mpp_record."
}, },
"custom_records": { "custom_records": {
"type": "object", "type": "object",

View File

@ -455,6 +455,11 @@ func UnmarshallHopWithPubkey(rpcHop *lnrpc.Hop, pubkey route.Vertex) (*route.Hop
return nil, err return nil, err
} }
amp, err := UnmarshalAMP(rpcHop.AmpRecord)
if err != nil {
return nil, err
}
return &route.Hop{ return &route.Hop{
OutgoingTimeLock: rpcHop.Expiry, OutgoingTimeLock: rpcHop.Expiry,
AmtToForward: lnwire.MilliSatoshi(rpcHop.AmtToForwardMsat), AmtToForward: lnwire.MilliSatoshi(rpcHop.AmtToForwardMsat),
@ -463,6 +468,7 @@ func UnmarshallHopWithPubkey(rpcHop *lnrpc.Hop, pubkey route.Vertex) (*route.Hop
CustomRecords: customRecords, CustomRecords: customRecords,
LegacyPayload: !rpcHop.TlvPayload, LegacyPayload: !rpcHop.TlvPayload,
MPP: mpp, MPP: mpp,
AMP: amp,
}, nil }, nil
} }
@ -895,6 +901,32 @@ func UnmarshalMPP(reqMPP *lnrpc.MPPRecord) (*record.MPP, error) {
return record.NewMPP(total, addr), nil return record.NewMPP(total, addr), nil
} }
func UnmarshalAMP(reqAMP *lnrpc.AMPRecord) (*record.AMP, error) {
if reqAMP == nil {
return nil, nil
}
reqRootShare := reqAMP.RootShare
reqSetID := reqAMP.SetId
switch {
case len(reqRootShare) != 32:
return nil, errors.New("AMP root_share must be 32 bytes")
case len(reqSetID) != 32:
return nil, errors.New("AMP set_id must be 32 bytes")
}
var (
rootShare [32]byte
setID [32]byte
)
copy(rootShare[:], reqRootShare)
copy(setID[:], reqSetID)
return record.NewAMP(rootShare, setID, reqAMP.ChildIndex), nil
}
// MarshalHTLCAttempt constructs an RPC HTLCAttempt from the db representation. // MarshalHTLCAttempt constructs an RPC HTLCAttempt from the db representation.
func (r *RouterBackend) MarshalHTLCAttempt( func (r *RouterBackend) MarshalHTLCAttempt(
htlc channeldb.HTLCAttempt) (*lnrpc.HTLCAttempt, error) { htlc channeldb.HTLCAttempt) (*lnrpc.HTLCAttempt, error) {

View File

@ -12,6 +12,7 @@ import (
"github.com/lightningnetwork/lnd/record" "github.com/lightningnetwork/lnd/record"
"github.com/lightningnetwork/lnd/routing" "github.com/lightningnetwork/lnd/routing"
"github.com/lightningnetwork/lnd/routing/route" "github.com/lightningnetwork/lnd/routing/route"
"github.com/stretchr/testify/require"
"github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc"
) )
@ -239,18 +240,18 @@ func (m *mockMissionControl) GetPairHistorySnapshot(fromNode,
return routing.TimedPairResult{} return routing.TimedPairResult{}
} }
type mppOutcome byte type recordParseOutcome byte
const ( const (
valid mppOutcome = iota valid recordParseOutcome = iota
invalid invalid
nompp norecord
) )
type unmarshalMPPTest struct { type unmarshalMPPTest struct {
name string name string
mpp *lnrpc.MPPRecord mpp *lnrpc.MPPRecord
outcome mppOutcome outcome recordParseOutcome
} }
// TestUnmarshalMPP checks both positive and negative cases of UnmarshalMPP to // TestUnmarshalMPP checks both positive and negative cases of UnmarshalMPP to
@ -262,7 +263,7 @@ func TestUnmarshalMPP(t *testing.T) {
{ {
name: "nil record", name: "nil record",
mpp: nil, mpp: nil,
outcome: nompp, outcome: norecord,
}, },
{ {
name: "invalid total or addr", name: "invalid total or addr",
@ -346,7 +347,7 @@ func testUnmarshalMPP(t *testing.T, test unmarshalMPPTest) {
// Arguments that produce no MPP field should return no error and no MPP // Arguments that produce no MPP field should return no error and no MPP
// record. // record.
case nompp: case norecord:
if err != nil { if err != nil {
t.Fatalf("failure for args resulting for no-mpp") t.Fatalf("failure for args resulting for no-mpp")
} }
@ -358,3 +359,95 @@ func testUnmarshalMPP(t *testing.T, test unmarshalMPPTest) {
t.Fatalf("test case has non-standard outcome") t.Fatalf("test case has non-standard outcome")
} }
} }
type unmarshalAMPTest struct {
name string
amp *lnrpc.AMPRecord
outcome recordParseOutcome
}
// TestUnmarshalAMP asserts the behavior of decoding an RPC AMPRecord.
func TestUnmarshalAMP(t *testing.T) {
rootShare := bytes.Repeat([]byte{0x01}, 32)
setID := bytes.Repeat([]byte{0x02}, 32)
// All child indexes are valid.
childIndex := uint32(3)
tests := []unmarshalAMPTest{
{
name: "nil record",
amp: nil,
outcome: norecord,
},
{
name: "invalid root share invalid set id",
amp: &lnrpc.AMPRecord{
RootShare: []byte{0x01},
SetId: []byte{0x02},
ChildIndex: childIndex,
},
outcome: invalid,
},
{
name: "valid root share invalid set id",
amp: &lnrpc.AMPRecord{
RootShare: rootShare,
SetId: []byte{0x02},
ChildIndex: childIndex,
},
outcome: invalid,
},
{
name: "invalid root share valid set id",
amp: &lnrpc.AMPRecord{
RootShare: []byte{0x01},
SetId: setID,
ChildIndex: childIndex,
},
outcome: invalid,
},
{
name: "valid root share valid set id",
amp: &lnrpc.AMPRecord{
RootShare: rootShare,
SetId: setID,
ChildIndex: childIndex,
},
outcome: valid,
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
testUnmarshalAMP(t, test)
})
}
}
func testUnmarshalAMP(t *testing.T, test unmarshalAMPTest) {
amp, err := UnmarshalAMP(test.amp)
switch test.outcome {
case valid:
require.NoError(t, err)
require.NotNil(t, amp)
rootShare := amp.RootShare()
setID := amp.SetID()
require.Equal(t, test.amp.RootShare, rootShare[:])
require.Equal(t, test.amp.SetId, setID[:])
require.Equal(t, test.amp.ChildIndex, amp.ChildIndex())
case invalid:
require.Error(t, err)
require.Nil(t, amp)
case norecord:
require.NoError(t, err)
require.Nil(t, amp)
default:
t.Fatalf("test case has non-standard outcome")
}
}

View File

@ -613,7 +613,7 @@ func (x Invoice_InvoiceState) String() string {
} }
func (Invoice_InvoiceState) EnumDescriptor() ([]byte, []int) { func (Invoice_InvoiceState) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{111, 0} return fileDescriptor_77a6da22d6a3feb1, []int{112, 0}
} }
type Payment_PaymentStatus int32 type Payment_PaymentStatus int32
@ -644,7 +644,7 @@ func (x Payment_PaymentStatus) String() string {
} }
func (Payment_PaymentStatus) EnumDescriptor() ([]byte, []int) { func (Payment_PaymentStatus) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{119, 0} return fileDescriptor_77a6da22d6a3feb1, []int{120, 0}
} }
type HTLCAttempt_HTLCStatus int32 type HTLCAttempt_HTLCStatus int32
@ -672,7 +672,7 @@ func (x HTLCAttempt_HTLCStatus) String() string {
} }
func (HTLCAttempt_HTLCStatus) EnumDescriptor() ([]byte, []int) { func (HTLCAttempt_HTLCStatus) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{120, 0} return fileDescriptor_77a6da22d6a3feb1, []int{121, 0}
} }
type Failure_FailureCode int32 type Failure_FailureCode int32
@ -786,7 +786,7 @@ func (x Failure_FailureCode) String() string {
} }
func (Failure_FailureCode) EnumDescriptor() ([]byte, []int) { func (Failure_FailureCode) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{160, 0} return fileDescriptor_77a6da22d6a3feb1, []int{161, 0}
} }
type Utxo struct { type Utxo struct {
@ -7717,11 +7717,19 @@ type Hop struct {
TlvPayload bool `protobuf:"varint,9,opt,name=tlv_payload,json=tlvPayload,proto3" json:"tlv_payload,omitempty"` TlvPayload bool `protobuf:"varint,9,opt,name=tlv_payload,json=tlvPayload,proto3" json:"tlv_payload,omitempty"`
// //
//An optional TLV record that signals the use of an MPP payment. If present, //An optional TLV record that signals the use of an MPP payment. If present,
//the receiver will enforce that that the same mpp_record is included in the //the receiver will enforce that the same mpp_record is included in the final
//final hop payload of all non-zero payments in the HTLC set. If empty, a //hop payload of all non-zero payments in the HTLC set. If empty, a regular
//regular single-shot payment is or was attempted. //single-shot payment is or was attempted.
MppRecord *MPPRecord `protobuf:"bytes,10,opt,name=mpp_record,json=mppRecord,proto3" json:"mpp_record,omitempty"` MppRecord *MPPRecord `protobuf:"bytes,10,opt,name=mpp_record,json=mppRecord,proto3" json:"mpp_record,omitempty"`
// //
//An optional TLV record that signals the use of an AMP payment. If present,
//the receiver will treat all received payments including the same
//(payment_addr, set_id) pair as being part of one logical payment. The
//payment will be settled by XORing the root_share's together and deriving the
//child hashes and preimages according to BOLT XX. Must be used in conjunction
//with mpp_record.
AmpRecord *AMPRecord `protobuf:"bytes,12,opt,name=amp_record,json=ampRecord,proto3" json:"amp_record,omitempty"`
//
//An optional set of key-value TLV records. This is useful within the context //An optional set of key-value TLV records. This is useful within the context
//of the SendToRoute call as it allows callers to specify arbitrary K-V pairs //of the SendToRoute call as it allows callers to specify arbitrary K-V pairs
//to drop off at each hop within the onion. //to drop off at each hop within the onion.
@ -7828,6 +7836,13 @@ func (m *Hop) GetMppRecord() *MPPRecord {
return nil return nil
} }
func (m *Hop) GetAmpRecord() *AMPRecord {
if m != nil {
return m.AmpRecord
}
return nil
}
func (m *Hop) GetCustomRecords() map[uint64][]byte { func (m *Hop) GetCustomRecords() map[uint64][]byte {
if m != nil { if m != nil {
return m.CustomRecords return m.CustomRecords
@ -7892,6 +7907,61 @@ func (m *MPPRecord) GetTotalAmtMsat() int64 {
return 0 return 0
} }
type AMPRecord struct {
RootShare []byte `protobuf:"bytes,1,opt,name=root_share,json=rootShare,proto3" json:"root_share,omitempty"`
SetId []byte `protobuf:"bytes,2,opt,name=set_id,json=setId,proto3" json:"set_id,omitempty"`
ChildIndex uint32 `protobuf:"varint,3,opt,name=child_index,json=childIndex,proto3" json:"child_index,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *AMPRecord) Reset() { *m = AMPRecord{} }
func (m *AMPRecord) String() string { return proto.CompactTextString(m) }
func (*AMPRecord) ProtoMessage() {}
func (*AMPRecord) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{87}
}
func (m *AMPRecord) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_AMPRecord.Unmarshal(m, b)
}
func (m *AMPRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_AMPRecord.Marshal(b, m, deterministic)
}
func (m *AMPRecord) XXX_Merge(src proto.Message) {
xxx_messageInfo_AMPRecord.Merge(m, src)
}
func (m *AMPRecord) XXX_Size() int {
return xxx_messageInfo_AMPRecord.Size(m)
}
func (m *AMPRecord) XXX_DiscardUnknown() {
xxx_messageInfo_AMPRecord.DiscardUnknown(m)
}
var xxx_messageInfo_AMPRecord proto.InternalMessageInfo
func (m *AMPRecord) GetRootShare() []byte {
if m != nil {
return m.RootShare
}
return nil
}
func (m *AMPRecord) GetSetId() []byte {
if m != nil {
return m.SetId
}
return nil
}
func (m *AMPRecord) GetChildIndex() uint32 {
if m != nil {
return m.ChildIndex
}
return 0
}
// //
//A path through the channel graph which runs over one or more channels in //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 //succession. This struct carries all the information required to craft the
@ -7935,7 +8005,7 @@ func (m *Route) Reset() { *m = Route{} }
func (m *Route) String() string { return proto.CompactTextString(m) } func (m *Route) String() string { return proto.CompactTextString(m) }
func (*Route) ProtoMessage() {} func (*Route) ProtoMessage() {}
func (*Route) Descriptor() ([]byte, []int) { func (*Route) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{87} return fileDescriptor_77a6da22d6a3feb1, []int{88}
} }
func (m *Route) XXX_Unmarshal(b []byte) error { func (m *Route) XXX_Unmarshal(b []byte) error {
@ -8014,7 +8084,7 @@ func (m *NodeInfoRequest) Reset() { *m = NodeInfoRequest{} }
func (m *NodeInfoRequest) String() string { return proto.CompactTextString(m) } func (m *NodeInfoRequest) String() string { return proto.CompactTextString(m) }
func (*NodeInfoRequest) ProtoMessage() {} func (*NodeInfoRequest) ProtoMessage() {}
func (*NodeInfoRequest) Descriptor() ([]byte, []int) { func (*NodeInfoRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{88} return fileDescriptor_77a6da22d6a3feb1, []int{89}
} }
func (m *NodeInfoRequest) XXX_Unmarshal(b []byte) error { func (m *NodeInfoRequest) XXX_Unmarshal(b []byte) error {
@ -8071,7 +8141,7 @@ func (m *NodeInfo) Reset() { *m = NodeInfo{} }
func (m *NodeInfo) String() string { return proto.CompactTextString(m) } func (m *NodeInfo) String() string { return proto.CompactTextString(m) }
func (*NodeInfo) ProtoMessage() {} func (*NodeInfo) ProtoMessage() {}
func (*NodeInfo) Descriptor() ([]byte, []int) { func (*NodeInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{89} return fileDescriptor_77a6da22d6a3feb1, []int{90}
} }
func (m *NodeInfo) XXX_Unmarshal(b []byte) error { func (m *NodeInfo) XXX_Unmarshal(b []byte) error {
@ -8141,7 +8211,7 @@ func (m *LightningNode) Reset() { *m = LightningNode{} }
func (m *LightningNode) String() string { return proto.CompactTextString(m) } func (m *LightningNode) String() string { return proto.CompactTextString(m) }
func (*LightningNode) ProtoMessage() {} func (*LightningNode) ProtoMessage() {}
func (*LightningNode) Descriptor() ([]byte, []int) { func (*LightningNode) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{90} return fileDescriptor_77a6da22d6a3feb1, []int{91}
} }
func (m *LightningNode) XXX_Unmarshal(b []byte) error { func (m *LightningNode) XXX_Unmarshal(b []byte) error {
@ -8216,7 +8286,7 @@ func (m *NodeAddress) Reset() { *m = NodeAddress{} }
func (m *NodeAddress) String() string { return proto.CompactTextString(m) } func (m *NodeAddress) String() string { return proto.CompactTextString(m) }
func (*NodeAddress) ProtoMessage() {} func (*NodeAddress) ProtoMessage() {}
func (*NodeAddress) Descriptor() ([]byte, []int) { func (*NodeAddress) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{91} return fileDescriptor_77a6da22d6a3feb1, []int{92}
} }
func (m *NodeAddress) XXX_Unmarshal(b []byte) error { func (m *NodeAddress) XXX_Unmarshal(b []byte) error {
@ -8268,7 +8338,7 @@ func (m *RoutingPolicy) Reset() { *m = RoutingPolicy{} }
func (m *RoutingPolicy) String() string { return proto.CompactTextString(m) } func (m *RoutingPolicy) String() string { return proto.CompactTextString(m) }
func (*RoutingPolicy) ProtoMessage() {} func (*RoutingPolicy) ProtoMessage() {}
func (*RoutingPolicy) Descriptor() ([]byte, []int) { func (*RoutingPolicy) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{92} return fileDescriptor_77a6da22d6a3feb1, []int{93}
} }
func (m *RoutingPolicy) XXX_Unmarshal(b []byte) error { func (m *RoutingPolicy) XXX_Unmarshal(b []byte) error {
@ -8366,7 +8436,7 @@ func (m *ChannelEdge) Reset() { *m = ChannelEdge{} }
func (m *ChannelEdge) String() string { return proto.CompactTextString(m) } func (m *ChannelEdge) String() string { return proto.CompactTextString(m) }
func (*ChannelEdge) ProtoMessage() {} func (*ChannelEdge) ProtoMessage() {}
func (*ChannelEdge) Descriptor() ([]byte, []int) { func (*ChannelEdge) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{93} return fileDescriptor_77a6da22d6a3feb1, []int{94}
} }
func (m *ChannelEdge) XXX_Unmarshal(b []byte) error { func (m *ChannelEdge) XXX_Unmarshal(b []byte) error {
@ -8459,7 +8529,7 @@ func (m *ChannelGraphRequest) Reset() { *m = ChannelGraphRequest{} }
func (m *ChannelGraphRequest) String() string { return proto.CompactTextString(m) } func (m *ChannelGraphRequest) String() string { return proto.CompactTextString(m) }
func (*ChannelGraphRequest) ProtoMessage() {} func (*ChannelGraphRequest) ProtoMessage() {}
func (*ChannelGraphRequest) Descriptor() ([]byte, []int) { func (*ChannelGraphRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{94} return fileDescriptor_77a6da22d6a3feb1, []int{95}
} }
func (m *ChannelGraphRequest) XXX_Unmarshal(b []byte) error { func (m *ChannelGraphRequest) XXX_Unmarshal(b []byte) error {
@ -8502,7 +8572,7 @@ func (m *ChannelGraph) Reset() { *m = ChannelGraph{} }
func (m *ChannelGraph) String() string { return proto.CompactTextString(m) } func (m *ChannelGraph) String() string { return proto.CompactTextString(m) }
func (*ChannelGraph) ProtoMessage() {} func (*ChannelGraph) ProtoMessage() {}
func (*ChannelGraph) Descriptor() ([]byte, []int) { func (*ChannelGraph) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{95} return fileDescriptor_77a6da22d6a3feb1, []int{96}
} }
func (m *ChannelGraph) XXX_Unmarshal(b []byte) error { func (m *ChannelGraph) XXX_Unmarshal(b []byte) error {
@ -8549,7 +8619,7 @@ func (m *NodeMetricsRequest) Reset() { *m = NodeMetricsRequest{} }
func (m *NodeMetricsRequest) String() string { return proto.CompactTextString(m) } func (m *NodeMetricsRequest) String() string { return proto.CompactTextString(m) }
func (*NodeMetricsRequest) ProtoMessage() {} func (*NodeMetricsRequest) ProtoMessage() {}
func (*NodeMetricsRequest) Descriptor() ([]byte, []int) { func (*NodeMetricsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{96} return fileDescriptor_77a6da22d6a3feb1, []int{97}
} }
func (m *NodeMetricsRequest) XXX_Unmarshal(b []byte) error { func (m *NodeMetricsRequest) XXX_Unmarshal(b []byte) error {
@ -8594,7 +8664,7 @@ func (m *NodeMetricsResponse) Reset() { *m = NodeMetricsResponse{} }
func (m *NodeMetricsResponse) String() string { return proto.CompactTextString(m) } func (m *NodeMetricsResponse) String() string { return proto.CompactTextString(m) }
func (*NodeMetricsResponse) ProtoMessage() {} func (*NodeMetricsResponse) ProtoMessage() {}
func (*NodeMetricsResponse) Descriptor() ([]byte, []int) { func (*NodeMetricsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{97} return fileDescriptor_77a6da22d6a3feb1, []int{98}
} }
func (m *NodeMetricsResponse) XXX_Unmarshal(b []byte) error { func (m *NodeMetricsResponse) XXX_Unmarshal(b []byte) error {
@ -8636,7 +8706,7 @@ func (m *FloatMetric) Reset() { *m = FloatMetric{} }
func (m *FloatMetric) String() string { return proto.CompactTextString(m) } func (m *FloatMetric) String() string { return proto.CompactTextString(m) }
func (*FloatMetric) ProtoMessage() {} func (*FloatMetric) ProtoMessage() {}
func (*FloatMetric) Descriptor() ([]byte, []int) { func (*FloatMetric) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{98} return fileDescriptor_77a6da22d6a3feb1, []int{99}
} }
func (m *FloatMetric) XXX_Unmarshal(b []byte) error { func (m *FloatMetric) XXX_Unmarshal(b []byte) error {
@ -8686,7 +8756,7 @@ func (m *ChanInfoRequest) Reset() { *m = ChanInfoRequest{} }
func (m *ChanInfoRequest) String() string { return proto.CompactTextString(m) } func (m *ChanInfoRequest) String() string { return proto.CompactTextString(m) }
func (*ChanInfoRequest) ProtoMessage() {} func (*ChanInfoRequest) ProtoMessage() {}
func (*ChanInfoRequest) Descriptor() ([]byte, []int) { func (*ChanInfoRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{99} return fileDescriptor_77a6da22d6a3feb1, []int{100}
} }
func (m *ChanInfoRequest) XXX_Unmarshal(b []byte) error { func (m *ChanInfoRequest) XXX_Unmarshal(b []byte) error {
@ -8724,7 +8794,7 @@ func (m *NetworkInfoRequest) Reset() { *m = NetworkInfoRequest{} }
func (m *NetworkInfoRequest) String() string { return proto.CompactTextString(m) } func (m *NetworkInfoRequest) String() string { return proto.CompactTextString(m) }
func (*NetworkInfoRequest) ProtoMessage() {} func (*NetworkInfoRequest) ProtoMessage() {}
func (*NetworkInfoRequest) Descriptor() ([]byte, []int) { func (*NetworkInfoRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{100} return fileDescriptor_77a6da22d6a3feb1, []int{101}
} }
func (m *NetworkInfoRequest) XXX_Unmarshal(b []byte) error { func (m *NetworkInfoRequest) XXX_Unmarshal(b []byte) error {
@ -8767,7 +8837,7 @@ func (m *NetworkInfo) Reset() { *m = NetworkInfo{} }
func (m *NetworkInfo) String() string { return proto.CompactTextString(m) } func (m *NetworkInfo) String() string { return proto.CompactTextString(m) }
func (*NetworkInfo) ProtoMessage() {} func (*NetworkInfo) ProtoMessage() {}
func (*NetworkInfo) Descriptor() ([]byte, []int) { func (*NetworkInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{101} return fileDescriptor_77a6da22d6a3feb1, []int{102}
} }
func (m *NetworkInfo) XXX_Unmarshal(b []byte) error { func (m *NetworkInfo) XXX_Unmarshal(b []byte) error {
@ -8875,7 +8945,7 @@ func (m *StopRequest) Reset() { *m = StopRequest{} }
func (m *StopRequest) String() string { return proto.CompactTextString(m) } func (m *StopRequest) String() string { return proto.CompactTextString(m) }
func (*StopRequest) ProtoMessage() {} func (*StopRequest) ProtoMessage() {}
func (*StopRequest) Descriptor() ([]byte, []int) { func (*StopRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{102} return fileDescriptor_77a6da22d6a3feb1, []int{103}
} }
func (m *StopRequest) XXX_Unmarshal(b []byte) error { func (m *StopRequest) XXX_Unmarshal(b []byte) error {
@ -8906,7 +8976,7 @@ func (m *StopResponse) Reset() { *m = StopResponse{} }
func (m *StopResponse) String() string { return proto.CompactTextString(m) } func (m *StopResponse) String() string { return proto.CompactTextString(m) }
func (*StopResponse) ProtoMessage() {} func (*StopResponse) ProtoMessage() {}
func (*StopResponse) Descriptor() ([]byte, []int) { func (*StopResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{103} return fileDescriptor_77a6da22d6a3feb1, []int{104}
} }
func (m *StopResponse) XXX_Unmarshal(b []byte) error { func (m *StopResponse) XXX_Unmarshal(b []byte) error {
@ -8937,7 +9007,7 @@ func (m *GraphTopologySubscription) Reset() { *m = GraphTopologySubscrip
func (m *GraphTopologySubscription) String() string { return proto.CompactTextString(m) } func (m *GraphTopologySubscription) String() string { return proto.CompactTextString(m) }
func (*GraphTopologySubscription) ProtoMessage() {} func (*GraphTopologySubscription) ProtoMessage() {}
func (*GraphTopologySubscription) Descriptor() ([]byte, []int) { func (*GraphTopologySubscription) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{104} return fileDescriptor_77a6da22d6a3feb1, []int{105}
} }
func (m *GraphTopologySubscription) XXX_Unmarshal(b []byte) error { func (m *GraphTopologySubscription) XXX_Unmarshal(b []byte) error {
@ -8971,7 +9041,7 @@ func (m *GraphTopologyUpdate) Reset() { *m = GraphTopologyUpdate{} }
func (m *GraphTopologyUpdate) String() string { return proto.CompactTextString(m) } func (m *GraphTopologyUpdate) String() string { return proto.CompactTextString(m) }
func (*GraphTopologyUpdate) ProtoMessage() {} func (*GraphTopologyUpdate) ProtoMessage() {}
func (*GraphTopologyUpdate) Descriptor() ([]byte, []int) { func (*GraphTopologyUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{105} return fileDescriptor_77a6da22d6a3feb1, []int{106}
} }
func (m *GraphTopologyUpdate) XXX_Unmarshal(b []byte) error { func (m *GraphTopologyUpdate) XXX_Unmarshal(b []byte) error {
@ -9032,7 +9102,7 @@ func (m *NodeUpdate) Reset() { *m = NodeUpdate{} }
func (m *NodeUpdate) String() string { return proto.CompactTextString(m) } func (m *NodeUpdate) String() string { return proto.CompactTextString(m) }
func (*NodeUpdate) ProtoMessage() {} func (*NodeUpdate) ProtoMessage() {}
func (*NodeUpdate) Descriptor() ([]byte, []int) { func (*NodeUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{106} return fileDescriptor_77a6da22d6a3feb1, []int{107}
} }
func (m *NodeUpdate) XXX_Unmarshal(b []byte) error { func (m *NodeUpdate) XXX_Unmarshal(b []byte) error {
@ -9116,7 +9186,7 @@ func (m *ChannelEdgeUpdate) Reset() { *m = ChannelEdgeUpdate{} }
func (m *ChannelEdgeUpdate) String() string { return proto.CompactTextString(m) } func (m *ChannelEdgeUpdate) String() string { return proto.CompactTextString(m) }
func (*ChannelEdgeUpdate) ProtoMessage() {} func (*ChannelEdgeUpdate) ProtoMessage() {}
func (*ChannelEdgeUpdate) Descriptor() ([]byte, []int) { func (*ChannelEdgeUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{107} return fileDescriptor_77a6da22d6a3feb1, []int{108}
} }
func (m *ChannelEdgeUpdate) XXX_Unmarshal(b []byte) error { func (m *ChannelEdgeUpdate) XXX_Unmarshal(b []byte) error {
@ -9197,7 +9267,7 @@ func (m *ClosedChannelUpdate) Reset() { *m = ClosedChannelUpdate{} }
func (m *ClosedChannelUpdate) String() string { return proto.CompactTextString(m) } func (m *ClosedChannelUpdate) String() string { return proto.CompactTextString(m) }
func (*ClosedChannelUpdate) ProtoMessage() {} func (*ClosedChannelUpdate) ProtoMessage() {}
func (*ClosedChannelUpdate) Descriptor() ([]byte, []int) { func (*ClosedChannelUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{108} return fileDescriptor_77a6da22d6a3feb1, []int{109}
} }
func (m *ClosedChannelUpdate) XXX_Unmarshal(b []byte) error { func (m *ClosedChannelUpdate) XXX_Unmarshal(b []byte) error {
@ -9268,7 +9338,7 @@ func (m *HopHint) Reset() { *m = HopHint{} }
func (m *HopHint) String() string { return proto.CompactTextString(m) } func (m *HopHint) String() string { return proto.CompactTextString(m) }
func (*HopHint) ProtoMessage() {} func (*HopHint) ProtoMessage() {}
func (*HopHint) Descriptor() ([]byte, []int) { func (*HopHint) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{109} return fileDescriptor_77a6da22d6a3feb1, []int{110}
} }
func (m *HopHint) XXX_Unmarshal(b []byte) error { func (m *HopHint) XXX_Unmarshal(b []byte) error {
@ -9338,7 +9408,7 @@ func (m *RouteHint) Reset() { *m = RouteHint{} }
func (m *RouteHint) String() string { return proto.CompactTextString(m) } func (m *RouteHint) String() string { return proto.CompactTextString(m) }
func (*RouteHint) ProtoMessage() {} func (*RouteHint) ProtoMessage() {}
func (*RouteHint) Descriptor() ([]byte, []int) { func (*RouteHint) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{110} return fileDescriptor_77a6da22d6a3feb1, []int{111}
} }
func (m *RouteHint) XXX_Unmarshal(b []byte) error { func (m *RouteHint) XXX_Unmarshal(b []byte) error {
@ -9476,7 +9546,7 @@ func (m *Invoice) Reset() { *m = Invoice{} }
func (m *Invoice) String() string { return proto.CompactTextString(m) } func (m *Invoice) String() string { return proto.CompactTextString(m) }
func (*Invoice) ProtoMessage() {} func (*Invoice) ProtoMessage() {}
func (*Invoice) Descriptor() ([]byte, []int) { func (*Invoice) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{111} return fileDescriptor_77a6da22d6a3feb1, []int{112}
} }
func (m *Invoice) XXX_Unmarshal(b []byte) error { func (m *Invoice) XXX_Unmarshal(b []byte) error {
@ -9707,7 +9777,7 @@ func (m *InvoiceHTLC) Reset() { *m = InvoiceHTLC{} }
func (m *InvoiceHTLC) String() string { return proto.CompactTextString(m) } func (m *InvoiceHTLC) String() string { return proto.CompactTextString(m) }
func (*InvoiceHTLC) ProtoMessage() {} func (*InvoiceHTLC) ProtoMessage() {}
func (*InvoiceHTLC) Descriptor() ([]byte, []int) { func (*InvoiceHTLC) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{112} return fileDescriptor_77a6da22d6a3feb1, []int{113}
} }
func (m *InvoiceHTLC) XXX_Unmarshal(b []byte) error { func (m *InvoiceHTLC) XXX_Unmarshal(b []byte) error {
@ -9830,7 +9900,7 @@ func (m *AMP) Reset() { *m = AMP{} }
func (m *AMP) String() string { return proto.CompactTextString(m) } func (m *AMP) String() string { return proto.CompactTextString(m) }
func (*AMP) ProtoMessage() {} func (*AMP) ProtoMessage() {}
func (*AMP) Descriptor() ([]byte, []int) { func (*AMP) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{113} return fileDescriptor_77a6da22d6a3feb1, []int{114}
} }
func (m *AMP) XXX_Unmarshal(b []byte) error { func (m *AMP) XXX_Unmarshal(b []byte) error {
@ -9913,7 +9983,7 @@ func (m *AddInvoiceResponse) Reset() { *m = AddInvoiceResponse{} }
func (m *AddInvoiceResponse) String() string { return proto.CompactTextString(m) } func (m *AddInvoiceResponse) String() string { return proto.CompactTextString(m) }
func (*AddInvoiceResponse) ProtoMessage() {} func (*AddInvoiceResponse) ProtoMessage() {}
func (*AddInvoiceResponse) Descriptor() ([]byte, []int) { func (*AddInvoiceResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{114} return fileDescriptor_77a6da22d6a3feb1, []int{115}
} }
func (m *AddInvoiceResponse) XXX_Unmarshal(b []byte) error { func (m *AddInvoiceResponse) XXX_Unmarshal(b []byte) error {
@ -9982,7 +10052,7 @@ func (m *PaymentHash) Reset() { *m = PaymentHash{} }
func (m *PaymentHash) String() string { return proto.CompactTextString(m) } func (m *PaymentHash) String() string { return proto.CompactTextString(m) }
func (*PaymentHash) ProtoMessage() {} func (*PaymentHash) ProtoMessage() {}
func (*PaymentHash) Descriptor() ([]byte, []int) { func (*PaymentHash) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{115} return fileDescriptor_77a6da22d6a3feb1, []int{116}
} }
func (m *PaymentHash) XXX_Unmarshal(b []byte) error { func (m *PaymentHash) XXX_Unmarshal(b []byte) error {
@ -10042,7 +10112,7 @@ func (m *ListInvoiceRequest) Reset() { *m = ListInvoiceRequest{} }
func (m *ListInvoiceRequest) String() string { return proto.CompactTextString(m) } func (m *ListInvoiceRequest) String() string { return proto.CompactTextString(m) }
func (*ListInvoiceRequest) ProtoMessage() {} func (*ListInvoiceRequest) ProtoMessage() {}
func (*ListInvoiceRequest) Descriptor() ([]byte, []int) { func (*ListInvoiceRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{116} return fileDescriptor_77a6da22d6a3feb1, []int{117}
} }
func (m *ListInvoiceRequest) XXX_Unmarshal(b []byte) error { func (m *ListInvoiceRequest) XXX_Unmarshal(b []byte) error {
@ -10113,7 +10183,7 @@ func (m *ListInvoiceResponse) Reset() { *m = ListInvoiceResponse{} }
func (m *ListInvoiceResponse) String() string { return proto.CompactTextString(m) } func (m *ListInvoiceResponse) String() string { return proto.CompactTextString(m) }
func (*ListInvoiceResponse) ProtoMessage() {} func (*ListInvoiceResponse) ProtoMessage() {}
func (*ListInvoiceResponse) Descriptor() ([]byte, []int) { func (*ListInvoiceResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{117} return fileDescriptor_77a6da22d6a3feb1, []int{118}
} }
func (m *ListInvoiceResponse) XXX_Unmarshal(b []byte) error { func (m *ListInvoiceResponse) XXX_Unmarshal(b []byte) error {
@ -10177,7 +10247,7 @@ func (m *InvoiceSubscription) Reset() { *m = InvoiceSubscription{} }
func (m *InvoiceSubscription) String() string { return proto.CompactTextString(m) } func (m *InvoiceSubscription) String() string { return proto.CompactTextString(m) }
func (*InvoiceSubscription) ProtoMessage() {} func (*InvoiceSubscription) ProtoMessage() {}
func (*InvoiceSubscription) Descriptor() ([]byte, []int) { func (*InvoiceSubscription) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{118} return fileDescriptor_77a6da22d6a3feb1, []int{119}
} }
func (m *InvoiceSubscription) XXX_Unmarshal(b []byte) error { func (m *InvoiceSubscription) XXX_Unmarshal(b []byte) error {
@ -10254,7 +10324,7 @@ func (m *Payment) Reset() { *m = Payment{} }
func (m *Payment) String() string { return proto.CompactTextString(m) } func (m *Payment) String() string { return proto.CompactTextString(m) }
func (*Payment) ProtoMessage() {} func (*Payment) ProtoMessage() {}
func (*Payment) Descriptor() ([]byte, []int) { func (*Payment) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{119} return fileDescriptor_77a6da22d6a3feb1, []int{120}
} }
func (m *Payment) XXX_Unmarshal(b []byte) error { func (m *Payment) XXX_Unmarshal(b []byte) error {
@ -10409,7 +10479,7 @@ func (m *HTLCAttempt) Reset() { *m = HTLCAttempt{} }
func (m *HTLCAttempt) String() string { return proto.CompactTextString(m) } func (m *HTLCAttempt) String() string { return proto.CompactTextString(m) }
func (*HTLCAttempt) ProtoMessage() {} func (*HTLCAttempt) ProtoMessage() {}
func (*HTLCAttempt) Descriptor() ([]byte, []int) { func (*HTLCAttempt) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{120} return fileDescriptor_77a6da22d6a3feb1, []int{121}
} }
func (m *HTLCAttempt) XXX_Unmarshal(b []byte) error { func (m *HTLCAttempt) XXX_Unmarshal(b []byte) error {
@ -10509,7 +10579,7 @@ func (m *ListPaymentsRequest) Reset() { *m = ListPaymentsRequest{} }
func (m *ListPaymentsRequest) String() string { return proto.CompactTextString(m) } func (m *ListPaymentsRequest) String() string { return proto.CompactTextString(m) }
func (*ListPaymentsRequest) ProtoMessage() {} func (*ListPaymentsRequest) ProtoMessage() {}
func (*ListPaymentsRequest) Descriptor() ([]byte, []int) { func (*ListPaymentsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{121} return fileDescriptor_77a6da22d6a3feb1, []int{122}
} }
func (m *ListPaymentsRequest) XXX_Unmarshal(b []byte) error { func (m *ListPaymentsRequest) XXX_Unmarshal(b []byte) error {
@ -10578,7 +10648,7 @@ func (m *ListPaymentsResponse) Reset() { *m = ListPaymentsResponse{} }
func (m *ListPaymentsResponse) String() string { return proto.CompactTextString(m) } func (m *ListPaymentsResponse) String() string { return proto.CompactTextString(m) }
func (*ListPaymentsResponse) ProtoMessage() {} func (*ListPaymentsResponse) ProtoMessage() {}
func (*ListPaymentsResponse) Descriptor() ([]byte, []int) { func (*ListPaymentsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{122} return fileDescriptor_77a6da22d6a3feb1, []int{123}
} }
func (m *ListPaymentsResponse) XXX_Unmarshal(b []byte) error { func (m *ListPaymentsResponse) XXX_Unmarshal(b []byte) error {
@ -10635,7 +10705,7 @@ func (m *DeleteAllPaymentsRequest) Reset() { *m = DeleteAllPaymentsReque
func (m *DeleteAllPaymentsRequest) String() string { return proto.CompactTextString(m) } func (m *DeleteAllPaymentsRequest) String() string { return proto.CompactTextString(m) }
func (*DeleteAllPaymentsRequest) ProtoMessage() {} func (*DeleteAllPaymentsRequest) ProtoMessage() {}
func (*DeleteAllPaymentsRequest) Descriptor() ([]byte, []int) { func (*DeleteAllPaymentsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{123} return fileDescriptor_77a6da22d6a3feb1, []int{124}
} }
func (m *DeleteAllPaymentsRequest) XXX_Unmarshal(b []byte) error { func (m *DeleteAllPaymentsRequest) XXX_Unmarshal(b []byte) error {
@ -10680,7 +10750,7 @@ func (m *DeleteAllPaymentsResponse) Reset() { *m = DeleteAllPaymentsResp
func (m *DeleteAllPaymentsResponse) String() string { return proto.CompactTextString(m) } func (m *DeleteAllPaymentsResponse) String() string { return proto.CompactTextString(m) }
func (*DeleteAllPaymentsResponse) ProtoMessage() {} func (*DeleteAllPaymentsResponse) ProtoMessage() {}
func (*DeleteAllPaymentsResponse) Descriptor() ([]byte, []int) { func (*DeleteAllPaymentsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{124} return fileDescriptor_77a6da22d6a3feb1, []int{125}
} }
func (m *DeleteAllPaymentsResponse) XXX_Unmarshal(b []byte) error { func (m *DeleteAllPaymentsResponse) XXX_Unmarshal(b []byte) error {
@ -10713,7 +10783,7 @@ func (m *AbandonChannelRequest) Reset() { *m = AbandonChannelRequest{} }
func (m *AbandonChannelRequest) String() string { return proto.CompactTextString(m) } func (m *AbandonChannelRequest) String() string { return proto.CompactTextString(m) }
func (*AbandonChannelRequest) ProtoMessage() {} func (*AbandonChannelRequest) ProtoMessage() {}
func (*AbandonChannelRequest) Descriptor() ([]byte, []int) { func (*AbandonChannelRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{125} return fileDescriptor_77a6da22d6a3feb1, []int{126}
} }
func (m *AbandonChannelRequest) XXX_Unmarshal(b []byte) error { func (m *AbandonChannelRequest) XXX_Unmarshal(b []byte) error {
@ -10758,7 +10828,7 @@ func (m *AbandonChannelResponse) Reset() { *m = AbandonChannelResponse{}
func (m *AbandonChannelResponse) String() string { return proto.CompactTextString(m) } func (m *AbandonChannelResponse) String() string { return proto.CompactTextString(m) }
func (*AbandonChannelResponse) ProtoMessage() {} func (*AbandonChannelResponse) ProtoMessage() {}
func (*AbandonChannelResponse) Descriptor() ([]byte, []int) { func (*AbandonChannelResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{126} return fileDescriptor_77a6da22d6a3feb1, []int{127}
} }
func (m *AbandonChannelResponse) XXX_Unmarshal(b []byte) error { func (m *AbandonChannelResponse) XXX_Unmarshal(b []byte) error {
@ -10791,7 +10861,7 @@ func (m *DebugLevelRequest) Reset() { *m = DebugLevelRequest{} }
func (m *DebugLevelRequest) String() string { return proto.CompactTextString(m) } func (m *DebugLevelRequest) String() string { return proto.CompactTextString(m) }
func (*DebugLevelRequest) ProtoMessage() {} func (*DebugLevelRequest) ProtoMessage() {}
func (*DebugLevelRequest) Descriptor() ([]byte, []int) { func (*DebugLevelRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{127} return fileDescriptor_77a6da22d6a3feb1, []int{128}
} }
func (m *DebugLevelRequest) XXX_Unmarshal(b []byte) error { func (m *DebugLevelRequest) XXX_Unmarshal(b []byte) error {
@ -10837,7 +10907,7 @@ func (m *DebugLevelResponse) Reset() { *m = DebugLevelResponse{} }
func (m *DebugLevelResponse) String() string { return proto.CompactTextString(m) } func (m *DebugLevelResponse) String() string { return proto.CompactTextString(m) }
func (*DebugLevelResponse) ProtoMessage() {} func (*DebugLevelResponse) ProtoMessage() {}
func (*DebugLevelResponse) Descriptor() ([]byte, []int) { func (*DebugLevelResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{128} return fileDescriptor_77a6da22d6a3feb1, []int{129}
} }
func (m *DebugLevelResponse) XXX_Unmarshal(b []byte) error { func (m *DebugLevelResponse) XXX_Unmarshal(b []byte) error {
@ -10877,7 +10947,7 @@ func (m *PayReqString) Reset() { *m = PayReqString{} }
func (m *PayReqString) String() string { return proto.CompactTextString(m) } func (m *PayReqString) String() string { return proto.CompactTextString(m) }
func (*PayReqString) ProtoMessage() {} func (*PayReqString) ProtoMessage() {}
func (*PayReqString) Descriptor() ([]byte, []int) { func (*PayReqString) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{129} return fileDescriptor_77a6da22d6a3feb1, []int{130}
} }
func (m *PayReqString) XXX_Unmarshal(b []byte) error { func (m *PayReqString) XXX_Unmarshal(b []byte) error {
@ -10928,7 +10998,7 @@ func (m *PayReq) Reset() { *m = PayReq{} }
func (m *PayReq) String() string { return proto.CompactTextString(m) } func (m *PayReq) String() string { return proto.CompactTextString(m) }
func (*PayReq) ProtoMessage() {} func (*PayReq) ProtoMessage() {}
func (*PayReq) Descriptor() ([]byte, []int) { func (*PayReq) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{130} return fileDescriptor_77a6da22d6a3feb1, []int{131}
} }
func (m *PayReq) XXX_Unmarshal(b []byte) error { func (m *PayReq) XXX_Unmarshal(b []byte) error {
@ -11053,7 +11123,7 @@ func (m *Feature) Reset() { *m = Feature{} }
func (m *Feature) String() string { return proto.CompactTextString(m) } func (m *Feature) String() string { return proto.CompactTextString(m) }
func (*Feature) ProtoMessage() {} func (*Feature) ProtoMessage() {}
func (*Feature) Descriptor() ([]byte, []int) { func (*Feature) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{131} return fileDescriptor_77a6da22d6a3feb1, []int{132}
} }
func (m *Feature) XXX_Unmarshal(b []byte) error { func (m *Feature) XXX_Unmarshal(b []byte) error {
@ -11105,7 +11175,7 @@ func (m *FeeReportRequest) Reset() { *m = FeeReportRequest{} }
func (m *FeeReportRequest) String() string { return proto.CompactTextString(m) } func (m *FeeReportRequest) String() string { return proto.CompactTextString(m) }
func (*FeeReportRequest) ProtoMessage() {} func (*FeeReportRequest) ProtoMessage() {}
func (*FeeReportRequest) Descriptor() ([]byte, []int) { func (*FeeReportRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{132} return fileDescriptor_77a6da22d6a3feb1, []int{133}
} }
func (m *FeeReportRequest) XXX_Unmarshal(b []byte) error { func (m *FeeReportRequest) XXX_Unmarshal(b []byte) error {
@ -11148,7 +11218,7 @@ func (m *ChannelFeeReport) Reset() { *m = ChannelFeeReport{} }
func (m *ChannelFeeReport) String() string { return proto.CompactTextString(m) } func (m *ChannelFeeReport) String() string { return proto.CompactTextString(m) }
func (*ChannelFeeReport) ProtoMessage() {} func (*ChannelFeeReport) ProtoMessage() {}
func (*ChannelFeeReport) Descriptor() ([]byte, []int) { func (*ChannelFeeReport) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{133} return fileDescriptor_77a6da22d6a3feb1, []int{134}
} }
func (m *ChannelFeeReport) XXX_Unmarshal(b []byte) error { func (m *ChannelFeeReport) XXX_Unmarshal(b []byte) error {
@ -11226,7 +11296,7 @@ func (m *FeeReportResponse) Reset() { *m = FeeReportResponse{} }
func (m *FeeReportResponse) String() string { return proto.CompactTextString(m) } func (m *FeeReportResponse) String() string { return proto.CompactTextString(m) }
func (*FeeReportResponse) ProtoMessage() {} func (*FeeReportResponse) ProtoMessage() {}
func (*FeeReportResponse) Descriptor() ([]byte, []int) { func (*FeeReportResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{134} return fileDescriptor_77a6da22d6a3feb1, []int{135}
} }
func (m *FeeReportResponse) XXX_Unmarshal(b []byte) error { func (m *FeeReportResponse) XXX_Unmarshal(b []byte) error {
@ -11304,7 +11374,7 @@ func (m *PolicyUpdateRequest) Reset() { *m = PolicyUpdateRequest{} }
func (m *PolicyUpdateRequest) String() string { return proto.CompactTextString(m) } func (m *PolicyUpdateRequest) String() string { return proto.CompactTextString(m) }
func (*PolicyUpdateRequest) ProtoMessage() {} func (*PolicyUpdateRequest) ProtoMessage() {}
func (*PolicyUpdateRequest) Descriptor() ([]byte, []int) { func (*PolicyUpdateRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{135} return fileDescriptor_77a6da22d6a3feb1, []int{136}
} }
func (m *PolicyUpdateRequest) XXX_Unmarshal(b []byte) error { func (m *PolicyUpdateRequest) XXX_Unmarshal(b []byte) error {
@ -11422,7 +11492,7 @@ func (m *PolicyUpdateResponse) Reset() { *m = PolicyUpdateResponse{} }
func (m *PolicyUpdateResponse) String() string { return proto.CompactTextString(m) } func (m *PolicyUpdateResponse) String() string { return proto.CompactTextString(m) }
func (*PolicyUpdateResponse) ProtoMessage() {} func (*PolicyUpdateResponse) ProtoMessage() {}
func (*PolicyUpdateResponse) Descriptor() ([]byte, []int) { func (*PolicyUpdateResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{136} return fileDescriptor_77a6da22d6a3feb1, []int{137}
} }
func (m *PolicyUpdateResponse) XXX_Unmarshal(b []byte) error { func (m *PolicyUpdateResponse) XXX_Unmarshal(b []byte) error {
@ -11467,7 +11537,7 @@ func (m *ForwardingHistoryRequest) Reset() { *m = ForwardingHistoryReque
func (m *ForwardingHistoryRequest) String() string { return proto.CompactTextString(m) } func (m *ForwardingHistoryRequest) String() string { return proto.CompactTextString(m) }
func (*ForwardingHistoryRequest) ProtoMessage() {} func (*ForwardingHistoryRequest) ProtoMessage() {}
func (*ForwardingHistoryRequest) Descriptor() ([]byte, []int) { func (*ForwardingHistoryRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{137} return fileDescriptor_77a6da22d6a3feb1, []int{138}
} }
func (m *ForwardingHistoryRequest) XXX_Unmarshal(b []byte) error { func (m *ForwardingHistoryRequest) XXX_Unmarshal(b []byte) error {
@ -11553,7 +11623,7 @@ func (m *ForwardingEvent) Reset() { *m = ForwardingEvent{} }
func (m *ForwardingEvent) String() string { return proto.CompactTextString(m) } func (m *ForwardingEvent) String() string { return proto.CompactTextString(m) }
func (*ForwardingEvent) ProtoMessage() {} func (*ForwardingEvent) ProtoMessage() {}
func (*ForwardingEvent) Descriptor() ([]byte, []int) { func (*ForwardingEvent) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{138} return fileDescriptor_77a6da22d6a3feb1, []int{139}
} }
func (m *ForwardingEvent) XXX_Unmarshal(b []byte) error { func (m *ForwardingEvent) XXX_Unmarshal(b []byte) error {
@ -11661,7 +11731,7 @@ func (m *ForwardingHistoryResponse) Reset() { *m = ForwardingHistoryResp
func (m *ForwardingHistoryResponse) String() string { return proto.CompactTextString(m) } func (m *ForwardingHistoryResponse) String() string { return proto.CompactTextString(m) }
func (*ForwardingHistoryResponse) ProtoMessage() {} func (*ForwardingHistoryResponse) ProtoMessage() {}
func (*ForwardingHistoryResponse) Descriptor() ([]byte, []int) { func (*ForwardingHistoryResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{139} return fileDescriptor_77a6da22d6a3feb1, []int{140}
} }
func (m *ForwardingHistoryResponse) XXX_Unmarshal(b []byte) error { func (m *ForwardingHistoryResponse) XXX_Unmarshal(b []byte) error {
@ -11708,7 +11778,7 @@ func (m *ExportChannelBackupRequest) Reset() { *m = ExportChannelBackupR
func (m *ExportChannelBackupRequest) String() string { return proto.CompactTextString(m) } func (m *ExportChannelBackupRequest) String() string { return proto.CompactTextString(m) }
func (*ExportChannelBackupRequest) ProtoMessage() {} func (*ExportChannelBackupRequest) ProtoMessage() {}
func (*ExportChannelBackupRequest) Descriptor() ([]byte, []int) { func (*ExportChannelBackupRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{140} return fileDescriptor_77a6da22d6a3feb1, []int{141}
} }
func (m *ExportChannelBackupRequest) XXX_Unmarshal(b []byte) error { func (m *ExportChannelBackupRequest) XXX_Unmarshal(b []byte) error {
@ -11755,7 +11825,7 @@ func (m *ChannelBackup) Reset() { *m = ChannelBackup{} }
func (m *ChannelBackup) String() string { return proto.CompactTextString(m) } func (m *ChannelBackup) String() string { return proto.CompactTextString(m) }
func (*ChannelBackup) ProtoMessage() {} func (*ChannelBackup) ProtoMessage() {}
func (*ChannelBackup) Descriptor() ([]byte, []int) { func (*ChannelBackup) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{141} return fileDescriptor_77a6da22d6a3feb1, []int{142}
} }
func (m *ChannelBackup) XXX_Unmarshal(b []byte) error { func (m *ChannelBackup) XXX_Unmarshal(b []byte) error {
@ -11809,7 +11879,7 @@ func (m *MultiChanBackup) Reset() { *m = MultiChanBackup{} }
func (m *MultiChanBackup) String() string { return proto.CompactTextString(m) } func (m *MultiChanBackup) String() string { return proto.CompactTextString(m) }
func (*MultiChanBackup) ProtoMessage() {} func (*MultiChanBackup) ProtoMessage() {}
func (*MultiChanBackup) Descriptor() ([]byte, []int) { func (*MultiChanBackup) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{142} return fileDescriptor_77a6da22d6a3feb1, []int{143}
} }
func (m *MultiChanBackup) XXX_Unmarshal(b []byte) error { func (m *MultiChanBackup) XXX_Unmarshal(b []byte) error {
@ -11854,7 +11924,7 @@ func (m *ChanBackupExportRequest) Reset() { *m = ChanBackupExportRequest
func (m *ChanBackupExportRequest) String() string { return proto.CompactTextString(m) } func (m *ChanBackupExportRequest) String() string { return proto.CompactTextString(m) }
func (*ChanBackupExportRequest) ProtoMessage() {} func (*ChanBackupExportRequest) ProtoMessage() {}
func (*ChanBackupExportRequest) Descriptor() ([]byte, []int) { func (*ChanBackupExportRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{143} return fileDescriptor_77a6da22d6a3feb1, []int{144}
} }
func (m *ChanBackupExportRequest) XXX_Unmarshal(b []byte) error { func (m *ChanBackupExportRequest) XXX_Unmarshal(b []byte) error {
@ -11893,7 +11963,7 @@ func (m *ChanBackupSnapshot) Reset() { *m = ChanBackupSnapshot{} }
func (m *ChanBackupSnapshot) String() string { return proto.CompactTextString(m) } func (m *ChanBackupSnapshot) String() string { return proto.CompactTextString(m) }
func (*ChanBackupSnapshot) ProtoMessage() {} func (*ChanBackupSnapshot) ProtoMessage() {}
func (*ChanBackupSnapshot) Descriptor() ([]byte, []int) { func (*ChanBackupSnapshot) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{144} return fileDescriptor_77a6da22d6a3feb1, []int{145}
} }
func (m *ChanBackupSnapshot) XXX_Unmarshal(b []byte) error { func (m *ChanBackupSnapshot) XXX_Unmarshal(b []byte) error {
@ -11941,7 +12011,7 @@ func (m *ChannelBackups) Reset() { *m = ChannelBackups{} }
func (m *ChannelBackups) String() string { return proto.CompactTextString(m) } func (m *ChannelBackups) String() string { return proto.CompactTextString(m) }
func (*ChannelBackups) ProtoMessage() {} func (*ChannelBackups) ProtoMessage() {}
func (*ChannelBackups) Descriptor() ([]byte, []int) { func (*ChannelBackups) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{145} return fileDescriptor_77a6da22d6a3feb1, []int{146}
} }
func (m *ChannelBackups) XXX_Unmarshal(b []byte) error { func (m *ChannelBackups) XXX_Unmarshal(b []byte) error {
@ -11983,7 +12053,7 @@ func (m *RestoreChanBackupRequest) Reset() { *m = RestoreChanBackupReque
func (m *RestoreChanBackupRequest) String() string { return proto.CompactTextString(m) } func (m *RestoreChanBackupRequest) String() string { return proto.CompactTextString(m) }
func (*RestoreChanBackupRequest) ProtoMessage() {} func (*RestoreChanBackupRequest) ProtoMessage() {}
func (*RestoreChanBackupRequest) Descriptor() ([]byte, []int) { func (*RestoreChanBackupRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{146} return fileDescriptor_77a6da22d6a3feb1, []int{147}
} }
func (m *RestoreChanBackupRequest) XXX_Unmarshal(b []byte) error { func (m *RestoreChanBackupRequest) XXX_Unmarshal(b []byte) error {
@ -12059,7 +12129,7 @@ func (m *RestoreBackupResponse) Reset() { *m = RestoreBackupResponse{} }
func (m *RestoreBackupResponse) String() string { return proto.CompactTextString(m) } func (m *RestoreBackupResponse) String() string { return proto.CompactTextString(m) }
func (*RestoreBackupResponse) ProtoMessage() {} func (*RestoreBackupResponse) ProtoMessage() {}
func (*RestoreBackupResponse) Descriptor() ([]byte, []int) { func (*RestoreBackupResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{147} return fileDescriptor_77a6da22d6a3feb1, []int{148}
} }
func (m *RestoreBackupResponse) XXX_Unmarshal(b []byte) error { func (m *RestoreBackupResponse) XXX_Unmarshal(b []byte) error {
@ -12090,7 +12160,7 @@ func (m *ChannelBackupSubscription) Reset() { *m = ChannelBackupSubscrip
func (m *ChannelBackupSubscription) String() string { return proto.CompactTextString(m) } func (m *ChannelBackupSubscription) String() string { return proto.CompactTextString(m) }
func (*ChannelBackupSubscription) ProtoMessage() {} func (*ChannelBackupSubscription) ProtoMessage() {}
func (*ChannelBackupSubscription) Descriptor() ([]byte, []int) { func (*ChannelBackupSubscription) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{148} return fileDescriptor_77a6da22d6a3feb1, []int{149}
} }
func (m *ChannelBackupSubscription) XXX_Unmarshal(b []byte) error { func (m *ChannelBackupSubscription) XXX_Unmarshal(b []byte) error {
@ -12121,7 +12191,7 @@ func (m *VerifyChanBackupResponse) Reset() { *m = VerifyChanBackupRespon
func (m *VerifyChanBackupResponse) String() string { return proto.CompactTextString(m) } func (m *VerifyChanBackupResponse) String() string { return proto.CompactTextString(m) }
func (*VerifyChanBackupResponse) ProtoMessage() {} func (*VerifyChanBackupResponse) ProtoMessage() {}
func (*VerifyChanBackupResponse) Descriptor() ([]byte, []int) { func (*VerifyChanBackupResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{149} return fileDescriptor_77a6da22d6a3feb1, []int{150}
} }
func (m *VerifyChanBackupResponse) XXX_Unmarshal(b []byte) error { func (m *VerifyChanBackupResponse) XXX_Unmarshal(b []byte) error {
@ -12156,7 +12226,7 @@ func (m *MacaroonPermission) Reset() { *m = MacaroonPermission{} }
func (m *MacaroonPermission) String() string { return proto.CompactTextString(m) } func (m *MacaroonPermission) String() string { return proto.CompactTextString(m) }
func (*MacaroonPermission) ProtoMessage() {} func (*MacaroonPermission) ProtoMessage() {}
func (*MacaroonPermission) Descriptor() ([]byte, []int) { func (*MacaroonPermission) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{150} return fileDescriptor_77a6da22d6a3feb1, []int{151}
} }
func (m *MacaroonPermission) XXX_Unmarshal(b []byte) error { func (m *MacaroonPermission) XXX_Unmarshal(b []byte) error {
@ -12205,7 +12275,7 @@ func (m *BakeMacaroonRequest) Reset() { *m = BakeMacaroonRequest{} }
func (m *BakeMacaroonRequest) String() string { return proto.CompactTextString(m) } func (m *BakeMacaroonRequest) String() string { return proto.CompactTextString(m) }
func (*BakeMacaroonRequest) ProtoMessage() {} func (*BakeMacaroonRequest) ProtoMessage() {}
func (*BakeMacaroonRequest) Descriptor() ([]byte, []int) { func (*BakeMacaroonRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{151} return fileDescriptor_77a6da22d6a3feb1, []int{152}
} }
func (m *BakeMacaroonRequest) XXX_Unmarshal(b []byte) error { func (m *BakeMacaroonRequest) XXX_Unmarshal(b []byte) error {
@ -12252,7 +12322,7 @@ func (m *BakeMacaroonResponse) Reset() { *m = BakeMacaroonResponse{} }
func (m *BakeMacaroonResponse) String() string { return proto.CompactTextString(m) } func (m *BakeMacaroonResponse) String() string { return proto.CompactTextString(m) }
func (*BakeMacaroonResponse) ProtoMessage() {} func (*BakeMacaroonResponse) ProtoMessage() {}
func (*BakeMacaroonResponse) Descriptor() ([]byte, []int) { func (*BakeMacaroonResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{152} return fileDescriptor_77a6da22d6a3feb1, []int{153}
} }
func (m *BakeMacaroonResponse) XXX_Unmarshal(b []byte) error { func (m *BakeMacaroonResponse) XXX_Unmarshal(b []byte) error {
@ -12290,7 +12360,7 @@ func (m *ListMacaroonIDsRequest) Reset() { *m = ListMacaroonIDsRequest{}
func (m *ListMacaroonIDsRequest) String() string { return proto.CompactTextString(m) } func (m *ListMacaroonIDsRequest) String() string { return proto.CompactTextString(m) }
func (*ListMacaroonIDsRequest) ProtoMessage() {} func (*ListMacaroonIDsRequest) ProtoMessage() {}
func (*ListMacaroonIDsRequest) Descriptor() ([]byte, []int) { func (*ListMacaroonIDsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{153} return fileDescriptor_77a6da22d6a3feb1, []int{154}
} }
func (m *ListMacaroonIDsRequest) XXX_Unmarshal(b []byte) error { func (m *ListMacaroonIDsRequest) XXX_Unmarshal(b []byte) error {
@ -12323,7 +12393,7 @@ func (m *ListMacaroonIDsResponse) Reset() { *m = ListMacaroonIDsResponse
func (m *ListMacaroonIDsResponse) String() string { return proto.CompactTextString(m) } func (m *ListMacaroonIDsResponse) String() string { return proto.CompactTextString(m) }
func (*ListMacaroonIDsResponse) ProtoMessage() {} func (*ListMacaroonIDsResponse) ProtoMessage() {}
func (*ListMacaroonIDsResponse) Descriptor() ([]byte, []int) { func (*ListMacaroonIDsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{154} return fileDescriptor_77a6da22d6a3feb1, []int{155}
} }
func (m *ListMacaroonIDsResponse) XXX_Unmarshal(b []byte) error { func (m *ListMacaroonIDsResponse) XXX_Unmarshal(b []byte) error {
@ -12363,7 +12433,7 @@ func (m *DeleteMacaroonIDRequest) Reset() { *m = DeleteMacaroonIDRequest
func (m *DeleteMacaroonIDRequest) String() string { return proto.CompactTextString(m) } func (m *DeleteMacaroonIDRequest) String() string { return proto.CompactTextString(m) }
func (*DeleteMacaroonIDRequest) ProtoMessage() {} func (*DeleteMacaroonIDRequest) ProtoMessage() {}
func (*DeleteMacaroonIDRequest) Descriptor() ([]byte, []int) { func (*DeleteMacaroonIDRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{155} return fileDescriptor_77a6da22d6a3feb1, []int{156}
} }
func (m *DeleteMacaroonIDRequest) XXX_Unmarshal(b []byte) error { func (m *DeleteMacaroonIDRequest) XXX_Unmarshal(b []byte) error {
@ -12403,7 +12473,7 @@ func (m *DeleteMacaroonIDResponse) Reset() { *m = DeleteMacaroonIDRespon
func (m *DeleteMacaroonIDResponse) String() string { return proto.CompactTextString(m) } func (m *DeleteMacaroonIDResponse) String() string { return proto.CompactTextString(m) }
func (*DeleteMacaroonIDResponse) ProtoMessage() {} func (*DeleteMacaroonIDResponse) ProtoMessage() {}
func (*DeleteMacaroonIDResponse) Descriptor() ([]byte, []int) { func (*DeleteMacaroonIDResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{156} return fileDescriptor_77a6da22d6a3feb1, []int{157}
} }
func (m *DeleteMacaroonIDResponse) XXX_Unmarshal(b []byte) error { func (m *DeleteMacaroonIDResponse) XXX_Unmarshal(b []byte) error {
@ -12443,7 +12513,7 @@ func (m *MacaroonPermissionList) Reset() { *m = MacaroonPermissionList{}
func (m *MacaroonPermissionList) String() string { return proto.CompactTextString(m) } func (m *MacaroonPermissionList) String() string { return proto.CompactTextString(m) }
func (*MacaroonPermissionList) ProtoMessage() {} func (*MacaroonPermissionList) ProtoMessage() {}
func (*MacaroonPermissionList) Descriptor() ([]byte, []int) { func (*MacaroonPermissionList) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{157} return fileDescriptor_77a6da22d6a3feb1, []int{158}
} }
func (m *MacaroonPermissionList) XXX_Unmarshal(b []byte) error { func (m *MacaroonPermissionList) XXX_Unmarshal(b []byte) error {
@ -12481,7 +12551,7 @@ func (m *ListPermissionsRequest) Reset() { *m = ListPermissionsRequest{}
func (m *ListPermissionsRequest) String() string { return proto.CompactTextString(m) } func (m *ListPermissionsRequest) String() string { return proto.CompactTextString(m) }
func (*ListPermissionsRequest) ProtoMessage() {} func (*ListPermissionsRequest) ProtoMessage() {}
func (*ListPermissionsRequest) Descriptor() ([]byte, []int) { func (*ListPermissionsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{158} return fileDescriptor_77a6da22d6a3feb1, []int{159}
} }
func (m *ListPermissionsRequest) XXX_Unmarshal(b []byte) error { func (m *ListPermissionsRequest) XXX_Unmarshal(b []byte) error {
@ -12516,7 +12586,7 @@ func (m *ListPermissionsResponse) Reset() { *m = ListPermissionsResponse
func (m *ListPermissionsResponse) String() string { return proto.CompactTextString(m) } func (m *ListPermissionsResponse) String() string { return proto.CompactTextString(m) }
func (*ListPermissionsResponse) ProtoMessage() {} func (*ListPermissionsResponse) ProtoMessage() {}
func (*ListPermissionsResponse) Descriptor() ([]byte, []int) { func (*ListPermissionsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{159} return fileDescriptor_77a6da22d6a3feb1, []int{160}
} }
func (m *ListPermissionsResponse) XXX_Unmarshal(b []byte) error { func (m *ListPermissionsResponse) XXX_Unmarshal(b []byte) error {
@ -12572,7 +12642,7 @@ func (m *Failure) Reset() { *m = Failure{} }
func (m *Failure) String() string { return proto.CompactTextString(m) } func (m *Failure) String() string { return proto.CompactTextString(m) }
func (*Failure) ProtoMessage() {} func (*Failure) ProtoMessage() {}
func (*Failure) Descriptor() ([]byte, []int) { func (*Failure) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{160} return fileDescriptor_77a6da22d6a3feb1, []int{161}
} }
func (m *Failure) XXX_Unmarshal(b []byte) error { func (m *Failure) XXX_Unmarshal(b []byte) error {
@ -12716,7 +12786,7 @@ func (m *ChannelUpdate) Reset() { *m = ChannelUpdate{} }
func (m *ChannelUpdate) String() string { return proto.CompactTextString(m) } func (m *ChannelUpdate) String() string { return proto.CompactTextString(m) }
func (*ChannelUpdate) ProtoMessage() {} func (*ChannelUpdate) ProtoMessage() {}
func (*ChannelUpdate) Descriptor() ([]byte, []int) { func (*ChannelUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{161} return fileDescriptor_77a6da22d6a3feb1, []int{162}
} }
func (m *ChannelUpdate) XXX_Unmarshal(b []byte) error { func (m *ChannelUpdate) XXX_Unmarshal(b []byte) error {
@ -12834,7 +12904,7 @@ func (m *MacaroonId) Reset() { *m = MacaroonId{} }
func (m *MacaroonId) String() string { return proto.CompactTextString(m) } func (m *MacaroonId) String() string { return proto.CompactTextString(m) }
func (*MacaroonId) ProtoMessage() {} func (*MacaroonId) ProtoMessage() {}
func (*MacaroonId) Descriptor() ([]byte, []int) { func (*MacaroonId) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{162} return fileDescriptor_77a6da22d6a3feb1, []int{163}
} }
func (m *MacaroonId) XXX_Unmarshal(b []byte) error { func (m *MacaroonId) XXX_Unmarshal(b []byte) error {
@ -12888,7 +12958,7 @@ func (m *Op) Reset() { *m = Op{} }
func (m *Op) String() string { return proto.CompactTextString(m) } func (m *Op) String() string { return proto.CompactTextString(m) }
func (*Op) ProtoMessage() {} func (*Op) ProtoMessage() {}
func (*Op) Descriptor() ([]byte, []int) { func (*Op) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{163} return fileDescriptor_77a6da22d6a3feb1, []int{164}
} }
func (m *Op) XXX_Unmarshal(b []byte) error { func (m *Op) XXX_Unmarshal(b []byte) error {
@ -13043,6 +13113,7 @@ func init() {
proto.RegisterType((*Hop)(nil), "lnrpc.Hop") proto.RegisterType((*Hop)(nil), "lnrpc.Hop")
proto.RegisterMapType((map[uint64][]byte)(nil), "lnrpc.Hop.CustomRecordsEntry") proto.RegisterMapType((map[uint64][]byte)(nil), "lnrpc.Hop.CustomRecordsEntry")
proto.RegisterType((*MPPRecord)(nil), "lnrpc.MPPRecord") proto.RegisterType((*MPPRecord)(nil), "lnrpc.MPPRecord")
proto.RegisterType((*AMPRecord)(nil), "lnrpc.AMPRecord")
proto.RegisterType((*Route)(nil), "lnrpc.Route") proto.RegisterType((*Route)(nil), "lnrpc.Route")
proto.RegisterType((*NodeInfoRequest)(nil), "lnrpc.NodeInfoRequest") proto.RegisterType((*NodeInfoRequest)(nil), "lnrpc.NodeInfoRequest")
proto.RegisterType((*NodeInfo)(nil), "lnrpc.NodeInfo") proto.RegisterType((*NodeInfo)(nil), "lnrpc.NodeInfo")
@ -13132,800 +13203,802 @@ func init() {
func init() { proto.RegisterFile("rpc.proto", fileDescriptor_77a6da22d6a3feb1) } func init() { proto.RegisterFile("rpc.proto", fileDescriptor_77a6da22d6a3feb1) }
var fileDescriptor_77a6da22d6a3feb1 = []byte{ var fileDescriptor_77a6da22d6a3feb1 = []byte{
// 12685 bytes of a gzipped FileDescriptorProto // 12707 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0xbd, 0x5b, 0x6c, 0x23, 0x59, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x7d, 0x5b, 0x6c, 0x23, 0x59,
0x7a, 0x18, 0xdc, 0xbc, 0x89, 0xe4, 0x47, 0x52, 0xa2, 0x8e, 0x6e, 0x6c, 0xf5, 0xf4, 0x74, 0x4f, 0x76, 0x58, 0xf3, 0x25, 0x92, 0x87, 0xa4, 0x44, 0x5d, 0xbd, 0xd8, 0xea, 0xe9, 0xe9, 0x9e, 0x9a,
0xcd, 0xec, 0x4c, 0x6f, 0xcf, 0x8e, 0xa6, 0xa7, 0x67, 0x7a, 0x2e, 0x3b, 0xbf, 0xd7, 0x4b, 0x49, 0xd9, 0x99, 0xde, 0x9e, 0x19, 0x4d, 0x4f, 0xcf, 0xf4, 0x3c, 0x76, 0xe2, 0xf5, 0x52, 0x12, 0xd5,
0x54, 0x8b, 0xdb, 0x12, 0xa9, 0x2d, 0x52, 0x3d, 0x6e, 0xc3, 0x76, 0xb9, 0x44, 0x1e, 0x49, 0xf5, 0xe2, 0xb6, 0x44, 0x6a, 0x8b, 0xd4, 0x8c, 0xdb, 0xb0, 0x5d, 0x2e, 0x91, 0x57, 0x52, 0xa5, 0xc9,
0x37, 0x59, 0xc5, 0xad, 0x2a, 0xaa, 0xa5, 0x0d, 0x02, 0xf8, 0xc1, 0xb1, 0x03, 0xc3, 0x08, 0x10, 0x2a, 0x6e, 0x55, 0x51, 0x2d, 0x6d, 0x10, 0xc0, 0x1f, 0x8e, 0x1d, 0x18, 0x4e, 0x80, 0x00, 0x71,
0x20, 0x0e, 0x10, 0x24, 0x46, 0x12, 0x24, 0x48, 0xde, 0x0c, 0x03, 0xb6, 0x9f, 0x92, 0x87, 0x3c, 0x80, 0x20, 0x31, 0x92, 0x20, 0x41, 0xf2, 0x67, 0x18, 0xb0, 0xfd, 0x95, 0x7c, 0xe4, 0x2b, 0x41,
0x25, 0x08, 0x90, 0x20, 0x08, 0x10, 0x23, 0x17, 0x04, 0x09, 0x02, 0x24, 0x0e, 0x10, 0x03, 0x89, 0x80, 0x04, 0x41, 0x80, 0x18, 0x79, 0x7c, 0x24, 0x08, 0x90, 0x38, 0x40, 0x0c, 0x24, 0x06, 0xfc,
0x01, 0x3f, 0x26, 0x41, 0x82, 0xf3, 0x9d, 0x4b, 0x9d, 0xba, 0xa8, 0xbb, 0x67, 0x3d, 0xd9, 0x17, 0x99, 0x04, 0x09, 0xee, 0xb9, 0x8f, 0xba, 0xf5, 0x50, 0x77, 0xcf, 0xee, 0x78, 0x7f, 0x24, 0xd6,
0x89, 0xf5, 0x9d, 0xef, 0xdc, 0xcf, 0xf9, 0xce, 0x77, 0x3b, 0xdf, 0x81, 0xaa, 0x3f, 0x1b, 0x6d, 0xb9, 0xe7, 0xbe, 0xef, 0x3d, 0xf7, 0xbc, 0xee, 0xb9, 0x50, 0xf5, 0x67, 0xa3, 0xad, 0x99, 0xef,
0xcd, 0x7c, 0x2f, 0xf4, 0x48, 0x69, 0xe2, 0xfa, 0xb3, 0x91, 0xf1, 0x47, 0x39, 0x28, 0x1e, 0x87, 0x85, 0x1e, 0x29, 0x4d, 0x5c, 0x7f, 0x36, 0x32, 0xfe, 0x28, 0x07, 0xc5, 0xe3, 0xf0, 0xd2, 0x23,
0x97, 0x1e, 0x79, 0x04, 0x75, 0x7b, 0x3c, 0xf6, 0x69, 0x10, 0x58, 0xe1, 0xd5, 0x8c, 0xb6, 0x72, 0x8f, 0xa0, 0x6e, 0x8f, 0xc7, 0x3e, 0x0d, 0x02, 0x2b, 0xbc, 0x9a, 0xd1, 0x56, 0xee, 0x6e, 0xee,
0x77, 0x73, 0xf7, 0x16, 0x1f, 0x92, 0x2d, 0x44, 0xdb, 0x6a, 0xf3, 0xa4, 0xe1, 0xd5, 0x8c, 0x9a, 0xde, 0xe2, 0x43, 0xb2, 0x85, 0x68, 0x5b, 0x6d, 0x9e, 0x34, 0xbc, 0x9a, 0x51, 0xb3, 0x66, 0x47,
0x35, 0x3b, 0xfa, 0x20, 0x2d, 0x28, 0x8b, 0xcf, 0x56, 0xfe, 0x6e, 0xee, 0x5e, 0xd5, 0x94, 0x9f, 0x1f, 0xa4, 0x05, 0x65, 0xf1, 0xd9, 0xca, 0xdf, 0xcd, 0xdd, 0xab, 0x9a, 0xf2, 0x93, 0xdc, 0x06,
0xe4, 0x36, 0x80, 0x3d, 0xf5, 0xe6, 0x6e, 0x68, 0x05, 0x76, 0xd8, 0x2a, 0xdc, 0xcd, 0xdd, 0x2b, 0xb0, 0xa7, 0xde, 0xdc, 0x0d, 0xad, 0xc0, 0x0e, 0x5b, 0x85, 0xbb, 0xb9, 0x7b, 0x05, 0xb3, 0xca,
0x98, 0x55, 0x0e, 0x19, 0xd8, 0x21, 0xb9, 0x05, 0xd5, 0xd9, 0x73, 0x2b, 0x18, 0xf9, 0xce, 0x2c, 0x21, 0x03, 0x3b, 0x24, 0xb7, 0xa0, 0x3a, 0x7b, 0x66, 0x05, 0x23, 0xdf, 0x99, 0x85, 0xad, 0x22,
0x6c, 0x15, 0x31, 0x6b, 0x65, 0xf6, 0x7c, 0x80, 0xdf, 0xe4, 0x7d, 0xa8, 0x78, 0xf3, 0x70, 0xe6, 0x66, 0xad, 0xcc, 0x9e, 0x0d, 0xf0, 0x9b, 0xbc, 0x0b, 0x15, 0x6f, 0x1e, 0xce, 0x3c, 0xc7, 0x0d,
0x39, 0x6e, 0xd8, 0x2a, 0xdd, 0xcd, 0xdd, 0xab, 0x3d, 0x5c, 0x12, 0x0d, 0xe9, 0xcf, 0xc3, 0x23, 0x5b, 0xa5, 0xbb, 0xb9, 0x7b, 0xb5, 0x87, 0x4b, 0xa2, 0x21, 0xfd, 0x79, 0x78, 0xc4, 0xc0, 0xa6,
0x06, 0x36, 0x15, 0x02, 0x79, 0x07, 0x1a, 0x23, 0xcf, 0x3d, 0x75, 0xfc, 0xa9, 0x1d, 0x3a, 0x9e, 0x42, 0x20, 0x6f, 0x41, 0x63, 0xe4, 0xb9, 0xa7, 0x8e, 0x3f, 0xb5, 0x43, 0xc7, 0x73, 0x83, 0xd6,
0x1b, 0xb4, 0x16, 0xb0, 0xae, 0x38, 0xd0, 0xf8, 0xc7, 0x79, 0xa8, 0x0d, 0x7d, 0xdb, 0x0d, 0xec, 0x02, 0xd6, 0x15, 0x07, 0x1a, 0xff, 0x2c, 0x0f, 0xb5, 0xa1, 0x6f, 0xbb, 0x81, 0x3d, 0x62, 0x00,
0x11, 0x03, 0x90, 0x0d, 0x28, 0x87, 0x97, 0xd6, 0xb9, 0x1d, 0x9c, 0x63, 0x57, 0xab, 0xe6, 0x42, 0xb2, 0x01, 0xe5, 0xf0, 0xd2, 0x3a, 0xb7, 0x83, 0x73, 0xec, 0x6a, 0xd5, 0x5c, 0x08, 0x2f, 0xf7,
0x78, 0xb9, 0x6f, 0x07, 0xe7, 0x64, 0x1d, 0x16, 0x78, 0x2b, 0xb1, 0x43, 0x05, 0x53, 0x7c, 0x91, 0xed, 0xe0, 0x9c, 0xac, 0xc3, 0x02, 0x6f, 0x25, 0x76, 0xa8, 0x60, 0x8a, 0x2f, 0xf2, 0x2e, 0x2c,
0xf7, 0x61, 0xd9, 0x9d, 0x4f, 0xad, 0x78, 0x55, 0xac, 0x5b, 0x25, 0xb3, 0xe9, 0xce, 0xa7, 0x3b, 0xbb, 0xf3, 0xa9, 0x15, 0xaf, 0x8a, 0x75, 0xab, 0x64, 0x36, 0xdd, 0xf9, 0x74, 0x47, 0x87, 0xb3,
0x3a, 0x9c, 0x75, 0xfe, 0x64, 0xe2, 0x8d, 0x9e, 0xf3, 0x0a, 0x78, 0xf7, 0xaa, 0x08, 0xc1, 0x3a, 0xce, 0x9f, 0x4c, 0xbc, 0xd1, 0x33, 0x5e, 0x01, 0xef, 0x5e, 0x15, 0x21, 0x58, 0xc7, 0x1b, 0x50,
0xde, 0x82, 0xba, 0x48, 0xa6, 0xce, 0xd9, 0x39, 0xef, 0x63, 0xc9, 0xac, 0x71, 0x04, 0x04, 0xb1, 0x17, 0xc9, 0xd4, 0x39, 0x3b, 0xe7, 0x7d, 0x2c, 0x99, 0x35, 0x8e, 0x80, 0x20, 0x56, 0x42, 0xe8,
0x12, 0x42, 0x67, 0x4a, 0xad, 0x20, 0xb4, 0xa7, 0x33, 0xd1, 0xa5, 0x2a, 0x83, 0x0c, 0x18, 0x00, 0x4c, 0xa9, 0x15, 0x84, 0xf6, 0x74, 0x26, 0xba, 0x54, 0x65, 0x90, 0x01, 0x03, 0x60, 0xb2, 0x17,
0x93, 0xbd, 0xd0, 0x9e, 0x58, 0xa7, 0x94, 0x06, 0xad, 0xb2, 0x48, 0x66, 0x90, 0x3d, 0x4a, 0x03, 0xda, 0x13, 0xeb, 0x94, 0xd2, 0xa0, 0x55, 0x16, 0xc9, 0x0c, 0xb2, 0x47, 0x69, 0x40, 0xbe, 0x05,
0xf2, 0x2d, 0x58, 0x1c, 0xd3, 0x20, 0xb4, 0xc4, 0x64, 0xd0, 0xa0, 0x55, 0xb9, 0x5b, 0xb8, 0x57, 0x8b, 0x63, 0x1a, 0x84, 0x96, 0x98, 0x0c, 0x1a, 0xb4, 0x2a, 0x77, 0x0b, 0xf7, 0xaa, 0x66, 0x83,
0x35, 0x1b, 0x0c, 0xda, 0x96, 0x40, 0xf2, 0x06, 0x80, 0x6f, 0xbf, 0xb0, 0xd8, 0x40, 0xd0, 0xcb, 0x41, 0xdb, 0x12, 0x48, 0x5e, 0x03, 0xf0, 0xed, 0xe7, 0x16, 0x1b, 0x08, 0x7a, 0xd9, 0xaa, 0xf2,
0x56, 0x95, 0xcf, 0x82, 0x6f, 0xbf, 0x18, 0x5e, 0xee, 0xd3, 0x4b, 0xb2, 0x0a, 0xa5, 0x89, 0x7d, 0x59, 0xf0, 0xed, 0xe7, 0xc3, 0xcb, 0x7d, 0x7a, 0x49, 0x56, 0xa1, 0x34, 0xb1, 0x4f, 0xe8, 0xa4,
0x42, 0x27, 0x2d, 0xc0, 0x04, 0xfe, 0x61, 0x84, 0xb0, 0xfe, 0x98, 0x86, 0xda, 0x50, 0x06, 0x26, 0x05, 0x98, 0xc0, 0x3f, 0x8c, 0x10, 0xd6, 0x1f, 0xd3, 0x50, 0x1b, 0xca, 0xc0, 0xa4, 0x3f, 0x9c,
0xfd, 0xd1, 0x9c, 0x06, 0x21, 0xeb, 0x55, 0x10, 0xda, 0x7e, 0x28, 0x7b, 0x95, 0xe3, 0xbd, 0x42, 0xd3, 0x20, 0x64, 0xbd, 0x0a, 0x42, 0xdb, 0x0f, 0x65, 0xaf, 0x72, 0xbc, 0x57, 0x08, 0x8b, 0x7a,
0x58, 0xd4, 0x2b, 0xea, 0x8e, 0x25, 0x42, 0x1e, 0x11, 0xaa, 0xd4, 0x1d, 0x8b, 0x64, 0xb6, 0x9a, 0x45, 0xdd, 0xb1, 0x44, 0xc8, 0x23, 0x42, 0x95, 0xba, 0x63, 0x91, 0xcc, 0x56, 0xd3, 0x68, 0x84,
0x46, 0x23, 0x1c, 0xfc, 0x82, 0x58, 0x4d, 0xfc, 0xd3, 0x38, 0x00, 0xa2, 0x55, 0xb9, 0x4b, 0x43, 0x83, 0x5f, 0x10, 0xab, 0x89, 0x7f, 0x1a, 0x07, 0x40, 0xb4, 0x2a, 0x77, 0x69, 0x68, 0x3b, 0x93,
0xdb, 0x99, 0x04, 0xe4, 0x53, 0xa8, 0x87, 0x5a, 0x43, 0x5a, 0xb9, 0xbb, 0x85, 0x7b, 0x35, 0xb5, 0x80, 0x7c, 0x02, 0xf5, 0x50, 0x6b, 0x48, 0x2b, 0x77, 0xb7, 0x70, 0xaf, 0xa6, 0x16, 0xad, 0x96,
0x68, 0xb5, 0x0c, 0x66, 0x0c, 0xcf, 0x38, 0x87, 0xca, 0x1e, 0xa5, 0x07, 0xce, 0xd4, 0x09, 0xc9, 0xc1, 0x8c, 0xe1, 0x19, 0xe7, 0x50, 0xd9, 0xa3, 0xf4, 0xc0, 0x99, 0x3a, 0x21, 0x59, 0x87, 0xd2,
0x3a, 0x94, 0x4e, 0x9d, 0x4b, 0x3a, 0xc6, 0xe6, 0x16, 0xf6, 0x6f, 0x98, 0xfc, 0x93, 0xdc, 0x01, 0xa9, 0x73, 0x49, 0xc7, 0xd8, 0xdc, 0xc2, 0xfe, 0x0d, 0x93, 0x7f, 0x92, 0x3b, 0x00, 0xf8, 0xc3,
0xc0, 0x1f, 0xd6, 0x54, 0xad, 0xdf, 0xfd, 0x1b, 0x66, 0x15, 0x61, 0x87, 0x81, 0x1d, 0x92, 0x4d, 0x9a, 0xaa, 0xf5, 0xbb, 0x7f, 0xc3, 0xac, 0x22, 0xec, 0x30, 0xb0, 0x43, 0xb2, 0x09, 0xe5, 0x19,
0x28, 0xcf, 0xa8, 0x3f, 0xa2, 0x72, 0xa5, 0xec, 0xdf, 0x30, 0x25, 0x60, 0xbb, 0x0c, 0xa5, 0x09, 0xf5, 0x47, 0x54, 0xae, 0x94, 0xfd, 0x1b, 0xa6, 0x04, 0x6c, 0x97, 0xa1, 0x34, 0x61, 0xa5, 0x1b,
0x2b, 0xdd, 0xf8, 0x6f, 0x25, 0xa8, 0x0d, 0xa8, 0x3b, 0x96, 0x63, 0x44, 0xa0, 0xc8, 0xa6, 0x00, 0xff, 0xa3, 0x04, 0xb5, 0x01, 0x75, 0xc7, 0x72, 0x8c, 0x08, 0x14, 0xd9, 0x14, 0x60, 0x65, 0x75,
0x2b, 0xab, 0x9b, 0xf8, 0x9b, 0xbc, 0x0d, 0x35, 0x9c, 0xac, 0x20, 0xf4, 0x1d, 0xf7, 0x8c, 0xef, 0x13, 0x7f, 0x93, 0x37, 0xa1, 0x86, 0x93, 0x15, 0x84, 0xbe, 0xe3, 0x9e, 0xf1, 0x7d, 0xb4, 0x9d,
0xa3, 0xed, 0x7c, 0x2b, 0x67, 0x02, 0x03, 0x0f, 0x10, 0x4a, 0x9a, 0x50, 0xb0, 0xa7, 0x72, 0x1f, 0x6f, 0xe5, 0x4c, 0x60, 0xe0, 0x01, 0x42, 0x49, 0x13, 0x0a, 0xf6, 0x54, 0xee, 0x23, 0xf6, 0x93,
0xb1, 0x9f, 0xe4, 0x26, 0x54, 0xec, 0x69, 0xc8, 0x9b, 0x57, 0x47, 0x70, 0xd9, 0x9e, 0x86, 0xd8, 0xdc, 0x84, 0x8a, 0x3d, 0x0d, 0x79, 0xf3, 0xea, 0x08, 0x2e, 0xdb, 0xd3, 0x10, 0x9b, 0xf6, 0x06,
0xb4, 0xb7, 0xa0, 0x3e, 0xb3, 0xaf, 0xa6, 0xd4, 0x0d, 0xa3, 0x05, 0x58, 0x37, 0x6b, 0x02, 0x86, 0xd4, 0x67, 0xf6, 0xd5, 0x94, 0xba, 0x61, 0xb4, 0x00, 0xeb, 0x66, 0x4d, 0xc0, 0x70, 0x09, 0x3e,
0x4b, 0xf0, 0x21, 0xac, 0xe8, 0x28, 0xb2, 0xf2, 0x92, 0xaa, 0x7c, 0x59, 0xc3, 0x16, 0x6d, 0x78, 0x84, 0x15, 0x1d, 0x45, 0x56, 0x5e, 0x52, 0x95, 0x2f, 0x6b, 0xd8, 0xa2, 0x0d, 0xef, 0xc0, 0x92,
0x0f, 0x96, 0x64, 0x1e, 0x9f, 0xf7, 0x07, 0x17, 0x66, 0xd5, 0x5c, 0x14, 0x60, 0xd9, 0xcb, 0x7b, 0xcc, 0xe3, 0xf3, 0xfe, 0xe0, 0xc2, 0xac, 0x9a, 0x8b, 0x02, 0x2c, 0x7b, 0x79, 0x0f, 0x9a, 0xa7,
0xd0, 0x3c, 0x75, 0x5c, 0x7b, 0x62, 0x8d, 0x26, 0xe1, 0x85, 0x35, 0xa6, 0x93, 0xd0, 0xc6, 0x35, 0x8e, 0x6b, 0x4f, 0xac, 0xd1, 0x24, 0xbc, 0xb0, 0xc6, 0x74, 0x12, 0xda, 0xb8, 0x46, 0x4b, 0xe6,
0x5a, 0x32, 0x17, 0x11, 0xbe, 0x33, 0x09, 0x2f, 0x76, 0x19, 0x94, 0x7c, 0x07, 0xaa, 0xa7, 0x94, 0x22, 0xc2, 0x77, 0x26, 0xe1, 0xc5, 0x2e, 0x83, 0x92, 0xf7, 0xa0, 0x7a, 0x4a, 0xa9, 0x85, 0x83,
0x5a, 0x38, 0x58, 0xad, 0x4a, 0x6c, 0xab, 0xcb, 0x19, 0x32, 0x2b, 0xa7, 0x72, 0xae, 0xbe, 0x03, 0xd5, 0xaa, 0xc4, 0xb6, 0xba, 0x9c, 0x21, 0xb3, 0x72, 0x2a, 0xe7, 0xea, 0x3d, 0x68, 0x7a, 0xf3,
0x4d, 0x6f, 0x1e, 0x9e, 0x79, 0x8e, 0x7b, 0x66, 0x8d, 0xce, 0x6d, 0xd7, 0x72, 0xc6, 0xb8, 0x6a, 0xf0, 0xcc, 0x73, 0xdc, 0x33, 0x6b, 0x74, 0x6e, 0xbb, 0x96, 0x33, 0xc6, 0x55, 0x5b, 0xdc, 0xce,
0x8b, 0xdb, 0xf9, 0x07, 0x39, 0x73, 0x51, 0xa6, 0xed, 0x9c, 0xdb, 0x6e, 0x77, 0x4c, 0xde, 0x85, 0x3f, 0xc8, 0x99, 0x8b, 0x32, 0x6d, 0xe7, 0xdc, 0x76, 0xbb, 0x63, 0xf2, 0x36, 0x2c, 0x4d, 0xec,
0xa5, 0x89, 0x1d, 0x84, 0xd6, 0xb9, 0x37, 0xb3, 0x66, 0xf3, 0x93, 0xe7, 0xf4, 0xaa, 0xd5, 0xc0, 0x20, 0xb4, 0xce, 0xbd, 0x99, 0x35, 0x9b, 0x9f, 0x3c, 0xa3, 0x57, 0xad, 0x06, 0x0e, 0x44, 0x83,
0x81, 0x68, 0x30, 0xf0, 0xbe, 0x37, 0x3b, 0x42, 0x20, 0x5b, 0x94, 0xd8, 0x4e, 0xde, 0x08, 0xb6, 0x81, 0xf7, 0xbd, 0xd9, 0x11, 0x02, 0xd9, 0xa2, 0xc4, 0x76, 0xf2, 0x46, 0xb0, 0xc5, 0xde, 0x30,
0xd8, 0x1b, 0x66, 0x95, 0x41, 0x78, 0xa5, 0xcf, 0x60, 0x05, 0xa7, 0x67, 0x34, 0x0f, 0x42, 0x6f, 0xab, 0x0c, 0xc2, 0x2b, 0x7d, 0x0a, 0x2b, 0x38, 0x3d, 0xa3, 0x79, 0x10, 0x7a, 0x53, 0xcb, 0xa7,
0x6a, 0xf9, 0x74, 0xe4, 0xf9, 0xe3, 0xa0, 0x55, 0xc3, 0xb5, 0xf6, 0x6d, 0xd1, 0x58, 0x6d, 0x8e, 0x23, 0xcf, 0x1f, 0x07, 0xad, 0x1a, 0xae, 0xb5, 0x6f, 0x8b, 0xc6, 0x6a, 0x73, 0xbc, 0xb5, 0x4b,
0xb7, 0x76, 0x69, 0x10, 0xee, 0x20, 0xb2, 0xc9, 0x71, 0x3b, 0x6e, 0xe8, 0x5f, 0x99, 0xcb, 0xe3, 0x83, 0x70, 0x07, 0x91, 0x4d, 0x8e, 0xdb, 0x71, 0x43, 0xff, 0xca, 0x5c, 0x1e, 0x27, 0xe1, 0xe4,
0x24, 0x9c, 0x7c, 0x07, 0x88, 0x3d, 0x99, 0x78, 0x2f, 0xac, 0x80, 0x4e, 0x4e, 0x2d, 0x31, 0x88, 0x3d, 0x20, 0xf6, 0x64, 0xe2, 0x3d, 0xb7, 0x02, 0x3a, 0x39, 0xb5, 0xc4, 0x20, 0xb6, 0x16, 0xef,
0xad, 0xc5, 0xbb, 0xb9, 0x7b, 0x15, 0xb3, 0x89, 0x29, 0x03, 0x3a, 0x39, 0x3d, 0xe2, 0x70, 0xf2, 0xe6, 0xee, 0x55, 0xcc, 0x26, 0xa6, 0x0c, 0xe8, 0xe4, 0xf4, 0x88, 0xc3, 0xc9, 0x27, 0x80, 0xdb,
0x29, 0xe0, 0xf6, 0xb5, 0x4e, 0xa9, 0x1d, 0xce, 0x7d, 0x1a, 0xb4, 0x96, 0xee, 0x16, 0xee, 0x2d, 0xd7, 0x3a, 0xa5, 0x76, 0x38, 0xf7, 0x69, 0xd0, 0x5a, 0xba, 0x5b, 0xb8, 0xb7, 0xf8, 0x70, 0x59,
0x3e, 0x5c, 0x56, 0xe3, 0x85, 0xe0, 0x6d, 0x27, 0x34, 0xeb, 0x0c, 0x4f, 0x7c, 0x07, 0xfa, 0x6a, 0x8d, 0x17, 0x82, 0xb7, 0x9d, 0xd0, 0xac, 0x33, 0x3c, 0xf1, 0x1d, 0xe8, 0xab, 0x81, 0xd1, 0x83,
0x60, 0xf4, 0xa0, 0xd5, 0x8c, 0xad, 0x06, 0x46, 0x0d, 0x36, 0x77, 0x61, 0x3d, 0xbb, 0xd5, 0x6c, 0x56, 0x33, 0xb6, 0x1a, 0x18, 0x35, 0xd8, 0xdc, 0x85, 0xf5, 0xec, 0x56, 0xb3, 0x75, 0xc7, 0x06,
0xdd, 0xb1, 0x81, 0x63, 0xeb, 0xb5, 0x68, 0xb2, 0x9f, 0x8c, 0x2c, 0x5c, 0xd8, 0x93, 0x39, 0xc5, 0x8e, 0xad, 0xd7, 0xa2, 0xc9, 0x7e, 0x32, 0xb2, 0x70, 0x61, 0x4f, 0xe6, 0x14, 0x17, 0x6a, 0xdd,
0x85, 0x5a, 0x37, 0xf9, 0xc7, 0x77, 0xf3, 0x9f, 0xe7, 0x8c, 0xdf, 0xcf, 0x41, 0x9d, 0x0f, 0x44, 0xe4, 0x1f, 0xdf, 0xc9, 0x7f, 0x96, 0x33, 0x7e, 0x3f, 0x07, 0x75, 0x3e, 0x10, 0xc1, 0xcc, 0x73,
0x30, 0xf3, 0xdc, 0x80, 0x92, 0xb7, 0xa1, 0x21, 0x6b, 0xa6, 0xbe, 0xef, 0xf9, 0x82, 0xd4, 0xca, 0x03, 0x4a, 0xde, 0x84, 0x86, 0xac, 0x99, 0xfa, 0xbe, 0xe7, 0x0b, 0x52, 0x2b, 0x9b, 0xd3, 0x61,
0xe6, 0x74, 0x18, 0x8c, 0x7c, 0x1b, 0x9a, 0x12, 0x69, 0xe6, 0x53, 0x67, 0x6a, 0x9f, 0xc9, 0xa2, 0x30, 0xf2, 0x6d, 0x68, 0x4a, 0xa4, 0x99, 0x4f, 0x9d, 0xa9, 0x7d, 0x26, 0x8b, 0x96, 0xab, 0xed,
0xe5, 0x6a, 0x3b, 0x12, 0x60, 0xf2, 0x51, 0x54, 0x9e, 0xef, 0xcd, 0x43, 0x8a, 0xdb, 0xa1, 0xf6, 0x48, 0x80, 0xc9, 0x87, 0x51, 0x79, 0xbe, 0x37, 0x0f, 0x29, 0x6e, 0x87, 0xda, 0xc3, 0xba, 0x18,
0xb0, 0x2e, 0x46, 0xc0, 0x64, 0x30, 0x55, 0x3a, 0x7e, 0xbd, 0xc6, 0x56, 0x30, 0x7e, 0x2b, 0x07, 0x01, 0x93, 0xc1, 0x54, 0xe9, 0xf8, 0xf5, 0x0a, 0x5b, 0xc1, 0xf8, 0xad, 0x1c, 0x10, 0xd6, 0xec,
0x84, 0x35, 0x7b, 0xe8, 0xf1, 0x02, 0x22, 0x72, 0x16, 0xcb, 0x99, 0x7b, 0xed, 0x4d, 0x94, 0x7f, 0xa1, 0xc7, 0x0b, 0x88, 0xc8, 0x59, 0x2c, 0x67, 0xee, 0x95, 0x37, 0x51, 0xfe, 0x45, 0x9b, 0xc8,
0xd9, 0x26, 0x32, 0xa0, 0xc4, 0xdb, 0x5e, 0xcc, 0x68, 0x3b, 0x4f, 0xfa, 0x41, 0xb1, 0x52, 0x68, 0x80, 0x12, 0x6f, 0x7b, 0x31, 0xa3, 0xed, 0x3c, 0xe9, 0xfb, 0xc5, 0x4a, 0xa1, 0x59, 0x34, 0xfe,
0x16, 0x8d, 0x7f, 0x57, 0x80, 0x55, 0xb6, 0x94, 0x5d, 0x3a, 0x69, 0x8f, 0x46, 0x74, 0xa6, 0xb6, 0x63, 0x01, 0x56, 0xd9, 0x52, 0x76, 0xe9, 0xa4, 0x3d, 0x1a, 0xd1, 0x99, 0xda, 0x5e, 0x77, 0xa0,
0xd7, 0x1d, 0xa8, 0xb9, 0xde, 0x98, 0xca, 0x45, 0xcd, 0x1b, 0x06, 0x0c, 0xa4, 0xad, 0xe8, 0x73, 0xe6, 0x7a, 0x63, 0x2a, 0x17, 0x35, 0x6f, 0x18, 0x30, 0x90, 0xb6, 0xa2, 0xcf, 0x6d, 0xc7, 0xe5,
0xdb, 0x71, 0x79, 0xc3, 0xf9, 0x60, 0x56, 0x11, 0x82, 0xcd, 0x7e, 0x17, 0x96, 0x66, 0xd4, 0x1d, 0x0d, 0xe7, 0x83, 0x59, 0x45, 0x08, 0x36, 0xfb, 0x6d, 0x58, 0x9a, 0x51, 0x77, 0xac, 0xef, 0xa2,
0xeb, 0xbb, 0xa8, 0xc0, 0x37, 0x86, 0x00, 0x8b, 0x0d, 0x74, 0x07, 0x6a, 0xa7, 0x73, 0x8e, 0xc7, 0x02, 0xdf, 0x18, 0x02, 0x2c, 0x36, 0xd0, 0x1d, 0xa8, 0x9d, 0xce, 0x39, 0x1e, 0xa3, 0x3d, 0x45,
0x68, 0x4f, 0x11, 0xd7, 0x00, 0x08, 0x50, 0x9b, 0x93, 0xa0, 0xd9, 0x3c, 0x38, 0xc7, 0xd4, 0x12, 0x5c, 0x03, 0x20, 0x40, 0x6d, 0x4e, 0x82, 0x66, 0xf3, 0xe0, 0x1c, 0x53, 0x4b, 0x98, 0x5a, 0x66,
0xa6, 0x96, 0xd9, 0x37, 0x4b, 0xba, 0x0d, 0x30, 0x9e, 0x07, 0xa1, 0xd8, 0x54, 0x0b, 0x98, 0x58, 0xdf, 0x2c, 0xe9, 0x36, 0xc0, 0x78, 0x1e, 0x84, 0x62, 0x53, 0x2d, 0x60, 0x62, 0x95, 0x41, 0xf8,
0x65, 0x10, 0xbe, 0xa9, 0x3e, 0x80, 0x95, 0xa9, 0x7d, 0x69, 0xe1, 0xda, 0xb1, 0x1c, 0xd7, 0x3a, 0xa6, 0x7a, 0x1f, 0x56, 0xa6, 0xf6, 0xa5, 0x85, 0x6b, 0xc7, 0x72, 0x5c, 0xeb, 0x74, 0x82, 0x27,
0x9d, 0xe0, 0x89, 0x50, 0x46, 0xbc, 0xe6, 0xd4, 0xbe, 0x7c, 0xca, 0x52, 0xba, 0xee, 0x1e, 0xc2, 0x42, 0x19, 0xf1, 0x9a, 0x53, 0xfb, 0xf2, 0x4b, 0x96, 0xd2, 0x75, 0xf7, 0x10, 0xce, 0x28, 0xcf,
0x19, 0xe5, 0x19, 0xf1, 0x91, 0xb0, 0x7c, 0x1a, 0x50, 0xff, 0x82, 0x22, 0xb1, 0x28, 0x9a, 0x8b, 0x88, 0x8f, 0x84, 0xe5, 0xd3, 0x80, 0xfa, 0x17, 0x14, 0x89, 0x45, 0xd1, 0x5c, 0x14, 0x60, 0x93,
0x02, 0x6c, 0x72, 0x28, 0x6b, 0xd1, 0x94, 0xf5, 0x3b, 0x9c, 0x8c, 0x38, 0x65, 0x30, 0xcb, 0x53, 0x43, 0x59, 0x8b, 0xa6, 0xac, 0xdf, 0xe1, 0x64, 0xc4, 0x29, 0x83, 0x59, 0x9e, 0x3a, 0xee, 0x7e,
0xc7, 0xdd, 0x0f, 0x27, 0x23, 0x76, 0xd8, 0x31, 0x52, 0x33, 0xa3, 0xbe, 0xf5, 0xfc, 0x05, 0x6e, 0x38, 0x19, 0xb1, 0xc3, 0x8e, 0x91, 0x9a, 0x19, 0xf5, 0xad, 0x67, 0xcf, 0x71, 0x9b, 0x17, 0x91,
0xf3, 0x22, 0x92, 0x96, 0x23, 0xea, 0x3f, 0x79, 0xc1, 0xf8, 0x91, 0x51, 0x80, 0xb4, 0xca, 0xbe, 0xb4, 0x1c, 0x51, 0xff, 0xc9, 0x73, 0xc6, 0x8f, 0x8c, 0x02, 0xa4, 0x55, 0xf6, 0x55, 0xab, 0x86,
0x6a, 0xd5, 0x90, 0x06, 0x54, 0x46, 0x01, 0xa3, 0x52, 0xf6, 0x15, 0xdb, 0xa7, 0xac, 0xb5, 0x36, 0x34, 0xa0, 0x32, 0x0a, 0x18, 0x95, 0xb2, 0xaf, 0xd8, 0x3e, 0x65, 0xad, 0xb5, 0x71, 0x16, 0xe8,
0xce, 0x02, 0x1d, 0x63, 0xf1, 0x01, 0x12, 0xdd, 0x06, 0x36, 0xb6, 0x2d, 0x12, 0x58, 0x3d, 0x01, 0x18, 0x8b, 0x0f, 0x90, 0xe8, 0x36, 0xb0, 0xb1, 0x6d, 0x91, 0xc0, 0xea, 0x09, 0xd8, 0xaa, 0x97,
0x5b, 0xf5, 0xb2, 0xb1, 0xa7, 0x13, 0xfb, 0x2c, 0x40, 0xaa, 0xd3, 0x30, 0xeb, 0x02, 0xb8, 0xc7, 0x8d, 0x3d, 0x9d, 0xd8, 0x67, 0x01, 0x52, 0x9d, 0x86, 0x59, 0x17, 0xc0, 0x3d, 0x06, 0x33, 0xfe,
0x60, 0xc6, 0x9f, 0xe6, 0x61, 0x2d, 0x31, 0xb9, 0x62, 0xd3, 0x30, 0x06, 0x04, 0x21, 0x38, 0xb1, 0x34, 0x0f, 0x6b, 0x89, 0xc9, 0x15, 0x9b, 0x86, 0x31, 0x20, 0x08, 0xc1, 0x89, 0xad, 0x98, 0xe2,
0x15, 0x53, 0x7c, 0x65, 0xcd, 0x5a, 0x3e, 0x6b, 0xd6, 0x56, 0xa1, 0xc4, 0x37, 0x1b, 0x3f, 0x42, 0x2b, 0x6b, 0xd6, 0xf2, 0x59, 0xb3, 0xb6, 0x0a, 0x25, 0xbe, 0xd9, 0xf8, 0x11, 0xca, 0x3f, 0xd8,
0xf9, 0x07, 0xdb, 0x65, 0xf3, 0xd9, 0xa9, 0xef, 0x31, 0x7e, 0xec, 0x7c, 0x1e, 0x8e, 0xbd, 0x17, 0x2e, 0x9b, 0xcf, 0x4e, 0x7d, 0x8f, 0xf1, 0x63, 0xe7, 0xf3, 0x70, 0xec, 0x3d, 0x77, 0x05, 0x5f,
0xae, 0xe0, 0x4b, 0x96, 0x04, 0x7c, 0x20, 0xc0, 0xf1, 0xa1, 0x28, 0x25, 0x86, 0xe2, 0x0e, 0xd4, 0xb2, 0x24, 0xe0, 0x03, 0x01, 0x8e, 0x0f, 0x45, 0x29, 0x31, 0x14, 0x77, 0xa0, 0x26, 0x66, 0x00,
0xc4, 0x0c, 0x20, 0x5f, 0xc7, 0x27, 0x16, 0x04, 0x88, 0x31, 0x76, 0xef, 0x03, 0x51, 0xf3, 0x69, 0xf9, 0x3a, 0x3e, 0xb1, 0x20, 0x40, 0x8c, 0xb1, 0x7b, 0x17, 0x88, 0x9a, 0x4f, 0x8b, 0x8d, 0x1a,
0xb1, 0x51, 0xc3, 0x03, 0x8a, 0x4f, 0xec, 0x92, 0x23, 0x26, 0xf4, 0xd0, 0xbe, 0xc4, 0x83, 0xea, 0x1e, 0x50, 0x7c, 0x62, 0x97, 0x1c, 0x31, 0xa1, 0x87, 0xf6, 0x25, 0x1e, 0x54, 0x6f, 0xc1, 0x22,
0x1d, 0x58, 0x64, 0x28, 0x6c, 0x3c, 0x2d, 0x7e, 0xee, 0x57, 0xf8, 0x58, 0x4d, 0xed, 0x4b, 0x36, 0x43, 0x61, 0xe3, 0x69, 0xf1, 0x73, 0xbf, 0xc2, 0xc7, 0x6a, 0x6a, 0x5f, 0xb2, 0xc1, 0xdc, 0x41,
0x98, 0x3b, 0xc8, 0x7a, 0xbd, 0x09, 0x35, 0x39, 0xa9, 0x96, 0xe3, 0x8a, 0x79, 0xad, 0x8a, 0x79, 0xd6, 0xeb, 0x75, 0xa8, 0xc9, 0x49, 0xb5, 0x1c, 0x57, 0xcc, 0x6b, 0x55, 0xcc, 0x6b, 0xd7, 0x65,
0xed, 0xba, 0xec, 0xb8, 0x61, 0xe9, 0x7c, 0x9c, 0xac, 0x31, 0x9d, 0x85, 0xe7, 0x82, 0x8c, 0x2f, 0xc7, 0x0d, 0x4b, 0xe7, 0xe3, 0x64, 0x8d, 0xe9, 0x2c, 0x3c, 0x17, 0x64, 0x7c, 0x71, 0xea, 0xb8,
0x4e, 0x1d, 0x97, 0x0f, 0xef, 0x2e, 0x83, 0x1a, 0xbf, 0x9d, 0x83, 0xba, 0x18, 0x75, 0x64, 0x23, 0x7c, 0x78, 0x77, 0x19, 0xd4, 0xf8, 0xed, 0x1c, 0xd4, 0xc5, 0xa8, 0x23, 0x1b, 0x49, 0xb6, 0x80,
0xc9, 0x16, 0x10, 0xb9, 0xc4, 0xc3, 0x4b, 0x67, 0x6c, 0x9d, 0x5c, 0x85, 0x34, 0xe0, 0x3b, 0x6a, 0xc8, 0x25, 0x1e, 0x5e, 0x3a, 0x63, 0xeb, 0xe4, 0x2a, 0xa4, 0x01, 0xdf, 0x51, 0xfb, 0x37, 0xcc,
0xff, 0x86, 0xd9, 0x14, 0x69, 0xc3, 0x4b, 0x67, 0xbc, 0xcd, 0x52, 0xc8, 0x7d, 0x68, 0xc6, 0xf0, 0xa6, 0x48, 0x1b, 0x5e, 0x3a, 0xe3, 0x6d, 0x96, 0x42, 0xee, 0x43, 0x33, 0x86, 0x1f, 0x84, 0x3e,
0x83, 0xd0, 0xe7, 0xdb, 0x7d, 0xff, 0x86, 0xb9, 0xa8, 0x61, 0x0f, 0x42, 0x9f, 0x11, 0x10, 0xc6, 0xdf, 0xee, 0xfb, 0x37, 0xcc, 0x45, 0x0d, 0x7b, 0x10, 0xfa, 0x8c, 0x80, 0x30, 0x26, 0x75, 0x1e,
0xa4, 0xce, 0x43, 0xcb, 0x71, 0xc7, 0xf4, 0x12, 0xe7, 0xa3, 0x61, 0xd6, 0x38, 0xac, 0xcb, 0x40, 0x5a, 0x8e, 0x3b, 0xa6, 0x97, 0x38, 0x1f, 0x0d, 0xb3, 0xc6, 0x61, 0x5d, 0x06, 0xda, 0x5e, 0x84,
0xdb, 0x8b, 0x50, 0xd7, 0x8b, 0x33, 0xce, 0xa0, 0x22, 0x39, 0x5c, 0x64, 0xf1, 0x12, 0x4d, 0x32, 0xba, 0x5e, 0x9c, 0x71, 0x06, 0x15, 0xc9, 0xe1, 0x22, 0x8b, 0x97, 0x68, 0x92, 0x59, 0x0d, 0x55,
0xab, 0xa1, 0x6a, 0xc9, 0x4d, 0xa8, 0xc4, 0x5b, 0x60, 0x96, 0xc3, 0xd7, 0xae, 0xd8, 0xf8, 0x1e, 0x4b, 0x6e, 0x42, 0x25, 0xde, 0x02, 0xb3, 0x1c, 0xbe, 0x72, 0xc5, 0xc6, 0x77, 0xa1, 0x79, 0xc0,
0x34, 0x0f, 0xd8, 0x44, 0xb8, 0x6c, 0x27, 0x0b, 0x8e, 0x7d, 0x1d, 0x16, 0x34, 0x8a, 0x52, 0x35, 0x26, 0xc2, 0x65, 0x3b, 0x59, 0x70, 0xec, 0xeb, 0xb0, 0xa0, 0x51, 0x94, 0xaa, 0x29, 0xbe, 0x18,
0xc5, 0x17, 0xe3, 0x59, 0xce, 0xbd, 0x20, 0x14, 0xb5, 0xe0, 0x6f, 0xe3, 0x9f, 0xe4, 0x80, 0x74, 0xcf, 0x72, 0xee, 0x05, 0xa1, 0xa8, 0x05, 0x7f, 0x1b, 0xff, 0x3c, 0x07, 0xa4, 0x13, 0x84, 0xce,
0x82, 0xd0, 0x99, 0xda, 0x21, 0xdd, 0xa3, 0x8a, 0x66, 0xf6, 0xa1, 0xce, 0x4a, 0x1b, 0x7a, 0x6d, 0xd4, 0x0e, 0xe9, 0x1e, 0x55, 0x34, 0xb3, 0x0f, 0x75, 0x56, 0xda, 0xd0, 0x6b, 0x73, 0x16, 0x9a,
0xce, 0x42, 0x73, 0x86, 0xec, 0x7d, 0x41, 0xe3, 0xd2, 0x19, 0xb6, 0x74, 0x6c, 0x7e, 0x4c, 0xc6, 0x33, 0x64, 0xef, 0x0a, 0x1a, 0x97, 0xce, 0xb0, 0xa5, 0x63, 0xf3, 0x63, 0x32, 0x56, 0x00, 0x5b,
0x0a, 0x60, 0xcb, 0x2d, 0xb4, 0xfd, 0x33, 0x1a, 0x22, 0xe3, 0x2d, 0x38, 0x46, 0xe0, 0x20, 0xc6, 0x6e, 0xa1, 0xed, 0x9f, 0xd1, 0x10, 0x19, 0x6f, 0xc1, 0x31, 0x02, 0x07, 0x31, 0x96, 0x7b, 0xf3,
0x72, 0x6f, 0xfe, 0x2c, 0x2c, 0xa7, 0xca, 0xd0, 0x0f, 0xad, 0x6a, 0xc6, 0xa1, 0x55, 0xd0, 0x0f, 0x67, 0x61, 0x39, 0x55, 0x86, 0x7e, 0x68, 0x55, 0x33, 0x0e, 0xad, 0x82, 0x7e, 0x68, 0xfd, 0x7a,
0xad, 0x5f, 0xcf, 0xc1, 0x4a, 0xac, 0x61, 0x62, 0x1b, 0x6e, 0x40, 0x99, 0x91, 0x0b, 0xb6, 0x78, 0x0e, 0x56, 0x62, 0x0d, 0x13, 0xdb, 0x70, 0x03, 0xca, 0x8c, 0x5c, 0xb0, 0xc5, 0x9b, 0xe3, 0x82,
0x73, 0x5c, 0x10, 0x38, 0xa5, 0xb8, 0xc0, 0x3f, 0x86, 0xd5, 0x53, 0x4a, 0x7d, 0x3b, 0xc4, 0x44, 0xc0, 0x29, 0xc5, 0x05, 0xfe, 0x11, 0xac, 0x9e, 0x52, 0xea, 0xdb, 0x21, 0x26, 0x22, 0x3d, 0x61,
0xa4, 0x27, 0x6c, 0x8a, 0x78, 0xc9, 0x9c, 0xea, 0x8b, 0xf4, 0x81, 0x1d, 0x1e, 0x51, 0x9f, 0x4d, 0x53, 0xc4, 0x4b, 0xe6, 0x54, 0x5f, 0xa4, 0x0f, 0xec, 0xf0, 0x88, 0xfa, 0x6c, 0xba, 0x88, 0x01,
0x17, 0x31, 0xa0, 0x21, 0x91, 0x2f, 0x10, 0xbb, 0x80, 0x8b, 0xb8, 0x16, 0x20, 0xca, 0x53, 0x06, 0x0d, 0x89, 0x7c, 0x81, 0xd8, 0x05, 0x5c, 0xc4, 0xb5, 0x00, 0x51, 0xbe, 0x64, 0x20, 0xe3, 0x8f,
0x32, 0xfe, 0x38, 0x0f, 0x4b, 0xec, 0x1c, 0x3a, 0xb4, 0xdd, 0x2b, 0x39, 0xa0, 0x07, 0x99, 0x03, 0xf3, 0xb0, 0xc4, 0xce, 0xa1, 0x43, 0xdb, 0xbd, 0x92, 0x03, 0x7a, 0x90, 0x39, 0xa0, 0xf7, 0x34,
0x7a, 0x4f, 0xe3, 0x3a, 0x34, 0xec, 0xaf, 0x3b, 0x9a, 0x85, 0xe4, 0x68, 0xa6, 0x9b, 0x59, 0x4c, 0xae, 0x43, 0xc3, 0xfe, 0xba, 0xa3, 0x59, 0x48, 0x8e, 0x66, 0xba, 0x99, 0xc5, 0x54, 0x33, 0xc9,
0x35, 0x93, 0xbc, 0x03, 0xf5, 0x58, 0xbf, 0x4b, 0xaa, 0xdf, 0x10, 0x44, 0x1d, 0x56, 0xc2, 0xc3, 0x5b, 0x50, 0x8f, 0xf5, 0xbb, 0xa4, 0xfa, 0x0d, 0x41, 0xd4, 0x61, 0x25, 0x3c, 0x2c, 0x68, 0xc2,
0x82, 0x26, 0x3c, 0x30, 0xd2, 0xc2, 0x76, 0x2a, 0xab, 0x3d, 0x10, 0x1c, 0x21, 0xa3, 0xd7, 0xac, 0x03, 0x23, 0x2d, 0x6c, 0xa7, 0xb2, 0xda, 0x03, 0xc1, 0x11, 0x32, 0x7a, 0xcd, 0xea, 0x0e, 0x98,
0xee, 0x80, 0x49, 0x58, 0x01, 0x23, 0x65, 0xd6, 0xdc, 0x15, 0x52, 0x16, 0x1d, 0x23, 0x3d, 0xa8, 0x84, 0x15, 0x30, 0x52, 0x66, 0xcd, 0x5d, 0x21, 0x65, 0xd1, 0x31, 0xd2, 0x83, 0x8a, 0xd9, 0xc4,
0x98, 0x4d, 0x4c, 0x38, 0x8e, 0xe0, 0x7f, 0xf6, 0x79, 0x7f, 0x17, 0x9a, 0xd1, 0xf0, 0x89, 0x39, 0x84, 0xe3, 0x08, 0xfe, 0x93, 0xcf, 0xfb, 0xdb, 0xd0, 0x8c, 0x86, 0x4f, 0xcc, 0x39, 0x81, 0x22,
0x27, 0x50, 0x64, 0x7b, 0x48, 0x14, 0x80, 0xbf, 0x8d, 0xbf, 0x9b, 0xe7, 0x88, 0x3b, 0x9e, 0x13, 0xdb, 0x43, 0xa2, 0x00, 0xfc, 0x6d, 0xfc, 0x83, 0x3c, 0x47, 0xdc, 0xf1, 0x9c, 0x48, 0xd4, 0x21,
0x89, 0x3a, 0x04, 0x8a, 0xc8, 0x4a, 0x09, 0x44, 0xf6, 0xfb, 0x5a, 0xc1, 0xf1, 0xa7, 0x38, 0xe8, 0x50, 0x44, 0x56, 0x4a, 0x20, 0xb2, 0xdf, 0xd7, 0x0a, 0x8e, 0x3f, 0xc5, 0x41, 0xbf, 0x09, 0x95,
0x37, 0xa1, 0x12, 0xb0, 0x01, 0xb4, 0x27, 0x7c, 0xdc, 0x2b, 0x66, 0x99, 0x7d, 0xb7, 0x27, 0x93, 0x80, 0x0d, 0xa0, 0x3d, 0xe1, 0xe3, 0x5e, 0x31, 0xcb, 0xec, 0xbb, 0x3d, 0x99, 0x44, 0xf3, 0x51,
0x68, 0x3e, 0xca, 0xd7, 0xce, 0x47, 0xe5, 0x75, 0xe6, 0xa3, 0x9a, 0x3d, 0x1f, 0xc6, 0x7b, 0xb0, 0xbe, 0x76, 0x3e, 0x2a, 0xaf, 0x32, 0x1f, 0xd5, 0xec, 0xf9, 0x30, 0xde, 0x81, 0x65, 0x6d, 0x94,
0xac, 0x8d, 0xd2, 0x4b, 0xc6, 0xf3, 0x1c, 0xc8, 0x81, 0x13, 0x84, 0xc7, 0x2e, 0x2b, 0x42, 0xb1, 0x5e, 0x30, 0x9e, 0xe7, 0x40, 0x0e, 0x9c, 0x20, 0x3c, 0x76, 0x59, 0x11, 0x8a, 0xa5, 0x89, 0x35,
0x34, 0xb1, 0x86, 0xe4, 0x12, 0x0d, 0x61, 0x89, 0xf6, 0xa5, 0x48, 0xcc, 0x8b, 0x44, 0xfb, 0x92, 0x24, 0x97, 0x68, 0x08, 0x4b, 0xb4, 0x2f, 0x45, 0x62, 0x5e, 0x24, 0xda, 0x97, 0x3c, 0xf1, 0x7a,
0x27, 0x5e, 0x2f, 0x33, 0x7e, 0x0e, 0x2b, 0xb1, 0x9a, 0x44, 0xa3, 0xde, 0x82, 0xd2, 0x3c, 0xbc, 0x99, 0xf1, 0x33, 0x58, 0x89, 0xd5, 0x24, 0x1a, 0xf5, 0x06, 0x94, 0xe6, 0xe1, 0xa5, 0x27, 0xa5,
0xf4, 0xa4, 0xb4, 0x58, 0x13, 0x7b, 0xe9, 0x38, 0xbc, 0xf4, 0x4c, 0x9e, 0x62, 0x1c, 0xc3, 0x72, 0xc5, 0x9a, 0xd8, 0x4b, 0xc7, 0xe1, 0xa5, 0x67, 0xf2, 0x14, 0xe3, 0x18, 0x96, 0x7b, 0xf4, 0xb9,
0x8f, 0xbe, 0x10, 0x74, 0x51, 0x36, 0xf1, 0x5d, 0x28, 0xbe, 0x42, 0x33, 0x82, 0xe9, 0x7a, 0x83, 0xa0, 0x8b, 0xb2, 0x89, 0x6f, 0x43, 0xf1, 0x25, 0x9a, 0x11, 0x4c, 0xd7, 0x1b, 0x94, 0x8f, 0x37,
0xf2, 0xf1, 0x06, 0x6d, 0x01, 0xd1, 0x8b, 0x15, 0xed, 0xd1, 0x54, 0x28, 0xb9, 0x98, 0x0a, 0xc5, 0x68, 0x0b, 0x88, 0x5e, 0xac, 0x68, 0x8f, 0xa6, 0x42, 0xc9, 0xc5, 0x54, 0x28, 0xc6, 0xdb, 0x40,
0x78, 0x17, 0xc8, 0xc0, 0x39, 0x73, 0x0f, 0x69, 0x10, 0xd8, 0x67, 0x8a, 0xc6, 0x36, 0xa1, 0x30, 0x06, 0xce, 0x99, 0x7b, 0x48, 0x83, 0xc0, 0x3e, 0x53, 0x34, 0xb6, 0x09, 0x85, 0x69, 0x70, 0x26,
0x0d, 0xce, 0xc4, 0x81, 0xc0, 0x7e, 0x1a, 0x1f, 0xc3, 0x4a, 0x0c, 0x4f, 0x14, 0xfc, 0x06, 0x54, 0x0e, 0x04, 0xf6, 0xd3, 0xf8, 0x08, 0x56, 0x62, 0x78, 0xa2, 0xe0, 0xd7, 0xa0, 0x1a, 0x38, 0x67,
0x03, 0xe7, 0xcc, 0x45, 0x29, 0x40, 0x14, 0x1d, 0x01, 0x8c, 0x3d, 0x58, 0x7d, 0x4a, 0x7d, 0xe7, 0x2e, 0x4a, 0x01, 0xa2, 0xe8, 0x08, 0x60, 0xec, 0xc1, 0xea, 0x97, 0xd4, 0x77, 0x4e, 0xaf, 0x5e,
0xf4, 0xea, 0x55, 0xc5, 0xc7, 0xcb, 0xc9, 0x27, 0xcb, 0xe9, 0xc0, 0x5a, 0xa2, 0x1c, 0x51, 0x3d, 0x56, 0x7c, 0xbc, 0x9c, 0x7c, 0xb2, 0x9c, 0x0e, 0xac, 0x25, 0xca, 0x11, 0xd5, 0xf3, 0xad, 0x27,
0xdf, 0x7a, 0x62, 0xf6, 0x2b, 0x26, 0xff, 0xd0, 0x0e, 0x99, 0xbc, 0x7e, 0xc8, 0x18, 0x1e, 0x90, 0x66, 0xbf, 0x62, 0xf2, 0x0f, 0xed, 0x90, 0xc9, 0xeb, 0x87, 0x8c, 0xe1, 0x01, 0xd9, 0xf1, 0x5c,
0x1d, 0xcf, 0x75, 0xe9, 0x28, 0x3c, 0xa2, 0xd4, 0x97, 0x8d, 0x79, 0x5f, 0xdb, 0x67, 0xb5, 0x87, 0x97, 0x8e, 0xc2, 0x23, 0x4a, 0x7d, 0xd9, 0x98, 0x77, 0xb5, 0x7d, 0x56, 0x7b, 0xb8, 0x21, 0xc6,
0x1b, 0x62, 0xcc, 0x93, 0x27, 0x97, 0xd8, 0x80, 0x04, 0x8a, 0x33, 0xea, 0x4f, 0xb1, 0xe0, 0x8a, 0x3c, 0x79, 0x72, 0x89, 0x0d, 0x48, 0xa0, 0x38, 0xa3, 0xfe, 0x14, 0x0b, 0xae, 0x98, 0xf8, 0x9b,
0x89, 0xbf, 0xd9, 0xe0, 0x86, 0xce, 0x94, 0x7a, 0xf3, 0x50, 0x50, 0x5c, 0xf9, 0x69, 0xac, 0xc1, 0x0d, 0x6e, 0xe8, 0x4c, 0xa9, 0x37, 0x0f, 0x05, 0xc5, 0x95, 0x9f, 0xc6, 0x1a, 0xac, 0xc4, 0x2a,
0x4a, 0xac, 0x42, 0xde, 0x6a, 0xe3, 0x01, 0xac, 0xed, 0x3a, 0xc1, 0x28, 0xdd, 0x94, 0x0d, 0x28, 0xe4, 0xad, 0x36, 0x1e, 0xc0, 0xda, 0xae, 0x13, 0x8c, 0xd2, 0x4d, 0xd9, 0x80, 0xf2, 0x6c, 0x7e,
0xcf, 0xe6, 0x27, 0x56, 0xfc, 0x78, 0x7c, 0x42, 0xaf, 0x8c, 0x16, 0xac, 0x27, 0x73, 0x88, 0xb2, 0x62, 0xc5, 0x8f, 0xc7, 0x27, 0xf4, 0xca, 0x68, 0xc1, 0x7a, 0x32, 0x87, 0x28, 0xeb, 0xd7, 0xf2,
0x7e, 0x2d, 0x0f, 0xc5, 0xfd, 0xe1, 0xc1, 0x0e, 0xd9, 0x84, 0x8a, 0xe3, 0x8e, 0xbc, 0x29, 0x13, 0x50, 0xdc, 0x1f, 0x1e, 0xec, 0x90, 0x4d, 0xa8, 0x38, 0xee, 0xc8, 0x9b, 0x32, 0xe1, 0x80, 0x8f,
0x0e, 0xf8, 0x68, 0xa8, 0xef, 0x6b, 0xc9, 0xc6, 0x2d, 0xa8, 0xa2, 0x4c, 0x31, 0xf1, 0x46, 0xcf, 0x86, 0xfa, 0xbe, 0x96, 0x6c, 0xdc, 0x82, 0x2a, 0xca, 0x14, 0x13, 0x6f, 0xf4, 0x4c, 0xb0, 0xe7,
0x05, 0x7b, 0x5e, 0x61, 0x80, 0x03, 0x6f, 0xf4, 0x9c, 0x6d, 0x4d, 0x7a, 0x39, 0x73, 0x7c, 0x54, 0x15, 0x06, 0x38, 0xf0, 0x46, 0xcf, 0xd8, 0xd6, 0xa4, 0x97, 0x33, 0xc7, 0x47, 0x75, 0x93, 0x54,
0x37, 0x49, 0x75, 0x4a, 0x91, 0xf3, 0xa3, 0x51, 0x42, 0xa4, 0x74, 0x11, 0xac, 0x13, 0x63, 0x06, 0xa7, 0x14, 0x39, 0x3f, 0x1a, 0x25, 0x44, 0x4a, 0x17, 0xc1, 0x3a, 0x31, 0x66, 0x80, 0xf3, 0xe9,
0x38, 0x9f, 0x5e, 0x3d, 0x47, 0xd6, 0x69, 0x4c, 0x2f, 0xc9, 0x07, 0x40, 0x4e, 0x3d, 0xff, 0x85, 0xd5, 0x73, 0x64, 0x9d, 0xc6, 0xf4, 0x92, 0xbc, 0x0f, 0xe4, 0xd4, 0xf3, 0x9f, 0xdb, 0xbe, 0x62,
0xed, 0x2b, 0xd6, 0xd2, 0x15, 0x64, 0xbb, 0x68, 0x2e, 0x47, 0x29, 0x82, 0x6d, 0x22, 0x0f, 0x61, 0x2d, 0x5d, 0x41, 0xb6, 0x8b, 0xe6, 0x72, 0x94, 0x22, 0xd8, 0x26, 0xf2, 0x10, 0xd6, 0x34, 0x74,
0x4d, 0x43, 0xd7, 0x0a, 0xe6, 0x2c, 0xde, 0x4a, 0x94, 0xb8, 0x2f, 0xab, 0x30, 0x7e, 0x35, 0x0f, 0xad, 0x60, 0xce, 0xe2, 0xad, 0x44, 0x89, 0xfb, 0xb2, 0x0a, 0xe3, 0x57, 0xf3, 0x40, 0x44, 0xfe,
0x44, 0xe4, 0xdf, 0xf1, 0xdc, 0x20, 0xf4, 0x6d, 0xc7, 0x0d, 0x83, 0x38, 0xa3, 0x99, 0x4b, 0x30, 0x1d, 0xcf, 0x0d, 0x42, 0xdf, 0x76, 0xdc, 0x30, 0x88, 0x33, 0x9a, 0xb9, 0x04, 0xa3, 0x79, 0x0f,
0x9a, 0xf7, 0xa0, 0x89, 0x6c, 0xae, 0xce, 0x6d, 0xe6, 0x23, 0x9e, 0xdf, 0x8c, 0x38, 0xce, 0x77, 0x9a, 0xc8, 0xe6, 0xea, 0xdc, 0x66, 0x3e, 0xe2, 0xf9, 0xcd, 0x88, 0xe3, 0x7c, 0x0b, 0x16, 0x23,
0x60, 0x31, 0x12, 0x35, 0x94, 0xb6, 0xb1, 0x68, 0xd6, 0x95, 0xb8, 0xc1, 0xb0, 0x3e, 0x84, 0x55, 0x51, 0x43, 0x69, 0x1b, 0x8b, 0x66, 0x5d, 0x89, 0x1b, 0x0c, 0xeb, 0x03, 0x58, 0x65, 0x44, 0x44,
0x46, 0x44, 0x24, 0x0b, 0xad, 0x54, 0x27, 0x9c, 0xd8, 0x2e, 0x4f, 0xed, 0xcb, 0x23, 0x2a, 0x05, 0xb2, 0xd0, 0x4a, 0x75, 0xc2, 0x89, 0xed, 0xf2, 0xd4, 0xbe, 0x3c, 0xa2, 0x52, 0xb0, 0x41, 0xde,
0x1b, 0xe4, 0x4d, 0x0d, 0x68, 0x28, 0xae, 0x13, 0x31, 0xf9, 0xc8, 0xd5, 0x04, 0xdf, 0x89, 0x38, 0xd4, 0x80, 0x86, 0xe2, 0x3a, 0x11, 0x93, 0x8f, 0x5c, 0x4d, 0xf0, 0x9d, 0x88, 0x93, 0x2d, 0x18,
0xd9, 0x82, 0xc1, 0x42, 0xb6, 0x60, 0x60, 0xfc, 0xeb, 0x2a, 0x94, 0xe5, 0x30, 0x22, 0x97, 0x1f, 0x2c, 0x64, 0x0b, 0x06, 0xc6, 0xbf, 0xab, 0x42, 0x59, 0x0e, 0x23, 0x72, 0xf9, 0xa1, 0x73, 0x41,
0x3a, 0x17, 0x34, 0xe2, 0xf2, 0xd9, 0x17, 0x13, 0x1e, 0x7c, 0x3a, 0xf5, 0x42, 0x25, 0xdd, 0xf1, 0x23, 0x2e, 0x9f, 0x7d, 0x31, 0xe1, 0xc1, 0xa7, 0x53, 0x2f, 0x54, 0xd2, 0x1d, 0xdf, 0x26, 0x75,
0x6d, 0x52, 0xe7, 0x40, 0x21, 0xdf, 0x69, 0x12, 0x06, 0x57, 0x92, 0x72, 0xca, 0x27, 0x25, 0x0c, 0x0e, 0x14, 0xf2, 0x9d, 0x26, 0x61, 0x70, 0x25, 0x29, 0xa7, 0x7c, 0x52, 0xc2, 0xe0, 0xfc, 0xe3,
0xce, 0x3f, 0xde, 0x82, 0xb2, 0x94, 0x13, 0x8a, 0x4a, 0x47, 0xb2, 0x30, 0xe2, 0x42, 0xc2, 0x26, 0x2d, 0x28, 0x4b, 0x39, 0xa1, 0xa8, 0x74, 0x24, 0x0b, 0x23, 0x2e, 0x24, 0x6c, 0x42, 0x65, 0x64,
0x54, 0x46, 0xf6, 0xcc, 0x1e, 0x39, 0x21, 0x67, 0xf1, 0x0b, 0xa6, 0xfa, 0x66, 0xa5, 0x4f, 0xbc, 0xcf, 0xec, 0x91, 0x13, 0x72, 0x16, 0xbf, 0x60, 0xaa, 0x6f, 0x56, 0xfa, 0xc4, 0x1b, 0xd9, 0x13,
0x91, 0x3d, 0xb1, 0x4e, 0xec, 0x89, 0xed, 0x8e, 0xa8, 0xd0, 0x3e, 0xd6, 0x11, 0xb8, 0xcd, 0x61, 0xeb, 0xc4, 0x9e, 0xd8, 0xee, 0x88, 0x0a, 0xed, 0x63, 0x1d, 0x81, 0xdb, 0x1c, 0x46, 0xbe, 0x05,
0xe4, 0x5b, 0xb0, 0x28, 0xda, 0x29, 0xb1, 0xb8, 0x12, 0x52, 0xb4, 0x5e, 0xa2, 0x31, 0x49, 0xd4, 0x8b, 0xa2, 0x9d, 0x12, 0x8b, 0x2b, 0x21, 0x45, 0xeb, 0x25, 0x1a, 0x93, 0x44, 0xbd, 0x29, 0x9b,
0x9b, 0xb2, 0x79, 0x39, 0xa5, 0x5c, 0x66, 0x2b, 0x98, 0x55, 0x0e, 0xd9, 0xa3, 0xd8, 0x5b, 0x91, 0x97, 0x53, 0xca, 0x65, 0xb6, 0x82, 0x59, 0xe5, 0x90, 0x3d, 0x8a, 0xbd, 0x15, 0xc9, 0xcf, 0xf9,
0xfc, 0x82, 0xaf, 0xe1, 0x2a, 0xaf, 0x8a, 0x03, 0xbf, 0xe2, 0xeb, 0x37, 0x2d, 0xb8, 0x15, 0x34, 0x1a, 0xae, 0xf2, 0xaa, 0x38, 0xf0, 0x2b, 0xbe, 0x7e, 0xd3, 0x82, 0x5b, 0x41, 0x13, 0xdc, 0xde,
0xc1, 0xed, 0x7d, 0x58, 0x9e, 0xbb, 0x01, 0x0d, 0xc3, 0x09, 0x1d, 0xab, 0xb6, 0xd4, 0x10, 0xa9, 0x85, 0xe5, 0xb9, 0x1b, 0xd0, 0x30, 0x9c, 0xd0, 0xb1, 0x6a, 0x4b, 0x0d, 0x91, 0x9a, 0x2a, 0x41,
0xa9, 0x12, 0x64, 0x73, 0xb6, 0x60, 0x85, 0xab, 0x4d, 0x03, 0x3b, 0xf4, 0x82, 0x73, 0x27, 0xb0, 0x36, 0x67, 0x0b, 0x56, 0xb8, 0xda, 0x34, 0xb0, 0x43, 0x2f, 0x38, 0x77, 0x02, 0x2b, 0xa0, 0xae,
0x02, 0xea, 0x4a, 0xf5, 0xd9, 0x32, 0x26, 0x0d, 0x44, 0xca, 0x80, 0xab, 0x5c, 0x36, 0x12, 0xf8, 0x54, 0x9f, 0x2d, 0x63, 0xd2, 0x40, 0xa4, 0x0c, 0xb8, 0xca, 0x65, 0x23, 0x81, 0xef, 0xd3, 0x11,
0x3e, 0x1d, 0x51, 0xe7, 0x82, 0x8e, 0x51, 0xa8, 0x2b, 0x98, 0x6b, 0xb1, 0x3c, 0xa6, 0x48, 0x44, 0x75, 0x2e, 0xe8, 0x18, 0x85, 0xba, 0x82, 0xb9, 0x16, 0xcb, 0x63, 0x8a, 0x44, 0x94, 0xd0, 0xe7,
0x09, 0x7d, 0x3e, 0xb5, 0xe6, 0xb3, 0xb1, 0xcd, 0x98, 0xf7, 0x45, 0x2e, 0x25, 0xb9, 0xf3, 0xe9, 0x53, 0x6b, 0x3e, 0x1b, 0xdb, 0x8c, 0x79, 0x5f, 0xe4, 0x52, 0x92, 0x3b, 0x9f, 0x1e, 0x73, 0x08,
0x31, 0x87, 0x90, 0x07, 0x20, 0xa5, 0x36, 0xb1, 0x66, 0x96, 0x62, 0x87, 0x11, 0xa3, 0x1a, 0x66, 0x79, 0x00, 0x52, 0x6a, 0x13, 0x6b, 0x66, 0x29, 0x76, 0x18, 0x31, 0xaa, 0x61, 0xd6, 0x05, 0x06,
0x5d, 0x60, 0x70, 0xa9, 0xf2, 0x8e, 0xbe, 0x59, 0x9a, 0x6c, 0x85, 0xe1, 0xf1, 0x1f, 0x6d, 0x98, 0x97, 0x2a, 0xef, 0xe8, 0x9b, 0xa5, 0xc9, 0x56, 0x18, 0x1e, 0xff, 0xd1, 0x86, 0x69, 0x41, 0x79,
0x16, 0x94, 0x67, 0xbe, 0x73, 0x61, 0x87, 0xb4, 0xb5, 0xcc, 0xcf, 0x7e, 0xf1, 0xc9, 0x08, 0xb8, 0xe6, 0x3b, 0x17, 0x76, 0x48, 0x5b, 0xcb, 0xfc, 0xec, 0x17, 0x9f, 0x8c, 0x80, 0x3b, 0xae, 0x13,
0xe3, 0x3a, 0xa1, 0x63, 0x87, 0x9e, 0xdf, 0x22, 0x98, 0x16, 0x01, 0xc8, 0x7d, 0x58, 0xc6, 0x75, 0x3a, 0x76, 0xe8, 0xf9, 0x2d, 0x82, 0x69, 0x11, 0x80, 0xdc, 0x87, 0x65, 0x5c, 0x27, 0x41, 0x68,
0x12, 0x84, 0x76, 0x38, 0x0f, 0x84, 0xc8, 0xba, 0xc2, 0x45, 0x43, 0x96, 0x30, 0x40, 0x38, 0x4a, 0x87, 0xf3, 0x40, 0x88, 0xac, 0x2b, 0x5c, 0x34, 0x64, 0x09, 0x03, 0x84, 0xa3, 0xd4, 0x4a, 0x3e,
0xad, 0xe4, 0x33, 0x58, 0xe7, 0x4b, 0x23, 0xb5, 0x35, 0x57, 0x15, 0x43, 0xb2, 0x82, 0x18, 0x3b, 0x85, 0x75, 0xbe, 0x34, 0x52, 0x5b, 0x73, 0x55, 0x31, 0x24, 0x2b, 0x88, 0xb1, 0x13, 0xdf, 0xa3,
0xf1, 0x3d, 0xfa, 0x05, 0x6c, 0x88, 0xe5, 0x92, 0xca, 0xb9, 0xa6, 0x72, 0xae, 0x72, 0x94, 0x44, 0x9f, 0xc3, 0x86, 0x58, 0x2e, 0xa9, 0x9c, 0x6b, 0x2a, 0xe7, 0x2a, 0x47, 0x49, 0x64, 0xdd, 0x82,
0xd6, 0x2d, 0x58, 0x66, 0x4d, 0x73, 0x46, 0x96, 0x28, 0x81, 0xed, 0x8a, 0x75, 0xd6, 0x0b, 0xcc, 0x65, 0xd6, 0x34, 0x67, 0x64, 0x89, 0x12, 0xd8, 0xae, 0x58, 0x67, 0xbd, 0xc0, 0x4c, 0x4b, 0x3c,
0xb4, 0xc4, 0x13, 0x4d, 0x4c, 0x7b, 0x42, 0xaf, 0xc8, 0xf7, 0x60, 0x89, 0x2f, 0x1f, 0xd4, 0xcb, 0xd1, 0xc4, 0xb4, 0x27, 0xf4, 0x8a, 0x7c, 0x17, 0x96, 0xf8, 0xf2, 0x41, 0xbd, 0x0c, 0x1e, 0xd9,
0xe0, 0x91, 0xbd, 0x89, 0x47, 0xf6, 0x9a, 0x18, 0xdc, 0x1d, 0x95, 0x8a, 0xa7, 0xf6, 0xe2, 0x28, 0x9b, 0x78, 0x64, 0xaf, 0x89, 0xc1, 0xdd, 0x51, 0xa9, 0x78, 0x6a, 0x2f, 0x8e, 0x62, 0xdf, 0x6c,
0xf6, 0xcd, 0xb6, 0xc6, 0xc4, 0x39, 0xa5, 0xec, 0x9c, 0x68, 0x6d, 0xf0, 0xc5, 0x26, 0xbf, 0xd9, 0x6b, 0x4c, 0x9c, 0x53, 0xca, 0xce, 0x89, 0xd6, 0x06, 0x5f, 0x6c, 0xf2, 0x9b, 0xed, 0xda, 0xf9,
0xae, 0x9d, 0xcf, 0x30, 0xa5, 0xc5, 0x89, 0x35, 0xff, 0xc2, 0x75, 0x3c, 0xf1, 0x02, 0x2a, 0x15, 0x0c, 0x53, 0x5a, 0x9c, 0x58, 0xf3, 0x2f, 0x5c, 0xc7, 0x13, 0x2f, 0xa0, 0x52, 0xe1, 0xde, 0xba,
0xee, 0xad, 0x9b, 0x62, 0x43, 0x32, 0xa0, 0x94, 0xaf, 0x98, 0x00, 0xcf, 0xb5, 0x25, 0xca, 0x2c, 0x29, 0x36, 0x24, 0x03, 0x4a, 0xf9, 0x8a, 0x09, 0xf0, 0x5c, 0x5b, 0xa2, 0xcc, 0x22, 0xb7, 0x70,
0x72, 0x0b, 0x17, 0x46, 0x83, 0x2b, 0x4d, 0xa4, 0x69, 0x84, 0x31, 0x8c, 0xe7, 0xf6, 0x0b, 0x49, 0x61, 0x34, 0xb8, 0xd2, 0x44, 0x9a, 0x46, 0x18, 0xc3, 0x78, 0x6e, 0x3f, 0x97, 0x64, 0xfd, 0x35,
0xd6, 0xdf, 0x40, 0x6a, 0x02, 0x0c, 0x24, 0x08, 0xfa, 0x1e, 0x2c, 0x8b, 0x59, 0x88, 0x88, 0x69, 0xa4, 0x26, 0xc0, 0x40, 0x82, 0xa0, 0xef, 0xc1, 0xb2, 0x98, 0x85, 0x88, 0x98, 0xb6, 0x6e, 0xe3,
0xeb, 0x36, 0x1e, 0x91, 0x37, 0x65, 0x1f, 0x53, 0xd4, 0xd6, 0x6c, 0xf2, 0x79, 0xd1, 0xe8, 0xef, 0x11, 0x79, 0x53, 0xf6, 0x31, 0x45, 0x6d, 0xcd, 0x26, 0x9f, 0x17, 0x8d, 0xfe, 0xee, 0x03, 0x91,
0x3e, 0x10, 0x39, 0x29, 0x5a, 0x41, 0x6f, 0xbe, 0xaa, 0xa0, 0x65, 0x31, 0x4d, 0x11, 0xc8, 0xf8, 0x93, 0xa2, 0x15, 0xf4, 0xfa, 0xcb, 0x0a, 0x5a, 0x16, 0xd3, 0x14, 0x81, 0x8c, 0xdf, 0xcb, 0x71,
0xbd, 0x1c, 0xe7, 0xb5, 0x04, 0x76, 0xa0, 0x69, 0xaa, 0x38, 0x5d, 0xb3, 0x3c, 0x77, 0x72, 0x25, 0x5e, 0x4b, 0x60, 0x07, 0x9a, 0xa6, 0x8a, 0xd3, 0x35, 0xcb, 0x73, 0x27, 0x57, 0x82, 0xd4, 0x01,
0x48, 0x1d, 0x70, 0x50, 0xdf, 0x9d, 0x20, 0xad, 0x71, 0x5c, 0x1d, 0x85, 0x1f, 0xde, 0x75, 0x09, 0x07, 0xf5, 0xdd, 0x09, 0xd2, 0x1a, 0xc7, 0xd5, 0x51, 0xf8, 0xe1, 0x5d, 0x97, 0x40, 0x44, 0xba,
0x44, 0xa4, 0x3b, 0x50, 0x9b, 0xcd, 0x4f, 0x26, 0xce, 0x88, 0xa3, 0x14, 0x78, 0x29, 0x1c, 0x84, 0x03, 0xb5, 0xd9, 0xfc, 0x64, 0xe2, 0x8c, 0x38, 0x4a, 0x81, 0x97, 0xc2, 0x41, 0x88, 0xf0, 0x06,
0x08, 0x6f, 0x41, 0x5d, 0xac, 0x75, 0x8e, 0x51, 0x44, 0x8c, 0x9a, 0x80, 0x21, 0x0a, 0x32, 0x07, 0xd4, 0xc5, 0x5a, 0xe7, 0x18, 0x45, 0xc4, 0xa8, 0x09, 0x18, 0xa2, 0x20, 0x73, 0x40, 0x7d, 0x24,
0xd4, 0x47, 0x62, 0x57, 0x37, 0xf1, 0xb7, 0xb1, 0x0d, 0xab, 0xf1, 0x46, 0x0b, 0xce, 0xe5, 0x3e, 0x76, 0x75, 0x13, 0x7f, 0x1b, 0xdb, 0xb0, 0x1a, 0x6f, 0xb4, 0xe0, 0x5c, 0xee, 0x43, 0x45, 0x50,
0x54, 0x04, 0x25, 0x95, 0x6a, 0xde, 0xc5, 0xf8, 0x68, 0x98, 0x2a, 0xdd, 0xf8, 0x37, 0x25, 0x58, 0x52, 0xa9, 0xe6, 0x5d, 0x8c, 0x8f, 0x86, 0xa9, 0xd2, 0x8d, 0x7f, 0x5f, 0x82, 0x15, 0x39, 0x46,
0x91, 0x63, 0xc4, 0x26, 0x7b, 0x30, 0x9f, 0x4e, 0x6d, 0x3f, 0x83, 0x44, 0xe7, 0x5e, 0x4e, 0xa2, 0x6c, 0xb2, 0x07, 0xf3, 0xe9, 0xd4, 0xf6, 0x33, 0x48, 0x74, 0xee, 0xc5, 0x24, 0x3a, 0x9f, 0x22,
0xf3, 0x29, 0x12, 0x1d, 0x57, 0xe2, 0x71, 0x0a, 0x1f, 0x57, 0xe2, 0xb1, 0xd5, 0xc5, 0x55, 0x07, 0xd1, 0x71, 0x25, 0x1e, 0xa7, 0xf0, 0x71, 0x25, 0x1e, 0x5b, 0x5d, 0x5c, 0x75, 0xa0, 0xdb, 0x99,
0xba, 0x9d, 0xa9, 0x21, 0xc0, 0x43, 0x6e, 0xcf, 0x4a, 0x1d, 0x28, 0xa5, 0x8c, 0x03, 0x45, 0x3f, 0x1a, 0x02, 0x3c, 0xe4, 0xf6, 0xac, 0xd4, 0x81, 0x52, 0xca, 0x38, 0x50, 0xf4, 0xe3, 0x60, 0x21,
0x0e, 0x16, 0x12, 0xc7, 0xc1, 0x5b, 0xc0, 0x97, 0xb1, 0x5c, 0x8f, 0x65, 0xae, 0x4d, 0x40, 0x98, 0x71, 0x1c, 0xbc, 0x01, 0x7c, 0x19, 0xcb, 0xf5, 0x58, 0xe6, 0xda, 0x04, 0x84, 0x89, 0x05, 0xf9,
0x58, 0x90, 0xef, 0xc1, 0x52, 0x92, 0x02, 0x73, 0x52, 0xbf, 0x98, 0x41, 0x7f, 0x9d, 0x29, 0x45, 0x0e, 0x2c, 0x25, 0x29, 0x30, 0x27, 0xf5, 0x8b, 0x19, 0xf4, 0xd7, 0x99, 0x52, 0x64, 0x6a, 0x34,
0xa6, 0x46, 0x43, 0xae, 0x0a, 0xfa, 0xeb, 0x4c, 0xe9, 0x01, 0xa6, 0x48, 0xfc, 0x0e, 0x00, 0xaf, 0xe4, 0xaa, 0xa0, 0xbf, 0xce, 0x94, 0x1e, 0x60, 0x8a, 0xc4, 0xef, 0x00, 0xf0, 0xba, 0x71, 0x1b,
0x1b, 0xb7, 0x31, 0xe0, 0x36, 0x7e, 0x37, 0xb1, 0x32, 0xb5, 0x51, 0xdf, 0x62, 0x1f, 0x73, 0x9f, 0x03, 0x6e, 0xe3, 0xb7, 0x13, 0x2b, 0x53, 0x1b, 0xf5, 0x2d, 0xf6, 0x31, 0xf7, 0x29, 0xee, 0xeb,
0xe2, 0xbe, 0xae, 0x62, 0x4e, 0xdc, 0xd2, 0x9f, 0xc1, 0xa2, 0x37, 0xa3, 0xae, 0x15, 0x51, 0xc1, 0x2a, 0xe6, 0xc4, 0x2d, 0xfd, 0x29, 0x2c, 0x7a, 0x33, 0xea, 0x5a, 0x11, 0x15, 0xac, 0x61, 0x51,
0x1a, 0x16, 0xd5, 0x14, 0x45, 0x75, 0x25, 0xdc, 0x6c, 0x30, 0x3c, 0xf5, 0x49, 0xbe, 0xe0, 0x83, 0x4d, 0x51, 0x54, 0x57, 0xc2, 0xcd, 0x06, 0xc3, 0x53, 0x9f, 0xe4, 0x73, 0x3e, 0xc8, 0x54, 0xcb,
0x4c, 0xb5, 0x9c, 0xf5, 0x6b, 0x72, 0x2e, 0x22, 0x62, 0x94, 0xf5, 0x63, 0x54, 0x94, 0x79, 0x93, 0x59, 0xbf, 0x26, 0xe7, 0x22, 0x22, 0x46, 0x59, 0x3f, 0x42, 0x45, 0x99, 0x37, 0x99, 0x73, 0xd3,
0x39, 0x37, 0x4d, 0x35, 0x70, 0x1d, 0x49, 0x5d, 0xbd, 0xa9, 0x52, 0x4c, 0x1d, 0xcb, 0xf8, 0x8d, 0x54, 0x03, 0xd7, 0x91, 0xd4, 0xd5, 0x9b, 0x2a, 0xc5, 0xd4, 0xb1, 0x8c, 0xdf, 0xc8, 0x41, 0x4d,
0x1c, 0xd4, 0xb4, 0x3e, 0x90, 0x35, 0x58, 0xde, 0xe9, 0xf7, 0x8f, 0x3a, 0x66, 0x7b, 0xd8, 0x7d, 0xeb, 0x03, 0x59, 0x83, 0xe5, 0x9d, 0x7e, 0xff, 0xa8, 0x63, 0xb6, 0x87, 0xdd, 0x2f, 0x3b, 0xd6,
0xda, 0xb1, 0x76, 0x0e, 0xfa, 0x83, 0x4e, 0xf3, 0x06, 0x03, 0x1f, 0xf4, 0x77, 0xda, 0x07, 0xd6, 0xce, 0x41, 0x7f, 0xd0, 0x69, 0xde, 0x60, 0xe0, 0x83, 0xfe, 0x4e, 0xfb, 0xc0, 0xda, 0xeb, 0x9b,
0x5e, 0xdf, 0xdc, 0x91, 0xe0, 0x1c, 0x59, 0x07, 0x62, 0x76, 0x0e, 0xfb, 0xc3, 0x4e, 0x0c, 0x9e, 0x3b, 0x12, 0x9c, 0x23, 0xeb, 0x40, 0xcc, 0xce, 0x61, 0x7f, 0xd8, 0x89, 0xc1, 0xf3, 0xa4, 0x09,
0x27, 0x4d, 0xa8, 0x6f, 0x9b, 0x9d, 0xf6, 0xce, 0xbe, 0x80, 0x14, 0xc8, 0x2a, 0x34, 0xf7, 0x8e, 0xf5, 0x6d, 0xb3, 0xd3, 0xde, 0xd9, 0x17, 0x90, 0x02, 0x59, 0x85, 0xe6, 0xde, 0x71, 0x6f, 0xb7,
0x7b, 0xbb, 0xdd, 0xde, 0x63, 0x6b, 0xa7, 0xdd, 0xdb, 0xe9, 0x1c, 0x74, 0x76, 0x9b, 0x45, 0xd2, 0xdb, 0x7b, 0x6c, 0xed, 0xb4, 0x7b, 0x3b, 0x9d, 0x83, 0xce, 0x6e, 0xb3, 0x48, 0x1a, 0x50, 0x6d,
0x80, 0x6a, 0x7b, 0xbb, 0xdd, 0xdb, 0xed, 0xf7, 0x3a, 0xbb, 0xcd, 0x92, 0xf1, 0xc7, 0x39, 0x80, 0x6f, 0xb7, 0x7b, 0xbb, 0xfd, 0x5e, 0x67, 0xb7, 0x59, 0x32, 0xfe, 0x38, 0x07, 0x10, 0x35, 0x94,
0xa8, 0xa1, 0x8c, 0xae, 0x46, 0x4d, 0xd5, 0x8d, 0xc4, 0x6b, 0xa9, 0x4e, 0x71, 0xba, 0xea, 0xc7, 0xd1, 0xd5, 0xa8, 0xa9, 0xba, 0x91, 0x78, 0x2d, 0xd5, 0x29, 0x4e, 0x57, 0xfd, 0xd8, 0x37, 0x79,
0xbe, 0xc9, 0x43, 0x28, 0x7b, 0xf3, 0x70, 0xe4, 0x4d, 0xb9, 0x10, 0xb1, 0xf8, 0xb0, 0x95, 0xca, 0x08, 0x65, 0x6f, 0x1e, 0x8e, 0xbc, 0x29, 0x17, 0x22, 0x16, 0x1f, 0xb6, 0x52, 0xf9, 0xfa, 0x3c,
0xd7, 0xe7, 0xe9, 0xa6, 0x44, 0x8c, 0x19, 0x82, 0x0b, 0xaf, 0x32, 0x04, 0xc7, 0x2d, 0xce, 0x9c, 0xdd, 0x94, 0x88, 0x31, 0x43, 0x70, 0xe1, 0x65, 0x86, 0xe0, 0xb8, 0xc5, 0x99, 0xf3, 0x75, 0x9a,
0xaf, 0xd3, 0x2c, 0xce, 0xb7, 0x01, 0x82, 0x17, 0x94, 0xce, 0x50, 0xd3, 0x26, 0x76, 0x41, 0x15, 0xc5, 0xf9, 0x36, 0x40, 0xf0, 0x9c, 0xd2, 0x19, 0x6a, 0xda, 0xc4, 0x2e, 0xa8, 0x22, 0x64, 0xc8,
0x21, 0x43, 0x26, 0x97, 0xfe, 0x87, 0x1c, 0xac, 0xe1, 0x5a, 0x1a, 0x27, 0x89, 0xd8, 0x5d, 0xa8, 0xe4, 0xd2, 0xff, 0x94, 0x83, 0x35, 0x5c, 0x4b, 0xe3, 0x24, 0x11, 0xbb, 0x0b, 0xb5, 0x91, 0xe7,
0x8d, 0x3c, 0x6f, 0x46, 0x19, 0x53, 0xad, 0xf8, 0x35, 0x1d, 0xc4, 0x08, 0x14, 0x27, 0xc8, 0xa7, 0xcd, 0x28, 0x63, 0xaa, 0x15, 0xbf, 0xa6, 0x83, 0x18, 0x81, 0xe2, 0x04, 0xf9, 0xd4, 0xf3, 0x47,
0x9e, 0x3f, 0xa2, 0x82, 0x86, 0x01, 0x82, 0xf6, 0x18, 0x84, 0xed, 0x21, 0xb1, 0x09, 0x39, 0x06, 0x54, 0xd0, 0x30, 0x40, 0xd0, 0x1e, 0x83, 0xb0, 0x3d, 0x24, 0x36, 0x21, 0xc7, 0xe0, 0x24, 0xac,
0x27, 0x61, 0x35, 0x0e, 0xe3, 0x28, 0xeb, 0xb0, 0x70, 0xe2, 0x53, 0x7b, 0x74, 0x2e, 0xa8, 0x97, 0xc6, 0x61, 0x1c, 0x65, 0x1d, 0x16, 0x4e, 0x7c, 0x6a, 0x8f, 0xce, 0x05, 0xf5, 0x12, 0x5f, 0xe4,
0xf8, 0x22, 0xdf, 0x8e, 0x34, 0x8e, 0x23, 0xb6, 0x27, 0x26, 0x94, 0x37, 0xbe, 0x62, 0x2e, 0x09, 0xdb, 0x91, 0xc6, 0x71, 0xc4, 0xf6, 0xc4, 0x84, 0xf2, 0xc6, 0x57, 0xcc, 0x25, 0x01, 0xdf, 0x11,
0xf8, 0x8e, 0x00, 0xb3, 0x73, 0xde, 0x3e, 0xb1, 0xdd, 0xb1, 0xe7, 0xd2, 0xb1, 0x90, 0xff, 0x23, 0x60, 0x76, 0xce, 0xdb, 0x27, 0xb6, 0x3b, 0xf6, 0x5c, 0x3a, 0x16, 0xf2, 0x7f, 0x04, 0x30, 0x8e,
0x80, 0x71, 0x04, 0xeb, 0xc9, 0xfe, 0x09, 0x7a, 0xf7, 0xa9, 0x46, 0xef, 0xb8, 0x50, 0xbc, 0x79, 0x60, 0x3d, 0xd9, 0x3f, 0x41, 0xef, 0x3e, 0xd1, 0xe8, 0x1d, 0x17, 0x8a, 0x37, 0xaf, 0xdf, 0x63,
0xfd, 0x1e, 0xd3, 0x68, 0xdf, 0x7f, 0x2c, 0x42, 0x91, 0x09, 0x3c, 0xd7, 0xca, 0x46, 0xba, 0x6c, 0x1a, 0xed, 0xfb, 0xcf, 0x45, 0x28, 0x32, 0x81, 0xe7, 0x5a, 0xd9, 0x48, 0x97, 0x6d, 0x0b, 0x29,
0x5b, 0x48, 0xb9, 0x07, 0xa0, 0x62, 0x93, 0x33, 0x60, 0x62, 0xb2, 0x10, 0x82, 0x8c, 0x97, 0x4a, 0xf7, 0x00, 0x54, 0x6c, 0x72, 0x06, 0x4c, 0x4c, 0x16, 0x42, 0x90, 0xf1, 0x52, 0xc9, 0x3e, 0x1d,
0xf6, 0xe9, 0xe8, 0x42, 0xca, 0x2c, 0x08, 0x31, 0xe9, 0xe8, 0x02, 0x15, 0x1d, 0x76, 0xc8, 0xf3, 0x5d, 0x48, 0x99, 0x05, 0x21, 0x26, 0x1d, 0x5d, 0xa0, 0xa2, 0xc3, 0x0e, 0x79, 0x5e, 0x4e, 0xaf,
0x72, 0x7a, 0x55, 0x0e, 0xec, 0x10, 0x73, 0x8a, 0x24, 0xcc, 0x57, 0x56, 0x49, 0x98, 0xab, 0x05, 0xca, 0x81, 0x1d, 0x62, 0x4e, 0x91, 0x84, 0xf9, 0xca, 0x2a, 0x09, 0x73, 0xb5, 0xa0, 0xec, 0xb8,
0x65, 0xc7, 0x3d, 0xf1, 0xe6, 0xae, 0x54, 0x2b, 0xc9, 0x4f, 0xf4, 0x46, 0x40, 0x4a, 0xca, 0x8e, 0x27, 0xde, 0xdc, 0x95, 0x6a, 0x25, 0xf9, 0x89, 0xde, 0x08, 0x48, 0x49, 0xd9, 0xd1, 0xce, 0xa9,
0x76, 0x4e, 0x8d, 0x2a, 0x0c, 0x30, 0x64, 0x87, 0xfb, 0x47, 0x50, 0x0d, 0xae, 0xdc, 0x91, 0x4e, 0x51, 0x85, 0x01, 0x86, 0xec, 0x70, 0xff, 0x10, 0xaa, 0xc1, 0x95, 0x3b, 0xd2, 0x69, 0xd0, 0xaa,
0x83, 0x56, 0xc5, 0xf8, 0xb0, 0xde, 0x6f, 0x0d, 0xae, 0xdc, 0x11, 0xae, 0xf8, 0x4a, 0x20, 0x7e, 0x18, 0x1f, 0xd6, 0xfb, 0xad, 0xc1, 0x95, 0x3b, 0xc2, 0x15, 0x5f, 0x09, 0xc4, 0x2f, 0xf2, 0x08,
0x91, 0x47, 0x50, 0x51, 0x56, 0x3a, 0x7e, 0x82, 0xdc, 0xd4, 0x73, 0x48, 0xd3, 0x1c, 0xd7, 0xd1, 0x2a, 0xca, 0x4a, 0xc7, 0x4f, 0x90, 0x9b, 0x7a, 0x0e, 0x69, 0x9a, 0xe3, 0x3a, 0x3a, 0x85, 0x4a,
0x29, 0x54, 0xf2, 0x21, 0x2c, 0xa0, 0xb6, 0x3e, 0x68, 0xd5, 0x31, 0x93, 0x14, 0x78, 0x59, 0x33, 0x3e, 0x80, 0x05, 0xd4, 0xd6, 0x07, 0xad, 0x3a, 0x66, 0x92, 0x02, 0x2f, 0x6b, 0x06, 0x3a, 0x02,
0xd0, 0x11, 0x80, 0x8e, 0xd1, 0x66, 0x66, 0x0a, 0x34, 0x36, 0x4c, 0xa7, 0x13, 0x7b, 0x26, 0x74, 0xd0, 0x31, 0xda, 0xcc, 0x4c, 0x81, 0xc6, 0x86, 0xe9, 0x74, 0x62, 0xcf, 0x84, 0xee, 0xbc, 0xc1,
0xe7, 0x0d, 0x6e, 0x4f, 0x67, 0x10, 0xae, 0x38, 0xbf, 0x0b, 0x75, 0xb4, 0x80, 0x22, 0x8e, 0xcb, 0xed, 0xe9, 0x0c, 0xc2, 0x15, 0xe7, 0x77, 0xa1, 0x8e, 0x16, 0x50, 0xc4, 0x71, 0x39, 0x1f, 0x5a,
0xf9, 0xd0, 0x82, 0x09, 0x0c, 0xb6, 0x37, 0xb1, 0x67, 0xbd, 0x60, 0xf3, 0x09, 0x34, 0x62, 0x8d, 0x30, 0x81, 0xc1, 0xf6, 0x26, 0xf6, 0xac, 0x17, 0x6c, 0x3e, 0x81, 0x46, 0xac, 0x31, 0xba, 0x0a,
0xd1, 0x55, 0x68, 0x0d, 0xae, 0x42, 0x7b, 0x47, 0x57, 0xa1, 0x45, 0x47, 0xa1, 0xc8, 0xa6, 0xab, 0xad, 0xc1, 0x55, 0x68, 0x6f, 0xe9, 0x2a, 0xb4, 0xe8, 0x28, 0x14, 0xd9, 0x74, 0x95, 0xda, 0x11,
0xd4, 0x8e, 0xa0, 0x22, 0xc7, 0x82, 0xd1, 0x9c, 0xe3, 0xde, 0x93, 0x5e, 0xff, 0xab, 0x9e, 0x35, 0x54, 0xe4, 0x58, 0x30, 0x9a, 0x73, 0xdc, 0x7b, 0xd2, 0xeb, 0x7f, 0xd5, 0xb3, 0x06, 0x4f, 0x7b,
0x78, 0xd6, 0xdb, 0x69, 0xde, 0x20, 0x4b, 0x50, 0x6b, 0xef, 0x20, 0x19, 0x43, 0x40, 0x8e, 0xa1, 0x3b, 0xcd, 0x1b, 0x64, 0x09, 0x6a, 0xed, 0x1d, 0x24, 0x63, 0x08, 0xc8, 0x31, 0x94, 0xa3, 0xf6,
0x1c, 0xb5, 0x07, 0x03, 0x05, 0xc9, 0x33, 0x94, 0xa3, 0x6e, 0xaf, 0xd7, 0xd9, 0xe5, 0x80, 0x82, 0x60, 0xa0, 0x20, 0x79, 0x86, 0x72, 0xd4, 0xed, 0xf5, 0x3a, 0xbb, 0x1c, 0x50, 0x30, 0xf6, 0xa0,
0xb1, 0x07, 0xcd, 0x64, 0xdf, 0xd9, 0x2a, 0x0f, 0x25, 0x4c, 0xd8, 0x25, 0x23, 0x40, 0x64, 0xfd, 0x99, 0xec, 0x3b, 0x5b, 0xe5, 0xa1, 0x84, 0x09, 0xbb, 0x64, 0x04, 0x88, 0xac, 0x1f, 0x79, 0xcd,
0xc8, 0x6b, 0xd6, 0x0f, 0xe3, 0x11, 0x34, 0xd9, 0x49, 0xcf, 0x06, 0x5f, 0x77, 0x57, 0x98, 0x30, 0xfa, 0x61, 0x3c, 0x82, 0x26, 0x3b, 0xe9, 0xd9, 0xe0, 0xeb, 0xee, 0x0a, 0x13, 0xc6, 0x8b, 0xeb,
0x5e, 0x5c, 0xb7, 0x4d, 0x56, 0xcc, 0x1a, 0x87, 0x61, 0x55, 0xc6, 0xa7, 0xb0, 0xac, 0x65, 0x8b, 0xb6, 0xc9, 0x8a, 0x59, 0xe3, 0x30, 0xac, 0xca, 0xf8, 0x04, 0x96, 0xb5, 0x6c, 0x91, 0xfe, 0x88,
0xf4, 0x47, 0x8c, 0x7b, 0x48, 0xea, 0x8f, 0x50, 0xf2, 0xe7, 0x29, 0xc6, 0x06, 0xac, 0xb1, 0xcf, 0x71, 0x0f, 0x49, 0xfd, 0x11, 0x4a, 0xfe, 0x3c, 0xc5, 0xd8, 0x80, 0x35, 0xf6, 0xd9, 0xb9, 0xa0,
0xce, 0x05, 0x75, 0xc3, 0xc1, 0xfc, 0x84, 0x7b, 0xb9, 0x38, 0x9e, 0x6b, 0xfc, 0x6a, 0x0e, 0xaa, 0x6e, 0x38, 0x98, 0x9f, 0x70, 0x2f, 0x17, 0xc7, 0x73, 0x8d, 0x5f, 0xcd, 0x41, 0x55, 0xa5, 0x5c,
0x2a, 0xe5, 0xfa, 0x6d, 0xb3, 0x25, 0x54, 0x4d, 0x9c, 0x4e, 0x6e, 0x6a, 0x35, 0x60, 0xc6, 0x2d, 0xbf, 0x6d, 0xb6, 0x84, 0xaa, 0x89, 0xd3, 0xc9, 0x4d, 0xad, 0x06, 0xcc, 0xb8, 0x85, 0x7f, 0x23,
0xfc, 0x1b, 0xa9, 0x9c, 0x8c, 0x2d, 0xa8, 0x2a, 0x10, 0x0e, 0x62, 0xa7, 0x63, 0x5a, 0xfd, 0xde, 0x95, 0x93, 0xb1, 0x05, 0x55, 0x05, 0xc2, 0x41, 0xec, 0x74, 0x4c, 0xab, 0xdf, 0x3b, 0xe8, 0xf6,
0x41, 0xb7, 0xc7, 0x4e, 0x0b, 0x36, 0xce, 0x08, 0xd8, 0xdb, 0x43, 0x48, 0xce, 0x68, 0xc2, 0xe2, 0xd8, 0x69, 0xc1, 0xc6, 0x19, 0x01, 0x7b, 0x7b, 0x08, 0xc9, 0x19, 0x4d, 0x58, 0x7c, 0x4c, 0xc3,
0x63, 0x1a, 0x76, 0xdd, 0x53, 0x4f, 0x0c, 0x86, 0xf1, 0xeb, 0x0b, 0xb0, 0xa4, 0x40, 0x91, 0x62, 0xae, 0x7b, 0xea, 0x89, 0xc1, 0x30, 0x7e, 0x7d, 0x01, 0x96, 0x14, 0x28, 0x52, 0x4c, 0x5d, 0x50,
0xea, 0x82, 0xfa, 0x81, 0xe3, 0xb9, 0xb8, 0x70, 0xaa, 0xa6, 0xfc, 0x64, 0xf4, 0x4e, 0x88, 0x6d, 0x3f, 0x70, 0x3c, 0x17, 0x17, 0x4e, 0xd5, 0x94, 0x9f, 0x8c, 0xde, 0x09, 0xb1, 0x0d, 0xf9, 0x8e,
0xc8, 0x77, 0xac, 0x62, 0xaa, 0x10, 0xf4, 0x90, 0xe9, 0x78, 0x0f, 0x96, 0x9c, 0x31, 0x75, 0x43, 0x55, 0x4c, 0x15, 0x82, 0x1e, 0x32, 0x1d, 0xef, 0xc0, 0x92, 0x33, 0xa6, 0x6e, 0xe8, 0x84, 0x57,
0x27, 0xbc, 0xb2, 0x62, 0x36, 0x85, 0x45, 0x09, 0x16, 0x8c, 0xc7, 0x2a, 0x94, 0xec, 0x89, 0x63, 0x56, 0xcc, 0xa6, 0xb0, 0x28, 0xc1, 0x82, 0xf1, 0x58, 0x85, 0x92, 0x3d, 0x71, 0x6c, 0xe9, 0x3d,
0x4b, 0xef, 0x21, 0xfe, 0xc1, 0xa0, 0x23, 0x6f, 0xe2, 0xf9, 0x28, 0xc8, 0x54, 0x4d, 0xfe, 0x41, 0xc4, 0x3f, 0x18, 0x74, 0xe4, 0x4d, 0x3c, 0x1f, 0x05, 0x99, 0xaa, 0xc9, 0x3f, 0xc8, 0x03, 0x58,
0x1e, 0xc0, 0x2a, 0x13, 0xaa, 0x74, 0x23, 0x18, 0x92, 0x2c, 0x6e, 0xde, 0x20, 0xee, 0x7c, 0x7a, 0x65, 0x42, 0x95, 0x6e, 0x04, 0x43, 0x92, 0xc5, 0xcd, 0x1b, 0xc4, 0x9d, 0x4f, 0x8f, 0x22, 0x43,
0x14, 0x19, 0xc2, 0x58, 0x0a, 0x63, 0x37, 0x58, 0x0e, 0xc1, 0x5f, 0xaa, 0x0c, 0x5c, 0x51, 0xb2, 0x18, 0x4b, 0x61, 0xec, 0x06, 0xcb, 0x21, 0xf8, 0x4b, 0x95, 0x81, 0x2b, 0x4a, 0x96, 0xdd, 0xf9,
0xec, 0xce, 0xa7, 0x6d, 0x4c, 0x51, 0xf8, 0x0f, 0x61, 0x8d, 0xe1, 0x2b, 0x8e, 0x54, 0xe5, 0x58, 0xb4, 0x8d, 0x29, 0x0a, 0xff, 0x21, 0xac, 0x31, 0x7c, 0xc5, 0x91, 0xaa, 0x1c, 0x4b, 0x98, 0x83,
0xc2, 0x1c, 0xac, 0xb0, 0xae, 0x48, 0x53, 0x79, 0x6e, 0x41, 0x95, 0xb7, 0x8a, 0x2d, 0x09, 0x61, 0x15, 0xd6, 0x15, 0x69, 0x2a, 0xcf, 0x2d, 0xa8, 0xf2, 0x56, 0xb1, 0x25, 0x21, 0xac, 0x65, 0xd8,
0x2d, 0xc3, 0xa6, 0x50, 0x3f, 0x48, 0x39, 0xfa, 0x70, 0xcd, 0x40, 0xd2, 0xd1, 0x47, 0x73, 0x15, 0x14, 0xea, 0x07, 0x29, 0x47, 0x1f, 0xae, 0x19, 0x48, 0x3a, 0xfa, 0x68, 0xae, 0x42, 0x95, 0xa4,
0xaa, 0x24, 0x5d, 0x85, 0x1e, 0xc2, 0xda, 0x09, 0x5b, 0xa3, 0xe7, 0xd4, 0x1e, 0x53, 0xdf, 0x8a, 0xab, 0xd0, 0x43, 0x58, 0x3b, 0x61, 0x6b, 0xf4, 0x9c, 0xda, 0x63, 0xea, 0x5b, 0xd1, 0xca, 0xe7,
0x56, 0x3e, 0x97, 0x3f, 0x57, 0x58, 0xe2, 0x3e, 0xa6, 0xa9, 0x8d, 0xc2, 0x58, 0x43, 0x46, 0x89, 0xf2, 0xe7, 0x0a, 0x4b, 0xdc, 0xc7, 0x34, 0xb5, 0x51, 0x18, 0x6b, 0xc8, 0x28, 0x11, 0x1d, 0x5b,
0xe8, 0xd8, 0x0a, 0x3d, 0x0b, 0x39, 0x46, 0xa1, 0xb6, 0x6d, 0x70, 0xf0, 0xd0, 0xdb, 0x61, 0xc0, 0xa1, 0x67, 0x21, 0xc7, 0x28, 0xd4, 0xb6, 0x0d, 0x0e, 0x1e, 0x7a, 0x3b, 0x0c, 0x18, 0xc7, 0x3b,
0x38, 0xde, 0x99, 0x6f, 0xcf, 0xce, 0x85, 0x74, 0xa8, 0xf0, 0x1e, 0x33, 0x20, 0x79, 0x03, 0xca, 0xf3, 0xed, 0xd9, 0xb9, 0x90, 0x0e, 0x15, 0xde, 0x63, 0x06, 0x24, 0xaf, 0x41, 0x99, 0xed, 0x09,
0x6c, 0x4f, 0xb8, 0x94, 0x7b, 0x47, 0x70, 0xb9, 0x4b, 0x82, 0xc8, 0x3b, 0xb0, 0x80, 0x75, 0x04, 0x97, 0x72, 0xef, 0x08, 0x2e, 0x77, 0x49, 0x10, 0x79, 0x0b, 0x16, 0xb0, 0x8e, 0xa0, 0xd5, 0xc4,
0xad, 0x26, 0x6e, 0x88, 0x7a, 0x74, 0x76, 0x38, 0xae, 0x29, 0xd2, 0x18, 0xff, 0x3d, 0xf7, 0x1d, 0x0d, 0x51, 0x8f, 0xce, 0x0e, 0xc7, 0x35, 0x45, 0x1a, 0xe3, 0xbf, 0xe7, 0xbe, 0xc3, 0x09, 0x5b,
0x4e, 0xd8, 0xaa, 0x26, 0xfe, 0x26, 0xdf, 0xd7, 0xa8, 0xe4, 0x0a, 0xe6, 0x7d, 0x47, 0xe4, 0x4d, 0xd5, 0xc4, 0xdf, 0xe4, 0x7b, 0x1a, 0x95, 0x5c, 0xc1, 0xbc, 0x6f, 0x89, 0xbc, 0x89, 0xa5, 0x78,
0x2c, 0xc5, 0xeb, 0x08, 0xe6, 0x37, 0x4a, 0xbe, 0x7e, 0x50, 0xac, 0xd4, 0x9a, 0x75, 0xa3, 0x85, 0x1d, 0xc1, 0xfc, 0x46, 0xc9, 0xd7, 0xf7, 0x8b, 0x95, 0x5a, 0xb3, 0x6e, 0xb4, 0xd0, 0xbf, 0xc9,
0xfe, 0x4d, 0x26, 0x1d, 0x79, 0x17, 0xd4, 0xbf, 0x8a, 0xed, 0x91, 0x1c, 0x6c, 0xa4, 0x92, 0x22, 0xa4, 0x23, 0xef, 0x82, 0xfa, 0x57, 0xb1, 0x3d, 0x92, 0x83, 0x8d, 0x54, 0x52, 0xe4, 0xe9, 0xe0,
0x4f, 0x07, 0x5f, 0xc0, 0xad, 0xa9, 0x37, 0x96, 0x5c, 0x42, 0x5d, 0x02, 0x0f, 0xbd, 0x31, 0xe3, 0x0b, 0xb8, 0x35, 0xf5, 0xc6, 0x92, 0x4b, 0xa8, 0x4b, 0xe0, 0xa1, 0x37, 0x66, 0xdc, 0xcc, 0xb2,
0x66, 0x96, 0x15, 0xd2, 0xa9, 0xe3, 0x3a, 0xc1, 0x39, 0x1d, 0x0b, 0x66, 0xa1, 0x29, 0x13, 0xf6, 0x42, 0x3a, 0x75, 0x5c, 0x27, 0x38, 0xa7, 0x63, 0xc1, 0x2c, 0x34, 0x65, 0xc2, 0x9e, 0x80, 0x33,
0x04, 0x9c, 0xb1, 0xe4, 0x33, 0xdf, 0x3b, 0x53, 0x67, 0x67, 0xce, 0x54, 0xdf, 0xc6, 0x67, 0x50, 0x96, 0x7c, 0xe6, 0x7b, 0x67, 0xea, 0xec, 0xcc, 0x99, 0xea, 0xdb, 0xf8, 0x14, 0x4a, 0x7c, 0x06,
0xe2, 0x33, 0xc8, 0x36, 0x0a, 0xce, 0x6f, 0x4e, 0x6c, 0x14, 0x84, 0xb6, 0xa0, 0xec, 0xd2, 0xf0, 0xd9, 0x46, 0xc1, 0xf9, 0xcd, 0x89, 0x8d, 0x82, 0xd0, 0x16, 0x94, 0x5d, 0x1a, 0x3e, 0xf7, 0xfc,
0x85, 0xe7, 0x3f, 0x97, 0x1a, 0x68, 0xf1, 0x69, 0xfc, 0x18, 0xb5, 0xac, 0xca, 0x51, 0x8d, 0x6b, 0x67, 0x52, 0x03, 0x2d, 0x3e, 0x8d, 0x1f, 0xa1, 0x96, 0x55, 0x39, 0xaa, 0x71, 0x6d, 0x04, 0x5b,
0x23, 0xd8, 0x12, 0xe6, 0x4b, 0x30, 0x38, 0xb7, 0x85, 0xe2, 0xb7, 0x82, 0x80, 0xc1, 0xb9, 0x9d, 0xc2, 0x7c, 0x09, 0x06, 0xe7, 0xb6, 0x50, 0xfc, 0x56, 0x10, 0x30, 0x38, 0xb7, 0x53, 0x4b, 0x38,
0x5a, 0xc2, 0xf9, 0xb4, 0xaf, 0xda, 0x3b, 0xb0, 0x28, 0x5d, 0xe3, 0x02, 0x6b, 0x42, 0x4f, 0x43, 0x9f, 0xf6, 0x55, 0x7b, 0x0b, 0x16, 0xa5, 0x6b, 0x5c, 0x60, 0x4d, 0xe8, 0x69, 0x28, 0xb6, 0x64,
0xb1, 0x25, 0xeb, 0xc2, 0x2f, 0x2e, 0x38, 0xa0, 0xa7, 0xa1, 0x71, 0x08, 0xcb, 0x62, 0xd3, 0xf4, 0x5d, 0xf8, 0xc5, 0x05, 0x07, 0xf4, 0x34, 0x34, 0x0e, 0x61, 0x59, 0x6c, 0x9a, 0xfe, 0x8c, 0xca,
0x67, 0x54, 0x56, 0xfd, 0x79, 0x96, 0x98, 0x54, 0x7b, 0xb8, 0x12, 0xe7, 0x3f, 0x38, 0xa7, 0x17, 0xaa, 0x3f, 0xcb, 0x12, 0x93, 0x6a, 0x0f, 0x57, 0xe2, 0xfc, 0x07, 0xe7, 0xf4, 0x62, 0xb2, 0x93,
0x93, 0x9d, 0x8c, 0x1f, 0x46, 0x2a, 0x45, 0xc6, 0x9d, 0x88, 0xf2, 0x84, 0xb0, 0x22, 0x0d, 0xaa, 0xf1, 0x83, 0x48, 0xa5, 0xc8, 0xb8, 0x13, 0x51, 0x9e, 0x10, 0x56, 0xa4, 0x41, 0x55, 0x3a, 0x6d,
0xd2, 0x69, 0x43, 0x89, 0x44, 0xce, 0x98, 0x8d, 0x4e, 0x30, 0x1f, 0x8d, 0xa4, 0xcb, 0x62, 0xc5, 0x28, 0x91, 0xc8, 0x19, 0xb3, 0xd1, 0x09, 0xe6, 0xa3, 0x91, 0x74, 0x59, 0xac, 0x98, 0xf2, 0xd3,
0x94, 0x9f, 0xc6, 0xff, 0xcc, 0xc1, 0x0a, 0x16, 0x26, 0xc5, 0x3c, 0x71, 0x52, 0xfc, 0xc4, 0x8d, 0xf8, 0xdf, 0x39, 0x58, 0xc1, 0xc2, 0xa4, 0x98, 0x27, 0x4e, 0x8a, 0x1f, 0xbb, 0x91, 0x6c, 0x7e,
0x64, 0xf3, 0xa3, 0xb3, 0x84, 0xfc, 0xe3, 0xd5, 0x16, 0xa1, 0xa4, 0xb5, 0xa7, 0x98, 0x69, 0xed, 0x74, 0x96, 0x90, 0x7f, 0xbc, 0xdc, 0x22, 0x94, 0xb4, 0xf6, 0x14, 0x33, 0xad, 0x3d, 0xdf, 0x86,
0xf9, 0x36, 0x34, 0xc7, 0x74, 0xe2, 0xe0, 0x72, 0x92, 0x5c, 0x16, 0x67, 0x6b, 0x97, 0x24, 0x5c, 0xe6, 0x98, 0x4e, 0x1c, 0x5c, 0x4e, 0x92, 0xcb, 0xe2, 0x6c, 0xed, 0x92, 0x84, 0x4b, 0xd5, 0x43,
0xaa, 0x1e, 0x52, 0x26, 0xa6, 0x85, 0xb4, 0xf9, 0xf1, 0xaf, 0xe6, 0x60, 0x99, 0x33, 0x7a, 0xa8, 0xca, 0xc4, 0xb4, 0x90, 0x36, 0x3f, 0xfe, 0x8d, 0x1c, 0x2c, 0x73, 0x46, 0x0f, 0x15, 0x3e, 0x62,
0xf0, 0x11, 0x03, 0xfa, 0xa5, 0xd4, 0x6c, 0x08, 0xb2, 0x2b, 0xfa, 0x1e, 0x31, 0x40, 0x08, 0xe5, 0x40, 0xbf, 0x90, 0x9a, 0x0d, 0x41, 0x76, 0x45, 0xdf, 0x23, 0x06, 0x08, 0xa1, 0x1c, 0x79, 0xff,
0xc8, 0xfb, 0x37, 0x84, 0xc6, 0x43, 0x40, 0xc9, 0x77, 0x51, 0x84, 0x75, 0x2d, 0x04, 0x0a, 0x06, 0x86, 0xd0, 0x78, 0x08, 0x28, 0xf9, 0x0e, 0x8a, 0xb0, 0xae, 0x85, 0x40, 0xc1, 0xc0, 0xdf, 0xcc,
0xfe, 0x66, 0x06, 0x6b, 0xa9, 0xb2, 0x33, 0xf9, 0xd6, 0x45, 0xd0, 0x76, 0x05, 0x16, 0xb8, 0xfa, 0x60, 0x2d, 0x55, 0x76, 0x26, 0xdf, 0xba, 0x08, 0xda, 0xae, 0xc0, 0x02, 0x57, 0x9f, 0x19, 0x7b,
0xcc, 0xd8, 0x83, 0x46, 0xac, 0x9a, 0x98, 0x59, 0xa9, 0xce, 0xcd, 0x4a, 0x29, 0x9b, 0x77, 0x3e, 0xd0, 0x88, 0x55, 0x13, 0x33, 0x2b, 0xd5, 0xb9, 0x59, 0x29, 0x65, 0xf3, 0xce, 0xa7, 0x6d, 0xde,
0x6d, 0xf3, 0xbe, 0x82, 0x15, 0x93, 0xda, 0xe3, 0xab, 0x3d, 0xcf, 0x3f, 0x0a, 0x4e, 0xc2, 0x3d, 0x57, 0xb0, 0x62, 0x52, 0x7b, 0x7c, 0xb5, 0xe7, 0xf9, 0x47, 0xc1, 0x49, 0xb8, 0xc7, 0xb9, 0x67,
0xce, 0x3d, 0xb3, 0xb3, 0x4a, 0x79, 0xb9, 0xc4, 0xec, 0x30, 0xd2, 0x9e, 0x2f, 0x07, 0xf1, 0x5b, 0x76, 0x56, 0x29, 0x2f, 0x97, 0x98, 0x1d, 0x46, 0xda, 0xf3, 0xe5, 0x20, 0x7e, 0x0b, 0x16, 0x23,
0xb0, 0x18, 0xb9, 0xc3, 0x68, 0x1a, 0xfb, 0x86, 0xf2, 0x88, 0x41, 0xa6, 0x8b, 0x40, 0x71, 0x16, 0x77, 0x18, 0x4d, 0x63, 0xdf, 0x50, 0x1e, 0x31, 0xc8, 0x74, 0x11, 0x28, 0xce, 0x82, 0x93, 0x50,
0x9c, 0x84, 0x42, 0x67, 0x8f, 0xbf, 0x8d, 0x7f, 0x54, 0x02, 0xc2, 0x56, 0x7d, 0x62, 0x61, 0xa5, 0xe8, 0xec, 0xf1, 0xb7, 0xf1, 0x4f, 0x4b, 0x40, 0xd8, 0xaa, 0x4f, 0x2c, 0xac, 0xd4, 0xb4, 0xe4,
0xa6, 0x25, 0x97, 0xb6, 0xfc, 0x25, 0x9c, 0x7d, 0xf2, 0x29, 0x67, 0x9f, 0x07, 0x40, 0x34, 0x04, 0xd2, 0x96, 0xbf, 0x84, 0xb3, 0x4f, 0x3e, 0xe5, 0xec, 0xf3, 0x00, 0x88, 0x86, 0x20, 0x7d, 0x90,
0xe9, 0x83, 0x54, 0x50, 0x3e, 0x48, 0xcd, 0x08, 0x57, 0xb8, 0x20, 0x3d, 0x80, 0x55, 0x21, 0xae, 0x0a, 0xca, 0x07, 0xa9, 0x19, 0xe1, 0x0a, 0x17, 0xa4, 0x07, 0xb0, 0x2a, 0xc4, 0x95, 0x78, 0x77,
0xc4, 0xbb, 0x83, 0xcb, 0xcc, 0x24, 0x5c, 0x6e, 0x89, 0xf5, 0x49, 0x3a, 0xfa, 0x48, 0x35, 0x78, 0x70, 0x99, 0x99, 0x84, 0xcb, 0x2d, 0xb1, 0x3e, 0x49, 0x47, 0x1f, 0xa9, 0x06, 0x2f, 0x70, 0x47,
0x81, 0x3b, 0xfa, 0x48, 0x6d, 0x95, 0xb6, 0x98, 0x17, 0x5e, 0xb9, 0x98, 0xcb, 0x99, 0x8b, 0x59, 0x1f, 0xa9, 0xad, 0xd2, 0x16, 0xf3, 0xc2, 0x4b, 0x17, 0x73, 0x39, 0x73, 0x31, 0x6b, 0xda, 0xcb,
0xd3, 0x5e, 0x56, 0xe2, 0xda, 0xcb, 0x94, 0x1e, 0x9e, 0xf3, 0xe7, 0x31, 0x3d, 0xfc, 0x3d, 0x68, 0x4a, 0x5c, 0x7b, 0x99, 0xd2, 0xc3, 0x73, 0xfe, 0x3c, 0xa6, 0x87, 0xbf, 0x07, 0x4d, 0xa9, 0xc9,
0x4a, 0x4d, 0x96, 0xd2, 0x91, 0x0a, 0x0f, 0x10, 0xa1, 0xac, 0x92, 0x5a, 0xd2, 0x98, 0xa1, 0xb1, 0x52, 0x3a, 0x52, 0xe1, 0x01, 0x22, 0x94, 0x55, 0x52, 0x4b, 0x1a, 0x33, 0x34, 0xd6, 0x5e, 0xc5,
0xf6, 0x3a, 0x16, 0xcf, 0x7a, 0xb6, 0xc5, 0x33, 0xad, 0xf3, 0x6b, 0x64, 0xe8, 0xfc, 0x1e, 0x45, 0xe2, 0x59, 0xcf, 0xb6, 0x78, 0xa6, 0x75, 0x7e, 0x8d, 0x0c, 0x9d, 0xdf, 0xa3, 0xc8, 0xc1, 0x23,
0x0e, 0x1e, 0xc1, 0xb9, 0x33, 0x45, 0x46, 0x2a, 0xf2, 0x50, 0x15, 0x83, 0x3c, 0x38, 0x77, 0xa6, 0x38, 0x77, 0xa6, 0xc8, 0x48, 0x45, 0x1e, 0xaa, 0x62, 0x90, 0x07, 0xe7, 0xce, 0xd4, 0x94, 0xae,
0xa6, 0x74, 0xb5, 0x62, 0x1f, 0x64, 0x07, 0xee, 0x88, 0xfe, 0x64, 0x78, 0x49, 0xf1, 0x51, 0x58, 0x56, 0xec, 0x83, 0xec, 0xc0, 0x1d, 0xd1, 0x9f, 0x0c, 0x2f, 0x29, 0x3e, 0x0a, 0x4b, 0xb8, 0x54,
0xc2, 0xa5, 0xb2, 0xc9, 0xd1, 0x0e, 0x13, 0x0e, 0x53, 0x89, 0x41, 0x91, 0x3e, 0x36, 0x01, 0x57, 0x36, 0x39, 0xda, 0x61, 0xc2, 0x61, 0x2a, 0x31, 0x28, 0xd2, 0xc7, 0x26, 0xe0, 0x8a, 0x63, 0x39,
0x1c, 0xcb, 0x41, 0x39, 0xe4, 0x4e, 0x36, 0x48, 0x1e, 0x18, 0x8a, 0x50, 0x2a, 0x06, 0x17, 0xc8, 0x28, 0x87, 0xdc, 0xc9, 0x06, 0xc9, 0x03, 0x43, 0x11, 0x4a, 0xc5, 0xe0, 0x02, 0xf9, 0xae, 0x86,
0x77, 0x35, 0xcc, 0xda, 0xd4, 0xbe, 0x3c, 0x40, 0xa5, 0x61, 0x70, 0x61, 0xfc, 0x69, 0x0e, 0x9a, 0x59, 0x9b, 0xda, 0x97, 0x07, 0xa8, 0x34, 0x0c, 0x2e, 0x8c, 0x3f, 0xcd, 0x41, 0x93, 0x2d, 0xe1,
0x6c, 0x09, 0xc7, 0xa8, 0xc3, 0x17, 0x80, 0xf4, 0xee, 0x35, 0x89, 0x43, 0x8d, 0xe1, 0x4a, 0xda, 0x18, 0x75, 0xf8, 0x1c, 0x90, 0xde, 0xbd, 0x22, 0x71, 0xa8, 0x31, 0x5c, 0x49, 0x1b, 0x3e, 0x05,
0xf0, 0x19, 0xe0, 0x66, 0xb7, 0xbc, 0x19, 0x75, 0x05, 0x69, 0x68, 0xc5, 0x49, 0x43, 0x74, 0x4c, 0xdc, 0xec, 0x96, 0x37, 0xa3, 0xae, 0x20, 0x0d, 0xad, 0x38, 0x69, 0x88, 0x8e, 0x89, 0xfd, 0x1b,
0xec, 0xdf, 0xe0, 0x52, 0x27, 0x83, 0x90, 0x2f, 0xa0, 0xca, 0xf6, 0x14, 0x2e, 0x5e, 0xe1, 0x1d, 0x5c, 0xea, 0x64, 0x10, 0xf2, 0x39, 0x54, 0xd9, 0x9e, 0xc2, 0xc5, 0x2b, 0xbc, 0xc3, 0x37, 0x95,
0xbe, 0xa9, 0x34, 0x09, 0xa9, 0xed, 0xcd, 0xb2, 0xce, 0xc4, 0x67, 0x96, 0x0b, 0x55, 0x31, 0xc3, 0x26, 0x21, 0xb5, 0xbd, 0x59, 0xd6, 0x99, 0xf8, 0xcc, 0x72, 0xa1, 0x2a, 0x66, 0xb8, 0x50, 0x69,
0x85, 0x4a, 0xa3, 0x3d, 0xfb, 0x00, 0x4f, 0xe8, 0x15, 0x1b, 0x84, 0xd0, 0xf3, 0x19, 0xaf, 0xc6, 0xb4, 0x67, 0x1f, 0xe0, 0x09, 0xbd, 0x62, 0x83, 0x10, 0x7a, 0x3e, 0xe3, 0xd5, 0xd8, 0x16, 0x3b,
0xb6, 0xd8, 0xa9, 0x3d, 0x75, 0x84, 0x36, 0xb3, 0x64, 0x56, 0x9f, 0xd3, 0xab, 0x3d, 0x04, 0xb0, 0xb5, 0xa7, 0x8e, 0xd0, 0x66, 0x96, 0xcc, 0xea, 0x33, 0x7a, 0xb5, 0x87, 0x00, 0xb6, 0xb6, 0x58,
0xb5, 0xc5, 0x92, 0x23, 0x02, 0x54, 0x32, 0x2b, 0xcf, 0xe9, 0x15, 0xa7, 0x3e, 0x16, 0x34, 0x9e, 0x72, 0x44, 0x80, 0x4a, 0x66, 0xe5, 0x19, 0xbd, 0xe2, 0xd4, 0xc7, 0x82, 0xc6, 0x13, 0x7a, 0xb5,
0xd0, 0xab, 0x5d, 0xca, 0x85, 0x01, 0xcf, 0x67, 0x83, 0xee, 0xdb, 0x2f, 0x18, 0xf7, 0x1f, 0x73, 0x4b, 0xb9, 0x30, 0xe0, 0xf9, 0x6c, 0xd0, 0x7d, 0xfb, 0x39, 0xe3, 0xfe, 0x63, 0x2e, 0x3e, 0x35,
0xf1, 0xa9, 0xf9, 0xf6, 0x8b, 0x27, 0xf4, 0x4a, 0xba, 0x1b, 0x95, 0x59, 0xfa, 0xc4, 0x1b, 0x09, 0xdf, 0x7e, 0xfe, 0x84, 0x5e, 0x49, 0x77, 0xa3, 0x32, 0x4b, 0x9f, 0x78, 0x23, 0xc1, 0xbe, 0x48,
0xf6, 0x45, 0x2a, 0x90, 0xa2, 0x46, 0x99, 0x0b, 0xcf, 0xf1, 0xb7, 0xf1, 0x27, 0x39, 0x68, 0xb0, 0x05, 0x52, 0xd4, 0x28, 0x73, 0xe1, 0x19, 0xfe, 0x36, 0xfe, 0x24, 0x07, 0x0d, 0xd6, 0x7e, 0x3c,
0xf6, 0xe3, 0xc9, 0x83, 0xab, 0x48, 0xf8, 0x0c, 0xe7, 0x22, 0x9f, 0xe1, 0x87, 0x82, 0x20, 0xf3, 0x79, 0x70, 0x15, 0x09, 0x9f, 0xe1, 0x5c, 0xe4, 0x33, 0xfc, 0x50, 0x10, 0x64, 0x7e, 0x8c, 0xe5,
0x63, 0x2c, 0x7f, 0xfd, 0x31, 0x86, 0x73, 0xc3, 0xcf, 0xb0, 0x8f, 0xa0, 0xca, 0x17, 0x06, 0x23, 0xaf, 0x3f, 0xc6, 0x70, 0x6e, 0xf8, 0x19, 0xf6, 0x21, 0x54, 0xf9, 0xc2, 0x60, 0xe4, 0xa7, 0x10,
0x3f, 0x85, 0xd8, 0x04, 0xc7, 0x3a, 0x64, 0x56, 0x10, 0xed, 0x09, 0xf7, 0x3f, 0xd4, 0x74, 0xf5, 0x9b, 0xe0, 0x58, 0x87, 0xcc, 0x0a, 0xa2, 0x3d, 0xe1, 0xfe, 0x87, 0x9a, 0xae, 0x9e, 0x0f, 0x71,
0x7c, 0x88, 0xab, 0xbe, 0xd2, 0xd0, 0x67, 0x4c, 0x43, 0xe9, 0x1a, 0xff, 0x43, 0x5d, 0x11, 0xbe, 0xd5, 0x57, 0x1a, 0xfa, 0x8c, 0x69, 0x28, 0x5d, 0xe3, 0x7f, 0xa8, 0x2b, 0xc2, 0x17, 0x92, 0x8a,
0x90, 0x54, 0x84, 0x1b, 0x2e, 0x54, 0xd8, 0x54, 0x63, 0x67, 0x33, 0x0a, 0xcd, 0x65, 0x15, 0xca, 0x70, 0xc3, 0x85, 0x0a, 0x9b, 0x6a, 0xec, 0x6c, 0x46, 0xa1, 0xb9, 0xac, 0x42, 0x19, 0xb3, 0x63,
0x98, 0x1d, 0x9b, 0x9d, 0x67, 0x8c, 0x46, 0xe7, 0x05, 0xb3, 0x63, 0x07, 0x94, 0x15, 0xc4, 0x1a, 0xb3, 0xf3, 0x8c, 0xd1, 0xe8, 0xbc, 0x60, 0x76, 0xec, 0x80, 0xb2, 0x82, 0x58, 0xc3, 0x5d, 0xcf,
0xee, 0x7a, 0x16, 0x6a, 0x96, 0x85, 0xce, 0xb5, 0x62, 0x56, 0x5d, 0xef, 0x88, 0x03, 0x8c, 0xbf, 0x42, 0xcd, 0xb2, 0xd0, 0xb9, 0x56, 0xcc, 0xaa, 0xeb, 0x1d, 0x71, 0x80, 0xf1, 0x97, 0x72, 0x50,
0x90, 0x83, 0x9a, 0xb6, 0x67, 0xd1, 0xd4, 0xa0, 0x86, 0x93, 0x6f, 0xf0, 0xf8, 0x0e, 0x88, 0xcd, 0xd3, 0xf6, 0x2c, 0x9a, 0x1a, 0xd4, 0x70, 0xf2, 0x0d, 0x1e, 0xdf, 0x01, 0xb1, 0xf9, 0xd8, 0xbf,
0xc7, 0xfe, 0x0d, 0xb3, 0x31, 0x8a, 0x4d, 0xd0, 0x96, 0x58, 0xca, 0x98, 0x33, 0x1f, 0xd3, 0x6f, 0x61, 0x36, 0x46, 0xb1, 0x09, 0xda, 0x12, 0x4b, 0x19, 0x73, 0xe6, 0x63, 0xfa, 0x2d, 0xd9, 0x2f,
0xc9, 0x7e, 0xc9, 0xf5, 0xcb, 0x7e, 0x6f, 0x2f, 0x40, 0x91, 0xa1, 0x1a, 0x5f, 0xc2, 0xb2, 0xd6, 0xb9, 0x7e, 0xd9, 0xef, 0xed, 0x05, 0x28, 0x32, 0x54, 0xe3, 0x0b, 0x58, 0xd6, 0x9a, 0xc1, 0xf5,
0x0c, 0xae, 0xff, 0x79, 0xdd, 0x01, 0x30, 0x7e, 0x41, 0x65, 0x66, 0x75, 0x70, 0xdb, 0xbd, 0x74, 0x3f, 0xaf, 0x3a, 0x00, 0xc6, 0x2f, 0xa8, 0xcc, 0xac, 0x0e, 0x6e, 0xbb, 0x97, 0xae, 0x9e, 0x74,
0xf5, 0xa4, 0x63, 0x3e, 0x2e, 0xc2, 0xa5, 0x94, 0x83, 0x70, 0x64, 0x5e, 0xd3, 0xfb, 0xd0, 0xf8, 0xcc, 0xc7, 0x45, 0xb8, 0x94, 0x72, 0x10, 0x8e, 0xcc, 0x2b, 0x7a, 0x1f, 0x1a, 0xbf, 0x92, 0x83,
0x95, 0x1c, 0xac, 0x68, 0xc5, 0xef, 0x39, 0xae, 0x3d, 0x71, 0x7e, 0x8c, 0xc7, 0x58, 0xe0, 0x9c, 0x15, 0xad, 0xf8, 0x3d, 0xc7, 0xb5, 0x27, 0xce, 0x8f, 0xf0, 0x18, 0x0b, 0x9c, 0x33, 0x37, 0x51,
0xb9, 0x89, 0x0a, 0x38, 0xe8, 0xeb, 0x54, 0x40, 0xee, 0x42, 0x9d, 0xfb, 0x96, 0xf3, 0x9b, 0x0b, 0x01, 0x07, 0x7d, 0x9d, 0x0a, 0xc8, 0x5d, 0xa8, 0x73, 0xdf, 0x72, 0x7e, 0x73, 0x41, 0x1c, 0xb3,
0xe2, 0x98, 0x05, 0x84, 0x99, 0xf6, 0x8b, 0xe1, 0xa5, 0xf1, 0xd7, 0xf2, 0xb0, 0x2a, 0x9a, 0x80, 0x80, 0x30, 0xd3, 0x7e, 0x3e, 0xbc, 0x34, 0xfe, 0x66, 0x1e, 0x56, 0x45, 0x13, 0xf0, 0x0a, 0x80,
0x57, 0x00, 0x1c, 0xc6, 0xea, 0x1e, 0x06, 0x67, 0xe4, 0x0b, 0x68, 0xb0, 0xe1, 0xb3, 0x7c, 0x7a, 0xc3, 0x58, 0xdd, 0xc3, 0xe0, 0x8c, 0x7c, 0x0e, 0x0d, 0x36, 0x7c, 0x96, 0x4f, 0xcf, 0x9c, 0x20,
0xe6, 0x04, 0x21, 0x95, 0x6e, 0x05, 0x19, 0xd4, 0x98, 0x71, 0x32, 0x0c, 0xd5, 0x14, 0x98, 0xe4, 0xa4, 0xd2, 0xad, 0x20, 0x83, 0x1a, 0x33, 0x4e, 0x86, 0xa1, 0x9a, 0x02, 0x93, 0x7c, 0x01, 0x35,
0x4b, 0xa8, 0x61, 0x56, 0xae, 0x82, 0x13, 0x73, 0xd5, 0x4a, 0x67, 0xe4, 0x73, 0xb1, 0x7f, 0xc3, 0xcc, 0xca, 0x55, 0x70, 0x62, 0xae, 0x5a, 0xe9, 0x8c, 0x7c, 0x2e, 0xf6, 0x6f, 0x98, 0x10, 0x44,
0x84, 0x20, 0x9a, 0x99, 0x2f, 0xa1, 0x86, 0xd3, 0x7c, 0x81, 0x63, 0x9d, 0x20, 0x76, 0xa9, 0xb9, 0x33, 0xf3, 0x05, 0xd4, 0x70, 0x9a, 0x2f, 0x70, 0xac, 0x13, 0xc4, 0x2e, 0x35, 0x17, 0x2c, 0xf3,
0x60, 0x99, 0x67, 0xd1, 0xcc, 0xb4, 0xa1, 0xc1, 0xc9, 0x9d, 0x18, 0x49, 0xe1, 0x37, 0xbc, 0x99, 0x2c, 0x9a, 0x99, 0x36, 0x34, 0x38, 0xb9, 0x13, 0x23, 0x29, 0xfc, 0x86, 0x37, 0xd3, 0xd9, 0xe5,
0xce, 0x2e, 0xc7, 0x9a, 0x35, 0x7e, 0xa6, 0x7d, 0x6f, 0x57, 0xa1, 0x1c, 0xfa, 0xce, 0xd9, 0x19, 0x58, 0xb3, 0xc6, 0xcf, 0xb4, 0xef, 0xed, 0x2a, 0x94, 0x43, 0xdf, 0x39, 0x3b, 0xa3, 0xbe, 0xb1,
0xf5, 0x8d, 0x75, 0x35, 0x34, 0x8c, 0x8e, 0xd3, 0x41, 0x48, 0x67, 0x4c, 0x86, 0x31, 0xfe, 0x59, 0xae, 0x86, 0x86, 0xd1, 0x71, 0x3a, 0x08, 0xe9, 0x8c, 0xc9, 0x30, 0xc6, 0xbf, 0xcc, 0x41, 0x4d,
0x0e, 0x6a, 0x82, 0x32, 0xff, 0xc4, 0x1e, 0x0b, 0x9b, 0x09, 0x65, 0x6d, 0x55, 0xd3, 0xcd, 0xbe, 0x50, 0xe6, 0x1f, 0xdb, 0x63, 0x61, 0x33, 0xa1, 0xac, 0xad, 0x6a, 0xba, 0xd9, 0x77, 0x60, 0x69,
0x07, 0x4b, 0x53, 0x26, 0x70, 0x39, 0xe1, 0x55, 0xdc, 0x5d, 0x61, 0x51, 0x82, 0x85, 0x2c, 0xb1, 0xca, 0x04, 0x2e, 0x27, 0xbc, 0x8a, 0xbb, 0x2b, 0x2c, 0x4a, 0xb0, 0x90, 0x25, 0xb6, 0x60, 0x05,
0x05, 0x2b, 0x28, 0x5a, 0x04, 0x56, 0xe8, 0x4c, 0x2c, 0x99, 0x28, 0x6e, 0xc8, 0x2c, 0xf3, 0xa4, 0x45, 0x8b, 0xc0, 0x0a, 0x9d, 0x89, 0x25, 0x13, 0xc5, 0x0d, 0x99, 0x65, 0x9e, 0x34, 0x74, 0x26,
0xa1, 0x33, 0x39, 0x14, 0x09, 0x8c, 0xc3, 0x0e, 0x42, 0xfb, 0x8c, 0x0a, 0xea, 0xc0, 0x3f, 0x98, 0x87, 0x22, 0x81, 0x71, 0xd8, 0x41, 0x68, 0x9f, 0x51, 0x41, 0x1d, 0xf8, 0x07, 0x13, 0xe2, 0x12,
0x10, 0x97, 0xd0, 0x05, 0x48, 0x21, 0xee, 0x7f, 0x2f, 0xc3, 0x46, 0x2a, 0x49, 0x08, 0x71, 0xca, 0xba, 0x00, 0x29, 0xc4, 0xfd, 0xdf, 0x65, 0xd8, 0x48, 0x25, 0x09, 0x21, 0x4e, 0x59, 0x87, 0x27,
0x3a, 0x3c, 0x71, 0xa6, 0x27, 0x9e, 0xb2, 0x4e, 0xe4, 0x34, 0xeb, 0xf0, 0x01, 0x4b, 0x91, 0xd6, 0xce, 0xf4, 0xc4, 0x53, 0xd6, 0x89, 0x9c, 0x66, 0x1d, 0x3e, 0x60, 0x29, 0xd2, 0x3a, 0x41, 0x61,
0x09, 0x0a, 0x6b, 0x72, 0xc9, 0xa2, 0x79, 0x41, 0xa9, 0x0b, 0xf2, 0x28, 0xcc, 0x7e, 0x14, 0x3f, 0x4d, 0x2e, 0x59, 0x34, 0x2f, 0x28, 0x75, 0x41, 0x1e, 0x85, 0xd9, 0x0f, 0xe3, 0xc7, 0x60, 0xb2,
0x06, 0x93, 0xd5, 0x49, 0xb8, 0xce, 0x17, 0xae, 0xcc, 0x52, 0xb0, 0x80, 0xfc, 0xff, 0xd0, 0x52, 0x3a, 0x09, 0xd7, 0xf9, 0xc2, 0x95, 0x59, 0x0a, 0x16, 0x90, 0x3f, 0x0f, 0x2d, 0xb5, 0x33, 0x84,
0x3b, 0x43, 0xc8, 0x36, 0x9a, 0xee, 0x83, 0xd5, 0xf4, 0x9d, 0x57, 0xd4, 0x14, 0xd3, 0xfb, 0x22, 0x6c, 0xa3, 0xe9, 0x3e, 0x58, 0x4d, 0xef, 0xbd, 0xa4, 0xa6, 0x98, 0xde, 0x17, 0x59, 0xaf, 0x75,
0xeb, 0xb5, 0x2e, 0x37, 0x15, 0x2f, 0x50, 0xd5, 0x75, 0x01, 0x6f, 0xca, 0xba, 0x50, 0x56, 0x49, 0xb9, 0xa9, 0x78, 0x81, 0xaa, 0xae, 0x0b, 0x78, 0x5d, 0xd6, 0x85, 0xb2, 0x4a, 0xba, 0xc6, 0xe2,
0xd7, 0x58, 0x7c, 0xad, 0xbe, 0xa1, 0x4e, 0x3b, 0x56, 0xad, 0x79, 0x4b, 0x14, 0xac, 0x92, 0xf4, 0x2b, 0xf5, 0x0d, 0x75, 0xda, 0xb1, 0x6a, 0xcd, 0x5b, 0xa2, 0x60, 0x95, 0xa4, 0xd7, 0x7b, 0x0e,
0x7a, 0xcf, 0x61, 0xfd, 0x85, 0xed, 0x84, 0xb2, 0x8f, 0x9a, 0xea, 0xa5, 0x84, 0xf5, 0x3d, 0x7c, 0xeb, 0xcf, 0x6d, 0x27, 0x94, 0x7d, 0xd4, 0x54, 0x2f, 0x25, 0xac, 0xef, 0xe1, 0x4b, 0xea, 0xfb,
0x45, 0x7d, 0x5f, 0xf1, 0xcc, 0x31, 0xe9, 0x6d, 0xf5, 0x45, 0x1a, 0x18, 0x6c, 0xfe, 0xed, 0x02, 0x8a, 0x67, 0x8e, 0x49, 0x6f, 0xab, 0xcf, 0xd3, 0xc0, 0x60, 0xf3, 0xef, 0x15, 0x60, 0x31, 0x5e,
0x2c, 0xc6, 0x4b, 0x61, 0xa4, 0x47, 0x1c, 0x57, 0x92, 0x91, 0x16, 0x12, 0x80, 0xb0, 0x9c, 0xf5, 0x0a, 0x23, 0x3d, 0xe2, 0xb8, 0x92, 0x8c, 0xb4, 0x90, 0x00, 0x84, 0xe5, 0xac, 0xc7, 0x19, 0xe8,
0x38, 0x03, 0x9d, 0xb6, 0xe9, 0xe5, 0x33, 0x6c, 0x7a, 0xba, 0x29, 0xad, 0xf0, 0x2a, 0xcf, 0x8a, 0xb4, 0x4d, 0x2f, 0x9f, 0x61, 0xd3, 0xd3, 0x4d, 0x69, 0x85, 0x97, 0x79, 0x56, 0x14, 0x5f, 0xc9,
0xe2, 0x6b, 0x79, 0x56, 0x94, 0xb2, 0x3c, 0x2b, 0x3e, 0xbe, 0xd6, 0x14, 0xcf, 0x15, 0xe2, 0x99, 0xb3, 0xa2, 0x94, 0xe5, 0x59, 0xf1, 0xd1, 0xb5, 0xa6, 0x78, 0xae, 0x10, 0xcf, 0x34, 0xc3, 0x3f,
0x66, 0xf8, 0x47, 0xd7, 0x9b, 0xe1, 0xb9, 0xae, 0xfc, 0x3a, 0x13, 0xbc, 0xe6, 0x40, 0x50, 0xb9, 0xba, 0xde, 0x0c, 0xcf, 0x75, 0xe5, 0xd7, 0x99, 0xe0, 0x35, 0x07, 0x82, 0xca, 0x35, 0x06, 0x30,
0xc6, 0x00, 0xa6, 0xb9, 0x14, 0x64, 0x98, 0xe0, 0xab, 0x5f, 0xc3, 0x04, 0xbf, 0xf9, 0x27, 0x39, 0xcd, 0xa5, 0x20, 0xc3, 0x04, 0x5f, 0xfd, 0x1a, 0x26, 0xf8, 0xcd, 0x3f, 0xc9, 0x01, 0x49, 0xef,
0x20, 0xe9, 0xdd, 0x41, 0x1e, 0x73, 0x73, 0xa9, 0x4b, 0x27, 0x82, 0x72, 0x7f, 0xf0, 0x7a, 0x3b, 0x0e, 0xf2, 0x98, 0x9b, 0x4b, 0x5d, 0x3a, 0x11, 0x94, 0xfb, 0xfd, 0x57, 0xdb, 0x61, 0x72, 0x41,
0x4c, 0x2e, 0x08, 0x99, 0x9b, 0x7c, 0x08, 0x2b, 0xfa, 0x3d, 0x3e, 0x5d, 0xb5, 0xd1, 0x30, 0x89, 0xc8, 0xdc, 0xe4, 0x03, 0x58, 0xd1, 0xef, 0xf1, 0xe9, 0xaa, 0x8d, 0x86, 0x49, 0xf4, 0xa4, 0x48,
0x9e, 0x14, 0x29, 0xe9, 0x34, 0x37, 0x96, 0xe2, 0x2b, 0xdd, 0x58, 0x4a, 0xaf, 0x74, 0x63, 0x59, 0x49, 0xa7, 0xb9, 0xb1, 0x14, 0x5f, 0xea, 0xc6, 0x52, 0x7a, 0xa9, 0x1b, 0xcb, 0x42, 0xdc, 0x8d,
0x88, 0xbb, 0xb1, 0x6c, 0xfe, 0xcb, 0x1c, 0xac, 0x64, 0x2c, 0xe2, 0x6f, 0xae, 0xcf, 0x6c, 0xed, 0x65, 0xf3, 0xdf, 0xe4, 0x60, 0x25, 0x63, 0x11, 0x7f, 0x73, 0x7d, 0x66, 0x6b, 0x2f, 0x46, 0xd6,
0xc5, 0xc8, 0x5a, 0x5e, 0xac, 0x3d, 0x9d, 0xa2, 0x1d, 0x48, 0xc5, 0x2e, 0x9b, 0x8a, 0x40, 0x9c, 0xf2, 0x62, 0xed, 0xe9, 0x14, 0xed, 0x40, 0x2a, 0x76, 0xd9, 0x54, 0x04, 0xe2, 0xa4, 0xba, 0xff,
0x54, 0xf7, 0x5f, 0x45, 0x5d, 0xa2, 0x1c, 0xa6, 0x9e, 0x7d, 0xf3, 0xef, 0xe4, 0xa1, 0xa6, 0x25, 0x32, 0xea, 0x12, 0xe5, 0x30, 0xf5, 0xec, 0x9b, 0x7f, 0x3f, 0x0f, 0x35, 0x2d, 0x91, 0x8d, 0x22,
0xb2, 0x51, 0xe4, 0x4b, 0x56, 0x73, 0x0a, 0xe5, 0xbc, 0x25, 0x2a, 0x66, 0xf0, 0x6a, 0x01, 0x2e, 0x5f, 0xb2, 0x9a, 0x53, 0x28, 0xe7, 0x2d, 0x51, 0x31, 0x83, 0x57, 0x0b, 0x70, 0x71, 0x62, 0x3a,
0x4e, 0x4c, 0xe7, 0x9b, 0x4b, 0x30, 0x92, 0x88, 0xb0, 0x05, 0x2b, 0xd2, 0x94, 0x4d, 0x23, 0xa7, 0xdf, 0x5c, 0x82, 0x91, 0x44, 0x84, 0x2d, 0x58, 0x91, 0xa6, 0x6c, 0x1a, 0x39, 0xcd, 0x8b, 0xb3,
0x79, 0x71, 0xd6, 0x08, 0xaf, 0x04, 0xd1, 0x48, 0xc4, 0xff, 0x50, 0xca, 0xb9, 0xd1, 0xdc, 0x69, 0x46, 0x78, 0x25, 0x88, 0x46, 0x22, 0xfe, 0x07, 0x52, 0xce, 0x8d, 0xe6, 0x4e, 0x33, 0x0d, 0x2e,
0xa6, 0xc1, 0x65, 0xe1, 0x0f, 0x21, 0x26, 0x91, 0xad, 0xf3, 0x8f, 0x60, 0x4d, 0x39, 0x44, 0xc4, 0x0b, 0x7f, 0x08, 0x31, 0x89, 0x6c, 0x9d, 0x7f, 0x08, 0x6b, 0xca, 0x21, 0x22, 0x96, 0x83, 0x1b,
0x72, 0x70, 0x03, 0x14, 0x91, 0x8e, 0x0f, 0x5a, 0x96, 0xef, 0xc3, 0xed, 0x44, 0x9b, 0x12, 0x59, 0xa0, 0x88, 0x74, 0x7c, 0xd0, 0xb2, 0x7c, 0x0f, 0x6e, 0x27, 0xda, 0x94, 0xc8, 0xca, 0x35, 0x2d,
0xb9, 0xa6, 0xe5, 0x66, 0xac, 0x75, 0x7a, 0x09, 0x9b, 0x7f, 0x0e, 0x1a, 0x31, 0x42, 0xf9, 0xcd, 0x37, 0x63, 0xad, 0xd3, 0x4b, 0xd8, 0xfc, 0x0b, 0xd0, 0x88, 0x11, 0xca, 0x6f, 0x6e, 0xca, 0x93,
0x4d, 0x79, 0x52, 0x19, 0xc6, 0x47, 0x54, 0x57, 0x86, 0x6d, 0xfe, 0xf7, 0x02, 0x90, 0x34, 0xad, 0xca, 0x30, 0x3e, 0xa2, 0xba, 0x32, 0x6c, 0xf3, 0x7f, 0x16, 0x80, 0xa4, 0x69, 0xf5, 0x4f, 0xb3,
0xfe, 0x69, 0x36, 0x21, 0xbd, 0x30, 0x0b, 0x19, 0x0b, 0xf3, 0xff, 0x19, 0xff, 0x10, 0xe9, 0x64, 0x09, 0xe9, 0x85, 0x59, 0xc8, 0x58, 0x98, 0x7f, 0x66, 0xfc, 0x43, 0xa4, 0x93, 0xd5, 0xfc, 0x11,
0x35, 0x7f, 0x04, 0xbe, 0x39, 0x9b, 0x2a, 0x41, 0xb6, 0xe2, 0xb3, 0xa4, 0xd7, 0x56, 0x25, 0x76, 0xf8, 0xe6, 0x6c, 0xaa, 0x04, 0xd9, 0x8a, 0x4f, 0x93, 0x5e, 0x5b, 0x95, 0xd8, 0x85, 0x53, 0x8d,
0xe1, 0x54, 0x63, 0xa0, 0x12, 0xce, 0x5b, 0xc7, 0xb0, 0x60, 0xbb, 0xa3, 0x73, 0xcf, 0x17, 0x74, 0x81, 0x4a, 0x38, 0x6f, 0x1d, 0xc3, 0x82, 0xed, 0x8e, 0xce, 0x3d, 0x5f, 0xd0, 0xc1, 0x9f, 0xf9,
0xf0, 0x67, 0xbe, 0xf6, 0xf1, 0xb9, 0xd5, 0xc6, 0xfc, 0xc8, 0xb5, 0x99, 0xa2, 0x30, 0xe3, 0x23, 0xda, 0xc7, 0xe7, 0x56, 0x1b, 0xf3, 0x23, 0xd7, 0x66, 0x8a, 0xc2, 0x8c, 0x0f, 0xa1, 0xa6, 0x81,
0xa8, 0x69, 0x60, 0x52, 0x85, 0xd2, 0x41, 0xf7, 0x70, 0xbb, 0xdf, 0xbc, 0x41, 0x1a, 0x50, 0x35, 0x49, 0x15, 0x4a, 0x07, 0xdd, 0xc3, 0xed, 0x7e, 0xf3, 0x06, 0x69, 0x40, 0xd5, 0xec, 0xec, 0xf4,
0x3b, 0x3b, 0xfd, 0xa7, 0x1d, 0xb3, 0xb3, 0xdb, 0xcc, 0x91, 0x0a, 0x14, 0x0f, 0xfa, 0x83, 0x61, 0xbf, 0xec, 0x98, 0x9d, 0xdd, 0x66, 0x8e, 0x54, 0xa0, 0x78, 0xd0, 0x1f, 0x0c, 0x9b, 0x79, 0x63,
0x33, 0x6f, 0x6c, 0x42, 0x4b, 0x94, 0x98, 0xb6, 0x4e, 0xfd, 0x56, 0x51, 0xe9, 0x54, 0x31, 0x51, 0x13, 0x5a, 0xa2, 0xc4, 0xb4, 0x75, 0xea, 0xb7, 0x8a, 0x4a, 0xa7, 0x8a, 0x89, 0x42, 0xc8, 0xff,
0x08, 0xf9, 0x1f, 0x43, 0x5d, 0x67, 0x6f, 0xc4, 0x8a, 0x48, 0xb8, 0xc4, 0x30, 0xf1, 0xde, 0xd3, 0x08, 0xea, 0x3a, 0x7b, 0x23, 0x56, 0x44, 0xc2, 0x25, 0x86, 0x89, 0xf7, 0x9e, 0x46, 0xab, 0x77,
0x68, 0xf5, 0x0e, 0x70, 0x87, 0x88, 0xb1, 0xca, 0x96, 0x8f, 0xf1, 0xad, 0x19, 0x96, 0x65, 0x94, 0x80, 0x3b, 0x44, 0x8c, 0x55, 0xb6, 0x7c, 0x8c, 0x6f, 0xcd, 0xb0, 0x2c, 0xa3, 0x7c, 0x14, 0x5b,
0x8f, 0x62, 0xcb, 0xf0, 0xff, 0x83, 0xc5, 0xb8, 0x25, 0x46, 0x50, 0xa4, 0x2c, 0x91, 0x95, 0xe5, 0x86, 0x7f, 0x0e, 0x16, 0xe3, 0x96, 0x18, 0x41, 0x91, 0xb2, 0x44, 0x56, 0x96, 0x3b, 0x66, 0x9a,
0x8e, 0x99, 0x66, 0xc8, 0xf7, 0xa1, 0x99, 0xb4, 0xe4, 0x08, 0xe6, 0xf9, 0x9a, 0xfc, 0x4b, 0x4e, 0x21, 0xdf, 0x83, 0x66, 0xd2, 0x92, 0x23, 0x98, 0xe7, 0x6b, 0xf2, 0x2f, 0x39, 0x71, 0xe3, 0x0e,
0xdc, 0xb8, 0x43, 0xf6, 0x61, 0x35, 0x8b, 0xc1, 0xc3, 0xf5, 0x71, 0xbd, 0x9a, 0x83, 0xa4, 0x99, 0xd9, 0x87, 0xd5, 0x2c, 0x06, 0x0f, 0xd7, 0xc7, 0xf5, 0x6a, 0x0e, 0x92, 0x66, 0xe2, 0xc8, 0x67,
0x38, 0xf2, 0xb9, 0xb0, 0xe8, 0x95, 0x70, 0xfa, 0xdf, 0x89, 0xd7, 0xaf, 0x0d, 0xf6, 0x16, 0xff, 0xc2, 0xa2, 0x57, 0xc2, 0xe9, 0x7f, 0x2b, 0x5e, 0xbf, 0x36, 0xd8, 0x5b, 0xfc, 0x9f, 0x66, 0xdb,
0xa7, 0xd9, 0xf6, 0x2e, 0x00, 0x22, 0x18, 0x69, 0x42, 0xbd, 0x7f, 0xd4, 0xe9, 0x59, 0x3b, 0xfb, 0xbb, 0x00, 0x88, 0x60, 0xa4, 0x09, 0xf5, 0xfe, 0x51, 0xa7, 0x67, 0xed, 0xec, 0xb7, 0x7b, 0xbd,
0xed, 0x5e, 0xaf, 0x73, 0xd0, 0xbc, 0x41, 0x08, 0x2c, 0xa2, 0x57, 0xc7, 0xae, 0x82, 0xe5, 0x18, 0xce, 0x41, 0xf3, 0x06, 0x21, 0xb0, 0x88, 0x5e, 0x1d, 0xbb, 0x0a, 0x96, 0x63, 0x30, 0x61, 0x6a,
0x4c, 0x98, 0x5a, 0x25, 0x2c, 0x4f, 0x56, 0xa1, 0xd9, 0xed, 0x25, 0xa0, 0x05, 0xd2, 0x82, 0xd5, 0x95, 0xb0, 0x3c, 0x59, 0x85, 0x66, 0xb7, 0x97, 0x80, 0x16, 0x48, 0x0b, 0x56, 0x8f, 0x3a, 0xdc,
0xa3, 0x0e, 0x77, 0x04, 0x89, 0x95, 0x5b, 0x64, 0x42, 0x83, 0xe8, 0xae, 0x11, 0xc2, 0xea, 0x57, 0x11, 0x24, 0x56, 0x6e, 0x91, 0x09, 0x0d, 0xa2, 0xbb, 0x46, 0x08, 0xab, 0x5f, 0xd9, 0x93, 0x09,
0xf6, 0x64, 0x42, 0xc3, 0x36, 0x77, 0x64, 0x97, 0xdb, 0xe1, 0x7d, 0x58, 0x56, 0xea, 0xb0, 0x04, 0x0d, 0xdb, 0xdc, 0x91, 0x5d, 0x6e, 0x87, 0x77, 0x61, 0x59, 0xa9, 0xc3, 0x12, 0xdc, 0x72, 0x53,
0xb7, 0xdc, 0x54, 0x09, 0x12, 0xf9, 0x43, 0x58, 0xd1, 0xb4, 0x6a, 0x89, 0x53, 0x88, 0x68, 0x49, 0x25, 0x48, 0xe4, 0x0f, 0x60, 0x45, 0xd3, 0xaa, 0x25, 0x4e, 0x21, 0xa2, 0x25, 0x89, 0x0c, 0x4c,
0x22, 0x03, 0x13, 0x55, 0x78, 0xad, 0x02, 0x20, 0x39, 0xf8, 0x3f, 0xcc, 0xc3, 0x5a, 0x22, 0x21, 0x54, 0xe1, 0xb5, 0x0a, 0x80, 0xe4, 0xe0, 0xff, 0x30, 0x0f, 0x6b, 0x89, 0x84, 0xc8, 0x08, 0xc3,
0x32, 0xc2, 0x70, 0xfe, 0x3d, 0xde, 0x96, 0x3a, 0x02, 0x5f, 0xda, 0xe8, 0xfc, 0xd7, 0x6b, 0x74, 0xf9, 0xf7, 0x78, 0x5b, 0xea, 0x08, 0x7c, 0x61, 0xa3, 0xf3, 0x5f, 0xaf, 0xd1, 0x85, 0xeb, 0x1a,
0xe1, 0xba, 0x46, 0x93, 0x67, 0xb0, 0x24, 0xbc, 0xfd, 0x35, 0x1e, 0x8f, 0xd1, 0x88, 0x07, 0x62, 0x4d, 0x9e, 0xc2, 0x92, 0xf0, 0xf6, 0xd7, 0x78, 0x3c, 0x46, 0x23, 0x1e, 0x88, 0x29, 0xcf, 0x6c,
0xca, 0x33, 0x5b, 0xbe, 0x15, 0x1f, 0x58, 0x6e, 0xe5, 0x5a, 0xb4, 0x63, 0xc0, 0xcd, 0x5f, 0x82, 0xf9, 0x56, 0x7c, 0x60, 0xb9, 0x95, 0x6b, 0xd1, 0x8e, 0x01, 0x37, 0x7f, 0x09, 0x56, 0x32, 0xd0,
0x95, 0x0c, 0xb4, 0x8c, 0x3b, 0x2f, 0x1f, 0xc5, 0x2d, 0x5e, 0xb7, 0x62, 0x35, 0xc7, 0x8b, 0xd0, 0x32, 0xee, 0xbc, 0x7c, 0x18, 0xb7, 0x78, 0xdd, 0x8a, 0xd5, 0x1c, 0x2f, 0x42, 0xb7, 0xde, 0x6f,
0xad, 0xf7, 0x5b, 0xb0, 0x20, 0xb4, 0xbd, 0x4d, 0x28, 0xc8, 0x6b, 0x4f, 0x45, 0x93, 0xfd, 0x24, 0xc1, 0x82, 0xd0, 0xf6, 0x36, 0xa1, 0x20, 0xaf, 0x3d, 0x15, 0x4d, 0xf6, 0x93, 0x10, 0x28, 0x4e,
0x04, 0x8a, 0xd3, 0xc8, 0x01, 0x1b, 0x7f, 0x1b, 0x1b, 0xea, 0x02, 0x63, 0x62, 0x82, 0x7e, 0xa5, 0x23, 0x07, 0x6c, 0xfc, 0x6d, 0x6c, 0xa8, 0x0b, 0x8c, 0x89, 0x09, 0xfa, 0x95, 0x22, 0xac, 0x27,
0x08, 0xeb, 0xc9, 0x14, 0x75, 0x25, 0xa1, 0x1c, 0x9b, 0x1b, 0x6e, 0x49, 0x14, 0x20, 0xf2, 0x49, 0x53, 0xd4, 0x95, 0x84, 0x72, 0x6c, 0x6e, 0xb8, 0x25, 0x51, 0x80, 0xc8, 0xc7, 0x89, 0xed, 0x16,
0x62, 0xbb, 0xc5, 0x66, 0x07, 0x51, 0xf5, 0xad, 0x25, 0x87, 0xfc, 0x61, 0x92, 0xa9, 0xe6, 0x34, 0x9b, 0x1d, 0x44, 0xd5, 0xb7, 0x96, 0x1c, 0xf2, 0x87, 0x49, 0xa6, 0x9a, 0xd3, 0x88, 0x86, 0xbc,
0xa2, 0x21, 0x2f, 0x68, 0x60, 0x9f, 0x12, 0x3c, 0xf6, 0x27, 0x29, 0x1e, 0xbb, 0x98, 0x95, 0x29, 0xa0, 0x81, 0x7d, 0x4a, 0xf0, 0xd8, 0x1f, 0xa7, 0x78, 0xec, 0x62, 0x56, 0xa6, 0x04, 0xcb, 0xdd,
0xc1, 0x72, 0x77, 0x60, 0x23, 0x72, 0x35, 0x8e, 0xd7, 0x59, 0xca, 0xca, 0xbe, 0xa6, 0xb0, 0x0f, 0x81, 0x8d, 0xc8, 0xd5, 0x38, 0x5e, 0x67, 0x29, 0x2b, 0xfb, 0x9a, 0xc2, 0x3e, 0xd0, 0x2b, 0x7f,
0xf4, 0xca, 0x1f, 0x43, 0x2b, 0x2a, 0x26, 0xd1, 0x8c, 0x85, 0xac, 0x72, 0xd6, 0x15, 0xba, 0x19, 0x0c, 0xad, 0xa8, 0x98, 0x44, 0x33, 0x16, 0xb2, 0xca, 0x59, 0x57, 0xe8, 0x66, 0xac, 0x3d, 0xdf,
0x6b, 0xcf, 0x0f, 0x60, 0x33, 0x36, 0x5e, 0xf1, 0x26, 0x95, 0xb3, 0x8a, 0xda, 0xd0, 0x06, 0x30, 0x87, 0xcd, 0xd8, 0x78, 0xc5, 0x9b, 0x54, 0xce, 0x2a, 0x6a, 0x43, 0x1b, 0xc0, 0x58, 0xa3, 0x0e,
0xd6, 0xa8, 0x03, 0xb8, 0x15, 0x2b, 0x2b, 0xd1, 0xae, 0x4a, 0x56, 0x61, 0x2d, 0xad, 0xb0, 0x58, 0xe0, 0x56, 0xac, 0xac, 0x44, 0xbb, 0x2a, 0x59, 0x85, 0xb5, 0xb4, 0xc2, 0x62, 0x2d, 0x33, 0x7e,
0xcb, 0x8c, 0xdf, 0x59, 0x00, 0xf2, 0xc3, 0x39, 0xf5, 0xaf, 0xf0, 0x5a, 0x73, 0xf0, 0xaa, 0x3b, 0x67, 0x01, 0xc8, 0x0f, 0xe6, 0xd4, 0xbf, 0xc2, 0x6b, 0xcd, 0xc1, 0xcb, 0xee, 0x50, 0x48, 0x4d,
0x14, 0x52, 0x53, 0x99, 0x7f, 0xad, 0xe8, 0x06, 0x59, 0xd1, 0x05, 0x8a, 0xaf, 0x8e, 0x2e, 0x50, 0x65, 0xfe, 0x95, 0xa2, 0x1b, 0x64, 0x45, 0x17, 0x28, 0xbe, 0x3c, 0xba, 0x40, 0xe9, 0x65, 0xd1,
0x7a, 0x55, 0x74, 0x81, 0xb7, 0xa1, 0xe1, 0x9c, 0xb9, 0x1e, 0x63, 0x04, 0x98, 0x1c, 0x18, 0xb4, 0x05, 0xde, 0x84, 0x86, 0x73, 0xe6, 0x7a, 0x8c, 0x11, 0x60, 0x72, 0x60, 0xd0, 0x5a, 0xb8, 0x5b,
0x16, 0xee, 0x16, 0xee, 0xd5, 0xcd, 0xba, 0x00, 0x32, 0x29, 0x30, 0x20, 0x5f, 0x46, 0x48, 0x74, 0xb8, 0x57, 0x37, 0xeb, 0x02, 0xc8, 0xa4, 0xc0, 0x80, 0x7c, 0x11, 0x21, 0xd1, 0xf1, 0x19, 0xc6,
0x7c, 0x86, 0xb1, 0x37, 0x74, 0x16, 0xa0, 0x33, 0x3e, 0xa3, 0x42, 0x31, 0x8b, 0x0b, 0x56, 0x66, 0xde, 0xd0, 0x59, 0x80, 0xce, 0xf8, 0x8c, 0x0a, 0xc5, 0x2c, 0x2e, 0x58, 0x99, 0x99, 0xc1, 0x03,
0x66, 0xf0, 0x80, 0xbc, 0x03, 0x8b, 0x81, 0x37, 0x67, 0x62, 0xb5, 0x1c, 0x06, 0x6e, 0xef, 0xaf, 0xf2, 0x16, 0x2c, 0x06, 0xde, 0x9c, 0x89, 0xd5, 0x72, 0x18, 0xb8, 0xbd, 0xbf, 0xce, 0xa1, 0x47,
0x73, 0xe8, 0x91, 0xf4, 0xfe, 0x58, 0x99, 0x07, 0xd4, 0x9a, 0x3a, 0x41, 0xc0, 0x84, 0x93, 0x91, 0xd2, 0xfb, 0x63, 0x65, 0x1e, 0x50, 0x6b, 0xea, 0x04, 0x01, 0x13, 0x4e, 0x46, 0x9e, 0x1b, 0xfa,
0xe7, 0x86, 0xbe, 0x37, 0x11, 0x26, 0xfc, 0xe5, 0x79, 0x40, 0x0f, 0x79, 0xca, 0x0e, 0x4f, 0x20, 0xde, 0x44, 0x98, 0xf0, 0x97, 0xe7, 0x01, 0x3d, 0xe4, 0x29, 0x3b, 0x3c, 0x81, 0x7c, 0x1c, 0x35,
0x9f, 0x44, 0x4d, 0x9a, 0xd9, 0x8e, 0x1f, 0xb4, 0x00, 0x9b, 0x24, 0x7b, 0x8a, 0xd2, 0xab, 0xed, 0x69, 0x66, 0x3b, 0x7e, 0xd0, 0x02, 0x6c, 0x92, 0xec, 0x29, 0x4a, 0xaf, 0xb6, 0xe3, 0xab, 0xb6,
0xf8, 0xaa, 0x2d, 0xec, 0x23, 0x48, 0x44, 0x3d, 0xa8, 0x25, 0xa3, 0x1e, 0xfc, 0x72, 0x76, 0xd4, 0xb0, 0x8f, 0x20, 0x11, 0xf5, 0xa0, 0x96, 0x8c, 0x7a, 0xf0, 0xcb, 0xd9, 0x51, 0x0f, 0x1a, 0x31,
0x83, 0x46, 0x8c, 0x98, 0xa5, 0xa7, 0xf8, 0x6b, 0x05, 0x3f, 0x48, 0x07, 0x73, 0x58, 0xfc, 0x3a, 0x62, 0x96, 0x9e, 0xe2, 0xaf, 0x15, 0xfc, 0x20, 0x1d, 0xcc, 0x61, 0xf1, 0xeb, 0x04, 0x73, 0x58,
0xc1, 0x1c, 0x96, 0xb2, 0x82, 0x39, 0x7c, 0x04, 0x35, 0xbc, 0x43, 0x6f, 0x9d, 0xa3, 0x33, 0x33, 0xca, 0x0a, 0xe6, 0xf0, 0x21, 0xd4, 0xf0, 0x0e, 0xbd, 0x75, 0x8e, 0xce, 0xcc, 0xdc, 0x25, 0xa1,
0x77, 0x49, 0x68, 0xea, 0x97, 0xec, 0xf7, 0x1d, 0x37, 0x34, 0xc1, 0x97, 0x3f, 0x83, 0x74, 0x5c, 0xa9, 0x5f, 0xb2, 0xdf, 0x77, 0xdc, 0xd0, 0x04, 0x5f, 0xfe, 0x0c, 0xd2, 0x71, 0x15, 0x96, 0x5f,
0x85, 0xe5, 0xd7, 0x8a, 0xab, 0xf0, 0xcd, 0x04, 0x4d, 0x10, 0x77, 0xfd, 0xb7, 0xa0, 0x22, 0xe7, 0x29, 0xae, 0xc2, 0x37, 0x13, 0x34, 0x41, 0xdc, 0xf5, 0xdf, 0x82, 0x8a, 0x9c, 0x27, 0x46, 0x6c,
0x89, 0x11, 0xdb, 0x53, 0xdf, 0x9b, 0x4a, 0xf3, 0x26, 0xfb, 0x4d, 0x16, 0x21, 0x1f, 0x7a, 0x22, 0x4f, 0x7d, 0x6f, 0x2a, 0xcd, 0x9b, 0xec, 0x37, 0x59, 0x84, 0x7c, 0xe8, 0x89, 0xcc, 0xf9, 0xd0,
0x73, 0x3e, 0xf4, 0x8c, 0x5f, 0x84, 0x9a, 0xb6, 0xd4, 0xc8, 0x5b, 0x5c, 0xaf, 0xef, 0xd2, 0x89, 0x33, 0x7e, 0x11, 0x6a, 0xda, 0x52, 0x23, 0x6f, 0x70, 0xbd, 0xbe, 0x4b, 0x27, 0x52, 0xed, 0xcb,
0x54, 0xfb, 0xf2, 0x51, 0xac, 0x0a, 0x68, 0x77, 0xcc, 0xce, 0xbd, 0xb1, 0xe3, 0x53, 0x8c, 0x80, 0x47, 0xb1, 0x2a, 0xa0, 0xdd, 0x31, 0x3b, 0xf7, 0xc6, 0x8e, 0x4f, 0x31, 0x02, 0x8a, 0xe5, 0xd3,
0x62, 0xf9, 0xf4, 0x82, 0xfa, 0x81, 0x34, 0x4b, 0x37, 0x55, 0x82, 0xc9, 0xe1, 0xc6, 0x2f, 0xc1, 0x0b, 0xea, 0x07, 0xd2, 0x2c, 0xdd, 0x54, 0x09, 0x26, 0x87, 0x1b, 0xbf, 0x04, 0x2b, 0xb1, 0xb9,
0x4a, 0x6c, 0x6e, 0x05, 0xf9, 0x7e, 0x07, 0x16, 0x70, 0xdc, 0xa4, 0xef, 0x53, 0x3c, 0x78, 0x81, 0x15, 0xe4, 0xfb, 0x2d, 0x58, 0xc0, 0x71, 0x93, 0xbe, 0x4f, 0xf1, 0xe0, 0x05, 0x22, 0x0d, 0xe3,
0x48, 0xc3, 0x38, 0x30, 0xdc, 0xa2, 0x6e, 0xcd, 0x7c, 0xef, 0x04, 0x2b, 0xc9, 0x99, 0x35, 0x01, 0xc0, 0x70, 0x8b, 0xba, 0x35, 0xf3, 0xbd, 0x13, 0xac, 0x24, 0x67, 0xd6, 0x04, 0xec, 0xc8, 0xf7,
0x3b, 0xf2, 0xbd, 0x13, 0xe3, 0xdf, 0x17, 0xa0, 0xb0, 0xef, 0xcd, 0x74, 0x07, 0xe8, 0x5c, 0xca, 0x4e, 0x8c, 0xbf, 0x52, 0x84, 0xc2, 0xbe, 0x37, 0xd3, 0x1d, 0xa0, 0x73, 0x29, 0x07, 0x68, 0xa1,
0x01, 0x5a, 0xa8, 0x5b, 0x2c, 0xa5, 0x4e, 0x11, 0x12, 0x2b, 0xda, 0x88, 0xa5, 0x4a, 0xe5, 0x1e, 0x6e, 0xb1, 0x94, 0x3a, 0x45, 0x48, 0xac, 0x68, 0x23, 0x96, 0x2a, 0x95, 0x7b, 0xb0, 0xc8, 0xe8,
0x2c, 0x32, 0x3a, 0x11, 0x7a, 0x96, 0xb8, 0x78, 0xc4, 0x0f, 0x67, 0xbe, 0xf9, 0xec, 0x69, 0x38, 0x44, 0xe8, 0x59, 0xe2, 0xe2, 0x11, 0x3f, 0x9c, 0xf9, 0xe6, 0xb3, 0xa7, 0xe1, 0xd0, 0xdb, 0xe3,
0xf4, 0xf6, 0x38, 0x9c, 0xac, 0x42, 0x41, 0x09, 0xef, 0x98, 0xcc, 0x3e, 0xc9, 0x3a, 0x2c, 0xe0, 0x70, 0xb2, 0x0a, 0x05, 0x25, 0xbc, 0x63, 0x32, 0xfb, 0x24, 0xeb, 0xb0, 0x80, 0x17, 0xa6, 0xe4,
0x85, 0x29, 0x79, 0xd3, 0x5d, 0x7c, 0x91, 0x0f, 0x60, 0x25, 0x5e, 0x2e, 0x27, 0x45, 0x42, 0x32, 0x4d, 0x77, 0xf1, 0x45, 0xde, 0x87, 0x95, 0x78, 0xb9, 0x9c, 0x14, 0x09, 0xc9, 0x40, 0x2f, 0x18,
0xd0, 0x0b, 0x46, 0x9a, 0x74, 0x13, 0x18, 0x1d, 0x89, 0xee, 0xba, 0x17, 0xcc, 0xf2, 0x29, 0xa5, 0x69, 0xd2, 0x4d, 0x60, 0x74, 0x24, 0xba, 0xeb, 0x5e, 0x30, 0xcb, 0xa7, 0x94, 0x62, 0x92, 0x46,
0x98, 0xa4, 0x11, 0xbd, 0x4a, 0x8c, 0xe8, 0xdd, 0x81, 0x5a, 0x38, 0xb9, 0xb0, 0x66, 0xf6, 0xd5, 0xf4, 0x2a, 0x31, 0xa2, 0x77, 0x07, 0x6a, 0xe1, 0xe4, 0xc2, 0x9a, 0xd9, 0x57, 0x13, 0xcf, 0x96,
0xc4, 0xb3, 0xe5, 0xcd, 0x4a, 0x08, 0x27, 0x17, 0x47, 0x1c, 0x42, 0x3e, 0x04, 0x98, 0xce, 0x66, 0x37, 0x2b, 0x21, 0x9c, 0x5c, 0x1c, 0x71, 0x08, 0xf9, 0x00, 0x60, 0x3a, 0x9b, 0x89, 0xbd, 0x87,
0x62, 0xef, 0xa1, 0x3d, 0x33, 0x5a, 0xca, 0x87, 0x47, 0x47, 0x7c, 0xc9, 0x99, 0xd5, 0xe9, 0x6c, 0xf6, 0xcc, 0x68, 0x29, 0x1f, 0x1e, 0x1d, 0xf1, 0x25, 0x67, 0x56, 0xa7, 0xb3, 0x19, 0xff, 0xc9,
0xc6, 0x7f, 0x92, 0x5d, 0x58, 0xcc, 0x8c, 0x52, 0x72, 0x5b, 0x5e, 0x2b, 0xf1, 0x66, 0x5b, 0x19, 0x32, 0xd8, 0x53, 0x95, 0xa1, 0x1e, 0xcb, 0xd0, 0x3e, 0x54, 0x19, 0xec, 0xa9, 0xcc, 0xb0, 0x0b,
0x9b, 0xb3, 0x31, 0xd2, 0x61, 0x9b, 0xdf, 0x07, 0xf2, 0x67, 0x0c, 0x04, 0x32, 0x84, 0xaa, 0x6a, 0x8b, 0x99, 0x61, 0x4d, 0x6e, 0xcb, 0x7b, 0x28, 0xde, 0x6c, 0x2b, 0x63, 0x37, 0x37, 0x46, 0x3a,
0x5f, 0x2a, 0xfc, 0x48, 0x2d, 0x15, 0x7e, 0x84, 0xd1, 0x45, 0xce, 0xb8, 0x29, 0x92, 0x0f, 0x1a, 0x6c, 0xf3, 0x7b, 0x40, 0x7e, 0xc2, 0xc8, 0x21, 0x43, 0xa8, 0xaa, 0x0e, 0xa5, 0xe2, 0x95, 0xd4,
0xe7, 0x26, 0x2e, 0x64, 0x19, 0xff, 0x29, 0x07, 0x25, 0x1e, 0xd4, 0xe3, 0x5d, 0x58, 0xe2, 0xf8, 0x52, 0xf1, 0x4a, 0x18, 0x21, 0xe5, 0x9c, 0x9e, 0x3a, 0x23, 0x40, 0x63, 0xf5, 0xc4, 0x0d, 0x2e,
0xca, 0x99, 0x5c, 0x78, 0xfc, 0x70, 0xfe, 0x6f, 0x28, 0xfc, 0xc8, 0xd9, 0xb6, 0xd0, 0xa2, 0x24, 0xe3, 0x04, 0xaa, 0xaa, 0xd7, 0x68, 0x93, 0xf2, 0xbc, 0xd0, 0x0a, 0xce, 0x6d, 0x71, 0x1d, 0xb2,
0x45, 0x6c, 0x84, 0x16, 0x29, 0xe9, 0x0e, 0x54, 0x55, 0xd5, 0xda, 0xd2, 0xa9, 0xc8, 0x9a, 0xc9, 0x6e, 0x56, 0x19, 0x64, 0xc0, 0x00, 0x64, 0x0d, 0x16, 0x02, 0x1a, 0x46, 0x56, 0x87, 0x52, 0x40,
0x9b, 0x50, 0x3c, 0xf7, 0x66, 0x52, 0xef, 0x09, 0xd1, 0x48, 0x9a, 0x08, 0x8f, 0xda, 0xc2, 0xea, 0x43, 0x6e, 0x82, 0x1a, 0x9d, 0x3b, 0x93, 0x71, 0xec, 0x26, 0x3d, 0x20, 0x88, 0x9b, 0xf5, 0xfe,
0x88, 0x2e, 0x8a, 0x15, 0x44, 0x5b, 0x58, 0x25, 0x32, 0xd4, 0x41, 0xa2, 0x8f, 0x0b, 0x19, 0x7d, 0x4b, 0x0e, 0x4a, 0x3c, 0xd2, 0xc8, 0xdb, 0xb0, 0xc4, 0xdb, 0xa4, 0x3c, 0xdc, 0x85, 0x1b, 0x12,
0x3c, 0x86, 0x25, 0x46, 0x07, 0x34, 0xb7, 0xa3, 0xeb, 0x0f, 0xcd, 0x6f, 0x33, 0xf9, 0x66, 0x34, 0x67, 0x4a, 0x87, 0xc2, 0xb9, 0x9d, 0xed, 0x55, 0x2d, 0x74, 0x53, 0xc4, 0xdb, 0x68, 0xe1, 0x9b,
0x99, 0x8f, 0xa9, 0xae, 0x79, 0x46, 0xcf, 0x60, 0x01, 0x97, 0x72, 0xa5, 0xf1, 0x3b, 0x39, 0x4e, 0xee, 0x40, 0x55, 0x75, 0x4f, 0x5b, 0xcf, 0x15, 0xd9, 0x3b, 0xf2, 0x3a, 0x14, 0xcf, 0xbd, 0x99,
0x5f, 0x58, 0xb9, 0xe4, 0x1e, 0x14, 0x5d, 0xe9, 0xa2, 0x14, 0x49, 0x31, 0xea, 0x52, 0x25, 0xc3, 0x54, 0xc6, 0x42, 0x34, 0x5b, 0x26, 0xc2, 0xa3, 0xb6, 0xb0, 0x3a, 0xa2, 0xdb, 0x6b, 0x05, 0xd1,
0x33, 0x11, 0x83, 0x4d, 0x1d, 0x3a, 0xf6, 0xe8, 0xa5, 0x37, 0xcc, 0x9a, 0x3b, 0x9f, 0x2a, 0xc5, 0x16, 0x56, 0x89, 0x8c, 0xbf, 0x90, 0x18, 0xc7, 0x85, 0x8c, 0x71, 0x3c, 0x86, 0x25, 0x46, 0x9c,
0xed, 0xb7, 0x64, 0xb7, 0x12, 0x4a, 0x4f, 0xde, 0x7b, 0xb5, 0x4d, 0xb7, 0x34, 0x17, 0xe3, 0x62, 0x34, 0x5f, 0xa8, 0xeb, 0x4f, 0xf2, 0x6f, 0x33, 0xa1, 0x6b, 0x34, 0x99, 0x8f, 0xa9, 0xae, 0x0e,
0xec, 0xc4, 0x94, 0x32, 0xd0, 0xf8, 0x8c, 0x6a, 0xae, 0xc5, 0xbf, 0x9f, 0x87, 0x46, 0xac, 0x45, 0x47, 0x77, 0x65, 0x01, 0x97, 0xc2, 0xae, 0xf1, 0x3b, 0x39, 0x4e, 0xf4, 0x58, 0xb9, 0xe4, 0x1e,
0xe8, 0x63, 0xcd, 0x0e, 0x00, 0x6e, 0x98, 0x15, 0xf3, 0x8d, 0xae, 0xac, 0x42, 0x4c, 0xd5, 0xc6, 0x14, 0x5d, 0xe9, 0x37, 0x15, 0x89, 0x56, 0xea, 0xa6, 0x27, 0xc3, 0x33, 0x11, 0x83, 0x2d, 0x0f,
0x29, 0x1f, 0x1b, 0x27, 0xe5, 0x63, 0x58, 0xd0, 0x7d, 0x0c, 0x1f, 0x40, 0x35, 0x8a, 0x8e, 0x15, 0xf4, 0x36, 0xd2, 0x4b, 0x6f, 0x98, 0x35, 0x77, 0x3e, 0x55, 0xda, 0xe4, 0x6f, 0xc9, 0x6e, 0x25,
0x6f, 0x12, 0xab, 0x4f, 0x5e, 0x2d, 0x8d, 0x90, 0x22, 0xaf, 0xc4, 0x92, 0xee, 0x95, 0xf8, 0x3d, 0x34, 0xb1, 0xbc, 0xf7, 0x8a, 0x76, 0x6c, 0x69, 0x7e, 0xcf, 0xc5, 0xd8, 0x31, 0x2e, 0x05, 0xb3,
0xcd, 0x89, 0x6d, 0x01, 0x8b, 0x31, 0xb2, 0x46, 0xf4, 0xa7, 0xe2, 0xc2, 0x66, 0x7c, 0x09, 0x35, 0xf1, 0x19, 0xd5, 0xfc, 0x9d, 0x7f, 0x3f, 0x0f, 0x8d, 0x58, 0x8b, 0xd0, 0xf1, 0x9b, 0x9d, 0x4a,
0xad, 0xf1, 0xba, 0x23, 0x58, 0x2e, 0xe6, 0x08, 0xa6, 0x2e, 0xb0, 0xe7, 0xa3, 0x0b, 0xec, 0xc6, 0xdc, 0x5a, 0x2c, 0xe6, 0x1b, 0xfd, 0x6b, 0x85, 0xec, 0xac, 0x8d, 0x53, 0x3e, 0x36, 0x4e, 0xca,
0xaf, 0xe5, 0xa1, 0xc1, 0xf6, 0x97, 0xe3, 0x9e, 0x1d, 0x79, 0x13, 0x67, 0x84, 0x86, 0x5a, 0xb5, 0xf1, 0xb1, 0xa0, 0x3b, 0x3e, 0x3e, 0x80, 0x6a, 0x14, 0xb2, 0x2b, 0xde, 0x24, 0x56, 0x9f, 0xbc,
0xc3, 0x04, 0xa3, 0x25, 0xf7, 0x99, 0xd8, 0x62, 0x9c, 0xcf, 0xd2, 0xa3, 0xae, 0x70, 0x22, 0xad, 0xef, 0x1a, 0x21, 0x45, 0xae, 0x92, 0x25, 0xdd, 0x55, 0xf2, 0xbb, 0x9a, 0x67, 0xdd, 0x02, 0x16,
0xa2, 0xae, 0x18, 0xd0, 0x60, 0x84, 0x11, 0x4d, 0xae, 0x51, 0x24, 0x2d, 0xb3, 0x76, 0x4a, 0xe9, 0x63, 0x64, 0x8d, 0xe8, 0x4f, 0xc5, 0xaf, 0xce, 0xf8, 0x02, 0x6a, 0x5a, 0xe3, 0x75, 0xef, 0xb4,
0xb6, 0x1d, 0x70, 0x0a, 0xf9, 0x01, 0xac, 0x30, 0x1c, 0x0c, 0xa9, 0x30, 0x75, 0x26, 0x13, 0x27, 0x5c, 0xcc, 0x3b, 0x4d, 0xdd, 0xaa, 0xcf, 0x47, 0xb7, 0xea, 0x8d, 0x5f, 0xcb, 0x43, 0x83, 0xed,
0xba, 0x99, 0x59, 0x30, 0x9b, 0xa7, 0x94, 0x9a, 0x76, 0x48, 0x0f, 0x59, 0x82, 0x08, 0xbc, 0x55, 0x2f, 0xc7, 0x3d, 0x3b, 0xf2, 0x26, 0xce, 0x08, 0xad, 0xc7, 0x6a, 0x87, 0x09, 0xee, 0x4f, 0xee,
0x19, 0x3b, 0x81, 0x7d, 0x12, 0x79, 0xc2, 0xab, 0x6f, 0xe9, 0xc9, 0x10, 0x39, 0x8b, 0x08, 0x47, 0x33, 0xb1, 0xc5, 0x38, 0xf3, 0xa7, 0x87, 0x82, 0xe1, 0x27, 0x87, 0x0a, 0x05, 0x63, 0x40, 0x83,
0x27, 0x11, 0x4f, 0x04, 0xf3, 0x27, 0x56, 0x52, 0x39, 0xb9, 0x92, 0x8c, 0x7f, 0x98, 0x87, 0x9a, 0x51, 0x6b, 0xb4, 0x03, 0x47, 0xe1, 0xbd, 0xcc, 0xda, 0x29, 0xa5, 0xdb, 0x76, 0xc0, 0xc9, 0xf6,
0xb6, 0x2c, 0x5f, 0xe7, 0x74, 0xbd, 0x9d, 0x32, 0xac, 0x57, 0x75, 0x1b, 0xfa, 0xdb, 0xf1, 0x2a, 0xfb, 0xb0, 0xc2, 0x70, 0x30, 0xce, 0xc3, 0xd4, 0x99, 0x4c, 0x9c, 0xe8, 0xba, 0x68, 0xc1, 0x6c,
0x0b, 0xea, 0xfa, 0x9e, 0xbe, 0x80, 0x6f, 0x41, 0x95, 0xed, 0xba, 0x8f, 0xd0, 0x00, 0x21, 0x42, 0x9e, 0x52, 0x6a, 0xda, 0x21, 0x3d, 0x64, 0x09, 0x22, 0x1a, 0x58, 0x65, 0xec, 0x04, 0xf6, 0x49,
0xe2, 0x21, 0xe0, 0x68, 0x7e, 0x22, 0x13, 0x1f, 0x62, 0x62, 0x29, 0x4a, 0x7c, 0xc8, 0x12, 0x5f, 0xe4, 0x9e, 0xaf, 0xbe, 0xa5, 0x7b, 0x45, 0xe4, 0xc1, 0x22, 0xbc, 0xaf, 0x44, 0x90, 0x13, 0xcc,
0x76, 0x7d, 0xe7, 0x33, 0xa8, 0x8b, 0x52, 0x71, 0x4e, 0x85, 0x58, 0xb0, 0xaa, 0x9d, 0xdc, 0x6a, 0x9f, 0x58, 0x49, 0xe5, 0xe4, 0x4a, 0x32, 0xfe, 0x49, 0x1e, 0x6a, 0xda, 0xb2, 0x7c, 0x95, 0x23,
0xbe, 0xcd, 0x1a, 0xaf, 0x8e, 0x4f, 0xbe, 0xc8, 0xf8, 0x50, 0x66, 0xac, 0xbc, 0x2a, 0xe3, 0x43, 0xff, 0x76, 0xca, 0xda, 0x5f, 0xd5, 0x0d, 0xfb, 0x6f, 0xc6, 0xab, 0x2c, 0xa8, 0x3b, 0x85, 0xfa,
0xfe, 0x61, 0xec, 0xa9, 0x1b, 0x51, 0xe8, 0x3e, 0x2a, 0xe9, 0xd8, 0x87, 0xb0, 0x22, 0xc9, 0xd5, 0x02, 0xbe, 0x05, 0x55, 0xb6, 0xeb, 0x3e, 0x44, 0xab, 0x88, 0x88, 0xd3, 0x87, 0x80, 0xa3, 0xf9,
0xdc, 0xb5, 0x5d, 0xd7, 0x9b, 0xbb, 0x23, 0x2a, 0x6f, 0x87, 0x13, 0x91, 0x74, 0x1c, 0xa5, 0x18, 0x89, 0x4c, 0x7c, 0x88, 0x89, 0xa5, 0x28, 0xf1, 0x21, 0x4b, 0x7c, 0xd1, 0x9d, 0xa2, 0x4f, 0xa1,
0x63, 0x15, 0xab, 0x85, 0xbb, 0xa1, 0xde, 0x87, 0x12, 0xe7, 0xcb, 0x39, 0xf3, 0x91, 0x4d, 0xb8, 0x2e, 0x4a, 0xc5, 0x39, 0x15, 0xb2, 0xca, 0xaa, 0xc6, 0x4e, 0xa8, 0xf9, 0x36, 0x6b, 0xbc, 0x3a,
0x38, 0x0a, 0xb9, 0x07, 0x25, 0xce, 0x9e, 0xe7, 0xaf, 0x25, 0x36, 0x1c, 0xc1, 0x68, 0x03, 0x61, 0x3e, 0xf9, 0x22, 0xe3, 0x43, 0x99, 0xb1, 0xf2, 0xb2, 0x8c, 0x0f, 0xf9, 0x87, 0xb1, 0xa7, 0xae,
0x19, 0x0f, 0x69, 0xe8, 0x3b, 0xa3, 0x20, 0xba, 0x78, 0x5e, 0x0a, 0xaf, 0x66, 0xa2, 0xae, 0xc8, 0x69, 0xa1, 0x4f, 0xab, 0xa4, 0x63, 0x1f, 0xc0, 0x8a, 0x24, 0x57, 0x73, 0xd7, 0x76, 0x5d, 0x6f,
0x6e, 0x11, 0x61, 0xa2, 0x86, 0x86, 0xe3, 0xb0, 0x83, 0x69, 0x25, 0x56, 0x86, 0x60, 0x97, 0x26, 0xee, 0x8e, 0xa8, 0xbc, 0xb2, 0x4e, 0x44, 0xd2, 0x71, 0x94, 0x62, 0x8c, 0x55, 0x00, 0x19, 0xee,
0xb0, 0x7e, 0x42, 0xc3, 0x17, 0x94, 0xba, 0x2e, 0x63, 0x86, 0x46, 0xd4, 0x0d, 0x7d, 0x7b, 0xc2, 0x1b, 0x7b, 0x1f, 0x4a, 0x5c, 0x58, 0xe0, 0x1c, 0x51, 0x36, 0xe1, 0xe2, 0x28, 0xe4, 0x1e, 0x94,
0x26, 0x89, 0xf7, 0xe0, 0x51, 0xaa, 0xd4, 0x48, 0x03, 0xb8, 0x1d, 0x65, 0xdc, 0x51, 0xf9, 0x38, 0xb8, 0xcc, 0x90, 0xbf, 0x96, 0xd8, 0x70, 0x04, 0xa3, 0x0d, 0x84, 0x65, 0x3c, 0xa4, 0xa1, 0xef,
0xed, 0x58, 0x3b, 0xc9, 0x4a, 0xdb, 0xfc, 0x05, 0xd8, 0xbc, 0x3e, 0x53, 0x86, 0x9a, 0xe0, 0x5e, 0x8c, 0x82, 0xe8, 0x36, 0x7c, 0x29, 0xbc, 0x9a, 0x89, 0xba, 0x22, 0x63, 0x4a, 0x84, 0x89, 0x6a,
0x9c, 0xaa, 0x28, 0x2b, 0xf8, 0xc4, 0xb3, 0x43, 0xde, 0x1a, 0x9d, 0xb2, 0xf4, 0xa0, 0xa6, 0xa5, 0x23, 0x8e, 0xc3, 0x0e, 0xa6, 0x95, 0x58, 0x19, 0x82, 0x87, 0x9b, 0xc0, 0xfa, 0x09, 0x0d, 0x9f,
0x44, 0x67, 0x7f, 0x0e, 0x99, 0x3b, 0xfe, 0xc1, 0x4e, 0x24, 0xd7, 0xf3, 0xa7, 0x68, 0x75, 0x1e, 0x53, 0xea, 0xba, 0x8c, 0x43, 0x1b, 0x51, 0x37, 0xf4, 0xed, 0x09, 0x9b, 0x24, 0xde, 0x83, 0x47,
0x5b, 0x51, 0xe9, 0x39, 0x73, 0x29, 0x82, 0xa3, 0xa3, 0x92, 0xb1, 0x05, 0x4b, 0xc8, 0xd9, 0x6b, 0xa9, 0x52, 0x23, 0xb5, 0xe4, 0x76, 0x94, 0x71, 0x47, 0xe5, 0xe3, 0xb4, 0x63, 0xed, 0x24, 0x2b,
0x07, 0xdd, 0xcb, 0x98, 0x41, 0x63, 0x15, 0x48, 0x8f, 0xd3, 0x2e, 0xdd, 0x25, 0xf7, 0x0f, 0x0b, 0x6d, 0xf3, 0x17, 0x60, 0xf3, 0xfa, 0x4c, 0x19, 0xba, 0x8b, 0x7b, 0x71, 0xaa, 0xa2, 0x4c, 0xf3,
0x50, 0xd3, 0xc0, 0xec, 0x34, 0x42, 0x3f, 0x66, 0x6b, 0xec, 0xd8, 0x53, 0x2a, 0x4d, 0xfc, 0x0d, 0x13, 0xcf, 0x0e, 0x79, 0x6b, 0x74, 0xca, 0xd2, 0x83, 0x9a, 0x96, 0x12, 0xf1, 0x17, 0x39, 0xe4,
0xb3, 0x81, 0xd0, 0x5d, 0x01, 0x64, 0x67, 0xb1, 0x7d, 0x71, 0x66, 0x79, 0xf3, 0xd0, 0x1a, 0xd3, 0x38, 0xf9, 0x07, 0x3b, 0x91, 0x5c, 0xcf, 0x9f, 0xa2, 0x29, 0x7c, 0x6c, 0x45, 0xa5, 0xe7, 0xcc,
0x33, 0x9f, 0xca, 0x56, 0xd6, 0xed, 0x8b, 0xb3, 0xfe, 0x3c, 0xdc, 0x45, 0x98, 0x0c, 0x4e, 0xa4, 0xa5, 0x08, 0x8e, 0xde, 0x53, 0xc6, 0x16, 0x2c, 0xa1, 0xb8, 0xa1, 0x1d, 0x74, 0x2f, 0xe2, 0x50,
0x61, 0x15, 0x54, 0x70, 0xa2, 0x08, 0x4b, 0xf8, 0x7f, 0xf3, 0x95, 0x59, 0x54, 0xfe, 0xdf, 0x5c, 0x8d, 0x55, 0x20, 0x3d, 0x4e, 0xbb, 0x74, 0x3f, 0xe1, 0x3f, 0x2c, 0x40, 0x4d, 0x03, 0xb3, 0xd3,
0x5a, 0x4c, 0x1e, 0xa0, 0xa5, 0xf4, 0x01, 0xfa, 0x09, 0xac, 0xf3, 0x03, 0x54, 0x90, 0x66, 0x2b, 0x08, 0x9d, 0xab, 0xad, 0xb1, 0x63, 0x4f, 0xa9, 0xf4, 0x3b, 0x68, 0x98, 0x0d, 0x84, 0xee, 0x0a,
0xb1, 0x93, 0x57, 0x31, 0x55, 0x74, 0x52, 0x63, 0x7b, 0x9b, 0xac, 0x07, 0x92, 0x2c, 0x05, 0xce, 0x20, 0x3b, 0x8b, 0xed, 0x8b, 0x33, 0xcb, 0x9b, 0x87, 0xd6, 0x98, 0x9e, 0xf9, 0x54, 0xb6, 0xb2,
0x8f, 0x39, 0x21, 0xcb, 0x99, 0xac, 0x67, 0xa2, 0xf0, 0x81, 0xf3, 0x63, 0x2a, 0x83, 0x23, 0xc5, 0x6e, 0x5f, 0x9c, 0xf5, 0xe7, 0xe1, 0x2e, 0xc2, 0x64, 0xc4, 0x24, 0x0d, 0xab, 0xa0, 0x22, 0x26,
0x30, 0xc5, 0xe5, 0xbc, 0xa9, 0xe3, 0x26, 0x31, 0xed, 0xcb, 0x38, 0x66, 0x55, 0x60, 0xda, 0x97, 0x45, 0x58, 0xc2, 0x29, 0x9d, 0xaf, 0xcc, 0xa2, 0x72, 0x4a, 0xe7, 0x22, 0x6c, 0xf2, 0x00, 0x2d,
0x3a, 0xe6, 0x23, 0xd8, 0x98, 0xd2, 0xb1, 0x63, 0xc7, 0x8b, 0xb5, 0x22, 0xc6, 0x6d, 0x95, 0x27, 0xa5, 0x0f, 0xd0, 0x8f, 0x61, 0x9d, 0x1f, 0xa0, 0x82, 0x34, 0x5b, 0x89, 0x9d, 0xbc, 0x8a, 0xa9,
0x6b, 0x79, 0x06, 0x5c, 0x70, 0x67, 0xa3, 0xf1, 0x63, 0x6f, 0x7a, 0xe2, 0x70, 0x9e, 0x85, 0xbb, 0xa2, 0x93, 0x1a, 0x2f, 0xde, 0x64, 0x3d, 0x90, 0x64, 0x29, 0x70, 0x7e, 0xc4, 0x09, 0x59, 0xce,
0xe0, 0x15, 0xcd, 0x45, 0x77, 0x3e, 0xfd, 0x79, 0x04, 0xb3, 0x2c, 0x81, 0xd1, 0x80, 0xda, 0x20, 0x64, 0x3d, 0x13, 0x85, 0x0f, 0x9c, 0x1f, 0x51, 0x19, 0xb1, 0x29, 0x86, 0x29, 0x6e, 0x0c, 0x4e,
0xf4, 0x66, 0x72, 0x9a, 0x17, 0xa1, 0xce, 0x3f, 0x45, 0x60, 0x85, 0x5b, 0x70, 0x13, 0x49, 0xc2, 0x1d, 0x37, 0x89, 0x69, 0x5f, 0xc6, 0x31, 0xab, 0x02, 0xd3, 0xbe, 0xd4, 0x31, 0x1f, 0xc1, 0xc6,
0xd0, 0x9b, 0x79, 0x13, 0xef, 0xec, 0x2a, 0xa6, 0xc5, 0xfe, 0xe7, 0x39, 0x58, 0x89, 0xa5, 0x0a, 0x94, 0x8e, 0x1d, 0x3b, 0x5e, 0xac, 0x15, 0x31, 0x87, 0xab, 0x3c, 0x59, 0xcb, 0x33, 0xe0, 0xda,
0xf2, 0xfa, 0x09, 0xa7, 0x67, 0xea, 0x52, 0x76, 0x2e, 0x76, 0x23, 0x8f, 0xcd, 0x17, 0x47, 0xe4, 0x04, 0x36, 0x1a, 0x3f, 0xf2, 0xa6, 0x27, 0x0e, 0xe7, 0x59, 0xb8, 0x5f, 0x60, 0xd1, 0x5c, 0x74,
0xc4, 0x4c, 0x5e, 0xd4, 0x6e, 0x47, 0x91, 0xc7, 0x64, 0x46, 0x4e, 0x52, 0x5a, 0x69, 0x92, 0x22, 0xe7, 0xd3, 0x9f, 0x47, 0x30, 0xcb, 0x12, 0x18, 0x0d, 0xa8, 0x0d, 0x42, 0x6f, 0x26, 0xa7, 0x79,
0xf2, 0xcb, 0x98, 0x64, 0xb2, 0x88, 0x9f, 0x11, 0x17, 0x28, 0xc7, 0xa2, 0xcb, 0x85, 0xf8, 0x15, 0x11, 0xea, 0xfc, 0x53, 0x44, 0x7b, 0xb8, 0x05, 0x37, 0x91, 0x24, 0x0c, 0xbd, 0x99, 0x37, 0xf1,
0x2b, 0x5d, 0xe3, 0x2d, 0x5b, 0x10, 0xa9, 0xc1, 0x03, 0xe3, 0x77, 0xf3, 0x00, 0x51, 0xeb, 0xf0, 0xce, 0xae, 0x62, 0xaa, 0xf5, 0x7f, 0x95, 0x83, 0x95, 0x58, 0xaa, 0x20, 0xaf, 0x1f, 0x73, 0x7a,
0x92, 0x97, 0xe2, 0x5b, 0x72, 0xe8, 0x4d, 0xaf, 0xf1, 0x28, 0x6f, 0x41, 0x5d, 0x5d, 0xbc, 0x88, 0xa6, 0x6e, 0x8a, 0xe7, 0x62, 0xd7, 0x04, 0xd9, 0x7c, 0x71, 0x44, 0x4e, 0xcc, 0xe4, 0xed, 0xf1,
0x38, 0xa1, 0x9a, 0x84, 0x31, 0x76, 0xe8, 0x7d, 0x58, 0x3a, 0x9b, 0x78, 0x27, 0xc8, 0xb1, 0x0a, 0x76, 0x14, 0x0e, 0x4d, 0x66, 0xe4, 0x24, 0xa5, 0x95, 0x26, 0x29, 0x22, 0xbf, 0x0c, 0x94, 0x26,
0xbe, 0x05, 0x7d, 0x68, 0xf0, 0x3c, 0x5a, 0xe4, 0x49, 0x2a, 0x76, 0xa0, 0xe2, 0x9d, 0x8a, 0x99, 0x8b, 0xf8, 0x19, 0x71, 0xab, 0x73, 0x2c, 0xba, 0x5c, 0x88, 0xdf, 0xfb, 0xd2, 0xd5, 0xf0, 0xb2,
0xf7, 0x33, 0x62, 0x9c, 0xd0, 0x97, 0x29, 0x4e, 0xe8, 0x4e, 0x6a, 0x70, 0x7f, 0x3a, 0x6c, 0xd0, 0x05, 0x91, 0x6e, 0x3e, 0x30, 0x7e, 0x37, 0x0f, 0x10, 0xb5, 0x0e, 0x6f, 0x9e, 0x29, 0xbe, 0x25,
0x5f, 0xce, 0x2b, 0x5f, 0xf3, 0x68, 0x5e, 0x5e, 0x2e, 0x6c, 0xfe, 0x24, 0x9e, 0x71, 0x2f, 0x33, 0x87, 0x2e, 0xfe, 0x1a, 0x8f, 0xf2, 0x06, 0xd4, 0xd5, 0x6d, 0x90, 0x88, 0x13, 0xaa, 0x49, 0x18,
0xf5, 0x7f, 0x09, 0x8b, 0x3e, 0x3f, 0x22, 0xe5, 0xf9, 0x59, 0x7c, 0xc9, 0xf9, 0xd9, 0xf0, 0x63, 0x63, 0x87, 0xde, 0x85, 0xa5, 0xb3, 0x89, 0x77, 0x82, 0x1c, 0xab, 0xe0, 0x5b, 0xd0, 0xb1, 0x07,
0x7c, 0xd7, 0xb7, 0xa1, 0x69, 0x8f, 0x2f, 0xa8, 0x1f, 0x3a, 0x68, 0x39, 0x43, 0x6e, 0x5d, 0x78, 0xcf, 0xa3, 0x45, 0x9e, 0xa4, 0x02, 0x1a, 0x2a, 0xde, 0xa9, 0x98, 0x79, 0x69, 0x24, 0xc6, 0x09,
0x76, 0x6b, 0x70, 0x64, 0x8b, 0xdf, 0x83, 0x25, 0x11, 0x7a, 0x44, 0x61, 0x8a, 0x98, 0x9c, 0x11, 0x7d, 0x91, 0xe2, 0x84, 0xee, 0xa4, 0x06, 0xf7, 0xa7, 0xc3, 0x06, 0xfd, 0xb5, 0xbc, 0x72, 0x80,
0x98, 0x21, 0x1a, 0x7f, 0x5f, 0x3a, 0xb7, 0xc7, 0xd7, 0xda, 0xcb, 0x47, 0x45, 0xef, 0x61, 0x3e, 0x8f, 0xe6, 0xe5, 0xc5, 0x12, 0xf0, 0x8f, 0xe3, 0xae, 0xf7, 0x22, 0xff, 0x83, 0x2f, 0x60, 0xd1,
0xed, 0xcc, 0x20, 0x96, 0xb5, 0x30, 0xc8, 0x09, 0xea, 0xc8, 0x81, 0xc2, 0x1c, 0x17, 0x1f, 0xd6, 0xe7, 0x47, 0xa4, 0x3c, 0x3f, 0x8b, 0x2f, 0x38, 0x3f, 0x1b, 0x7e, 0x8c, 0xef, 0xfa, 0x36, 0x34,
0xe2, 0xeb, 0x0c, 0xab, 0xf1, 0x2f, 0x72, 0x50, 0xde, 0xf7, 0x66, 0xfb, 0x0e, 0xbf, 0x22, 0x85, 0xed, 0xf1, 0x05, 0xf5, 0x43, 0x07, 0xcd, 0x79, 0xc8, 0xad, 0x0b, 0x77, 0x73, 0x0d, 0x8e, 0x6c,
0x9b, 0x56, 0xd9, 0x8b, 0x17, 0xd8, 0x27, 0xba, 0xf1, 0xbd, 0xe4, 0xea, 0x74, 0x26, 0xd3, 0xd9, 0xf1, 0x3b, 0xb0, 0x24, 0xe2, 0xa1, 0x28, 0x4c, 0x11, 0x28, 0x34, 0x02, 0x33, 0x44, 0xe3, 0x1f,
0x88, 0x33, 0x9d, 0xdf, 0x83, 0x5b, 0x68, 0x8e, 0xf7, 0xbd, 0x99, 0xe7, 0x33, 0xc2, 0x61, 0x4f, 0x49, 0x8f, 0xfb, 0xf8, 0x5a, 0x7b, 0xf1, 0xa8, 0xe8, 0x3d, 0xcc, 0xa7, 0x3d, 0x2c, 0xc4, 0xb2,
0x38, 0xf3, 0xe9, 0xb9, 0xe1, 0xb9, 0xa4, 0xe4, 0x37, 0x4f, 0x29, 0x3d, 0xd2, 0x30, 0x0e, 0x15, 0x16, 0x56, 0x42, 0x41, 0x1d, 0x39, 0x50, 0xd8, 0x08, 0xe3, 0xc3, 0x5a, 0x7c, 0x95, 0x61, 0x35,
0x02, 0x86, 0x4d, 0x98, 0x84, 0x17, 0x16, 0xd7, 0x17, 0x08, 0xee, 0x98, 0xd3, 0xf7, 0x25, 0x96, 0xfe, 0x75, 0x0e, 0xca, 0xfb, 0xde, 0x6c, 0xdf, 0xe1, 0xf7, 0xb6, 0x70, 0xd3, 0x2a, 0x23, 0xf6,
0xd0, 0x41, 0x38, 0xf2, 0xc7, 0xc6, 0xe7, 0x50, 0x55, 0xaa, 0x27, 0xf2, 0x3e, 0x54, 0xcf, 0xbd, 0x02, 0xfb, 0x44, 0xdf, 0xc2, 0x17, 0xdc, 0xe7, 0xce, 0x64, 0x3a, 0x1b, 0x71, 0xa6, 0xf3, 0xbb,
0x99, 0xd0, 0x4f, 0xe5, 0x62, 0xd7, 0xcb, 0x45, 0xaf, 0xcd, 0xca, 0x39, 0xff, 0x11, 0x18, 0xff, 0x70, 0x0b, 0x7d, 0x04, 0x7c, 0x6f, 0xe6, 0xf9, 0x8c, 0x70, 0xd8, 0x13, 0xce, 0x7c, 0x7a, 0x6e,
0xa7, 0x0c, 0xe5, 0xae, 0x7b, 0xe1, 0x39, 0x23, 0x74, 0x7b, 0x9f, 0xd2, 0xa9, 0x27, 0xa3, 0x29, 0x78, 0x2e, 0x29, 0xf9, 0xcd, 0x53, 0x4a, 0x8f, 0x34, 0x8c, 0x43, 0x85, 0x80, 0xb1, 0x1c, 0x26,
0xb1, 0xdf, 0xe8, 0x69, 0x19, 0x85, 0xcd, 0x2c, 0x08, 0x4f, 0x4b, 0x15, 0x30, 0x73, 0x0d, 0x16, 0xe1, 0x85, 0xc5, 0x95, 0x18, 0x82, 0x3b, 0xe6, 0xf4, 0x7d, 0x89, 0x25, 0x74, 0x10, 0x8e, 0xfc,
0x7c, 0x3d, 0xee, 0x65, 0xc9, 0xc7, 0x4b, 0x45, 0xea, 0xf4, 0x2e, 0x69, 0x51, 0xb1, 0x58, 0x59, 0xb1, 0xf1, 0x19, 0x54, 0x95, 0x3e, 0x8c, 0xbc, 0x0b, 0xd5, 0x73, 0x6f, 0x26, 0x94, 0x66, 0xb9,
0xdc, 0xd3, 0x18, 0x87, 0x8c, 0x87, 0x3e, 0xa8, 0x22, 0x04, 0x07, 0xec, 0x0d, 0x28, 0x0b, 0x2d, 0xd8, 0x9d, 0x77, 0xd1, 0x6b, 0xb3, 0x72, 0xce, 0x7f, 0x04, 0xc6, 0xff, 0x2b, 0x43, 0xb9, 0xeb,
0x34, 0xbf, 0x5b, 0xca, 0x75, 0xf7, 0x02, 0x84, 0xab, 0xc1, 0xa7, 0xdc, 0x9d, 0x42, 0xb1, 0xd5, 0x5e, 0x78, 0xce, 0x08, 0x7d, 0xf1, 0xa7, 0x74, 0xea, 0xc9, 0x10, 0x4f, 0xec, 0x37, 0x8a, 0xda,
0x05, 0xb3, 0x2e, 0x81, 0xbb, 0x36, 0xf7, 0x65, 0xe7, 0xf8, 0x1c, 0x85, 0x1f, 0x43, 0xc0, 0x41, 0x51, 0x2c, 0xcf, 0x82, 0x10, 0xb5, 0x55, 0x14, 0xcf, 0x35, 0x58, 0xf0, 0xf5, 0x60, 0x9c, 0x25,
0x88, 0x90, 0x11, 0x61, 0xb6, 0x9a, 0x19, 0x61, 0x16, 0xef, 0x3e, 0x28, 0x9a, 0xcf, 0xbb, 0x08, 0x1f, 0x6f, 0x3a, 0xa9, 0xd3, 0xbb, 0xa4, 0x85, 0xea, 0x62, 0x65, 0x71, 0xf7, 0x67, 0x1c, 0x32,
0x3c, 0x68, 0xa8, 0x06, 0x97, 0x01, 0x9d, 0x85, 0x86, 0x87, 0x47, 0x05, 0x91, 0x1a, 0x9e, 0xb7, 0x1e, 0x8f, 0xa1, 0x8a, 0x10, 0x1c, 0xb0, 0xd7, 0xa0, 0x2c, 0x54, 0xe3, 0xfc, 0xc2, 0x2b, 0x37,
0xa1, 0x71, 0x6a, 0x4f, 0x26, 0x27, 0xf6, 0xe8, 0x39, 0x57, 0x4c, 0xd4, 0xb9, 0x2e, 0x56, 0x02, 0x28, 0x08, 0x10, 0xae, 0x06, 0x9f, 0x72, 0x1f, 0x0f, 0xc5, 0x56, 0x17, 0xcc, 0xba, 0x04, 0xee,
0x51, 0x33, 0x71, 0x07, 0x6a, 0xda, 0x2c, 0xa3, 0x8b, 0x77, 0xd1, 0x84, 0x68, 0x7e, 0x93, 0xfa, 0xda, 0xdc, 0xc1, 0x9e, 0xe3, 0x73, 0x14, 0x7e, 0x0c, 0x01, 0x07, 0x21, 0x42, 0x46, 0xd8, 0xdb,
0xc6, 0xc5, 0xd7, 0xd0, 0x37, 0x6a, 0xae, 0xee, 0x4b, 0x71, 0x57, 0xf7, 0x5b, 0x48, 0xdb, 0x85, 0x6a, 0x66, 0xd8, 0x5b, 0xbc, 0x90, 0xa1, 0x68, 0x3e, 0xef, 0x22, 0xf0, 0x48, 0xa6, 0x1a, 0x5c,
0x03, 0x71, 0x93, 0x47, 0xa8, 0xb4, 0xc7, 0x63, 0x1e, 0xa7, 0xe7, 0x2d, 0xa8, 0x8b, 0xc1, 0xe3, 0x46, 0x99, 0x16, 0x6a, 0x27, 0x1e, 0xaa, 0x44, 0xaa, 0x9d, 0xde, 0x84, 0xc6, 0xa9, 0x3d, 0x99,
0xe9, 0xcb, 0xe2, 0xae, 0x00, 0xc2, 0x38, 0xca, 0x6d, 0xae, 0x34, 0x9f, 0xd9, 0xce, 0x18, 0x6f, 0x9c, 0xd8, 0xa3, 0x67, 0x5c, 0xf9, 0x51, 0xe7, 0x0a, 0x62, 0x09, 0x44, 0xed, 0xc7, 0x1d, 0xa8,
0x72, 0x09, 0xfb, 0x8a, 0x3d, 0x0d, 0x8f, 0x6c, 0x07, 0x5d, 0x27, 0x65, 0x32, 0x9e, 0xd5, 0x2b, 0x69, 0xb3, 0x8c, 0x7e, 0xe7, 0x45, 0x13, 0xa2, 0xf9, 0x4d, 0x2a, 0x41, 0x17, 0x5f, 0x41, 0x09,
0x7c, 0xfc, 0x45, 0xf2, 0x80, 0xc7, 0xbc, 0x51, 0x18, 0x53, 0x15, 0xd6, 0xc3, 0xac, 0x09, 0x14, 0xaa, 0xf9, 0xdf, 0x2f, 0xc5, 0xfd, 0xef, 0x6f, 0x21, 0x6d, 0x17, 0x0a, 0x90, 0x26, 0x0f, 0x9b,
0x5c, 0x07, 0x1f, 0xa1, 0xc7, 0x5d, 0x48, 0x31, 0x70, 0xc7, 0xa2, 0x32, 0x2f, 0x89, 0x55, 0x2a, 0x69, 0x8f, 0xb9, 0xfa, 0x03, 0x75, 0x7d, 0x7c, 0xf0, 0x78, 0xfa, 0xb2, 0xb8, 0xc0, 0x80, 0x30,
0xff, 0x73, 0x43, 0x35, 0xc7, 0x64, 0xac, 0x26, 0xb7, 0x97, 0xaf, 0xc7, 0xb8, 0x71, 0x81, 0x8a, 0x8e, 0x72, 0x9b, 0x6b, 0xf2, 0x67, 0xb6, 0x33, 0xc6, 0xeb, 0x65, 0xc2, 0xe8, 0x63, 0x4f, 0xc3,
0xf6, 0x72, 0x8e, 0x40, 0x3e, 0xd7, 0xce, 0x90, 0x16, 0x22, 0xbf, 0x91, 0x28, 0xff, 0xba, 0xbb, 0x23, 0xdb, 0x41, 0x7f, 0x4e, 0x99, 0x8c, 0x67, 0xf5, 0x0a, 0x1f, 0x7f, 0x91, 0x3c, 0xe0, 0x81,
0xb3, 0xb7, 0x01, 0x9c, 0x80, 0x9d, 0x79, 0x01, 0x75, 0xc7, 0x18, 0x7f, 0xa3, 0x62, 0x56, 0x9d, 0x78, 0x14, 0xc6, 0x54, 0xc5, 0x1a, 0x31, 0x6b, 0x02, 0x05, 0xd7, 0xc1, 0x87, 0xe8, 0x06, 0x18,
0xe0, 0x09, 0x07, 0xa4, 0xb4, 0x50, 0x9b, 0xe9, 0x20, 0xb8, 0xdf, 0xe8, 0x11, 0xd4, 0x86, 0xba, 0x52, 0x8c, 0x26, 0xb2, 0xa8, 0x6c, 0x5e, 0x62, 0x95, 0xca, 0xff, 0xdc, 0x7a, 0xce, 0x31, 0x19,
0x3e, 0x12, 0xa4, 0x02, 0xc5, 0xfe, 0x51, 0xa7, 0xd7, 0xbc, 0x41, 0x6a, 0x50, 0x1e, 0x74, 0x86, 0xab, 0xc9, 0x8d, 0xf8, 0xeb, 0x31, 0x6e, 0x5c, 0xa0, 0xa2, 0x11, 0x9f, 0x23, 0x90, 0xcf, 0xb4,
0xc3, 0x03, 0x34, 0xcc, 0xd7, 0xa1, 0xa2, 0x2e, 0xe0, 0xe7, 0xd9, 0x57, 0x7b, 0x67, 0xa7, 0x73, 0x33, 0xa4, 0x85, 0xc8, 0xaf, 0x25, 0xca, 0xbf, 0xee, 0x42, 0xef, 0x6d, 0x00, 0x27, 0x60, 0x67,
0x34, 0xec, 0xec, 0x36, 0x0b, 0x3f, 0x28, 0x56, 0xf2, 0xcd, 0x82, 0xf1, 0xbf, 0x0a, 0x50, 0xd3, 0x5e, 0x40, 0xdd, 0x31, 0x06, 0x05, 0xa9, 0x98, 0x55, 0x27, 0x78, 0xc2, 0x01, 0x29, 0x4d, 0xd7,
0x06, 0xea, 0xe5, 0xf4, 0x3a, 0x1e, 0xea, 0x29, 0x9f, 0x0c, 0xf5, 0xa4, 0x1b, 0x55, 0x44, 0x38, 0x66, 0x3a, 0x32, 0xef, 0x37, 0x7a, 0x04, 0xb5, 0xa1, 0xae, 0x8f, 0x04, 0xa9, 0x40, 0xb1, 0x7f,
0x2c, 0x69, 0x54, 0x79, 0x1b, 0x1a, 0x22, 0x7e, 0xa6, 0xe6, 0x5e, 0x51, 0x32, 0xeb, 0x1c, 0x28, 0xd4, 0xe9, 0x35, 0x6f, 0x90, 0x1a, 0x94, 0x07, 0x9d, 0xe1, 0xf0, 0x00, 0xbd, 0x05, 0xea, 0x50,
0xa8, 0x39, 0x86, 0xf3, 0x40, 0x24, 0xbc, 0x28, 0x5d, 0x12, 0xeb, 0x07, 0x41, 0x78, 0x55, 0x1a, 0x51, 0x51, 0x01, 0xf2, 0xec, 0xab, 0xbd, 0xb3, 0xd3, 0x39, 0x1a, 0x76, 0x76, 0x9b, 0x85, 0xef,
0xef, 0xb9, 0x07, 0xde, 0xe4, 0x82, 0x72, 0x0c, 0xce, 0xc2, 0xd6, 0x04, 0x6c, 0x28, 0x42, 0xa5, 0x17, 0x2b, 0xf9, 0x66, 0xc1, 0xf8, 0x3f, 0x05, 0xa8, 0x69, 0x03, 0xf5, 0x62, 0x7a, 0x1d, 0x8f,
0x08, 0x92, 0xa9, 0xc5, 0x93, 0x28, 0x99, 0x75, 0x0e, 0x14, 0x15, 0x7d, 0x20, 0xd7, 0x18, 0x77, 0x3f, 0x95, 0x4f, 0xc6, 0x9f, 0xd2, 0x2d, 0x3d, 0x22, 0x46, 0x97, 0xb4, 0xf4, 0xbc, 0x09, 0x0d,
0x36, 0xdb, 0x48, 0x2f, 0x98, 0xd8, 0xfa, 0x3a, 0x48, 0xe9, 0x3d, 0xab, 0xb8, 0x76, 0xbe, 0x95, 0x11, 0xd4, 0x53, 0xf3, 0xf9, 0x28, 0x99, 0x75, 0x0e, 0x14, 0xd4, 0x1c, 0x63, 0x8c, 0x20, 0x12,
0xce, 0xf7, 0x6a, 0xfd, 0x27, 0x79, 0x1f, 0xc8, 0x74, 0x36, 0xb3, 0x32, 0x34, 0x92, 0x45, 0x73, 0xde, 0xde, 0x2e, 0x89, 0xf5, 0x83, 0x20, 0xbc, 0xbf, 0x8d, 0x97, 0xef, 0x03, 0x6f, 0x72, 0x41,
0x69, 0x3a, 0x9b, 0x0d, 0x35, 0x85, 0x1d, 0x79, 0x03, 0x0a, 0xf6, 0x74, 0x86, 0xa4, 0x25, 0xd2, 0x39, 0x06, 0x67, 0x61, 0x6b, 0x02, 0x36, 0x14, 0xf1, 0x5b, 0x04, 0xc9, 0xd4, 0x82, 0x5c, 0x94,
0x0e, 0xb6, 0x0f, 0x8f, 0x4c, 0x06, 0xfe, 0x06, 0x54, 0xa9, 0xbf, 0x99, 0x83, 0x42, 0xfb, 0xf0, 0xcc, 0x3a, 0x07, 0x8a, 0x8a, 0xde, 0x97, 0x6b, 0x8c, 0x7b, 0xc0, 0x6d, 0xa4, 0x17, 0x4c, 0x6c,
0x08, 0x09, 0xbd, 0xe7, 0x85, 0x56, 0x70, 0x6e, 0x8b, 0x68, 0x6e, 0x8c, 0xd0, 0x7b, 0x5e, 0x38, 0x7d, 0x1d, 0xa4, 0x74, 0xab, 0x55, 0x5c, 0x3b, 0xdf, 0x4a, 0xe7, 0x7b, 0xb9, 0x8e, 0x95, 0xbc,
0x60, 0x00, 0x46, 0xe8, 0x03, 0x1a, 0x46, 0x4e, 0xd3, 0xa5, 0x80, 0x86, 0xdc, 0x83, 0x7e, 0x74, 0x0b, 0x64, 0x3a, 0x9b, 0x59, 0x19, 0x5a, 0xcf, 0xa2, 0xb9, 0x34, 0x9d, 0xcd, 0x86, 0x9a, 0xc2,
0xee, 0x4c, 0xc6, 0xb1, 0x40, 0xa0, 0x80, 0x20, 0xbe, 0x22, 0x08, 0x14, 0xb5, 0xe3, 0x01, 0x7f, 0x8e, 0xbc, 0x06, 0x05, 0x7b, 0x3a, 0x43, 0xd2, 0x12, 0x69, 0x07, 0xdb, 0x87, 0x47, 0x26, 0x03,
0xf3, 0x9b, 0x87, 0xe2, 0x44, 0xe1, 0x7e, 0xf9, 0xea, 0xdb, 0xf8, 0x2b, 0x39, 0x20, 0x6d, 0x46, 0x7f, 0x03, 0xea, 0xda, 0xdf, 0xcc, 0x41, 0xa1, 0x7d, 0x78, 0xf4, 0x67, 0xa4, 0x53, 0xc5, 0x80,
0x91, 0x70, 0x40, 0x95, 0xa4, 0x1b, 0x9d, 0x33, 0x39, 0xfd, 0x9c, 0xc9, 0x20, 0xe7, 0xf9, 0x4c, 0xa3, 0xd1, 0xf1, 0x80, 0xbf, 0xf9, 0x75, 0x48, 0x71, 0xa2, 0xf0, 0xcb, 0x02, 0xea, 0xdb, 0xf8,
0x72, 0xfe, 0x2a, 0xc2, 0x17, 0xdb, 0xba, 0xcb, 0xa9, 0xad, 0x6b, 0xec, 0x41, 0xed, 0x48, 0x8b, 0xeb, 0x39, 0x20, 0x6d, 0x46, 0x91, 0x70, 0x40, 0x95, 0xa4, 0x1b, 0x9d, 0x33, 0x39, 0xfd, 0x9c,
0xcb, 0x7c, 0x97, 0x9d, 0x8a, 0x32, 0x22, 0x33, 0x3f, 0x2f, 0xb9, 0x56, 0xd7, 0x17, 0x81, 0x98, 0xc9, 0x20, 0xe7, 0xf9, 0x4c, 0x72, 0xfe, 0x32, 0xc2, 0x17, 0xdb, 0xba, 0xcb, 0xa9, 0xad, 0x6b,
0xb5, 0x06, 0xe7, 0xb5, 0x06, 0x1b, 0x7f, 0x2b, 0xc7, 0xa3, 0x13, 0xaa, 0xfe, 0x45, 0xa1, 0xa0, 0xec, 0x41, 0xed, 0x48, 0x0b, 0x16, 0x7d, 0x97, 0x9d, 0x8a, 0x32, 0x4c, 0x34, 0x3f, 0x2f, 0xb9,
0xa5, 0x71, 0x34, 0x8a, 0x63, 0x53, 0x93, 0xe6, 0x4f, 0x11, 0x82, 0x06, 0x5b, 0x6f, 0x79, 0xa7, 0x56, 0xd7, 0x17, 0xd1, 0xa1, 0xb5, 0x06, 0xe7, 0xb5, 0x06, 0x1b, 0x7f, 0x37, 0xc7, 0x43, 0x26,
0xa7, 0x01, 0x95, 0x3e, 0x66, 0x35, 0x84, 0xf5, 0x11, 0x24, 0xc5, 0x1f, 0x26, 0x63, 0x39, 0xbc, 0xaa, 0xfe, 0x45, 0xf1, 0xa9, 0xa5, 0xc5, 0x36, 0x0a, 0xae, 0x53, 0x93, 0x36, 0x59, 0x11, 0x17,
0xfc, 0x40, 0x38, 0x96, 0x31, 0xf1, 0xe7, 0xd0, 0xbe, 0x14, 0xb5, 0x06, 0x6c, 0x06, 0x84, 0x85, 0x07, 0x5b, 0x6f, 0x79, 0xa7, 0xa7, 0x01, 0x95, 0x8e, 0x6f, 0x35, 0x84, 0xf5, 0x11, 0x24, 0xc5,
0x46, 0xc6, 0x71, 0x50, 0xdf, 0xc6, 0x5f, 0x17, 0xa1, 0x76, 0x92, 0x53, 0x70, 0x1f, 0x2a, 0xaa, 0x1f, 0x26, 0x63, 0x39, 0xbc, 0xfc, 0x40, 0x78, 0xbb, 0x31, 0xf1, 0xe7, 0xd0, 0xbe, 0x14, 0xb5,
0xd4, 0x38, 0x57, 0x21, 0x31, 0x55, 0x3a, 0xe3, 0x5d, 0x50, 0x1d, 0x15, 0x6b, 0x31, 0xa7, 0x16, 0x06, 0x6c, 0x06, 0x84, 0xd9, 0x48, 0x06, 0x97, 0x50, 0xdf, 0xc6, 0xdf, 0x12, 0xf1, 0x7f, 0x92,
0x68, 0x65, 0xeb, 0x6a, 0xad, 0xfe, 0x0e, 0x90, 0x53, 0xc7, 0x4f, 0x22, 0x73, 0xea, 0xd1, 0xc4, 0x53, 0x70, 0x1f, 0x2a, 0xaa, 0xd4, 0x38, 0x57, 0x21, 0x31, 0x55, 0x3a, 0xe3, 0x5d, 0x50, 0x1d,
0x14, 0x0d, 0xdb, 0x38, 0x86, 0x15, 0x49, 0xf6, 0x34, 0x99, 0x2c, 0x3e, 0xbf, 0xb9, 0x57, 0x1c, 0x15, 0x6b, 0x31, 0xa7, 0x16, 0x68, 0xfa, 0xeb, 0x6a, 0xad, 0x7e, 0x0f, 0xc8, 0xa9, 0xe3, 0x27,
0x6c, 0xf9, 0xd4, 0xc1, 0x66, 0xfc, 0x46, 0x09, 0xca, 0x32, 0x0c, 0x7a, 0x56, 0x5c, 0xee, 0x6a, 0x91, 0x39, 0xf5, 0x68, 0x62, 0x8a, 0x86, 0x6d, 0x1c, 0xc3, 0x8a, 0x24, 0x7b, 0x9a, 0x4c, 0x16,
0x3c, 0x2e, 0x77, 0x2b, 0x16, 0xf5, 0x13, 0xa7, 0x5e, 0xf0, 0x38, 0xef, 0x25, 0xd9, 0x14, 0xcd, 0x9f, 0xdf, 0xdc, 0x4b, 0x0e, 0xb6, 0x7c, 0xea, 0x60, 0x33, 0x7e, 0xa3, 0x04, 0x65, 0x19, 0x9b,
0x5a, 0x14, 0x63, 0x55, 0x84, 0xb5, 0xa8, 0x14, 0xb7, 0x16, 0x65, 0xc5, 0x2a, 0xe7, 0xec, 0x76, 0x3d, 0x2b, 0x58, 0x78, 0x35, 0x1e, 0x2c, 0xbc, 0x15, 0x0b, 0x45, 0x8a, 0x53, 0x2f, 0x78, 0x9c,
0x2a, 0x56, 0xf9, 0x2d, 0xe0, 0xbc, 0x93, 0xe6, 0x5c, 0x5b, 0x41, 0x80, 0x88, 0x45, 0xa2, 0xb1, 0x77, 0x92, 0x6c, 0x8a, 0x66, 0xc2, 0x8a, 0xb1, 0x2a, 0xc2, 0x84, 0x55, 0x8a, 0x9b, 0xb0, 0xb2,
0x5a, 0x95, 0x24, 0xab, 0xf5, 0xda, 0x6c, 0xd0, 0x27, 0xb0, 0xc0, 0xc3, 0x76, 0x89, 0xb8, 0x14, 0x02, 0xa8, 0x73, 0x76, 0x3b, 0x15, 0x40, 0xfd, 0x16, 0x70, 0xde, 0x49, 0xf3, 0xf8, 0xad, 0x20,
0xf2, 0xb0, 0x14, 0x63, 0x25, 0xff, 0xf3, 0x3b, 0x5b, 0xa6, 0xc0, 0xd5, 0x43, 0xdb, 0xd6, 0x62, 0x40, 0x04, 0x48, 0xd1, 0x58, 0xad, 0x4a, 0x92, 0xd5, 0x7a, 0x65, 0x36, 0xe8, 0x63, 0x58, 0xe0,
0xa1, 0x6d, 0x75, 0x2b, 0x56, 0x3d, 0x6e, 0xc5, 0xba, 0x07, 0x4d, 0x35, 0x70, 0xa8, 0x13, 0x76, 0xb1, 0xc4, 0x44, 0xb0, 0x0c, 0x79, 0x58, 0x8a, 0xb1, 0x92, 0xff, 0xf9, 0x45, 0x32, 0x53, 0xe0,
0x03, 0x71, 0x05, 0x7d, 0x51, 0xc2, 0x19, 0x79, 0xef, 0x05, 0xd1, 0x61, 0xbf, 0x18, 0x3b, 0xec, 0xea, 0xf1, 0x76, 0x6b, 0xb1, 0x78, 0xbb, 0xba, 0x69, 0xad, 0x1e, 0x37, 0xad, 0xdd, 0x83, 0xa6,
0x19, 0xf1, 0x6d, 0x87, 0x21, 0x9d, 0xce, 0x42, 0x79, 0xd8, 0x6b, 0xe1, 0xe1, 0xf9, 0xcc, 0xf3, 0x1a, 0x38, 0xd4, 0x09, 0xbb, 0x81, 0xb8, 0x17, 0xbf, 0x28, 0xe1, 0x8c, 0xbc, 0xf7, 0x82, 0xe8,
0x3b, 0x6d, 0x72, 0x7a, 0xf9, 0xea, 0xd8, 0x86, 0xc5, 0x53, 0xdb, 0x99, 0xcc, 0x7d, 0x6a, 0xf9, 0xb0, 0x5f, 0x8c, 0x1d, 0xf6, 0x8c, 0xf8, 0xb6, 0xc3, 0x90, 0x4e, 0x67, 0xa1, 0x3c, 0xec, 0xb5,
0xd4, 0x0e, 0x3c, 0x17, 0xe9, 0x43, 0xc4, 0x77, 0x88, 0x2e, 0xee, 0x71, 0x1c, 0x13, 0x51, 0xcc, 0x98, 0xf5, 0x7c, 0xe6, 0xf9, 0x45, 0x3b, 0x39, 0xbd, 0x7c, 0x75, 0x6c, 0xc3, 0xe2, 0xa9, 0xed,
0xc6, 0xa9, 0xfe, 0x89, 0x37, 0x48, 0xf5, 0x91, 0x60, 0x67, 0xb0, 0x88, 0x4e, 0xc1, 0x7d, 0xe5, 0x4c, 0xe6, 0x3e, 0xb5, 0x7c, 0x6a, 0x07, 0x9e, 0x8b, 0xf4, 0x21, 0xe2, 0x3b, 0x44, 0x17, 0xf7,
0xba, 0x3d, 0x6b, 0xef, 0xa0, 0xfb, 0x78, 0x7f, 0xd8, 0xcc, 0xb1, 0xcf, 0xc1, 0xf1, 0xce, 0x4e, 0x38, 0x8e, 0x89, 0x28, 0x66, 0xe3, 0x54, 0xff, 0xc4, 0x6b, 0xad, 0xfa, 0x48, 0xb0, 0x33, 0x58,
0xa7, 0xb3, 0x8b, 0x67, 0x32, 0xc0, 0xc2, 0x5e, 0xbb, 0x7b, 0x20, 0x4e, 0xe4, 0x62, 0xb3, 0x64, 0x84, 0xcc, 0xe0, 0x0e, 0x7c, 0xdd, 0x9e, 0xb5, 0x77, 0xd0, 0x7d, 0xbc, 0x3f, 0x6c, 0xe6, 0xd8,
0xfc, 0x61, 0x1e, 0x6a, 0x5a, 0x6f, 0x30, 0xee, 0x0c, 0xff, 0xc9, 0xe8, 0x6f, 0x59, 0xc4, 0x9d, 0xe7, 0xe0, 0x78, 0x67, 0xa7, 0xd3, 0xd9, 0xc5, 0x33, 0x19, 0x60, 0x61, 0xaf, 0xdd, 0x3d, 0x10,
0xe1, 0x90, 0xee, 0x98, 0x3c, 0x52, 0x73, 0xc4, 0xc3, 0xe5, 0xdc, 0x4e, 0x0f, 0xc8, 0x96, 0x3c, 0x27, 0x72, 0xb1, 0x59, 0x32, 0xfe, 0x30, 0x0f, 0x35, 0xad, 0x37, 0x18, 0x0c, 0x87, 0xff, 0x64,
0xd1, 0xb4, 0x49, 0x52, 0x71, 0xe2, 0xf3, 0xd7, 0xc6, 0x89, 0x27, 0xef, 0xc2, 0x92, 0xac, 0x59, 0xf4, 0xb7, 0x2c, 0x82, 0xe1, 0x70, 0x48, 0x77, 0x4c, 0x1e, 0xa9, 0x39, 0xe2, 0x31, 0x7c, 0x6e,
0xce, 0x89, 0xb0, 0xbe, 0x08, 0xb0, 0x98, 0x92, 0x77, 0x45, 0xe8, 0x1e, 0x71, 0x2c, 0x33, 0xbc, 0xa7, 0x07, 0x64, 0x4b, 0x9e, 0x68, 0xda, 0x24, 0xa9, 0xe0, 0xf5, 0xf9, 0x6b, 0x83, 0xd7, 0x93,
0xa2, 0xf4, 0x29, 0x57, 0x27, 0x33, 0x4e, 0x5d, 0x59, 0x0c, 0x9c, 0xf0, 0x96, 0x50, 0x0c, 0x8e, 0xb7, 0x61, 0x49, 0xd6, 0x2c, 0xe7, 0x44, 0x58, 0x5f, 0x04, 0x58, 0x4c, 0xc9, 0xdb, 0x22, 0x9e,
0x18, 0x4e, 0x99, 0x1c, 0x3b, 0x23, 0x16, 0x12, 0x67, 0xc4, 0xa7, 0x00, 0x51, 0x7f, 0xe2, 0xa3, 0x90, 0x38, 0x96, 0x19, 0x5e, 0x51, 0x3a, 0xba, 0xab, 0x93, 0x19, 0xa7, 0xae, 0x2c, 0x06, 0x4e,
0x7b, 0x23, 0x3e, 0xba, 0x39, 0x6d, 0x74, 0xf3, 0xc6, 0xdf, 0x13, 0x94, 0x4d, 0x4c, 0x95, 0xd2, 0xb8, 0x70, 0x28, 0x06, 0x47, 0x0c, 0xa7, 0x4c, 0x8e, 0x9d, 0x11, 0x0b, 0x89, 0x33, 0xe2, 0x13,
0xc5, 0x7e, 0x00, 0x52, 0x3b, 0x6c, 0xe1, 0x1d, 0x94, 0xd9, 0x84, 0x86, 0xf2, 0x82, 0xfd, 0xb2, 0x80, 0xa8, 0x3f, 0xf1, 0xd1, 0xbd, 0x11, 0x1f, 0xdd, 0x9c, 0x36, 0xba, 0x79, 0xe3, 0x1f, 0x0a,
0x48, 0xe9, 0xaa, 0x84, 0x14, 0x25, 0xce, 0xa7, 0x29, 0xf1, 0x5b, 0x50, 0xc7, 0x58, 0x90, 0xa2, 0xca, 0x26, 0xa6, 0x4a, 0xe9, 0x62, 0xdf, 0x07, 0xa9, 0x1d, 0xb6, 0xf0, 0x62, 0xcc, 0x6c, 0x42,
0x22, 0x19, 0x8c, 0x79, 0x6a, 0x5f, 0xca, 0xba, 0x63, 0x24, 0xb8, 0x98, 0x20, 0xc1, 0x7f, 0x23, 0x43, 0x79, 0xeb, 0x7f, 0x59, 0xa4, 0x74, 0x55, 0x42, 0x8a, 0x12, 0xe7, 0xd3, 0x94, 0xf8, 0x0d,
0xc7, 0x03, 0x87, 0x45, 0x0d, 0x8d, 0x68, 0xb0, 0x2a, 0x33, 0x4e, 0x83, 0x05, 0xaa, 0xa9, 0xd2, 0xa8, 0x63, 0x80, 0x4a, 0x51, 0x91, 0x8c, 0x10, 0x3d, 0xb5, 0x2f, 0x65, 0xdd, 0x31, 0x12, 0x5c,
0xaf, 0xa1, 0xab, 0xf9, 0x6c, 0xba, 0x9a, 0x4d, 0xb1, 0x0b, 0x99, 0x14, 0xdb, 0xb8, 0x84, 0xd6, 0x4c, 0x90, 0xe0, 0xbf, 0x9d, 0xe3, 0xd1, 0xcc, 0xa2, 0x86, 0x46, 0x34, 0x58, 0x95, 0x19, 0xa7,
0x2e, 0x65, 0x43, 0xd1, 0x9e, 0x4c, 0x92, 0x63, 0xf9, 0x00, 0x56, 0xd9, 0x14, 0xa2, 0xab, 0x08, 0xc1, 0x02, 0xd5, 0x54, 0xe9, 0xd7, 0xd0, 0xd5, 0x7c, 0x36, 0x5d, 0xcd, 0xa6, 0xd8, 0x85, 0x4c,
0x4f, 0xd1, 0x4f, 0x34, 0xc2, 0xd3, 0x64, 0x26, 0x3c, 0xd8, 0xee, 0xc3, 0xb2, 0xc8, 0x81, 0x9b, 0x8a, 0x6d, 0x5c, 0x42, 0x6b, 0x97, 0xb2, 0xa1, 0x68, 0x4f, 0x26, 0xc9, 0xb1, 0x7c, 0x00, 0xab,
0x56, 0x8f, 0xd2, 0xb6, 0xc4, 0x13, 0xd0, 0xc5, 0x95, 0xe1, 0x1a, 0xb7, 0xe0, 0x66, 0x46, 0xcd, 0x6c, 0x0a, 0xd1, 0x7f, 0x85, 0xa7, 0xe8, 0x27, 0x1a, 0xe1, 0x69, 0x32, 0x13, 0x1e, 0x6c, 0xf7,
0x42, 0x69, 0xf7, 0x9b, 0x39, 0x58, 0x6b, 0xf3, 0x68, 0x44, 0xdf, 0xd8, 0xfd, 0xfa, 0x2f, 0xe0, 0x61, 0x59, 0xe4, 0xc0, 0x4d, 0xab, 0x87, 0x8e, 0x5b, 0xe2, 0x09, 0xe8, 0x77, 0xcb, 0x70, 0x8d,
0xa6, 0xba, 0xae, 0xa2, 0x5d, 0xb3, 0xd5, 0x1b, 0x29, 0x6f, 0xba, 0x68, 0x97, 0xb4, 0xb0, 0xad, 0x5b, 0x70, 0x33, 0xa3, 0x66, 0xa1, 0xb4, 0xfb, 0xcd, 0x1c, 0xac, 0xb5, 0x79, 0x88, 0xa4, 0x6f,
0x2d, 0x58, 0x4f, 0xb6, 0x46, 0x34, 0x74, 0x0f, 0x96, 0x77, 0xe9, 0xc9, 0xfc, 0xec, 0x80, 0x5e, 0xec, 0xd2, 0xff, 0xe7, 0x70, 0x53, 0xdd, 0xa1, 0xd1, 0xee, 0xfe, 0xea, 0x8d, 0x94, 0xd7, 0x6f,
0x44, 0x6d, 0x24, 0x50, 0x0c, 0xce, 0xbd, 0x17, 0x62, 0xa0, 0xf0, 0x37, 0xfa, 0xb3, 0x33, 0x1c, 0xb4, 0x9b, 0x63, 0xd8, 0xd6, 0x16, 0xac, 0x27, 0x5b, 0x23, 0x1a, 0xba, 0x07, 0xcb, 0xbb, 0xf4,
0x2b, 0x98, 0xd1, 0x91, 0x34, 0xfa, 0x20, 0x64, 0x30, 0xa3, 0x23, 0xe3, 0x11, 0x10, 0xbd, 0x1c, 0x64, 0x7e, 0x76, 0x40, 0x2f, 0xa2, 0x36, 0x12, 0x28, 0x06, 0xe7, 0xde, 0x73, 0x31, 0x50, 0xf8,
0xb1, 0x46, 0x98, 0x0c, 0x3c, 0x3f, 0xb1, 0x82, 0xab, 0x20, 0xa4, 0x53, 0x79, 0xd5, 0x1c, 0x82, 0x1b, 0x9d, 0xec, 0x19, 0x8e, 0x15, 0xcc, 0xe8, 0x48, 0x1a, 0x7d, 0x10, 0x32, 0x98, 0xd1, 0x91,
0xf9, 0xc9, 0x80, 0x43, 0x8c, 0xf7, 0xa0, 0x7e, 0x64, 0x5f, 0x99, 0xf4, 0x47, 0xe2, 0xb6, 0xf6, 0xf1, 0x08, 0x88, 0x5e, 0x8e, 0x58, 0x23, 0x4c, 0x06, 0x9e, 0x9f, 0x58, 0xc1, 0x55, 0x10, 0xd2,
0x06, 0x94, 0x67, 0xf6, 0x15, 0x3b, 0x08, 0x94, 0xfd, 0x17, 0x93, 0x8d, 0xdf, 0x2d, 0xc2, 0x02, 0xa9, 0xbc, 0xff, 0x0e, 0xc1, 0xfc, 0x64, 0xc0, 0x21, 0xc6, 0x3b, 0x50, 0x3f, 0xb2, 0xaf, 0x4c,
0xc7, 0x24, 0x77, 0xf9, 0x13, 0x32, 0x8e, 0x8b, 0x84, 0x58, 0x1e, 0x89, 0x1a, 0x28, 0x75, 0x6a, 0xfa, 0x43, 0x71, 0x85, 0x7c, 0x03, 0xca, 0x33, 0xfb, 0x8a, 0x1d, 0x04, 0xca, 0xfe, 0x8b, 0xc9,
0xe6, 0xd3, 0xa7, 0xa6, 0x50, 0x56, 0xcb, 0x50, 0x97, 0xd2, 0x52, 0xe7, 0xce, 0xa7, 0x32, 0xbe, 0xc6, 0xef, 0x16, 0x61, 0x81, 0x63, 0x92, 0xbb, 0xfc, 0x5d, 0x1b, 0xc7, 0x45, 0x42, 0x2c, 0x8f,
0x65, 0x3c, 0xf6, 0x4e, 0x31, 0x7a, 0x94, 0x88, 0xc7, 0x1d, 0x89, 0xfb, 0x52, 0x44, 0x92, 0x36, 0x44, 0x0d, 0x94, 0x3a, 0x35, 0xf3, 0xe9, 0x53, 0x53, 0x28, 0xab, 0x65, 0xfc, 0x4d, 0x69, 0xa9,
0x6f, 0x9d, 0x64, 0x06, 0xc4, 0x81, 0xa9, 0x83, 0x32, 0xc5, 0xf9, 0xb2, 0x0c, 0x65, 0x10, 0x17, 0x73, 0xe7, 0x53, 0x19, 0x74, 0x33, 0x1e, 0x10, 0xa8, 0x18, 0xbd, 0x94, 0xc4, 0x83, 0xa1, 0xc4,
0xe7, 0x53, 0x62, 0x7b, 0xe5, 0xd5, 0x62, 0x3b, 0xd7, 0x62, 0xbf, 0x44, 0x6c, 0x87, 0xd7, 0x10, 0x1d, 0x3c, 0x22, 0x49, 0x9b, 0xb7, 0x4e, 0x32, 0x03, 0xe2, 0xc0, 0xd4, 0x41, 0x99, 0xe2, 0x7c,
0xdb, 0x5f, 0xc3, 0x8f, 0xe1, 0x26, 0x54, 0x90, 0xc3, 0xd3, 0xce, 0x4f, 0xc6, 0xd9, 0xb1, 0xf3, 0x59, 0xc6, 0x57, 0x88, 0x8b, 0xf3, 0x29, 0xb1, 0xbd, 0xf2, 0x72, 0xb1, 0x9d, 0x6b, 0xb1, 0x5f,
0xf3, 0x33, 0x4d, 0xb0, 0xe5, 0x4e, 0x54, 0xda, 0x01, 0x66, 0xd2, 0x1f, 0xfd, 0x74, 0x14, 0xa3, 0x20, 0xb6, 0xc3, 0x2b, 0x88, 0xed, 0xaf, 0xe0, 0x2b, 0x71, 0x13, 0x2a, 0xc8, 0xe1, 0x69, 0xe7,
0xcf, 0xa0, 0x2c, 0xa0, 0x6c, 0x41, 0xbb, 0xf6, 0x54, 0x06, 0x74, 0xc6, 0xdf, 0x6c, 0xd8, 0x30, 0x27, 0xe3, 0xec, 0xd8, 0xf9, 0xf9, 0xa9, 0x26, 0xd8, 0x72, 0xcf, 0x2e, 0xed, 0x00, 0x33, 0xe9,
0xc4, 0xe9, 0x8f, 0xe6, 0x8e, 0x4f, 0xc7, 0x32, 0xd0, 0xa2, 0x83, 0xd4, 0x83, 0x41, 0x58, 0x07, 0x0f, 0x7f, 0x3a, 0x8a, 0xd1, 0xa7, 0x50, 0x16, 0x50, 0xb6, 0xa0, 0x5d, 0x7b, 0x2a, 0xa3, 0x4c,
0x99, 0x90, 0xed, 0xca, 0xd7, 0x23, 0x2a, 0x66, 0xd9, 0x09, 0x9e, 0xb0, 0x4f, 0x83, 0x40, 0x13, 0xe3, 0x6f, 0x36, 0x6c, 0x18, 0x77, 0xf5, 0x87, 0x73, 0xc7, 0xa7, 0x63, 0x19, 0xfd, 0xd1, 0x41,
0xc3, 0xe7, 0xcf, 0x3c, 0x5f, 0xb2, 0x27, 0xc6, 0xef, 0xe5, 0xa0, 0x29, 0x76, 0x97, 0x4a, 0xd3, 0xea, 0xc1, 0x20, 0xac, 0x83, 0x4c, 0xc8, 0x76, 0xe5, 0x93, 0x16, 0x15, 0xb3, 0xec, 0x04, 0x4f,
0x05, 0xd8, 0xd2, 0x75, 0x3e, 0x3f, 0x2f, 0x0f, 0x9b, 0x68, 0x40, 0x03, 0x55, 0x7b, 0x8a, 0x57, 0xd8, 0xa7, 0x41, 0xa0, 0x89, 0x31, 0xfd, 0x67, 0x9e, 0x2f, 0xd9, 0x13, 0xe3, 0xf7, 0x72, 0xd0,
0xe1, 0xaa, 0xc9, 0x1a, 0x03, 0xee, 0x09, 0x7e, 0xe5, 0x4d, 0xa8, 0xc9, 0xdb, 0x36, 0x53, 0x67, 0x14, 0xbb, 0x4b, 0xa5, 0xe9, 0x02, 0x6c, 0xe9, 0x3a, 0x47, 0xa4, 0x17, 0xc7, 0x72, 0x34, 0xa0,
0x22, 0xdf, 0x1f, 0xe3, 0xd7, 0x6d, 0x0e, 0x9d, 0x89, 0x64, 0x75, 0x7c, 0x5b, 0x84, 0xd7, 0xc8, 0x81, 0xaa, 0x3d, 0xc5, 0xab, 0x70, 0xd5, 0x64, 0x8d, 0x01, 0xf7, 0x04, 0xbf, 0xf2, 0x3a, 0xd4,
0x21, 0xab, 0x63, 0xda, 0x21, 0x35, 0xfe, 0x20, 0x07, 0xcb, 0x5a, 0x57, 0xc4, 0xbe, 0xfd, 0x2e, 0xe4, 0x15, 0xa0, 0xa9, 0x33, 0x91, 0x8f, 0xa2, 0xf1, 0x3b, 0x40, 0x87, 0xce, 0x44, 0xb2, 0x3a,
0xd4, 0xd5, 0xab, 0x1e, 0x54, 0xf1, 0xd8, 0x1b, 0x71, 0x1a, 0x15, 0x65, 0xab, 0x8d, 0x14, 0x24, 0xbe, 0x2d, 0x62, 0x7e, 0xe4, 0x90, 0xd5, 0x31, 0xed, 0x90, 0x1a, 0x7f, 0x90, 0x83, 0x65, 0xad,
0x60, 0x8d, 0x19, 0xdb, 0x57, 0xfc, 0x4a, 0xc8, 0x7c, 0x2a, 0xe5, 0xf2, 0xb1, 0x7d, 0xb5, 0x47, 0x2b, 0x62, 0xdf, 0x7e, 0x07, 0xea, 0xea, 0xa9, 0x11, 0xaa, 0x78, 0xec, 0x8d, 0x38, 0x8d, 0x8a,
0xe9, 0x60, 0x3e, 0x25, 0x77, 0xa1, 0xfe, 0x82, 0xd2, 0xe7, 0x0a, 0x81, 0x13, 0x76, 0x60, 0x30, 0xb2, 0xd5, 0x46, 0x0a, 0x12, 0xb0, 0xc6, 0x8c, 0xed, 0x2b, 0x7e, 0x4f, 0x65, 0x3e, 0x95, 0x72,
0x81, 0x61, 0x40, 0x63, 0xea, 0xb9, 0xe1, 0xb9, 0x42, 0x11, 0xf2, 0x05, 0x02, 0x39, 0x8e, 0xf1, 0xf9, 0xd8, 0xbe, 0xda, 0xa3, 0x74, 0x30, 0x9f, 0x92, 0xbb, 0x50, 0x7f, 0x4e, 0xe9, 0x33, 0x85,
0xaf, 0xf2, 0xb0, 0xc2, 0x15, 0xc8, 0xc2, 0x8c, 0x20, 0x48, 0x57, 0x0b, 0x16, 0xb8, 0x56, 0x9f, 0xc0, 0x09, 0x3b, 0x30, 0x98, 0xc0, 0x30, 0xa0, 0x31, 0xf5, 0xdc, 0xf0, 0x5c, 0xa1, 0x08, 0xf9,
0x13, 0xaf, 0xfd, 0x1b, 0xa6, 0xf8, 0x26, 0x9f, 0xbc, 0xa6, 0xd2, 0x5b, 0x46, 0xe6, 0xb8, 0x66, 0x02, 0x81, 0x1c, 0xc7, 0xf8, 0xb7, 0x79, 0x58, 0xe1, 0x0a, 0x64, 0x61, 0x46, 0x10, 0xa4, 0xab,
0xf8, 0x0b, 0xe9, 0xe1, 0xbf, 0x7e, 0x78, 0xb3, 0x9c, 0x0a, 0x4a, 0x59, 0x4e, 0x05, 0xaf, 0x63, 0x05, 0x0b, 0x5c, 0xab, 0xcf, 0x89, 0xd7, 0xfe, 0x0d, 0x53, 0x7c, 0x93, 0x8f, 0x5f, 0x51, 0xe9,
0xca, 0x4f, 0xc5, 0x86, 0x28, 0xa7, 0x63, 0x34, 0x3f, 0x82, 0x8d, 0x18, 0x0e, 0x52, 0x6b, 0xe7, 0x2d, 0xc3, 0x85, 0x5c, 0x33, 0xfc, 0x85, 0xf4, 0xf0, 0x5f, 0x3f, 0xbc, 0x59, 0x4e, 0x05, 0xa5,
0xd4, 0x51, 0x8f, 0x0b, 0xac, 0x6a, 0xd8, 0x03, 0x99, 0xb6, 0x5d, 0x86, 0x52, 0x30, 0xf2, 0x66, 0x2c, 0xa7, 0x82, 0x57, 0x31, 0xe5, 0xa7, 0x02, 0x56, 0x94, 0xd3, 0x81, 0xa3, 0x1f, 0xc1, 0x46,
0xe8, 0x87, 0x1e, 0x1f, 0x55, 0x71, 0x4c, 0xfc, 0x76, 0x0e, 0x5a, 0x7b, 0x51, 0xb0, 0x6b, 0x27, 0x0c, 0x07, 0xa9, 0xb5, 0x73, 0xea, 0xa8, 0x17, 0x0f, 0x56, 0x35, 0xec, 0x81, 0x4c, 0xdb, 0x2e,
0x08, 0x3d, 0x5f, 0xbd, 0xdb, 0x70, 0x1b, 0x80, 0xbf, 0x85, 0x86, 0x6a, 0x10, 0x11, 0xa5, 0x0c, 0x43, 0x29, 0x18, 0x79, 0x33, 0x74, 0x8e, 0x8f, 0x8f, 0xaa, 0x38, 0x26, 0x7e, 0x3b, 0x07, 0xad,
0x21, 0xa8, 0x04, 0xb9, 0x09, 0x15, 0xea, 0x8e, 0x79, 0x22, 0x5f, 0x0d, 0x65, 0xea, 0x8e, 0xa5, 0xbd, 0x28, 0x02, 0xb7, 0x13, 0x84, 0x9e, 0xaf, 0x1e, 0x93, 0xb8, 0x0d, 0xc0, 0x1f, 0x68, 0x43,
0x0a, 0x25, 0x75, 0xc8, 0x37, 0xe2, 0xec, 0x8b, 0x88, 0xb7, 0xc3, 0x46, 0x87, 0x5e, 0x20, 0xb3, 0x35, 0x88, 0x08, 0x9d, 0x86, 0x10, 0x54, 0x82, 0xdc, 0x84, 0x0a, 0x75, 0xc7, 0x3c, 0x91, 0xaf,
0x51, 0x54, 0xf1, 0x76, 0x0e, 0xed, 0x4b, 0xbc, 0x4e, 0x10, 0x18, 0xff, 0x20, 0x0f, 0x4b, 0x51, 0x86, 0x32, 0x75, 0xc7, 0x52, 0x85, 0x92, 0x3a, 0xe4, 0x1b, 0x71, 0xf6, 0x45, 0x04, 0x01, 0x62,
0xfb, 0x78, 0xc4, 0xb1, 0xbb, 0xa9, 0xd8, 0x69, 0xc2, 0x1f, 0x4a, 0xd1, 0xf0, 0xbb, 0x62, 0x49, 0xa3, 0x43, 0x2f, 0x90, 0xd9, 0x28, 0xaa, 0x20, 0x40, 0x87, 0xf6, 0x25, 0xde, 0x71, 0x08, 0x8c,
0x38, 0x4c, 0x5a, 0xd3, 0x54, 0xeb, 0x15, 0xbe, 0x41, 0xbb, 0x2e, 0x31, 0xa0, 0x26, 0x31, 0xbc, 0x7f, 0x9c, 0x87, 0xa5, 0xa8, 0x7d, 0x3c, 0x0c, 0xda, 0xdd, 0x54, 0x40, 0x37, 0xe1, 0x0f, 0xa5,
0x79, 0xa8, 0xc5, 0x96, 0xae, 0x72, 0x94, 0xfe, 0x3c, 0x64, 0xe2, 0xb5, 0x3d, 0x65, 0xdc, 0x8a, 0x68, 0xf8, 0x5d, 0xb1, 0x24, 0x1c, 0x26, 0xad, 0x69, 0xaa, 0xf5, 0x0a, 0xdf, 0xa0, 0x5d, 0x97,
0x10, 0x70, 0x4b, 0xf6, 0x34, 0xec, 0xe2, 0xa3, 0x7b, 0x0c, 0xcc, 0xb2, 0xf1, 0xc9, 0x64, 0x58, 0x18, 0x50, 0x93, 0x18, 0xde, 0x3c, 0xd4, 0x02, 0x5e, 0x57, 0x39, 0x4a, 0x7f, 0x1e, 0x32, 0xf1,
0x0c, 0xbf, 0xc9, 0xa5, 0x2d, 0x3e, 0x7b, 0x28, 0x69, 0xe9, 0xa2, 0x08, 0x7f, 0xea, 0x47, 0x89, 0xda, 0x9e, 0x32, 0x6e, 0x45, 0x08, 0xb8, 0x25, 0x7b, 0x1a, 0x76, 0xf1, 0x25, 0x40, 0x06, 0x66,
0x22, 0x6f, 0x42, 0x8d, 0x17, 0x1e, 0x85, 0x03, 0xc1, 0x40, 0x8f, 0x61, 0xd7, 0xc5, 0x74, 0xa1, 0xd9, 0xf8, 0x64, 0x32, 0x2c, 0x86, 0xdf, 0xe4, 0xd2, 0x16, 0x9f, 0x3d, 0x94, 0xb4, 0x74, 0x51,
0xe6, 0xf4, 0xe6, 0x31, 0xcd, 0x0d, 0xf0, 0xaa, 0xe4, 0xfb, 0x68, 0xaa, 0xc7, 0x96, 0x32, 0x42, 0x84, 0xbf, 0x3f, 0xa4, 0x44, 0x91, 0xd7, 0xa1, 0xc6, 0x0b, 0x8f, 0x62, 0x94, 0x60, 0xf4, 0xc9,
0xd6, 0x14, 0xac, 0x17, 0x30, 0x6e, 0xe5, 0x66, 0xc6, 0xec, 0x0a, 0x62, 0xb0, 0x03, 0x5a, 0x64, 0xb0, 0xeb, 0x62, 0xba, 0x50, 0x73, 0x7a, 0xf3, 0x98, 0xe6, 0x06, 0x78, 0x55, 0xf2, 0xd1, 0x36,
0x74, 0x39, 0x09, 0x9c, 0x22, 0xac, 0x4b, 0xea, 0x1b, 0x1f, 0x7a, 0xb3, 0x79, 0x1a, 0x07, 0x44, 0xd5, 0x63, 0x4b, 0x19, 0x21, 0x6b, 0x0a, 0xd6, 0x0b, 0x18, 0xb7, 0x72, 0x33, 0x63, 0x76, 0x05,
0x52, 0x38, 0x9f, 0xe8, 0x58, 0xdc, 0x1a, 0xe4, 0xe9, 0xf8, 0x6c, 0x73, 0x01, 0xf8, 0x08, 0x36, 0x31, 0xd8, 0x01, 0x2d, 0x5c, 0xbb, 0x9c, 0x04, 0x4e, 0x11, 0xd6, 0x25, 0xf5, 0x8d, 0x0f, 0xbd,
0x3b, 0x97, 0x8c, 0xb0, 0x28, 0xc7, 0xfa, 0xd1, 0xf3, 0xb9, 0xb4, 0x8f, 0x26, 0xac, 0x2c, 0xb9, 0xd9, 0x3c, 0x8d, 0x03, 0x22, 0x29, 0x9c, 0x4f, 0x74, 0x2c, 0x98, 0x0e, 0xf2, 0x74, 0x7c, 0xb6,
0xd7, 0xb2, 0xb2, 0x8c, 0x79, 0xb4, 0x08, 0x55, 0xd6, 0x4f, 0x52, 0x08, 0xd7, 0x2f, 0xd9, 0xae, 0xb9, 0x00, 0x7c, 0x04, 0x9b, 0x9d, 0x4b, 0x46, 0x58, 0x94, 0xb7, 0xff, 0xe8, 0xd9, 0x5c, 0xda,
0x75, 0x82, 0x45, 0xc8, 0xe0, 0x34, 0x0c, 0xc4, 0x0b, 0x35, 0x02, 0x58, 0x3a, 0x9c, 0x4f, 0x42, 0x47, 0x13, 0x56, 0x96, 0xdc, 0x2b, 0x59, 0x59, 0xc6, 0x3c, 0x84, 0x85, 0x2a, 0xeb, 0xc7, 0x29,
0x67, 0x47, 0x81, 0xc8, 0x27, 0x22, 0x0f, 0xd6, 0x23, 0x47, 0x2d, 0xb3, 0x22, 0x50, 0x15, 0xe1, 0x84, 0xeb, 0x97, 0x6c, 0xd7, 0x3a, 0xc1, 0x22, 0x64, 0xc4, 0x1c, 0x06, 0xe2, 0x85, 0x1a, 0x01,
0x60, 0x4d, 0x59, 0x41, 0x56, 0xba, 0xbe, 0xa5, 0x69, 0xbc, 0x06, 0xe3, 0x26, 0x6c, 0x44, 0x5f, 0x2c, 0x1d, 0xce, 0x27, 0xa1, 0xb3, 0xa3, 0x40, 0xe4, 0x63, 0x91, 0x07, 0xeb, 0x91, 0xa3, 0x96,
0x7c, 0xd8, 0xe4, 0x89, 0xf4, 0x37, 0x73, 0xfc, 0x8a, 0x13, 0x4f, 0x1b, 0xb8, 0xf6, 0x2c, 0x38, 0x59, 0x11, 0xa8, 0x8a, 0x70, 0xb0, 0xa6, 0xac, 0x20, 0x2b, 0x5d, 0xdf, 0xd2, 0x34, 0x5e, 0x83,
0xf7, 0x42, 0xd2, 0x81, 0x95, 0xc0, 0x71, 0xcf, 0x26, 0x54, 0x2f, 0x3e, 0x10, 0x83, 0xb0, 0x16, 0x71, 0x13, 0x36, 0xa2, 0x2f, 0x3e, 0x6c, 0xf2, 0x44, 0xfa, 0x3b, 0x39, 0x7e, 0xef, 0x8a, 0xa7,
0x6f, 0x1b, 0xcf, 0x1a, 0x98, 0xcb, 0x3c, 0x47, 0x54, 0x5a, 0x40, 0xb6, 0xaf, 0x6b, 0x64, 0xb4, 0x0d, 0x5c, 0x7b, 0x16, 0x9c, 0x7b, 0x21, 0xe9, 0xc0, 0x4a, 0xe0, 0xb8, 0x67, 0x13, 0xaa, 0x17,
0x2c, 0x12, 0xa3, 0x91, 0x6e, 0x7c, 0x17, 0x16, 0xe3, 0x15, 0x91, 0xcf, 0x44, 0x90, 0x95, 0xa8, 0x1f, 0x88, 0x41, 0x58, 0x8b, 0xb7, 0x8d, 0x67, 0x0d, 0xcc, 0x65, 0x9e, 0x23, 0x2a, 0x2d, 0x20,
0x55, 0x85, 0x44, 0x88, 0x89, 0x68, 0x41, 0xd4, 0xa2, 0xb1, 0x0f, 0x8c, 0xbf, 0x94, 0x83, 0x96, 0xdb, 0xd7, 0x35, 0x32, 0x5a, 0x16, 0x89, 0xd1, 0x48, 0x37, 0xbe, 0x0b, 0x8b, 0xf1, 0x8a, 0xc8,
0x49, 0xd9, 0xca, 0xd5, 0x5a, 0x29, 0xd7, 0xcc, 0x77, 0x53, 0xa5, 0x5e, 0xdf, 0x57, 0x19, 0xbb, 0xa7, 0x22, 0xf2, 0x4b, 0xd4, 0xaa, 0x42, 0x22, 0xee, 0x45, 0xb4, 0x20, 0x6a, 0xd1, 0xd8, 0x07,
0x45, 0xb6, 0xe8, 0x3b, 0xd7, 0x4e, 0xc6, 0xfe, 0x8d, 0x54, 0x8f, 0xb6, 0x2b, 0xb0, 0xc0, 0x51, 0xc6, 0x5f, 0xcd, 0x41, 0xcb, 0xa4, 0x6c, 0xe5, 0x6a, 0xad, 0x94, 0x6b, 0xe6, 0x3b, 0xa9, 0x52,
0x8c, 0x0d, 0x58, 0x13, 0xed, 0x91, 0x6d, 0x89, 0x0c, 0xfa, 0xb1, 0x1a, 0x63, 0x06, 0xfd, 0x4d, 0xaf, 0xef, 0xab, 0x0c, 0x28, 0x23, 0x5b, 0xf4, 0xde, 0xb5, 0x93, 0xb1, 0x7f, 0x23, 0xd5, 0xa3,
0x68, 0xf1, 0x58, 0x08, 0x7a, 0x27, 0x44, 0xc6, 0x5d, 0x20, 0x87, 0xf6, 0xc8, 0xf6, 0x3d, 0xcf, 0xed, 0x0a, 0x2c, 0x70, 0x14, 0x63, 0x03, 0xd6, 0x44, 0x7b, 0x64, 0x5b, 0x22, 0x83, 0x7e, 0xac,
0x3d, 0xa2, 0xbe, 0x70, 0x99, 0x47, 0x46, 0x14, 0xed, 0xdd, 0x92, 0x63, 0xe6, 0x5f, 0x32, 0xe8, 0xc6, 0x98, 0x41, 0x7f, 0x13, 0x5a, 0x3c, 0x40, 0x83, 0xde, 0x09, 0x91, 0x71, 0x17, 0xc8, 0xa1,
0xbe, 0xe7, 0x4a, 0x0f, 0x41, 0xfe, 0x65, 0xf8, 0xb0, 0xb2, 0x6d, 0x3f, 0xa7, 0xb2, 0x24, 0x39, 0x3d, 0xb2, 0x7d, 0xcf, 0x73, 0x8f, 0xa8, 0x2f, 0xfc, 0xf8, 0x91, 0x11, 0x45, 0x7b, 0xb7, 0xe4,
0x44, 0x5f, 0x42, 0x6d, 0xa6, 0x0a, 0x95, 0xe3, 0x2e, 0xe3, 0x57, 0xa5, 0xab, 0x35, 0x75, 0x6c, 0x98, 0xf9, 0x97, 0x7c, 0x09, 0xc0, 0x73, 0xa5, 0x87, 0x20, 0xff, 0x32, 0x7c, 0x58, 0xd9, 0xb6,
0x46, 0xa5, 0x50, 0x61, 0x8b, 0x11, 0x61, 0xc6, 0xf2, 0xcc, 0x67, 0xa0, 0x27, 0xf4, 0xaa, 0x3b, 0x9f, 0x51, 0x59, 0x92, 0x1c, 0xa2, 0x2f, 0xa0, 0x36, 0x53, 0x85, 0xca, 0x71, 0x97, 0x41, 0xb5,
0x36, 0x1e, 0xc2, 0x6a, 0xbc, 0x4e, 0x41, 0x5a, 0x36, 0xa1, 0x32, 0x15, 0x30, 0xd1, 0x7a, 0xf5, 0xd2, 0xd5, 0x9a, 0x3a, 0x36, 0xa3, 0x52, 0xa8, 0xb0, 0xc5, 0x30, 0x35, 0x63, 0x79, 0xe6, 0x33,
0xcd, 0x64, 0x16, 0x26, 0x77, 0xca, 0x3c, 0xdd, 0x5d, 0x15, 0xd6, 0xe0, 0x4b, 0xd8, 0x48, 0xa5, 0xd0, 0x13, 0x7a, 0xd5, 0x1d, 0x1b, 0x0f, 0x61, 0x35, 0x5e, 0xa7, 0x20, 0x2d, 0x9b, 0x50, 0x99,
0x88, 0x02, 0xef, 0x42, 0x5d, 0x6b, 0x08, 0xef, 0x46, 0xd1, 0x04, 0xd5, 0x92, 0xc0, 0xf8, 0x02, 0x0a, 0x98, 0x68, 0xbd, 0xfa, 0x66, 0x32, 0x0b, 0x93, 0x3b, 0x65, 0x9e, 0xee, 0xae, 0x8a, 0xb5,
0x36, 0xb8, 0xd8, 0x16, 0x65, 0x97, 0x43, 0x90, 0xe8, 0x45, 0x2e, 0xd9, 0x8b, 0x4f, 0xa4, 0xac, 0xf0, 0x05, 0x6c, 0xa4, 0x52, 0x44, 0x81, 0x77, 0xa1, 0xae, 0x35, 0x84, 0x77, 0xa3, 0x68, 0x82,
0xa9, 0x67, 0x8d, 0xe2, 0x47, 0x8e, 0x31, 0x4d, 0x3a, 0x79, 0xc9, 0x4f, 0xe3, 0x18, 0xd6, 0xd3, 0x6a, 0x49, 0x60, 0x7c, 0x0e, 0x1b, 0x5c, 0x6c, 0x8b, 0xb2, 0xcb, 0x21, 0x48, 0xf4, 0x22, 0x97,
0xc3, 0xc7, 0xda, 0xff, 0x67, 0x1a, 0x72, 0x39, 0x3c, 0x51, 0xb2, 0x1a, 0x9e, 0xff, 0x9c, 0xe3, 0xec, 0xc5, 0xc7, 0x52, 0xd6, 0xd4, 0xb3, 0x46, 0x41, 0x2d, 0xc7, 0x98, 0x26, 0x9d, 0xbc, 0xe4,
0xe3, 0x13, 0x4b, 0x12, 0xcd, 0x1c, 0x03, 0x99, 0xd2, 0xf0, 0xdc, 0x1b, 0x5b, 0xe9, 0x9a, 0x1f, 0xa7, 0x71, 0x0c, 0xeb, 0xe9, 0xe1, 0x63, 0xed, 0xff, 0x89, 0x86, 0x5c, 0x0e, 0x4f, 0x94, 0xac,
0x29, 0x1f, 0xb3, 0xcc, 0xbc, 0x5b, 0x87, 0x98, 0x51, 0x4b, 0x11, 0xb7, 0x1d, 0xa6, 0x49, 0xf8, 0x86, 0xe7, 0xbf, 0xe6, 0xf8, 0xf8, 0xc4, 0x92, 0x44, 0x33, 0xc7, 0x40, 0xa6, 0x34, 0x3c, 0xf7,
0xe6, 0x08, 0xd6, 0xb3, 0x91, 0x33, 0x3c, 0xb3, 0x3e, 0x8e, 0xf3, 0xf3, 0xb7, 0xaf, 0xed, 0x3e, 0xc6, 0x56, 0xba, 0xe6, 0x47, 0xca, 0xc7, 0x2c, 0x33, 0xef, 0xd6, 0x21, 0x66, 0xd4, 0x52, 0xc4,
0x6b, 0x96, 0xce, 0xde, 0xff, 0x6e, 0x05, 0xca, 0x42, 0x55, 0x43, 0xb6, 0xa0, 0x38, 0x92, 0x5e, 0x15, 0x8c, 0x69, 0x12, 0xbe, 0x39, 0x82, 0xf5, 0x6c, 0xe4, 0x0c, 0xcf, 0xac, 0x8f, 0xe2, 0xfc,
0xbe, 0x51, 0x0c, 0x51, 0x91, 0x2a, 0xff, 0xef, 0xa0, 0xaf, 0x2f, 0xc3, 0x23, 0x5f, 0xc2, 0x62, 0xfc, 0xed, 0x6b, 0xbb, 0xcf, 0x9a, 0xa5, 0xb3, 0xf7, 0xbf, 0x5b, 0x81, 0xb2, 0x50, 0xd5, 0x90,
0xdc, 0xd1, 0x25, 0x11, 0xeb, 0x27, 0xee, 0xa1, 0xd2, 0x18, 0x25, 0x9c, 0x08, 0xaa, 0x11, 0x0f, 0x2d, 0x28, 0x8e, 0xa4, 0x97, 0x6f, 0x14, 0xd8, 0x54, 0xa4, 0xca, 0xff, 0x3b, 0xe8, 0xeb, 0xcb,
0xc6, 0x59, 0xd3, 0xca, 0xb9, 0xc6, 0xa4, 0x79, 0x2e, 0x13, 0xeb, 0x82, 0x73, 0xdb, 0x7a, 0xf8, 0xf0, 0xc8, 0x17, 0xb0, 0x18, 0x77, 0x74, 0x49, 0x04, 0x20, 0x8a, 0x7b, 0xa8, 0x34, 0x46, 0x09,
0xe8, 0x53, 0x61, 0x54, 0xa8, 0x21, 0x70, 0x70, 0x6e, 0x3f, 0x7c, 0xf4, 0x69, 0x52, 0x60, 0x13, 0x27, 0x82, 0x6a, 0xc4, 0x83, 0x71, 0xd6, 0xb4, 0x72, 0xae, 0x31, 0x69, 0x9e, 0xcb, 0xc4, 0xba,
0xa1, 0x7e, 0x34, 0x81, 0x6d, 0x15, 0x4a, 0xfc, 0x65, 0x02, 0xee, 0xae, 0xc9, 0x3f, 0xa4, 0x3a, 0xe0, 0xdc, 0xb6, 0x1e, 0x3e, 0xfa, 0x44, 0x18, 0x15, 0x6a, 0x08, 0x1c, 0x9c, 0xdb, 0x0f, 0x1f,
0x63, 0xee, 0x53, 0x4b, 0x5c, 0xac, 0xe1, 0xa7, 0x28, 0x7f, 0x45, 0x8e, 0x88, 0xb4, 0x01, 0x26, 0x7d, 0x92, 0x14, 0xd8, 0x44, 0xfc, 0x21, 0x4d, 0x60, 0x5b, 0x85, 0x12, 0x7f, 0x2e, 0x81, 0xbb,
0x71, 0x75, 0xe2, 0x3a, 0x2c, 0x9c, 0x47, 0x4f, 0x4d, 0x34, 0x4c, 0xf1, 0x65, 0xfc, 0x8f, 0x12, 0x6b, 0xf2, 0x0f, 0xa9, 0xce, 0x98, 0xfb, 0xd4, 0x12, 0xb7, 0x7d, 0xf8, 0x29, 0xca, 0x9f, 0xb6,
0xd4, 0xb4, 0x41, 0x21, 0x75, 0xa8, 0x98, 0x9d, 0x41, 0xc7, 0x7c, 0xda, 0xd9, 0x6d, 0xde, 0x20, 0x23, 0x22, 0x6d, 0x80, 0x49, 0x5c, 0x9d, 0xb8, 0x0e, 0x0b, 0xe7, 0xd1, 0xfb, 0x17, 0x0d, 0x53,
0xf7, 0xe0, 0x9d, 0x6e, 0x6f, 0xa7, 0x6f, 0x9a, 0x9d, 0x9d, 0xa1, 0xd5, 0x37, 0x2d, 0x19, 0xda, 0x7c, 0x19, 0xff, 0xab, 0x04, 0x35, 0x6d, 0x50, 0x48, 0x1d, 0x2a, 0x66, 0x67, 0xd0, 0x31, 0xbf,
0xf6, 0xa8, 0xfd, 0xec, 0xb0, 0xd3, 0x1b, 0x5a, 0xbb, 0x9d, 0x61, 0xbb, 0x7b, 0x30, 0x68, 0xe6, 0xec, 0xec, 0x36, 0x6f, 0x90, 0x7b, 0xf0, 0x56, 0xb7, 0xb7, 0xd3, 0x37, 0xcd, 0xce, 0xce, 0xd0,
0xc8, 0x1b, 0xd0, 0x8a, 0x30, 0x65, 0x72, 0xfb, 0xb0, 0x7f, 0xdc, 0x1b, 0x36, 0xf3, 0xe4, 0x0e, 0xea, 0x9b, 0x96, 0x8c, 0xb7, 0x7b, 0xd4, 0x7e, 0x7a, 0xd8, 0xe9, 0x0d, 0xad, 0xdd, 0xce, 0xb0,
0xdc, 0xda, 0xeb, 0xf6, 0xda, 0x07, 0x56, 0x84, 0xb3, 0x73, 0x30, 0x7c, 0x6a, 0x75, 0x7e, 0xee, 0xdd, 0x3d, 0x18, 0x34, 0x73, 0xe4, 0x35, 0x68, 0x45, 0x98, 0x32, 0xb9, 0x7d, 0xd8, 0x3f, 0xee,
0xa8, 0x6b, 0x3e, 0x6b, 0x16, 0xb2, 0x10, 0xf6, 0x87, 0x07, 0x3b, 0xb2, 0x84, 0x22, 0xb9, 0x09, 0x0d, 0x9b, 0x79, 0x72, 0x07, 0x6e, 0xed, 0x75, 0x7b, 0xed, 0x03, 0x2b, 0xc2, 0xd9, 0x39, 0x18,
0x6b, 0x1c, 0x81, 0x67, 0xb1, 0x86, 0xfd, 0xbe, 0x35, 0xe8, 0xf7, 0x7b, 0xcd, 0x12, 0x59, 0x86, 0x7e, 0x69, 0x75, 0x7e, 0xee, 0xa8, 0x6b, 0x3e, 0x6d, 0x16, 0xb2, 0x10, 0xf6, 0x87, 0x07, 0x3b,
0x46, 0xb7, 0xf7, 0xb4, 0x7d, 0xd0, 0xdd, 0xb5, 0xcc, 0x4e, 0xfb, 0xe0, 0xb0, 0xb9, 0x40, 0x56, 0xb2, 0x84, 0x22, 0xb9, 0x09, 0x6b, 0x1c, 0x81, 0x67, 0xb1, 0x86, 0xfd, 0xbe, 0x35, 0xe8, 0xf7,
0x60, 0x29, 0x89, 0x57, 0x66, 0x45, 0x48, 0xbc, 0x7e, 0xaf, 0xdb, 0xef, 0x59, 0x4f, 0x3b, 0xe6, 0x7b, 0xcd, 0x12, 0x59, 0x86, 0x46, 0xb7, 0xf7, 0x65, 0xfb, 0xa0, 0xbb, 0x6b, 0x99, 0x9d, 0xf6,
0xa0, 0xdb, 0xef, 0x35, 0x2b, 0x64, 0x1d, 0x48, 0x3c, 0x69, 0xff, 0xb0, 0xbd, 0xd3, 0xac, 0x92, 0xc1, 0x61, 0x73, 0x81, 0xac, 0xc0, 0x52, 0x12, 0xaf, 0xcc, 0x8a, 0x90, 0x78, 0xfd, 0x5e, 0xb7,
0x35, 0x58, 0x8e, 0xc3, 0x9f, 0x74, 0x9e, 0x35, 0x81, 0xb4, 0x60, 0x95, 0x37, 0xcc, 0xda, 0xee, 0xdf, 0xb3, 0xbe, 0xec, 0x98, 0x83, 0x6e, 0xbf, 0xd7, 0xac, 0x90, 0x75, 0x20, 0xf1, 0xa4, 0xfd,
0x1c, 0xf4, 0xbf, 0xb2, 0x0e, 0xbb, 0xbd, 0xee, 0xe1, 0xf1, 0x61, 0xb3, 0x86, 0x01, 0xc6, 0x3b, 0xc3, 0xf6, 0x4e, 0xb3, 0x4a, 0xd6, 0x60, 0x39, 0x0e, 0x7f, 0xd2, 0x79, 0xda, 0x04, 0xd2, 0x82,
0x1d, 0xab, 0xdb, 0x1b, 0x1c, 0xef, 0xed, 0x75, 0x77, 0xba, 0x9d, 0xde, 0xb0, 0x59, 0xe7, 0x35, 0x55, 0xde, 0x30, 0x6b, 0xbb, 0x73, 0xd0, 0xff, 0xca, 0x3a, 0xec, 0xf6, 0xba, 0x87, 0xc7, 0x87,
0x67, 0x75, 0xbc, 0xc1, 0x32, 0x88, 0xbb, 0xa7, 0xd6, 0x6e, 0x77, 0xd0, 0xde, 0x3e, 0xe8, 0xec, 0xcd, 0x1a, 0x46, 0x3d, 0xef, 0x74, 0xac, 0x6e, 0x6f, 0x70, 0xbc, 0xb7, 0xd7, 0xdd, 0xe9, 0x76,
0x36, 0x17, 0xc9, 0x6d, 0xb8, 0x39, 0xec, 0x1c, 0x1e, 0xf5, 0xcd, 0xb6, 0xf9, 0x4c, 0xde, 0x4d, 0x7a, 0xc3, 0x66, 0x9d, 0xd7, 0x9c, 0xd5, 0xf1, 0x06, 0xcb, 0x20, 0x2e, 0xc4, 0x5a, 0xbb, 0xdd,
0xb5, 0xf6, 0xda, 0xdd, 0x83, 0x63, 0xb3, 0xd3, 0x5c, 0x22, 0x6f, 0xc1, 0x6d, 0xb3, 0xf3, 0xc3, 0x41, 0x7b, 0xfb, 0xa0, 0xb3, 0xdb, 0x5c, 0x24, 0xb7, 0xe1, 0xe6, 0xb0, 0x73, 0x78, 0xd4, 0x37,
0xe3, 0xae, 0xd9, 0xd9, 0xb5, 0x7a, 0xfd, 0xdd, 0x8e, 0xb5, 0xd7, 0x69, 0x0f, 0x8f, 0xcd, 0x8e, 0xdb, 0xe6, 0x53, 0x79, 0x61, 0xd6, 0xda, 0x6b, 0x77, 0x0f, 0x8e, 0xcd, 0x4e, 0x73, 0x89, 0xbc,
0x75, 0xd8, 0x1d, 0x0c, 0xba, 0xbd, 0xc7, 0xcd, 0x26, 0x79, 0x07, 0xee, 0x2a, 0x14, 0x55, 0x40, 0x01, 0xb7, 0xcd, 0xce, 0x0f, 0x8e, 0xbb, 0x66, 0x67, 0xd7, 0xea, 0xf5, 0x77, 0x3b, 0xd6, 0x5e,
0x02, 0x6b, 0x99, 0xf5, 0x4f, 0x4e, 0x69, 0xaf, 0xf3, 0x73, 0x43, 0xeb, 0xa8, 0xd3, 0x31, 0x9b, 0xa7, 0x3d, 0x3c, 0x36, 0x3b, 0xd6, 0x61, 0x77, 0x30, 0xe8, 0xf6, 0x1e, 0x37, 0x9b, 0xe4, 0x2d,
0x84, 0x6c, 0xc2, 0x7a, 0x54, 0x3d, 0xaf, 0x40, 0xd4, 0xbd, 0xc2, 0xd2, 0x8e, 0x3a, 0xe6, 0x61, 0xb8, 0xab, 0x50, 0x54, 0x01, 0x09, 0xac, 0x65, 0xd6, 0x3f, 0x39, 0xa5, 0xbd, 0xce, 0xcf, 0x0d,
0xbb, 0xc7, 0x26, 0x38, 0x96, 0xb6, 0xca, 0x9a, 0x1d, 0xa5, 0x25, 0x9b, 0xbd, 0x46, 0x08, 0x2c, 0xad, 0xa3, 0x4e, 0xc7, 0x6c, 0x12, 0xb2, 0x09, 0xeb, 0x51, 0xf5, 0xbc, 0x02, 0x51, 0xf7, 0x0a,
0x6a, 0xb3, 0xb2, 0xd7, 0x36, 0x9b, 0xeb, 0x64, 0x09, 0x6a, 0x87, 0x47, 0x47, 0xd6, 0xb0, 0x7b, 0x4b, 0x3b, 0xea, 0x98, 0x87, 0xed, 0x1e, 0x9b, 0xe0, 0x58, 0xda, 0x2a, 0x6b, 0x76, 0x94, 0x96,
0xd8, 0xe9, 0x1f, 0x0f, 0x9b, 0x1b, 0xe9, 0x59, 0x3a, 0x6a, 0x3f, 0x3b, 0xe8, 0xb7, 0x77, 0x9b, 0x6c, 0xf6, 0x1a, 0x21, 0xb0, 0xa8, 0xcd, 0xca, 0x5e, 0xdb, 0x6c, 0xae, 0x93, 0x25, 0xa8, 0x1d,
0x2d, 0xb2, 0x06, 0xcd, 0x6e, 0x6f, 0xd8, 0x31, 0xd9, 0x32, 0x90, 0xa5, 0xfe, 0x97, 0x32, 0x59, 0x1e, 0x1d, 0x59, 0xc3, 0xee, 0x61, 0xa7, 0x7f, 0x3c, 0x6c, 0x6e, 0xa4, 0x67, 0xe9, 0xa8, 0xfd,
0x85, 0x25, 0xd9, 0x09, 0x09, 0xfd, 0xa3, 0x32, 0xd9, 0x00, 0x72, 0xdc, 0x33, 0x3b, 0xed, 0x5d, 0xf4, 0xa0, 0xdf, 0xde, 0x6d, 0xb6, 0xc8, 0x1a, 0x34, 0xbb, 0xbd, 0x61, 0xc7, 0x64, 0xcb, 0x40,
0x36, 0xa6, 0x2a, 0xe1, 0xbf, 0x96, 0x85, 0x79, 0xf9, 0xf7, 0x0a, 0x8a, 0x0f, 0x8c, 0x1c, 0xcc, 0x96, 0xfa, 0xdf, 0xca, 0x64, 0x15, 0x96, 0x64, 0x27, 0x24, 0xf4, 0x8f, 0xca, 0x64, 0x03, 0xc8,
0xe2, 0xcf, 0x46, 0xd5, 0xb5, 0xe7, 0x9e, 0x5e, 0xf5, 0xb4, 0xa8, 0x26, 0xdc, 0x17, 0x52, 0xc2, 0x71, 0xcf, 0xec, 0xb4, 0x77, 0xd9, 0x98, 0xaa, 0x84, 0xff, 0x5e, 0x16, 0xe6, 0xe5, 0xdf, 0x2b,
0x7d, 0x4a, 0x7b, 0xd4, 0xd0, 0x25, 0x8f, 0xb7, 0xa1, 0x31, 0xe5, 0x4f, 0x48, 0x89, 0x37, 0x48, 0x28, 0x3e, 0x30, 0x72, 0x30, 0x8b, 0xbf, 0x65, 0x55, 0xd7, 0xde, 0xa0, 0x7a, 0xd9, 0x7b, 0xa7,
0x40, 0x78, 0x5b, 0x72, 0x20, 0x7f, 0x80, 0x24, 0xf5, 0xb6, 0x66, 0x29, 0xfd, 0xb6, 0x66, 0x96, 0x9a, 0x70, 0x5f, 0x48, 0x09, 0xf7, 0x29, 0xed, 0x51, 0x43, 0x97, 0x3c, 0xde, 0x84, 0xc6, 0x94,
0x84, 0xb9, 0x90, 0x25, 0x61, 0xde, 0x87, 0x65, 0x4e, 0xb5, 0x1c, 0xd7, 0x99, 0x4a, 0xbd, 0x8d, 0xbf, 0x6b, 0x25, 0x1e, 0x46, 0x01, 0xe1, 0x6d, 0xc9, 0x81, 0xfc, 0x55, 0x94, 0xd4, 0x83, 0x9f,
0x78, 0xa9, 0x12, 0xa9, 0x17, 0x87, 0x4b, 0x81, 0x56, 0x0a, 0xbd, 0x82, 0xba, 0x94, 0x85, 0xbc, 0xa5, 0xf4, 0x83, 0x9f, 0x59, 0x12, 0xe6, 0x42, 0x96, 0x84, 0x79, 0x1f, 0x96, 0x39, 0xd5, 0x72,
0x1b, 0x93, 0x75, 0x39, 0x51, 0x51, 0xb2, 0xae, 0xaa, 0xc1, 0xbe, 0x8c, 0x6a, 0xa8, 0x69, 0x35, 0x5c, 0x67, 0x2a, 0xf5, 0x36, 0xe2, 0xf9, 0x4c, 0xa4, 0x5e, 0x1c, 0x2e, 0x05, 0x5a, 0x29, 0xf4,
0x70, 0x38, 0xd6, 0x70, 0x1f, 0x96, 0xe9, 0x65, 0xe8, 0xdb, 0x96, 0x37, 0xb3, 0x7f, 0x34, 0x47, 0x0a, 0xea, 0x52, 0x16, 0xf2, 0x6e, 0x4c, 0xd6, 0xe5, 0x44, 0x45, 0xc9, 0xba, 0xaa, 0x06, 0xfb,
0x17, 0x19, 0x1b, 0xb5, 0x48, 0x75, 0x73, 0x09, 0x13, 0xfa, 0x08, 0xdf, 0xb5, 0x43, 0xdb, 0xf8, 0x32, 0xaa, 0xa1, 0xa6, 0xd5, 0xc0, 0xe1, 0x58, 0xc3, 0x7d, 0x58, 0xa6, 0x97, 0xa1, 0x6f, 0x5b,
0x45, 0x00, 0x75, 0xe0, 0xe2, 0x8b, 0x9f, 0xae, 0x27, 0xef, 0xd4, 0xd6, 0x4d, 0xfe, 0x81, 0xf3, 0xde, 0xcc, 0xfe, 0xe1, 0x1c, 0x5d, 0x64, 0x6c, 0xd4, 0x22, 0xd5, 0xcd, 0x25, 0x4c, 0xe8, 0x23,
0x18, 0x7a, 0xbe, 0x7d, 0x46, 0xbb, 0xd2, 0x2a, 0x1c, 0x01, 0xc8, 0x2d, 0x28, 0x78, 0x33, 0xe9, 0x7c, 0xd7, 0x0e, 0x6d, 0xe3, 0x17, 0x01, 0xd4, 0x81, 0x8b, 0xcf, 0x90, 0xba, 0x9e, 0xbc, 0xe8,
0x8b, 0x58, 0x95, 0x41, 0xf5, 0x67, 0x26, 0x83, 0x1a, 0x9f, 0x42, 0xbe, 0x3f, 0xbb, 0x96, 0x8b, 0x5b, 0x37, 0xf9, 0x07, 0xce, 0x63, 0xe8, 0xf9, 0xf6, 0x19, 0xed, 0x4a, 0xab, 0x70, 0x04, 0x20,
0xc2, 0x07, 0xce, 0xf8, 0xab, 0x06, 0x79, 0xf4, 0x3f, 0x94, 0x9f, 0xf7, 0xff, 0x3c, 0xd4, 0xb4, 0xb7, 0xa0, 0xe0, 0xcd, 0xa4, 0x2f, 0x62, 0x55, 0x46, 0xfa, 0x9f, 0x99, 0x0c, 0x6a, 0x7c, 0x02,
0xf7, 0xd0, 0xc8, 0x06, 0xac, 0x7c, 0xd5, 0x1d, 0xf6, 0x3a, 0x83, 0x81, 0x75, 0x74, 0xbc, 0xfd, 0xf9, 0xfe, 0xec, 0x5a, 0x2e, 0x0a, 0x5f, 0x5d, 0xe3, 0x4f, 0x2d, 0xe4, 0xd1, 0xff, 0x50, 0x7e,
0xa4, 0xf3, 0xcc, 0xda, 0x6f, 0x0f, 0xf6, 0x9b, 0x37, 0x18, 0x99, 0xe9, 0x75, 0x06, 0xc3, 0xce, 0xde, 0xff, 0x8b, 0x50, 0xd3, 0x1e, 0x69, 0x23, 0x1b, 0xb0, 0xf2, 0x55, 0x77, 0xd8, 0xeb, 0x0c,
0x6e, 0x0c, 0x9e, 0x23, 0x6f, 0xc2, 0xe6, 0x71, 0xef, 0x78, 0xd0, 0xd9, 0xb5, 0xb2, 0xf2, 0xe5, 0x06, 0xd6, 0xd1, 0xf1, 0xf6, 0x93, 0xce, 0x53, 0x6b, 0xbf, 0x3d, 0xd8, 0x6f, 0xde, 0x60, 0x64,
0xd9, 0xbe, 0x12, 0xe9, 0x19, 0xd9, 0x0b, 0xf7, 0x7f, 0x09, 0x16, 0xe3, 0x81, 0x65, 0x08, 0xc0, 0xa6, 0xd7, 0x19, 0x0c, 0x3b, 0xbb, 0x31, 0x78, 0x8e, 0xbc, 0x0e, 0x9b, 0xc7, 0xbd, 0xe3, 0x41,
0xc2, 0x41, 0xe7, 0x71, 0x7b, 0xe7, 0x19, 0x7f, 0x34, 0x61, 0x30, 0x6c, 0x0f, 0xbb, 0x3b, 0x96, 0x67, 0xd7, 0xca, 0xca, 0x97, 0x67, 0xfb, 0x4a, 0xa4, 0x67, 0x64, 0x2f, 0xdc, 0xff, 0x25, 0x58,
0x78, 0x24, 0x81, 0xd1, 0xb0, 0x1c, 0xa9, 0x41, 0xb9, 0xdd, 0xdb, 0xd9, 0xef, 0x9b, 0x83, 0x66, 0x8c, 0x47, 0xbb, 0x21, 0x00, 0x0b, 0x07, 0x9d, 0xc7, 0xed, 0x9d, 0xa7, 0xfc, 0x25, 0x87, 0xc1,
0x9e, 0xbc, 0x01, 0x1b, 0x72, 0x0b, 0xed, 0xf4, 0x0f, 0x0f, 0xbb, 0x43, 0x24, 0xdf, 0xc3, 0x67, 0xb0, 0x3d, 0xec, 0xee, 0x58, 0xe2, 0xe5, 0x06, 0x46, 0xc3, 0x72, 0xa4, 0x06, 0xe5, 0x76, 0x6f,
0x47, 0x6c, 0xc7, 0xdc, 0xb7, 0xa1, 0x1a, 0xbd, 0xef, 0x80, 0x24, 0xb1, 0x3b, 0xec, 0xb6, 0x87, 0x67, 0xbf, 0x6f, 0x0e, 0x9a, 0x79, 0xf2, 0x1a, 0x6c, 0xc8, 0x2d, 0xb4, 0xd3, 0x3f, 0x3c, 0xec,
0xd1, 0x79, 0xd0, 0xbc, 0xc1, 0x28, 0x6e, 0x04, 0xc6, 0x47, 0x1a, 0x9a, 0x39, 0x7e, 0xf7, 0x5e, 0x0e, 0x91, 0x7c, 0x0f, 0x9f, 0x1e, 0xb1, 0x1d, 0x73, 0xdf, 0x86, 0x6a, 0xf4, 0xe8, 0x04, 0x92,
0x02, 0x79, 0xed, 0xcd, 0x3c, 0x23, 0x03, 0x11, 0x74, 0xbb, 0x3f, 0x64, 0x5d, 0xf8, 0x65, 0x58, 0xc4, 0xee, 0xb0, 0xdb, 0x1e, 0x46, 0xe7, 0x41, 0xf3, 0x06, 0xa3, 0xb8, 0x11, 0x18, 0x5f, 0x8e,
0x8c, 0x3f, 0xa3, 0x40, 0x9a, 0x50, 0x67, 0xf5, 0x6b, 0x55, 0x00, 0x2c, 0xf0, 0x16, 0x37, 0x73, 0x68, 0xe6, 0x78, 0x40, 0x00, 0x09, 0xe4, 0xb5, 0x37, 0xf3, 0x8c, 0x0c, 0x44, 0xd0, 0xed, 0xfe,
0x9c, 0xe6, 0xef, 0xf4, 0x0f, 0xbb, 0xbd, 0xc7, 0x78, 0x50, 0x34, 0xf3, 0x0c, 0xd4, 0x3f, 0x1e, 0x90, 0x75, 0xe1, 0x97, 0x61, 0x31, 0xfe, 0xb6, 0x03, 0x69, 0x42, 0x9d, 0xd5, 0xaf, 0x55, 0x01,
0x3e, 0xee, 0x2b, 0x50, 0x81, 0xe5, 0xe0, 0xdd, 0x69, 0x16, 0xef, 0xff, 0x08, 0x96, 0x53, 0x0f, 0xb0, 0xc0, 0x5b, 0xdc, 0xcc, 0x71, 0x9a, 0xbf, 0xd3, 0x3f, 0xec, 0xf6, 0x1e, 0xe3, 0x41, 0xd1,
0x2e, 0xb0, 0x56, 0xf7, 0x8f, 0x87, 0x3b, 0xfd, 0x43, 0xbd, 0x9e, 0x1a, 0x94, 0x77, 0x0e, 0xda, 0xcc, 0x33, 0x50, 0xff, 0x78, 0xf8, 0xb8, 0xaf, 0x40, 0x05, 0x96, 0x83, 0x77, 0xa7, 0x59, 0xbc,
0xdd, 0x43, 0x34, 0xd4, 0x34, 0xa0, 0x7a, 0xdc, 0x93, 0x9f, 0xf9, 0xf8, 0x53, 0x11, 0x05, 0x46, 0xff, 0x43, 0x58, 0x4e, 0xbd, 0x02, 0xc1, 0x5a, 0xdd, 0x3f, 0x1e, 0xee, 0xf4, 0x0f, 0xf5, 0x7a,
0xbd, 0xf6, 0xba, 0xe6, 0x60, 0x68, 0x0d, 0x86, 0xed, 0xc7, 0x9d, 0x66, 0x91, 0xe5, 0x95, 0xa4, 0x6a, 0x50, 0xde, 0x39, 0x68, 0x77, 0x0f, 0xd1, 0x50, 0xd3, 0x80, 0xea, 0x71, 0x4f, 0x7e, 0xe6,
0xac, 0x74, 0xff, 0x0b, 0x58, 0x8c, 0x3b, 0xce, 0xc7, 0xed, 0x6f, 0x9b, 0xb0, 0xbe, 0xdd, 0x19, 0xe3, 0xef, 0x57, 0x14, 0x18, 0xf5, 0xda, 0xeb, 0x9a, 0x83, 0xa1, 0x35, 0x18, 0xb6, 0x1f, 0x77,
0x7e, 0xd5, 0xe9, 0xf4, 0x70, 0xca, 0x77, 0x3a, 0xbd, 0xa1, 0xd9, 0x3e, 0xe8, 0x0e, 0x9f, 0x35, 0x9a, 0x45, 0x96, 0x57, 0x92, 0xb2, 0xd2, 0xfd, 0xcf, 0x61, 0x31, 0xee, 0x38, 0x1f, 0xb7, 0xbf,
0x73, 0xf7, 0xbf, 0x84, 0x66, 0xd2, 0xe9, 0x23, 0xe6, 0x25, 0xf3, 0x32, 0x77, 0x9a, 0xfb, 0xff, 0x6d, 0xc2, 0xfa, 0x76, 0x67, 0xf8, 0x55, 0xa7, 0xd3, 0xc3, 0x29, 0xdf, 0xe9, 0xf4, 0x86, 0x66,
0x36, 0x07, 0xab, 0x59, 0xe6, 0x41, 0xb6, 0x30, 0x05, 0x21, 0x64, 0x27, 0xe5, 0xa0, 0xdf, 0xb3, 0xfb, 0xa0, 0x3b, 0x7c, 0xda, 0xcc, 0xdd, 0xff, 0x02, 0x9a, 0x49, 0xa7, 0x8f, 0x98, 0x97, 0xcc,
0x7a, 0x7d, 0x0c, 0x95, 0xbe, 0x09, 0xeb, 0x89, 0x04, 0xd9, 0x8b, 0x1c, 0xb9, 0x05, 0x1b, 0xa9, 0x8b, 0xdc, 0x69, 0xee, 0xff, 0x87, 0x1c, 0xac, 0x66, 0x99, 0x07, 0xd9, 0xc2, 0x14, 0x84, 0x90,
0x4c, 0x96, 0xd9, 0x3f, 0xc6, 0xb9, 0x6c, 0xc1, 0x6a, 0x22, 0xb1, 0x63, 0x9a, 0x7d, 0xb3, 0x59, 0x9d, 0x94, 0x83, 0x7e, 0xcf, 0xea, 0xf5, 0x31, 0x7e, 0xfb, 0x26, 0xac, 0x27, 0x12, 0x64, 0x2f,
0x20, 0xdf, 0x81, 0x7b, 0x89, 0x94, 0x34, 0x7f, 0x20, 0xd9, 0x87, 0x22, 0x79, 0x0f, 0xde, 0x4e, 0x72, 0xe4, 0x16, 0x6c, 0xa4, 0x32, 0x59, 0x66, 0xff, 0x18, 0xe7, 0xb2, 0x05, 0xab, 0x89, 0xc4,
0x61, 0x47, 0x47, 0xa8, 0xb5, 0xdd, 0x3e, 0x60, 0xdd, 0x6b, 0x96, 0xee, 0xff, 0x41, 0x11, 0x20, 0x8e, 0x69, 0xf6, 0xcd, 0x66, 0x81, 0xbc, 0x07, 0xf7, 0x12, 0x29, 0x69, 0xfe, 0x40, 0xb2, 0x0f,
0xba, 0x99, 0xca, 0xea, 0xdf, 0x6d, 0x0f, 0xdb, 0x07, 0x7d, 0xb6, 0x67, 0xcc, 0xfe, 0x90, 0x95, 0x45, 0xf2, 0x0e, 0xbc, 0x99, 0xc2, 0x8e, 0x8e, 0x50, 0x6b, 0xbb, 0x7d, 0xc0, 0xba, 0xd7, 0x2c,
0x6e, 0x76, 0x7e, 0xd8, 0xbc, 0x91, 0x99, 0xd2, 0x3f, 0x62, 0x1d, 0xda, 0x80, 0x15, 0xbe, 0xfe, 0xdd, 0xff, 0x83, 0x22, 0x40, 0x74, 0x5d, 0x96, 0xd5, 0xbf, 0xdb, 0x1e, 0xb6, 0x0f, 0xfa, 0x6c,
0x0e, 0x58, 0x37, 0xd8, 0x72, 0xe1, 0x51, 0xf7, 0x19, 0x13, 0x72, 0x7c, 0xb4, 0x67, 0xf6, 0x7b, 0xcf, 0x98, 0xfd, 0x21, 0x2b, 0xdd, 0xec, 0xfc, 0xa0, 0x79, 0x23, 0x33, 0xa5, 0x7f, 0xc4, 0x3a,
0x43, 0x6b, 0xb0, 0x7f, 0x3c, 0xdc, 0xc5, 0x20, 0xfe, 0x3b, 0x66, 0xf7, 0x88, 0x97, 0x59, 0x7c, 0xb4, 0x01, 0x2b, 0x7c, 0xfd, 0x1d, 0xb0, 0x6e, 0xb0, 0xe5, 0xc2, 0x9f, 0x02, 0x60, 0x4c, 0xc8,
0x19, 0x02, 0x2b, 0xba, 0xc4, 0x36, 0xf8, 0xe3, 0xfe, 0x60, 0xd0, 0x3d, 0xb2, 0x7e, 0x78, 0xdc, 0xf1, 0xd1, 0x9e, 0xd9, 0xef, 0x0d, 0xad, 0xc1, 0xfe, 0xf1, 0x70, 0x17, 0x5f, 0x16, 0xd8, 0x31,
0x31, 0xbb, 0x9d, 0x01, 0x66, 0x5c, 0xc8, 0x80, 0x33, 0xfc, 0x32, 0x5b, 0xb3, 0xc3, 0x83, 0xa7, 0xbb, 0x47, 0xbc, 0xcc, 0xe2, 0x8b, 0x10, 0x58, 0xd1, 0x25, 0xb6, 0xc1, 0x1f, 0xf7, 0x07, 0x83,
0xe2, 0xa0, 0x63, 0xa8, 0x95, 0x38, 0x88, 0x61, 0x55, 0xd9, 0xec, 0xb0, 0xc3, 0x39, 0xa3, 0x64, 0xee, 0x91, 0xf5, 0x83, 0xe3, 0x8e, 0xd9, 0xed, 0x0c, 0x30, 0xe3, 0x42, 0x06, 0x9c, 0xe1, 0x97,
0xb8, 0x26, 0x8d, 0xe5, 0xab, 0xb1, 0xa3, 0x34, 0xb5, 0xf3, 0x31, 0x5b, 0x3d, 0x3b, 0x89, 0xe5, 0xd9, 0x9a, 0x1d, 0x1e, 0x7c, 0x29, 0x0e, 0x3a, 0x86, 0x5a, 0x89, 0x83, 0x18, 0x56, 0x95, 0xcd,
0x42, 0x8e, 0x44, 0xf1, 0x6f, 0xbb, 0xbb, 0x26, 0x66, 0x58, 0x4c, 0x41, 0x19, 0xee, 0x12, 0x5b, 0x0e, 0x3b, 0x9c, 0x33, 0x4a, 0x86, 0x6b, 0xd2, 0x58, 0xbe, 0x1a, 0x3b, 0x4a, 0x53, 0x3b, 0x1f,
0x84, 0xec, 0xf4, 0x66, 0x28, 0x4d, 0xf9, 0xc1, 0x52, 0x96, 0x59, 0x8f, 0xbf, 0x3a, 0x3e, 0xdc, 0xb3, 0xd5, 0xb3, 0x93, 0x58, 0x2e, 0xe4, 0x48, 0x14, 0xff, 0xb6, 0xbb, 0x6b, 0x62, 0x86, 0xc5,
0xee, 0x4b, 0x36, 0x80, 0xb7, 0x97, 0x64, 0xc0, 0x19, 0xfe, 0x0a, 0xbe, 0x92, 0xc0, 0xc9, 0x11, 0x14, 0x94, 0xe1, 0x2e, 0xb1, 0x45, 0xc8, 0x4e, 0x6f, 0x86, 0xd2, 0x94, 0x1f, 0x2c, 0x65, 0x99,
0x22, 0xae, 0xea, 0x00, 0x86, 0xb1, 0xc6, 0x88, 0xa0, 0x04, 0xfc, 0x7c, 0xc7, 0xec, 0x5b, 0x8c, 0xf5, 0xf8, 0xab, 0xe3, 0xc3, 0xed, 0xbe, 0x64, 0x03, 0x78, 0x7b, 0x49, 0x06, 0x9c, 0xe1, 0xaf,
0xcf, 0x42, 0x1e, 0x91, 0xe1, 0xaf, 0x5f, 0x9f, 0xcc, 0x72, 0x6f, 0x3c, 0xfc, 0xa7, 0x6f, 0x41, 0xe0, 0xd3, 0x0d, 0x9c, 0x1c, 0x21, 0xe2, 0xaa, 0x0e, 0x60, 0x18, 0x6b, 0x8c, 0x08, 0x4a, 0xc0,
0x55, 0xdd, 0x98, 0x21, 0x3f, 0x80, 0x46, 0x2c, 0x20, 0x05, 0xb9, 0x95, 0x1d, 0xa6, 0x02, 0xa5, 0xcf, 0x77, 0xcc, 0xbe, 0xc5, 0xf8, 0x2c, 0xe4, 0x11, 0x19, 0xfe, 0xfa, 0xf5, 0xc9, 0x2c, 0xf7,
0xa8, 0xcd, 0x37, 0x5e, 0x16, 0xc3, 0x82, 0x1c, 0x6a, 0x8a, 0x0b, 0x5e, 0xd8, 0x1b, 0x49, 0x65, 0xc6, 0xc3, 0x7f, 0xf1, 0x06, 0x54, 0xd5, 0x8d, 0x19, 0xf2, 0x7d, 0x68, 0xc4, 0xa2, 0x64, 0x90,
0x42, 0xac, 0xb4, 0xdb, 0xd7, 0xa4, 0x8a, 0xe2, 0x9e, 0xe0, 0x83, 0x04, 0x18, 0xc0, 0x51, 0x1c, 0x5b, 0xd9, 0xb1, 0x33, 0x50, 0x8a, 0xda, 0x7c, 0xed, 0x45, 0x81, 0x35, 0xc8, 0xa1, 0xa6, 0xb8,
0x2f, 0xe4, 0x76, 0x14, 0x1d, 0x5e, 0x87, 0xcb, 0x02, 0xa5, 0x98, 0xa8, 0xa5, 0xed, 0xd2, 0xd0, 0xe0, 0x85, 0xbd, 0x96, 0x54, 0x26, 0xc4, 0x4a, 0xbb, 0x7d, 0x4d, 0xaa, 0x28, 0xee, 0x09, 0xbe,
0x76, 0x26, 0x01, 0xd9, 0x85, 0x9a, 0xf6, 0xc6, 0x2f, 0xb9, 0x79, 0xed, 0x83, 0xc4, 0x9b, 0x9b, 0x92, 0x80, 0x51, 0x25, 0xc5, 0xf1, 0x42, 0x6e, 0x47, 0x21, 0xeb, 0x75, 0xb8, 0x2c, 0x50, 0x8a,
0x59, 0x49, 0xa2, 0x49, 0xdf, 0x83, 0xaa, 0x7a, 0xe3, 0x94, 0x6c, 0x68, 0x6f, 0xf0, 0xea, 0x6f, 0x89, 0x5a, 0xda, 0x2e, 0x0d, 0x6d, 0x67, 0x12, 0x90, 0x5d, 0xa8, 0x69, 0x0f, 0x0f, 0x93, 0x9b,
0xc3, 0x6e, 0xb6, 0xd2, 0x09, 0x22, 0xff, 0x2e, 0xd4, 0xb4, 0x07, 0x49, 0x55, 0x2b, 0xd2, 0xcf, 0xd7, 0xbe, 0x92, 0xbc, 0xb9, 0x99, 0x95, 0x24, 0x9a, 0xf4, 0x5d, 0xa8, 0xaa, 0x87, 0x57, 0xc9,
0xa1, 0xaa, 0x56, 0x64, 0xbd, 0x5f, 0x7a, 0x00, 0x6b, 0x42, 0x3d, 0x72, 0x42, 0xbf, 0xce, 0xf0, 0x86, 0xf6, 0x30, 0xb0, 0xfe, 0x60, 0xed, 0x66, 0x2b, 0x9d, 0x20, 0xf2, 0xef, 0x42, 0x4d, 0x7b,
0x90, 0xf4, 0xf0, 0x3c, 0xc8, 0x91, 0x2f, 0xa1, 0x22, 0x9f, 0xc1, 0x25, 0xeb, 0xd9, 0xcf, 0x0a, 0x25, 0x55, 0xb5, 0x22, 0xfd, 0x46, 0xab, 0x6a, 0x45, 0xd6, 0xa3, 0xaa, 0x07, 0xb0, 0x26, 0xd4,
0x6f, 0x6e, 0xa4, 0xe0, 0xa2, 0x29, 0x6d, 0x80, 0xe8, 0x41, 0x53, 0x22, 0x3b, 0x9e, 0x7a, 0x3a, 0x23, 0x27, 0xf4, 0xeb, 0x0c, 0x0f, 0x49, 0x0f, 0xcf, 0x83, 0x1c, 0xf9, 0x02, 0x2a, 0xf2, 0x6d,
0x55, 0xcd, 0x4c, 0xc6, 0xeb, 0xa7, 0xbb, 0x50, 0xd3, 0xde, 0x2e, 0x55, 0x63, 0x92, 0x7e, 0xf7, 0x5e, 0xb2, 0x9e, 0xfd, 0xd6, 0xf1, 0xe6, 0x46, 0x0a, 0x2e, 0x9a, 0xd2, 0x06, 0x88, 0x5e, 0x59,
0x54, 0x8d, 0x49, 0xd6, 0x53, 0xa7, 0x3f, 0x80, 0x46, 0xec, 0x11, 0x52, 0xb5, 0x8e, 0xb3, 0x9e, 0x25, 0xb2, 0xe3, 0xa9, 0xf7, 0x5c, 0xd5, 0xcc, 0x64, 0x3c, 0xc9, 0xba, 0x0b, 0x35, 0xed, 0x41,
0x38, 0x55, 0xeb, 0x38, 0xfb, 0xdd, 0xd2, 0x5d, 0xa8, 0x69, 0x0f, 0x83, 0xaa, 0x16, 0xa5, 0x5f, 0x55, 0x35, 0x26, 0xe9, 0xc7, 0x58, 0xd5, 0x98, 0x64, 0xbd, 0xbf, 0xfa, 0x7d, 0x68, 0xc4, 0x5e,
0x27, 0x55, 0x2d, 0xca, 0x78, 0x47, 0x94, 0xed, 0x86, 0xf8, 0xab, 0xa0, 0x6a, 0x37, 0x64, 0x3e, 0x46, 0x55, 0xeb, 0x38, 0xeb, 0xdd, 0x55, 0xb5, 0x8e, 0xb3, 0x1f, 0x53, 0xdd, 0x85, 0x9a, 0xf6,
0x2f, 0xaa, 0x76, 0x43, 0xf6, 0x53, 0xa2, 0x6c, 0xe9, 0xa9, 0x97, 0x48, 0xc8, 0x46, 0x4c, 0x2b, 0x5a, 0xa9, 0x6a, 0x51, 0xfa, 0xc9, 0x54, 0xd5, 0xa2, 0x8c, 0xc7, 0x4d, 0xd9, 0x6e, 0x88, 0x3f,
0x11, 0x3d, 0x69, 0xa2, 0x96, 0x5e, 0xfa, 0xd1, 0x92, 0xc7, 0xb0, 0xa2, 0x16, 0x8d, 0x7a, 0x47, 0x55, 0xaa, 0x76, 0x43, 0xe6, 0x9b, 0xa7, 0x6a, 0x37, 0x64, 0xbf, 0x6f, 0xca, 0x96, 0x9e, 0x7a,
0x24, 0x50, 0x6d, 0xca, 0x7c, 0xad, 0x64, 0xb3, 0x99, 0x4c, 0x7d, 0x90, 0x23, 0x9f, 0x43, 0x59, 0x1e, 0x85, 0x6c, 0xc4, 0xb4, 0x12, 0xd1, 0x3b, 0x2b, 0x6a, 0xe9, 0xa5, 0x5f, 0x52, 0x79, 0x0c,
0x3c, 0xce, 0x40, 0xd6, 0x92, 0x8f, 0x35, 0xf0, 0x46, 0xac, 0x67, 0xbf, 0xe1, 0x40, 0x8e, 0x70, 0x2b, 0x6a, 0xd1, 0xa8, 0xc7, 0x4d, 0x02, 0xd5, 0xa6, 0xcc, 0x27, 0x54, 0x36, 0x9b, 0xc9, 0xd4,
0x43, 0xeb, 0xaf, 0x27, 0xe8, 0x2b, 0x36, 0xe3, 0xc1, 0x85, 0xcd, 0x37, 0xaf, 0x4b, 0x8e, 0x4a, 0x07, 0x39, 0xf2, 0x19, 0x94, 0xc5, 0x8b, 0x11, 0x64, 0x2d, 0xf9, 0x82, 0x04, 0x6f, 0xc4, 0x7a,
0x4c, 0xbe, 0xf8, 0x71, 0xfb, 0xba, 0xc0, 0x5a, 0xf1, 0x12, 0xaf, 0x8b, 0x00, 0xfa, 0x18, 0xea, 0xf6, 0xc3, 0x12, 0xe4, 0x08, 0x37, 0xb4, 0xfe, 0xa4, 0x83, 0xbe, 0x62, 0x33, 0x5e, 0x81, 0xd8,
0xfa, 0x8b, 0x70, 0x44, 0xdf, 0x87, 0xc9, 0xb2, 0x6e, 0x65, 0xa6, 0x89, 0x82, 0x9e, 0xc2, 0xba, 0x7c, 0xfd, 0xba, 0xe4, 0xa8, 0xc4, 0xe4, 0x33, 0x24, 0xb7, 0xaf, 0x8b, 0xf6, 0x15, 0x2f, 0xf1,
0x1a, 0x6f, 0x3d, 0xca, 0x53, 0x40, 0xee, 0x64, 0xc4, 0x7e, 0x8a, 0x8d, 0xfa, 0xcd, 0x6b, 0x83, 0xba, 0xb0, 0xa4, 0x8f, 0xa1, 0xae, 0x3f, 0x53, 0x47, 0xf4, 0x7d, 0x98, 0x2c, 0xeb, 0x56, 0x66,
0x43, 0x3d, 0xc8, 0x21, 0x91, 0x8d, 0x3d, 0xe2, 0x14, 0x11, 0xd9, 0xac, 0xb7, 0xab, 0x22, 0x22, 0x9a, 0x28, 0xe8, 0x4b, 0x58, 0x57, 0xe3, 0xad, 0x87, 0x9e, 0x0a, 0xc8, 0x9d, 0x8c, 0x80, 0x54,
0x9b, 0xfd, 0xf2, 0x53, 0x1b, 0x96, 0xb4, 0x28, 0x55, 0x83, 0x2b, 0x77, 0xa4, 0xd6, 0x7b, 0x3a, 0xb1, 0x51, 0xbf, 0x79, 0x6d, 0xc4, 0xaa, 0x07, 0x39, 0x24, 0xb2, 0xb1, 0x97, 0xa5, 0x22, 0x22,
0x5c, 0xfd, 0x66, 0x96, 0x92, 0x9e, 0xec, 0x40, 0x4d, 0x0f, 0x74, 0xf5, 0x92, 0xec, 0x1b, 0x5a, 0x9b, 0xf5, 0xa0, 0x56, 0x44, 0x64, 0xb3, 0x9f, 0xa3, 0x6a, 0xc3, 0x92, 0x16, 0x3a, 0x6b, 0x70,
0x92, 0x1e, 0x45, 0xfc, 0x41, 0x8e, 0x1c, 0x40, 0x33, 0x19, 0x96, 0x56, 0x6d, 0xe1, 0xac, 0x50, 0xe5, 0x8e, 0xd4, 0x7a, 0x4f, 0xc7, 0xd0, 0xdf, 0xcc, 0x52, 0xd2, 0x93, 0x1d, 0xa8, 0xe9, 0xd1,
0xbe, 0x9b, 0x89, 0xc4, 0x58, 0x30, 0x5b, 0xb6, 0x2e, 0x44, 0xd5, 0xfc, 0xfd, 0x55, 0xcf, 0x4f, 0xb7, 0x5e, 0x90, 0x7d, 0x43, 0x4b, 0xd2, 0x43, 0x9b, 0x3f, 0xc8, 0x91, 0x03, 0x68, 0x26, 0x63,
0x1e, 0x45, 0x1c, 0x2e, 0x87, 0x41, 0x95, 0x96, 0x48, 0xc5, 0x66, 0xdf, 0xcb, 0x3d, 0xc8, 0x91, 0xe5, 0xaa, 0x2d, 0x9c, 0x15, 0x5f, 0x78, 0x33, 0x91, 0x18, 0x8b, 0xb0, 0xcb, 0xd6, 0x85, 0xa8,
0x3d, 0xa8, 0xc7, 0xa2, 0x32, 0xc6, 0x2e, 0x6f, 0x25, 0xba, 0xd9, 0xd2, 0xd3, 0x12, 0xfd, 0x3c, 0x9a, 0x3f, 0x0a, 0xeb, 0xf9, 0xc9, 0xa3, 0x88, 0xc3, 0xe5, 0x30, 0xa8, 0xd2, 0x12, 0xa9, 0xd8,
0x84, 0xc5, 0xb8, 0xd3, 0x89, 0x6a, 0x58, 0xa6, 0x67, 0x8c, 0x9a, 0xbe, 0x6c, 0x4f, 0x15, 0xf2, 0xec, 0x7b, 0xb9, 0x07, 0x39, 0xb2, 0x07, 0xf5, 0x58, 0xa8, 0xc8, 0xd8, 0xe5, 0xad, 0x44, 0x37,
0xb3, 0x50, 0x63, 0x34, 0x59, 0x7a, 0x46, 0x12, 0x8d, 0x4e, 0x27, 0xe7, 0x8c, 0xc3, 0x84, 0xd6, 0x5b, 0x7a, 0x5a, 0xa2, 0x9f, 0x87, 0xb0, 0x18, 0x77, 0x3a, 0x51, 0x0d, 0xcb, 0xf4, 0x8c, 0x51,
0xbc, 0xf0, 0x17, 0xf3, 0x39, 0xec, 0xd7, 0x77, 0xf9, 0x8b, 0xf3, 0xd2, 0x39, 0x8e, 0xcd, 0xff, 0xd3, 0x97, 0xed, 0xa9, 0x42, 0x7e, 0x16, 0x6a, 0x8c, 0x26, 0x4b, 0xcf, 0x48, 0xa2, 0xd1, 0xe9,
0xeb, 0x16, 0x42, 0xf6, 0x78, 0xe5, 0x43, 0x8f, 0xc7, 0x64, 0xb8, 0xa9, 0xe1, 0x08, 0xd8, 0xeb, 0xe4, 0x9c, 0x71, 0x98, 0xd0, 0x9a, 0x17, 0xfe, 0x72, 0x3e, 0x87, 0xfd, 0xfa, 0x0e, 0x7f, 0x06,
0xb5, 0xa1, 0xcd, 0xdb, 0x20, 0xf2, 0xc4, 0xd6, 0xe0, 0x6b, 0x96, 0x45, 0x3e, 0x03, 0x88, 0x9c, 0x5f, 0x3a, 0xc7, 0xb1, 0xf9, 0x7f, 0xd5, 0x42, 0xc8, 0x1e, 0xaf, 0x7c, 0xe8, 0xf1, 0x98, 0x0c,
0x92, 0x49, 0xc2, 0xef, 0x55, 0x6d, 0xa8, 0x0c, 0xbf, 0xe5, 0x0e, 0xdf, 0xef, 0xca, 0xf1, 0x56, 0x37, 0x35, 0x1c, 0x01, 0x7b, 0xb5, 0x36, 0xb4, 0x79, 0x1b, 0x44, 0x9e, 0xd8, 0x1a, 0x7c, 0xc5,
0x3f, 0x92, 0xe3, 0x3e, 0xc0, 0xb1, 0x23, 0x39, 0x59, 0xcc, 0xc7, 0xd0, 0x38, 0xf0, 0xbc, 0xe7, 0xb2, 0xc8, 0xa7, 0x00, 0x91, 0x53, 0x32, 0x49, 0xf8, 0xbd, 0xaa, 0x0d, 0x95, 0xe1, 0xb7, 0xdc,
0xf3, 0x99, 0xba, 0xaa, 0x13, 0x77, 0xfb, 0xda, 0xb7, 0x83, 0xf3, 0xcd, 0x44, 0xb3, 0x48, 0x1b, 0xe1, 0xfb, 0x5d, 0x39, 0xde, 0xea, 0x47, 0x72, 0xdc, 0x07, 0x38, 0x76, 0x24, 0x27, 0x8b, 0xf9,
0x96, 0x15, 0x89, 0x88, 0x3c, 0x7f, 0xe3, 0x48, 0x31, 0xc2, 0x90, 0x28, 0xe0, 0x41, 0x8e, 0x3c, 0x08, 0x1a, 0x07, 0x9e, 0xf7, 0x6c, 0x3e, 0x53, 0x57, 0x75, 0xe2, 0x6e, 0x5f, 0xfb, 0x76, 0x70,
0x84, 0xfa, 0x2e, 0x1d, 0x61, 0xdc, 0x18, 0x74, 0x03, 0x5a, 0x89, 0xb9, 0x94, 0x70, 0xff, 0xa1, 0xbe, 0x99, 0x68, 0x16, 0x69, 0xc3, 0xb2, 0x22, 0x11, 0x91, 0xe7, 0x6f, 0x1c, 0x29, 0x46, 0x18,
0xcd, 0x46, 0x0c, 0x28, 0x49, 0x5c, 0xe4, 0xe8, 0xa6, 0x9f, 0x19, 0x71, 0x6f, 0xb1, 0x18, 0x89, 0x12, 0x05, 0x3c, 0xc8, 0x91, 0x87, 0x50, 0xdf, 0xa5, 0x23, 0x0c, 0x66, 0x83, 0x6e, 0x40, 0x2b,
0x4b, 0x39, 0xbb, 0x3d, 0x85, 0xe5, 0x94, 0xb3, 0x97, 0xa2, 0x6e, 0xd7, 0x39, 0xa0, 0x6d, 0xde, 0x31, 0x97, 0x12, 0xee, 0x3f, 0xb4, 0xd9, 0x88, 0x01, 0x25, 0x89, 0x8b, 0x1c, 0xdd, 0xf4, 0x33,
0xbd, 0x1e, 0x41, 0x94, 0xfb, 0x7d, 0x68, 0xf0, 0xa0, 0xf2, 0x27, 0x94, 0xdf, 0xfb, 0x4e, 0x84, 0x23, 0xee, 0x2d, 0x16, 0x23, 0x71, 0x29, 0x67, 0xb7, 0x2f, 0x61, 0x39, 0xe5, 0xec, 0xa5, 0xa8,
0x0c, 0xd4, 0x2f, 0x95, 0x27, 0x49, 0x12, 0xcf, 0xf0, 0x18, 0x9f, 0xb7, 0xd2, 0x6e, 0x55, 0xab, 0xdb, 0x75, 0x0e, 0x68, 0x9b, 0x77, 0xaf, 0x47, 0x10, 0xe5, 0x7e, 0x0f, 0x1a, 0x3c, 0xd2, 0xfd,
0x79, 0x4d, 0xdf, 0xf4, 0x56, 0xf3, 0x9a, 0x75, 0x81, 0xfb, 0x0b, 0xa8, 0x3d, 0xa6, 0xa1, 0xbc, 0x09, 0xe5, 0xf7, 0xbe, 0x13, 0x71, 0x0c, 0xf5, 0x4b, 0xe5, 0x49, 0x92, 0xc4, 0x33, 0x3c, 0xc6,
0xa7, 0xac, 0xf8, 0xa3, 0xc4, 0xc5, 0xe5, 0xcd, 0x8c, 0xdb, 0xe5, 0xe4, 0x53, 0xcc, 0xaa, 0x62, 0x37, 0xb7, 0xb4, 0x5b, 0xd5, 0x6a, 0x5e, 0xd3, 0x37, 0xbd, 0xd5, 0xbc, 0x66, 0x5d, 0xe0, 0xfe,
0x6e, 0xac, 0x6b, 0xb5, 0xe8, 0x59, 0x97, 0x12, 0x70, 0xc6, 0x7d, 0x68, 0x91, 0x77, 0x54, 0xc3, 0x1c, 0x6a, 0x8f, 0x69, 0x28, 0xef, 0x29, 0x2b, 0xfe, 0x28, 0x71, 0x71, 0x79, 0x33, 0xe3, 0x76,
0xd3, 0x91, 0x96, 0x54, 0xc3, 0xb3, 0x02, 0xf5, 0xfc, 0x2c, 0x1f, 0x01, 0xed, 0x66, 0x74, 0xc4, 0x39, 0xf9, 0x04, 0xb3, 0xaa, 0x98, 0x1b, 0xeb, 0x5a, 0x2d, 0x7a, 0xd6, 0xa5, 0x04, 0x9c, 0x71,
0x82, 0x25, 0x2f, 0x51, 0xab, 0xe6, 0xeb, 0xe8, 0x8f, 0x00, 0x06, 0xa1, 0x37, 0xdb, 0xb5, 0xe9, 0x1f, 0x5a, 0x38, 0x20, 0xd5, 0xf0, 0x74, 0xf8, 0x27, 0xd5, 0xf0, 0xac, 0xe8, 0x41, 0x3f, 0xcb,
0xd4, 0x73, 0x23, 0x9a, 0x10, 0xdd, 0xc9, 0x8d, 0x36, 0xa2, 0x76, 0x31, 0x97, 0x7c, 0xa5, 0xf1, 0x47, 0x40, 0xbb, 0x19, 0x1d, 0xb1, 0x60, 0xc9, 0x4b, 0xd4, 0xaa, 0xf9, 0x3a, 0xfa, 0x23, 0x80,
0xa6, 0xb1, 0x29, 0x91, 0xd3, 0x7e, 0xed, 0xb5, 0x5d, 0xd5, 0x9d, 0x8c, 0xab, 0xbb, 0x48, 0x24, 0x41, 0xe8, 0xcd, 0x76, 0x6d, 0x3a, 0xf5, 0xdc, 0x88, 0x26, 0x44, 0x77, 0x72, 0xa3, 0x8d, 0xa8,
0x20, 0xf2, 0xa5, 0x53, 0x9c, 0x66, 0xca, 0x4d, 0x4f, 0xed, 0xf5, 0x0c, 0xc7, 0xbb, 0xef, 0x41, 0x5d, 0xcc, 0x25, 0x5f, 0x69, 0xbc, 0x69, 0x6c, 0x4a, 0xe4, 0xb4, 0x5f, 0x7b, 0x6d, 0x57, 0x75,
0x35, 0x72, 0x42, 0xda, 0x88, 0xc2, 0x80, 0xc5, 0x5c, 0x96, 0x14, 0xf5, 0x4e, 0x3b, 0x00, 0xf5, 0x27, 0xe3, 0xea, 0x2e, 0x12, 0x09, 0x88, 0x7c, 0xe9, 0x14, 0xa7, 0x99, 0x72, 0xd3, 0x53, 0x7b,
0x60, 0x85, 0x37, 0x47, 0x1d, 0x7f, 0x78, 0x57, 0x53, 0xbd, 0xce, 0x96, 0xf6, 0xbc, 0x51, 0xfb, 0x3d, 0xc3, 0xf1, 0xee, 0xbb, 0x50, 0x8d, 0x9c, 0x90, 0x36, 0xa2, 0xd8, 0x64, 0x31, 0x97, 0x25,
0x27, 0xcb, 0x7f, 0x84, 0xed, 0x9f, 0x94, 0x83, 0x81, 0xda, 0x3f, 0xd7, 0x39, 0x96, 0xa8, 0xfd, 0x45, 0xbd, 0xd3, 0x0e, 0x40, 0x3d, 0x58, 0xe1, 0xcd, 0x51, 0xc7, 0x1f, 0xde, 0xd5, 0x54, 0x4f,
0x73, 0xbd, 0x6f, 0x42, 0x0f, 0x56, 0x32, 0x5c, 0x05, 0xc8, 0x5b, 0x52, 0xb0, 0xb9, 0xd6, 0x8d, 0xc6, 0xa5, 0x3d, 0x6f, 0xd4, 0xfe, 0xc9, 0xf2, 0x1f, 0x61, 0xfb, 0x27, 0xe5, 0x60, 0xa0, 0xf6,
0x60, 0x33, 0xd3, 0xa4, 0x4c, 0x86, 0xb0, 0xc1, 0xf3, 0xb4, 0x27, 0x93, 0x84, 0x65, 0xfa, 0x4d, 0xcf, 0x75, 0x8e, 0x25, 0x6a, 0xff, 0x5c, 0xef, 0x9b, 0xd0, 0x83, 0x95, 0x0c, 0x57, 0x01, 0xf2,
0x2d, 0x43, 0x86, 0xb5, 0x3d, 0xc6, 0xca, 0x24, 0x2c, 0xee, 0x3d, 0x68, 0x26, 0x8d, 0xba, 0xe4, 0x86, 0x14, 0x6c, 0xae, 0x75, 0x23, 0xd8, 0xcc, 0x34, 0x29, 0x93, 0x21, 0x6c, 0xf0, 0x3c, 0xed,
0x7a, 0xf4, 0xcd, 0x3b, 0x31, 0x96, 0x3d, 0x6d, 0x08, 0x26, 0x4f, 0x95, 0x69, 0x39, 0xd1, 0xc6, 0xc9, 0x24, 0x61, 0x99, 0x7e, 0x5d, 0xcb, 0x90, 0x61, 0x6d, 0x8f, 0xb1, 0x32, 0x09, 0x8b, 0x7b,
0x3b, 0xd1, 0x2b, 0xa3, 0x99, 0x86, 0x70, 0x25, 0x0d, 0x64, 0x5a, 0xa6, 0xc9, 0xcf, 0xc1, 0x46, 0x0f, 0x9a, 0x49, 0xa3, 0x2e, 0xb9, 0x1e, 0x7d, 0xf3, 0x4e, 0x8c, 0x65, 0x4f, 0x1b, 0x82, 0xc9,
0x72, 0x45, 0xcb, 0x92, 0xef, 0x66, 0x0d, 0xd7, 0xb5, 0xac, 0x5c, 0xbc, 0x43, 0x0f, 0x72, 0x8c, 0x97, 0xca, 0xb4, 0x9c, 0x68, 0xe3, 0x9d, 0xe8, 0xe9, 0xd3, 0x4c, 0x43, 0xb8, 0x92, 0x06, 0x32,
0x10, 0xeb, 0x06, 0x60, 0xb5, 0x90, 0x32, 0x2c, 0xd1, 0x6a, 0x21, 0x65, 0x5a, 0x8c, 0x8f, 0x60, 0x2d, 0xd3, 0xe4, 0xe7, 0x60, 0x23, 0xb9, 0xa2, 0x65, 0xc9, 0x77, 0xb3, 0x86, 0xeb, 0x5a, 0x56,
0x29, 0x61, 0xfb, 0x55, 0x6c, 0x70, 0xb6, 0xb5, 0x58, 0xb1, 0xc1, 0xd7, 0x99, 0x8c, 0x07, 0xd0, 0x2e, 0xde, 0xa1, 0x07, 0x39, 0x46, 0x88, 0x75, 0x03, 0xb0, 0x5a, 0x48, 0x19, 0x96, 0x68, 0xb5,
0x4c, 0x5a, 0x75, 0xd5, 0x5c, 0x5f, 0x63, 0x29, 0xde, 0xbc, 0x73, 0x6d, 0x7a, 0xbc, 0x99, 0x9a, 0x90, 0x32, 0x2d, 0xc6, 0x47, 0xb0, 0x94, 0xb0, 0xfd, 0x2a, 0x36, 0x38, 0xdb, 0x5a, 0xac, 0xd8,
0xfd, 0x33, 0xd6, 0xcc, 0xb4, 0xd5, 0x36, 0xd6, 0xcc, 0x0c, 0xeb, 0xeb, 0xf6, 0x7b, 0x3f, 0xff, 0xe0, 0xeb, 0x4c, 0xc6, 0x03, 0x68, 0x26, 0xad, 0xba, 0x6a, 0xae, 0xaf, 0xb1, 0x14, 0x6f, 0xde,
0xad, 0x33, 0x27, 0x3c, 0x9f, 0x9f, 0x6c, 0x8d, 0xbc, 0xe9, 0x87, 0x13, 0xa9, 0xd5, 0x10, 0x81, 0xb9, 0x36, 0x3d, 0xde, 0x4c, 0xcd, 0xfe, 0x19, 0x6b, 0x66, 0xda, 0x6a, 0x1b, 0x6b, 0x66, 0x86,
0x14, 0x3e, 0x9c, 0xb8, 0xe3, 0x0f, 0xb1, 0x80, 0x93, 0x85, 0x99, 0xef, 0x85, 0xde, 0xc7, 0xff, 0xf5, 0x75, 0xfb, 0x9d, 0x9f, 0xff, 0xd6, 0x99, 0x13, 0x9e, 0xcf, 0x4f, 0xb6, 0x46, 0xde, 0xf4,
0x37, 0x00, 0x00, 0xff, 0xff, 0xe1, 0xea, 0x86, 0x7c, 0x00, 0x95, 0x00, 0x00, 0x83, 0x89, 0xd4, 0x6a, 0x88, 0x40, 0x0a, 0x1f, 0x4c, 0xdc, 0xf1, 0x07, 0x58, 0xc0, 0xc9, 0xc2,
0xcc, 0xf7, 0x42, 0xef, 0xa3, 0xff, 0x1f, 0x00, 0x00, 0xff, 0xff, 0xb7, 0x5d, 0x18, 0x9c, 0x95,
0x95, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.

View File

@ -2493,12 +2493,22 @@ message Hop {
/* /*
An optional TLV record that signals the use of an MPP payment. If present, An optional TLV record that signals the use of an MPP payment. If present,
the receiver will enforce that that the same mpp_record is included in the the receiver will enforce that the same mpp_record is included in the final
final hop payload of all non-zero payments in the HTLC set. If empty, a hop payload of all non-zero payments in the HTLC set. If empty, a regular
regular single-shot payment is or was attempted. single-shot payment is or was attempted.
*/ */
MPPRecord mpp_record = 10; MPPRecord mpp_record = 10;
/*
An optional TLV record that signals the use of an AMP payment. If present,
the receiver will treat all received payments including the same
(payment_addr, set_id) pair as being part of one logical payment. The
payment will be settled by XORing the root_share's together and deriving the
child hashes and preimages according to BOLT XX. Must be used in conjunction
with mpp_record.
*/
AMPRecord amp_record = 12;
/* /*
An optional set of key-value TLV records. This is useful within the context An optional set of key-value TLV records. This is useful within the context
of the SendToRoute call as it allows callers to specify arbitrary K-V pairs of the SendToRoute call as it allows callers to specify arbitrary K-V pairs
@ -2525,6 +2535,14 @@ message MPPRecord {
int64 total_amt_msat = 10; int64 total_amt_msat = 10;
} }
message AMPRecord {
bytes root_share = 1;
bytes set_id = 2;
uint32 child_index = 3;
}
/* /*
A path through the channel graph which runs over one or more channels in 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 succession. This struct carries all the information required to craft the

View File

@ -2536,6 +2536,23 @@
}, },
"description": "Details specific to AMP HTLCs." "description": "Details specific to AMP HTLCs."
}, },
"lnrpcAMPRecord": {
"type": "object",
"properties": {
"root_share": {
"type": "string",
"format": "byte"
},
"set_id": {
"type": "string",
"format": "byte"
},
"child_index": {
"type": "integer",
"format": "int64"
}
}
},
"lnrpcAbandonChannelResponse": { "lnrpcAbandonChannelResponse": {
"type": "object" "type": "object"
}, },
@ -4025,7 +4042,11 @@
}, },
"mpp_record": { "mpp_record": {
"$ref": "#/definitions/lnrpcMPPRecord", "$ref": "#/definitions/lnrpcMPPRecord",
"description": "An optional TLV record that signals 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." "description": "An optional TLV record that signals the use of an MPP payment. If present,\nthe receiver will enforce that the same mpp_record is included in the final\nhop payload of all non-zero payments in the HTLC set. If empty, a regular\nsingle-shot payment is or was attempted."
},
"amp_record": {
"$ref": "#/definitions/lnrpcAMPRecord",
"description": "An optional TLV record that signals the use of an AMP payment. If present,\nthe receiver will treat all received payments including the same\n(payment_addr, set_id) pair as being part of one logical payment. The\npayment will be settled by XORing the root_share's together and deriving the\nchild hashes and preimages according to BOLT XX. Must be used in conjunction\nwith mpp_record."
}, },
"custom_records": { "custom_records": {
"type": "object", "type": "object",

View File

@ -0,0 +1,208 @@
package itest
import (
"context"
"crypto/rand"
"time"
"github.com/btcsuite/btcutil"
"github.com/lightningnetwork/lnd/amp"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
"github.com/lightningnetwork/lnd/lntest"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/stretchr/testify/require"
)
func testSendToRouteAMP(net *lntest.NetworkHarness, t *harnessTest) {
ctxb := context.Background()
ctx := newMppTestContext(t, net)
defer ctx.shutdownNodes()
const (
paymentAmt = btcutil.Amount(300000)
numShards = 3
shardAmt = paymentAmt / numShards
chanAmt = shardAmt * 3 / 2
)
// Set up a network with three different paths Alice <-> Bob.
// _ Eve _
// / \
// Alice -- Carol ---- Bob
// \ /
// \__ Dave ____/
//
ctx.openChannel(ctx.carol, ctx.bob, chanAmt)
ctx.openChannel(ctx.dave, ctx.bob, chanAmt)
ctx.openChannel(ctx.alice, ctx.dave, chanAmt)
ctx.openChannel(ctx.eve, ctx.bob, chanAmt)
ctx.openChannel(ctx.carol, ctx.eve, chanAmt)
// Since the channel Alice-> Carol will have to carry two
// shards, we make it larger.
ctx.openChannel(ctx.alice, ctx.carol, chanAmt+shardAmt)
defer ctx.closeChannels()
ctx.waitForChannels()
// We'll send shards along three routes from Alice.
sendRoutes := [numShards][]*lntest.HarnessNode{
{ctx.carol, ctx.bob},
{ctx.dave, ctx.bob},
{ctx.carol, ctx.eve, ctx.bob},
}
payAddr := make([]byte, 32)
_, err := rand.Read(payAddr)
require.NoError(t.t, err)
setID := make([]byte, 32)
_, err = rand.Read(setID)
require.NoError(t.t, err)
var sharer amp.Sharer
sharer, err = amp.NewSeedSharer()
require.NoError(t.t, err)
childPreimages := make(map[lntypes.Preimage]uint32)
responses := make(chan *lnrpc.HTLCAttempt, len(sendRoutes))
for i, hops := range sendRoutes {
// Build a route for the specified hops.
r, err := ctx.buildRoute(ctxb, shardAmt, net.Alice, hops)
if err != nil {
t.Fatalf("unable to build route: %v", err)
}
// Set the MPP records to indicate this is a payment shard.
hop := r.Hops[len(r.Hops)-1]
hop.TlvPayload = true
hop.MppRecord = &lnrpc.MPPRecord{
PaymentAddr: payAddr,
TotalAmtMsat: int64(paymentAmt * 1000),
}
var child *amp.Child
if i < len(sendRoutes)-1 {
var left amp.Sharer
left, sharer, err = sharer.Split()
require.NoError(t.t, err)
child = left.Child(uint32(i))
} else {
child = sharer.Child(uint32(i))
}
childPreimages[child.Preimage] = child.Index
hop.AmpRecord = &lnrpc.AMPRecord{
RootShare: child.Share[:],
SetId: setID,
ChildIndex: child.Index,
}
// Send the shard.
sendReq := &routerrpc.SendToRouteRequest{
PaymentHash: child.Hash[:],
Route: r,
}
// We'll send all shards in their own goroutine, since SendToRoute will
// block as long as the payment is in flight.
go func() {
ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)
resp, err := net.Alice.RouterClient.SendToRouteV2(ctxt, sendReq)
if err != nil {
t.Fatalf("unable to send payment: %v", err)
}
responses <- resp
}()
}
// Assert that all of the child preimages are unique.
require.Equal(t.t, len(sendRoutes), len(childPreimages))
// Make a copy of the childPreimages map for validating the resulting
// invoice.
childPreimagesCopy := make(map[lntypes.Preimage]uint32)
for preimage, childIndex := range childPreimages {
childPreimagesCopy[preimage] = childIndex
}
// Wait for all responses to be back, and check that they all
// succeeded.
for range sendRoutes {
var resp *lnrpc.HTLCAttempt
select {
case resp = <-responses:
case <-time.After(defaultTimeout):
t.Fatalf("response not received")
}
if resp.Failure != nil {
t.Fatalf("received payment failure : %v", resp.Failure)
}
preimage, err := lntypes.MakePreimage(resp.Preimage)
require.NoError(t.t, err)
// Assert that the response includes one of our child preimages.
_, ok := childPreimages[preimage]
require.True(t.t, ok)
// Remove this preimage from out set so that we ensure all
// responses have a unique child preimage.
delete(childPreimages, preimage)
}
childPreimages = childPreimagesCopy
// Fetch Bob's invoices.
invoiceResp, err := net.Bob.ListInvoices(
ctxb, &lnrpc.ListInvoiceRequest{},
)
require.NoError(t.t, err)
// There should only be one invoice.
require.Equal(t.t, 1, len(invoiceResp.Invoices))
rpcInvoice := invoiceResp.Invoices[0]
// Assert that the invoice is settled for the total payment amount and
// has the correct payment address.
require.True(t.t, rpcInvoice.Settled)
require.Equal(t.t, lnrpc.Invoice_SETTLED, rpcInvoice.State)
require.Equal(t.t, int64(paymentAmt), rpcInvoice.AmtPaidSat)
require.Equal(t.t, int64(paymentAmt*1000), rpcInvoice.AmtPaidMsat)
require.Equal(t.t, payAddr, rpcInvoice.PaymentAddr)
// Finally, assert that the proper set id is recorded for each htlc, and
// that the preimage hash pair is valid.
require.Equal(t.t, numShards, len(rpcInvoice.Htlcs))
for _, htlc := range rpcInvoice.Htlcs {
require.NotNil(t.t, htlc.Amp)
require.Equal(t.t, setID, htlc.Amp.SetId)
// Parse the child hash and child preimage, and assert they are
// well-formed.
childHash, err := lntypes.MakeHash(htlc.Amp.Hash)
require.NoError(t.t, err)
childPreimage, err := lntypes.MakePreimage(htlc.Amp.Preimage)
require.NoError(t.t, err)
// Assert that the preimage actually matches the hashes.
validPreimage := childPreimage.Matches(childHash)
require.True(t.t, validPreimage)
// Assert that the HTLC includes one of our child preimages.
childIndex, ok := childPreimages[childPreimage]
require.True(t.t, ok)
// Assert that the correct child index is reflected.
require.Equal(t.t, childIndex, htlc.Amp.ChildIndex)
// Remove this preimage from our set so that we ensure all HTLCs
// have a unique child preimage.
delete(childPreimages, childPreimage)
}
}

View File

@ -74,36 +74,6 @@ func testSendToRouteMultiPath(net *lntest.NetworkHarness, t *harnessTest) {
payAddr := decodeResp.PaymentAddr payAddr := decodeResp.PaymentAddr
// Helper function for Alice to build a route from pubkeys.
buildRoute := func(amt btcutil.Amount, hops []*lntest.HarnessNode) (
*lnrpc.Route, error) {
rpcHops := make([][]byte, 0, len(hops))
for _, hop := range hops {
k := hop.PubKeyStr
pubkey, err := route.NewVertexFromStr(k)
if err != nil {
return nil, fmt.Errorf("error parsing %v: %v",
k, err)
}
rpcHops = append(rpcHops, pubkey[:])
}
req := &routerrpc.BuildRouteRequest{
AmtMsat: int64(amt * 1000),
FinalCltvDelta: chainreg.DefaultBitcoinTimeLockDelta,
HopPubkeys: rpcHops,
}
ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)
routeResp, err := net.Alice.RouterClient.BuildRoute(ctxt, req)
if err != nil {
return nil, err
}
return routeResp.Route, nil
}
// We'll send shards along three routes from Alice. // We'll send shards along three routes from Alice.
sendRoutes := [][]*lntest.HarnessNode{ sendRoutes := [][]*lntest.HarnessNode{
{ctx.carol, ctx.bob}, {ctx.carol, ctx.bob},
@ -114,7 +84,7 @@ func testSendToRouteMultiPath(net *lntest.NetworkHarness, t *harnessTest) {
responses := make(chan *lnrpc.HTLCAttempt, len(sendRoutes)) responses := make(chan *lnrpc.HTLCAttempt, len(sendRoutes))
for _, hops := range sendRoutes { for _, hops := range sendRoutes {
// Build a route for the specified hops. // Build a route for the specified hops.
r, err := buildRoute(shardAmt, hops) r, err := ctx.buildRoute(ctxb, shardAmt, net.Alice, hops)
if err != nil { if err != nil {
t.Fatalf("unable to build route: %v", err) t.Fatalf("unable to build route: %v", err)
} }
@ -394,3 +364,34 @@ func (c *mppTestContext) waitForChannels() {
} }
} }
} }
// Helper function for Alice to build a route from pubkeys.
func (c *mppTestContext) buildRoute(ctxb context.Context, amt btcutil.Amount,
sender *lntest.HarnessNode, hops []*lntest.HarnessNode) (*lnrpc.Route,
error) {
rpcHops := make([][]byte, 0, len(hops))
for _, hop := range hops {
k := hop.PubKeyStr
pubkey, err := route.NewVertexFromStr(k)
if err != nil {
return nil, fmt.Errorf("error parsing %v: %v",
k, err)
}
rpcHops = append(rpcHops, pubkey[:])
}
req := &routerrpc.BuildRouteRequest{
AmtMsat: int64(amt * 1000),
FinalCltvDelta: chainreg.DefaultBitcoinTimeLockDelta,
HopPubkeys: rpcHops,
}
ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)
routeResp, err := sender.RouterClient.BuildRoute(ctxt, req)
if err != nil {
return nil, err
}
return routeResp.Route, nil
}

View File

@ -266,6 +266,10 @@ var allTestCases = []*testCase{
name: "sendtoroute multi path payment", name: "sendtoroute multi path payment",
test: testSendToRouteMultiPath, test: testSendToRouteMultiPath,
}, },
{
name: "sendtoroute amp",
test: testSendToRouteAMP,
},
{ {
name: "send multi path payment", name: "send multi path payment",
test: testSendMultiPathPayment, test: testSendMultiPathPayment,

View File

@ -129,6 +129,16 @@ const (
// transactions, which also imply anchor commitments. // transactions, which also imply anchor commitments.
AnchorsZeroFeeHtlcTxOptional FeatureBit = 23 AnchorsZeroFeeHtlcTxOptional FeatureBit = 23
// AMPRequired is a required feature bit that signals that the receiver
// of a payment supports accepts spontaneous payments, i.e.
// sender-generated preimages according to BOLT XX.
AMPRequired FeatureBit = 30
// AMPOptional is an optional feature bit that signals that the receiver
// of a payment supports accepts spontaneous payments, i.e.
// sender-generated preimages according to BOLT XX.
AMPOptional FeatureBit = 31
// maxAllowedSize is a maximum allowed size of feature vector. // maxAllowedSize is a maximum allowed size of feature vector.
// //
// NOTE: Within the protocol, the maximum allowed message size is 65535 // NOTE: Within the protocol, the maximum allowed message size is 65535
@ -172,6 +182,8 @@ var Features = map[FeatureBit]string{
AnchorsZeroFeeHtlcTxOptional: "anchors-zero-fee-htlc-tx", AnchorsZeroFeeHtlcTxOptional: "anchors-zero-fee-htlc-tx",
WumboChannelsRequired: "wumbo-channels", WumboChannelsRequired: "wumbo-channels",
WumboChannelsOptional: "wumbo-channels", WumboChannelsOptional: "wumbo-channels",
AMPRequired: "amp",
AMPOptional: "amp",
} }
// RawFeatureVector represents a set of feature bits as defined in BOLT-09. A // RawFeatureVector represents a set of feature bits as defined in BOLT-09. A

View File

@ -9,19 +9,19 @@ import (
// AMPOnionType is the type used in the onion to reference the AMP fields: // AMPOnionType is the type used in the onion to reference the AMP fields:
// root_share, set_id, and child_index. // root_share, set_id, and child_index.
const AMPOnionType tlv.Type = 10 const AMPOnionType tlv.Type = 14
// AMP is a record that encodes the fields necessary for atomic multi-path // AMP is a record that encodes the fields necessary for atomic multi-path
// payments. // payments.
type AMP struct { type AMP struct {
rootShare [32]byte rootShare [32]byte
setID [32]byte setID [32]byte
childIndex uint16 childIndex uint32
} }
// NewAMP generate a new AMP record with the given root_share, set_id, and // NewAMP generate a new AMP record with the given root_share, set_id, and
// child_index. // child_index.
func NewAMP(rootShare, setID [32]byte, childIndex uint16) *AMP { func NewAMP(rootShare, setID [32]byte, childIndex uint32) *AMP {
return &AMP{ return &AMP{
rootShare: rootShare, rootShare: rootShare,
setID: setID, setID: setID,
@ -40,7 +40,7 @@ func (a *AMP) SetID() [32]byte {
} }
// ChildIndex returns the child index contained in the AMP record. // ChildIndex returns the child index contained in the AMP record.
func (a *AMP) ChildIndex() uint16 { func (a *AMP) ChildIndex() uint32 {
return a.childIndex return a.childIndex
} }
@ -55,7 +55,7 @@ func AMPEncoder(w io.Writer, val interface{}, buf *[8]byte) error {
return err return err
} }
return tlv.ETUint16T(w, v.childIndex, buf) return tlv.ETUint32T(w, v.childIndex, buf)
} }
return tlv.NewTypeForEncodingErr(val, "AMP") return tlv.NewTypeForEncodingErr(val, "AMP")
} }
@ -69,7 +69,7 @@ const (
// maxAMPLength is the maximum legnth of a serialized AMP TLV record, // maxAMPLength is the maximum legnth of a serialized AMP TLV record,
// which occurs when the truncated endoing of a child_index takes 2 // which occurs when the truncated endoing of a child_index takes 2
// bytes. // bytes.
maxAMPLength = 66 maxAMPLength = 68
) )
// AMPDecoder reads the AMP record from the provided io.Reader. // AMPDecoder reads the AMP record from the provided io.Reader.
@ -83,7 +83,7 @@ func AMPDecoder(r io.Reader, val interface{}, buf *[8]byte, l uint64) error {
return err return err
} }
return tlv.DTUint16(r, &v.childIndex, buf, l-64) return tlv.DTUint32(r, &v.childIndex, buf, l-minAMPLength)
} }
return tlv.NewTypeForDecodingErr(val, "AMP", l, maxAMPLength) return tlv.NewTypeForDecodingErr(val, "AMP", l, maxAMPLength)
} }
@ -97,7 +97,7 @@ func (a *AMP) Record() tlv.Record {
// PayloadSize returns the size this record takes up in encoded form. // PayloadSize returns the size this record takes up in encoded form.
func (a *AMP) PayloadSize() uint64 { func (a *AMP) PayloadSize() uint64 {
return 32 + 32 + tlv.SizeTUint16(a.childIndex) return 32 + 32 + tlv.SizeTUint32(a.childIndex)
} }
// String returns a human-readble description of the amp payload fields. // String returns a human-readble description of the amp payload fields.

View File

@ -21,7 +21,7 @@ var (
testAddr = [32]byte{0x01, 0x02} testAddr = [32]byte{0x01, 0x02}
testShare = [32]byte{0x03, 0x04} testShare = [32]byte{0x03, 0x04}
testSetID = [32]byte{0x05, 0x06} testSetID = [32]byte{0x05, 0x06}
testChildIndex = uint16(17) testChildIndex = uint32(17)
) )
var recordEncDecTests = []recordEncDecTest{ var recordEncDecTests = []recordEncDecTest{