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

@ -8,6 +8,7 @@ import (
"time"
"github.com/lightningnetwork/lnd/clock"
"github.com/lightningnetwork/lnd/feature"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/record"
@ -16,7 +17,15 @@ import (
var (
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) {
@ -1208,23 +1217,30 @@ func TestInvoiceRef(t *testing.T) {
// An InvoiceRef by hash should return the provided hash and a nil
// payment addr.
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.SetID())
// An InvoiceRef by hash and addr should return the payment hash and
// payment addr passed to the constructor.
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, (*[32]byte)(nil), refByHashAndAddr.SetID())
// An InvoiceRef by set id should return an empty pay hash, a nil pay
// addr, and a reference to the given set id.
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, &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
@ -1366,7 +1382,7 @@ func TestSetIDIndex(t *testing.T) {
invoice.AmtPaid = amt
invoice.SettleDate = dbInvoice.SettleDate
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.
@ -1406,9 +1422,9 @@ func TestSetIDIndex(t *testing.T) {
invoice.AmtPaid += 2 * amt
invoice.SettleDate = dbInvoice.SettleDate
invoice.Htlcs = map[CircuitKey]*InvoiceHTLC{
{HtlcID: 0}: makeAMPInvoiceHTLC(amt, *setID, preimage),
{HtlcID: 1}: makeAMPInvoiceHTLC(amt, *setID2, preimage),
{HtlcID: 2}: makeAMPInvoiceHTLC(amt, *setID2, preimage),
{HtlcID: 0}: makeAMPInvoiceHTLC(amt, *setID, payHash, &preimage),
{HtlcID: 1}: makeAMPInvoiceHTLC(amt, *setID2, payHash, nil),
{HtlcID: 2}: makeAMPInvoiceHTLC(amt, *setID2, payHash, nil),
}
// 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,
preimage lntypes.Preimage) *InvoiceHTLC {
hash lntypes.Hash, preimage *lntypes.Preimage) *InvoiceHTLC {
return &InvoiceHTLC{
Amt: amt,
@ -1462,8 +1478,8 @@ func makeAMPInvoiceHTLC(amt lnwire.MilliSatoshi, setID [32]byte,
CustomRecords: make(record.CustomSet),
AMP: &InvoiceHtlcAMPData{
Record: *record.NewAMP([32]byte{}, setID, 0),
Hash: preimage.Hash(),
Preimage: &preimage,
Hash: hash,
Preimage: preimage,
},
}
}
@ -1480,18 +1496,23 @@ func updateAcceptAMPHtlc(id uint64, amt lnwire.MilliSatoshi,
noRecords := make(record.CustomSet)
var state *InvoiceStateUpdateDesc
var (
state *InvoiceStateUpdateDesc
preimage *lntypes.Preimage
)
if accept {
state = &InvoiceStateUpdateDesc{
NewState: ContractAccepted,
SetID: setID,
}
pre := *invoice.Terms.PaymentPreimage
preimage = &pre
}
ampData := &InvoiceHtlcAMPData{
Record: *record.NewAMP([32]byte{}, *setID, 0),
Hash: invoice.Terms.PaymentPreimage.Hash(),
Preimage: invoice.Terms.PaymentPreimage,
Preimage: preimage,
}
update := &InvoiceUpdateDesc{
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
// if all delete references are valid, or will fail otherwise.
func TestDeleteInvoices(t *testing.T) {
@ -1619,3 +2426,30 @@ func TestDeleteInvoices(t *testing.T) {
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,
))
}

@ -6,9 +6,11 @@ import (
"errors"
"fmt"
"io"
"strings"
"time"
"github.com/lightningnetwork/lnd/channeldb/kvdb"
"github.com/lightningnetwork/lnd/feature"
"github.com/lightningnetwork/lnd/htlcswitch/hop"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwire"
@ -115,6 +117,19 @@ var (
// match the invoice hash.
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
// that already has HTLCs.
ErrInvoiceHasHtlcs = errors.New("cannot add invoice with htlcs")
@ -122,6 +137,19 @@ var (
// ErrEmptyHTLCSet is returned when attempting to accept or settle and
// HTLC set that has no HTLCs.
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
@ -198,7 +226,7 @@ type InvoiceRef struct {
// payHash is the payment hash of the target invoice. All invoices are
// currently indexed by payment hash. This value will be used as a
// fallback when no payment address is known.
payHash lntypes.Hash
payHash *lntypes.Hash
// payAddr is the payment addr of the target invoice. Newer invoices
// (0.11 and up) are indexed by payment address in addition to payment
@ -220,7 +248,7 @@ type InvoiceRef struct {
// its payment hash.
func InvoiceRefByHash(payHash lntypes.Hash) InvoiceRef {
return InvoiceRef{
payHash: payHash,
payHash: &payHash,
}
}
@ -231,11 +259,19 @@ func InvoiceRefByHashAndAddr(payHash lntypes.Hash,
payAddr [32]byte) InvoiceRef {
return InvoiceRef{
payHash: payHash,
payHash: &payHash,
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
// invoice with the provided setID. If the invoice is not found, the query will
// not fallback to payHash or payAddr.
@ -245,9 +281,15 @@ func InvoiceRefBySetID(setID [32]byte) InvoiceRef {
}
}
// PayHash returns the target invoice's payment hash.
func (r InvoiceRef) PayHash() lntypes.Hash {
return r.payHash
// PayHash returns the optional payment hash of the target invoice.
//
// 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.
@ -274,10 +316,17 @@ func (r InvoiceRef) SetID() *[32]byte {
// String returns a human-readable representation of an InvoiceRef.
func (r InvoiceRef) String() string {
if r.payAddr != nil {
return fmt.Sprintf("(pay_hash=%v, pay_addr=%x)", r.payHash, *r.payAddr)
var ids []string
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.
@ -499,6 +548,21 @@ type InvoiceHTLC struct {
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,
// 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.
@ -616,6 +680,11 @@ type InvoiceStateUpdateDesc struct {
// Preimage must be set to the preimage when NewState is settled.
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
// invoice as part of a larger AMP payment. This value will be nil for
// 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")
}
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")
}
@ -879,19 +958,27 @@ func fetchInvoiceNumByRef(invoiceIndex, payAddrIndex, setIDIndex kvdb.RBucket,
payHash := ref.PayHash()
payAddr := ref.PayAddr()
var (
invoiceNumByHash = invoiceIndex.Get(payHash[:])
invoiceNumByAddr []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 {
invoiceNumByAddr = payAddrIndex.Get(payAddr[:])
getInvoiceNumByHash := func() []byte {
if payHash != nil {
return invoiceIndex.Get(payHash[:])
}
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 {
// 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 invoices by payment addr only.
case invoiceNumByAddr != nil:
return invoiceNumByAddr, nil
// If we were only able to reference the invoice by hash, return the
// corresponding invoice number. This can happen when no payment address
// was provided, or if it didn't match anything in our records.
@ -1684,21 +1775,6 @@ func copySlice(src []byte) []byte {
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.
func copyInvoice(src *Invoice) *Invoice {
dest := Invoice{
@ -1725,7 +1801,7 @@ func copyInvoice(src *Invoice) *Invoice {
}
for k, v := range src.Htlcs {
dest.Htlcs[k] = copyInvoiceHTLC(v)
dest.Htlcs[k] = v.Copy()
}
return &dest
@ -1733,7 +1809,7 @@ func copyInvoice(src *Invoice) *Invoice {
// updateInvoice fetches the invoice, obtains the update descriptor from the
// 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,
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
// and recalculate the total amount paid to the invoice.
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
// implications for the states of the individual htlcs. Align
// 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.
func updateInvoiceState(invoice *Invoice, hash lntypes.Hash,
func updateInvoiceState(invoice *Invoice, hash *lntypes.Hash,
update InvoiceStateUpdateDesc) error {
// Returning to open is never allowed from any state.
@ -1950,9 +2044,14 @@ func updateInvoiceState(invoice *Invoice, hash lntypes.Hash,
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.
case update.Preimage != nil:
if update.Preimage.Hash() != hash {
if update.Preimage.Hash() != *hash {
return ErrInvoicePreimageMismatch
}
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
// the invoice level. For AMP HTLCs, verify that the
// per-HTLC preimage-hash pair is valid.
if setID != nil && !htlc.AMP.Preimage.Matches(htlc.AMP.Hash) {
return fmt.Errorf("AMP preimage mismatch, "+
"preimage=%v hash=%v", *htlc.AMP.Preimage,
htlc.AMP.Hash)
switch {
// Non-AMP HTLCs can be settle immediately since we
// 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
@ -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
// ContractSettled.
if htlc.State == HtlcStateSettled {
return fmt.Errorf("cannot have a settled htlc with "+
"invoice in state %v", invState)
return ErrHTLCAlreadySettled
}
switch invState {

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

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

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

@ -119,6 +119,7 @@ func NewPayloadFromReader(r io.Reader) (*Payload, error) {
amt uint64
cltv uint32
mpp = &record.MPP{}
amp = &record.AMP{}
)
tlvStream, err := tlv.NewStream(
@ -126,6 +127,7 @@ func NewPayloadFromReader(r io.Reader) (*Payload, error) {
record.NewLockTimeRecord(&cltv),
record.NewNextHopIDRecord(&cid),
mpp.Record(),
amp.Record(),
)
if err != nil {
return nil, err
@ -160,6 +162,12 @@ func NewPayloadFromReader(r io.Reader) (*Payload, error) {
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.
customRecords := NewCustomRecords(parsedTypes)
@ -171,6 +179,7 @@ func NewPayloadFromReader(r io.Reader) (*Payload, error) {
OutgoingCTLV: cltv,
},
MPP: mpp,
AMP: amp,
customRecords: customRecords,
}, nil
}
@ -207,6 +216,7 @@ func ValidateParsedPayloadTypes(parsedTypes tlv.TypeMap,
_, hasLockTime := parsedTypes[record.LockTimeOnionType]
_, hasNextHop := parsedTypes[record.NextHopOnionType]
_, hasMPP := parsedTypes[record.MPPOnionType]
_, hasAMP := parsedTypes[record.AMPOnionType]
switch {
@ -243,6 +253,14 @@ func ValidateParsedPayloadTypes(parsedTypes tlv.TypeMap,
Violation: IncludedViolation,
FinalHop: isFinalHop,
}
// Intermediate nodes should never receive AMP fields.
case !isFinalHop && hasAMP:
return ErrInvalidPayload{
Type: record.AMPOnionType,
Violation: IncludedViolation,
FinalHop: isFinalHop,
}
}
return nil

@ -8,14 +8,18 @@ import (
"github.com/lightningnetwork/lnd/htlcswitch/hop"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/record"
"github.com/stretchr/testify/require"
)
const testUnknownRequiredType = 0x10
type decodePayloadTest struct {
name string
payload []byte
expErr error
expCustomRecords map[uint64][]byte
shouldHaveMPP bool
shouldHaveAMP bool
}
var decodePayloadTests = []decodePayloadTest{
@ -81,21 +85,26 @@ var decodePayloadTests = []decodePayloadTest{
},
},
{
name: "required type after omitted hop id",
payload: []byte{0x02, 0x00, 0x04, 0x00, 0x0a, 0x00},
name: "required type after omitted hop id",
payload: []byte{
0x02, 0x00, 0x04, 0x00,
testUnknownRequiredType, 0x00,
},
expErr: hop.ErrInvalidPayload{
Type: 10,
Type: testUnknownRequiredType,
Violation: hop.RequiredViolation,
FinalHop: true,
},
},
{
name: "required type after included hop id",
payload: []byte{0x02, 0x00, 0x04, 0x00, 0x06, 0x08, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
payload: []byte{
0x02, 0x00, 0x04, 0x00, 0x06, 0x08, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
testUnknownRequiredType, 0x00,
},
expErr: hop.ErrInvalidPayload{
Type: 10,
Type: testUnknownRequiredType,
Violation: hop.RequiredViolation,
FinalHop: false,
},
@ -176,6 +185,37 @@ var decodePayloadTests = []decodePayloadTest{
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",
payload: []byte{
@ -194,6 +234,30 @@ var decodePayloadTests = []decodePayloadTest{
expErr: nil,
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
@ -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,
}
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))
@ -242,6 +320,17 @@ func testDecodeHopPayloadValidation(t *testing.T, test decodePayloadTest) {
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
// initiated map from the payload.
expCustomRecords := make(record.CustomSet)

@ -377,7 +377,8 @@ func (i *InvoiceRegistry) invoiceEventLoop() {
func (i *InvoiceRegistry) dispatchToSingleClients(event *invoiceEvent) {
// Dispatch to single invoice subscribers.
for _, client := range i.singleNotificationClients {
if client.invoiceRef.PayHash() != event.hash {
payHash := client.invoiceRef.PayHash()
if payHash == nil || *payHash != event.hash {
continue
}
@ -524,8 +525,13 @@ func (i *InvoiceRegistry) deliverSingleBacklogEvents(
return err
}
payHash := client.invoiceRef.PayHash()
if payHash == nil {
return nil
}
err = client.notify(&invoiceEvent{
hash: client.invoiceRef.PayHash(),
hash: *payHash,
invoice: &invoice,
})
if err != nil {
@ -775,6 +781,67 @@ func (i *InvoiceRegistry) processKeySend(ctx invoiceUpdateCtx) error {
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
// 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
// operation is idempotent.
if i.cfg.AcceptKeySend {
err := i.processKeySend(ctx)
if err != nil {
ctx.log(fmt.Sprintf("keysend error: %v", err))
if ctx.amp != nil {
err := i.processAMP(ctx)
if err != nil {
ctx.log(fmt.Sprintf("amp error: %v", err))
return NewFailResolution(
circuitKey, currentHeight, ResultKeySendError,
), nil
return NewFailResolution(
circuitKey, currentHeight, ResultAmpError,
), 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",
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
// htlcs and notify our peer to settle them.
case *HtlcSettleResolution:
@ -941,13 +1044,18 @@ func (i *InvoiceRegistry) notifyExitHopHtlcLocked(
continue
}
preimage := res.Preimage
if htlc.AMP != nil && htlc.AMP.Preimage != nil {
preimage = *htlc.AMP.Preimage
}
// Notify subscribers that the htlcs should be settled
// with our peer. Note that the outcome of the
// resolution is set based on the outcome of the single
// htlc that we just settled, so may not be accurate
// for all htlcs.
htlcSettleResolution := NewSettleResolution(
res.Preimage, key,
preimage, key,
int32(htlc.AcceptHeight), res.Outcome,
)

@ -1,10 +1,12 @@
package invoices
import (
"crypto/rand"
"math"
"testing"
"time"
"github.com/lightningnetwork/lnd/amp"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/clock"
"github.com/lightningnetwork/lnd/lntypes"
@ -29,9 +31,7 @@ func TestSettleInvoice(t *testing.T) {
}
defer subscription.Cancel()
if subscription.invoiceRef.PayHash() != testInvoicePaymentHash {
t.Fatalf("expected subscription for provided hash")
}
require.Equal(t, subscription.invoiceRef.PayHash(), &testInvoicePaymentHash)
// Add the invoice.
addIdx, err := ctx.registry.AddInvoice(testInvoice, testInvoicePaymentHash)
@ -77,19 +77,11 @@ func TestSettleInvoice(t *testing.T) {
if err != nil {
t.Fatal(err)
}
failResolution, ok := resolution.(*HtlcFailResolution)
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 failResolution.Outcome != ResultExpiryTooSoon {
t.Fatalf("expected expiry too soon, got: %v",
failResolution.Outcome)
}
require.NotNil(t, resolution)
failResolution := checkFailResolution(
t, resolution, ResultExpiryTooSoon,
)
require.Equal(t, testCurrentHeight, failResolution.AcceptHeight)
// Settle invoice with a slightly higher amount.
amtPaid := lnwire.MilliSatoshi(100500)
@ -101,15 +93,11 @@ func TestSettleInvoice(t *testing.T) {
if err != nil {
t.Fatal(err)
}
settleResolution, ok := resolution.(*HtlcSettleResolution)
if !ok {
t.Fatalf("expected settle resolution, got: %T",
resolution)
}
if settleResolution.Outcome != ResultSettled {
t.Fatalf("expected settled, got: %v",
settleResolution.Outcome)
}
require.NotNil(t, resolution)
settleResolution := checkSettleResolution(
t, resolution, testInvoicePreimage,
)
require.Equal(t, ResultSettled, settleResolution.Outcome)
// We expect the settled state to be sent to the single invoice
// subscriber.
@ -146,15 +134,11 @@ func TestSettleInvoice(t *testing.T) {
if err != nil {
t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err)
}
settleResolution, ok = resolution.(*HtlcSettleResolution)
if !ok {
t.Fatalf("expected settle resolution, got: %T",
resolution)
}
if settleResolution.Outcome != ResultReplayToSettled {
t.Fatalf("expected replay settled, got: %v",
settleResolution.Outcome)
}
require.NotNil(t, resolution)
settleResolution = checkSettleResolution(
t, resolution, testInvoicePreimage,
)
require.Equal(t, ResultReplayToSettled, settleResolution.Outcome)
// Try to settle again with a new higher-valued htlc. This payment
// should also be accepted, to prevent any change in behaviour for a
@ -166,15 +150,11 @@ func TestSettleInvoice(t *testing.T) {
if err != nil {
t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err)
}
settleResolution, ok = resolution.(*HtlcSettleResolution)
if !ok {
t.Fatalf("expected settle resolution, got: %T",
resolution)
}
if settleResolution.Outcome != ResultDuplicateToSettled {
t.Fatalf("expected duplicate settled, got: %v",
settleResolution.Outcome)
}
require.NotNil(t, resolution)
settleResolution = checkSettleResolution(
t, resolution, testInvoicePreimage,
)
require.Equal(t, ResultDuplicateToSettled, settleResolution.Outcome)
// Try to settle again with a lower amount. This should fail just as it
// would have failed if it were the first payment.
@ -185,15 +165,8 @@ func TestSettleInvoice(t *testing.T) {
if err != nil {
t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err)
}
failResolution, ok = resolution.(*HtlcFailResolution)
if !ok {
t.Fatalf("expected fail resolution, got: %T",
resolution)
}
if failResolution.Outcome != ResultAmountTooLow {
t.Fatalf("expected amount too low, got: %v",
failResolution.Outcome)
}
require.NotNil(t, resolution)
checkFailResolution(t, resolution, ResultAmountTooLow)
// Check that settled amount is equal to the sum of values of the htlcs
// 0 and 1.
@ -244,9 +217,7 @@ func testCancelInvoice(t *testing.T, gc bool) {
}
defer subscription.Cancel()
if subscription.invoiceRef.PayHash() != testInvoicePaymentHash {
t.Fatalf("expected subscription for provided hash")
}
require.Equal(t, subscription.invoiceRef.PayHash(), &testInvoicePaymentHash)
// Add the invoice.
amt := lnwire.MilliSatoshi(100000)
@ -333,27 +304,23 @@ func testCancelInvoice(t *testing.T, gc bool) {
if err != nil {
t.Fatal("expected settlement of a canceled invoice to succeed")
}
failResolution, ok := resolution.(*HtlcFailResolution)
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)
}
require.NotNil(t, resolution)
// If the invoice has been deleted (or not present) then we expect the
// outcome to be ResultInvoiceNotFound instead of when the invoice is
// in our database in which case we expect ResultInvoiceAlreadyCanceled.
var failResolution *HtlcFailResolution
if gc {
require.Equal(t, failResolution.Outcome, ResultInvoiceNotFound)
failResolution = checkFailResolution(
t, resolution, ResultInvoiceNotFound,
)
} else {
require.Equal(t,
failResolution.Outcome,
ResultInvoiceAlreadyCanceled,
failResolution = checkFailResolution(
t, resolution, ResultInvoiceAlreadyCanceled,
)
}
require.Equal(t, testCurrentHeight, failResolution.AcceptHeight)
}
// TestCancelInvoice tests cancelation of an invoice and related notifications.
@ -404,9 +371,7 @@ func TestSettleHoldInvoice(t *testing.T) {
}
defer subscription.Cancel()
if subscription.invoiceRef.PayHash() != testInvoicePaymentHash {
t.Fatalf("expected subscription for provided hash")
}
require.Equal(t, subscription.invoiceRef.PayHash(), &testInvoicePaymentHash)
// Add the invoice.
_, err = registry.AddInvoice(testHodlInvoice, testInvoicePaymentHash)
@ -480,15 +445,8 @@ func TestSettleHoldInvoice(t *testing.T) {
if err != nil {
t.Fatalf("expected settle to succeed but got %v", err)
}
failResolution, ok := resolution.(*HtlcFailResolution)
if !ok {
t.Fatalf("expected fail resolution, got: %T",
resolution)
}
if failResolution.Outcome != ResultExpiryTooSoon {
t.Fatalf("expected expiry too soon, got: %v",
failResolution.Outcome)
}
require.NotNil(t, resolution)
checkFailResolution(t, resolution, ResultExpiryTooSoon)
// We expect the accepted state to be sent to the single invoice
// subscriber. For all invoice subscribers, we don't expect an update.
@ -509,22 +467,12 @@ func TestSettleHoldInvoice(t *testing.T) {
}
htlcResolution := (<-hodlChan).(HtlcResolution)
settleResolution, ok := htlcResolution.(*HtlcSettleResolution)
if !ok {
t.Fatalf("expected settle resolution, got: %T",
htlcResolution)
}
if settleResolution.Preimage != testInvoicePreimage {
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)
}
require.NotNil(t, htlcResolution)
settleResolution := checkSettleResolution(
t, htlcResolution, testInvoicePreimage,
)
require.Equal(t, testCurrentHeight, settleResolution.AcceptHeight)
require.Equal(t, ResultSettled, settleResolution.Outcome)
// We expect a settled notification to be sent out for both all and
// single invoice subscribers.
@ -610,11 +558,8 @@ func TestCancelHoldInvoice(t *testing.T) {
}
htlcResolution := (<-hodlChan).(HtlcResolution)
_, ok := htlcResolution.(*HtlcFailResolution)
if !ok {
t.Fatalf("expected fail resolution, got: %T",
htlcResolution)
}
require.NotNil(t, htlcResolution)
checkFailResolution(t, htlcResolution, ResultCanceled)
// Offering the same htlc again at a higher height should still result
// in a rejection. The accept height is expected to be the original
@ -626,19 +571,11 @@ func TestCancelHoldInvoice(t *testing.T) {
if err != nil {
t.Fatalf("expected settle to succeed but got %v", err)
}
failResolution, ok := resolution.(*HtlcFailResolution)
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 failResolution.Outcome != ResultReplayToCanceled {
t.Fatalf("expected replay to canceled, got %v",
failResolution.Outcome)
}
require.NotNil(t, resolution)
failResolution := checkFailResolution(
t, resolution, ResultReplayToCanceled,
)
require.Equal(t, testCurrentHeight, failResolution.AcceptHeight)
}
// TestUnknownInvoice tests that invoice registry returns an error when the
@ -661,15 +598,8 @@ func TestUnknownInvoice(t *testing.T) {
if err != nil {
t.Fatal("unexpected error")
}
failResolution, ok := resolution.(*HtlcFailResolution)
if !ok {
t.Fatalf("expected fail resolution, got: %T",
resolution)
}
if failResolution.Outcome != ResultInvoiceNotFound {
t.Fatalf("expected ResultInvoiceNotFound, got: %v",
failResolution.Outcome)
}
require.NotNil(t, resolution)
checkFailResolution(t, resolution, ResultInvoiceNotFound)
}
// TestKeySend tests receiving a spontaneous payment with and without keysend
@ -721,18 +651,12 @@ func testKeySend(t *testing.T, keySendEnabled bool) {
if err != nil {
t.Fatal(err)
}
failResolution, ok := resolution.(*HtlcFailResolution)
if !ok {
t.Fatalf("expected fail resolution, got: %T",
resolution)
}
require.NotNil(t, resolution)
switch {
case !keySendEnabled && failResolution.Outcome != ResultInvoiceNotFound:
t.Fatal("expected invoice not found outcome")
case keySendEnabled && failResolution.Outcome != ResultKeySendError:
t.Fatal("expected keysend error")
if !keySendEnabled {
checkFailResolution(t, resolution, ResultInvoiceNotFound)
} else {
checkFailResolution(t, resolution, ResultKeySendError)
}
// 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.
if !keySendEnabled {
failResolution, ok = resolution.(*HtlcFailResolution)
if !ok {
t.Fatalf("expected fail resolution, got: %T",
resolution)
}
if failResolution.Outcome != ResultInvoiceNotFound {
t.Fatal("expected keysend payment not to be accepted")
}
checkFailResolution(t, resolution, ResultInvoiceNotFound)
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() {
// We expect a new invoice notification to be sent out.
newInvoice := <-allSubscriptions.NewInvoices
@ -779,7 +690,7 @@ func testKeySend(t *testing.T, keySendEnabled bool) {
require.Equal(t, settledInvoice.State, channeldb.ContractSettled)
}
checkResolution(resolution, preimage)
checkSettleResolution(t, resolution, preimage)
checkSubscription()
// 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,
)
require.Nil(t, err)
checkResolution(resolution, preimage)
checkSettleResolution(t, resolution, preimage)
select {
case <-allSubscriptions.NewInvoices:
@ -814,7 +725,7 @@ func testKeySend(t *testing.T, keySendEnabled bool) {
)
require.Nil(t, err)
checkResolution(resolution, preimage2)
checkSettleResolution(t, resolution, preimage2)
checkSubscription()
}
@ -1211,7 +1122,7 @@ func TestSettleInvoicePaymentAddrRequired(t *testing.T) {
defer subscription.Cancel()
require.Equal(
t, subscription.invoiceRef.PayHash(), testInvoicePaymentHash,
t, subscription.invoiceRef.PayHash(), &testInvoicePaymentHash,
)
// Add the invoice, which requires the MPP payload to always be
@ -1287,7 +1198,7 @@ func TestSettleInvoicePaymentAddrRequiredOptionalGrace(t *testing.T) {
defer subscription.Cancel()
require.Equal(
t, subscription.invoiceRef.PayHash(), testInvoicePaymentHash,
t, subscription.invoiceRef.PayHash(), &testInvoicePaymentHash,
)
// 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")
}
}
// 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)
}
}
}

@ -105,6 +105,13 @@ const (
// ResultMppInProgress is returned when we are busy receiving a mpp
// payment.
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.
@ -162,11 +169,34 @@ func (f FailResolutionResult) FailureString() string {
case ResultMppInProgress:
return "mpp reception in progress"
case ResultAmpError:
return "invalid amp parameters"
case ResultAmpReconstruction:
return "amp reconstruction failed"
default:
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
// by the registry. It can be used to take custom actions on resolution of the
// htlc.

@ -19,6 +19,7 @@ import (
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/record"
"github.com/lightningnetwork/lnd/zpay32"
"github.com/stretchr/testify/require"
)
type mockPayload struct {
@ -45,6 +46,16 @@ func (p *mockPayload) CustomRecords() record.CustomSet {
return p.customRecords
}
const (
testHtlcExpiry = uint32(5)
testInvoiceCltvDelta = uint32(4)
testFinalCltvRejectDelta = int32(4)
testCurrentHeight = int32(1)
)
var (
testTimeout = 5 * time.Second
@ -54,14 +65,6 @@ var (
testInvoicePaymentHash = testInvoicePreimage.Hash()
testHtlcExpiry = uint32(5)
testInvoiceCltvDelta = uint32(4)
testFinalCltvRejectDelta = int32(4)
testCurrentHeight = int32(1)
testPrivKeyBytes, _ = hex.DecodeString(
"e126f68f7eafcc8b74f54d269fe206be715000f94dac067d1c04a8ca3b2db734")
@ -111,7 +114,10 @@ var (
Value: testInvoiceAmt,
Expiry: time.Hour,
Features: lnwire.NewFeatureVector(
lnwire.NewRawFeatureVector(lnwire.PaymentAddrRequired),
lnwire.NewRawFeatureVector(
lnwire.TLVOnionPayloadOptional,
lnwire.PaymentAddrRequired,
),
lnwire.Features,
),
},
@ -124,7 +130,10 @@ var (
Value: testInvoiceAmt,
Expiry: time.Hour,
Features: lnwire.NewFeatureVector(
lnwire.NewRawFeatureVector(lnwire.PaymentAddrOptional),
lnwire.NewRawFeatureVector(
lnwire.TLVOnionPayloadOptional,
lnwire.PaymentAddrOptional,
),
lnwire.Features,
),
},
@ -325,3 +334,32 @@ func generateInvoiceExpiryTestData(
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
}

@ -3,6 +3,7 @@ package invoices
import (
"errors"
"github.com/lightningnetwork/lnd/amp"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/lntypes"
"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
// invoice this HTLC is targeting.
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()
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
@ -47,7 +53,7 @@ func (i invoiceUpdateCtx) setID() *[32]byte {
// log logs a message specific to this update context.
func (i *invoiceUpdateCtx) log(s string) {
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)
}
@ -130,6 +136,14 @@ func updateMpp(ctx *invoiceUpdateCtx,
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
// 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
@ -154,9 +168,18 @@ func updateMpp(ctx *invoiceUpdateCtx,
return nil, ctx.failRes(ResultHtlcSetTotalTooLow), nil
}
htlcSet := inv.HTLCSet(setID)
// Check whether total amt matches other htlcs in the set.
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 {
return nil, ctx.failRes(ResultHtlcSetTotalMismatch), nil
}
@ -206,15 +229,107 @@ func updateMpp(ctx *invoiceUpdateCtx,
return &update, ctx.acceptRes(resultAccepted), nil
}
update.State = &channeldb.InvoiceStateUpdateDesc{
NewState: channeldb.ContractSettled,
Preimage: inv.Terms.PaymentPreimage,
SetID: setID,
var (
htlcPreimages map[channeldb.CircuitKey]lntypes.Preimage
htlcPreimage lntypes.Preimage
)
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(
*inv.Terms.PaymentPreimage, ResultSettled,
), nil
update.State = &channeldb.InvoiceStateUpdateDesc{
NewState: channeldb.ContractSettled,
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

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

@ -441,6 +441,23 @@
],
"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": {
"type": "object",
"properties": {
@ -677,7 +694,11 @@
},
"mpp_record": {
"$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": {
"type": "object",

@ -455,6 +455,11 @@ func UnmarshallHopWithPubkey(rpcHop *lnrpc.Hop, pubkey route.Vertex) (*route.Hop
return nil, err
}
amp, err := UnmarshalAMP(rpcHop.AmpRecord)
if err != nil {
return nil, err
}
return &route.Hop{
OutgoingTimeLock: rpcHop.Expiry,
AmtToForward: lnwire.MilliSatoshi(rpcHop.AmtToForwardMsat),
@ -463,6 +468,7 @@ func UnmarshallHopWithPubkey(rpcHop *lnrpc.Hop, pubkey route.Vertex) (*route.Hop
CustomRecords: customRecords,
LegacyPayload: !rpcHop.TlvPayload,
MPP: mpp,
AMP: amp,
}, nil
}
@ -895,6 +901,32 @@ func UnmarshalMPP(reqMPP *lnrpc.MPPRecord) (*record.MPP, error) {
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.
func (r *RouterBackend) MarshalHTLCAttempt(
htlc channeldb.HTLCAttempt) (*lnrpc.HTLCAttempt, error) {

@ -12,6 +12,7 @@ import (
"github.com/lightningnetwork/lnd/record"
"github.com/lightningnetwork/lnd/routing"
"github.com/lightningnetwork/lnd/routing/route"
"github.com/stretchr/testify/require"
"github.com/lightningnetwork/lnd/lnrpc"
)
@ -239,18 +240,18 @@ func (m *mockMissionControl) GetPairHistorySnapshot(fromNode,
return routing.TimedPairResult{}
}
type mppOutcome byte
type recordParseOutcome byte
const (
valid mppOutcome = iota
valid recordParseOutcome = iota
invalid
nompp
norecord
)
type unmarshalMPPTest struct {
name string
mpp *lnrpc.MPPRecord
outcome mppOutcome
outcome recordParseOutcome
}
// TestUnmarshalMPP checks both positive and negative cases of UnmarshalMPP to
@ -262,7 +263,7 @@ func TestUnmarshalMPP(t *testing.T) {
{
name: "nil record",
mpp: nil,
outcome: nompp,
outcome: norecord,
},
{
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
// record.
case nompp:
case norecord:
if err != nil {
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")
}
}
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")
}
}

@ -613,7 +613,7 @@ func (x Invoice_InvoiceState) String() string {
}
func (Invoice_InvoiceState) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{111, 0}
return fileDescriptor_77a6da22d6a3feb1, []int{112, 0}
}
type Payment_PaymentStatus int32
@ -644,7 +644,7 @@ func (x Payment_PaymentStatus) String() string {
}
func (Payment_PaymentStatus) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{119, 0}
return fileDescriptor_77a6da22d6a3feb1, []int{120, 0}
}
type HTLCAttempt_HTLCStatus int32
@ -672,7 +672,7 @@ func (x HTLCAttempt_HTLCStatus) String() string {
}
func (HTLCAttempt_HTLCStatus) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{120, 0}
return fileDescriptor_77a6da22d6a3feb1, []int{121, 0}
}
type Failure_FailureCode int32
@ -786,7 +786,7 @@ func (x Failure_FailureCode) String() string {
}
func (Failure_FailureCode) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{160, 0}
return fileDescriptor_77a6da22d6a3feb1, []int{161, 0}
}
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"`
//
//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
//final hop payload of all non-zero payments in the HTLC set. If empty, a
//regular single-shot payment is or was attempted.
//the receiver will enforce that the same mpp_record is included in the final
//hop payload of all non-zero payments in the HTLC set. If empty, a regular
//single-shot payment is or was attempted.
MppRecord *MPPRecord `protobuf:"bytes,10,opt,name=mpp_record,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
//of the SendToRoute call as it allows callers to specify arbitrary K-V pairs
//to drop off at each hop within the onion.
@ -7828,6 +7836,13 @@ func (m *Hop) GetMppRecord() *MPPRecord {
return nil
}
func (m *Hop) GetAmpRecord() *AMPRecord {
if m != nil {
return m.AmpRecord
}
return nil
}
func (m *Hop) GetCustomRecords() map[uint64][]byte {
if m != nil {
return m.CustomRecords
@ -7892,6 +7907,61 @@ func (m *MPPRecord) GetTotalAmtMsat() int64 {
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
//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 (*Route) ProtoMessage() {}
func (*Route) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{87}
return fileDescriptor_77a6da22d6a3feb1, []int{88}
}
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 (*NodeInfoRequest) ProtoMessage() {}
func (*NodeInfoRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{88}
return fileDescriptor_77a6da22d6a3feb1, []int{89}
}
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 (*NodeInfo) ProtoMessage() {}
func (*NodeInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{89}
return fileDescriptor_77a6da22d6a3feb1, []int{90}
}
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 (*LightningNode) ProtoMessage() {}
func (*LightningNode) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{90}
return fileDescriptor_77a6da22d6a3feb1, []int{91}
}
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 (*NodeAddress) ProtoMessage() {}
func (*NodeAddress) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{91}
return fileDescriptor_77a6da22d6a3feb1, []int{92}
}
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 (*RoutingPolicy) ProtoMessage() {}
func (*RoutingPolicy) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{92}
return fileDescriptor_77a6da22d6a3feb1, []int{93}
}
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 (*ChannelEdge) ProtoMessage() {}
func (*ChannelEdge) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{93}
return fileDescriptor_77a6da22d6a3feb1, []int{94}
}
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 (*ChannelGraphRequest) ProtoMessage() {}
func (*ChannelGraphRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{94}
return fileDescriptor_77a6da22d6a3feb1, []int{95}
}
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 (*ChannelGraph) ProtoMessage() {}
func (*ChannelGraph) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{95}
return fileDescriptor_77a6da22d6a3feb1, []int{96}
}
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 (*NodeMetricsRequest) ProtoMessage() {}
func (*NodeMetricsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{96}
return fileDescriptor_77a6da22d6a3feb1, []int{97}
}
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 (*NodeMetricsResponse) ProtoMessage() {}
func (*NodeMetricsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{97}
return fileDescriptor_77a6da22d6a3feb1, []int{98}
}
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 (*FloatMetric) ProtoMessage() {}
func (*FloatMetric) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{98}
return fileDescriptor_77a6da22d6a3feb1, []int{99}
}
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 (*ChanInfoRequest) ProtoMessage() {}
func (*ChanInfoRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{99}
return fileDescriptor_77a6da22d6a3feb1, []int{100}
}
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 (*NetworkInfoRequest) ProtoMessage() {}
func (*NetworkInfoRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{100}
return fileDescriptor_77a6da22d6a3feb1, []int{101}
}
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 (*NetworkInfo) ProtoMessage() {}
func (*NetworkInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{101}
return fileDescriptor_77a6da22d6a3feb1, []int{102}
}
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 (*StopRequest) ProtoMessage() {}
func (*StopRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{102}
return fileDescriptor_77a6da22d6a3feb1, []int{103}
}
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 (*StopResponse) ProtoMessage() {}
func (*StopResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{103}
return fileDescriptor_77a6da22d6a3feb1, []int{104}
}
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 (*GraphTopologySubscription) ProtoMessage() {}
func (*GraphTopologySubscription) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{104}
return fileDescriptor_77a6da22d6a3feb1, []int{105}
}
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 (*GraphTopologyUpdate) ProtoMessage() {}
func (*GraphTopologyUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{105}
return fileDescriptor_77a6da22d6a3feb1, []int{106}
}
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 (*NodeUpdate) ProtoMessage() {}
func (*NodeUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{106}
return fileDescriptor_77a6da22d6a3feb1, []int{107}
}
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 (*ChannelEdgeUpdate) ProtoMessage() {}
func (*ChannelEdgeUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{107}
return fileDescriptor_77a6da22d6a3feb1, []int{108}
}
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 (*ClosedChannelUpdate) ProtoMessage() {}
func (*ClosedChannelUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{108}
return fileDescriptor_77a6da22d6a3feb1, []int{109}
}
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 (*HopHint) ProtoMessage() {}
func (*HopHint) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{109}
return fileDescriptor_77a6da22d6a3feb1, []int{110}
}
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 (*RouteHint) ProtoMessage() {}
func (*RouteHint) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{110}
return fileDescriptor_77a6da22d6a3feb1, []int{111}
}
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 (*Invoice) ProtoMessage() {}
func (*Invoice) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{111}
return fileDescriptor_77a6da22d6a3feb1, []int{112}
}
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 (*InvoiceHTLC) ProtoMessage() {}
func (*InvoiceHTLC) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{112}
return fileDescriptor_77a6da22d6a3feb1, []int{113}
}
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 (*AMP) ProtoMessage() {}
func (*AMP) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{113}
return fileDescriptor_77a6da22d6a3feb1, []int{114}
}
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 (*AddInvoiceResponse) ProtoMessage() {}
func (*AddInvoiceResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{114}
return fileDescriptor_77a6da22d6a3feb1, []int{115}
}
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 (*PaymentHash) ProtoMessage() {}
func (*PaymentHash) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{115}
return fileDescriptor_77a6da22d6a3feb1, []int{116}
}
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 (*ListInvoiceRequest) ProtoMessage() {}
func (*ListInvoiceRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{116}
return fileDescriptor_77a6da22d6a3feb1, []int{117}
}
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 (*ListInvoiceResponse) ProtoMessage() {}
func (*ListInvoiceResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{117}
return fileDescriptor_77a6da22d6a3feb1, []int{118}
}
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 (*InvoiceSubscription) ProtoMessage() {}
func (*InvoiceSubscription) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{118}
return fileDescriptor_77a6da22d6a3feb1, []int{119}
}
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 (*Payment) ProtoMessage() {}
func (*Payment) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{119}
return fileDescriptor_77a6da22d6a3feb1, []int{120}
}
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 (*HTLCAttempt) ProtoMessage() {}
func (*HTLCAttempt) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{120}
return fileDescriptor_77a6da22d6a3feb1, []int{121}
}
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 (*ListPaymentsRequest) ProtoMessage() {}
func (*ListPaymentsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{121}
return fileDescriptor_77a6da22d6a3feb1, []int{122}
}
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 (*ListPaymentsResponse) ProtoMessage() {}
func (*ListPaymentsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{122}
return fileDescriptor_77a6da22d6a3feb1, []int{123}
}
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 (*DeleteAllPaymentsRequest) ProtoMessage() {}
func (*DeleteAllPaymentsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{123}
return fileDescriptor_77a6da22d6a3feb1, []int{124}
}
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 (*DeleteAllPaymentsResponse) ProtoMessage() {}
func (*DeleteAllPaymentsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{124}
return fileDescriptor_77a6da22d6a3feb1, []int{125}
}
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 (*AbandonChannelRequest) ProtoMessage() {}
func (*AbandonChannelRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{125}
return fileDescriptor_77a6da22d6a3feb1, []int{126}
}
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 (*AbandonChannelResponse) ProtoMessage() {}
func (*AbandonChannelResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{126}
return fileDescriptor_77a6da22d6a3feb1, []int{127}
}
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 (*DebugLevelRequest) ProtoMessage() {}
func (*DebugLevelRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{127}
return fileDescriptor_77a6da22d6a3feb1, []int{128}
}
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 (*DebugLevelResponse) ProtoMessage() {}
func (*DebugLevelResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{128}
return fileDescriptor_77a6da22d6a3feb1, []int{129}
}
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 (*PayReqString) ProtoMessage() {}
func (*PayReqString) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{129}
return fileDescriptor_77a6da22d6a3feb1, []int{130}
}
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 (*PayReq) ProtoMessage() {}
func (*PayReq) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{130}
return fileDescriptor_77a6da22d6a3feb1, []int{131}
}
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 (*Feature) ProtoMessage() {}
func (*Feature) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{131}
return fileDescriptor_77a6da22d6a3feb1, []int{132}
}
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 (*FeeReportRequest) ProtoMessage() {}
func (*FeeReportRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{132}
return fileDescriptor_77a6da22d6a3feb1, []int{133}
}
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 (*ChannelFeeReport) ProtoMessage() {}
func (*ChannelFeeReport) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{133}
return fileDescriptor_77a6da22d6a3feb1, []int{134}
}
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 (*FeeReportResponse) ProtoMessage() {}
func (*FeeReportResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{134}
return fileDescriptor_77a6da22d6a3feb1, []int{135}
}
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 (*PolicyUpdateRequest) ProtoMessage() {}
func (*PolicyUpdateRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{135}
return fileDescriptor_77a6da22d6a3feb1, []int{136}
}
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 (*PolicyUpdateResponse) ProtoMessage() {}
func (*PolicyUpdateResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{136}
return fileDescriptor_77a6da22d6a3feb1, []int{137}
}
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 (*ForwardingHistoryRequest) ProtoMessage() {}
func (*ForwardingHistoryRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{137}
return fileDescriptor_77a6da22d6a3feb1, []int{138}
}
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 (*ForwardingEvent) ProtoMessage() {}
func (*ForwardingEvent) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{138}
return fileDescriptor_77a6da22d6a3feb1, []int{139}
}
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 (*ForwardingHistoryResponse) ProtoMessage() {}
func (*ForwardingHistoryResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{139}
return fileDescriptor_77a6da22d6a3feb1, []int{140}
}
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 (*ExportChannelBackupRequest) ProtoMessage() {}
func (*ExportChannelBackupRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{140}
return fileDescriptor_77a6da22d6a3feb1, []int{141}
}
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 (*ChannelBackup) ProtoMessage() {}
func (*ChannelBackup) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{141}
return fileDescriptor_77a6da22d6a3feb1, []int{142}
}
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 (*MultiChanBackup) ProtoMessage() {}
func (*MultiChanBackup) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{142}
return fileDescriptor_77a6da22d6a3feb1, []int{143}
}
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 (*ChanBackupExportRequest) ProtoMessage() {}
func (*ChanBackupExportRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{143}
return fileDescriptor_77a6da22d6a3feb1, []int{144}
}
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 (*ChanBackupSnapshot) ProtoMessage() {}
func (*ChanBackupSnapshot) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{144}
return fileDescriptor_77a6da22d6a3feb1, []int{145}
}
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 (*ChannelBackups) ProtoMessage() {}
func (*ChannelBackups) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{145}
return fileDescriptor_77a6da22d6a3feb1, []int{146}
}
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 (*RestoreChanBackupRequest) ProtoMessage() {}
func (*RestoreChanBackupRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{146}
return fileDescriptor_77a6da22d6a3feb1, []int{147}
}
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 (*RestoreBackupResponse) ProtoMessage() {}
func (*RestoreBackupResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{147}
return fileDescriptor_77a6da22d6a3feb1, []int{148}
}
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 (*ChannelBackupSubscription) ProtoMessage() {}
func (*ChannelBackupSubscription) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{148}
return fileDescriptor_77a6da22d6a3feb1, []int{149}
}
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 (*VerifyChanBackupResponse) ProtoMessage() {}
func (*VerifyChanBackupResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{149}
return fileDescriptor_77a6da22d6a3feb1, []int{150}
}
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 (*MacaroonPermission) ProtoMessage() {}
func (*MacaroonPermission) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{150}
return fileDescriptor_77a6da22d6a3feb1, []int{151}
}
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 (*BakeMacaroonRequest) ProtoMessage() {}
func (*BakeMacaroonRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{151}
return fileDescriptor_77a6da22d6a3feb1, []int{152}
}
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 (*BakeMacaroonResponse) ProtoMessage() {}
func (*BakeMacaroonResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{152}
return fileDescriptor_77a6da22d6a3feb1, []int{153}
}
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 (*ListMacaroonIDsRequest) ProtoMessage() {}
func (*ListMacaroonIDsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{153}
return fileDescriptor_77a6da22d6a3feb1, []int{154}
}
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 (*ListMacaroonIDsResponse) ProtoMessage() {}
func (*ListMacaroonIDsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{154}
return fileDescriptor_77a6da22d6a3feb1, []int{155}
}
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 (*DeleteMacaroonIDRequest) ProtoMessage() {}
func (*DeleteMacaroonIDRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{155}
return fileDescriptor_77a6da22d6a3feb1, []int{156}
}
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 (*DeleteMacaroonIDResponse) ProtoMessage() {}
func (*DeleteMacaroonIDResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{156}
return fileDescriptor_77a6da22d6a3feb1, []int{157}
}
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 (*MacaroonPermissionList) ProtoMessage() {}
func (*MacaroonPermissionList) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{157}
return fileDescriptor_77a6da22d6a3feb1, []int{158}
}
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 (*ListPermissionsRequest) ProtoMessage() {}
func (*ListPermissionsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{158}
return fileDescriptor_77a6da22d6a3feb1, []int{159}
}
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 (*ListPermissionsResponse) ProtoMessage() {}
func (*ListPermissionsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{159}
return fileDescriptor_77a6da22d6a3feb1, []int{160}
}
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 (*Failure) ProtoMessage() {}
func (*Failure) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{160}
return fileDescriptor_77a6da22d6a3feb1, []int{161}
}
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 (*ChannelUpdate) ProtoMessage() {}
func (*ChannelUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{161}
return fileDescriptor_77a6da22d6a3feb1, []int{162}
}
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 (*MacaroonId) ProtoMessage() {}
func (*MacaroonId) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{162}
return fileDescriptor_77a6da22d6a3feb1, []int{163}
}
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 (*Op) ProtoMessage() {}
func (*Op) Descriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{163}
return fileDescriptor_77a6da22d6a3feb1, []int{164}
}
func (m *Op) XXX_Unmarshal(b []byte) error {
@ -13043,6 +13113,7 @@ func init() {
proto.RegisterType((*Hop)(nil), "lnrpc.Hop")
proto.RegisterMapType((map[uint64][]byte)(nil), "lnrpc.Hop.CustomRecordsEntry")
proto.RegisterType((*MPPRecord)(nil), "lnrpc.MPPRecord")
proto.RegisterType((*AMPRecord)(nil), "lnrpc.AMPRecord")
proto.RegisterType((*Route)(nil), "lnrpc.Route")
proto.RegisterType((*NodeInfoRequest)(nil), "lnrpc.NodeInfoRequest")
proto.RegisterType((*NodeInfo)(nil), "lnrpc.NodeInfo")
@ -13132,800 +13203,802 @@ func init() {
func init() { proto.RegisterFile("rpc.proto", fileDescriptor_77a6da22d6a3feb1) }
var fileDescriptor_77a6da22d6a3feb1 = []byte{
// 12685 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0xbd, 0x5b, 0x6c, 0x23, 0x59,
0x7a, 0x18, 0xdc, 0xbc, 0x89, 0xe4, 0x47, 0x52, 0xa2, 0x8e, 0x6e, 0x6c, 0xf5, 0xf4, 0x74, 0x4f,
0xcd, 0xec, 0x4c, 0x6f, 0xcf, 0x8e, 0xa6, 0xa7, 0x67, 0x7a, 0x2e, 0x3b, 0xbf, 0xd7, 0x4b, 0x49,
0x54, 0x8b, 0xdb, 0x12, 0xa9, 0x2d, 0x52, 0x3d, 0x6e, 0xc3, 0x76, 0xb9, 0x44, 0x1e, 0x49, 0xf5,
0x37, 0x59, 0xc5, 0xad, 0x2a, 0xaa, 0xa5, 0x0d, 0x02, 0xf8, 0xc1, 0xb1, 0x03, 0xc3, 0x08, 0x10,
0x20, 0x0e, 0x10, 0x24, 0x46, 0x12, 0x24, 0x48, 0xde, 0x0c, 0x03, 0xb6, 0x9f, 0x92, 0x87, 0x3c,
0x25, 0x08, 0x90, 0x20, 0x08, 0x10, 0x23, 0x17, 0x04, 0x09, 0x02, 0x24, 0x0e, 0x10, 0x03, 0x89,
0x01, 0x3f, 0x26, 0x41, 0x82, 0xf3, 0x9d, 0x4b, 0x9d, 0xba, 0xa8, 0xbb, 0x67, 0x3d, 0xd9, 0x17,
0x89, 0xf5, 0x9d, 0xef, 0xdc, 0xcf, 0xf9, 0xce, 0x77, 0x3b, 0xdf, 0x81, 0xaa, 0x3f, 0x1b, 0x6d,
0xcd, 0x7c, 0x2f, 0xf4, 0x48, 0x69, 0xe2, 0xfa, 0xb3, 0x91, 0xf1, 0x47, 0x39, 0x28, 0x1e, 0x87,
0x97, 0x1e, 0x79, 0x04, 0x75, 0x7b, 0x3c, 0xf6, 0x69, 0x10, 0x58, 0xe1, 0xd5, 0x8c, 0xb6, 0x72,
0x77, 0x73, 0xf7, 0x16, 0x1f, 0x92, 0x2d, 0x44, 0xdb, 0x6a, 0xf3, 0xa4, 0xe1, 0xd5, 0x8c, 0x9a,
0x35, 0x3b, 0xfa, 0x20, 0x2d, 0x28, 0x8b, 0xcf, 0x56, 0xfe, 0x6e, 0xee, 0x5e, 0xd5, 0x94, 0x9f,
0xe4, 0x36, 0x80, 0x3d, 0xf5, 0xe6, 0x6e, 0x68, 0x05, 0x76, 0xd8, 0x2a, 0xdc, 0xcd, 0xdd, 0x2b,
0x98, 0x55, 0x0e, 0x19, 0xd8, 0x21, 0xb9, 0x05, 0xd5, 0xd9, 0x73, 0x2b, 0x18, 0xf9, 0xce, 0x2c,
0x6c, 0x15, 0x31, 0x6b, 0x65, 0xf6, 0x7c, 0x80, 0xdf, 0xe4, 0x7d, 0xa8, 0x78, 0xf3, 0x70, 0xe6,
0x39, 0x6e, 0xd8, 0x2a, 0xdd, 0xcd, 0xdd, 0xab, 0x3d, 0x5c, 0x12, 0x0d, 0xe9, 0xcf, 0xc3, 0x23,
0x06, 0x36, 0x15, 0x02, 0x79, 0x07, 0x1a, 0x23, 0xcf, 0x3d, 0x75, 0xfc, 0xa9, 0x1d, 0x3a, 0x9e,
0x1b, 0xb4, 0x16, 0xb0, 0xae, 0x38, 0xd0, 0xf8, 0xc7, 0x79, 0xa8, 0x0d, 0x7d, 0xdb, 0x0d, 0xec,
0x11, 0x03, 0x90, 0x0d, 0x28, 0x87, 0x97, 0xd6, 0xb9, 0x1d, 0x9c, 0x63, 0x57, 0xab, 0xe6, 0x42,
0x78, 0xb9, 0x6f, 0x07, 0xe7, 0x64, 0x1d, 0x16, 0x78, 0x2b, 0xb1, 0x43, 0x05, 0x53, 0x7c, 0x91,
0xf7, 0x61, 0xd9, 0x9d, 0x4f, 0xad, 0x78, 0x55, 0xac, 0x5b, 0x25, 0xb3, 0xe9, 0xce, 0xa7, 0x3b,
0x3a, 0x9c, 0x75, 0xfe, 0x64, 0xe2, 0x8d, 0x9e, 0xf3, 0x0a, 0x78, 0xf7, 0xaa, 0x08, 0xc1, 0x3a,
0xde, 0x82, 0xba, 0x48, 0xa6, 0xce, 0xd9, 0x39, 0xef, 0x63, 0xc9, 0xac, 0x71, 0x04, 0x04, 0xb1,
0x12, 0x42, 0x67, 0x4a, 0xad, 0x20, 0xb4, 0xa7, 0x33, 0xd1, 0xa5, 0x2a, 0x83, 0x0c, 0x18, 0x00,
0x93, 0xbd, 0xd0, 0x9e, 0x58, 0xa7, 0x94, 0x06, 0xad, 0xb2, 0x48, 0x66, 0x90, 0x3d, 0x4a, 0x03,
0xf2, 0x2d, 0x58, 0x1c, 0xd3, 0x20, 0xb4, 0xc4, 0x64, 0xd0, 0xa0, 0x55, 0xb9, 0x5b, 0xb8, 0x57,
0x35, 0x1b, 0x0c, 0xda, 0x96, 0x40, 0xf2, 0x06, 0x80, 0x6f, 0xbf, 0xb0, 0xd8, 0x40, 0xd0, 0xcb,
0x56, 0x95, 0xcf, 0x82, 0x6f, 0xbf, 0x18, 0x5e, 0xee, 0xd3, 0x4b, 0xb2, 0x0a, 0xa5, 0x89, 0x7d,
0x42, 0x27, 0x2d, 0xc0, 0x04, 0xfe, 0x61, 0x84, 0xb0, 0xfe, 0x98, 0x86, 0xda, 0x50, 0x06, 0x26,
0xfd, 0xd1, 0x9c, 0x06, 0x21, 0xeb, 0x55, 0x10, 0xda, 0x7e, 0x28, 0x7b, 0x95, 0xe3, 0xbd, 0x42,
0x58, 0xd4, 0x2b, 0xea, 0x8e, 0x25, 0x42, 0x1e, 0x11, 0xaa, 0xd4, 0x1d, 0x8b, 0x64, 0xb6, 0x9a,
0x46, 0x23, 0x1c, 0xfc, 0x82, 0x58, 0x4d, 0xfc, 0xd3, 0x38, 0x00, 0xa2, 0x55, 0xb9, 0x4b, 0x43,
0xdb, 0x99, 0x04, 0xe4, 0x53, 0xa8, 0x87, 0x5a, 0x43, 0x5a, 0xb9, 0xbb, 0x85, 0x7b, 0x35, 0xb5,
0x68, 0xb5, 0x0c, 0x66, 0x0c, 0xcf, 0x38, 0x87, 0xca, 0x1e, 0xa5, 0x07, 0xce, 0xd4, 0x09, 0xc9,
0x3a, 0x94, 0x4e, 0x9d, 0x4b, 0x3a, 0xc6, 0xe6, 0x16, 0xf6, 0x6f, 0x98, 0xfc, 0x93, 0xdc, 0x01,
0xc0, 0x1f, 0xd6, 0x54, 0xad, 0xdf, 0xfd, 0x1b, 0x66, 0x15, 0x61, 0x87, 0x81, 0x1d, 0x92, 0x4d,
0x28, 0xcf, 0xa8, 0x3f, 0xa2, 0x72, 0xa5, 0xec, 0xdf, 0x30, 0x25, 0x60, 0xbb, 0x0c, 0xa5, 0x09,
0x2b, 0xdd, 0xf8, 0x6f, 0x25, 0xa8, 0x0d, 0xa8, 0x3b, 0x96, 0x63, 0x44, 0xa0, 0xc8, 0xa6, 0x00,
0x2b, 0xab, 0x9b, 0xf8, 0x9b, 0xbc, 0x0d, 0x35, 0x9c, 0xac, 0x20, 0xf4, 0x1d, 0xf7, 0x8c, 0xef,
0xa3, 0xed, 0x7c, 0x2b, 0x67, 0x02, 0x03, 0x0f, 0x10, 0x4a, 0x9a, 0x50, 0xb0, 0xa7, 0x72, 0x1f,
0xb1, 0x9f, 0xe4, 0x26, 0x54, 0xec, 0x69, 0xc8, 0x9b, 0x57, 0x47, 0x70, 0xd9, 0x9e, 0x86, 0xd8,
0xb4, 0xb7, 0xa0, 0x3e, 0xb3, 0xaf, 0xa6, 0xd4, 0x0d, 0xa3, 0x05, 0x58, 0x37, 0x6b, 0x02, 0x86,
0x4b, 0xf0, 0x21, 0xac, 0xe8, 0x28, 0xb2, 0xf2, 0x92, 0xaa, 0x7c, 0x59, 0xc3, 0x16, 0x6d, 0x78,
0x0f, 0x96, 0x64, 0x1e, 0x9f, 0xf7, 0x07, 0x17, 0x66, 0xd5, 0x5c, 0x14, 0x60, 0xd9, 0xcb, 0x7b,
0xd0, 0x3c, 0x75, 0x5c, 0x7b, 0x62, 0x8d, 0x26, 0xe1, 0x85, 0x35, 0xa6, 0x93, 0xd0, 0xc6, 0x35,
0x5a, 0x32, 0x17, 0x11, 0xbe, 0x33, 0x09, 0x2f, 0x76, 0x19, 0x94, 0x7c, 0x07, 0xaa, 0xa7, 0x94,
0x5a, 0x38, 0x58, 0xad, 0x4a, 0x6c, 0xab, 0xcb, 0x19, 0x32, 0x2b, 0xa7, 0x72, 0xae, 0xbe, 0x03,
0x4d, 0x6f, 0x1e, 0x9e, 0x79, 0x8e, 0x7b, 0x66, 0x8d, 0xce, 0x6d, 0xd7, 0x72, 0xc6, 0xb8, 0x6a,
0x8b, 0xdb, 0xf9, 0x07, 0x39, 0x73, 0x51, 0xa6, 0xed, 0x9c, 0xdb, 0x6e, 0x77, 0x4c, 0xde, 0x85,
0xa5, 0x89, 0x1d, 0x84, 0xd6, 0xb9, 0x37, 0xb3, 0x66, 0xf3, 0x93, 0xe7, 0xf4, 0xaa, 0xd5, 0xc0,
0x81, 0x68, 0x30, 0xf0, 0xbe, 0x37, 0x3b, 0x42, 0x20, 0x5b, 0x94, 0xd8, 0x4e, 0xde, 0x08, 0xb6,
0xd8, 0x1b, 0x66, 0x95, 0x41, 0x78, 0xa5, 0xcf, 0x60, 0x05, 0xa7, 0x67, 0x34, 0x0f, 0x42, 0x6f,
0x6a, 0xf9, 0x74, 0xe4, 0xf9, 0xe3, 0xa0, 0x55, 0xc3, 0xb5, 0xf6, 0x6d, 0xd1, 0x58, 0x6d, 0x8e,
0xb7, 0x76, 0x69, 0x10, 0xee, 0x20, 0xb2, 0xc9, 0x71, 0x3b, 0x6e, 0xe8, 0x5f, 0x99, 0xcb, 0xe3,
0x24, 0x9c, 0x7c, 0x07, 0x88, 0x3d, 0x99, 0x78, 0x2f, 0xac, 0x80, 0x4e, 0x4e, 0x2d, 0x31, 0x88,
0xad, 0xc5, 0xbb, 0xb9, 0x7b, 0x15, 0xb3, 0x89, 0x29, 0x03, 0x3a, 0x39, 0x3d, 0xe2, 0x70, 0xf2,
0x29, 0xe0, 0xf6, 0xb5, 0x4e, 0xa9, 0x1d, 0xce, 0x7d, 0x1a, 0xb4, 0x96, 0xee, 0x16, 0xee, 0x2d,
0x3e, 0x5c, 0x56, 0xe3, 0x85, 0xe0, 0x6d, 0x27, 0x34, 0xeb, 0x0c, 0x4f, 0x7c, 0x07, 0xfa, 0x6a,
0x60, 0xf4, 0xa0, 0xd5, 0x8c, 0xad, 0x06, 0x46, 0x0d, 0x36, 0x77, 0x61, 0x3d, 0xbb, 0xd5, 0x6c,
0xdd, 0xb1, 0x81, 0x63, 0xeb, 0xb5, 0x68, 0xb2, 0x9f, 0x8c, 0x2c, 0x5c, 0xd8, 0x93, 0x39, 0xc5,
0x85, 0x5a, 0x37, 0xf9, 0xc7, 0x77, 0xf3, 0x9f, 0xe7, 0x8c, 0xdf, 0xcf, 0x41, 0x9d, 0x0f, 0x44,
0x30, 0xf3, 0xdc, 0x80, 0x92, 0xb7, 0xa1, 0x21, 0x6b, 0xa6, 0xbe, 0xef, 0xf9, 0x82, 0xd4, 0xca,
0xe6, 0x74, 0x18, 0x8c, 0x7c, 0x1b, 0x9a, 0x12, 0x69, 0xe6, 0x53, 0x67, 0x6a, 0x9f, 0xc9, 0xa2,
0xe5, 0x6a, 0x3b, 0x12, 0x60, 0xf2, 0x51, 0x54, 0x9e, 0xef, 0xcd, 0x43, 0x8a, 0xdb, 0xa1, 0xf6,
0xb0, 0x2e, 0x46, 0xc0, 0x64, 0x30, 0x55, 0x3a, 0x7e, 0xbd, 0xc6, 0x56, 0x30, 0x7e, 0x2b, 0x07,
0x84, 0x35, 0x7b, 0xe8, 0xf1, 0x02, 0x22, 0x72, 0x16, 0xcb, 0x99, 0x7b, 0xed, 0x4d, 0x94, 0x7f,
0xd9, 0x26, 0x32, 0xa0, 0xc4, 0xdb, 0x5e, 0xcc, 0x68, 0x3b, 0x4f, 0xfa, 0x41, 0xb1, 0x52, 0x68,
0x16, 0x8d, 0x7f, 0x57, 0x80, 0x55, 0xb6, 0x94, 0x5d, 0x3a, 0x69, 0x8f, 0x46, 0x74, 0xa6, 0xb6,
0xd7, 0x1d, 0xa8, 0xb9, 0xde, 0x98, 0xca, 0x45, 0xcd, 0x1b, 0x06, 0x0c, 0xa4, 0xad, 0xe8, 0x73,
0xdb, 0x71, 0x79, 0xc3, 0xf9, 0x60, 0x56, 0x11, 0x82, 0xcd, 0x7e, 0x17, 0x96, 0x66, 0xd4, 0x1d,
0xeb, 0xbb, 0xa8, 0xc0, 0x37, 0x86, 0x00, 0x8b, 0x0d, 0x74, 0x07, 0x6a, 0xa7, 0x73, 0x8e, 0xc7,
0x68, 0x4f, 0x11, 0xd7, 0x00, 0x08, 0x50, 0x9b, 0x93, 0xa0, 0xd9, 0x3c, 0x38, 0xc7, 0xd4, 0x12,
0xa6, 0x96, 0xd9, 0x37, 0x4b, 0xba, 0x0d, 0x30, 0x9e, 0x07, 0xa1, 0xd8, 0x54, 0x0b, 0x98, 0x58,
0x65, 0x10, 0xbe, 0xa9, 0x3e, 0x80, 0x95, 0xa9, 0x7d, 0x69, 0xe1, 0xda, 0xb1, 0x1c, 0xd7, 0x3a,
0x9d, 0xe0, 0x89, 0x50, 0x46, 0xbc, 0xe6, 0xd4, 0xbe, 0x7c, 0xca, 0x52, 0xba, 0xee, 0x1e, 0xc2,
0x19, 0xe5, 0x19, 0xf1, 0x91, 0xb0, 0x7c, 0x1a, 0x50, 0xff, 0x82, 0x22, 0xb1, 0x28, 0x9a, 0x8b,
0x02, 0x6c, 0x72, 0x28, 0x6b, 0xd1, 0x94, 0xf5, 0x3b, 0x9c, 0x8c, 0x38, 0x65, 0x30, 0xcb, 0x53,
0xc7, 0xdd, 0x0f, 0x27, 0x23, 0x76, 0xd8, 0x31, 0x52, 0x33, 0xa3, 0xbe, 0xf5, 0xfc, 0x05, 0x6e,
0xf3, 0x22, 0x92, 0x96, 0x23, 0xea, 0x3f, 0x79, 0xc1, 0xf8, 0x91, 0x51, 0x80, 0xb4, 0xca, 0xbe,
0x6a, 0xd5, 0x90, 0x06, 0x54, 0x46, 0x01, 0xa3, 0x52, 0xf6, 0x15, 0xdb, 0xa7, 0xac, 0xb5, 0x36,
0xce, 0x02, 0x1d, 0x63, 0xf1, 0x01, 0x12, 0xdd, 0x06, 0x36, 0xb6, 0x2d, 0x12, 0x58, 0x3d, 0x01,
0x5b, 0xf5, 0xb2, 0xb1, 0xa7, 0x13, 0xfb, 0x2c, 0x40, 0xaa, 0xd3, 0x30, 0xeb, 0x02, 0xb8, 0xc7,
0x60, 0xc6, 0x9f, 0xe6, 0x61, 0x2d, 0x31, 0xb9, 0x62, 0xd3, 0x30, 0x06, 0x04, 0x21, 0x38, 0xb1,
0x15, 0x53, 0x7c, 0x65, 0xcd, 0x5a, 0x3e, 0x6b, 0xd6, 0x56, 0xa1, 0xc4, 0x37, 0x1b, 0x3f, 0x42,
0xf9, 0x07, 0xdb, 0x65, 0xf3, 0xd9, 0xa9, 0xef, 0x31, 0x7e, 0xec, 0x7c, 0x1e, 0x8e, 0xbd, 0x17,
0xae, 0xe0, 0x4b, 0x96, 0x04, 0x7c, 0x20, 0xc0, 0xf1, 0xa1, 0x28, 0x25, 0x86, 0xe2, 0x0e, 0xd4,
0xc4, 0x0c, 0x20, 0x5f, 0xc7, 0x27, 0x16, 0x04, 0x88, 0x31, 0x76, 0xef, 0x03, 0x51, 0xf3, 0x69,
0xb1, 0x51, 0xc3, 0x03, 0x8a, 0x4f, 0xec, 0x92, 0x23, 0x26, 0xf4, 0xd0, 0xbe, 0xc4, 0x83, 0xea,
0x1d, 0x58, 0x64, 0x28, 0x6c, 0x3c, 0x2d, 0x7e, 0xee, 0x57, 0xf8, 0x58, 0x4d, 0xed, 0x4b, 0x36,
0x98, 0x3b, 0xc8, 0x7a, 0xbd, 0x09, 0x35, 0x39, 0xa9, 0x96, 0xe3, 0x8a, 0x79, 0xad, 0x8a, 0x79,
0xed, 0xba, 0xec, 0xb8, 0x61, 0xe9, 0x7c, 0x9c, 0xac, 0x31, 0x9d, 0x85, 0xe7, 0x82, 0x8c, 0x2f,
0x4e, 0x1d, 0x97, 0x0f, 0xef, 0x2e, 0x83, 0x1a, 0xbf, 0x9d, 0x83, 0xba, 0x18, 0x75, 0x64, 0x23,
0xc9, 0x16, 0x10, 0xb9, 0xc4, 0xc3, 0x4b, 0x67, 0x6c, 0x9d, 0x5c, 0x85, 0x34, 0xe0, 0x3b, 0x6a,
0xff, 0x86, 0xd9, 0x14, 0x69, 0xc3, 0x4b, 0x67, 0xbc, 0xcd, 0x52, 0xc8, 0x7d, 0x68, 0xc6, 0xf0,
0x83, 0xd0, 0xe7, 0xdb, 0x7d, 0xff, 0x86, 0xb9, 0xa8, 0x61, 0x0f, 0x42, 0x9f, 0x11, 0x10, 0xc6,
0xa4, 0xce, 0x43, 0xcb, 0x71, 0xc7, 0xf4, 0x12, 0xe7, 0xa3, 0x61, 0xd6, 0x38, 0xac, 0xcb, 0x40,
0xdb, 0x8b, 0x50, 0xd7, 0x8b, 0x33, 0xce, 0xa0, 0x22, 0x39, 0x5c, 0x64, 0xf1, 0x12, 0x4d, 0x32,
0xab, 0xa1, 0x6a, 0xc9, 0x4d, 0xa8, 0xc4, 0x5b, 0x60, 0x96, 0xc3, 0xd7, 0xae, 0xd8, 0xf8, 0x1e,
0x34, 0x0f, 0xd8, 0x44, 0xb8, 0x6c, 0x27, 0x0b, 0x8e, 0x7d, 0x1d, 0x16, 0x34, 0x8a, 0x52, 0x35,
0xc5, 0x17, 0xe3, 0x59, 0xce, 0xbd, 0x20, 0x14, 0xb5, 0xe0, 0x6f, 0xe3, 0x9f, 0xe4, 0x80, 0x74,
0x82, 0xd0, 0x99, 0xda, 0x21, 0xdd, 0xa3, 0x8a, 0x66, 0xf6, 0xa1, 0xce, 0x4a, 0x1b, 0x7a, 0x6d,
0xce, 0x42, 0x73, 0x86, 0xec, 0x7d, 0x41, 0xe3, 0xd2, 0x19, 0xb6, 0x74, 0x6c, 0x7e, 0x4c, 0xc6,
0x0a, 0x60, 0xcb, 0x2d, 0xb4, 0xfd, 0x33, 0x1a, 0x22, 0xe3, 0x2d, 0x38, 0x46, 0xe0, 0x20, 0xc6,
0x72, 0x6f, 0xfe, 0x2c, 0x2c, 0xa7, 0xca, 0xd0, 0x0f, 0xad, 0x6a, 0xc6, 0xa1, 0x55, 0xd0, 0x0f,
0xad, 0x5f, 0xcf, 0xc1, 0x4a, 0xac, 0x61, 0x62, 0x1b, 0x6e, 0x40, 0x99, 0x91, 0x0b, 0xb6, 0x78,
0x73, 0x5c, 0x10, 0x38, 0xa5, 0xb8, 0xc0, 0x3f, 0x86, 0xd5, 0x53, 0x4a, 0x7d, 0x3b, 0xc4, 0x44,
0xa4, 0x27, 0x6c, 0x8a, 0x78, 0xc9, 0x9c, 0xea, 0x8b, 0xf4, 0x81, 0x1d, 0x1e, 0x51, 0x9f, 0x4d,
0x17, 0x31, 0xa0, 0x21, 0x91, 0x2f, 0x10, 0xbb, 0x80, 0x8b, 0xb8, 0x16, 0x20, 0xca, 0x53, 0x06,
0x32, 0xfe, 0x38, 0x0f, 0x4b, 0xec, 0x1c, 0x3a, 0xb4, 0xdd, 0x2b, 0x39, 0xa0, 0x07, 0x99, 0x03,
0x7a, 0x4f, 0xe3, 0x3a, 0x34, 0xec, 0xaf, 0x3b, 0x9a, 0x85, 0xe4, 0x68, 0xa6, 0x9b, 0x59, 0x4c,
0x35, 0x93, 0xbc, 0x03, 0xf5, 0x58, 0xbf, 0x4b, 0xaa, 0xdf, 0x10, 0x44, 0x1d, 0x56, 0xc2, 0xc3,
0x82, 0x26, 0x3c, 0x30, 0xd2, 0xc2, 0x76, 0x2a, 0xab, 0x3d, 0x10, 0x1c, 0x21, 0xa3, 0xd7, 0xac,
0xee, 0x80, 0x49, 0x58, 0x01, 0x23, 0x65, 0xd6, 0xdc, 0x15, 0x52, 0x16, 0x1d, 0x23, 0x3d, 0xa8,
0x98, 0x4d, 0x4c, 0x38, 0x8e, 0xe0, 0x7f, 0xf6, 0x79, 0x7f, 0x17, 0x9a, 0xd1, 0xf0, 0x89, 0x39,
0x27, 0x50, 0x64, 0x7b, 0x48, 0x14, 0x80, 0xbf, 0x8d, 0xbf, 0x9b, 0xe7, 0x88, 0x3b, 0x9e, 0x13,
0x89, 0x3a, 0x04, 0x8a, 0xc8, 0x4a, 0x09, 0x44, 0xf6, 0xfb, 0x5a, 0xc1, 0xf1, 0xa7, 0x38, 0xe8,
0x37, 0xa1, 0x12, 0xb0, 0x01, 0xb4, 0x27, 0x7c, 0xdc, 0x2b, 0x66, 0x99, 0x7d, 0xb7, 0x27, 0x93,
0x68, 0x3e, 0xca, 0xd7, 0xce, 0x47, 0xe5, 0x75, 0xe6, 0xa3, 0x9a, 0x3d, 0x1f, 0xc6, 0x7b, 0xb0,
0xac, 0x8d, 0xd2, 0x4b, 0xc6, 0xf3, 0x1c, 0xc8, 0x81, 0x13, 0x84, 0xc7, 0x2e, 0x2b, 0x42, 0xb1,
0x34, 0xb1, 0x86, 0xe4, 0x12, 0x0d, 0x61, 0x89, 0xf6, 0xa5, 0x48, 0xcc, 0x8b, 0x44, 0xfb, 0x92,
0x27, 0x5e, 0x2f, 0x33, 0x7e, 0x0e, 0x2b, 0xb1, 0x9a, 0x44, 0xa3, 0xde, 0x82, 0xd2, 0x3c, 0xbc,
0xf4, 0xa4, 0xb4, 0x58, 0x13, 0x7b, 0xe9, 0x38, 0xbc, 0xf4, 0x4c, 0x9e, 0x62, 0x1c, 0xc3, 0x72,
0x8f, 0xbe, 0x10, 0x74, 0x51, 0x36, 0xf1, 0x5d, 0x28, 0xbe, 0x42, 0x33, 0x82, 0xe9, 0x7a, 0x83,
0xf2, 0xf1, 0x06, 0x6d, 0x01, 0xd1, 0x8b, 0x15, 0xed, 0xd1, 0x54, 0x28, 0xb9, 0x98, 0x0a, 0xc5,
0x78, 0x17, 0xc8, 0xc0, 0x39, 0x73, 0x0f, 0x69, 0x10, 0xd8, 0x67, 0x8a, 0xc6, 0x36, 0xa1, 0x30,
0x0d, 0xce, 0xc4, 0x81, 0xc0, 0x7e, 0x1a, 0x1f, 0xc3, 0x4a, 0x0c, 0x4f, 0x14, 0xfc, 0x06, 0x54,
0x03, 0xe7, 0xcc, 0x45, 0x29, 0x40, 0x14, 0x1d, 0x01, 0x8c, 0x3d, 0x58, 0x7d, 0x4a, 0x7d, 0xe7,
0xf4, 0xea, 0x55, 0xc5, 0xc7, 0xcb, 0xc9, 0x27, 0xcb, 0xe9, 0xc0, 0x5a, 0xa2, 0x1c, 0x51, 0x3d,
0xdf, 0x7a, 0x62, 0xf6, 0x2b, 0x26, 0xff, 0xd0, 0x0e, 0x99, 0xbc, 0x7e, 0xc8, 0x18, 0x1e, 0x90,
0x1d, 0xcf, 0x75, 0xe9, 0x28, 0x3c, 0xa2, 0xd4, 0x97, 0x8d, 0x79, 0x5f, 0xdb, 0x67, 0xb5, 0x87,
0x1b, 0x62, 0xcc, 0x93, 0x27, 0x97, 0xd8, 0x80, 0x04, 0x8a, 0x33, 0xea, 0x4f, 0xb1, 0xe0, 0x8a,
0x89, 0xbf, 0xd9, 0xe0, 0x86, 0xce, 0x94, 0x7a, 0xf3, 0x50, 0x50, 0x5c, 0xf9, 0x69, 0xac, 0xc1,
0x4a, 0xac, 0x42, 0xde, 0x6a, 0xe3, 0x01, 0xac, 0xed, 0x3a, 0xc1, 0x28, 0xdd, 0x94, 0x0d, 0x28,
0xcf, 0xe6, 0x27, 0x56, 0xfc, 0x78, 0x7c, 0x42, 0xaf, 0x8c, 0x16, 0xac, 0x27, 0x73, 0x88, 0xb2,
0x7e, 0x2d, 0x0f, 0xc5, 0xfd, 0xe1, 0xc1, 0x0e, 0xd9, 0x84, 0x8a, 0xe3, 0x8e, 0xbc, 0x29, 0x13,
0x0e, 0xf8, 0x68, 0xa8, 0xef, 0x6b, 0xc9, 0xc6, 0x2d, 0xa8, 0xa2, 0x4c, 0x31, 0xf1, 0x46, 0xcf,
0x05, 0x7b, 0x5e, 0x61, 0x80, 0x03, 0x6f, 0xf4, 0x9c, 0x6d, 0x4d, 0x7a, 0x39, 0x73, 0x7c, 0x54,
0x37, 0x49, 0x75, 0x4a, 0x91, 0xf3, 0xa3, 0x51, 0x42, 0xa4, 0x74, 0x11, 0xac, 0x13, 0x63, 0x06,
0x38, 0x9f, 0x5e, 0x3d, 0x47, 0xd6, 0x69, 0x4c, 0x2f, 0xc9, 0x07, 0x40, 0x4e, 0x3d, 0xff, 0x85,
0xed, 0x2b, 0xd6, 0xd2, 0x15, 0x64, 0xbb, 0x68, 0x2e, 0x47, 0x29, 0x82, 0x6d, 0x22, 0x0f, 0x61,
0x4d, 0x43, 0xd7, 0x0a, 0xe6, 0x2c, 0xde, 0x4a, 0x94, 0xb8, 0x2f, 0xab, 0x30, 0x7e, 0x35, 0x0f,
0x44, 0xe4, 0xdf, 0xf1, 0xdc, 0x20, 0xf4, 0x6d, 0xc7, 0x0d, 0x83, 0x38, 0xa3, 0x99, 0x4b, 0x30,
0x9a, 0xf7, 0xa0, 0x89, 0x6c, 0xae, 0xce, 0x6d, 0xe6, 0x23, 0x9e, 0xdf, 0x8c, 0x38, 0xce, 0x77,
0x60, 0x31, 0x12, 0x35, 0x94, 0xb6, 0xb1, 0x68, 0xd6, 0x95, 0xb8, 0xc1, 0xb0, 0x3e, 0x84, 0x55,
0x46, 0x44, 0x24, 0x0b, 0xad, 0x54, 0x27, 0x9c, 0xd8, 0x2e, 0x4f, 0xed, 0xcb, 0x23, 0x2a, 0x05,
0x1b, 0xe4, 0x4d, 0x0d, 0x68, 0x28, 0xae, 0x13, 0x31, 0xf9, 0xc8, 0xd5, 0x04, 0xdf, 0x89, 0x38,
0xd9, 0x82, 0xc1, 0x42, 0xb6, 0x60, 0x60, 0xfc, 0xeb, 0x2a, 0x94, 0xe5, 0x30, 0x22, 0x97, 0x1f,
0x3a, 0x17, 0x34, 0xe2, 0xf2, 0xd9, 0x17, 0x13, 0x1e, 0x7c, 0x3a, 0xf5, 0x42, 0x25, 0xdd, 0xf1,
0x6d, 0x52, 0xe7, 0x40, 0x21, 0xdf, 0x69, 0x12, 0x06, 0x57, 0x92, 0x72, 0xca, 0x27, 0x25, 0x0c,
0xce, 0x3f, 0xde, 0x82, 0xb2, 0x94, 0x13, 0x8a, 0x4a, 0x47, 0xb2, 0x30, 0xe2, 0x42, 0xc2, 0x26,
0x54, 0x46, 0xf6, 0xcc, 0x1e, 0x39, 0x21, 0x67, 0xf1, 0x0b, 0xa6, 0xfa, 0x66, 0xa5, 0x4f, 0xbc,
0x91, 0x3d, 0xb1, 0x4e, 0xec, 0x89, 0xed, 0x8e, 0xa8, 0xd0, 0x3e, 0xd6, 0x11, 0xb8, 0xcd, 0x61,
0xe4, 0x5b, 0xb0, 0x28, 0xda, 0x29, 0xb1, 0xb8, 0x12, 0x52, 0xb4, 0x5e, 0xa2, 0x31, 0x49, 0xd4,
0x9b, 0xb2, 0x79, 0x39, 0xa5, 0x5c, 0x66, 0x2b, 0x98, 0x55, 0x0e, 0xd9, 0xa3, 0xd8, 0x5b, 0x91,
0xfc, 0x82, 0xaf, 0xe1, 0x2a, 0xaf, 0x8a, 0x03, 0xbf, 0xe2, 0xeb, 0x37, 0x2d, 0xb8, 0x15, 0x34,
0xc1, 0xed, 0x7d, 0x58, 0x9e, 0xbb, 0x01, 0x0d, 0xc3, 0x09, 0x1d, 0xab, 0xb6, 0xd4, 0x10, 0xa9,
0xa9, 0x12, 0x64, 0x73, 0xb6, 0x60, 0x85, 0xab, 0x4d, 0x03, 0x3b, 0xf4, 0x82, 0x73, 0x27, 0xb0,
0x02, 0xea, 0x4a, 0xf5, 0xd9, 0x32, 0x26, 0x0d, 0x44, 0xca, 0x80, 0xab, 0x5c, 0x36, 0x12, 0xf8,
0x3e, 0x1d, 0x51, 0xe7, 0x82, 0x8e, 0x51, 0xa8, 0x2b, 0x98, 0x6b, 0xb1, 0x3c, 0xa6, 0x48, 0x44,
0x09, 0x7d, 0x3e, 0xb5, 0xe6, 0xb3, 0xb1, 0xcd, 0x98, 0xf7, 0x45, 0x2e, 0x25, 0xb9, 0xf3, 0xe9,
0x31, 0x87, 0x90, 0x07, 0x20, 0xa5, 0x36, 0xb1, 0x66, 0x96, 0x62, 0x87, 0x11, 0xa3, 0x1a, 0x66,
0x5d, 0x60, 0x70, 0xa9, 0xf2, 0x8e, 0xbe, 0x59, 0x9a, 0x6c, 0x85, 0xe1, 0xf1, 0x1f, 0x6d, 0x98,
0x16, 0x94, 0x67, 0xbe, 0x73, 0x61, 0x87, 0xb4, 0xb5, 0xcc, 0xcf, 0x7e, 0xf1, 0xc9, 0x08, 0xb8,
0xe3, 0x3a, 0xa1, 0x63, 0x87, 0x9e, 0xdf, 0x22, 0x98, 0x16, 0x01, 0xc8, 0x7d, 0x58, 0xc6, 0x75,
0x12, 0x84, 0x76, 0x38, 0x0f, 0x84, 0xc8, 0xba, 0xc2, 0x45, 0x43, 0x96, 0x30, 0x40, 0x38, 0x4a,
0xad, 0xe4, 0x33, 0x58, 0xe7, 0x4b, 0x23, 0xb5, 0x35, 0x57, 0x15, 0x43, 0xb2, 0x82, 0x18, 0x3b,
0xf1, 0x3d, 0xfa, 0x05, 0x6c, 0x88, 0xe5, 0x92, 0xca, 0xb9, 0xa6, 0x72, 0xae, 0x72, 0x94, 0x44,
0xd6, 0x2d, 0x58, 0x66, 0x4d, 0x73, 0x46, 0x96, 0x28, 0x81, 0xed, 0x8a, 0x75, 0xd6, 0x0b, 0xcc,
0xb4, 0xc4, 0x13, 0x4d, 0x4c, 0x7b, 0x42, 0xaf, 0xc8, 0xf7, 0x60, 0x89, 0x2f, 0x1f, 0xd4, 0xcb,
0xe0, 0x91, 0xbd, 0x89, 0x47, 0xf6, 0x9a, 0x18, 0xdc, 0x1d, 0x95, 0x8a, 0xa7, 0xf6, 0xe2, 0x28,
0xf6, 0xcd, 0xb6, 0xc6, 0xc4, 0x39, 0xa5, 0xec, 0x9c, 0x68, 0x6d, 0xf0, 0xc5, 0x26, 0xbf, 0xd9,
0xae, 0x9d, 0xcf, 0x30, 0xa5, 0xc5, 0x89, 0x35, 0xff, 0xc2, 0x75, 0x3c, 0xf1, 0x02, 0x2a, 0x15,
0xee, 0xad, 0x9b, 0x62, 0x43, 0x32, 0xa0, 0x94, 0xaf, 0x98, 0x00, 0xcf, 0xb5, 0x25, 0xca, 0x2c,
0x72, 0x0b, 0x17, 0x46, 0x83, 0x2b, 0x4d, 0xa4, 0x69, 0x84, 0x31, 0x8c, 0xe7, 0xf6, 0x0b, 0x49,
0xd6, 0xdf, 0x40, 0x6a, 0x02, 0x0c, 0x24, 0x08, 0xfa, 0x1e, 0x2c, 0x8b, 0x59, 0x88, 0x88, 0x69,
0xeb, 0x36, 0x1e, 0x91, 0x37, 0x65, 0x1f, 0x53, 0xd4, 0xd6, 0x6c, 0xf2, 0x79, 0xd1, 0xe8, 0xef,
0x3e, 0x10, 0x39, 0x29, 0x5a, 0x41, 0x6f, 0xbe, 0xaa, 0xa0, 0x65, 0x31, 0x4d, 0x11, 0xc8, 0xf8,
0xbd, 0x1c, 0xe7, 0xb5, 0x04, 0x76, 0xa0, 0x69, 0xaa, 0x38, 0x5d, 0xb3, 0x3c, 0x77, 0x72, 0x25,
0x48, 0x1d, 0x70, 0x50, 0xdf, 0x9d, 0x20, 0xad, 0x71, 0x5c, 0x1d, 0x85, 0x1f, 0xde, 0x75, 0x09,
0x44, 0xa4, 0x3b, 0x50, 0x9b, 0xcd, 0x4f, 0x26, 0xce, 0x88, 0xa3, 0x14, 0x78, 0x29, 0x1c, 0x84,
0x08, 0x6f, 0x41, 0x5d, 0xac, 0x75, 0x8e, 0x51, 0x44, 0x8c, 0x9a, 0x80, 0x21, 0x0a, 0x32, 0x07,
0xd4, 0x47, 0x62, 0x57, 0x37, 0xf1, 0xb7, 0xb1, 0x0d, 0xab, 0xf1, 0x46, 0x0b, 0xce, 0xe5, 0x3e,
0x54, 0x04, 0x25, 0x95, 0x6a, 0xde, 0xc5, 0xf8, 0x68, 0x98, 0x2a, 0xdd, 0xf8, 0x37, 0x25, 0x58,
0x91, 0x63, 0xc4, 0x26, 0x7b, 0x30, 0x9f, 0x4e, 0x6d, 0x3f, 0x83, 0x44, 0xe7, 0x5e, 0x4e, 0xa2,
0xf3, 0x29, 0x12, 0x1d, 0x57, 0xe2, 0x71, 0x0a, 0x1f, 0x57, 0xe2, 0xb1, 0xd5, 0xc5, 0x55, 0x07,
0xba, 0x9d, 0xa9, 0x21, 0xc0, 0x43, 0x6e, 0xcf, 0x4a, 0x1d, 0x28, 0xa5, 0x8c, 0x03, 0x45, 0x3f,
0x0e, 0x16, 0x12, 0xc7, 0xc1, 0x5b, 0xc0, 0x97, 0xb1, 0x5c, 0x8f, 0x65, 0xae, 0x4d, 0x40, 0x98,
0x58, 0x90, 0xef, 0xc1, 0x52, 0x92, 0x02, 0x73, 0x52, 0xbf, 0x98, 0x41, 0x7f, 0x9d, 0x29, 0x45,
0xa6, 0x46, 0x43, 0xae, 0x0a, 0xfa, 0xeb, 0x4c, 0xe9, 0x01, 0xa6, 0x48, 0xfc, 0x0e, 0x00, 0xaf,
0x1b, 0xb7, 0x31, 0xe0, 0x36, 0x7e, 0x37, 0xb1, 0x32, 0xb5, 0x51, 0xdf, 0x62, 0x1f, 0x73, 0x9f,
0xe2, 0xbe, 0xae, 0x62, 0x4e, 0xdc, 0xd2, 0x9f, 0xc1, 0xa2, 0x37, 0xa3, 0xae, 0x15, 0x51, 0xc1,
0x1a, 0x16, 0xd5, 0x14, 0x45, 0x75, 0x25, 0xdc, 0x6c, 0x30, 0x3c, 0xf5, 0x49, 0xbe, 0xe0, 0x83,
0x4c, 0xb5, 0x9c, 0xf5, 0x6b, 0x72, 0x2e, 0x22, 0x62, 0x94, 0xf5, 0x63, 0x54, 0x94, 0x79, 0x93,
0x39, 0x37, 0x4d, 0x35, 0x70, 0x1d, 0x49, 0x5d, 0xbd, 0xa9, 0x52, 0x4c, 0x1d, 0xcb, 0xf8, 0x8d,
0x1c, 0xd4, 0xb4, 0x3e, 0x90, 0x35, 0x58, 0xde, 0xe9, 0xf7, 0x8f, 0x3a, 0x66, 0x7b, 0xd8, 0x7d,
0xda, 0xb1, 0x76, 0x0e, 0xfa, 0x83, 0x4e, 0xf3, 0x06, 0x03, 0x1f, 0xf4, 0x77, 0xda, 0x07, 0xd6,
0x5e, 0xdf, 0xdc, 0x91, 0xe0, 0x1c, 0x59, 0x07, 0x62, 0x76, 0x0e, 0xfb, 0xc3, 0x4e, 0x0c, 0x9e,
0x27, 0x4d, 0xa8, 0x6f, 0x9b, 0x9d, 0xf6, 0xce, 0xbe, 0x80, 0x14, 0xc8, 0x2a, 0x34, 0xf7, 0x8e,
0x7b, 0xbb, 0xdd, 0xde, 0x63, 0x6b, 0xa7, 0xdd, 0xdb, 0xe9, 0x1c, 0x74, 0x76, 0x9b, 0x45, 0xd2,
0x80, 0x6a, 0x7b, 0xbb, 0xdd, 0xdb, 0xed, 0xf7, 0x3a, 0xbb, 0xcd, 0x92, 0xf1, 0xc7, 0x39, 0x80,
0xa8, 0xa1, 0x8c, 0xae, 0x46, 0x4d, 0xd5, 0x8d, 0xc4, 0x6b, 0xa9, 0x4e, 0x71, 0xba, 0xea, 0xc7,
0xbe, 0xc9, 0x43, 0x28, 0x7b, 0xf3, 0x70, 0xe4, 0x4d, 0xb9, 0x10, 0xb1, 0xf8, 0xb0, 0x95, 0xca,
0xd7, 0xe7, 0xe9, 0xa6, 0x44, 0x8c, 0x19, 0x82, 0x0b, 0xaf, 0x32, 0x04, 0xc7, 0x2d, 0xce, 0x9c,
0xaf, 0xd3, 0x2c, 0xce, 0xb7, 0x01, 0x82, 0x17, 0x94, 0xce, 0x50, 0xd3, 0x26, 0x76, 0x41, 0x15,
0x21, 0x43, 0x26, 0x97, 0xfe, 0x87, 0x1c, 0xac, 0xe1, 0x5a, 0x1a, 0x27, 0x89, 0xd8, 0x5d, 0xa8,
0x8d, 0x3c, 0x6f, 0x46, 0x19, 0x53, 0xad, 0xf8, 0x35, 0x1d, 0xc4, 0x08, 0x14, 0x27, 0xc8, 0xa7,
0x9e, 0x3f, 0xa2, 0x82, 0x86, 0x01, 0x82, 0xf6, 0x18, 0x84, 0xed, 0x21, 0xb1, 0x09, 0x39, 0x06,
0x27, 0x61, 0x35, 0x0e, 0xe3, 0x28, 0xeb, 0xb0, 0x70, 0xe2, 0x53, 0x7b, 0x74, 0x2e, 0xa8, 0x97,
0xf8, 0x22, 0xdf, 0x8e, 0x34, 0x8e, 0x23, 0xb6, 0x27, 0x26, 0x94, 0x37, 0xbe, 0x62, 0x2e, 0x09,
0xf8, 0x8e, 0x00, 0xb3, 0x73, 0xde, 0x3e, 0xb1, 0xdd, 0xb1, 0xe7, 0xd2, 0xb1, 0x90, 0xff, 0x23,
0x80, 0x71, 0x04, 0xeb, 0xc9, 0xfe, 0x09, 0x7a, 0xf7, 0xa9, 0x46, 0xef, 0xb8, 0x50, 0xbc, 0x79,
0xfd, 0x1e, 0xd3, 0x68, 0xdf, 0x7f, 0x2c, 0x42, 0x91, 0x09, 0x3c, 0xd7, 0xca, 0x46, 0xba, 0x6c,
0x5b, 0x48, 0xb9, 0x07, 0xa0, 0x62, 0x93, 0x33, 0x60, 0x62, 0xb2, 0x10, 0x82, 0x8c, 0x97, 0x4a,
0xf6, 0xe9, 0xe8, 0x42, 0xca, 0x2c, 0x08, 0x31, 0xe9, 0xe8, 0x02, 0x15, 0x1d, 0x76, 0xc8, 0xf3,
0x72, 0x7a, 0x55, 0x0e, 0xec, 0x10, 0x73, 0x8a, 0x24, 0xcc, 0x57, 0x56, 0x49, 0x98, 0xab, 0x05,
0x65, 0xc7, 0x3d, 0xf1, 0xe6, 0xae, 0x54, 0x2b, 0xc9, 0x4f, 0xf4, 0x46, 0x40, 0x4a, 0xca, 0x8e,
0x76, 0x4e, 0x8d, 0x2a, 0x0c, 0x30, 0x64, 0x87, 0xfb, 0x47, 0x50, 0x0d, 0xae, 0xdc, 0x91, 0x4e,
0x83, 0x56, 0xc5, 0xf8, 0xb0, 0xde, 0x6f, 0x0d, 0xae, 0xdc, 0x11, 0xae, 0xf8, 0x4a, 0x20, 0x7e,
0x91, 0x47, 0x50, 0x51, 0x56, 0x3a, 0x7e, 0x82, 0xdc, 0xd4, 0x73, 0x48, 0xd3, 0x1c, 0xd7, 0xd1,
0x29, 0x54, 0xf2, 0x21, 0x2c, 0xa0, 0xb6, 0x3e, 0x68, 0xd5, 0x31, 0x93, 0x14, 0x78, 0x59, 0x33,
0xd0, 0x11, 0x80, 0x8e, 0xd1, 0x66, 0x66, 0x0a, 0x34, 0x36, 0x4c, 0xa7, 0x13, 0x7b, 0x26, 0x74,
0xe7, 0x0d, 0x6e, 0x4f, 0x67, 0x10, 0xae, 0x38, 0xbf, 0x0b, 0x75, 0xb4, 0x80, 0x22, 0x8e, 0xcb,
0xf9, 0xd0, 0x82, 0x09, 0x0c, 0xb6, 0x37, 0xb1, 0x67, 0xbd, 0x60, 0xf3, 0x09, 0x34, 0x62, 0x8d,
0xd1, 0x55, 0x68, 0x0d, 0xae, 0x42, 0x7b, 0x47, 0x57, 0xa1, 0x45, 0x47, 0xa1, 0xc8, 0xa6, 0xab,
0xd4, 0x8e, 0xa0, 0x22, 0xc7, 0x82, 0xd1, 0x9c, 0xe3, 0xde, 0x93, 0x5e, 0xff, 0xab, 0x9e, 0x35,
0x78, 0xd6, 0xdb, 0x69, 0xde, 0x20, 0x4b, 0x50, 0x6b, 0xef, 0x20, 0x19, 0x43, 0x40, 0x8e, 0xa1,
0x1c, 0xb5, 0x07, 0x03, 0x05, 0xc9, 0x33, 0x94, 0xa3, 0x6e, 0xaf, 0xd7, 0xd9, 0xe5, 0x80, 0x82,
0xb1, 0x07, 0xcd, 0x64, 0xdf, 0xd9, 0x2a, 0x0f, 0x25, 0x4c, 0xd8, 0x25, 0x23, 0x40, 0x64, 0xfd,
0xc8, 0x6b, 0xd6, 0x0f, 0xe3, 0x11, 0x34, 0xd9, 0x49, 0xcf, 0x06, 0x5f, 0x77, 0x57, 0x98, 0x30,
0x5e, 0x5c, 0xb7, 0x4d, 0x56, 0xcc, 0x1a, 0x87, 0x61, 0x55, 0xc6, 0xa7, 0xb0, 0xac, 0x65, 0x8b,
0xf4, 0x47, 0x8c, 0x7b, 0x48, 0xea, 0x8f, 0x50, 0xf2, 0xe7, 0x29, 0xc6, 0x06, 0xac, 0xb1, 0xcf,
0xce, 0x05, 0x75, 0xc3, 0xc1, 0xfc, 0x84, 0x7b, 0xb9, 0x38, 0x9e, 0x6b, 0xfc, 0x6a, 0x0e, 0xaa,
0x2a, 0xe5, 0xfa, 0x6d, 0xb3, 0x25, 0x54, 0x4d, 0x9c, 0x4e, 0x6e, 0x6a, 0x35, 0x60, 0xc6, 0x2d,
0xfc, 0x1b, 0xa9, 0x9c, 0x8c, 0x2d, 0xa8, 0x2a, 0x10, 0x0e, 0x62, 0xa7, 0x63, 0x5a, 0xfd, 0xde,
0x41, 0xb7, 0xc7, 0x4e, 0x0b, 0x36, 0xce, 0x08, 0xd8, 0xdb, 0x43, 0x48, 0xce, 0x68, 0xc2, 0xe2,
0x63, 0x1a, 0x76, 0xdd, 0x53, 0x4f, 0x0c, 0x86, 0xf1, 0xeb, 0x0b, 0xb0, 0xa4, 0x40, 0x91, 0x62,
0xea, 0x82, 0xfa, 0x81, 0xe3, 0xb9, 0xb8, 0x70, 0xaa, 0xa6, 0xfc, 0x64, 0xf4, 0x4e, 0x88, 0x6d,
0xc8, 0x77, 0xac, 0x62, 0xaa, 0x10, 0xf4, 0x90, 0xe9, 0x78, 0x0f, 0x96, 0x9c, 0x31, 0x75, 0x43,
0x27, 0xbc, 0xb2, 0x62, 0x36, 0x85, 0x45, 0x09, 0x16, 0x8c, 0xc7, 0x2a, 0x94, 0xec, 0x89, 0x63,
0x4b, 0xef, 0x21, 0xfe, 0xc1, 0xa0, 0x23, 0x6f, 0xe2, 0xf9, 0x28, 0xc8, 0x54, 0x4d, 0xfe, 0x41,
0x1e, 0xc0, 0x2a, 0x13, 0xaa, 0x74, 0x23, 0x18, 0x92, 0x2c, 0x6e, 0xde, 0x20, 0xee, 0x7c, 0x7a,
0x14, 0x19, 0xc2, 0x58, 0x0a, 0x63, 0x37, 0x58, 0x0e, 0xc1, 0x5f, 0xaa, 0x0c, 0x5c, 0x51, 0xb2,
0xec, 0xce, 0xa7, 0x6d, 0x4c, 0x51, 0xf8, 0x0f, 0x61, 0x8d, 0xe1, 0x2b, 0x8e, 0x54, 0xe5, 0x58,
0xc2, 0x1c, 0xac, 0xb0, 0xae, 0x48, 0x53, 0x79, 0x6e, 0x41, 0x95, 0xb7, 0x8a, 0x2d, 0x09, 0x61,
0x2d, 0xc3, 0xa6, 0x50, 0x3f, 0x48, 0x39, 0xfa, 0x70, 0xcd, 0x40, 0xd2, 0xd1, 0x47, 0x73, 0x15,
0xaa, 0x24, 0x5d, 0x85, 0x1e, 0xc2, 0xda, 0x09, 0x5b, 0xa3, 0xe7, 0xd4, 0x1e, 0x53, 0xdf, 0x8a,
0x56, 0x3e, 0x97, 0x3f, 0x57, 0x58, 0xe2, 0x3e, 0xa6, 0xa9, 0x8d, 0xc2, 0x58, 0x43, 0x46, 0x89,
0xe8, 0xd8, 0x0a, 0x3d, 0x0b, 0x39, 0x46, 0xa1, 0xb6, 0x6d, 0x70, 0xf0, 0xd0, 0xdb, 0x61, 0xc0,
0x38, 0xde, 0x99, 0x6f, 0xcf, 0xce, 0x85, 0x74, 0xa8, 0xf0, 0x1e, 0x33, 0x20, 0x79, 0x03, 0xca,
0x6c, 0x4f, 0xb8, 0x94, 0x7b, 0x47, 0x70, 0xb9, 0x4b, 0x82, 0xc8, 0x3b, 0xb0, 0x80, 0x75, 0x04,
0xad, 0x26, 0x6e, 0x88, 0x7a, 0x74, 0x76, 0x38, 0xae, 0x29, 0xd2, 0x18, 0xff, 0x3d, 0xf7, 0x1d,
0x4e, 0xd8, 0xaa, 0x26, 0xfe, 0x26, 0xdf, 0xd7, 0xa8, 0xe4, 0x0a, 0xe6, 0x7d, 0x47, 0xe4, 0x4d,
0x2c, 0xc5, 0xeb, 0x08, 0xe6, 0x37, 0x4a, 0xbe, 0x7e, 0x50, 0xac, 0xd4, 0x9a, 0x75, 0xa3, 0x85,
0xfe, 0x4d, 0x26, 0x1d, 0x79, 0x17, 0xd4, 0xbf, 0x8a, 0xed, 0x91, 0x1c, 0x6c, 0xa4, 0x92, 0x22,
0x4f, 0x07, 0x5f, 0xc0, 0xad, 0xa9, 0x37, 0x96, 0x5c, 0x42, 0x5d, 0x02, 0x0f, 0xbd, 0x31, 0xe3,
0x66, 0x96, 0x15, 0xd2, 0xa9, 0xe3, 0x3a, 0xc1, 0x39, 0x1d, 0x0b, 0x66, 0xa1, 0x29, 0x13, 0xf6,
0x04, 0x9c, 0xb1, 0xe4, 0x33, 0xdf, 0x3b, 0x53, 0x67, 0x67, 0xce, 0x54, 0xdf, 0xc6, 0x67, 0x50,
0xe2, 0x33, 0xc8, 0x36, 0x0a, 0xce, 0x6f, 0x4e, 0x6c, 0x14, 0x84, 0xb6, 0xa0, 0xec, 0xd2, 0xf0,
0x85, 0xe7, 0x3f, 0x97, 0x1a, 0x68, 0xf1, 0x69, 0xfc, 0x18, 0xb5, 0xac, 0xca, 0x51, 0x8d, 0x6b,
0x23, 0xd8, 0x12, 0xe6, 0x4b, 0x30, 0x38, 0xb7, 0x85, 0xe2, 0xb7, 0x82, 0x80, 0xc1, 0xb9, 0x9d,
0x5a, 0xc2, 0xf9, 0xb4, 0xaf, 0xda, 0x3b, 0xb0, 0x28, 0x5d, 0xe3, 0x02, 0x6b, 0x42, 0x4f, 0x43,
0xb1, 0x25, 0xeb, 0xc2, 0x2f, 0x2e, 0x38, 0xa0, 0xa7, 0xa1, 0x71, 0x08, 0xcb, 0x62, 0xd3, 0xf4,
0x67, 0x54, 0x56, 0xfd, 0x79, 0x96, 0x98, 0x54, 0x7b, 0xb8, 0x12, 0xe7, 0x3f, 0x38, 0xa7, 0x17,
0x93, 0x9d, 0x8c, 0x1f, 0x46, 0x2a, 0x45, 0xc6, 0x9d, 0x88, 0xf2, 0x84, 0xb0, 0x22, 0x0d, 0xaa,
0xd2, 0x69, 0x43, 0x89, 0x44, 0xce, 0x98, 0x8d, 0x4e, 0x30, 0x1f, 0x8d, 0xa4, 0xcb, 0x62, 0xc5,
0x94, 0x9f, 0xc6, 0xff, 0xcc, 0xc1, 0x0a, 0x16, 0x26, 0xc5, 0x3c, 0x71, 0x52, 0xfc, 0xc4, 0x8d,
0x64, 0xf3, 0xa3, 0xb3, 0x84, 0xfc, 0xe3, 0xd5, 0x16, 0xa1, 0xa4, 0xb5, 0xa7, 0x98, 0x69, 0xed,
0xf9, 0x36, 0x34, 0xc7, 0x74, 0xe2, 0xe0, 0x72, 0x92, 0x5c, 0x16, 0x67, 0x6b, 0x97, 0x24, 0x5c,
0xaa, 0x1e, 0x52, 0x26, 0xa6, 0x85, 0xb4, 0xf9, 0xf1, 0xaf, 0xe6, 0x60, 0x99, 0x33, 0x7a, 0xa8,
0xf0, 0x11, 0x03, 0xfa, 0xa5, 0xd4, 0x6c, 0x08, 0xb2, 0x2b, 0xfa, 0x1e, 0x31, 0x40, 0x08, 0xe5,
0xc8, 0xfb, 0x37, 0x84, 0xc6, 0x43, 0x40, 0xc9, 0x77, 0x51, 0x84, 0x75, 0x2d, 0x04, 0x0a, 0x06,
0xfe, 0x66, 0x06, 0x6b, 0xa9, 0xb2, 0x33, 0xf9, 0xd6, 0x45, 0xd0, 0x76, 0x05, 0x16, 0xb8, 0xfa,
0xcc, 0xd8, 0x83, 0x46, 0xac, 0x9a, 0x98, 0x59, 0xa9, 0xce, 0xcd, 0x4a, 0x29, 0x9b, 0x77, 0x3e,
0x6d, 0xf3, 0xbe, 0x82, 0x15, 0x93, 0xda, 0xe3, 0xab, 0x3d, 0xcf, 0x3f, 0x0a, 0x4e, 0xc2, 0x3d,
0xce, 0x3d, 0xb3, 0xb3, 0x4a, 0x79, 0xb9, 0xc4, 0xec, 0x30, 0xd2, 0x9e, 0x2f, 0x07, 0xf1, 0x5b,
0xb0, 0x18, 0xb9, 0xc3, 0x68, 0x1a, 0xfb, 0x86, 0xf2, 0x88, 0x41, 0xa6, 0x8b, 0x40, 0x71, 0x16,
0x9c, 0x84, 0x42, 0x67, 0x8f, 0xbf, 0x8d, 0x7f, 0x54, 0x02, 0xc2, 0x56, 0x7d, 0x62, 0x61, 0xa5,
0xa6, 0x25, 0x97, 0xb6, 0xfc, 0x25, 0x9c, 0x7d, 0xf2, 0x29, 0x67, 0x9f, 0x07, 0x40, 0x34, 0x04,
0xe9, 0x83, 0x54, 0x50, 0x3e, 0x48, 0xcd, 0x08, 0x57, 0xb8, 0x20, 0x3d, 0x80, 0x55, 0x21, 0xae,
0xc4, 0xbb, 0x83, 0xcb, 0xcc, 0x24, 0x5c, 0x6e, 0x89, 0xf5, 0x49, 0x3a, 0xfa, 0x48, 0x35, 0x78,
0x81, 0x3b, 0xfa, 0x48, 0x6d, 0x95, 0xb6, 0x98, 0x17, 0x5e, 0xb9, 0x98, 0xcb, 0x99, 0x8b, 0x59,
0xd3, 0x5e, 0x56, 0xe2, 0xda, 0xcb, 0x94, 0x1e, 0x9e, 0xf3, 0xe7, 0x31, 0x3d, 0xfc, 0x3d, 0x68,
0x4a, 0x4d, 0x96, 0xd2, 0x91, 0x0a, 0x0f, 0x10, 0xa1, 0xac, 0x92, 0x5a, 0xd2, 0x98, 0xa1, 0xb1,
0xf6, 0x3a, 0x16, 0xcf, 0x7a, 0xb6, 0xc5, 0x33, 0xad, 0xf3, 0x6b, 0x64, 0xe8, 0xfc, 0x1e, 0x45,
0x0e, 0x1e, 0xc1, 0xb9, 0x33, 0x45, 0x46, 0x2a, 0xf2, 0x50, 0x15, 0x83, 0x3c, 0x38, 0x77, 0xa6,
0xa6, 0x74, 0xb5, 0x62, 0x1f, 0x64, 0x07, 0xee, 0x88, 0xfe, 0x64, 0x78, 0x49, 0xf1, 0x51, 0x58,
0xc2, 0xa5, 0xb2, 0xc9, 0xd1, 0x0e, 0x13, 0x0e, 0x53, 0x89, 0x41, 0x91, 0x3e, 0x36, 0x01, 0x57,
0x1c, 0xcb, 0x41, 0x39, 0xe4, 0x4e, 0x36, 0x48, 0x1e, 0x18, 0x8a, 0x50, 0x2a, 0x06, 0x17, 0xc8,
0x77, 0x35, 0xcc, 0xda, 0xd4, 0xbe, 0x3c, 0x40, 0xa5, 0x61, 0x70, 0x61, 0xfc, 0x69, 0x0e, 0x9a,
0x6c, 0x09, 0xc7, 0xa8, 0xc3, 0x17, 0x80, 0xf4, 0xee, 0x35, 0x89, 0x43, 0x8d, 0xe1, 0x4a, 0xda,
0xf0, 0x19, 0xe0, 0x66, 0xb7, 0xbc, 0x19, 0x75, 0x05, 0x69, 0x68, 0xc5, 0x49, 0x43, 0x74, 0x4c,
0xec, 0xdf, 0xe0, 0x52, 0x27, 0x83, 0x90, 0x2f, 0xa0, 0xca, 0xf6, 0x14, 0x2e, 0x5e, 0xe1, 0x1d,
0xbe, 0xa9, 0x34, 0x09, 0xa9, 0xed, 0xcd, 0xb2, 0xce, 0xc4, 0x67, 0x96, 0x0b, 0x55, 0x31, 0xc3,
0x85, 0x4a, 0xa3, 0x3d, 0xfb, 0x00, 0x4f, 0xe8, 0x15, 0x1b, 0x84, 0xd0, 0xf3, 0x19, 0xaf, 0xc6,
0xb6, 0xd8, 0xa9, 0x3d, 0x75, 0x84, 0x36, 0xb3, 0x64, 0x56, 0x9f, 0xd3, 0xab, 0x3d, 0x04, 0xb0,
0xb5, 0xc5, 0x92, 0x23, 0x02, 0x54, 0x32, 0x2b, 0xcf, 0xe9, 0x15, 0xa7, 0x3e, 0x16, 0x34, 0x9e,
0xd0, 0xab, 0x5d, 0xca, 0x85, 0x01, 0xcf, 0x67, 0x83, 0xee, 0xdb, 0x2f, 0x18, 0xf7, 0x1f, 0x73,
0xf1, 0xa9, 0xf9, 0xf6, 0x8b, 0x27, 0xf4, 0x4a, 0xba, 0x1b, 0x95, 0x59, 0xfa, 0xc4, 0x1b, 0x09,
0xf6, 0x45, 0x2a, 0x90, 0xa2, 0x46, 0x99, 0x0b, 0xcf, 0xf1, 0xb7, 0xf1, 0x27, 0x39, 0x68, 0xb0,
0xf6, 0xe3, 0xc9, 0x83, 0xab, 0x48, 0xf8, 0x0c, 0xe7, 0x22, 0x9f, 0xe1, 0x87, 0x82, 0x20, 0xf3,
0x63, 0x2c, 0x7f, 0xfd, 0x31, 0x86, 0x73, 0xc3, 0xcf, 0xb0, 0x8f, 0xa0, 0xca, 0x17, 0x06, 0x23,
0x3f, 0x85, 0xd8, 0x04, 0xc7, 0x3a, 0x64, 0x56, 0x10, 0xed, 0x09, 0xf7, 0x3f, 0xd4, 0x74, 0xf5,
0x7c, 0x88, 0xab, 0xbe, 0xd2, 0xd0, 0x67, 0x4c, 0x43, 0xe9, 0x1a, 0xff, 0x43, 0x5d, 0x11, 0xbe,
0x90, 0x54, 0x84, 0x1b, 0x2e, 0x54, 0xd8, 0x54, 0x63, 0x67, 0x33, 0x0a, 0xcd, 0x65, 0x15, 0xca,
0x98, 0x1d, 0x9b, 0x9d, 0x67, 0x8c, 0x46, 0xe7, 0x05, 0xb3, 0x63, 0x07, 0x94, 0x15, 0xc4, 0x1a,
0xee, 0x7a, 0x16, 0x6a, 0x96, 0x85, 0xce, 0xb5, 0x62, 0x56, 0x5d, 0xef, 0x88, 0x03, 0x8c, 0xbf,
0x90, 0x83, 0x9a, 0xb6, 0x67, 0xd1, 0xd4, 0xa0, 0x86, 0x93, 0x6f, 0xf0, 0xf8, 0x0e, 0x88, 0xcd,
0xc7, 0xfe, 0x0d, 0xb3, 0x31, 0x8a, 0x4d, 0xd0, 0x96, 0x58, 0xca, 0x98, 0x33, 0x1f, 0xd3, 0x6f,
0xc9, 0x7e, 0xc9, 0xf5, 0xcb, 0x7e, 0x6f, 0x2f, 0x40, 0x91, 0xa1, 0x1a, 0x5f, 0xc2, 0xb2, 0xd6,
0x0c, 0xae, 0xff, 0x79, 0xdd, 0x01, 0x30, 0x7e, 0x41, 0x65, 0x66, 0x75, 0x70, 0xdb, 0xbd, 0x74,
0xf5, 0xa4, 0x63, 0x3e, 0x2e, 0xc2, 0xa5, 0x94, 0x83, 0x70, 0x64, 0x5e, 0xd3, 0xfb, 0xd0, 0xf8,
0x95, 0x1c, 0xac, 0x68, 0xc5, 0xef, 0x39, 0xae, 0x3d, 0x71, 0x7e, 0x8c, 0xc7, 0x58, 0xe0, 0x9c,
0xb9, 0x89, 0x0a, 0x38, 0xe8, 0xeb, 0x54, 0x40, 0xee, 0x42, 0x9d, 0xfb, 0x96, 0xf3, 0x9b, 0x0b,
0xe2, 0x98, 0x05, 0x84, 0x99, 0xf6, 0x8b, 0xe1, 0xa5, 0xf1, 0xd7, 0xf2, 0xb0, 0x2a, 0x9a, 0x80,
0x57, 0x00, 0x1c, 0xc6, 0xea, 0x1e, 0x06, 0x67, 0xe4, 0x0b, 0x68, 0xb0, 0xe1, 0xb3, 0x7c, 0x7a,
0xe6, 0x04, 0x21, 0x95, 0x6e, 0x05, 0x19, 0xd4, 0x98, 0x71, 0x32, 0x0c, 0xd5, 0x14, 0x98, 0xe4,
0x4b, 0xa8, 0x61, 0x56, 0xae, 0x82, 0x13, 0x73, 0xd5, 0x4a, 0x67, 0xe4, 0x73, 0xb1, 0x7f, 0xc3,
0x84, 0x20, 0x9a, 0x99, 0x2f, 0xa1, 0x86, 0xd3, 0x7c, 0x81, 0x63, 0x9d, 0x20, 0x76, 0xa9, 0xb9,
0x60, 0x99, 0x67, 0xd1, 0xcc, 0xb4, 0xa1, 0xc1, 0xc9, 0x9d, 0x18, 0x49, 0xe1, 0x37, 0xbc, 0x99,
0xce, 0x2e, 0xc7, 0x9a, 0x35, 0x7e, 0xa6, 0x7d, 0x6f, 0x57, 0xa1, 0x1c, 0xfa, 0xce, 0xd9, 0x19,
0xf5, 0x8d, 0x75, 0x35, 0x34, 0x8c, 0x8e, 0xd3, 0x41, 0x48, 0x67, 0x4c, 0x86, 0x31, 0xfe, 0x59,
0x0e, 0x6a, 0x82, 0x32, 0xff, 0xc4, 0x1e, 0x0b, 0x9b, 0x09, 0x65, 0x6d, 0x55, 0xd3, 0xcd, 0xbe,
0x07, 0x4b, 0x53, 0x26, 0x70, 0x39, 0xe1, 0x55, 0xdc, 0x5d, 0x61, 0x51, 0x82, 0x85, 0x2c, 0xb1,
0x05, 0x2b, 0x28, 0x5a, 0x04, 0x56, 0xe8, 0x4c, 0x2c, 0x99, 0x28, 0x6e, 0xc8, 0x2c, 0xf3, 0xa4,
0xa1, 0x33, 0x39, 0x14, 0x09, 0x8c, 0xc3, 0x0e, 0x42, 0xfb, 0x8c, 0x0a, 0xea, 0xc0, 0x3f, 0x98,
0x10, 0x97, 0xd0, 0x05, 0x48, 0x21, 0xee, 0x7f, 0x2f, 0xc3, 0x46, 0x2a, 0x49, 0x08, 0x71, 0xca,
0x3a, 0x3c, 0x71, 0xa6, 0x27, 0x9e, 0xb2, 0x4e, 0xe4, 0x34, 0xeb, 0xf0, 0x01, 0x4b, 0x91, 0xd6,
0x09, 0x0a, 0x6b, 0x72, 0xc9, 0xa2, 0x79, 0x41, 0xa9, 0x0b, 0xf2, 0x28, 0xcc, 0x7e, 0x14, 0x3f,
0x06, 0x93, 0xd5, 0x49, 0xb8, 0xce, 0x17, 0xae, 0xcc, 0x52, 0xb0, 0x80, 0xfc, 0xff, 0xd0, 0x52,
0x3b, 0x43, 0xc8, 0x36, 0x9a, 0xee, 0x83, 0xd5, 0xf4, 0x9d, 0x57, 0xd4, 0x14, 0xd3, 0xfb, 0x22,
0xeb, 0xb5, 0x2e, 0x37, 0x15, 0x2f, 0x50, 0xd5, 0x75, 0x01, 0x6f, 0xca, 0xba, 0x50, 0x56, 0x49,
0xd7, 0x58, 0x7c, 0xad, 0xbe, 0xa1, 0x4e, 0x3b, 0x56, 0xad, 0x79, 0x4b, 0x14, 0xac, 0x92, 0xf4,
0x7a, 0xcf, 0x61, 0xfd, 0x85, 0xed, 0x84, 0xb2, 0x8f, 0x9a, 0xea, 0xa5, 0x84, 0xf5, 0x3d, 0x7c,
0x45, 0x7d, 0x5f, 0xf1, 0xcc, 0x31, 0xe9, 0x6d, 0xf5, 0x45, 0x1a, 0x18, 0x6c, 0xfe, 0xed, 0x02,
0x2c, 0xc6, 0x4b, 0x61, 0xa4, 0x47, 0x1c, 0x57, 0x92, 0x91, 0x16, 0x12, 0x80, 0xb0, 0x9c, 0xf5,
0x38, 0x03, 0x9d, 0xb6, 0xe9, 0xe5, 0x33, 0x6c, 0x7a, 0xba, 0x29, 0xad, 0xf0, 0x2a, 0xcf, 0x8a,
0xe2, 0x6b, 0x79, 0x56, 0x94, 0xb2, 0x3c, 0x2b, 0x3e, 0xbe, 0xd6, 0x14, 0xcf, 0x15, 0xe2, 0x99,
0x66, 0xf8, 0x47, 0xd7, 0x9b, 0xe1, 0xb9, 0xae, 0xfc, 0x3a, 0x13, 0xbc, 0xe6, 0x40, 0x50, 0xb9,
0xc6, 0x00, 0xa6, 0xb9, 0x14, 0x64, 0x98, 0xe0, 0xab, 0x5f, 0xc3, 0x04, 0xbf, 0xf9, 0x27, 0x39,
0x20, 0xe9, 0xdd, 0x41, 0x1e, 0x73, 0x73, 0xa9, 0x4b, 0x27, 0x82, 0x72, 0x7f, 0xf0, 0x7a, 0x3b,
0x4c, 0x2e, 0x08, 0x99, 0x9b, 0x7c, 0x08, 0x2b, 0xfa, 0x3d, 0x3e, 0x5d, 0xb5, 0xd1, 0x30, 0x89,
0x9e, 0x14, 0x29, 0xe9, 0x34, 0x37, 0x96, 0xe2, 0x2b, 0xdd, 0x58, 0x4a, 0xaf, 0x74, 0x63, 0x59,
0x88, 0xbb, 0xb1, 0x6c, 0xfe, 0xcb, 0x1c, 0xac, 0x64, 0x2c, 0xe2, 0x6f, 0xae, 0xcf, 0x6c, 0xed,
0xc5, 0xc8, 0x5a, 0x5e, 0xac, 0x3d, 0x9d, 0xa2, 0x1d, 0x48, 0xc5, 0x2e, 0x9b, 0x8a, 0x40, 0x9c,
0x54, 0xf7, 0x5f, 0x45, 0x5d, 0xa2, 0x1c, 0xa6, 0x9e, 0x7d, 0xf3, 0xef, 0xe4, 0xa1, 0xa6, 0x25,
0xb2, 0x51, 0xe4, 0x4b, 0x56, 0x73, 0x0a, 0xe5, 0xbc, 0x25, 0x2a, 0x66, 0xf0, 0x6a, 0x01, 0x2e,
0x4e, 0x4c, 0xe7, 0x9b, 0x4b, 0x30, 0x92, 0x88, 0xb0, 0x05, 0x2b, 0xd2, 0x94, 0x4d, 0x23, 0xa7,
0x79, 0x71, 0xd6, 0x08, 0xaf, 0x04, 0xd1, 0x48, 0xc4, 0xff, 0x50, 0xca, 0xb9, 0xd1, 0xdc, 0x69,
0xa6, 0xc1, 0x65, 0xe1, 0x0f, 0x21, 0x26, 0x91, 0xad, 0xf3, 0x8f, 0x60, 0x4d, 0x39, 0x44, 0xc4,
0x72, 0x70, 0x03, 0x14, 0x91, 0x8e, 0x0f, 0x5a, 0x96, 0xef, 0xc3, 0xed, 0x44, 0x9b, 0x12, 0x59,
0xb9, 0xa6, 0xe5, 0x66, 0xac, 0x75, 0x7a, 0x09, 0x9b, 0x7f, 0x0e, 0x1a, 0x31, 0x42, 0xf9, 0xcd,
0x4d, 0x79, 0x52, 0x19, 0xc6, 0x47, 0x54, 0x57, 0x86, 0x6d, 0xfe, 0xf7, 0x02, 0x90, 0x34, 0xad,
0xfe, 0x69, 0x36, 0x21, 0xbd, 0x30, 0x0b, 0x19, 0x0b, 0xf3, 0xff, 0x19, 0xff, 0x10, 0xe9, 0x64,
0x35, 0x7f, 0x04, 0xbe, 0x39, 0x9b, 0x2a, 0x41, 0xb6, 0xe2, 0xb3, 0xa4, 0xd7, 0x56, 0x25, 0x76,
0xe1, 0x54, 0x63, 0xa0, 0x12, 0xce, 0x5b, 0xc7, 0xb0, 0x60, 0xbb, 0xa3, 0x73, 0xcf, 0x17, 0x74,
0xf0, 0x67, 0xbe, 0xf6, 0xf1, 0xb9, 0xd5, 0xc6, 0xfc, 0xc8, 0xb5, 0x99, 0xa2, 0x30, 0xe3, 0x23,
0xa8, 0x69, 0x60, 0x52, 0x85, 0xd2, 0x41, 0xf7, 0x70, 0xbb, 0xdf, 0xbc, 0x41, 0x1a, 0x50, 0x35,
0x3b, 0x3b, 0xfd, 0xa7, 0x1d, 0xb3, 0xb3, 0xdb, 0xcc, 0x91, 0x0a, 0x14, 0x0f, 0xfa, 0x83, 0x61,
0x33, 0x6f, 0x6c, 0x42, 0x4b, 0x94, 0x98, 0xb6, 0x4e, 0xfd, 0x56, 0x51, 0xe9, 0x54, 0x31, 0x51,
0x08, 0xf9, 0x1f, 0x43, 0x5d, 0x67, 0x6f, 0xc4, 0x8a, 0x48, 0xb8, 0xc4, 0x30, 0xf1, 0xde, 0xd3,
0x68, 0xf5, 0x0e, 0x70, 0x87, 0x88, 0xb1, 0xca, 0x96, 0x8f, 0xf1, 0xad, 0x19, 0x96, 0x65, 0x94,
0x8f, 0x62, 0xcb, 0xf0, 0xff, 0x83, 0xc5, 0xb8, 0x25, 0x46, 0x50, 0xa4, 0x2c, 0x91, 0x95, 0xe5,
0x8e, 0x99, 0x66, 0xc8, 0xf7, 0xa1, 0x99, 0xb4, 0xe4, 0x08, 0xe6, 0xf9, 0x9a, 0xfc, 0x4b, 0x4e,
0xdc, 0xb8, 0x43, 0xf6, 0x61, 0x35, 0x8b, 0xc1, 0xc3, 0xf5, 0x71, 0xbd, 0x9a, 0x83, 0xa4, 0x99,
0x38, 0xf2, 0xb9, 0xb0, 0xe8, 0x95, 0x70, 0xfa, 0xdf, 0x89, 0xd7, 0xaf, 0x0d, 0xf6, 0x16, 0xff,
0xa7, 0xd9, 0xf6, 0x2e, 0x00, 0x22, 0x18, 0x69, 0x42, 0xbd, 0x7f, 0xd4, 0xe9, 0x59, 0x3b, 0xfb,
0xed, 0x5e, 0xaf, 0x73, 0xd0, 0xbc, 0x41, 0x08, 0x2c, 0xa2, 0x57, 0xc7, 0xae, 0x82, 0xe5, 0x18,
0x4c, 0x98, 0x5a, 0x25, 0x2c, 0x4f, 0x56, 0xa1, 0xd9, 0xed, 0x25, 0xa0, 0x05, 0xd2, 0x82, 0xd5,
0xa3, 0x0e, 0x77, 0x04, 0x89, 0x95, 0x5b, 0x64, 0x42, 0x83, 0xe8, 0xae, 0x11, 0xc2, 0xea, 0x57,
0xf6, 0x64, 0x42, 0xc3, 0x36, 0x77, 0x64, 0x97, 0xdb, 0xe1, 0x7d, 0x58, 0x56, 0xea, 0xb0, 0x04,
0xb7, 0xdc, 0x54, 0x09, 0x12, 0xf9, 0x43, 0x58, 0xd1, 0xb4, 0x6a, 0x89, 0x53, 0x88, 0x68, 0x49,
0x22, 0x03, 0x13, 0x55, 0x78, 0xad, 0x02, 0x20, 0x39, 0xf8, 0x3f, 0xcc, 0xc3, 0x5a, 0x22, 0x21,
0x32, 0xc2, 0x70, 0xfe, 0x3d, 0xde, 0x96, 0x3a, 0x02, 0x5f, 0xda, 0xe8, 0xfc, 0xd7, 0x6b, 0x74,
0xe1, 0xba, 0x46, 0x93, 0x67, 0xb0, 0x24, 0xbc, 0xfd, 0x35, 0x1e, 0x8f, 0xd1, 0x88, 0x07, 0x62,
0xca, 0x33, 0x5b, 0xbe, 0x15, 0x1f, 0x58, 0x6e, 0xe5, 0x5a, 0xb4, 0x63, 0xc0, 0xcd, 0x5f, 0x82,
0x95, 0x0c, 0xb4, 0x8c, 0x3b, 0x2f, 0x1f, 0xc5, 0x2d, 0x5e, 0xb7, 0x62, 0x35, 0xc7, 0x8b, 0xd0,
0xad, 0xf7, 0x5b, 0xb0, 0x20, 0xb4, 0xbd, 0x4d, 0x28, 0xc8, 0x6b, 0x4f, 0x45, 0x93, 0xfd, 0x24,
0x04, 0x8a, 0xd3, 0xc8, 0x01, 0x1b, 0x7f, 0x1b, 0x1b, 0xea, 0x02, 0x63, 0x62, 0x82, 0x7e, 0xa5,
0x08, 0xeb, 0xc9, 0x14, 0x75, 0x25, 0xa1, 0x1c, 0x9b, 0x1b, 0x6e, 0x49, 0x14, 0x20, 0xf2, 0x49,
0x62, 0xbb, 0xc5, 0x66, 0x07, 0x51, 0xf5, 0xad, 0x25, 0x87, 0xfc, 0x61, 0x92, 0xa9, 0xe6, 0x34,
0xa2, 0x21, 0x2f, 0x68, 0x60, 0x9f, 0x12, 0x3c, 0xf6, 0x27, 0x29, 0x1e, 0xbb, 0x98, 0x95, 0x29,
0xc1, 0x72, 0x77, 0x60, 0x23, 0x72, 0x35, 0x8e, 0xd7, 0x59, 0xca, 0xca, 0xbe, 0xa6, 0xb0, 0x0f,
0xf4, 0xca, 0x1f, 0x43, 0x2b, 0x2a, 0x26, 0xd1, 0x8c, 0x85, 0xac, 0x72, 0xd6, 0x15, 0xba, 0x19,
0x6b, 0xcf, 0x0f, 0x60, 0x33, 0x36, 0x5e, 0xf1, 0x26, 0x95, 0xb3, 0x8a, 0xda, 0xd0, 0x06, 0x30,
0xd6, 0xa8, 0x03, 0xb8, 0x15, 0x2b, 0x2b, 0xd1, 0xae, 0x4a, 0x56, 0x61, 0x2d, 0xad, 0xb0, 0x58,
0xcb, 0x8c, 0xdf, 0x59, 0x00, 0xf2, 0xc3, 0x39, 0xf5, 0xaf, 0xf0, 0x5a, 0x73, 0xf0, 0xaa, 0x3b,
0x14, 0x52, 0x53, 0x99, 0x7f, 0xad, 0xe8, 0x06, 0x59, 0xd1, 0x05, 0x8a, 0xaf, 0x8e, 0x2e, 0x50,
0x7a, 0x55, 0x74, 0x81, 0xb7, 0xa1, 0xe1, 0x9c, 0xb9, 0x1e, 0x63, 0x04, 0x98, 0x1c, 0x18, 0xb4,
0x16, 0xee, 0x16, 0xee, 0xd5, 0xcd, 0xba, 0x00, 0x32, 0x29, 0x30, 0x20, 0x5f, 0x46, 0x48, 0x74,
0x7c, 0x86, 0xb1, 0x37, 0x74, 0x16, 0xa0, 0x33, 0x3e, 0xa3, 0x42, 0x31, 0x8b, 0x0b, 0x56, 0x66,
0x66, 0xf0, 0x80, 0xbc, 0x03, 0x8b, 0x81, 0x37, 0x67, 0x62, 0xb5, 0x1c, 0x06, 0x6e, 0xef, 0xaf,
0x73, 0xe8, 0x91, 0xf4, 0xfe, 0x58, 0x99, 0x07, 0xd4, 0x9a, 0x3a, 0x41, 0xc0, 0x84, 0x93, 0x91,
0xe7, 0x86, 0xbe, 0x37, 0x11, 0x26, 0xfc, 0xe5, 0x79, 0x40, 0x0f, 0x79, 0xca, 0x0e, 0x4f, 0x20,
0x9f, 0x44, 0x4d, 0x9a, 0xd9, 0x8e, 0x1f, 0xb4, 0x00, 0x9b, 0x24, 0x7b, 0x8a, 0xd2, 0xab, 0xed,
0xf8, 0xaa, 0x2d, 0xec, 0x23, 0x48, 0x44, 0x3d, 0xa8, 0x25, 0xa3, 0x1e, 0xfc, 0x72, 0x76, 0xd4,
0x83, 0x46, 0x8c, 0x98, 0xa5, 0xa7, 0xf8, 0x6b, 0x05, 0x3f, 0x48, 0x07, 0x73, 0x58, 0xfc, 0x3a,
0xc1, 0x1c, 0x96, 0xb2, 0x82, 0x39, 0x7c, 0x04, 0x35, 0xbc, 0x43, 0x6f, 0x9d, 0xa3, 0x33, 0x33,
0x77, 0x49, 0x68, 0xea, 0x97, 0xec, 0xf7, 0x1d, 0x37, 0x34, 0xc1, 0x97, 0x3f, 0x83, 0x74, 0x5c,
0x85, 0xe5, 0xd7, 0x8a, 0xab, 0xf0, 0xcd, 0x04, 0x4d, 0x10, 0x77, 0xfd, 0xb7, 0xa0, 0x22, 0xe7,
0x89, 0x11, 0xdb, 0x53, 0xdf, 0x9b, 0x4a, 0xf3, 0x26, 0xfb, 0x4d, 0x16, 0x21, 0x1f, 0x7a, 0x22,
0x73, 0x3e, 0xf4, 0x8c, 0x5f, 0x84, 0x9a, 0xb6, 0xd4, 0xc8, 0x5b, 0x5c, 0xaf, 0xef, 0xd2, 0x89,
0x54, 0xfb, 0xf2, 0x51, 0xac, 0x0a, 0x68, 0x77, 0xcc, 0xce, 0xbd, 0xb1, 0xe3, 0x53, 0x8c, 0x80,
0x62, 0xf9, 0xf4, 0x82, 0xfa, 0x81, 0x34, 0x4b, 0x37, 0x55, 0x82, 0xc9, 0xe1, 0xc6, 0x2f, 0xc1,
0x4a, 0x6c, 0x6e, 0x05, 0xf9, 0x7e, 0x07, 0x16, 0x70, 0xdc, 0xa4, 0xef, 0x53, 0x3c, 0x78, 0x81,
0x48, 0xc3, 0x38, 0x30, 0xdc, 0xa2, 0x6e, 0xcd, 0x7c, 0xef, 0x04, 0x2b, 0xc9, 0x99, 0x35, 0x01,
0x3b, 0xf2, 0xbd, 0x13, 0xe3, 0xdf, 0x17, 0xa0, 0xb0, 0xef, 0xcd, 0x74, 0x07, 0xe8, 0x5c, 0xca,
0x01, 0x5a, 0xa8, 0x5b, 0x2c, 0xa5, 0x4e, 0x11, 0x12, 0x2b, 0xda, 0x88, 0xa5, 0x4a, 0xe5, 0x1e,
0x2c, 0x32, 0x3a, 0x11, 0x7a, 0x96, 0xb8, 0x78, 0xc4, 0x0f, 0x67, 0xbe, 0xf9, 0xec, 0x69, 0x38,
0xf4, 0xf6, 0x38, 0x9c, 0xac, 0x42, 0x41, 0x09, 0xef, 0x98, 0xcc, 0x3e, 0xc9, 0x3a, 0x2c, 0xe0,
0x85, 0x29, 0x79, 0xd3, 0x5d, 0x7c, 0x91, 0x0f, 0x60, 0x25, 0x5e, 0x2e, 0x27, 0x45, 0x42, 0x32,
0xd0, 0x0b, 0x46, 0x9a, 0x74, 0x13, 0x18, 0x1d, 0x89, 0xee, 0xba, 0x17, 0xcc, 0xf2, 0x29, 0xa5,
0x98, 0xa4, 0x11, 0xbd, 0x4a, 0x8c, 0xe8, 0xdd, 0x81, 0x5a, 0x38, 0xb9, 0xb0, 0x66, 0xf6, 0xd5,
0xc4, 0xb3, 0xe5, 0xcd, 0x4a, 0x08, 0x27, 0x17, 0x47, 0x1c, 0x42, 0x3e, 0x04, 0x98, 0xce, 0x66,
0x62, 0xef, 0xa1, 0x3d, 0x33, 0x5a, 0xca, 0x87, 0x47, 0x47, 0x7c, 0xc9, 0x99, 0xd5, 0xe9, 0x6c,
0xc6, 0x7f, 0x92, 0x5d, 0x58, 0xcc, 0x8c, 0x52, 0x72, 0x5b, 0x5e, 0x2b, 0xf1, 0x66, 0x5b, 0x19,
0x9b, 0xb3, 0x31, 0xd2, 0x61, 0x9b, 0xdf, 0x07, 0xf2, 0x67, 0x0c, 0x04, 0x32, 0x84, 0xaa, 0x6a,
0x5f, 0x2a, 0xfc, 0x48, 0x2d, 0x15, 0x7e, 0x84, 0xd1, 0x45, 0xce, 0xb8, 0x29, 0x92, 0x0f, 0x1a,
0xe7, 0x26, 0x2e, 0x64, 0x19, 0xff, 0x29, 0x07, 0x25, 0x1e, 0xd4, 0xe3, 0x5d, 0x58, 0xe2, 0xf8,
0xca, 0x99, 0x5c, 0x78, 0xfc, 0x70, 0xfe, 0x6f, 0x28, 0xfc, 0xc8, 0xd9, 0xb6, 0xd0, 0xa2, 0x24,
0x45, 0x6c, 0x84, 0x16, 0x29, 0xe9, 0x0e, 0x54, 0x55, 0xd5, 0xda, 0xd2, 0xa9, 0xc8, 0x9a, 0xc9,
0x9b, 0x50, 0x3c, 0xf7, 0x66, 0x52, 0xef, 0x09, 0xd1, 0x48, 0x9a, 0x08, 0x8f, 0xda, 0xc2, 0xea,
0x88, 0x2e, 0x8a, 0x15, 0x44, 0x5b, 0x58, 0x25, 0x32, 0xd4, 0x41, 0xa2, 0x8f, 0x0b, 0x19, 0x7d,
0x3c, 0x86, 0x25, 0x46, 0x07, 0x34, 0xb7, 0xa3, 0xeb, 0x0f, 0xcd, 0x6f, 0x33, 0xf9, 0x66, 0x34,
0x99, 0x8f, 0xa9, 0xae, 0x79, 0x46, 0xcf, 0x60, 0x01, 0x97, 0x72, 0xa5, 0xf1, 0x3b, 0x39, 0x4e,
0x5f, 0x58, 0xb9, 0xe4, 0x1e, 0x14, 0x5d, 0xe9, 0xa2, 0x14, 0x49, 0x31, 0xea, 0x52, 0x25, 0xc3,
0x33, 0x11, 0x83, 0x4d, 0x1d, 0x3a, 0xf6, 0xe8, 0xa5, 0x37, 0xcc, 0x9a, 0x3b, 0x9f, 0x2a, 0xc5,
0xed, 0xb7, 0x64, 0xb7, 0x12, 0x4a, 0x4f, 0xde, 0x7b, 0xb5, 0x4d, 0xb7, 0x34, 0x17, 0xe3, 0x62,
0xec, 0xc4, 0x94, 0x32, 0xd0, 0xf8, 0x8c, 0x6a, 0xae, 0xc5, 0xbf, 0x9f, 0x87, 0x46, 0xac, 0x45,
0xe8, 0x63, 0xcd, 0x0e, 0x00, 0x6e, 0x98, 0x15, 0xf3, 0x8d, 0xae, 0xac, 0x42, 0x4c, 0xd5, 0xc6,
0x29, 0x1f, 0x1b, 0x27, 0xe5, 0x63, 0x58, 0xd0, 0x7d, 0x0c, 0x1f, 0x40, 0x35, 0x8a, 0x8e, 0x15,
0x6f, 0x12, 0xab, 0x4f, 0x5e, 0x2d, 0x8d, 0x90, 0x22, 0xaf, 0xc4, 0x92, 0xee, 0x95, 0xf8, 0x3d,
0xcd, 0x89, 0x6d, 0x01, 0x8b, 0x31, 0xb2, 0x46, 0xf4, 0xa7, 0xe2, 0xc2, 0x66, 0x7c, 0x09, 0x35,
0xad, 0xf1, 0xba, 0x23, 0x58, 0x2e, 0xe6, 0x08, 0xa6, 0x2e, 0xb0, 0xe7, 0xa3, 0x0b, 0xec, 0xc6,
0xaf, 0xe5, 0xa1, 0xc1, 0xf6, 0x97, 0xe3, 0x9e, 0x1d, 0x79, 0x13, 0x67, 0x84, 0x86, 0x5a, 0xb5,
0xc3, 0x04, 0xa3, 0x25, 0xf7, 0x99, 0xd8, 0x62, 0x9c, 0xcf, 0xd2, 0xa3, 0xae, 0x70, 0x22, 0xad,
0xa2, 0xae, 0x18, 0xd0, 0x60, 0x84, 0x11, 0x4d, 0xae, 0x51, 0x24, 0x2d, 0xb3, 0x76, 0x4a, 0xe9,
0xb6, 0x1d, 0x70, 0x0a, 0xf9, 0x01, 0xac, 0x30, 0x1c, 0x0c, 0xa9, 0x30, 0x75, 0x26, 0x13, 0x27,
0xba, 0x99, 0x59, 0x30, 0x9b, 0xa7, 0x94, 0x9a, 0x76, 0x48, 0x0f, 0x59, 0x82, 0x08, 0xbc, 0x55,
0x19, 0x3b, 0x81, 0x7d, 0x12, 0x79, 0xc2, 0xab, 0x6f, 0xe9, 0xc9, 0x10, 0x39, 0x8b, 0x08, 0x47,
0x27, 0x11, 0x4f, 0x04, 0xf3, 0x27, 0x56, 0x52, 0x39, 0xb9, 0x92, 0x8c, 0x7f, 0x98, 0x87, 0x9a,
0xb6, 0x2c, 0x5f, 0xe7, 0x74, 0xbd, 0x9d, 0x32, 0xac, 0x57, 0x75, 0x1b, 0xfa, 0xdb, 0xf1, 0x2a,
0x0b, 0xea, 0xfa, 0x9e, 0xbe, 0x80, 0x6f, 0x41, 0x95, 0xed, 0xba, 0x8f, 0xd0, 0x00, 0x21, 0x42,
0xe2, 0x21, 0xe0, 0x68, 0x7e, 0x22, 0x13, 0x1f, 0x62, 0x62, 0x29, 0x4a, 0x7c, 0xc8, 0x12, 0x5f,
0x76, 0x7d, 0xe7, 0x33, 0xa8, 0x8b, 0x52, 0x71, 0x4e, 0x85, 0x58, 0xb0, 0xaa, 0x9d, 0xdc, 0x6a,
0xbe, 0xcd, 0x1a, 0xaf, 0x8e, 0x4f, 0xbe, 0xc8, 0xf8, 0x50, 0x66, 0xac, 0xbc, 0x2a, 0xe3, 0x43,
0xfe, 0x61, 0xec, 0xa9, 0x1b, 0x51, 0xe8, 0x3e, 0x2a, 0xe9, 0xd8, 0x87, 0xb0, 0x22, 0xc9, 0xd5,
0xdc, 0xb5, 0x5d, 0xd7, 0x9b, 0xbb, 0x23, 0x2a, 0x6f, 0x87, 0x13, 0x91, 0x74, 0x1c, 0xa5, 0x18,
0x63, 0x15, 0xab, 0x85, 0xbb, 0xa1, 0xde, 0x87, 0x12, 0xe7, 0xcb, 0x39, 0xf3, 0x91, 0x4d, 0xb8,
0x38, 0x0a, 0xb9, 0x07, 0x25, 0xce, 0x9e, 0xe7, 0xaf, 0x25, 0x36, 0x1c, 0xc1, 0x68, 0x03, 0x61,
0x19, 0x0f, 0x69, 0xe8, 0x3b, 0xa3, 0x20, 0xba, 0x78, 0x5e, 0x0a, 0xaf, 0x66, 0xa2, 0xae, 0xc8,
0x6e, 0x11, 0x61, 0xa2, 0x86, 0x86, 0xe3, 0xb0, 0x83, 0x69, 0x25, 0x56, 0x86, 0x60, 0x97, 0x26,
0xb0, 0x7e, 0x42, 0xc3, 0x17, 0x94, 0xba, 0x2e, 0x63, 0x86, 0x46, 0xd4, 0x0d, 0x7d, 0x7b, 0xc2,
0x26, 0x89, 0xf7, 0xe0, 0x51, 0xaa, 0xd4, 0x48, 0x03, 0xb8, 0x1d, 0x65, 0xdc, 0x51, 0xf9, 0x38,
0xed, 0x58, 0x3b, 0xc9, 0x4a, 0xdb, 0xfc, 0x05, 0xd8, 0xbc, 0x3e, 0x53, 0x86, 0x9a, 0xe0, 0x5e,
0x9c, 0xaa, 0x28, 0x2b, 0xf8, 0xc4, 0xb3, 0x43, 0xde, 0x1a, 0x9d, 0xb2, 0xf4, 0xa0, 0xa6, 0xa5,
0x44, 0x67, 0x7f, 0x0e, 0x99, 0x3b, 0xfe, 0xc1, 0x4e, 0x24, 0xd7, 0xf3, 0xa7, 0x68, 0x75, 0x1e,
0x5b, 0x51, 0xe9, 0x39, 0x73, 0x29, 0x82, 0xa3, 0xa3, 0x92, 0xb1, 0x05, 0x4b, 0xc8, 0xd9, 0x6b,
0x07, 0xdd, 0xcb, 0x98, 0x41, 0x63, 0x15, 0x48, 0x8f, 0xd3, 0x2e, 0xdd, 0x25, 0xf7, 0x0f, 0x0b,
0x50, 0xd3, 0xc0, 0xec, 0x34, 0x42, 0x3f, 0x66, 0x6b, 0xec, 0xd8, 0x53, 0x2a, 0x4d, 0xfc, 0x0d,
0xb3, 0x81, 0xd0, 0x5d, 0x01, 0x64, 0x67, 0xb1, 0x7d, 0x71, 0x66, 0x79, 0xf3, 0xd0, 0x1a, 0xd3,
0x33, 0x9f, 0xca, 0x56, 0xd6, 0xed, 0x8b, 0xb3, 0xfe, 0x3c, 0xdc, 0x45, 0x98, 0x0c, 0x4e, 0xa4,
0x61, 0x15, 0x54, 0x70, 0xa2, 0x08, 0x4b, 0xf8, 0x7f, 0xf3, 0x95, 0x59, 0x54, 0xfe, 0xdf, 0x5c,
0x5a, 0x4c, 0x1e, 0xa0, 0xa5, 0xf4, 0x01, 0xfa, 0x09, 0xac, 0xf3, 0x03, 0x54, 0x90, 0x66, 0x2b,
0xb1, 0x93, 0x57, 0x31, 0x55, 0x74, 0x52, 0x63, 0x7b, 0x9b, 0xac, 0x07, 0x92, 0x2c, 0x05, 0xce,
0x8f, 0x39, 0x21, 0xcb, 0x99, 0xac, 0x67, 0xa2, 0xf0, 0x81, 0xf3, 0x63, 0x2a, 0x83, 0x23, 0xc5,
0x30, 0xc5, 0xe5, 0xbc, 0xa9, 0xe3, 0x26, 0x31, 0xed, 0xcb, 0x38, 0x66, 0x55, 0x60, 0xda, 0x97,
0x3a, 0xe6, 0x23, 0xd8, 0x98, 0xd2, 0xb1, 0x63, 0xc7, 0x8b, 0xb5, 0x22, 0xc6, 0x6d, 0x95, 0x27,
0x6b, 0x79, 0x06, 0x5c, 0x70, 0x67, 0xa3, 0xf1, 0x63, 0x6f, 0x7a, 0xe2, 0x70, 0x9e, 0x85, 0xbb,
0xe0, 0x15, 0xcd, 0x45, 0x77, 0x3e, 0xfd, 0x79, 0x04, 0xb3, 0x2c, 0x81, 0xd1, 0x80, 0xda, 0x20,
0xf4, 0x66, 0x72, 0x9a, 0x17, 0xa1, 0xce, 0x3f, 0x45, 0x60, 0x85, 0x5b, 0x70, 0x13, 0x49, 0xc2,
0xd0, 0x9b, 0x79, 0x13, 0xef, 0xec, 0x2a, 0xa6, 0xc5, 0xfe, 0xe7, 0x39, 0x58, 0x89, 0xa5, 0x0a,
0xf2, 0xfa, 0x09, 0xa7, 0x67, 0xea, 0x52, 0x76, 0x2e, 0x76, 0x23, 0x8f, 0xcd, 0x17, 0x47, 0xe4,
0xc4, 0x4c, 0x5e, 0xd4, 0x6e, 0x47, 0x91, 0xc7, 0x64, 0x46, 0x4e, 0x52, 0x5a, 0x69, 0x92, 0x22,
0xf2, 0xcb, 0x98, 0x64, 0xb2, 0x88, 0x9f, 0x11, 0x17, 0x28, 0xc7, 0xa2, 0xcb, 0x85, 0xf8, 0x15,
0x2b, 0x5d, 0xe3, 0x2d, 0x5b, 0x10, 0xa9, 0xc1, 0x03, 0xe3, 0x77, 0xf3, 0x00, 0x51, 0xeb, 0xf0,
0x92, 0x97, 0xe2, 0x5b, 0x72, 0xe8, 0x4d, 0xaf, 0xf1, 0x28, 0x6f, 0x41, 0x5d, 0x5d, 0xbc, 0x88,
0x38, 0xa1, 0x9a, 0x84, 0x31, 0x76, 0xe8, 0x7d, 0x58, 0x3a, 0x9b, 0x78, 0x27, 0xc8, 0xb1, 0x0a,
0xbe, 0x05, 0x7d, 0x68, 0xf0, 0x3c, 0x5a, 0xe4, 0x49, 0x2a, 0x76, 0xa0, 0xe2, 0x9d, 0x8a, 0x99,
0xf7, 0x33, 0x62, 0x9c, 0xd0, 0x97, 0x29, 0x4e, 0xe8, 0x4e, 0x6a, 0x70, 0x7f, 0x3a, 0x6c, 0xd0,
0x5f, 0xce, 0x2b, 0x5f, 0xf3, 0x68, 0x5e, 0x5e, 0x2e, 0x6c, 0xfe, 0x24, 0x9e, 0x71, 0x2f, 0x33,
0xf5, 0x7f, 0x09, 0x8b, 0x3e, 0x3f, 0x22, 0xe5, 0xf9, 0x59, 0x7c, 0xc9, 0xf9, 0xd9, 0xf0, 0x63,
0x7c, 0xd7, 0xb7, 0xa1, 0x69, 0x8f, 0x2f, 0xa8, 0x1f, 0x3a, 0x68, 0x39, 0x43, 0x6e, 0x5d, 0x78,
0x76, 0x6b, 0x70, 0x64, 0x8b, 0xdf, 0x83, 0x25, 0x11, 0x7a, 0x44, 0x61, 0x8a, 0x98, 0x9c, 0x11,
0x98, 0x21, 0x1a, 0x7f, 0x5f, 0x3a, 0xb7, 0xc7, 0xd7, 0xda, 0xcb, 0x47, 0x45, 0xef, 0x61, 0x3e,
0xed, 0xcc, 0x20, 0x96, 0xb5, 0x30, 0xc8, 0x09, 0xea, 0xc8, 0x81, 0xc2, 0x1c, 0x17, 0x1f, 0xd6,
0xe2, 0xeb, 0x0c, 0xab, 0xf1, 0x2f, 0x72, 0x50, 0xde, 0xf7, 0x66, 0xfb, 0x0e, 0xbf, 0x22, 0x85,
0x9b, 0x56, 0xd9, 0x8b, 0x17, 0xd8, 0x27, 0xba, 0xf1, 0xbd, 0xe4, 0xea, 0x74, 0x26, 0xd3, 0xd9,
0x88, 0x33, 0x9d, 0xdf, 0x83, 0x5b, 0x68, 0x8e, 0xf7, 0xbd, 0x99, 0xe7, 0x33, 0xc2, 0x61, 0x4f,
0x38, 0xf3, 0xe9, 0xb9, 0xe1, 0xb9, 0xa4, 0xe4, 0x37, 0x4f, 0x29, 0x3d, 0xd2, 0x30, 0x0e, 0x15,
0x02, 0x86, 0x4d, 0x98, 0x84, 0x17, 0x16, 0xd7, 0x17, 0x08, 0xee, 0x98, 0xd3, 0xf7, 0x25, 0x96,
0xd0, 0x41, 0x38, 0xf2, 0xc7, 0xc6, 0xe7, 0x50, 0x55, 0xaa, 0x27, 0xf2, 0x3e, 0x54, 0xcf, 0xbd,
0x99, 0xd0, 0x4f, 0xe5, 0x62, 0xd7, 0xcb, 0x45, 0xaf, 0xcd, 0xca, 0x39, 0xff, 0x11, 0x18, 0xff,
0xa7, 0x0c, 0xe5, 0xae, 0x7b, 0xe1, 0x39, 0x23, 0x74, 0x7b, 0x9f, 0xd2, 0xa9, 0x27, 0xa3, 0x29,
0xb1, 0xdf, 0xe8, 0x69, 0x19, 0x85, 0xcd, 0x2c, 0x08, 0x4f, 0x4b, 0x15, 0x30, 0x73, 0x0d, 0x16,
0x7c, 0x3d, 0xee, 0x65, 0xc9, 0xc7, 0x4b, 0x45, 0xea, 0xf4, 0x2e, 0x69, 0x51, 0xb1, 0x58, 0x59,
0xdc, 0xd3, 0x18, 0x87, 0x8c, 0x87, 0x3e, 0xa8, 0x22, 0x04, 0x07, 0xec, 0x0d, 0x28, 0x0b, 0x2d,
0x34, 0xbf, 0x5b, 0xca, 0x75, 0xf7, 0x02, 0x84, 0xab, 0xc1, 0xa7, 0xdc, 0x9d, 0x42, 0xb1, 0xd5,
0x05, 0xb3, 0x2e, 0x81, 0xbb, 0x36, 0xf7, 0x65, 0xe7, 0xf8, 0x1c, 0x85, 0x1f, 0x43, 0xc0, 0x41,
0x88, 0x90, 0x11, 0x61, 0xb6, 0x9a, 0x19, 0x61, 0x16, 0xef, 0x3e, 0x28, 0x9a, 0xcf, 0xbb, 0x08,
0x3c, 0x68, 0xa8, 0x06, 0x97, 0x01, 0x9d, 0x85, 0x86, 0x87, 0x47, 0x05, 0x91, 0x1a, 0x9e, 0xb7,
0xa1, 0x71, 0x6a, 0x4f, 0x26, 0x27, 0xf6, 0xe8, 0x39, 0x57, 0x4c, 0xd4, 0xb9, 0x2e, 0x56, 0x02,
0x51, 0x33, 0x71, 0x07, 0x6a, 0xda, 0x2c, 0xa3, 0x8b, 0x77, 0xd1, 0x84, 0x68, 0x7e, 0x93, 0xfa,
0xc6, 0xc5, 0xd7, 0xd0, 0x37, 0x6a, 0xae, 0xee, 0x4b, 0x71, 0x57, 0xf7, 0x5b, 0x48, 0xdb, 0x85,
0x03, 0x71, 0x93, 0x47, 0xa8, 0xb4, 0xc7, 0x63, 0x1e, 0xa7, 0xe7, 0x2d, 0xa8, 0x8b, 0xc1, 0xe3,
0xe9, 0xcb, 0xe2, 0xae, 0x00, 0xc2, 0x38, 0xca, 0x6d, 0xae, 0x34, 0x9f, 0xd9, 0xce, 0x18, 0x6f,
0x72, 0x09, 0xfb, 0x8a, 0x3d, 0x0d, 0x8f, 0x6c, 0x07, 0x5d, 0x27, 0x65, 0x32, 0x9e, 0xd5, 0x2b,
0x7c, 0xfc, 0x45, 0xf2, 0x80, 0xc7, 0xbc, 0x51, 0x18, 0x53, 0x15, 0xd6, 0xc3, 0xac, 0x09, 0x14,
0x5c, 0x07, 0x1f, 0xa1, 0xc7, 0x5d, 0x48, 0x31, 0x70, 0xc7, 0xa2, 0x32, 0x2f, 0x89, 0x55, 0x2a,
0xff, 0x73, 0x43, 0x35, 0xc7, 0x64, 0xac, 0x26, 0xb7, 0x97, 0xaf, 0xc7, 0xb8, 0x71, 0x81, 0x8a,
0xf6, 0x72, 0x8e, 0x40, 0x3e, 0xd7, 0xce, 0x90, 0x16, 0x22, 0xbf, 0x91, 0x28, 0xff, 0xba, 0xbb,
0xb3, 0xb7, 0x01, 0x9c, 0x80, 0x9d, 0x79, 0x01, 0x75, 0xc7, 0x18, 0x7f, 0xa3, 0x62, 0x56, 0x9d,
0xe0, 0x09, 0x07, 0xa4, 0xb4, 0x50, 0x9b, 0xe9, 0x20, 0xb8, 0xdf, 0xe8, 0x11, 0xd4, 0x86, 0xba,
0x3e, 0x12, 0xa4, 0x02, 0xc5, 0xfe, 0x51, 0xa7, 0xd7, 0xbc, 0x41, 0x6a, 0x50, 0x1e, 0x74, 0x86,
0xc3, 0x03, 0x34, 0xcc, 0xd7, 0xa1, 0xa2, 0x2e, 0xe0, 0xe7, 0xd9, 0x57, 0x7b, 0x67, 0xa7, 0x73,
0x34, 0xec, 0xec, 0x36, 0x0b, 0x3f, 0x28, 0x56, 0xf2, 0xcd, 0x82, 0xf1, 0xbf, 0x0a, 0x50, 0xd3,
0x06, 0xea, 0xe5, 0xf4, 0x3a, 0x1e, 0xea, 0x29, 0x9f, 0x0c, 0xf5, 0xa4, 0x1b, 0x55, 0x44, 0x38,
0x2c, 0x69, 0x54, 0x79, 0x1b, 0x1a, 0x22, 0x7e, 0xa6, 0xe6, 0x5e, 0x51, 0x32, 0xeb, 0x1c, 0x28,
0xa8, 0x39, 0x86, 0xf3, 0x40, 0x24, 0xbc, 0x28, 0x5d, 0x12, 0xeb, 0x07, 0x41, 0x78, 0x55, 0x1a,
0xef, 0xb9, 0x07, 0xde, 0xe4, 0x82, 0x72, 0x0c, 0xce, 0xc2, 0xd6, 0x04, 0x6c, 0x28, 0x42, 0xa5,
0x08, 0x92, 0xa9, 0xc5, 0x93, 0x28, 0x99, 0x75, 0x0e, 0x14, 0x15, 0x7d, 0x20, 0xd7, 0x18, 0x77,
0x36, 0xdb, 0x48, 0x2f, 0x98, 0xd8, 0xfa, 0x3a, 0x48, 0xe9, 0x3d, 0xab, 0xb8, 0x76, 0xbe, 0x95,
0xce, 0xf7, 0x6a, 0xfd, 0x27, 0x79, 0x1f, 0xc8, 0x74, 0x36, 0xb3, 0x32, 0x34, 0x92, 0x45, 0x73,
0x69, 0x3a, 0x9b, 0x0d, 0x35, 0x85, 0x1d, 0x79, 0x03, 0x0a, 0xf6, 0x74, 0x86, 0xa4, 0x25, 0xd2,
0x0e, 0xb6, 0x0f, 0x8f, 0x4c, 0x06, 0xfe, 0x06, 0x54, 0xa9, 0xbf, 0x99, 0x83, 0x42, 0xfb, 0xf0,
0x08, 0x09, 0xbd, 0xe7, 0x85, 0x56, 0x70, 0x6e, 0x8b, 0x68, 0x6e, 0x8c, 0xd0, 0x7b, 0x5e, 0x38,
0x60, 0x00, 0x46, 0xe8, 0x03, 0x1a, 0x46, 0x4e, 0xd3, 0xa5, 0x80, 0x86, 0xdc, 0x83, 0x7e, 0x74,
0xee, 0x4c, 0xc6, 0xb1, 0x40, 0xa0, 0x80, 0x20, 0xbe, 0x22, 0x08, 0x14, 0xb5, 0xe3, 0x01, 0x7f,
0xf3, 0x9b, 0x87, 0xe2, 0x44, 0xe1, 0x7e, 0xf9, 0xea, 0xdb, 0xf8, 0x2b, 0x39, 0x20, 0x6d, 0x46,
0x91, 0x70, 0x40, 0x95, 0xa4, 0x1b, 0x9d, 0x33, 0x39, 0xfd, 0x9c, 0xc9, 0x20, 0xe7, 0xf9, 0x4c,
0x72, 0xfe, 0x2a, 0xc2, 0x17, 0xdb, 0xba, 0xcb, 0xa9, 0xad, 0x6b, 0xec, 0x41, 0xed, 0x48, 0x8b,
0xcb, 0x7c, 0x97, 0x9d, 0x8a, 0x32, 0x22, 0x33, 0x3f, 0x2f, 0xb9, 0x56, 0xd7, 0x17, 0x81, 0x98,
0xb5, 0x06, 0xe7, 0xb5, 0x06, 0x1b, 0x7f, 0x2b, 0xc7, 0xa3, 0x13, 0xaa, 0xfe, 0x45, 0xa1, 0xa0,
0xa5, 0x71, 0x34, 0x8a, 0x63, 0x53, 0x93, 0xe6, 0x4f, 0x11, 0x82, 0x06, 0x5b, 0x6f, 0x79, 0xa7,
0xa7, 0x01, 0x95, 0x3e, 0x66, 0x35, 0x84, 0xf5, 0x11, 0x24, 0xc5, 0x1f, 0x26, 0x63, 0x39, 0xbc,
0xfc, 0x40, 0x38, 0x96, 0x31, 0xf1, 0xe7, 0xd0, 0xbe, 0x14, 0xb5, 0x06, 0x6c, 0x06, 0x84, 0x85,
0x46, 0xc6, 0x71, 0x50, 0xdf, 0xc6, 0x5f, 0x17, 0xa1, 0x76, 0x92, 0x53, 0x70, 0x1f, 0x2a, 0xaa,
0xd4, 0x38, 0x57, 0x21, 0x31, 0x55, 0x3a, 0xe3, 0x5d, 0x50, 0x1d, 0x15, 0x6b, 0x31, 0xa7, 0x16,
0x68, 0x65, 0xeb, 0x6a, 0xad, 0xfe, 0x0e, 0x90, 0x53, 0xc7, 0x4f, 0x22, 0x73, 0xea, 0xd1, 0xc4,
0x14, 0x0d, 0xdb, 0x38, 0x86, 0x15, 0x49, 0xf6, 0x34, 0x99, 0x2c, 0x3e, 0xbf, 0xb9, 0x57, 0x1c,
0x6c, 0xf9, 0xd4, 0xc1, 0x66, 0xfc, 0x46, 0x09, 0xca, 0x32, 0x0c, 0x7a, 0x56, 0x5c, 0xee, 0x6a,
0x3c, 0x2e, 0x77, 0x2b, 0x16, 0xf5, 0x13, 0xa7, 0x5e, 0xf0, 0x38, 0xef, 0x25, 0xd9, 0x14, 0xcd,
0x5a, 0x14, 0x63, 0x55, 0x84, 0xb5, 0xa8, 0x14, 0xb7, 0x16, 0x65, 0xc5, 0x2a, 0xe7, 0xec, 0x76,
0x2a, 0x56, 0xf9, 0x2d, 0xe0, 0xbc, 0x93, 0xe6, 0x5c, 0x5b, 0x41, 0x80, 0x88, 0x45, 0xa2, 0xb1,
0x5a, 0x95, 0x24, 0xab, 0xf5, 0xda, 0x6c, 0xd0, 0x27, 0xb0, 0xc0, 0xc3, 0x76, 0x89, 0xb8, 0x14,
0xf2, 0xb0, 0x14, 0x63, 0x25, 0xff, 0xf3, 0x3b, 0x5b, 0xa6, 0xc0, 0xd5, 0x43, 0xdb, 0xd6, 0x62,
0xa1, 0x6d, 0x75, 0x2b, 0x56, 0x3d, 0x6e, 0xc5, 0xba, 0x07, 0x4d, 0x35, 0x70, 0xa8, 0x13, 0x76,
0x03, 0x71, 0x05, 0x7d, 0x51, 0xc2, 0x19, 0x79, 0xef, 0x05, 0xd1, 0x61, 0xbf, 0x18, 0x3b, 0xec,
0x19, 0xf1, 0x6d, 0x87, 0x21, 0x9d, 0xce, 0x42, 0x79, 0xd8, 0x6b, 0xe1, 0xe1, 0xf9, 0xcc, 0xf3,
0x3b, 0x6d, 0x72, 0x7a, 0xf9, 0xea, 0xd8, 0x86, 0xc5, 0x53, 0xdb, 0x99, 0xcc, 0x7d, 0x6a, 0xf9,
0xd4, 0x0e, 0x3c, 0x17, 0xe9, 0x43, 0xc4, 0x77, 0x88, 0x2e, 0xee, 0x71, 0x1c, 0x13, 0x51, 0xcc,
0xc6, 0xa9, 0xfe, 0x89, 0x37, 0x48, 0xf5, 0x91, 0x60, 0x67, 0xb0, 0x88, 0x4e, 0xc1, 0x7d, 0xe5,
0xba, 0x3d, 0x6b, 0xef, 0xa0, 0xfb, 0x78, 0x7f, 0xd8, 0xcc, 0xb1, 0xcf, 0xc1, 0xf1, 0xce, 0x4e,
0xa7, 0xb3, 0x8b, 0x67, 0x32, 0xc0, 0xc2, 0x5e, 0xbb, 0x7b, 0x20, 0x4e, 0xe4, 0x62, 0xb3, 0x64,
0xfc, 0x61, 0x1e, 0x6a, 0x5a, 0x6f, 0x30, 0xee, 0x0c, 0xff, 0xc9, 0xe8, 0x6f, 0x59, 0xc4, 0x9d,
0xe1, 0x90, 0xee, 0x98, 0x3c, 0x52, 0x73, 0xc4, 0xc3, 0xe5, 0xdc, 0x4e, 0x0f, 0xc8, 0x96, 0x3c,
0xd1, 0xb4, 0x49, 0x52, 0x71, 0xe2, 0xf3, 0xd7, 0xc6, 0x89, 0x27, 0xef, 0xc2, 0x92, 0xac, 0x59,
0xce, 0x89, 0xb0, 0xbe, 0x08, 0xb0, 0x98, 0x92, 0x77, 0x45, 0xe8, 0x1e, 0x71, 0x2c, 0x33, 0xbc,
0xa2, 0xf4, 0x29, 0x57, 0x27, 0x33, 0x4e, 0x5d, 0x59, 0x0c, 0x9c, 0xf0, 0x96, 0x50, 0x0c, 0x8e,
0x18, 0x4e, 0x99, 0x1c, 0x3b, 0x23, 0x16, 0x12, 0x67, 0xc4, 0xa7, 0x00, 0x51, 0x7f, 0xe2, 0xa3,
0x7b, 0x23, 0x3e, 0xba, 0x39, 0x6d, 0x74, 0xf3, 0xc6, 0xdf, 0x13, 0x94, 0x4d, 0x4c, 0x95, 0xd2,
0xc5, 0x7e, 0x00, 0x52, 0x3b, 0x6c, 0xe1, 0x1d, 0x94, 0xd9, 0x84, 0x86, 0xf2, 0x82, 0xfd, 0xb2,
0x48, 0xe9, 0xaa, 0x84, 0x14, 0x25, 0xce, 0xa7, 0x29, 0xf1, 0x5b, 0x50, 0xc7, 0x58, 0x90, 0xa2,
0x22, 0x19, 0x8c, 0x79, 0x6a, 0x5f, 0xca, 0xba, 0x63, 0x24, 0xb8, 0x98, 0x20, 0xc1, 0x7f, 0x23,
0xc7, 0x03, 0x87, 0x45, 0x0d, 0x8d, 0x68, 0xb0, 0x2a, 0x33, 0x4e, 0x83, 0x05, 0xaa, 0xa9, 0xd2,
0xaf, 0xa1, 0xab, 0xf9, 0x6c, 0xba, 0x9a, 0x4d, 0xb1, 0x0b, 0x99, 0x14, 0xdb, 0xb8, 0x84, 0xd6,
0x2e, 0x65, 0x43, 0xd1, 0x9e, 0x4c, 0x92, 0x63, 0xf9, 0x00, 0x56, 0xd9, 0x14, 0xa2, 0xab, 0x08,
0x4f, 0xd1, 0x4f, 0x34, 0xc2, 0xd3, 0x64, 0x26, 0x3c, 0xd8, 0xee, 0xc3, 0xb2, 0xc8, 0x81, 0x9b,
0x56, 0x8f, 0xd2, 0xb6, 0xc4, 0x13, 0xd0, 0xc5, 0x95, 0xe1, 0x1a, 0xb7, 0xe0, 0x66, 0x46, 0xcd,
0x42, 0x69, 0xf7, 0x9b, 0x39, 0x58, 0x6b, 0xf3, 0x68, 0x44, 0xdf, 0xd8, 0xfd, 0xfa, 0x2f, 0xe0,
0xa6, 0xba, 0xae, 0xa2, 0x5d, 0xb3, 0xd5, 0x1b, 0x29, 0x6f, 0xba, 0x68, 0x97, 0xb4, 0xb0, 0xad,
0x2d, 0x58, 0x4f, 0xb6, 0x46, 0x34, 0x74, 0x0f, 0x96, 0x77, 0xe9, 0xc9, 0xfc, 0xec, 0x80, 0x5e,
0x44, 0x6d, 0x24, 0x50, 0x0c, 0xce, 0xbd, 0x17, 0x62, 0xa0, 0xf0, 0x37, 0xfa, 0xb3, 0x33, 0x1c,
0x2b, 0x98, 0xd1, 0x91, 0x34, 0xfa, 0x20, 0x64, 0x30, 0xa3, 0x23, 0xe3, 0x11, 0x10, 0xbd, 0x1c,
0xb1, 0x46, 0x98, 0x0c, 0x3c, 0x3f, 0xb1, 0x82, 0xab, 0x20, 0xa4, 0x53, 0x79, 0xd5, 0x1c, 0x82,
0xf9, 0xc9, 0x80, 0x43, 0x8c, 0xf7, 0xa0, 0x7e, 0x64, 0x5f, 0x99, 0xf4, 0x47, 0xe2, 0xb6, 0xf6,
0x06, 0x94, 0x67, 0xf6, 0x15, 0x3b, 0x08, 0x94, 0xfd, 0x17, 0x93, 0x8d, 0xdf, 0x2d, 0xc2, 0x02,
0xc7, 0x24, 0x77, 0xf9, 0x13, 0x32, 0x8e, 0x8b, 0x84, 0x58, 0x1e, 0x89, 0x1a, 0x28, 0x75, 0x6a,
0xe6, 0xd3, 0xa7, 0xa6, 0x50, 0x56, 0xcb, 0x50, 0x97, 0xd2, 0x52, 0xe7, 0xce, 0xa7, 0x32, 0xbe,
0x65, 0x3c, 0xf6, 0x4e, 0x31, 0x7a, 0x94, 0x88, 0xc7, 0x1d, 0x89, 0xfb, 0x52, 0x44, 0x92, 0x36,
0x6f, 0x9d, 0x64, 0x06, 0xc4, 0x81, 0xa9, 0x83, 0x32, 0xc5, 0xf9, 0xb2, 0x0c, 0x65, 0x10, 0x17,
0xe7, 0x53, 0x62, 0x7b, 0xe5, 0xd5, 0x62, 0x3b, 0xd7, 0x62, 0xbf, 0x44, 0x6c, 0x87, 0xd7, 0x10,
0xdb, 0x5f, 0xc3, 0x8f, 0xe1, 0x26, 0x54, 0x90, 0xc3, 0xd3, 0xce, 0x4f, 0xc6, 0xd9, 0xb1, 0xf3,
0xf3, 0x33, 0x4d, 0xb0, 0xe5, 0x4e, 0x54, 0xda, 0x01, 0x66, 0xd2, 0x1f, 0xfd, 0x74, 0x14, 0xa3,
0xcf, 0xa0, 0x2c, 0xa0, 0x6c, 0x41, 0xbb, 0xf6, 0x54, 0x06, 0x74, 0xc6, 0xdf, 0x6c, 0xd8, 0x30,
0xc4, 0xe9, 0x8f, 0xe6, 0x8e, 0x4f, 0xc7, 0x32, 0xd0, 0xa2, 0x83, 0xd4, 0x83, 0x41, 0x58, 0x07,
0x99, 0x90, 0xed, 0xca, 0xd7, 0x23, 0x2a, 0x66, 0xd9, 0x09, 0x9e, 0xb0, 0x4f, 0x83, 0x40, 0x13,
0xc3, 0xe7, 0xcf, 0x3c, 0x5f, 0xb2, 0x27, 0xc6, 0xef, 0xe5, 0xa0, 0x29, 0x76, 0x97, 0x4a, 0xd3,
0x05, 0xd8, 0xd2, 0x75, 0x3e, 0x3f, 0x2f, 0x0f, 0x9b, 0x68, 0x40, 0x03, 0x55, 0x7b, 0x8a, 0x57,
0xe1, 0xaa, 0xc9, 0x1a, 0x03, 0xee, 0x09, 0x7e, 0xe5, 0x4d, 0xa8, 0xc9, 0xdb, 0x36, 0x53, 0x67,
0x22, 0xdf, 0x1f, 0xe3, 0xd7, 0x6d, 0x0e, 0x9d, 0x89, 0x64, 0x75, 0x7c, 0x5b, 0x84, 0xd7, 0xc8,
0x21, 0xab, 0x63, 0xda, 0x21, 0x35, 0xfe, 0x20, 0x07, 0xcb, 0x5a, 0x57, 0xc4, 0xbe, 0xfd, 0x2e,
0xd4, 0xd5, 0xab, 0x1e, 0x54, 0xf1, 0xd8, 0x1b, 0x71, 0x1a, 0x15, 0x65, 0xab, 0x8d, 0x14, 0x24,
0x60, 0x8d, 0x19, 0xdb, 0x57, 0xfc, 0x4a, 0xc8, 0x7c, 0x2a, 0xe5, 0xf2, 0xb1, 0x7d, 0xb5, 0x47,
0xe9, 0x60, 0x3e, 0x25, 0x77, 0xa1, 0xfe, 0x82, 0xd2, 0xe7, 0x0a, 0x81, 0x13, 0x76, 0x60, 0x30,
0x81, 0x61, 0x40, 0x63, 0xea, 0xb9, 0xe1, 0xb9, 0x42, 0x11, 0xf2, 0x05, 0x02, 0x39, 0x8e, 0xf1,
0xaf, 0xf2, 0xb0, 0xc2, 0x15, 0xc8, 0xc2, 0x8c, 0x20, 0x48, 0x57, 0x0b, 0x16, 0xb8, 0x56, 0x9f,
0x13, 0xaf, 0xfd, 0x1b, 0xa6, 0xf8, 0x26, 0x9f, 0xbc, 0xa6, 0xd2, 0x5b, 0x46, 0xe6, 0xb8, 0x66,
0xf8, 0x0b, 0xe9, 0xe1, 0xbf, 0x7e, 0x78, 0xb3, 0x9c, 0x0a, 0x4a, 0x59, 0x4e, 0x05, 0xaf, 0x63,
0xca, 0x4f, 0xc5, 0x86, 0x28, 0xa7, 0x63, 0x34, 0x3f, 0x82, 0x8d, 0x18, 0x0e, 0x52, 0x6b, 0xe7,
0xd4, 0x51, 0x8f, 0x0b, 0xac, 0x6a, 0xd8, 0x03, 0x99, 0xb6, 0x5d, 0x86, 0x52, 0x30, 0xf2, 0x66,
0xe8, 0x87, 0x1e, 0x1f, 0x55, 0x71, 0x4c, 0xfc, 0x76, 0x0e, 0x5a, 0x7b, 0x51, 0xb0, 0x6b, 0x27,
0x08, 0x3d, 0x5f, 0xbd, 0xdb, 0x70, 0x1b, 0x80, 0xbf, 0x85, 0x86, 0x6a, 0x10, 0x11, 0xa5, 0x0c,
0x21, 0xa8, 0x04, 0xb9, 0x09, 0x15, 0xea, 0x8e, 0x79, 0x22, 0x5f, 0x0d, 0x65, 0xea, 0x8e, 0xa5,
0x0a, 0x25, 0x75, 0xc8, 0x37, 0xe2, 0xec, 0x8b, 0x88, 0xb7, 0xc3, 0x46, 0x87, 0x5e, 0x20, 0xb3,
0x51, 0x54, 0xf1, 0x76, 0x0e, 0xed, 0x4b, 0xbc, 0x4e, 0x10, 0x18, 0xff, 0x20, 0x0f, 0x4b, 0x51,
0xfb, 0x78, 0xc4, 0xb1, 0xbb, 0xa9, 0xd8, 0x69, 0xc2, 0x1f, 0x4a, 0xd1, 0xf0, 0xbb, 0x62, 0x49,
0x38, 0x4c, 0x5a, 0xd3, 0x54, 0xeb, 0x15, 0xbe, 0x41, 0xbb, 0x2e, 0x31, 0xa0, 0x26, 0x31, 0xbc,
0x79, 0xa8, 0xc5, 0x96, 0xae, 0x72, 0x94, 0xfe, 0x3c, 0x64, 0xe2, 0xb5, 0x3d, 0x65, 0xdc, 0x8a,
0x10, 0x70, 0x4b, 0xf6, 0x34, 0xec, 0xe2, 0xa3, 0x7b, 0x0c, 0xcc, 0xb2, 0xf1, 0xc9, 0x64, 0x58,
0x0c, 0xbf, 0xc9, 0xa5, 0x2d, 0x3e, 0x7b, 0x28, 0x69, 0xe9, 0xa2, 0x08, 0x7f, 0xea, 0x47, 0x89,
0x22, 0x6f, 0x42, 0x8d, 0x17, 0x1e, 0x85, 0x03, 0xc1, 0x40, 0x8f, 0x61, 0xd7, 0xc5, 0x74, 0xa1,
0xe6, 0xf4, 0xe6, 0x31, 0xcd, 0x0d, 0xf0, 0xaa, 0xe4, 0xfb, 0x68, 0xaa, 0xc7, 0x96, 0x32, 0x42,
0xd6, 0x14, 0xac, 0x17, 0x30, 0x6e, 0xe5, 0x66, 0xc6, 0xec, 0x0a, 0x62, 0xb0, 0x03, 0x5a, 0x64,
0x74, 0x39, 0x09, 0x9c, 0x22, 0xac, 0x4b, 0xea, 0x1b, 0x1f, 0x7a, 0xb3, 0x79, 0x1a, 0x07, 0x44,
0x52, 0x38, 0x9f, 0xe8, 0x58, 0xdc, 0x1a, 0xe4, 0xe9, 0xf8, 0x6c, 0x73, 0x01, 0xf8, 0x08, 0x36,
0x3b, 0x97, 0x8c, 0xb0, 0x28, 0xc7, 0xfa, 0xd1, 0xf3, 0xb9, 0xb4, 0x8f, 0x26, 0xac, 0x2c, 0xb9,
0xd7, 0xb2, 0xb2, 0x8c, 0x79, 0xb4, 0x08, 0x55, 0xd6, 0x4f, 0x52, 0x08, 0xd7, 0x2f, 0xd9, 0xae,
0x75, 0x82, 0x45, 0xc8, 0xe0, 0x34, 0x0c, 0xc4, 0x0b, 0x35, 0x02, 0x58, 0x3a, 0x9c, 0x4f, 0x42,
0x67, 0x47, 0x81, 0xc8, 0x27, 0x22, 0x0f, 0xd6, 0x23, 0x47, 0x2d, 0xb3, 0x22, 0x50, 0x15, 0xe1,
0x60, 0x4d, 0x59, 0x41, 0x56, 0xba, 0xbe, 0xa5, 0x69, 0xbc, 0x06, 0xe3, 0x26, 0x6c, 0x44, 0x5f,
0x7c, 0xd8, 0xe4, 0x89, 0xf4, 0x37, 0x73, 0xfc, 0x8a, 0x13, 0x4f, 0x1b, 0xb8, 0xf6, 0x2c, 0x38,
0xf7, 0x42, 0xd2, 0x81, 0x95, 0xc0, 0x71, 0xcf, 0x26, 0x54, 0x2f, 0x3e, 0x10, 0x83, 0xb0, 0x16,
0x6f, 0x1b, 0xcf, 0x1a, 0x98, 0xcb, 0x3c, 0x47, 0x54, 0x5a, 0x40, 0xb6, 0xaf, 0x6b, 0x64, 0xb4,
0x2c, 0x12, 0xa3, 0x91, 0x6e, 0x7c, 0x17, 0x16, 0xe3, 0x15, 0x91, 0xcf, 0x44, 0x90, 0x95, 0xa8,
0x55, 0x85, 0x44, 0x88, 0x89, 0x68, 0x41, 0xd4, 0xa2, 0xb1, 0x0f, 0x8c, 0xbf, 0x94, 0x83, 0x96,
0x49, 0xd9, 0xca, 0xd5, 0x5a, 0x29, 0xd7, 0xcc, 0x77, 0x53, 0xa5, 0x5e, 0xdf, 0x57, 0x19, 0xbb,
0x45, 0xb6, 0xe8, 0x3b, 0xd7, 0x4e, 0xc6, 0xfe, 0x8d, 0x54, 0x8f, 0xb6, 0x2b, 0xb0, 0xc0, 0x51,
0x8c, 0x0d, 0x58, 0x13, 0xed, 0x91, 0x6d, 0x89, 0x0c, 0xfa, 0xb1, 0x1a, 0x63, 0x06, 0xfd, 0x4d,
0x68, 0xf1, 0x58, 0x08, 0x7a, 0x27, 0x44, 0xc6, 0x5d, 0x20, 0x87, 0xf6, 0xc8, 0xf6, 0x3d, 0xcf,
0x3d, 0xa2, 0xbe, 0x70, 0x99, 0x47, 0x46, 0x14, 0xed, 0xdd, 0x92, 0x63, 0xe6, 0x5f, 0x32, 0xe8,
0xbe, 0xe7, 0x4a, 0x0f, 0x41, 0xfe, 0x65, 0xf8, 0xb0, 0xb2, 0x6d, 0x3f, 0xa7, 0xb2, 0x24, 0x39,
0x44, 0x5f, 0x42, 0x6d, 0xa6, 0x0a, 0x95, 0xe3, 0x2e, 0xe3, 0x57, 0xa5, 0xab, 0x35, 0x75, 0x6c,
0x46, 0xa5, 0x50, 0x61, 0x8b, 0x11, 0x61, 0xc6, 0xf2, 0xcc, 0x67, 0xa0, 0x27, 0xf4, 0xaa, 0x3b,
0x36, 0x1e, 0xc2, 0x6a, 0xbc, 0x4e, 0x41, 0x5a, 0x36, 0xa1, 0x32, 0x15, 0x30, 0xd1, 0x7a, 0xf5,
0xcd, 0x64, 0x16, 0x26, 0x77, 0xca, 0x3c, 0xdd, 0x5d, 0x15, 0xd6, 0xe0, 0x4b, 0xd8, 0x48, 0xa5,
0x88, 0x02, 0xef, 0x42, 0x5d, 0x6b, 0x08, 0xef, 0x46, 0xd1, 0x04, 0xd5, 0x92, 0xc0, 0xf8, 0x02,
0x36, 0xb8, 0xd8, 0x16, 0x65, 0x97, 0x43, 0x90, 0xe8, 0x45, 0x2e, 0xd9, 0x8b, 0x4f, 0xa4, 0xac,
0xa9, 0x67, 0x8d, 0xe2, 0x47, 0x8e, 0x31, 0x4d, 0x3a, 0x79, 0xc9, 0x4f, 0xe3, 0x18, 0xd6, 0xd3,
0xc3, 0xc7, 0xda, 0xff, 0x67, 0x1a, 0x72, 0x39, 0x3c, 0x51, 0xb2, 0x1a, 0x9e, 0xff, 0x9c, 0xe3,
0xe3, 0x13, 0x4b, 0x12, 0xcd, 0x1c, 0x03, 0x99, 0xd2, 0xf0, 0xdc, 0x1b, 0x5b, 0xe9, 0x9a, 0x1f,
0x29, 0x1f, 0xb3, 0xcc, 0xbc, 0x5b, 0x87, 0x98, 0x51, 0x4b, 0x11, 0xb7, 0x1d, 0xa6, 0x49, 0xf8,
0xe6, 0x08, 0xd6, 0xb3, 0x91, 0x33, 0x3c, 0xb3, 0x3e, 0x8e, 0xf3, 0xf3, 0xb7, 0xaf, 0xed, 0x3e,
0x6b, 0x96, 0xce, 0xde, 0xff, 0x6e, 0x05, 0xca, 0x42, 0x55, 0x43, 0xb6, 0xa0, 0x38, 0x92, 0x5e,
0xbe, 0x51, 0x0c, 0x51, 0x91, 0x2a, 0xff, 0xef, 0xa0, 0xaf, 0x2f, 0xc3, 0x23, 0x5f, 0xc2, 0x62,
0xdc, 0xd1, 0x25, 0x11, 0xeb, 0x27, 0xee, 0xa1, 0xd2, 0x18, 0x25, 0x9c, 0x08, 0xaa, 0x11, 0x0f,
0xc6, 0x59, 0xd3, 0xca, 0xb9, 0xc6, 0xa4, 0x79, 0x2e, 0x13, 0xeb, 0x82, 0x73, 0xdb, 0x7a, 0xf8,
0xe8, 0x53, 0x61, 0x54, 0xa8, 0x21, 0x70, 0x70, 0x6e, 0x3f, 0x7c, 0xf4, 0x69, 0x52, 0x60, 0x13,
0xa1, 0x7e, 0x34, 0x81, 0x6d, 0x15, 0x4a, 0xfc, 0x65, 0x02, 0xee, 0xae, 0xc9, 0x3f, 0xa4, 0x3a,
0x63, 0xee, 0x53, 0x4b, 0x5c, 0xac, 0xe1, 0xa7, 0x28, 0x7f, 0x45, 0x8e, 0x88, 0xb4, 0x01, 0x26,
0x71, 0x75, 0xe2, 0x3a, 0x2c, 0x9c, 0x47, 0x4f, 0x4d, 0x34, 0x4c, 0xf1, 0x65, 0xfc, 0x8f, 0x12,
0xd4, 0xb4, 0x41, 0x21, 0x75, 0xa8, 0x98, 0x9d, 0x41, 0xc7, 0x7c, 0xda, 0xd9, 0x6d, 0xde, 0x20,
0xf7, 0xe0, 0x9d, 0x6e, 0x6f, 0xa7, 0x6f, 0x9a, 0x9d, 0x9d, 0xa1, 0xd5, 0x37, 0x2d, 0x19, 0xda,
0xf6, 0xa8, 0xfd, 0xec, 0xb0, 0xd3, 0x1b, 0x5a, 0xbb, 0x9d, 0x61, 0xbb, 0x7b, 0x30, 0x68, 0xe6,
0xc8, 0x1b, 0xd0, 0x8a, 0x30, 0x65, 0x72, 0xfb, 0xb0, 0x7f, 0xdc, 0x1b, 0x36, 0xf3, 0xe4, 0x0e,
0xdc, 0xda, 0xeb, 0xf6, 0xda, 0x07, 0x56, 0x84, 0xb3, 0x73, 0x30, 0x7c, 0x6a, 0x75, 0x7e, 0xee,
0xa8, 0x6b, 0x3e, 0x6b, 0x16, 0xb2, 0x10, 0xf6, 0x87, 0x07, 0x3b, 0xb2, 0x84, 0x22, 0xb9, 0x09,
0x6b, 0x1c, 0x81, 0x67, 0xb1, 0x86, 0xfd, 0xbe, 0x35, 0xe8, 0xf7, 0x7b, 0xcd, 0x12, 0x59, 0x86,
0x46, 0xb7, 0xf7, 0xb4, 0x7d, 0xd0, 0xdd, 0xb5, 0xcc, 0x4e, 0xfb, 0xe0, 0xb0, 0xb9, 0x40, 0x56,
0x60, 0x29, 0x89, 0x57, 0x66, 0x45, 0x48, 0xbc, 0x7e, 0xaf, 0xdb, 0xef, 0x59, 0x4f, 0x3b, 0xe6,
0xa0, 0xdb, 0xef, 0x35, 0x2b, 0x64, 0x1d, 0x48, 0x3c, 0x69, 0xff, 0xb0, 0xbd, 0xd3, 0xac, 0x92,
0x35, 0x58, 0x8e, 0xc3, 0x9f, 0x74, 0x9e, 0x35, 0x81, 0xb4, 0x60, 0x95, 0x37, 0xcc, 0xda, 0xee,
0x1c, 0xf4, 0xbf, 0xb2, 0x0e, 0xbb, 0xbd, 0xee, 0xe1, 0xf1, 0x61, 0xb3, 0x86, 0x01, 0xc6, 0x3b,
0x1d, 0xab, 0xdb, 0x1b, 0x1c, 0xef, 0xed, 0x75, 0x77, 0xba, 0x9d, 0xde, 0xb0, 0x59, 0xe7, 0x35,
0x67, 0x75, 0xbc, 0xc1, 0x32, 0x88, 0xbb, 0xa7, 0xd6, 0x6e, 0x77, 0xd0, 0xde, 0x3e, 0xe8, 0xec,
0x36, 0x17, 0xc9, 0x6d, 0xb8, 0x39, 0xec, 0x1c, 0x1e, 0xf5, 0xcd, 0xb6, 0xf9, 0x4c, 0xde, 0x4d,
0xb5, 0xf6, 0xda, 0xdd, 0x83, 0x63, 0xb3, 0xd3, 0x5c, 0x22, 0x6f, 0xc1, 0x6d, 0xb3, 0xf3, 0xc3,
0xe3, 0xae, 0xd9, 0xd9, 0xb5, 0x7a, 0xfd, 0xdd, 0x8e, 0xb5, 0xd7, 0x69, 0x0f, 0x8f, 0xcd, 0x8e,
0x75, 0xd8, 0x1d, 0x0c, 0xba, 0xbd, 0xc7, 0xcd, 0x26, 0x79, 0x07, 0xee, 0x2a, 0x14, 0x55, 0x40,
0x02, 0x6b, 0x99, 0xf5, 0x4f, 0x4e, 0x69, 0xaf, 0xf3, 0x73, 0x43, 0xeb, 0xa8, 0xd3, 0x31, 0x9b,
0x84, 0x6c, 0xc2, 0x7a, 0x54, 0x3d, 0xaf, 0x40, 0xd4, 0xbd, 0xc2, 0xd2, 0x8e, 0x3a, 0xe6, 0x61,
0xbb, 0xc7, 0x26, 0x38, 0x96, 0xb6, 0xca, 0x9a, 0x1d, 0xa5, 0x25, 0x9b, 0xbd, 0x46, 0x08, 0x2c,
0x6a, 0xb3, 0xb2, 0xd7, 0x36, 0x9b, 0xeb, 0x64, 0x09, 0x6a, 0x87, 0x47, 0x47, 0xd6, 0xb0, 0x7b,
0xd8, 0xe9, 0x1f, 0x0f, 0x9b, 0x1b, 0xe9, 0x59, 0x3a, 0x6a, 0x3f, 0x3b, 0xe8, 0xb7, 0x77, 0x9b,
0x2d, 0xb2, 0x06, 0xcd, 0x6e, 0x6f, 0xd8, 0x31, 0xd9, 0x32, 0x90, 0xa5, 0xfe, 0x97, 0x32, 0x59,
0x85, 0x25, 0xd9, 0x09, 0x09, 0xfd, 0xa3, 0x32, 0xd9, 0x00, 0x72, 0xdc, 0x33, 0x3b, 0xed, 0x5d,
0x36, 0xa6, 0x2a, 0xe1, 0xbf, 0x96, 0x85, 0x79, 0xf9, 0xf7, 0x0a, 0x8a, 0x0f, 0x8c, 0x1c, 0xcc,
0xe2, 0xcf, 0x46, 0xd5, 0xb5, 0xe7, 0x9e, 0x5e, 0xf5, 0xb4, 0xa8, 0x26, 0xdc, 0x17, 0x52, 0xc2,
0x7d, 0x4a, 0x7b, 0xd4, 0xd0, 0x25, 0x8f, 0xb7, 0xa1, 0x31, 0xe5, 0x4f, 0x48, 0x89, 0x37, 0x48,
0x40, 0x78, 0x5b, 0x72, 0x20, 0x7f, 0x80, 0x24, 0xf5, 0xb6, 0x66, 0x29, 0xfd, 0xb6, 0x66, 0x96,
0x84, 0xb9, 0x90, 0x25, 0x61, 0xde, 0x87, 0x65, 0x4e, 0xb5, 0x1c, 0xd7, 0x99, 0x4a, 0xbd, 0x8d,
0x78, 0xa9, 0x12, 0xa9, 0x17, 0x87, 0x4b, 0x81, 0x56, 0x0a, 0xbd, 0x82, 0xba, 0x94, 0x85, 0xbc,
0x1b, 0x93, 0x75, 0x39, 0x51, 0x51, 0xb2, 0xae, 0xaa, 0xc1, 0xbe, 0x8c, 0x6a, 0xa8, 0x69, 0x35,
0x70, 0x38, 0xd6, 0x70, 0x1f, 0x96, 0xe9, 0x65, 0xe8, 0xdb, 0x96, 0x37, 0xb3, 0x7f, 0x34, 0x47,
0x17, 0x19, 0x1b, 0xb5, 0x48, 0x75, 0x73, 0x09, 0x13, 0xfa, 0x08, 0xdf, 0xb5, 0x43, 0xdb, 0xf8,
0x45, 0x00, 0x75, 0xe0, 0xe2, 0x8b, 0x9f, 0xae, 0x27, 0xef, 0xd4, 0xd6, 0x4d, 0xfe, 0x81, 0xf3,
0x18, 0x7a, 0xbe, 0x7d, 0x46, 0xbb, 0xd2, 0x2a, 0x1c, 0x01, 0xc8, 0x2d, 0x28, 0x78, 0x33, 0xe9,
0x8b, 0x58, 0x95, 0x41, 0xf5, 0x67, 0x26, 0x83, 0x1a, 0x9f, 0x42, 0xbe, 0x3f, 0xbb, 0x96, 0x8b,
0xc2, 0x07, 0xce, 0xf8, 0xab, 0x06, 0x79, 0xf4, 0x3f, 0x94, 0x9f, 0xf7, 0xff, 0x3c, 0xd4, 0xb4,
0xf7, 0xd0, 0xc8, 0x06, 0xac, 0x7c, 0xd5, 0x1d, 0xf6, 0x3a, 0x83, 0x81, 0x75, 0x74, 0xbc, 0xfd,
0xa4, 0xf3, 0xcc, 0xda, 0x6f, 0x0f, 0xf6, 0x9b, 0x37, 0x18, 0x99, 0xe9, 0x75, 0x06, 0xc3, 0xce,
0x6e, 0x0c, 0x9e, 0x23, 0x6f, 0xc2, 0xe6, 0x71, 0xef, 0x78, 0xd0, 0xd9, 0xb5, 0xb2, 0xf2, 0xe5,
0xd9, 0xbe, 0x12, 0xe9, 0x19, 0xd9, 0x0b, 0xf7, 0x7f, 0x09, 0x16, 0xe3, 0x81, 0x65, 0x08, 0xc0,
0xc2, 0x41, 0xe7, 0x71, 0x7b, 0xe7, 0x19, 0x7f, 0x34, 0x61, 0x30, 0x6c, 0x0f, 0xbb, 0x3b, 0x96,
0x78, 0x24, 0x81, 0xd1, 0xb0, 0x1c, 0xa9, 0x41, 0xb9, 0xdd, 0xdb, 0xd9, 0xef, 0x9b, 0x83, 0x66,
0x9e, 0xbc, 0x01, 0x1b, 0x72, 0x0b, 0xed, 0xf4, 0x0f, 0x0f, 0xbb, 0x43, 0x24, 0xdf, 0xc3, 0x67,
0x47, 0x6c, 0xc7, 0xdc, 0xb7, 0xa1, 0x1a, 0xbd, 0xef, 0x80, 0x24, 0xb1, 0x3b, 0xec, 0xb6, 0x87,
0xd1, 0x79, 0xd0, 0xbc, 0xc1, 0x28, 0x6e, 0x04, 0xc6, 0x47, 0x1a, 0x9a, 0x39, 0x7e, 0xf7, 0x5e,
0x02, 0x79, 0xed, 0xcd, 0x3c, 0x23, 0x03, 0x11, 0x74, 0xbb, 0x3f, 0x64, 0x5d, 0xf8, 0x65, 0x58,
0x8c, 0x3f, 0xa3, 0x40, 0x9a, 0x50, 0x67, 0xf5, 0x6b, 0x55, 0x00, 0x2c, 0xf0, 0x16, 0x37, 0x73,
0x9c, 0xe6, 0xef, 0xf4, 0x0f, 0xbb, 0xbd, 0xc7, 0x78, 0x50, 0x34, 0xf3, 0x0c, 0xd4, 0x3f, 0x1e,
0x3e, 0xee, 0x2b, 0x50, 0x81, 0xe5, 0xe0, 0xdd, 0x69, 0x16, 0xef, 0xff, 0x08, 0x96, 0x53, 0x0f,
0x2e, 0xb0, 0x56, 0xf7, 0x8f, 0x87, 0x3b, 0xfd, 0x43, 0xbd, 0x9e, 0x1a, 0x94, 0x77, 0x0e, 0xda,
0xdd, 0x43, 0x34, 0xd4, 0x34, 0xa0, 0x7a, 0xdc, 0x93, 0x9f, 0xf9, 0xf8, 0x53, 0x11, 0x05, 0x46,
0xbd, 0xf6, 0xba, 0xe6, 0x60, 0x68, 0x0d, 0x86, 0xed, 0xc7, 0x9d, 0x66, 0x91, 0xe5, 0x95, 0xa4,
0xac, 0x74, 0xff, 0x0b, 0x58, 0x8c, 0x3b, 0xce, 0xc7, 0xed, 0x6f, 0x9b, 0xb0, 0xbe, 0xdd, 0x19,
0x7e, 0xd5, 0xe9, 0xf4, 0x70, 0xca, 0x77, 0x3a, 0xbd, 0xa1, 0xd9, 0x3e, 0xe8, 0x0e, 0x9f, 0x35,
0x73, 0xf7, 0xbf, 0x84, 0x66, 0xd2, 0xe9, 0x23, 0xe6, 0x25, 0xf3, 0x32, 0x77, 0x9a, 0xfb, 0xff,
0x36, 0x07, 0xab, 0x59, 0xe6, 0x41, 0xb6, 0x30, 0x05, 0x21, 0x64, 0x27, 0xe5, 0xa0, 0xdf, 0xb3,
0x7a, 0x7d, 0x0c, 0x95, 0xbe, 0x09, 0xeb, 0x89, 0x04, 0xd9, 0x8b, 0x1c, 0xb9, 0x05, 0x1b, 0xa9,
0x4c, 0x96, 0xd9, 0x3f, 0xc6, 0xb9, 0x6c, 0xc1, 0x6a, 0x22, 0xb1, 0x63, 0x9a, 0x7d, 0xb3, 0x59,
0x20, 0xdf, 0x81, 0x7b, 0x89, 0x94, 0x34, 0x7f, 0x20, 0xd9, 0x87, 0x22, 0x79, 0x0f, 0xde, 0x4e,
0x61, 0x47, 0x47, 0xa8, 0xb5, 0xdd, 0x3e, 0x60, 0xdd, 0x6b, 0x96, 0xee, 0xff, 0x41, 0x11, 0x20,
0xba, 0x99, 0xca, 0xea, 0xdf, 0x6d, 0x0f, 0xdb, 0x07, 0x7d, 0xb6, 0x67, 0xcc, 0xfe, 0x90, 0x95,
0x6e, 0x76, 0x7e, 0xd8, 0xbc, 0x91, 0x99, 0xd2, 0x3f, 0x62, 0x1d, 0xda, 0x80, 0x15, 0xbe, 0xfe,
0x0e, 0x58, 0x37, 0xd8, 0x72, 0xe1, 0x51, 0xf7, 0x19, 0x13, 0x72, 0x7c, 0xb4, 0x67, 0xf6, 0x7b,
0x43, 0x6b, 0xb0, 0x7f, 0x3c, 0xdc, 0xc5, 0x20, 0xfe, 0x3b, 0x66, 0xf7, 0x88, 0x97, 0x59, 0x7c,
0x19, 0x02, 0x2b, 0xba, 0xc4, 0x36, 0xf8, 0xe3, 0xfe, 0x60, 0xd0, 0x3d, 0xb2, 0x7e, 0x78, 0xdc,
0x31, 0xbb, 0x9d, 0x01, 0x66, 0x5c, 0xc8, 0x80, 0x33, 0xfc, 0x32, 0x5b, 0xb3, 0xc3, 0x83, 0xa7,
0xe2, 0xa0, 0x63, 0xa8, 0x95, 0x38, 0x88, 0x61, 0x55, 0xd9, 0xec, 0xb0, 0xc3, 0x39, 0xa3, 0x64,
0xb8, 0x26, 0x8d, 0xe5, 0xab, 0xb1, 0xa3, 0x34, 0xb5, 0xf3, 0x31, 0x5b, 0x3d, 0x3b, 0x89, 0xe5,
0x42, 0x8e, 0x44, 0xf1, 0x6f, 0xbb, 0xbb, 0x26, 0x66, 0x58, 0x4c, 0x41, 0x19, 0xee, 0x12, 0x5b,
0x84, 0xec, 0xf4, 0x66, 0x28, 0x4d, 0xf9, 0xc1, 0x52, 0x96, 0x59, 0x8f, 0xbf, 0x3a, 0x3e, 0xdc,
0xee, 0x4b, 0x36, 0x80, 0xb7, 0x97, 0x64, 0xc0, 0x19, 0xfe, 0x0a, 0xbe, 0x92, 0xc0, 0xc9, 0x11,
0x22, 0xae, 0xea, 0x00, 0x86, 0xb1, 0xc6, 0x88, 0xa0, 0x04, 0xfc, 0x7c, 0xc7, 0xec, 0x5b, 0x8c,
0xcf, 0x42, 0x1e, 0x91, 0xe1, 0xaf, 0x5f, 0x9f, 0xcc, 0x72, 0x6f, 0x3c, 0xfc, 0xa7, 0x6f, 0x41,
0x55, 0xdd, 0x98, 0x21, 0x3f, 0x80, 0x46, 0x2c, 0x20, 0x05, 0xb9, 0x95, 0x1d, 0xa6, 0x02, 0xa5,
0xa8, 0xcd, 0x37, 0x5e, 0x16, 0xc3, 0x82, 0x1c, 0x6a, 0x8a, 0x0b, 0x5e, 0xd8, 0x1b, 0x49, 0x65,
0x42, 0xac, 0xb4, 0xdb, 0xd7, 0xa4, 0x8a, 0xe2, 0x9e, 0xe0, 0x83, 0x04, 0x18, 0xc0, 0x51, 0x1c,
0x2f, 0xe4, 0x76, 0x14, 0x1d, 0x5e, 0x87, 0xcb, 0x02, 0xa5, 0x98, 0xa8, 0xa5, 0xed, 0xd2, 0xd0,
0x76, 0x26, 0x01, 0xd9, 0x85, 0x9a, 0xf6, 0xc6, 0x2f, 0xb9, 0x79, 0xed, 0x83, 0xc4, 0x9b, 0x9b,
0x59, 0x49, 0xa2, 0x49, 0xdf, 0x83, 0xaa, 0x7a, 0xe3, 0x94, 0x6c, 0x68, 0x6f, 0xf0, 0xea, 0x6f,
0xc3, 0x6e, 0xb6, 0xd2, 0x09, 0x22, 0xff, 0x2e, 0xd4, 0xb4, 0x07, 0x49, 0x55, 0x2b, 0xd2, 0xcf,
0xa1, 0xaa, 0x56, 0x64, 0xbd, 0x5f, 0x7a, 0x00, 0x6b, 0x42, 0x3d, 0x72, 0x42, 0xbf, 0xce, 0xf0,
0x90, 0xf4, 0xf0, 0x3c, 0xc8, 0x91, 0x2f, 0xa1, 0x22, 0x9f, 0xc1, 0x25, 0xeb, 0xd9, 0xcf, 0x0a,
0x6f, 0x6e, 0xa4, 0xe0, 0xa2, 0x29, 0x6d, 0x80, 0xe8, 0x41, 0x53, 0x22, 0x3b, 0x9e, 0x7a, 0x3a,
0x55, 0xcd, 0x4c, 0xc6, 0xeb, 0xa7, 0xbb, 0x50, 0xd3, 0xde, 0x2e, 0x55, 0x63, 0x92, 0x7e, 0xf7,
0x54, 0x8d, 0x49, 0xd6, 0x53, 0xa7, 0x3f, 0x80, 0x46, 0xec, 0x11, 0x52, 0xb5, 0x8e, 0xb3, 0x9e,
0x38, 0x55, 0xeb, 0x38, 0xfb, 0xdd, 0xd2, 0x5d, 0xa8, 0x69, 0x0f, 0x83, 0xaa, 0x16, 0xa5, 0x5f,
0x27, 0x55, 0x2d, 0xca, 0x78, 0x47, 0x94, 0xed, 0x86, 0xf8, 0xab, 0xa0, 0x6a, 0x37, 0x64, 0x3e,
0x2f, 0xaa, 0x76, 0x43, 0xf6, 0x53, 0xa2, 0x6c, 0xe9, 0xa9, 0x97, 0x48, 0xc8, 0x46, 0x4c, 0x2b,
0x11, 0x3d, 0x69, 0xa2, 0x96, 0x5e, 0xfa, 0xd1, 0x92, 0xc7, 0xb0, 0xa2, 0x16, 0x8d, 0x7a, 0x47,
0x24, 0x50, 0x6d, 0xca, 0x7c, 0xad, 0x64, 0xb3, 0x99, 0x4c, 0x7d, 0x90, 0x23, 0x9f, 0x43, 0x59,
0x3c, 0xce, 0x40, 0xd6, 0x92, 0x8f, 0x35, 0xf0, 0x46, 0xac, 0x67, 0xbf, 0xe1, 0x40, 0x8e, 0x70,
0x43, 0xeb, 0xaf, 0x27, 0xe8, 0x2b, 0x36, 0xe3, 0xc1, 0x85, 0xcd, 0x37, 0xaf, 0x4b, 0x8e, 0x4a,
0x4c, 0xbe, 0xf8, 0x71, 0xfb, 0xba, 0xc0, 0x5a, 0xf1, 0x12, 0xaf, 0x8b, 0x00, 0xfa, 0x18, 0xea,
0xfa, 0x8b, 0x70, 0x44, 0xdf, 0x87, 0xc9, 0xb2, 0x6e, 0x65, 0xa6, 0x89, 0x82, 0x9e, 0xc2, 0xba,
0x1a, 0x6f, 0x3d, 0xca, 0x53, 0x40, 0xee, 0x64, 0xc4, 0x7e, 0x8a, 0x8d, 0xfa, 0xcd, 0x6b, 0x83,
0x43, 0x3d, 0xc8, 0x21, 0x91, 0x8d, 0x3d, 0xe2, 0x14, 0x11, 0xd9, 0xac, 0xb7, 0xab, 0x22, 0x22,
0x9b, 0xfd, 0xf2, 0x53, 0x1b, 0x96, 0xb4, 0x28, 0x55, 0x83, 0x2b, 0x77, 0xa4, 0xd6, 0x7b, 0x3a,
0x5c, 0xfd, 0x66, 0x96, 0x92, 0x9e, 0xec, 0x40, 0x4d, 0x0f, 0x74, 0xf5, 0x92, 0xec, 0x1b, 0x5a,
0x92, 0x1e, 0x45, 0xfc, 0x41, 0x8e, 0x1c, 0x40, 0x33, 0x19, 0x96, 0x56, 0x6d, 0xe1, 0xac, 0x50,
0xbe, 0x9b, 0x89, 0xc4, 0x58, 0x30, 0x5b, 0xb6, 0x2e, 0x44, 0xd5, 0xfc, 0xfd, 0x55, 0xcf, 0x4f,
0x1e, 0x45, 0x1c, 0x2e, 0x87, 0x41, 0x95, 0x96, 0x48, 0xc5, 0x66, 0xdf, 0xcb, 0x3d, 0xc8, 0x91,
0x3d, 0xa8, 0xc7, 0xa2, 0x32, 0xc6, 0x2e, 0x6f, 0x25, 0xba, 0xd9, 0xd2, 0xd3, 0x12, 0xfd, 0x3c,
0x84, 0xc5, 0xb8, 0xd3, 0x89, 0x6a, 0x58, 0xa6, 0x67, 0x8c, 0x9a, 0xbe, 0x6c, 0x4f, 0x15, 0xf2,
0xb3, 0x50, 0x63, 0x34, 0x59, 0x7a, 0x46, 0x12, 0x8d, 0x4e, 0x27, 0xe7, 0x8c, 0xc3, 0x84, 0xd6,
0xbc, 0xf0, 0x17, 0xf3, 0x39, 0xec, 0xd7, 0x77, 0xf9, 0x8b, 0xf3, 0xd2, 0x39, 0x8e, 0xcd, 0xff,
0xeb, 0x16, 0x42, 0xf6, 0x78, 0xe5, 0x43, 0x8f, 0xc7, 0x64, 0xb8, 0xa9, 0xe1, 0x08, 0xd8, 0xeb,
0xb5, 0xa1, 0xcd, 0xdb, 0x20, 0xf2, 0xc4, 0xd6, 0xe0, 0x6b, 0x96, 0x45, 0x3e, 0x03, 0x88, 0x9c,
0x92, 0x49, 0xc2, 0xef, 0x55, 0x6d, 0xa8, 0x0c, 0xbf, 0xe5, 0x0e, 0xdf, 0xef, 0xca, 0xf1, 0x56,
0x3f, 0x92, 0xe3, 0x3e, 0xc0, 0xb1, 0x23, 0x39, 0x59, 0xcc, 0xc7, 0xd0, 0x38, 0xf0, 0xbc, 0xe7,
0xf3, 0x99, 0xba, 0xaa, 0x13, 0x77, 0xfb, 0xda, 0xb7, 0x83, 0xf3, 0xcd, 0x44, 0xb3, 0x48, 0x1b,
0x96, 0x15, 0x89, 0x88, 0x3c, 0x7f, 0xe3, 0x48, 0x31, 0xc2, 0x90, 0x28, 0xe0, 0x41, 0x8e, 0x3c,
0x84, 0xfa, 0x2e, 0x1d, 0x61, 0xdc, 0x18, 0x74, 0x03, 0x5a, 0x89, 0xb9, 0x94, 0x70, 0xff, 0xa1,
0xcd, 0x46, 0x0c, 0x28, 0x49, 0x5c, 0xe4, 0xe8, 0xa6, 0x9f, 0x19, 0x71, 0x6f, 0xb1, 0x18, 0x89,
0x4b, 0x39, 0xbb, 0x3d, 0x85, 0xe5, 0x94, 0xb3, 0x97, 0xa2, 0x6e, 0xd7, 0x39, 0xa0, 0x6d, 0xde,
0xbd, 0x1e, 0x41, 0x94, 0xfb, 0x7d, 0x68, 0xf0, 0xa0, 0xf2, 0x27, 0x94, 0xdf, 0xfb, 0x4e, 0x84,
0x0c, 0xd4, 0x2f, 0x95, 0x27, 0x49, 0x12, 0xcf, 0xf0, 0x18, 0x9f, 0xb7, 0xd2, 0x6e, 0x55, 0xab,
0x79, 0x4d, 0xdf, 0xf4, 0x56, 0xf3, 0x9a, 0x75, 0x81, 0xfb, 0x0b, 0xa8, 0x3d, 0xa6, 0xa1, 0xbc,
0xa7, 0xac, 0xf8, 0xa3, 0xc4, 0xc5, 0xe5, 0xcd, 0x8c, 0xdb, 0xe5, 0xe4, 0x53, 0xcc, 0xaa, 0x62,
0x6e, 0xac, 0x6b, 0xb5, 0xe8, 0x59, 0x97, 0x12, 0x70, 0xc6, 0x7d, 0x68, 0x91, 0x77, 0x54, 0xc3,
0xd3, 0x91, 0x96, 0x54, 0xc3, 0xb3, 0x02, 0xf5, 0xfc, 0x2c, 0x1f, 0x01, 0xed, 0x66, 0x74, 0xc4,
0x82, 0x25, 0x2f, 0x51, 0xab, 0xe6, 0xeb, 0xe8, 0x8f, 0x00, 0x06, 0xa1, 0x37, 0xdb, 0xb5, 0xe9,
0xd4, 0x73, 0x23, 0x9a, 0x10, 0xdd, 0xc9, 0x8d, 0x36, 0xa2, 0x76, 0x31, 0x97, 0x7c, 0xa5, 0xf1,
0xa6, 0xb1, 0x29, 0x91, 0xd3, 0x7e, 0xed, 0xb5, 0x5d, 0xd5, 0x9d, 0x8c, 0xab, 0xbb, 0x48, 0x24,
0x20, 0xf2, 0xa5, 0x53, 0x9c, 0x66, 0xca, 0x4d, 0x4f, 0xed, 0xf5, 0x0c, 0xc7, 0xbb, 0xef, 0x41,
0x35, 0x72, 0x42, 0xda, 0x88, 0xc2, 0x80, 0xc5, 0x5c, 0x96, 0x14, 0xf5, 0x4e, 0x3b, 0x00, 0xf5,
0x60, 0x85, 0x37, 0x47, 0x1d, 0x7f, 0x78, 0x57, 0x53, 0xbd, 0xce, 0x96, 0xf6, 0xbc, 0x51, 0xfb,
0x27, 0xcb, 0x7f, 0x84, 0xed, 0x9f, 0x94, 0x83, 0x81, 0xda, 0x3f, 0xd7, 0x39, 0x96, 0xa8, 0xfd,
0x73, 0xbd, 0x6f, 0x42, 0x0f, 0x56, 0x32, 0x5c, 0x05, 0xc8, 0x5b, 0x52, 0xb0, 0xb9, 0xd6, 0x8d,
0x60, 0x33, 0xd3, 0xa4, 0x4c, 0x86, 0xb0, 0xc1, 0xf3, 0xb4, 0x27, 0x93, 0x84, 0x65, 0xfa, 0x4d,
0x2d, 0x43, 0x86, 0xb5, 0x3d, 0xc6, 0xca, 0x24, 0x2c, 0xee, 0x3d, 0x68, 0x26, 0x8d, 0xba, 0xe4,
0x7a, 0xf4, 0xcd, 0x3b, 0x31, 0x96, 0x3d, 0x6d, 0x08, 0x26, 0x4f, 0x95, 0x69, 0x39, 0xd1, 0xc6,
0x3b, 0xd1, 0x2b, 0xa3, 0x99, 0x86, 0x70, 0x25, 0x0d, 0x64, 0x5a, 0xa6, 0xc9, 0xcf, 0xc1, 0x46,
0x72, 0x45, 0xcb, 0x92, 0xef, 0x66, 0x0d, 0xd7, 0xb5, 0xac, 0x5c, 0xbc, 0x43, 0x0f, 0x72, 0x8c,
0x10, 0xeb, 0x06, 0x60, 0xb5, 0x90, 0x32, 0x2c, 0xd1, 0x6a, 0x21, 0x65, 0x5a, 0x8c, 0x8f, 0x60,
0x29, 0x61, 0xfb, 0x55, 0x6c, 0x70, 0xb6, 0xb5, 0x58, 0xb1, 0xc1, 0xd7, 0x99, 0x8c, 0x07, 0xd0,
0x4c, 0x5a, 0x75, 0xd5, 0x5c, 0x5f, 0x63, 0x29, 0xde, 0xbc, 0x73, 0x6d, 0x7a, 0xbc, 0x99, 0x9a,
0xfd, 0x33, 0xd6, 0xcc, 0xb4, 0xd5, 0x36, 0xd6, 0xcc, 0x0c, 0xeb, 0xeb, 0xf6, 0x7b, 0x3f, 0xff,
0xad, 0x33, 0x27, 0x3c, 0x9f, 0x9f, 0x6c, 0x8d, 0xbc, 0xe9, 0x87, 0x13, 0xa9, 0xd5, 0x10, 0x81,
0x14, 0x3e, 0x9c, 0xb8, 0xe3, 0x0f, 0xb1, 0x80, 0x93, 0x85, 0x99, 0xef, 0x85, 0xde, 0xc7, 0xff,
0x37, 0x00, 0x00, 0xff, 0xff, 0xe1, 0xea, 0x86, 0x7c, 0x00, 0x95, 0x00, 0x00,
// 12707 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x7d, 0x5b, 0x6c, 0x23, 0x59,
0x76, 0x58, 0xf3, 0x25, 0x92, 0x87, 0xa4, 0x44, 0x5d, 0xbd, 0xd8, 0xea, 0xe9, 0xe9, 0x9e, 0x9a,
0xd9, 0x99, 0xde, 0x9e, 0x19, 0x4d, 0x4f, 0xcf, 0xf4, 0x3c, 0x76, 0xe2, 0xf5, 0x52, 0x12, 0xd5,
0xe2, 0xb6, 0x44, 0x6a, 0x8b, 0xd4, 0x8c, 0xdb, 0xb0, 0x5d, 0x2e, 0x91, 0x57, 0x52, 0xa5, 0xc9,
0x2a, 0x6e, 0x55, 0x51, 0x2d, 0x6d, 0x10, 0xc0, 0x1f, 0x8e, 0x1d, 0x18, 0x4e, 0x80, 0x00, 0x71,
0x80, 0x20, 0x31, 0x92, 0x20, 0x41, 0xf2, 0x67, 0x18, 0xb0, 0xfd, 0x95, 0x7c, 0xe4, 0x2b, 0x41,
0x80, 0x04, 0x41, 0x80, 0x18, 0x79, 0x7c, 0x24, 0x08, 0x90, 0x38, 0x40, 0x0c, 0x24, 0x06, 0xfc,
0x99, 0x04, 0x09, 0xee, 0xb9, 0x8f, 0xba, 0xf5, 0x50, 0x77, 0xcf, 0xee, 0x78, 0x7f, 0x24, 0xd6,
0xb9, 0xe7, 0xbe, 0xef, 0x3d, 0xf7, 0xbc, 0xee, 0xb9, 0x50, 0xf5, 0x67, 0xa3, 0xad, 0x99, 0xef,
0x85, 0x1e, 0x29, 0x4d, 0x5c, 0x7f, 0x36, 0x32, 0xfe, 0x28, 0x07, 0xc5, 0xe3, 0xf0, 0xd2, 0x23,
0x8f, 0xa0, 0x6e, 0x8f, 0xc7, 0x3e, 0x0d, 0x02, 0x2b, 0xbc, 0x9a, 0xd1, 0x56, 0xee, 0x6e, 0xee,
0xde, 0xe2, 0x43, 0xb2, 0x85, 0x68, 0x5b, 0x6d, 0x9e, 0x34, 0xbc, 0x9a, 0x51, 0xb3, 0x66, 0x47,
0x1f, 0xa4, 0x05, 0x65, 0xf1, 0xd9, 0xca, 0xdf, 0xcd, 0xdd, 0xab, 0x9a, 0xf2, 0x93, 0xdc, 0x06,
0xb0, 0xa7, 0xde, 0xdc, 0x0d, 0xad, 0xc0, 0x0e, 0x5b, 0x85, 0xbb, 0xb9, 0x7b, 0x05, 0xb3, 0xca,
0x21, 0x03, 0x3b, 0x24, 0xb7, 0xa0, 0x3a, 0x7b, 0x66, 0x05, 0x23, 0xdf, 0x99, 0x85, 0xad, 0x22,
0x66, 0xad, 0xcc, 0x9e, 0x0d, 0xf0, 0x9b, 0xbc, 0x0b, 0x15, 0x6f, 0x1e, 0xce, 0x3c, 0xc7, 0x0d,
0x5b, 0xa5, 0xbb, 0xb9, 0x7b, 0xb5, 0x87, 0x4b, 0xa2, 0x21, 0xfd, 0x79, 0x78, 0xc4, 0xc0, 0xa6,
0x42, 0x20, 0x6f, 0x41, 0x63, 0xe4, 0xb9, 0xa7, 0x8e, 0x3f, 0xb5, 0x43, 0xc7, 0x73, 0x83, 0xd6,
0x02, 0xd6, 0x15, 0x07, 0x1a, 0xff, 0x2c, 0x0f, 0xb5, 0xa1, 0x6f, 0xbb, 0x81, 0x3d, 0x62, 0x00,
0xb2, 0x01, 0xe5, 0xf0, 0xd2, 0x3a, 0xb7, 0x83, 0x73, 0xec, 0x6a, 0xd5, 0x5c, 0x08, 0x2f, 0xf7,
0xed, 0xe0, 0x9c, 0xac, 0xc3, 0x02, 0x6f, 0x25, 0x76, 0xa8, 0x60, 0x8a, 0x2f, 0xf2, 0x2e, 0x2c,
0xbb, 0xf3, 0xa9, 0x15, 0xaf, 0x8a, 0x75, 0xab, 0x64, 0x36, 0xdd, 0xf9, 0x74, 0x47, 0x87, 0xb3,
0xce, 0x9f, 0x4c, 0xbc, 0xd1, 0x33, 0x5e, 0x01, 0xef, 0x5e, 0x15, 0x21, 0x58, 0xc7, 0x1b, 0x50,
0x17, 0xc9, 0xd4, 0x39, 0x3b, 0xe7, 0x7d, 0x2c, 0x99, 0x35, 0x8e, 0x80, 0x20, 0x56, 0x42, 0xe8,
0x4c, 0xa9, 0x15, 0x84, 0xf6, 0x74, 0x26, 0xba, 0x54, 0x65, 0x90, 0x01, 0x03, 0x60, 0xb2, 0x17,
0xda, 0x13, 0xeb, 0x94, 0xd2, 0xa0, 0x55, 0x16, 0xc9, 0x0c, 0xb2, 0x47, 0x69, 0x40, 0xbe, 0x05,
0x8b, 0x63, 0x1a, 0x84, 0x96, 0x98, 0x0c, 0x1a, 0xb4, 0x2a, 0x77, 0x0b, 0xf7, 0xaa, 0x66, 0x83,
0x41, 0xdb, 0x12, 0x48, 0x5e, 0x03, 0xf0, 0xed, 0xe7, 0x16, 0x1b, 0x08, 0x7a, 0xd9, 0xaa, 0xf2,
0x59, 0xf0, 0xed, 0xe7, 0xc3, 0xcb, 0x7d, 0x7a, 0x49, 0x56, 0xa1, 0x34, 0xb1, 0x4f, 0xe8, 0xa4,
0x05, 0x98, 0xc0, 0x3f, 0x8c, 0x10, 0xd6, 0x1f, 0xd3, 0x50, 0x1b, 0xca, 0xc0, 0xa4, 0x3f, 0x9c,
0xd3, 0x20, 0x64, 0xbd, 0x0a, 0x42, 0xdb, 0x0f, 0x65, 0xaf, 0x72, 0xbc, 0x57, 0x08, 0x8b, 0x7a,
0x45, 0xdd, 0xb1, 0x44, 0xc8, 0x23, 0x42, 0x95, 0xba, 0x63, 0x91, 0xcc, 0x56, 0xd3, 0x68, 0x84,
0x83, 0x5f, 0x10, 0xab, 0x89, 0x7f, 0x1a, 0x07, 0x40, 0xb4, 0x2a, 0x77, 0x69, 0x68, 0x3b, 0x93,
0x80, 0x7c, 0x02, 0xf5, 0x50, 0x6b, 0x48, 0x2b, 0x77, 0xb7, 0x70, 0xaf, 0xa6, 0x16, 0xad, 0x96,
0xc1, 0x8c, 0xe1, 0x19, 0xe7, 0x50, 0xd9, 0xa3, 0xf4, 0xc0, 0x99, 0x3a, 0x21, 0x59, 0x87, 0xd2,
0xa9, 0x73, 0x49, 0xc7, 0xd8, 0xdc, 0xc2, 0xfe, 0x0d, 0x93, 0x7f, 0x92, 0x3b, 0x00, 0xf8, 0xc3,
0x9a, 0xaa, 0xf5, 0xbb, 0x7f, 0xc3, 0xac, 0x22, 0xec, 0x30, 0xb0, 0x43, 0xb2, 0x09, 0xe5, 0x19,
0xf5, 0x47, 0x54, 0xae, 0x94, 0xfd, 0x1b, 0xa6, 0x04, 0x6c, 0x97, 0xa1, 0x34, 0x61, 0xa5, 0x1b,
0xff, 0xa3, 0x04, 0xb5, 0x01, 0x75, 0xc7, 0x72, 0x8c, 0x08, 0x14, 0xd9, 0x14, 0x60, 0x65, 0x75,
0x13, 0x7f, 0x93, 0x37, 0xa1, 0x86, 0x93, 0x15, 0x84, 0xbe, 0xe3, 0x9e, 0xf1, 0x7d, 0xb4, 0x9d,
0x6f, 0xe5, 0x4c, 0x60, 0xe0, 0x01, 0x42, 0x49, 0x13, 0x0a, 0xf6, 0x54, 0xee, 0x23, 0xf6, 0x93,
0xdc, 0x84, 0x8a, 0x3d, 0x0d, 0x79, 0xf3, 0xea, 0x08, 0x2e, 0xdb, 0xd3, 0x10, 0x9b, 0xf6, 0x06,
0xd4, 0x67, 0xf6, 0xd5, 0x94, 0xba, 0x61, 0xb4, 0x00, 0xeb, 0x66, 0x4d, 0xc0, 0x70, 0x09, 0x3e,
0x84, 0x15, 0x1d, 0x45, 0x56, 0x5e, 0x52, 0x95, 0x2f, 0x6b, 0xd8, 0xa2, 0x0d, 0xef, 0xc0, 0x92,
0xcc, 0xe3, 0xf3, 0xfe, 0xe0, 0xc2, 0xac, 0x9a, 0x8b, 0x02, 0x2c, 0x7b, 0x79, 0x0f, 0x9a, 0xa7,
0x8e, 0x6b, 0x4f, 0xac, 0xd1, 0x24, 0xbc, 0xb0, 0xc6, 0x74, 0x12, 0xda, 0xb8, 0x46, 0x4b, 0xe6,
0x22, 0xc2, 0x77, 0x26, 0xe1, 0xc5, 0x2e, 0x83, 0x92, 0xf7, 0xa0, 0x7a, 0x4a, 0xa9, 0x85, 0x83,
0xd5, 0xaa, 0xc4, 0xb6, 0xba, 0x9c, 0x21, 0xb3, 0x72, 0x2a, 0xe7, 0xea, 0x3d, 0x68, 0x7a, 0xf3,
0xf0, 0xcc, 0x73, 0xdc, 0x33, 0x6b, 0x74, 0x6e, 0xbb, 0x96, 0x33, 0xc6, 0x55, 0x5b, 0xdc, 0xce,
0x3f, 0xc8, 0x99, 0x8b, 0x32, 0x6d, 0xe7, 0xdc, 0x76, 0xbb, 0x63, 0xf2, 0x36, 0x2c, 0x4d, 0xec,
0x20, 0xb4, 0xce, 0xbd, 0x99, 0x35, 0x9b, 0x9f, 0x3c, 0xa3, 0x57, 0xad, 0x06, 0x0e, 0x44, 0x83,
0x81, 0xf7, 0xbd, 0xd9, 0x11, 0x02, 0xd9, 0xa2, 0xc4, 0x76, 0xf2, 0x46, 0xb0, 0xc5, 0xde, 0x30,
0xab, 0x0c, 0xc2, 0x2b, 0x7d, 0x0a, 0x2b, 0x38, 0x3d, 0xa3, 0x79, 0x10, 0x7a, 0x53, 0xcb, 0xa7,
0x23, 0xcf, 0x1f, 0x07, 0xad, 0x1a, 0xae, 0xb5, 0x6f, 0x8b, 0xc6, 0x6a, 0x73, 0xbc, 0xb5, 0x4b,
0x83, 0x70, 0x07, 0x91, 0x4d, 0x8e, 0xdb, 0x71, 0x43, 0xff, 0xca, 0x5c, 0x1e, 0x27, 0xe1, 0xe4,
0x3d, 0x20, 0xf6, 0x64, 0xe2, 0x3d, 0xb7, 0x02, 0x3a, 0x39, 0xb5, 0xc4, 0x20, 0xb6, 0x16, 0xef,
0xe6, 0xee, 0x55, 0xcc, 0x26, 0xa6, 0x0c, 0xe8, 0xe4, 0xf4, 0x88, 0xc3, 0xc9, 0x27, 0x80, 0xdb,
0xd7, 0x3a, 0xa5, 0x76, 0x38, 0xf7, 0x69, 0xd0, 0x5a, 0xba, 0x5b, 0xb8, 0xb7, 0xf8, 0x70, 0x59,
0x8d, 0x17, 0x82, 0xb7, 0x9d, 0xd0, 0xac, 0x33, 0x3c, 0xf1, 0x1d, 0xe8, 0xab, 0x81, 0xd1, 0x83,
0x56, 0x33, 0xb6, 0x1a, 0x18, 0x35, 0xd8, 0xdc, 0x85, 0xf5, 0xec, 0x56, 0xb3, 0x75, 0xc7, 0x06,
0x8e, 0xad, 0xd7, 0xa2, 0xc9, 0x7e, 0x32, 0xb2, 0x70, 0x61, 0x4f, 0xe6, 0x14, 0x17, 0x6a, 0xdd,
0xe4, 0x1f, 0xdf, 0xc9, 0x7f, 0x96, 0x33, 0x7e, 0x3f, 0x07, 0x75, 0x3e, 0x10, 0xc1, 0xcc, 0x73,
0x03, 0x4a, 0xde, 0x84, 0x86, 0xac, 0x99, 0xfa, 0xbe, 0xe7, 0x0b, 0x52, 0x2b, 0x9b, 0xd3, 0x61,
0x30, 0xf2, 0x6d, 0x68, 0x4a, 0xa4, 0x99, 0x4f, 0x9d, 0xa9, 0x7d, 0x26, 0x8b, 0x96, 0xab, 0xed,
0x48, 0x80, 0xc9, 0x87, 0x51, 0x79, 0xbe, 0x37, 0x0f, 0x29, 0x6e, 0x87, 0xda, 0xc3, 0xba, 0x18,
0x01, 0x93, 0xc1, 0x54, 0xe9, 0xf8, 0xf5, 0x0a, 0x5b, 0xc1, 0xf8, 0xad, 0x1c, 0x10, 0xd6, 0xec,
0xa1, 0xc7, 0x0b, 0x88, 0xc8, 0x59, 0x2c, 0x67, 0xee, 0x95, 0x37, 0x51, 0xfe, 0x45, 0x9b, 0xc8,
0x80, 0x12, 0x6f, 0x7b, 0x31, 0xa3, 0xed, 0x3c, 0xe9, 0xfb, 0xc5, 0x4a, 0xa1, 0x59, 0x34, 0xfe,
0x63, 0x01, 0x56, 0xd9, 0x52, 0x76, 0xe9, 0xa4, 0x3d, 0x1a, 0xd1, 0x99, 0xda, 0x5e, 0x77, 0xa0,
0xe6, 0x7a, 0x63, 0x2a, 0x17, 0x35, 0x6f, 0x18, 0x30, 0x90, 0xb6, 0xa2, 0xcf, 0x6d, 0xc7, 0xe5,
0x0d, 0xe7, 0x83, 0x59, 0x45, 0x08, 0x36, 0xfb, 0x6d, 0x58, 0x9a, 0x51, 0x77, 0xac, 0xef, 0xa2,
0x02, 0xdf, 0x18, 0x02, 0x2c, 0x36, 0xd0, 0x1d, 0xa8, 0x9d, 0xce, 0x39, 0x1e, 0xa3, 0x3d, 0x45,
0x5c, 0x03, 0x20, 0x40, 0x6d, 0x4e, 0x82, 0x66, 0xf3, 0xe0, 0x1c, 0x53, 0x4b, 0x98, 0x5a, 0x66,
0xdf, 0x2c, 0xe9, 0x36, 0xc0, 0x78, 0x1e, 0x84, 0x62, 0x53, 0x2d, 0x60, 0x62, 0x95, 0x41, 0xf8,
0xa6, 0x7a, 0x1f, 0x56, 0xa6, 0xf6, 0xa5, 0x85, 0x6b, 0xc7, 0x72, 0x5c, 0xeb, 0x74, 0x82, 0x27,
0x42, 0x19, 0xf1, 0x9a, 0x53, 0xfb, 0xf2, 0x4b, 0x96, 0xd2, 0x75, 0xf7, 0x10, 0xce, 0x28, 0xcf,
0x88, 0x8f, 0x84, 0xe5, 0xd3, 0x80, 0xfa, 0x17, 0x14, 0x89, 0x45, 0xd1, 0x5c, 0x14, 0x60, 0x93,
0x43, 0x59, 0x8b, 0xa6, 0xac, 0xdf, 0xe1, 0x64, 0xc4, 0x29, 0x83, 0x59, 0x9e, 0x3a, 0xee, 0x7e,
0x38, 0x19, 0xb1, 0xc3, 0x8e, 0x91, 0x9a, 0x19, 0xf5, 0xad, 0x67, 0xcf, 0x71, 0x9b, 0x17, 0x91,
0xb4, 0x1c, 0x51, 0xff, 0xc9, 0x73, 0xc6, 0x8f, 0x8c, 0x02, 0xa4, 0x55, 0xf6, 0x55, 0xab, 0x86,
0x34, 0xa0, 0x32, 0x0a, 0x18, 0x95, 0xb2, 0xaf, 0xd8, 0x3e, 0x65, 0xad, 0xb5, 0x71, 0x16, 0xe8,
0x18, 0x8b, 0x0f, 0x90, 0xe8, 0x36, 0xb0, 0xb1, 0x6d, 0x91, 0xc0, 0xea, 0x09, 0xd8, 0xaa, 0x97,
0x8d, 0x3d, 0x9d, 0xd8, 0x67, 0x01, 0x52, 0x9d, 0x86, 0x59, 0x17, 0xc0, 0x3d, 0x06, 0x33, 0xfe,
0x34, 0x0f, 0x6b, 0x89, 0xc9, 0x15, 0x9b, 0x86, 0x31, 0x20, 0x08, 0xc1, 0x89, 0xad, 0x98, 0xe2,
0x2b, 0x6b, 0xd6, 0xf2, 0x59, 0xb3, 0xb6, 0x0a, 0x25, 0xbe, 0xd9, 0xf8, 0x11, 0xca, 0x3f, 0xd8,
0x2e, 0x9b, 0xcf, 0x4e, 0x7d, 0x8f, 0xf1, 0x63, 0xe7, 0xf3, 0x70, 0xec, 0x3d, 0x77, 0x05, 0x5f,
0xb2, 0x24, 0xe0, 0x03, 0x01, 0x8e, 0x0f, 0x45, 0x29, 0x31, 0x14, 0x77, 0xa0, 0x26, 0x66, 0x00,
0xf9, 0x3a, 0x3e, 0xb1, 0x20, 0x40, 0x8c, 0xb1, 0x7b, 0x17, 0x88, 0x9a, 0x4f, 0x8b, 0x8d, 0x1a,
0x1e, 0x50, 0x7c, 0x62, 0x97, 0x1c, 0x31, 0xa1, 0x87, 0xf6, 0x25, 0x1e, 0x54, 0x6f, 0xc1, 0x22,
0x43, 0x61, 0xe3, 0x69, 0xf1, 0x73, 0xbf, 0xc2, 0xc7, 0x6a, 0x6a, 0x5f, 0xb2, 0xc1, 0xdc, 0x41,
0xd6, 0xeb, 0x75, 0xa8, 0xc9, 0x49, 0xb5, 0x1c, 0x57, 0xcc, 0x6b, 0x55, 0xcc, 0x6b, 0xd7, 0x65,
0xc7, 0x0d, 0x4b, 0xe7, 0xe3, 0x64, 0x8d, 0xe9, 0x2c, 0x3c, 0x17, 0x64, 0x7c, 0x71, 0xea, 0xb8,
0x7c, 0x78, 0x77, 0x19, 0xd4, 0xf8, 0xed, 0x1c, 0xd4, 0xc5, 0xa8, 0x23, 0x1b, 0x49, 0xb6, 0x80,
0xc8, 0x25, 0x1e, 0x5e, 0x3a, 0x63, 0xeb, 0xe4, 0x2a, 0xa4, 0x01, 0xdf, 0x51, 0xfb, 0x37, 0xcc,
0xa6, 0x48, 0x1b, 0x5e, 0x3a, 0xe3, 0x6d, 0x96, 0x42, 0xee, 0x43, 0x33, 0x86, 0x1f, 0x84, 0x3e,
0xdf, 0xee, 0xfb, 0x37, 0xcc, 0x45, 0x0d, 0x7b, 0x10, 0xfa, 0x8c, 0x80, 0x30, 0x26, 0x75, 0x1e,
0x5a, 0x8e, 0x3b, 0xa6, 0x97, 0x38, 0x1f, 0x0d, 0xb3, 0xc6, 0x61, 0x5d, 0x06, 0xda, 0x5e, 0x84,
0xba, 0x5e, 0x9c, 0x71, 0x06, 0x15, 0xc9, 0xe1, 0x22, 0x8b, 0x97, 0x68, 0x92, 0x59, 0x0d, 0x55,
0x4b, 0x6e, 0x42, 0x25, 0xde, 0x02, 0xb3, 0x1c, 0xbe, 0x72, 0xc5, 0xc6, 0x77, 0xa1, 0x79, 0xc0,
0x26, 0xc2, 0x65, 0x3b, 0x59, 0x70, 0xec, 0xeb, 0xb0, 0xa0, 0x51, 0x94, 0xaa, 0x29, 0xbe, 0x18,
0xcf, 0x72, 0xee, 0x05, 0xa1, 0xa8, 0x05, 0x7f, 0x1b, 0xff, 0x3c, 0x07, 0xa4, 0x13, 0x84, 0xce,
0xd4, 0x0e, 0xe9, 0x1e, 0x55, 0x34, 0xb3, 0x0f, 0x75, 0x56, 0xda, 0xd0, 0x6b, 0x73, 0x16, 0x9a,
0x33, 0x64, 0xef, 0x0a, 0x1a, 0x97, 0xce, 0xb0, 0xa5, 0x63, 0xf3, 0x63, 0x32, 0x56, 0x00, 0x5b,
0x6e, 0xa1, 0xed, 0x9f, 0xd1, 0x10, 0x19, 0x6f, 0xc1, 0x31, 0x02, 0x07, 0x31, 0x96, 0x7b, 0xf3,
0x67, 0x61, 0x39, 0x55, 0x86, 0x7e, 0x68, 0x55, 0x33, 0x0e, 0xad, 0x82, 0x7e, 0x68, 0xfd, 0x7a,
0x0e, 0x56, 0x62, 0x0d, 0x13, 0xdb, 0x70, 0x03, 0xca, 0x8c, 0x5c, 0xb0, 0xc5, 0x9b, 0xe3, 0x82,
0xc0, 0x29, 0xc5, 0x05, 0xfe, 0x11, 0xac, 0x9e, 0x52, 0xea, 0xdb, 0x21, 0x26, 0x22, 0x3d, 0x61,
0x53, 0xc4, 0x4b, 0xe6, 0x54, 0x5f, 0xa4, 0x0f, 0xec, 0xf0, 0x88, 0xfa, 0x6c, 0xba, 0x88, 0x01,
0x0d, 0x89, 0x7c, 0x81, 0xd8, 0x05, 0x5c, 0xc4, 0xb5, 0x00, 0x51, 0xbe, 0x64, 0x20, 0xe3, 0x8f,
0xf3, 0xb0, 0xc4, 0xce, 0xa1, 0x43, 0xdb, 0xbd, 0x92, 0x03, 0x7a, 0x90, 0x39, 0xa0, 0xf7, 0x34,
0xae, 0x43, 0xc3, 0xfe, 0xba, 0xa3, 0x59, 0x48, 0x8e, 0x66, 0xba, 0x99, 0xc5, 0x54, 0x33, 0xc9,
0x5b, 0x50, 0x8f, 0xf5, 0xbb, 0xa4, 0xfa, 0x0d, 0x41, 0xd4, 0x61, 0x25, 0x3c, 0x2c, 0x68, 0xc2,
0x03, 0x23, 0x2d, 0x6c, 0xa7, 0xb2, 0xda, 0x03, 0xc1, 0x11, 0x32, 0x7a, 0xcd, 0xea, 0x0e, 0x98,
0x84, 0x15, 0x30, 0x52, 0x66, 0xcd, 0x5d, 0x21, 0x65, 0xd1, 0x31, 0xd2, 0x83, 0x8a, 0xd9, 0xc4,
0x84, 0xe3, 0x08, 0xfe, 0x93, 0xcf, 0xfb, 0xdb, 0xd0, 0x8c, 0x86, 0x4f, 0xcc, 0x39, 0x81, 0x22,
0xdb, 0x43, 0xa2, 0x00, 0xfc, 0x6d, 0xfc, 0x83, 0x3c, 0x47, 0xdc, 0xf1, 0x9c, 0x48, 0xd4, 0x21,
0x50, 0x44, 0x56, 0x4a, 0x20, 0xb2, 0xdf, 0xd7, 0x0a, 0x8e, 0x3f, 0xc5, 0x41, 0xbf, 0x09, 0x95,
0x80, 0x0d, 0xa0, 0x3d, 0xe1, 0xe3, 0x5e, 0x31, 0xcb, 0xec, 0xbb, 0x3d, 0x99, 0x44, 0xf3, 0x51,
0xbe, 0x76, 0x3e, 0x2a, 0xaf, 0x32, 0x1f, 0xd5, 0xec, 0xf9, 0x30, 0xde, 0x81, 0x65, 0x6d, 0x94,
0x5e, 0x30, 0x9e, 0xe7, 0x40, 0x0e, 0x9c, 0x20, 0x3c, 0x76, 0x59, 0x11, 0x8a, 0xa5, 0x89, 0x35,
0x24, 0x97, 0x68, 0x08, 0x4b, 0xb4, 0x2f, 0x45, 0x62, 0x5e, 0x24, 0xda, 0x97, 0x3c, 0xf1, 0x7a,
0x99, 0xf1, 0x33, 0x58, 0x89, 0xd5, 0x24, 0x1a, 0xf5, 0x06, 0x94, 0xe6, 0xe1, 0xa5, 0x27, 0xa5,
0xc5, 0x9a, 0xd8, 0x4b, 0xc7, 0xe1, 0xa5, 0x67, 0xf2, 0x14, 0xe3, 0x18, 0x96, 0x7b, 0xf4, 0xb9,
0xa0, 0x8b, 0xb2, 0x89, 0x6f, 0x43, 0xf1, 0x25, 0x9a, 0x11, 0x4c, 0xd7, 0x1b, 0x94, 0x8f, 0x37,
0x68, 0x0b, 0x88, 0x5e, 0xac, 0x68, 0x8f, 0xa6, 0x42, 0xc9, 0xc5, 0x54, 0x28, 0xc6, 0xdb, 0x40,
0x06, 0xce, 0x99, 0x7b, 0x48, 0x83, 0xc0, 0x3e, 0x53, 0x34, 0xb6, 0x09, 0x85, 0x69, 0x70, 0x26,
0x0e, 0x04, 0xf6, 0xd3, 0xf8, 0x08, 0x56, 0x62, 0x78, 0xa2, 0xe0, 0xd7, 0xa0, 0x1a, 0x38, 0x67,
0x2e, 0x4a, 0x01, 0xa2, 0xe8, 0x08, 0x60, 0xec, 0xc1, 0xea, 0x97, 0xd4, 0x77, 0x4e, 0xaf, 0x5e,
0x56, 0x7c, 0xbc, 0x9c, 0x7c, 0xb2, 0x9c, 0x0e, 0xac, 0x25, 0xca, 0x11, 0xd5, 0xf3, 0xad, 0x27,
0x66, 0xbf, 0x62, 0xf2, 0x0f, 0xed, 0x90, 0xc9, 0xeb, 0x87, 0x8c, 0xe1, 0x01, 0xd9, 0xf1, 0x5c,
0x97, 0x8e, 0xc2, 0x23, 0x4a, 0x7d, 0xd9, 0x98, 0x77, 0xb5, 0x7d, 0x56, 0x7b, 0xb8, 0x21, 0xc6,
0x3c, 0x79, 0x72, 0x89, 0x0d, 0x48, 0xa0, 0x38, 0xa3, 0xfe, 0x14, 0x0b, 0xae, 0x98, 0xf8, 0x9b,
0x0d, 0x6e, 0xe8, 0x4c, 0xa9, 0x37, 0x0f, 0x05, 0xc5, 0x95, 0x9f, 0xc6, 0x1a, 0xac, 0xc4, 0x2a,
0xe4, 0xad, 0x36, 0x1e, 0xc0, 0xda, 0xae, 0x13, 0x8c, 0xd2, 0x4d, 0xd9, 0x80, 0xf2, 0x6c, 0x7e,
0x62, 0xc5, 0x8f, 0xc7, 0x27, 0xf4, 0xca, 0x68, 0xc1, 0x7a, 0x32, 0x87, 0x28, 0xeb, 0xd7, 0xf2,
0x50, 0xdc, 0x1f, 0x1e, 0xec, 0x90, 0x4d, 0xa8, 0x38, 0xee, 0xc8, 0x9b, 0x32, 0xe1, 0x80, 0x8f,
0x86, 0xfa, 0xbe, 0x96, 0x6c, 0xdc, 0x82, 0x2a, 0xca, 0x14, 0x13, 0x6f, 0xf4, 0x4c, 0xb0, 0xe7,
0x15, 0x06, 0x38, 0xf0, 0x46, 0xcf, 0xd8, 0xd6, 0xa4, 0x97, 0x33, 0xc7, 0x47, 0x75, 0x93, 0x54,
0xa7, 0x14, 0x39, 0x3f, 0x1a, 0x25, 0x44, 0x4a, 0x17, 0xc1, 0x3a, 0x31, 0x66, 0x80, 0xf3, 0xe9,
0xd5, 0x73, 0x64, 0x9d, 0xc6, 0xf4, 0x92, 0xbc, 0x0f, 0xe4, 0xd4, 0xf3, 0x9f, 0xdb, 0xbe, 0x62,
0x2d, 0x5d, 0x41, 0xb6, 0x8b, 0xe6, 0x72, 0x94, 0x22, 0xd8, 0x26, 0xf2, 0x10, 0xd6, 0x34, 0x74,
0xad, 0x60, 0xce, 0xe2, 0xad, 0x44, 0x89, 0xfb, 0xb2, 0x0a, 0xe3, 0x57, 0xf3, 0x40, 0x44, 0xfe,
0x1d, 0xcf, 0x0d, 0x42, 0xdf, 0x76, 0xdc, 0x30, 0x88, 0x33, 0x9a, 0xb9, 0x04, 0xa3, 0x79, 0x0f,
0x9a, 0xc8, 0xe6, 0xea, 0xdc, 0x66, 0x3e, 0xe2, 0xf9, 0xcd, 0x88, 0xe3, 0x7c, 0x0b, 0x16, 0x23,
0x51, 0x43, 0x69, 0x1b, 0x8b, 0x66, 0x5d, 0x89, 0x1b, 0x0c, 0xeb, 0x03, 0x58, 0x65, 0x44, 0x44,
0xb2, 0xd0, 0x4a, 0x75, 0xc2, 0x89, 0xed, 0xf2, 0xd4, 0xbe, 0x3c, 0xa2, 0x52, 0xb0, 0x41, 0xde,
0xd4, 0x80, 0x86, 0xe2, 0x3a, 0x11, 0x93, 0x8f, 0x5c, 0x4d, 0xf0, 0x9d, 0x88, 0x93, 0x2d, 0x18,
0x2c, 0x64, 0x0b, 0x06, 0xc6, 0xbf, 0xab, 0x42, 0x59, 0x0e, 0x23, 0x72, 0xf9, 0xa1, 0x73, 0x41,
0x23, 0x2e, 0x9f, 0x7d, 0x31, 0xe1, 0xc1, 0xa7, 0x53, 0x2f, 0x54, 0xd2, 0x1d, 0xdf, 0x26, 0x75,
0x0e, 0x14, 0xf2, 0x9d, 0x26, 0x61, 0x70, 0x25, 0x29, 0xa7, 0x7c, 0x52, 0xc2, 0xe0, 0xfc, 0xe3,
0x2d, 0x28, 0x4b, 0x39, 0xa1, 0xa8, 0x74, 0x24, 0x0b, 0x23, 0x2e, 0x24, 0x6c, 0x42, 0x65, 0x64,
0xcf, 0xec, 0x91, 0x13, 0x72, 0x16, 0xbf, 0x60, 0xaa, 0x6f, 0x56, 0xfa, 0xc4, 0x1b, 0xd9, 0x13,
0xeb, 0xc4, 0x9e, 0xd8, 0xee, 0x88, 0x0a, 0xed, 0x63, 0x1d, 0x81, 0xdb, 0x1c, 0x46, 0xbe, 0x05,
0x8b, 0xa2, 0x9d, 0x12, 0x8b, 0x2b, 0x21, 0x45, 0xeb, 0x25, 0x1a, 0x93, 0x44, 0xbd, 0x29, 0x9b,
0x97, 0x53, 0xca, 0x65, 0xb6, 0x82, 0x59, 0xe5, 0x90, 0x3d, 0x8a, 0xbd, 0x15, 0xc9, 0xcf, 0xf9,
0x1a, 0xae, 0xf2, 0xaa, 0x38, 0xf0, 0x2b, 0xbe, 0x7e, 0xd3, 0x82, 0x5b, 0x41, 0x13, 0xdc, 0xde,
0x85, 0xe5, 0xb9, 0x1b, 0xd0, 0x30, 0x9c, 0xd0, 0xb1, 0x6a, 0x4b, 0x0d, 0x91, 0x9a, 0x2a, 0x41,
0x36, 0x67, 0x0b, 0x56, 0xb8, 0xda, 0x34, 0xb0, 0x43, 0x2f, 0x38, 0x77, 0x02, 0x2b, 0xa0, 0xae,
0x54, 0x9f, 0x2d, 0x63, 0xd2, 0x40, 0xa4, 0x0c, 0xb8, 0xca, 0x65, 0x23, 0x81, 0xef, 0xd3, 0x11,
0x75, 0x2e, 0xe8, 0x18, 0x85, 0xba, 0x82, 0xb9, 0x16, 0xcb, 0x63, 0x8a, 0x44, 0x94, 0xd0, 0xe7,
0x53, 0x6b, 0x3e, 0x1b, 0xdb, 0x8c, 0x79, 0x5f, 0xe4, 0x52, 0x92, 0x3b, 0x9f, 0x1e, 0x73, 0x08,
0x79, 0x00, 0x52, 0x6a, 0x13, 0x6b, 0x66, 0x29, 0x76, 0x18, 0x31, 0xaa, 0x61, 0xd6, 0x05, 0x06,
0x97, 0x2a, 0xef, 0xe8, 0x9b, 0xa5, 0xc9, 0x56, 0x18, 0x1e, 0xff, 0xd1, 0x86, 0x69, 0x41, 0x79,
0xe6, 0x3b, 0x17, 0x76, 0x48, 0x5b, 0xcb, 0xfc, 0xec, 0x17, 0x9f, 0x8c, 0x80, 0x3b, 0xae, 0x13,
0x3a, 0x76, 0xe8, 0xf9, 0x2d, 0x82, 0x69, 0x11, 0x80, 0xdc, 0x87, 0x65, 0x5c, 0x27, 0x41, 0x68,
0x87, 0xf3, 0x40, 0x88, 0xac, 0x2b, 0x5c, 0x34, 0x64, 0x09, 0x03, 0x84, 0xa3, 0xd4, 0x4a, 0x3e,
0x85, 0x75, 0xbe, 0x34, 0x52, 0x5b, 0x73, 0x55, 0x31, 0x24, 0x2b, 0x88, 0xb1, 0x13, 0xdf, 0xa3,
0x9f, 0xc3, 0x86, 0x58, 0x2e, 0xa9, 0x9c, 0x6b, 0x2a, 0xe7, 0x2a, 0x47, 0x49, 0x64, 0xdd, 0x82,
0x65, 0xd6, 0x34, 0x67, 0x64, 0x89, 0x12, 0xd8, 0xae, 0x58, 0x67, 0xbd, 0xc0, 0x4c, 0x4b, 0x3c,
0xd1, 0xc4, 0xb4, 0x27, 0xf4, 0x8a, 0x7c, 0x17, 0x96, 0xf8, 0xf2, 0x41, 0xbd, 0x0c, 0x1e, 0xd9,
0x9b, 0x78, 0x64, 0xaf, 0x89, 0xc1, 0xdd, 0x51, 0xa9, 0x78, 0x6a, 0x2f, 0x8e, 0x62, 0xdf, 0x6c,
0x6b, 0x4c, 0x9c, 0x53, 0xca, 0xce, 0x89, 0xd6, 0x06, 0x5f, 0x6c, 0xf2, 0x9b, 0xed, 0xda, 0xf9,
0x0c, 0x53, 0x5a, 0x9c, 0x58, 0xf3, 0x2f, 0x5c, 0xc7, 0x13, 0x2f, 0xa0, 0x52, 0xe1, 0xde, 0xba,
0x29, 0x36, 0x24, 0x03, 0x4a, 0xf9, 0x8a, 0x09, 0xf0, 0x5c, 0x5b, 0xa2, 0xcc, 0x22, 0xb7, 0x70,
0x61, 0x34, 0xb8, 0xd2, 0x44, 0x9a, 0x46, 0x18, 0xc3, 0x78, 0x6e, 0x3f, 0x97, 0x64, 0xfd, 0x35,
0xa4, 0x26, 0xc0, 0x40, 0x82, 0xa0, 0xef, 0xc1, 0xb2, 0x98, 0x85, 0x88, 0x98, 0xb6, 0x6e, 0xe3,
0x11, 0x79, 0x53, 0xf6, 0x31, 0x45, 0x6d, 0xcd, 0x26, 0x9f, 0x17, 0x8d, 0xfe, 0xee, 0x03, 0x91,
0x93, 0xa2, 0x15, 0xf4, 0xfa, 0xcb, 0x0a, 0x5a, 0x16, 0xd3, 0x14, 0x81, 0x8c, 0xdf, 0xcb, 0x71,
0x5e, 0x4b, 0x60, 0x07, 0x9a, 0xa6, 0x8a, 0xd3, 0x35, 0xcb, 0x73, 0x27, 0x57, 0x82, 0xd4, 0x01,
0x07, 0xf5, 0xdd, 0x09, 0xd2, 0x1a, 0xc7, 0xd5, 0x51, 0xf8, 0xe1, 0x5d, 0x97, 0x40, 0x44, 0xba,
0x03, 0xb5, 0xd9, 0xfc, 0x64, 0xe2, 0x8c, 0x38, 0x4a, 0x81, 0x97, 0xc2, 0x41, 0x88, 0xf0, 0x06,
0xd4, 0xc5, 0x5a, 0xe7, 0x18, 0x45, 0xc4, 0xa8, 0x09, 0x18, 0xa2, 0x20, 0x73, 0x40, 0x7d, 0x24,
0x76, 0x75, 0x13, 0x7f, 0x1b, 0xdb, 0xb0, 0x1a, 0x6f, 0xb4, 0xe0, 0x5c, 0xee, 0x43, 0x45, 0x50,
0x52, 0xa9, 0xe6, 0x5d, 0x8c, 0x8f, 0x86, 0xa9, 0xd2, 0x8d, 0x7f, 0x5f, 0x82, 0x15, 0x39, 0x46,
0x6c, 0xb2, 0x07, 0xf3, 0xe9, 0xd4, 0xf6, 0x33, 0x48, 0x74, 0xee, 0xc5, 0x24, 0x3a, 0x9f, 0x22,
0xd1, 0x71, 0x25, 0x1e, 0xa7, 0xf0, 0x71, 0x25, 0x1e, 0x5b, 0x5d, 0x5c, 0x75, 0xa0, 0xdb, 0x99,
0x1a, 0x02, 0x3c, 0xe4, 0xf6, 0xac, 0xd4, 0x81, 0x52, 0xca, 0x38, 0x50, 0xf4, 0xe3, 0x60, 0x21,
0x71, 0x1c, 0xbc, 0x01, 0x7c, 0x19, 0xcb, 0xf5, 0x58, 0xe6, 0xda, 0x04, 0x84, 0x89, 0x05, 0xf9,
0x0e, 0x2c, 0x25, 0x29, 0x30, 0x27, 0xf5, 0x8b, 0x19, 0xf4, 0xd7, 0x99, 0x52, 0x64, 0x6a, 0x34,
0xe4, 0xaa, 0xa0, 0xbf, 0xce, 0x94, 0x1e, 0x60, 0x8a, 0xc4, 0xef, 0x00, 0xf0, 0xba, 0x71, 0x1b,
0x03, 0x6e, 0xe3, 0xb7, 0x13, 0x2b, 0x53, 0x1b, 0xf5, 0x2d, 0xf6, 0x31, 0xf7, 0x29, 0xee, 0xeb,
0x2a, 0xe6, 0xc4, 0x2d, 0xfd, 0x29, 0x2c, 0x7a, 0x33, 0xea, 0x5a, 0x11, 0x15, 0xac, 0x61, 0x51,
0x4d, 0x51, 0x54, 0x57, 0xc2, 0xcd, 0x06, 0xc3, 0x53, 0x9f, 0xe4, 0x73, 0x3e, 0xc8, 0x54, 0xcb,
0x59, 0xbf, 0x26, 0xe7, 0x22, 0x22, 0x46, 0x59, 0x3f, 0x42, 0x45, 0x99, 0x37, 0x99, 0x73, 0xd3,
0x54, 0x03, 0xd7, 0x91, 0xd4, 0xd5, 0x9b, 0x2a, 0xc5, 0xd4, 0xb1, 0x8c, 0xdf, 0xc8, 0x41, 0x4d,
0xeb, 0x03, 0x59, 0x83, 0xe5, 0x9d, 0x7e, 0xff, 0xa8, 0x63, 0xb6, 0x87, 0xdd, 0x2f, 0x3b, 0xd6,
0xce, 0x41, 0x7f, 0xd0, 0x69, 0xde, 0x60, 0xe0, 0x83, 0xfe, 0x4e, 0xfb, 0xc0, 0xda, 0xeb, 0x9b,
0x3b, 0x12, 0x9c, 0x23, 0xeb, 0x40, 0xcc, 0xce, 0x61, 0x7f, 0xd8, 0x89, 0xc1, 0xf3, 0xa4, 0x09,
0xf5, 0x6d, 0xb3, 0xd3, 0xde, 0xd9, 0x17, 0x90, 0x02, 0x59, 0x85, 0xe6, 0xde, 0x71, 0x6f, 0xb7,
0xdb, 0x7b, 0x6c, 0xed, 0xb4, 0x7b, 0x3b, 0x9d, 0x83, 0xce, 0x6e, 0xb3, 0x48, 0x1a, 0x50, 0x6d,
0x6f, 0xb7, 0x7b, 0xbb, 0xfd, 0x5e, 0x67, 0xb7, 0x59, 0x32, 0xfe, 0x38, 0x07, 0x10, 0x35, 0x94,
0xd1, 0xd5, 0xa8, 0xa9, 0xba, 0x91, 0x78, 0x2d, 0xd5, 0x29, 0x4e, 0x57, 0xfd, 0xd8, 0x37, 0x79,
0x08, 0x65, 0x6f, 0x1e, 0x8e, 0xbc, 0x29, 0x17, 0x22, 0x16, 0x1f, 0xb6, 0x52, 0xf9, 0xfa, 0x3c,
0xdd, 0x94, 0x88, 0x31, 0x43, 0x70, 0xe1, 0x65, 0x86, 0xe0, 0xb8, 0xc5, 0x99, 0xf3, 0x75, 0x9a,
0xc5, 0xf9, 0x36, 0x40, 0xf0, 0x9c, 0xd2, 0x19, 0x6a, 0xda, 0xc4, 0x2e, 0xa8, 0x22, 0x64, 0xc8,
0xe4, 0xd2, 0xff, 0x94, 0x83, 0x35, 0x5c, 0x4b, 0xe3, 0x24, 0x11, 0xbb, 0x0b, 0xb5, 0x91, 0xe7,
0xcd, 0x28, 0x63, 0xaa, 0x15, 0xbf, 0xa6, 0x83, 0x18, 0x81, 0xe2, 0x04, 0xf9, 0xd4, 0xf3, 0x47,
0x54, 0xd0, 0x30, 0x40, 0xd0, 0x1e, 0x83, 0xb0, 0x3d, 0x24, 0x36, 0x21, 0xc7, 0xe0, 0x24, 0xac,
0xc6, 0x61, 0x1c, 0x65, 0x1d, 0x16, 0x4e, 0x7c, 0x6a, 0x8f, 0xce, 0x05, 0xf5, 0x12, 0x5f, 0xe4,
0xdb, 0x91, 0xc6, 0x71, 0xc4, 0xf6, 0xc4, 0x84, 0xf2, 0xc6, 0x57, 0xcc, 0x25, 0x01, 0xdf, 0x11,
0x60, 0x76, 0xce, 0xdb, 0x27, 0xb6, 0x3b, 0xf6, 0x5c, 0x3a, 0x16, 0xf2, 0x7f, 0x04, 0x30, 0x8e,
0x60, 0x3d, 0xd9, 0x3f, 0x41, 0xef, 0x3e, 0xd1, 0xe8, 0x1d, 0x17, 0x8a, 0x37, 0xaf, 0xdf, 0x63,
0x1a, 0xed, 0xfb, 0xcf, 0x45, 0x28, 0x32, 0x81, 0xe7, 0x5a, 0xd9, 0x48, 0x97, 0x6d, 0x0b, 0x29,
0xf7, 0x00, 0x54, 0x6c, 0x72, 0x06, 0x4c, 0x4c, 0x16, 0x42, 0x90, 0xf1, 0x52, 0xc9, 0x3e, 0x1d,
0x5d, 0x48, 0x99, 0x05, 0x21, 0x26, 0x1d, 0x5d, 0xa0, 0xa2, 0xc3, 0x0e, 0x79, 0x5e, 0x4e, 0xaf,
0xca, 0x81, 0x1d, 0x62, 0x4e, 0x91, 0x84, 0xf9, 0xca, 0x2a, 0x09, 0x73, 0xb5, 0xa0, 0xec, 0xb8,
0x27, 0xde, 0xdc, 0x95, 0x6a, 0x25, 0xf9, 0x89, 0xde, 0x08, 0x48, 0x49, 0xd9, 0xd1, 0xce, 0xa9,
0x51, 0x85, 0x01, 0x86, 0xec, 0x70, 0xff, 0x10, 0xaa, 0xc1, 0x95, 0x3b, 0xd2, 0x69, 0xd0, 0xaa,
0x18, 0x1f, 0xd6, 0xfb, 0xad, 0xc1, 0x95, 0x3b, 0xc2, 0x15, 0x5f, 0x09, 0xc4, 0x2f, 0xf2, 0x08,
0x2a, 0xca, 0x4a, 0xc7, 0x4f, 0x90, 0x9b, 0x7a, 0x0e, 0x69, 0x9a, 0xe3, 0x3a, 0x3a, 0x85, 0x4a,
0x3e, 0x80, 0x05, 0xd4, 0xd6, 0x07, 0xad, 0x3a, 0x66, 0x92, 0x02, 0x2f, 0x6b, 0x06, 0x3a, 0x02,
0xd0, 0x31, 0xda, 0xcc, 0x4c, 0x81, 0xc6, 0x86, 0xe9, 0x74, 0x62, 0xcf, 0x84, 0xee, 0xbc, 0xc1,
0xed, 0xe9, 0x0c, 0xc2, 0x15, 0xe7, 0x77, 0xa1, 0x8e, 0x16, 0x50, 0xc4, 0x71, 0x39, 0x1f, 0x5a,
0x30, 0x81, 0xc1, 0xf6, 0x26, 0xf6, 0xac, 0x17, 0x6c, 0x3e, 0x81, 0x46, 0xac, 0x31, 0xba, 0x0a,
0xad, 0xc1, 0x55, 0x68, 0x6f, 0xe9, 0x2a, 0xb4, 0xe8, 0x28, 0x14, 0xd9, 0x74, 0x95, 0xda, 0x11,
0x54, 0xe4, 0x58, 0x30, 0x9a, 0x73, 0xdc, 0x7b, 0xd2, 0xeb, 0x7f, 0xd5, 0xb3, 0x06, 0x4f, 0x7b,
0x3b, 0xcd, 0x1b, 0x64, 0x09, 0x6a, 0xed, 0x1d, 0x24, 0x63, 0x08, 0xc8, 0x31, 0x94, 0xa3, 0xf6,
0x60, 0xa0, 0x20, 0x79, 0x86, 0x72, 0xd4, 0xed, 0xf5, 0x3a, 0xbb, 0x1c, 0x50, 0x30, 0xf6, 0xa0,
0x99, 0xec, 0x3b, 0x5b, 0xe5, 0xa1, 0x84, 0x09, 0xbb, 0x64, 0x04, 0x88, 0xac, 0x1f, 0x79, 0xcd,
0xfa, 0x61, 0x3c, 0x82, 0x26, 0x3b, 0xe9, 0xd9, 0xe0, 0xeb, 0xee, 0x0a, 0x13, 0xc6, 0x8b, 0xeb,
0xb6, 0xc9, 0x8a, 0x59, 0xe3, 0x30, 0xac, 0xca, 0xf8, 0x04, 0x96, 0xb5, 0x6c, 0x91, 0xfe, 0x88,
0x71, 0x0f, 0x49, 0xfd, 0x11, 0x4a, 0xfe, 0x3c, 0xc5, 0xd8, 0x80, 0x35, 0xf6, 0xd9, 0xb9, 0xa0,
0x6e, 0x38, 0x98, 0x9f, 0x70, 0x2f, 0x17, 0xc7, 0x73, 0x8d, 0x5f, 0xcd, 0x41, 0x55, 0xa5, 0x5c,
0xbf, 0x6d, 0xb6, 0x84, 0xaa, 0x89, 0xd3, 0xc9, 0x4d, 0xad, 0x06, 0xcc, 0xb8, 0x85, 0x7f, 0x23,
0x95, 0x93, 0xb1, 0x05, 0x55, 0x05, 0xc2, 0x41, 0xec, 0x74, 0x4c, 0xab, 0xdf, 0x3b, 0xe8, 0xf6,
0xd8, 0x69, 0xc1, 0xc6, 0x19, 0x01, 0x7b, 0x7b, 0x08, 0xc9, 0x19, 0x4d, 0x58, 0x7c, 0x4c, 0xc3,
0xae, 0x7b, 0xea, 0x89, 0xc1, 0x30, 0x7e, 0x7d, 0x01, 0x96, 0x14, 0x28, 0x52, 0x4c, 0x5d, 0x50,
0x3f, 0x70, 0x3c, 0x17, 0x17, 0x4e, 0xd5, 0x94, 0x9f, 0x8c, 0xde, 0x09, 0xb1, 0x0d, 0xf9, 0x8e,
0x55, 0x4c, 0x15, 0x82, 0x1e, 0x32, 0x1d, 0xef, 0xc0, 0x92, 0x33, 0xa6, 0x6e, 0xe8, 0x84, 0x57,
0x56, 0xcc, 0xa6, 0xb0, 0x28, 0xc1, 0x82, 0xf1, 0x58, 0x85, 0x92, 0x3d, 0x71, 0x6c, 0xe9, 0x3d,
0xc4, 0x3f, 0x18, 0x74, 0xe4, 0x4d, 0x3c, 0x1f, 0x05, 0x99, 0xaa, 0xc9, 0x3f, 0xc8, 0x03, 0x58,
0x65, 0x42, 0x95, 0x6e, 0x04, 0x43, 0x92, 0xc5, 0xcd, 0x1b, 0xc4, 0x9d, 0x4f, 0x8f, 0x22, 0x43,
0x18, 0x4b, 0x61, 0xec, 0x06, 0xcb, 0x21, 0xf8, 0x4b, 0x95, 0x81, 0x2b, 0x4a, 0x96, 0xdd, 0xf9,
0xb4, 0x8d, 0x29, 0x0a, 0xff, 0x21, 0xac, 0x31, 0x7c, 0xc5, 0x91, 0xaa, 0x1c, 0x4b, 0x98, 0x83,
0x15, 0xd6, 0x15, 0x69, 0x2a, 0xcf, 0x2d, 0xa8, 0xf2, 0x56, 0xb1, 0x25, 0x21, 0xac, 0x65, 0xd8,
0x14, 0xea, 0x07, 0x29, 0x47, 0x1f, 0xae, 0x19, 0x48, 0x3a, 0xfa, 0x68, 0xae, 0x42, 0x95, 0xa4,
0xab, 0xd0, 0x43, 0x58, 0x3b, 0x61, 0x6b, 0xf4, 0x9c, 0xda, 0x63, 0xea, 0x5b, 0xd1, 0xca, 0xe7,
0xf2, 0xe7, 0x0a, 0x4b, 0xdc, 0xc7, 0x34, 0xb5, 0x51, 0x18, 0x6b, 0xc8, 0x28, 0x11, 0x1d, 0x5b,
0xa1, 0x67, 0x21, 0xc7, 0x28, 0xd4, 0xb6, 0x0d, 0x0e, 0x1e, 0x7a, 0x3b, 0x0c, 0x18, 0xc7, 0x3b,
0xf3, 0xed, 0xd9, 0xb9, 0x90, 0x0e, 0x15, 0xde, 0x63, 0x06, 0x24, 0xaf, 0x41, 0x99, 0xed, 0x09,
0x97, 0x72, 0xef, 0x08, 0x2e, 0x77, 0x49, 0x10, 0x79, 0x0b, 0x16, 0xb0, 0x8e, 0xa0, 0xd5, 0xc4,
0x0d, 0x51, 0x8f, 0xce, 0x0e, 0xc7, 0x35, 0x45, 0x1a, 0xe3, 0xbf, 0xe7, 0xbe, 0xc3, 0x09, 0x5b,
0xd5, 0xc4, 0xdf, 0xe4, 0x7b, 0x1a, 0x95, 0x5c, 0xc1, 0xbc, 0x6f, 0x89, 0xbc, 0x89, 0xa5, 0x78,
0x1d, 0xc1, 0xfc, 0x46, 0xc9, 0xd7, 0xf7, 0x8b, 0x95, 0x5a, 0xb3, 0x6e, 0xb4, 0xd0, 0xbf, 0xc9,
0xa4, 0x23, 0xef, 0x82, 0xfa, 0x57, 0xb1, 0x3d, 0x92, 0x83, 0x8d, 0x54, 0x52, 0xe4, 0xe9, 0xe0,
0x0b, 0xb8, 0x35, 0xf5, 0xc6, 0x92, 0x4b, 0xa8, 0x4b, 0xe0, 0xa1, 0x37, 0x66, 0xdc, 0xcc, 0xb2,
0x42, 0x3a, 0x75, 0x5c, 0x27, 0x38, 0xa7, 0x63, 0xc1, 0x2c, 0x34, 0x65, 0xc2, 0x9e, 0x80, 0x33,
0x96, 0x7c, 0xe6, 0x7b, 0x67, 0xea, 0xec, 0xcc, 0x99, 0xea, 0xdb, 0xf8, 0x14, 0x4a, 0x7c, 0x06,
0xd9, 0x46, 0xc1, 0xf9, 0xcd, 0x89, 0x8d, 0x82, 0xd0, 0x16, 0x94, 0x5d, 0x1a, 0x3e, 0xf7, 0xfc,
0x67, 0x52, 0x03, 0x2d, 0x3e, 0x8d, 0x1f, 0xa1, 0x96, 0x55, 0x39, 0xaa, 0x71, 0x6d, 0x04, 0x5b,
0xc2, 0x7c, 0x09, 0x06, 0xe7, 0xb6, 0x50, 0xfc, 0x56, 0x10, 0x30, 0x38, 0xb7, 0x53, 0x4b, 0x38,
0x9f, 0xf6, 0x55, 0x7b, 0x0b, 0x16, 0xa5, 0x6b, 0x5c, 0x60, 0x4d, 0xe8, 0x69, 0x28, 0xb6, 0x64,
0x5d, 0xf8, 0xc5, 0x05, 0x07, 0xf4, 0x34, 0x34, 0x0e, 0x61, 0x59, 0x6c, 0x9a, 0xfe, 0x8c, 0xca,
0xaa, 0x3f, 0xcb, 0x12, 0x93, 0x6a, 0x0f, 0x57, 0xe2, 0xfc, 0x07, 0xe7, 0xf4, 0x62, 0xb2, 0x93,
0xf1, 0x83, 0x48, 0xa5, 0xc8, 0xb8, 0x13, 0x51, 0x9e, 0x10, 0x56, 0xa4, 0x41, 0x55, 0x3a, 0x6d,
0x28, 0x91, 0xc8, 0x19, 0xb3, 0xd1, 0x09, 0xe6, 0xa3, 0x91, 0x74, 0x59, 0xac, 0x98, 0xf2, 0xd3,
0xf8, 0xdf, 0x39, 0x58, 0xc1, 0xc2, 0xa4, 0x98, 0x27, 0x4e, 0x8a, 0x1f, 0xbb, 0x91, 0x6c, 0x7e,
0x74, 0x96, 0x90, 0x7f, 0xbc, 0xdc, 0x22, 0x94, 0xb4, 0xf6, 0x14, 0x33, 0xad, 0x3d, 0xdf, 0x86,
0xe6, 0x98, 0x4e, 0x1c, 0x5c, 0x4e, 0x92, 0xcb, 0xe2, 0x6c, 0xed, 0x92, 0x84, 0x4b, 0xd5, 0x43,
0xca, 0xc4, 0xb4, 0x90, 0x36, 0x3f, 0xfe, 0x8d, 0x1c, 0x2c, 0x73, 0x46, 0x0f, 0x15, 0x3e, 0x62,
0x40, 0xbf, 0x90, 0x9a, 0x0d, 0x41, 0x76, 0x45, 0xdf, 0x23, 0x06, 0x08, 0xa1, 0x1c, 0x79, 0xff,
0x86, 0xd0, 0x78, 0x08, 0x28, 0xf9, 0x0e, 0x8a, 0xb0, 0xae, 0x85, 0x40, 0xc1, 0xc0, 0xdf, 0xcc,
0x60, 0x2d, 0x55, 0x76, 0x26, 0xdf, 0xba, 0x08, 0xda, 0xae, 0xc0, 0x02, 0x57, 0x9f, 0x19, 0x7b,
0xd0, 0x88, 0x55, 0x13, 0x33, 0x2b, 0xd5, 0xb9, 0x59, 0x29, 0x65, 0xf3, 0xce, 0xa7, 0x6d, 0xde,
0x57, 0xb0, 0x62, 0x52, 0x7b, 0x7c, 0xb5, 0xe7, 0xf9, 0x47, 0xc1, 0x49, 0xb8, 0xc7, 0xb9, 0x67,
0x76, 0x56, 0x29, 0x2f, 0x97, 0x98, 0x1d, 0x46, 0xda, 0xf3, 0xe5, 0x20, 0x7e, 0x0b, 0x16, 0x23,
0x77, 0x18, 0x4d, 0x63, 0xdf, 0x50, 0x1e, 0x31, 0xc8, 0x74, 0x11, 0x28, 0xce, 0x82, 0x93, 0x50,
0xe8, 0xec, 0xf1, 0xb7, 0xf1, 0x4f, 0x4b, 0x40, 0xd8, 0xaa, 0x4f, 0x2c, 0xac, 0xd4, 0xb4, 0xe4,
0xd2, 0x96, 0xbf, 0x84, 0xb3, 0x4f, 0x3e, 0xe5, 0xec, 0xf3, 0x00, 0x88, 0x86, 0x20, 0x7d, 0x90,
0x0a, 0xca, 0x07, 0xa9, 0x19, 0xe1, 0x0a, 0x17, 0xa4, 0x07, 0xb0, 0x2a, 0xc4, 0x95, 0x78, 0x77,
0x70, 0x99, 0x99, 0x84, 0xcb, 0x2d, 0xb1, 0x3e, 0x49, 0x47, 0x1f, 0xa9, 0x06, 0x2f, 0x70, 0x47,
0x1f, 0xa9, 0xad, 0xd2, 0x16, 0xf3, 0xc2, 0x4b, 0x17, 0x73, 0x39, 0x73, 0x31, 0x6b, 0xda, 0xcb,
0x4a, 0x5c, 0x7b, 0x99, 0xd2, 0xc3, 0x73, 0xfe, 0x3c, 0xa6, 0x87, 0xbf, 0x07, 0x4d, 0xa9, 0xc9,
0x52, 0x3a, 0x52, 0xe1, 0x01, 0x22, 0x94, 0x55, 0x52, 0x4b, 0x1a, 0x33, 0x34, 0xd6, 0x5e, 0xc5,
0xe2, 0x59, 0xcf, 0xb6, 0x78, 0xa6, 0x75, 0x7e, 0x8d, 0x0c, 0x9d, 0xdf, 0xa3, 0xc8, 0xc1, 0x23,
0x38, 0x77, 0xa6, 0xc8, 0x48, 0x45, 0x1e, 0xaa, 0x62, 0x90, 0x07, 0xe7, 0xce, 0xd4, 0x94, 0xae,
0x56, 0xec, 0x83, 0xec, 0xc0, 0x1d, 0xd1, 0x9f, 0x0c, 0x2f, 0x29, 0x3e, 0x0a, 0x4b, 0xb8, 0x54,
0x36, 0x39, 0xda, 0x61, 0xc2, 0x61, 0x2a, 0x31, 0x28, 0xd2, 0xc7, 0x26, 0xe0, 0x8a, 0x63, 0x39,
0x28, 0x87, 0xdc, 0xc9, 0x06, 0xc9, 0x03, 0x43, 0x11, 0x4a, 0xc5, 0xe0, 0x02, 0xf9, 0xae, 0x86,
0x59, 0x9b, 0xda, 0x97, 0x07, 0xa8, 0x34, 0x0c, 0x2e, 0x8c, 0x3f, 0xcd, 0x41, 0x93, 0x2d, 0xe1,
0x18, 0x75, 0xf8, 0x1c, 0x90, 0xde, 0xbd, 0x22, 0x71, 0xa8, 0x31, 0x5c, 0x49, 0x1b, 0x3e, 0x05,
0xdc, 0xec, 0x96, 0x37, 0xa3, 0xae, 0x20, 0x0d, 0xad, 0x38, 0x69, 0x88, 0x8e, 0x89, 0xfd, 0x1b,
0x5c, 0xea, 0x64, 0x10, 0xf2, 0x39, 0x54, 0xd9, 0x9e, 0xc2, 0xc5, 0x2b, 0xbc, 0xc3, 0x37, 0x95,
0x26, 0x21, 0xb5, 0xbd, 0x59, 0xd6, 0x99, 0xf8, 0xcc, 0x72, 0xa1, 0x2a, 0x66, 0xb8, 0x50, 0x69,
0xb4, 0x67, 0x1f, 0xe0, 0x09, 0xbd, 0x62, 0x83, 0x10, 0x7a, 0x3e, 0xe3, 0xd5, 0xd8, 0x16, 0x3b,
0xb5, 0xa7, 0x8e, 0xd0, 0x66, 0x96, 0xcc, 0xea, 0x33, 0x7a, 0xb5, 0x87, 0x00, 0xb6, 0xb6, 0x58,
0x72, 0x44, 0x80, 0x4a, 0x66, 0xe5, 0x19, 0xbd, 0xe2, 0xd4, 0xc7, 0x82, 0xc6, 0x13, 0x7a, 0xb5,
0x4b, 0xb9, 0x30, 0xe0, 0xf9, 0x6c, 0xd0, 0x7d, 0xfb, 0x39, 0xe3, 0xfe, 0x63, 0x2e, 0x3e, 0x35,
0xdf, 0x7e, 0xfe, 0x84, 0x5e, 0x49, 0x77, 0xa3, 0x32, 0x4b, 0x9f, 0x78, 0x23, 0xc1, 0xbe, 0x48,
0x05, 0x52, 0xd4, 0x28, 0x73, 0xe1, 0x19, 0xfe, 0x36, 0xfe, 0x24, 0x07, 0x0d, 0xd6, 0x7e, 0x3c,
0x79, 0x70, 0x15, 0x09, 0x9f, 0xe1, 0x5c, 0xe4, 0x33, 0xfc, 0x50, 0x10, 0x64, 0x7e, 0x8c, 0xe5,
0xaf, 0x3f, 0xc6, 0x70, 0x6e, 0xf8, 0x19, 0xf6, 0x21, 0x54, 0xf9, 0xc2, 0x60, 0xe4, 0xa7, 0x10,
0x9b, 0xe0, 0x58, 0x87, 0xcc, 0x0a, 0xa2, 0x3d, 0xe1, 0xfe, 0x87, 0x9a, 0xae, 0x9e, 0x0f, 0x71,
0xd5, 0x57, 0x1a, 0xfa, 0x8c, 0x69, 0x28, 0x5d, 0xe3, 0x7f, 0xa8, 0x2b, 0xc2, 0x17, 0x92, 0x8a,
0x70, 0xc3, 0x85, 0x0a, 0x9b, 0x6a, 0xec, 0x6c, 0x46, 0xa1, 0xb9, 0xac, 0x42, 0x19, 0xb3, 0x63,
0xb3, 0xf3, 0x8c, 0xd1, 0xe8, 0xbc, 0x60, 0x76, 0xec, 0x80, 0xb2, 0x82, 0x58, 0xc3, 0x5d, 0xcf,
0x42, 0xcd, 0xb2, 0xd0, 0xb9, 0x56, 0xcc, 0xaa, 0xeb, 0x1d, 0x71, 0x80, 0xf1, 0x97, 0x72, 0x50,
0xd3, 0xf6, 0x2c, 0x9a, 0x1a, 0xd4, 0x70, 0xf2, 0x0d, 0x1e, 0xdf, 0x01, 0xb1, 0xf9, 0xd8, 0xbf,
0x61, 0x36, 0x46, 0xb1, 0x09, 0xda, 0x12, 0x4b, 0x19, 0x73, 0xe6, 0x63, 0xfa, 0x2d, 0xd9, 0x2f,
0xb9, 0x7e, 0xd9, 0xef, 0xed, 0x05, 0x28, 0x32, 0x54, 0xe3, 0x0b, 0x58, 0xd6, 0x9a, 0xc1, 0xf5,
0x3f, 0xaf, 0x3a, 0x00, 0xc6, 0x2f, 0xa8, 0xcc, 0xac, 0x0e, 0x6e, 0xbb, 0x97, 0xae, 0x9e, 0x74,
0xcc, 0xc7, 0x45, 0xb8, 0x94, 0x72, 0x10, 0x8e, 0xcc, 0x2b, 0x7a, 0x1f, 0x1a, 0xbf, 0x92, 0x83,
0x15, 0xad, 0xf8, 0x3d, 0xc7, 0xb5, 0x27, 0xce, 0x8f, 0xf0, 0x18, 0x0b, 0x9c, 0x33, 0x37, 0x51,
0x01, 0x07, 0x7d, 0x9d, 0x0a, 0xc8, 0x5d, 0xa8, 0x73, 0xdf, 0x72, 0x7e, 0x73, 0x41, 0x1c, 0xb3,
0x80, 0x30, 0xd3, 0x7e, 0x3e, 0xbc, 0x34, 0xfe, 0x66, 0x1e, 0x56, 0x45, 0x13, 0xf0, 0x0a, 0x80,
0xc3, 0x58, 0xdd, 0xc3, 0xe0, 0x8c, 0x7c, 0x0e, 0x0d, 0x36, 0x7c, 0x96, 0x4f, 0xcf, 0x9c, 0x20,
0xa4, 0xd2, 0xad, 0x20, 0x83, 0x1a, 0x33, 0x4e, 0x86, 0xa1, 0x9a, 0x02, 0x93, 0x7c, 0x01, 0x35,
0xcc, 0xca, 0x55, 0x70, 0x62, 0xae, 0x5a, 0xe9, 0x8c, 0x7c, 0x2e, 0xf6, 0x6f, 0x98, 0x10, 0x44,
0x33, 0xf3, 0x05, 0xd4, 0x70, 0x9a, 0x2f, 0x70, 0xac, 0x13, 0xc4, 0x2e, 0x35, 0x17, 0x2c, 0xf3,
0x2c, 0x9a, 0x99, 0x36, 0x34, 0x38, 0xb9, 0x13, 0x23, 0x29, 0xfc, 0x86, 0x37, 0xd3, 0xd9, 0xe5,
0x58, 0xb3, 0xc6, 0xcf, 0xb4, 0xef, 0xed, 0x2a, 0x94, 0x43, 0xdf, 0x39, 0x3b, 0xa3, 0xbe, 0xb1,
0xae, 0x86, 0x86, 0xd1, 0x71, 0x3a, 0x08, 0xe9, 0x8c, 0xc9, 0x30, 0xc6, 0xbf, 0xcc, 0x41, 0x4d,
0x50, 0xe6, 0x1f, 0xdb, 0x63, 0x61, 0x33, 0xa1, 0xac, 0xad, 0x6a, 0xba, 0xd9, 0x77, 0x60, 0x69,
0xca, 0x04, 0x2e, 0x27, 0xbc, 0x8a, 0xbb, 0x2b, 0x2c, 0x4a, 0xb0, 0x90, 0x25, 0xb6, 0x60, 0x05,
0x45, 0x8b, 0xc0, 0x0a, 0x9d, 0x89, 0x25, 0x13, 0xc5, 0x0d, 0x99, 0x65, 0x9e, 0x34, 0x74, 0x26,
0x87, 0x22, 0x81, 0x71, 0xd8, 0x41, 0x68, 0x9f, 0x51, 0x41, 0x1d, 0xf8, 0x07, 0x13, 0xe2, 0x12,
0xba, 0x00, 0x29, 0xc4, 0xfd, 0xdf, 0x65, 0xd8, 0x48, 0x25, 0x09, 0x21, 0x4e, 0x59, 0x87, 0x27,
0xce, 0xf4, 0xc4, 0x53, 0xd6, 0x89, 0x9c, 0x66, 0x1d, 0x3e, 0x60, 0x29, 0xd2, 0x3a, 0x41, 0x61,
0x4d, 0x2e, 0x59, 0x34, 0x2f, 0x28, 0x75, 0x41, 0x1e, 0x85, 0xd9, 0x0f, 0xe3, 0xc7, 0x60, 0xb2,
0x3a, 0x09, 0xd7, 0xf9, 0xc2, 0x95, 0x59, 0x0a, 0x16, 0x90, 0x3f, 0x0f, 0x2d, 0xb5, 0x33, 0x84,
0x6c, 0xa3, 0xe9, 0x3e, 0x58, 0x4d, 0xef, 0xbd, 0xa4, 0xa6, 0x98, 0xde, 0x17, 0x59, 0xaf, 0x75,
0xb9, 0xa9, 0x78, 0x81, 0xaa, 0xae, 0x0b, 0x78, 0x5d, 0xd6, 0x85, 0xb2, 0x4a, 0xba, 0xc6, 0xe2,
0x2b, 0xf5, 0x0d, 0x75, 0xda, 0xb1, 0x6a, 0xcd, 0x5b, 0xa2, 0x60, 0x95, 0xa4, 0xd7, 0x7b, 0x0e,
0xeb, 0xcf, 0x6d, 0x27, 0x94, 0x7d, 0xd4, 0x54, 0x2f, 0x25, 0xac, 0xef, 0xe1, 0x4b, 0xea, 0xfb,
0x8a, 0x67, 0x8e, 0x49, 0x6f, 0xab, 0xcf, 0xd3, 0xc0, 0x60, 0xf3, 0xef, 0x15, 0x60, 0x31, 0x5e,
0x0a, 0x23, 0x3d, 0xe2, 0xb8, 0x92, 0x8c, 0xb4, 0x90, 0x00, 0x84, 0xe5, 0xac, 0xc7, 0x19, 0xe8,
0xb4, 0x4d, 0x2f, 0x9f, 0x61, 0xd3, 0xd3, 0x4d, 0x69, 0x85, 0x97, 0x79, 0x56, 0x14, 0x5f, 0xc9,
0xb3, 0xa2, 0x94, 0xe5, 0x59, 0xf1, 0xd1, 0xb5, 0xa6, 0x78, 0xae, 0x10, 0xcf, 0x34, 0xc3, 0x3f,
0xba, 0xde, 0x0c, 0xcf, 0x75, 0xe5, 0xd7, 0x99, 0xe0, 0x35, 0x07, 0x82, 0xca, 0x35, 0x06, 0x30,
0xcd, 0xa5, 0x20, 0xc3, 0x04, 0x5f, 0xfd, 0x1a, 0x26, 0xf8, 0xcd, 0x3f, 0xc9, 0x01, 0x49, 0xef,
0x0e, 0xf2, 0x98, 0x9b, 0x4b, 0x5d, 0x3a, 0x11, 0x94, 0xfb, 0xfd, 0x57, 0xdb, 0x61, 0x72, 0x41,
0xc8, 0xdc, 0xe4, 0x03, 0x58, 0xd1, 0xef, 0xf1, 0xe9, 0xaa, 0x8d, 0x86, 0x49, 0xf4, 0xa4, 0x48,
0x49, 0xa7, 0xb9, 0xb1, 0x14, 0x5f, 0xea, 0xc6, 0x52, 0x7a, 0xa9, 0x1b, 0xcb, 0x42, 0xdc, 0x8d,
0x65, 0xf3, 0xdf, 0xe4, 0x60, 0x25, 0x63, 0x11, 0x7f, 0x73, 0x7d, 0x66, 0x6b, 0x2f, 0x46, 0xd6,
0xf2, 0x62, 0xed, 0xe9, 0x14, 0xed, 0x40, 0x2a, 0x76, 0xd9, 0x54, 0x04, 0xe2, 0xa4, 0xba, 0xff,
0x32, 0xea, 0x12, 0xe5, 0x30, 0xf5, 0xec, 0x9b, 0x7f, 0x3f, 0x0f, 0x35, 0x2d, 0x91, 0x8d, 0x22,
0x5f, 0xb2, 0x9a, 0x53, 0x28, 0xe7, 0x2d, 0x51, 0x31, 0x83, 0x57, 0x0b, 0x70, 0x71, 0x62, 0x3a,
0xdf, 0x5c, 0x82, 0x91, 0x44, 0x84, 0x2d, 0x58, 0x91, 0xa6, 0x6c, 0x1a, 0x39, 0xcd, 0x8b, 0xb3,
0x46, 0x78, 0x25, 0x88, 0x46, 0x22, 0xfe, 0x07, 0x52, 0xce, 0x8d, 0xe6, 0x4e, 0x33, 0x0d, 0x2e,
0x0b, 0x7f, 0x08, 0x31, 0x89, 0x6c, 0x9d, 0x7f, 0x08, 0x6b, 0xca, 0x21, 0x22, 0x96, 0x83, 0x1b,
0xa0, 0x88, 0x74, 0x7c, 0xd0, 0xb2, 0x7c, 0x0f, 0x6e, 0x27, 0xda, 0x94, 0xc8, 0xca, 0x35, 0x2d,
0x37, 0x63, 0xad, 0xd3, 0x4b, 0xd8, 0xfc, 0x0b, 0xd0, 0x88, 0x11, 0xca, 0x6f, 0x6e, 0xca, 0x93,
0xca, 0x30, 0x3e, 0xa2, 0xba, 0x32, 0x6c, 0xf3, 0x7f, 0x16, 0x80, 0xa4, 0x69, 0xf5, 0x4f, 0xb3,
0x09, 0xe9, 0x85, 0x59, 0xc8, 0x58, 0x98, 0x7f, 0x66, 0xfc, 0x43, 0xa4, 0x93, 0xd5, 0xfc, 0x11,
0xf8, 0xe6, 0x6c, 0xaa, 0x04, 0xd9, 0x8a, 0x4f, 0x93, 0x5e, 0x5b, 0x95, 0xd8, 0x85, 0x53, 0x8d,
0x81, 0x4a, 0x38, 0x6f, 0x1d, 0xc3, 0x82, 0xed, 0x8e, 0xce, 0x3d, 0x5f, 0xd0, 0xc1, 0x9f, 0xf9,
0xda, 0xc7, 0xe7, 0x56, 0x1b, 0xf3, 0x23, 0xd7, 0x66, 0x8a, 0xc2, 0x8c, 0x0f, 0xa1, 0xa6, 0x81,
0x49, 0x15, 0x4a, 0x07, 0xdd, 0xc3, 0xed, 0x7e, 0xf3, 0x06, 0x69, 0x40, 0xd5, 0xec, 0xec, 0xf4,
0xbf, 0xec, 0x98, 0x9d, 0xdd, 0x66, 0x8e, 0x54, 0xa0, 0x78, 0xd0, 0x1f, 0x0c, 0x9b, 0x79, 0x63,
0x13, 0x5a, 0xa2, 0xc4, 0xb4, 0x75, 0xea, 0xb7, 0x8a, 0x4a, 0xa7, 0x8a, 0x89, 0x42, 0xc8, 0xff,
0x08, 0xea, 0x3a, 0x7b, 0x23, 0x56, 0x44, 0xc2, 0x25, 0x86, 0x89, 0xf7, 0x9e, 0x46, 0xab, 0x77,
0x80, 0x3b, 0x44, 0x8c, 0x55, 0xb6, 0x7c, 0x8c, 0x6f, 0xcd, 0xb0, 0x2c, 0xa3, 0x7c, 0x14, 0x5b,
0x86, 0x7f, 0x0e, 0x16, 0xe3, 0x96, 0x18, 0x41, 0x91, 0xb2, 0x44, 0x56, 0x96, 0x3b, 0x66, 0x9a,
0x21, 0xdf, 0x83, 0x66, 0xd2, 0x92, 0x23, 0x98, 0xe7, 0x6b, 0xf2, 0x2f, 0x39, 0x71, 0xe3, 0x0e,
0xd9, 0x87, 0xd5, 0x2c, 0x06, 0x0f, 0xd7, 0xc7, 0xf5, 0x6a, 0x0e, 0x92, 0x66, 0xe2, 0xc8, 0x67,
0xc2, 0xa2, 0x57, 0xc2, 0xe9, 0x7f, 0x2b, 0x5e, 0xbf, 0x36, 0xd8, 0x5b, 0xfc, 0x9f, 0x66, 0xdb,
0xbb, 0x00, 0x88, 0x60, 0xa4, 0x09, 0xf5, 0xfe, 0x51, 0xa7, 0x67, 0xed, 0xec, 0xb7, 0x7b, 0xbd,
0xce, 0x41, 0xf3, 0x06, 0x21, 0xb0, 0x88, 0x5e, 0x1d, 0xbb, 0x0a, 0x96, 0x63, 0x30, 0x61, 0x6a,
0x95, 0xb0, 0x3c, 0x59, 0x85, 0x66, 0xb7, 0x97, 0x80, 0x16, 0x48, 0x0b, 0x56, 0x8f, 0x3a, 0xdc,
0x11, 0x24, 0x56, 0x6e, 0x91, 0x09, 0x0d, 0xa2, 0xbb, 0x46, 0x08, 0xab, 0x5f, 0xd9, 0x93, 0x09,
0x0d, 0xdb, 0xdc, 0x91, 0x5d, 0x6e, 0x87, 0x77, 0x61, 0x59, 0xa9, 0xc3, 0x12, 0xdc, 0x72, 0x53,
0x25, 0x48, 0xe4, 0x0f, 0x60, 0x45, 0xd3, 0xaa, 0x25, 0x4e, 0x21, 0xa2, 0x25, 0x89, 0x0c, 0x4c,
0x54, 0xe1, 0xb5, 0x0a, 0x80, 0xe4, 0xe0, 0xff, 0x30, 0x0f, 0x6b, 0x89, 0x84, 0xc8, 0x08, 0xc3,
0xf9, 0xf7, 0x78, 0x5b, 0xea, 0x08, 0x7c, 0x61, 0xa3, 0xf3, 0x5f, 0xaf, 0xd1, 0x85, 0xeb, 0x1a,
0x4d, 0x9e, 0xc2, 0x92, 0xf0, 0xf6, 0xd7, 0x78, 0x3c, 0x46, 0x23, 0x1e, 0x88, 0x29, 0xcf, 0x6c,
0xf9, 0x56, 0x7c, 0x60, 0xb9, 0x95, 0x6b, 0xd1, 0x8e, 0x01, 0x37, 0x7f, 0x09, 0x56, 0x32, 0xd0,
0x32, 0xee, 0xbc, 0x7c, 0x18, 0xb7, 0x78, 0xdd, 0x8a, 0xd5, 0x1c, 0x2f, 0x42, 0xb7, 0xde, 0x6f,
0xc1, 0x82, 0xd0, 0xf6, 0x36, 0xa1, 0x20, 0xaf, 0x3d, 0x15, 0x4d, 0xf6, 0x93, 0x10, 0x28, 0x4e,
0x23, 0x07, 0x6c, 0xfc, 0x6d, 0x6c, 0xa8, 0x0b, 0x8c, 0x89, 0x09, 0xfa, 0x95, 0x22, 0xac, 0x27,
0x53, 0xd4, 0x95, 0x84, 0x72, 0x6c, 0x6e, 0xb8, 0x25, 0x51, 0x80, 0xc8, 0xc7, 0x89, 0xed, 0x16,
0x9b, 0x1d, 0x44, 0xd5, 0xb7, 0x96, 0x1c, 0xf2, 0x87, 0x49, 0xa6, 0x9a, 0xd3, 0x88, 0x86, 0xbc,
0xa0, 0x81, 0x7d, 0x4a, 0xf0, 0xd8, 0x1f, 0xa7, 0x78, 0xec, 0x62, 0x56, 0xa6, 0x04, 0xcb, 0xdd,
0x81, 0x8d, 0xc8, 0xd5, 0x38, 0x5e, 0x67, 0x29, 0x2b, 0xfb, 0x9a, 0xc2, 0x3e, 0xd0, 0x2b, 0x7f,
0x0c, 0xad, 0xa8, 0x98, 0x44, 0x33, 0x16, 0xb2, 0xca, 0x59, 0x57, 0xe8, 0x66, 0xac, 0x3d, 0xdf,
0x87, 0xcd, 0xd8, 0x78, 0xc5, 0x9b, 0x54, 0xce, 0x2a, 0x6a, 0x43, 0x1b, 0xc0, 0x58, 0xa3, 0x0e,
0xe0, 0x56, 0xac, 0xac, 0x44, 0xbb, 0x2a, 0x59, 0x85, 0xb5, 0xb4, 0xc2, 0x62, 0x2d, 0x33, 0x7e,
0x67, 0x01, 0xc8, 0x0f, 0xe6, 0xd4, 0xbf, 0xc2, 0x6b, 0xcd, 0xc1, 0xcb, 0xee, 0x50, 0x48, 0x4d,
0x65, 0xfe, 0x95, 0xa2, 0x1b, 0x64, 0x45, 0x17, 0x28, 0xbe, 0x3c, 0xba, 0x40, 0xe9, 0x65, 0xd1,
0x05, 0xde, 0x84, 0x86, 0x73, 0xe6, 0x7a, 0x8c, 0x11, 0x60, 0x72, 0x60, 0xd0, 0x5a, 0xb8, 0x5b,
0xb8, 0x57, 0x37, 0xeb, 0x02, 0xc8, 0xa4, 0xc0, 0x80, 0x7c, 0x11, 0x21, 0xd1, 0xf1, 0x19, 0xc6,
0xde, 0xd0, 0x59, 0x80, 0xce, 0xf8, 0x8c, 0x0a, 0xc5, 0x2c, 0x2e, 0x58, 0x99, 0x99, 0xc1, 0x03,
0xf2, 0x16, 0x2c, 0x06, 0xde, 0x9c, 0x89, 0xd5, 0x72, 0x18, 0xb8, 0xbd, 0xbf, 0xce, 0xa1, 0x47,
0xd2, 0xfb, 0x63, 0x65, 0x1e, 0x50, 0x6b, 0xea, 0x04, 0x01, 0x13, 0x4e, 0x46, 0x9e, 0x1b, 0xfa,
0xde, 0x44, 0x98, 0xf0, 0x97, 0xe7, 0x01, 0x3d, 0xe4, 0x29, 0x3b, 0x3c, 0x81, 0x7c, 0x1c, 0x35,
0x69, 0x66, 0x3b, 0x7e, 0xd0, 0x02, 0x6c, 0x92, 0xec, 0x29, 0x4a, 0xaf, 0xb6, 0xe3, 0xab, 0xb6,
0xb0, 0x8f, 0x20, 0x11, 0xf5, 0xa0, 0x96, 0x8c, 0x7a, 0xf0, 0xcb, 0xd9, 0x51, 0x0f, 0x1a, 0x31,
0x62, 0x96, 0x9e, 0xe2, 0xaf, 0x15, 0xfc, 0x20, 0x1d, 0xcc, 0x61, 0xf1, 0xeb, 0x04, 0x73, 0x58,
0xca, 0x0a, 0xe6, 0xf0, 0x21, 0xd4, 0xf0, 0x0e, 0xbd, 0x75, 0x8e, 0xce, 0xcc, 0xdc, 0x25, 0xa1,
0xa9, 0x5f, 0xb2, 0xdf, 0x77, 0xdc, 0xd0, 0x04, 0x5f, 0xfe, 0x0c, 0xd2, 0x71, 0x15, 0x96, 0x5f,
0x29, 0xae, 0xc2, 0x37, 0x13, 0x34, 0x41, 0xdc, 0xf5, 0xdf, 0x82, 0x8a, 0x9c, 0x27, 0x46, 0x6c,
0x4f, 0x7d, 0x6f, 0x2a, 0xcd, 0x9b, 0xec, 0x37, 0x59, 0x84, 0x7c, 0xe8, 0x89, 0xcc, 0xf9, 0xd0,
0x33, 0x7e, 0x11, 0x6a, 0xda, 0x52, 0x23, 0x6f, 0x70, 0xbd, 0xbe, 0x4b, 0x27, 0x52, 0xed, 0xcb,
0x47, 0xb1, 0x2a, 0xa0, 0xdd, 0x31, 0x3b, 0xf7, 0xc6, 0x8e, 0x4f, 0x31, 0x02, 0x8a, 0xe5, 0xd3,
0x0b, 0xea, 0x07, 0xd2, 0x2c, 0xdd, 0x54, 0x09, 0x26, 0x87, 0x1b, 0xbf, 0x04, 0x2b, 0xb1, 0xb9,
0x15, 0xe4, 0xfb, 0x2d, 0x58, 0xc0, 0x71, 0x93, 0xbe, 0x4f, 0xf1, 0xe0, 0x05, 0x22, 0x0d, 0xe3,
0xc0, 0x70, 0x8b, 0xba, 0x35, 0xf3, 0xbd, 0x13, 0xac, 0x24, 0x67, 0xd6, 0x04, 0xec, 0xc8, 0xf7,
0x4e, 0x8c, 0xbf, 0x52, 0x84, 0xc2, 0xbe, 0x37, 0xd3, 0x1d, 0xa0, 0x73, 0x29, 0x07, 0x68, 0xa1,
0x6e, 0xb1, 0x94, 0x3a, 0x45, 0x48, 0xac, 0x68, 0x23, 0x96, 0x2a, 0x95, 0x7b, 0xb0, 0xc8, 0xe8,
0x44, 0xe8, 0x59, 0xe2, 0xe2, 0x11, 0x3f, 0x9c, 0xf9, 0xe6, 0xb3, 0xa7, 0xe1, 0xd0, 0xdb, 0xe3,
0x70, 0xb2, 0x0a, 0x05, 0x25, 0xbc, 0x63, 0x32, 0xfb, 0x24, 0xeb, 0xb0, 0x80, 0x17, 0xa6, 0xe4,
0x4d, 0x77, 0xf1, 0x45, 0xde, 0x87, 0x95, 0x78, 0xb9, 0x9c, 0x14, 0x09, 0xc9, 0x40, 0x2f, 0x18,
0x69, 0xd2, 0x4d, 0x60, 0x74, 0x24, 0xba, 0xeb, 0x5e, 0x30, 0xcb, 0xa7, 0x94, 0x62, 0x92, 0x46,
0xf4, 0x2a, 0x31, 0xa2, 0x77, 0x07, 0x6a, 0xe1, 0xe4, 0xc2, 0x9a, 0xd9, 0x57, 0x13, 0xcf, 0x96,
0x37, 0x2b, 0x21, 0x9c, 0x5c, 0x1c, 0x71, 0x08, 0xf9, 0x00, 0x60, 0x3a, 0x9b, 0x89, 0xbd, 0x87,
0xf6, 0xcc, 0x68, 0x29, 0x1f, 0x1e, 0x1d, 0xf1, 0x25, 0x67, 0x56, 0xa7, 0xb3, 0x19, 0xff, 0xc9,
0x32, 0xd8, 0x53, 0x95, 0xa1, 0x1e, 0xcb, 0xd0, 0x3e, 0x54, 0x19, 0xec, 0xa9, 0xcc, 0xb0, 0x0b,
0x8b, 0x99, 0x61, 0x4d, 0x6e, 0xcb, 0x7b, 0x28, 0xde, 0x6c, 0x2b, 0x63, 0x37, 0x37, 0x46, 0x3a,
0x6c, 0xf3, 0x7b, 0x40, 0x7e, 0xc2, 0xc8, 0x21, 0x43, 0xa8, 0xaa, 0x0e, 0xa5, 0xe2, 0x95, 0xd4,
0x52, 0xf1, 0x4a, 0x18, 0x21, 0xe5, 0x9c, 0x9e, 0x3a, 0x23, 0x40, 0x63, 0xf5, 0xc4, 0x0d, 0x2e,
0xe3, 0x04, 0xaa, 0xaa, 0xd7, 0x68, 0x93, 0xf2, 0xbc, 0xd0, 0x0a, 0xce, 0x6d, 0x71, 0x1d, 0xb2,
0x6e, 0x56, 0x19, 0x64, 0xc0, 0x00, 0x64, 0x0d, 0x16, 0x02, 0x1a, 0x46, 0x56, 0x87, 0x52, 0x40,
0x43, 0x6e, 0x82, 0x1a, 0x9d, 0x3b, 0x93, 0x71, 0xec, 0x26, 0x3d, 0x20, 0x88, 0x9b, 0xf5, 0xfe,
0x4b, 0x0e, 0x4a, 0x3c, 0xd2, 0xc8, 0xdb, 0xb0, 0xc4, 0xdb, 0xa4, 0x3c, 0xdc, 0x85, 0x1b, 0x12,
0x67, 0x4a, 0x87, 0xc2, 0xb9, 0x9d, 0xed, 0x55, 0x2d, 0x74, 0x53, 0xc4, 0xdb, 0x68, 0xe1, 0x9b,
0xee, 0x40, 0x55, 0x75, 0x4f, 0x5b, 0xcf, 0x15, 0xd9, 0x3b, 0xf2, 0x3a, 0x14, 0xcf, 0xbd, 0x99,
0x54, 0xc6, 0x42, 0x34, 0x5b, 0x26, 0xc2, 0xa3, 0xb6, 0xb0, 0x3a, 0xa2, 0xdb, 0x6b, 0x05, 0xd1,
0x16, 0x56, 0x89, 0x8c, 0xbf, 0x90, 0x18, 0xc7, 0x85, 0x8c, 0x71, 0x3c, 0x86, 0x25, 0x46, 0x9c,
0x34, 0x5f, 0xa8, 0xeb, 0x4f, 0xf2, 0x6f, 0x33, 0xa1, 0x6b, 0x34, 0x99, 0x8f, 0xa9, 0xae, 0x0e,
0x47, 0x77, 0x65, 0x01, 0x97, 0xc2, 0xae, 0xf1, 0x3b, 0x39, 0x4e, 0xf4, 0x58, 0xb9, 0xe4, 0x1e,
0x14, 0x5d, 0xe9, 0x37, 0x15, 0x89, 0x56, 0xea, 0xa6, 0x27, 0xc3, 0x33, 0x11, 0x83, 0x2d, 0x0f,
0xf4, 0x36, 0xd2, 0x4b, 0x6f, 0x98, 0x35, 0x77, 0x3e, 0x55, 0xda, 0xe4, 0x6f, 0xc9, 0x6e, 0x25,
0x34, 0xb1, 0xbc, 0xf7, 0x8a, 0x76, 0x6c, 0x69, 0x7e, 0xcf, 0xc5, 0xd8, 0x31, 0x2e, 0x05, 0xb3,
0xf1, 0x19, 0xd5, 0xfc, 0x9d, 0x7f, 0x3f, 0x0f, 0x8d, 0x58, 0x8b, 0xd0, 0xf1, 0x9b, 0x9d, 0x4a,
0xdc, 0x5a, 0x2c, 0xe6, 0x1b, 0xfd, 0x6b, 0x85, 0xec, 0xac, 0x8d, 0x53, 0x3e, 0x36, 0x4e, 0xca,
0xf1, 0xb1, 0xa0, 0x3b, 0x3e, 0x3e, 0x80, 0x6a, 0x14, 0xb2, 0x2b, 0xde, 0x24, 0x56, 0x9f, 0xbc,
0xef, 0x1a, 0x21, 0x45, 0xae, 0x92, 0x25, 0xdd, 0x55, 0xf2, 0xbb, 0x9a, 0x67, 0xdd, 0x02, 0x16,
0x63, 0x64, 0x8d, 0xe8, 0x4f, 0xc5, 0xaf, 0xce, 0xf8, 0x02, 0x6a, 0x5a, 0xe3, 0x75, 0xef, 0xb4,
0x5c, 0xcc, 0x3b, 0x4d, 0xdd, 0xaa, 0xcf, 0x47, 0xb7, 0xea, 0x8d, 0x5f, 0xcb, 0x43, 0x83, 0xed,
0x2f, 0xc7, 0x3d, 0x3b, 0xf2, 0x26, 0xce, 0x08, 0xad, 0xc7, 0x6a, 0x87, 0x09, 0xee, 0x4f, 0xee,
0x33, 0xb1, 0xc5, 0x38, 0xf3, 0xa7, 0x87, 0x82, 0xe1, 0x27, 0x87, 0x0a, 0x05, 0x63, 0x40, 0x83,
0x51, 0x6b, 0xb4, 0x03, 0x47, 0xe1, 0xbd, 0xcc, 0xda, 0x29, 0xa5, 0xdb, 0x76, 0xc0, 0xc9, 0xf6,
0xfb, 0xb0, 0xc2, 0x70, 0x30, 0xce, 0xc3, 0xd4, 0x99, 0x4c, 0x9c, 0xe8, 0xba, 0x68, 0xc1, 0x6c,
0x9e, 0x52, 0x6a, 0xda, 0x21, 0x3d, 0x64, 0x09, 0x22, 0x1a, 0x58, 0x65, 0xec, 0x04, 0xf6, 0x49,
0xe4, 0x9e, 0xaf, 0xbe, 0xa5, 0x7b, 0x45, 0xe4, 0xc1, 0x22, 0xbc, 0xaf, 0x44, 0x90, 0x13, 0xcc,
0x9f, 0x58, 0x49, 0xe5, 0xe4, 0x4a, 0x32, 0xfe, 0x49, 0x1e, 0x6a, 0xda, 0xb2, 0x7c, 0x95, 0x23,
0xff, 0x76, 0xca, 0xda, 0x5f, 0xd5, 0x0d, 0xfb, 0x6f, 0xc6, 0xab, 0x2c, 0xa8, 0x3b, 0x85, 0xfa,
0x02, 0xbe, 0x05, 0x55, 0xb6, 0xeb, 0x3e, 0x44, 0xab, 0x88, 0x88, 0xd3, 0x87, 0x80, 0xa3, 0xf9,
0x89, 0x4c, 0x7c, 0x88, 0x89, 0xa5, 0x28, 0xf1, 0x21, 0x4b, 0x7c, 0xd1, 0x9d, 0xa2, 0x4f, 0xa1,
0x2e, 0x4a, 0xc5, 0x39, 0x15, 0xb2, 0xca, 0xaa, 0xc6, 0x4e, 0xa8, 0xf9, 0x36, 0x6b, 0xbc, 0x3a,
0x3e, 0xf9, 0x22, 0xe3, 0x43, 0x99, 0xb1, 0xf2, 0xb2, 0x8c, 0x0f, 0xf9, 0x87, 0xb1, 0xa7, 0xae,
0x69, 0xa1, 0x4f, 0xab, 0xa4, 0x63, 0x1f, 0xc0, 0x8a, 0x24, 0x57, 0x73, 0xd7, 0x76, 0x5d, 0x6f,
0xee, 0x8e, 0xa8, 0xbc, 0xb2, 0x4e, 0x44, 0xd2, 0x71, 0x94, 0x62, 0x8c, 0x55, 0x00, 0x19, 0xee,
0x1b, 0x7b, 0x1f, 0x4a, 0x5c, 0x58, 0xe0, 0x1c, 0x51, 0x36, 0xe1, 0xe2, 0x28, 0xe4, 0x1e, 0x94,
0xb8, 0xcc, 0x90, 0xbf, 0x96, 0xd8, 0x70, 0x04, 0xa3, 0x0d, 0x84, 0x65, 0x3c, 0xa4, 0xa1, 0xef,
0x8c, 0x82, 0xe8, 0x36, 0x7c, 0x29, 0xbc, 0x9a, 0x89, 0xba, 0x22, 0x63, 0x4a, 0x84, 0x89, 0x6a,
0x23, 0x8e, 0xc3, 0x0e, 0xa6, 0x95, 0x58, 0x19, 0x82, 0x87, 0x9b, 0xc0, 0xfa, 0x09, 0x0d, 0x9f,
0x53, 0xea, 0xba, 0x8c, 0x43, 0x1b, 0x51, 0x37, 0xf4, 0xed, 0x09, 0x9b, 0x24, 0xde, 0x83, 0x47,
0xa9, 0x52, 0x23, 0xb5, 0xe4, 0x76, 0x94, 0x71, 0x47, 0xe5, 0xe3, 0xb4, 0x63, 0xed, 0x24, 0x2b,
0x6d, 0xf3, 0x17, 0x60, 0xf3, 0xfa, 0x4c, 0x19, 0xba, 0x8b, 0x7b, 0x71, 0xaa, 0xa2, 0x4c, 0xf3,
0x13, 0xcf, 0x0e, 0x79, 0x6b, 0x74, 0xca, 0xd2, 0x83, 0x9a, 0x96, 0x12, 0xf1, 0x17, 0x39, 0xe4,
0x38, 0xf9, 0x07, 0x3b, 0x91, 0x5c, 0xcf, 0x9f, 0xa2, 0x29, 0x7c, 0x6c, 0x45, 0xa5, 0xe7, 0xcc,
0xa5, 0x08, 0x8e, 0xde, 0x53, 0xc6, 0x16, 0x2c, 0xa1, 0xb8, 0xa1, 0x1d, 0x74, 0x2f, 0xe2, 0x50,
0x8d, 0x55, 0x20, 0x3d, 0x4e, 0xbb, 0x74, 0x3f, 0xe1, 0x3f, 0x2c, 0x40, 0x4d, 0x03, 0xb3, 0xd3,
0x08, 0x9d, 0xab, 0xad, 0xb1, 0x63, 0x4f, 0xa9, 0xf4, 0x3b, 0x68, 0x98, 0x0d, 0x84, 0xee, 0x0a,
0x20, 0x3b, 0x8b, 0xed, 0x8b, 0x33, 0xcb, 0x9b, 0x87, 0xd6, 0x98, 0x9e, 0xf9, 0x54, 0xb6, 0xb2,
0x6e, 0x5f, 0x9c, 0xf5, 0xe7, 0xe1, 0x2e, 0xc2, 0x64, 0xc4, 0x24, 0x0d, 0xab, 0xa0, 0x22, 0x26,
0x45, 0x58, 0xc2, 0x29, 0x9d, 0xaf, 0xcc, 0xa2, 0x72, 0x4a, 0xe7, 0x22, 0x6c, 0xf2, 0x00, 0x2d,
0xa5, 0x0f, 0xd0, 0x8f, 0x61, 0x9d, 0x1f, 0xa0, 0x82, 0x34, 0x5b, 0x89, 0x9d, 0xbc, 0x8a, 0xa9,
0xa2, 0x93, 0x1a, 0x2f, 0xde, 0x64, 0x3d, 0x90, 0x64, 0x29, 0x70, 0x7e, 0xc4, 0x09, 0x59, 0xce,
0x64, 0x3d, 0x13, 0x85, 0x0f, 0x9c, 0x1f, 0x51, 0x19, 0xb1, 0x29, 0x86, 0x29, 0x6e, 0x0c, 0x4e,
0x1d, 0x37, 0x89, 0x69, 0x5f, 0xc6, 0x31, 0xab, 0x02, 0xd3, 0xbe, 0xd4, 0x31, 0x1f, 0xc1, 0xc6,
0x94, 0x8e, 0x1d, 0x3b, 0x5e, 0xac, 0x15, 0x31, 0x87, 0xab, 0x3c, 0x59, 0xcb, 0x33, 0xe0, 0xda,
0x04, 0x36, 0x1a, 0x3f, 0xf2, 0xa6, 0x27, 0x0e, 0xe7, 0x59, 0xb8, 0x5f, 0x60, 0xd1, 0x5c, 0x74,
0xe7, 0xd3, 0x9f, 0x47, 0x30, 0xcb, 0x12, 0x18, 0x0d, 0xa8, 0x0d, 0x42, 0x6f, 0x26, 0xa7, 0x79,
0x11, 0xea, 0xfc, 0x53, 0x44, 0x7b, 0xb8, 0x05, 0x37, 0x91, 0x24, 0x0c, 0xbd, 0x99, 0x37, 0xf1,
0xce, 0xae, 0x62, 0xaa, 0xf5, 0x7f, 0x95, 0x83, 0x95, 0x58, 0xaa, 0x20, 0xaf, 0x1f, 0x73, 0x7a,
0xa6, 0x6e, 0x8a, 0xe7, 0x62, 0xd7, 0x04, 0xd9, 0x7c, 0x71, 0x44, 0x4e, 0xcc, 0xe4, 0xed, 0xf1,
0x76, 0x14, 0x0e, 0x4d, 0x66, 0xe4, 0x24, 0xa5, 0x95, 0x26, 0x29, 0x22, 0xbf, 0x0c, 0x94, 0x26,
0x8b, 0xf8, 0x19, 0x71, 0xab, 0x73, 0x2c, 0xba, 0x5c, 0x88, 0xdf, 0xfb, 0xd2, 0xd5, 0xf0, 0xb2,
0x05, 0x91, 0x6e, 0x3e, 0x30, 0x7e, 0x37, 0x0f, 0x10, 0xb5, 0x0e, 0x6f, 0x9e, 0x29, 0xbe, 0x25,
0x87, 0x2e, 0xfe, 0x1a, 0x8f, 0xf2, 0x06, 0xd4, 0xd5, 0x6d, 0x90, 0x88, 0x13, 0xaa, 0x49, 0x18,
0x63, 0x87, 0xde, 0x85, 0xa5, 0xb3, 0x89, 0x77, 0x82, 0x1c, 0xab, 0xe0, 0x5b, 0xd0, 0xb1, 0x07,
0xcf, 0xa3, 0x45, 0x9e, 0xa4, 0x02, 0x1a, 0x2a, 0xde, 0xa9, 0x98, 0x79, 0x69, 0x24, 0xc6, 0x09,
0x7d, 0x91, 0xe2, 0x84, 0xee, 0xa4, 0x06, 0xf7, 0xa7, 0xc3, 0x06, 0xfd, 0xb5, 0xbc, 0x72, 0x80,
0x8f, 0xe6, 0xe5, 0xc5, 0x12, 0xf0, 0x8f, 0xe3, 0xae, 0xf7, 0x22, 0xff, 0x83, 0x2f, 0x60, 0xd1,
0xe7, 0x47, 0xa4, 0x3c, 0x3f, 0x8b, 0x2f, 0x38, 0x3f, 0x1b, 0x7e, 0x8c, 0xef, 0xfa, 0x36, 0x34,
0xed, 0xf1, 0x05, 0xf5, 0x43, 0x07, 0xcd, 0x79, 0xc8, 0xad, 0x0b, 0x77, 0x73, 0x0d, 0x8e, 0x6c,
0xf1, 0x3b, 0xb0, 0x24, 0xe2, 0xa1, 0x28, 0x4c, 0x11, 0x28, 0x34, 0x02, 0x33, 0x44, 0xe3, 0x1f,
0x49, 0x8f, 0xfb, 0xf8, 0x5a, 0x7b, 0xf1, 0xa8, 0xe8, 0x3d, 0xcc, 0xa7, 0x3d, 0x2c, 0xc4, 0xb2,
0x16, 0x56, 0x42, 0x41, 0x1d, 0x39, 0x50, 0xd8, 0x08, 0xe3, 0xc3, 0x5a, 0x7c, 0x95, 0x61, 0x35,
0xfe, 0x75, 0x0e, 0xca, 0xfb, 0xde, 0x6c, 0xdf, 0xe1, 0xf7, 0xb6, 0x70, 0xd3, 0x2a, 0x23, 0xf6,
0x02, 0xfb, 0x44, 0xdf, 0xc2, 0x17, 0xdc, 0xe7, 0xce, 0x64, 0x3a, 0x1b, 0x71, 0xa6, 0xf3, 0xbb,
0x70, 0x0b, 0x7d, 0x04, 0x7c, 0x6f, 0xe6, 0xf9, 0x8c, 0x70, 0xd8, 0x13, 0xce, 0x7c, 0x7a, 0x6e,
0x78, 0x2e, 0x29, 0xf9, 0xcd, 0x53, 0x4a, 0x8f, 0x34, 0x8c, 0x43, 0x85, 0x80, 0xb1, 0x1c, 0x26,
0xe1, 0x85, 0xc5, 0x95, 0x18, 0x82, 0x3b, 0xe6, 0xf4, 0x7d, 0x89, 0x25, 0x74, 0x10, 0x8e, 0xfc,
0xb1, 0xf1, 0x19, 0x54, 0x95, 0x3e, 0x8c, 0xbc, 0x0b, 0xd5, 0x73, 0x6f, 0x26, 0x94, 0x66, 0xb9,
0xd8, 0x9d, 0x77, 0xd1, 0x6b, 0xb3, 0x72, 0xce, 0x7f, 0x04, 0xc6, 0xff, 0x2b, 0x43, 0xb9, 0xeb,
0x5e, 0x78, 0xce, 0x08, 0x7d, 0xf1, 0xa7, 0x74, 0xea, 0xc9, 0x10, 0x4f, 0xec, 0x37, 0x8a, 0xda,
0x51, 0x2c, 0xcf, 0x82, 0x10, 0xb5, 0x55, 0x14, 0xcf, 0x35, 0x58, 0xf0, 0xf5, 0x60, 0x9c, 0x25,
0x1f, 0x6f, 0x3a, 0xa9, 0xd3, 0xbb, 0xa4, 0x85, 0xea, 0x62, 0x65, 0x71, 0xf7, 0x67, 0x1c, 0x32,
0x1e, 0x8f, 0xa1, 0x8a, 0x10, 0x1c, 0xb0, 0xd7, 0xa0, 0x2c, 0x54, 0xe3, 0xfc, 0xc2, 0x2b, 0x37,
0x28, 0x08, 0x10, 0xae, 0x06, 0x9f, 0x72, 0x1f, 0x0f, 0xc5, 0x56, 0x17, 0xcc, 0xba, 0x04, 0xee,
0xda, 0xdc, 0xc1, 0x9e, 0xe3, 0x73, 0x14, 0x7e, 0x0c, 0x01, 0x07, 0x21, 0x42, 0x46, 0xd8, 0xdb,
0x6a, 0x66, 0xd8, 0x5b, 0xbc, 0x90, 0xa1, 0x68, 0x3e, 0xef, 0x22, 0xf0, 0x48, 0xa6, 0x1a, 0x5c,
0x46, 0x99, 0x16, 0x6a, 0x27, 0x1e, 0xaa, 0x44, 0xaa, 0x9d, 0xde, 0x84, 0xc6, 0xa9, 0x3d, 0x99,
0x9c, 0xd8, 0xa3, 0x67, 0x5c, 0xf9, 0x51, 0xe7, 0x0a, 0x62, 0x09, 0x44, 0xed, 0xc7, 0x1d, 0xa8,
0x69, 0xb3, 0x8c, 0x7e, 0xe7, 0x45, 0x13, 0xa2, 0xf9, 0x4d, 0x2a, 0x41, 0x17, 0x5f, 0x41, 0x09,
0xaa, 0xf9, 0xdf, 0x2f, 0xc5, 0xfd, 0xef, 0x6f, 0x21, 0x6d, 0x17, 0x0a, 0x90, 0x26, 0x0f, 0x9b,
0x69, 0x8f, 0xb9, 0xfa, 0x03, 0x75, 0x7d, 0x7c, 0xf0, 0x78, 0xfa, 0xb2, 0xb8, 0xc0, 0x80, 0x30,
0x8e, 0x72, 0x9b, 0x6b, 0xf2, 0x67, 0xb6, 0x33, 0xc6, 0xeb, 0x65, 0xc2, 0xe8, 0x63, 0x4f, 0xc3,
0x23, 0xdb, 0x41, 0x7f, 0x4e, 0x99, 0x8c, 0x67, 0xf5, 0x0a, 0x1f, 0x7f, 0x91, 0x3c, 0xe0, 0x81,
0x78, 0x14, 0xc6, 0x54, 0xc5, 0x1a, 0x31, 0x6b, 0x02, 0x05, 0xd7, 0xc1, 0x87, 0xe8, 0x06, 0x18,
0x52, 0x8c, 0x26, 0xb2, 0xa8, 0x6c, 0x5e, 0x62, 0x95, 0xca, 0xff, 0xdc, 0x7a, 0xce, 0x31, 0x19,
0xab, 0xc9, 0x8d, 0xf8, 0xeb, 0x31, 0x6e, 0x5c, 0xa0, 0xa2, 0x11, 0x9f, 0x23, 0x90, 0xcf, 0xb4,
0x33, 0xa4, 0x85, 0xc8, 0xaf, 0x25, 0xca, 0xbf, 0xee, 0x42, 0xef, 0x6d, 0x00, 0x27, 0x60, 0x67,
0x5e, 0x40, 0xdd, 0x31, 0x06, 0x05, 0xa9, 0x98, 0x55, 0x27, 0x78, 0xc2, 0x01, 0x29, 0x4d, 0xd7,
0x66, 0x3a, 0x32, 0xef, 0x37, 0x7a, 0x04, 0xb5, 0xa1, 0xae, 0x8f, 0x04, 0xa9, 0x40, 0xb1, 0x7f,
0xd4, 0xe9, 0x35, 0x6f, 0x90, 0x1a, 0x94, 0x07, 0x9d, 0xe1, 0xf0, 0x00, 0xbd, 0x05, 0xea, 0x50,
0x51, 0x51, 0x01, 0xf2, 0xec, 0xab, 0xbd, 0xb3, 0xd3, 0x39, 0x1a, 0x76, 0x76, 0x9b, 0x85, 0xef,
0x17, 0x2b, 0xf9, 0x66, 0xc1, 0xf8, 0x3f, 0x05, 0xa8, 0x69, 0x03, 0xf5, 0x62, 0x7a, 0x1d, 0x8f,
0x3f, 0x95, 0x4f, 0xc6, 0x9f, 0xd2, 0x2d, 0x3d, 0x22, 0x46, 0x97, 0xb4, 0xf4, 0xbc, 0x09, 0x0d,
0x11, 0xd4, 0x53, 0xf3, 0xf9, 0x28, 0x99, 0x75, 0x0e, 0x14, 0xd4, 0x1c, 0x63, 0x8c, 0x20, 0x12,
0xde, 0xde, 0x2e, 0x89, 0xf5, 0x83, 0x20, 0xbc, 0xbf, 0x8d, 0x97, 0xef, 0x03, 0x6f, 0x72, 0x41,
0x39, 0x06, 0x67, 0x61, 0x6b, 0x02, 0x36, 0x14, 0xf1, 0x5b, 0x04, 0xc9, 0xd4, 0x82, 0x5c, 0x94,
0xcc, 0x3a, 0x07, 0x8a, 0x8a, 0xde, 0x97, 0x6b, 0x8c, 0x7b, 0xc0, 0x6d, 0xa4, 0x17, 0x4c, 0x6c,
0x7d, 0x1d, 0xa4, 0x74, 0xab, 0x55, 0x5c, 0x3b, 0xdf, 0x4a, 0xe7, 0x7b, 0xb9, 0x8e, 0x95, 0xbc,
0x0b, 0x64, 0x3a, 0x9b, 0x59, 0x19, 0x5a, 0xcf, 0xa2, 0xb9, 0x34, 0x9d, 0xcd, 0x86, 0x9a, 0xc2,
0x8e, 0xbc, 0x06, 0x05, 0x7b, 0x3a, 0x43, 0xd2, 0x12, 0x69, 0x07, 0xdb, 0x87, 0x47, 0x26, 0x03,
0x7f, 0x03, 0xea, 0xda, 0xdf, 0xcc, 0x41, 0xa1, 0x7d, 0x78, 0xf4, 0x67, 0xa4, 0x53, 0xc5, 0x80,
0xa3, 0xd1, 0xf1, 0x80, 0xbf, 0xf9, 0x75, 0x48, 0x71, 0xa2, 0xf0, 0xcb, 0x02, 0xea, 0xdb, 0xf8,
0xeb, 0x39, 0x20, 0x6d, 0x46, 0x91, 0x70, 0x40, 0x95, 0xa4, 0x1b, 0x9d, 0x33, 0x39, 0xfd, 0x9c,
0xc9, 0x20, 0xe7, 0xf9, 0x4c, 0x72, 0xfe, 0x32, 0xc2, 0x17, 0xdb, 0xba, 0xcb, 0xa9, 0xad, 0x6b,
0xec, 0x41, 0xed, 0x48, 0x0b, 0x16, 0x7d, 0x97, 0x9d, 0x8a, 0x32, 0x4c, 0x34, 0x3f, 0x2f, 0xb9,
0x56, 0xd7, 0x17, 0xd1, 0xa1, 0xb5, 0x06, 0xe7, 0xb5, 0x06, 0x1b, 0x7f, 0x37, 0xc7, 0x43, 0x26,
0xaa, 0xfe, 0x45, 0xf1, 0xa9, 0xa5, 0xc5, 0x36, 0x0a, 0xae, 0x53, 0x93, 0x36, 0x59, 0x11, 0x17,
0x07, 0x5b, 0x6f, 0x79, 0xa7, 0xa7, 0x01, 0x95, 0x8e, 0x6f, 0x35, 0x84, 0xf5, 0x11, 0x24, 0xc5,
0x1f, 0x26, 0x63, 0x39, 0xbc, 0xfc, 0x40, 0x78, 0xbb, 0x31, 0xf1, 0xe7, 0xd0, 0xbe, 0x14, 0xb5,
0x06, 0x6c, 0x06, 0x84, 0xd9, 0x48, 0x06, 0x97, 0x50, 0xdf, 0xc6, 0xdf, 0x12, 0xf1, 0x7f, 0x92,
0x53, 0x70, 0x1f, 0x2a, 0xaa, 0xd4, 0x38, 0x57, 0x21, 0x31, 0x55, 0x3a, 0xe3, 0x5d, 0x50, 0x1d,
0x15, 0x6b, 0x31, 0xa7, 0x16, 0x68, 0xfa, 0xeb, 0x6a, 0xad, 0x7e, 0x0f, 0xc8, 0xa9, 0xe3, 0x27,
0x91, 0x39, 0xf5, 0x68, 0x62, 0x8a, 0x86, 0x6d, 0x1c, 0xc3, 0x8a, 0x24, 0x7b, 0x9a, 0x4c, 0x16,
0x9f, 0xdf, 0xdc, 0x4b, 0x0e, 0xb6, 0x7c, 0xea, 0x60, 0x33, 0x7e, 0xa3, 0x04, 0x65, 0x19, 0x9b,
0x3d, 0x2b, 0x58, 0x78, 0x35, 0x1e, 0x2c, 0xbc, 0x15, 0x0b, 0x45, 0x8a, 0x53, 0x2f, 0x78, 0x9c,
0x77, 0x92, 0x6c, 0x8a, 0x66, 0xc2, 0x8a, 0xb1, 0x2a, 0xc2, 0x84, 0x55, 0x8a, 0x9b, 0xb0, 0xb2,
0x02, 0xa8, 0x73, 0x76, 0x3b, 0x15, 0x40, 0xfd, 0x16, 0x70, 0xde, 0x49, 0xf3, 0xf8, 0xad, 0x20,
0x40, 0x04, 0x48, 0xd1, 0x58, 0xad, 0x4a, 0x92, 0xd5, 0x7a, 0x65, 0x36, 0xe8, 0x63, 0x58, 0xe0,
0xb1, 0xc4, 0x44, 0xb0, 0x0c, 0x79, 0x58, 0x8a, 0xb1, 0x92, 0xff, 0xf9, 0x45, 0x32, 0x53, 0xe0,
0xea, 0xf1, 0x76, 0x6b, 0xb1, 0x78, 0xbb, 0xba, 0x69, 0xad, 0x1e, 0x37, 0xad, 0xdd, 0x83, 0xa6,
0x1a, 0x38, 0xd4, 0x09, 0xbb, 0x81, 0xb8, 0x17, 0xbf, 0x28, 0xe1, 0x8c, 0xbc, 0xf7, 0x82, 0xe8,
0xb0, 0x5f, 0x8c, 0x1d, 0xf6, 0x8c, 0xf8, 0xb6, 0xc3, 0x90, 0x4e, 0x67, 0xa1, 0x3c, 0xec, 0xb5,
0x98, 0xf5, 0x7c, 0xe6, 0xf9, 0x45, 0x3b, 0x39, 0xbd, 0x7c, 0x75, 0x6c, 0xc3, 0xe2, 0xa9, 0xed,
0x4c, 0xe6, 0x3e, 0xb5, 0x7c, 0x6a, 0x07, 0x9e, 0x8b, 0xf4, 0x21, 0xe2, 0x3b, 0x44, 0x17, 0xf7,
0x38, 0x8e, 0x89, 0x28, 0x66, 0xe3, 0x54, 0xff, 0xc4, 0x6b, 0xad, 0xfa, 0x48, 0xb0, 0x33, 0x58,
0x84, 0xcc, 0xe0, 0x0e, 0x7c, 0xdd, 0x9e, 0xb5, 0x77, 0xd0, 0x7d, 0xbc, 0x3f, 0x6c, 0xe6, 0xd8,
0xe7, 0xe0, 0x78, 0x67, 0xa7, 0xd3, 0xd9, 0xc5, 0x33, 0x19, 0x60, 0x61, 0xaf, 0xdd, 0x3d, 0x10,
0x27, 0x72, 0xb1, 0x59, 0x32, 0xfe, 0x30, 0x0f, 0x35, 0xad, 0x37, 0x18, 0x0c, 0x87, 0xff, 0x64,
0xf4, 0xb7, 0x2c, 0x82, 0xe1, 0x70, 0x48, 0x77, 0x4c, 0x1e, 0xa9, 0x39, 0xe2, 0x31, 0x7c, 0x6e,
0xa7, 0x07, 0x64, 0x4b, 0x9e, 0x68, 0xda, 0x24, 0xa9, 0xe0, 0xf5, 0xf9, 0x6b, 0x83, 0xd7, 0x93,
0xb7, 0x61, 0x49, 0xd6, 0x2c, 0xe7, 0x44, 0x58, 0x5f, 0x04, 0x58, 0x4c, 0xc9, 0xdb, 0x22, 0x9e,
0x90, 0x38, 0x96, 0x19, 0x5e, 0x51, 0x3a, 0xba, 0xab, 0x93, 0x19, 0xa7, 0xae, 0x2c, 0x06, 0x4e,
0xb8, 0x70, 0x28, 0x06, 0x47, 0x0c, 0xa7, 0x4c, 0x8e, 0x9d, 0x11, 0x0b, 0x89, 0x33, 0xe2, 0x13,
0x80, 0xa8, 0x3f, 0xf1, 0xd1, 0xbd, 0x11, 0x1f, 0xdd, 0x9c, 0x36, 0xba, 0x79, 0xe3, 0x1f, 0x0a,
0xca, 0x26, 0xa6, 0x4a, 0xe9, 0x62, 0xdf, 0x07, 0xa9, 0x1d, 0xb6, 0xf0, 0x62, 0xcc, 0x6c, 0x42,
0x43, 0x79, 0xeb, 0x7f, 0x59, 0xa4, 0x74, 0x55, 0x42, 0x8a, 0x12, 0xe7, 0xd3, 0x94, 0xf8, 0x0d,
0xa8, 0x63, 0x80, 0x4a, 0x51, 0x91, 0x8c, 0x10, 0x3d, 0xb5, 0x2f, 0x65, 0xdd, 0x31, 0x12, 0x5c,
0x4c, 0x90, 0xe0, 0xbf, 0x9d, 0xe3, 0xd1, 0xcc, 0xa2, 0x86, 0x46, 0x34, 0x58, 0x95, 0x19, 0xa7,
0xc1, 0x02, 0xd5, 0x54, 0xe9, 0xd7, 0xd0, 0xd5, 0x7c, 0x36, 0x5d, 0xcd, 0xa6, 0xd8, 0x85, 0x4c,
0x8a, 0x6d, 0x5c, 0x42, 0x6b, 0x97, 0xb2, 0xa1, 0x68, 0x4f, 0x26, 0xc9, 0xb1, 0x7c, 0x00, 0xab,
0x6c, 0x0a, 0xd1, 0x7f, 0x85, 0xa7, 0xe8, 0x27, 0x1a, 0xe1, 0x69, 0x32, 0x13, 0x1e, 0x6c, 0xf7,
0x61, 0x59, 0xe4, 0xc0, 0x4d, 0xab, 0x87, 0x8e, 0x5b, 0xe2, 0x09, 0xe8, 0x77, 0xcb, 0x70, 0x8d,
0x5b, 0x70, 0x33, 0xa3, 0x66, 0xa1, 0xb4, 0xfb, 0xcd, 0x1c, 0xac, 0xb5, 0x79, 0x88, 0xa4, 0x6f,
0xec, 0xd2, 0xff, 0xe7, 0x70, 0x53, 0xdd, 0xa1, 0xd1, 0xee, 0xfe, 0xea, 0x8d, 0x94, 0xd7, 0x6f,
0xb4, 0x9b, 0x63, 0xd8, 0xd6, 0x16, 0xac, 0x27, 0x5b, 0x23, 0x1a, 0xba, 0x07, 0xcb, 0xbb, 0xf4,
0x64, 0x7e, 0x76, 0x40, 0x2f, 0xa2, 0x36, 0x12, 0x28, 0x06, 0xe7, 0xde, 0x73, 0x31, 0x50, 0xf8,
0x1b, 0x9d, 0xec, 0x19, 0x8e, 0x15, 0xcc, 0xe8, 0x48, 0x1a, 0x7d, 0x10, 0x32, 0x98, 0xd1, 0x91,
0xf1, 0x08, 0x88, 0x5e, 0x8e, 0x58, 0x23, 0x4c, 0x06, 0x9e, 0x9f, 0x58, 0xc1, 0x55, 0x10, 0xd2,
0xa9, 0xbc, 0xff, 0x0e, 0xc1, 0xfc, 0x64, 0xc0, 0x21, 0xc6, 0x3b, 0x50, 0x3f, 0xb2, 0xaf, 0x4c,
0xfa, 0x43, 0x71, 0x85, 0x7c, 0x03, 0xca, 0x33, 0xfb, 0x8a, 0x1d, 0x04, 0xca, 0xfe, 0x8b, 0xc9,
0xc6, 0xef, 0x16, 0x61, 0x81, 0x63, 0x92, 0xbb, 0xfc, 0x5d, 0x1b, 0xc7, 0x45, 0x42, 0x2c, 0x8f,
0x44, 0x0d, 0x94, 0x3a, 0x35, 0xf3, 0xe9, 0x53, 0x53, 0x28, 0xab, 0x65, 0xfc, 0x4d, 0x69, 0xa9,
0x73, 0xe7, 0x53, 0x19, 0x74, 0x33, 0x1e, 0x10, 0xa8, 0x18, 0xbd, 0x94, 0xc4, 0x83, 0xa1, 0xc4,
0x1d, 0x3c, 0x22, 0x49, 0x9b, 0xb7, 0x4e, 0x32, 0x03, 0xe2, 0xc0, 0xd4, 0x41, 0x99, 0xe2, 0x7c,
0x59, 0xc6, 0x57, 0x88, 0x8b, 0xf3, 0x29, 0xb1, 0xbd, 0xf2, 0x72, 0xb1, 0x9d, 0x6b, 0xb1, 0x5f,
0x20, 0xb6, 0xc3, 0x2b, 0x88, 0xed, 0xaf, 0xe0, 0x2b, 0x71, 0x13, 0x2a, 0xc8, 0xe1, 0x69, 0xe7,
0x27, 0xe3, 0xec, 0xd8, 0xf9, 0xf9, 0xa9, 0x26, 0xd8, 0x72, 0xcf, 0x2e, 0xed, 0x00, 0x33, 0xe9,
0x0f, 0x7f, 0x3a, 0x8a, 0xd1, 0xa7, 0x50, 0x16, 0x50, 0xb6, 0xa0, 0x5d, 0x7b, 0x2a, 0xa3, 0x4c,
0xe3, 0x6f, 0x36, 0x6c, 0x18, 0x77, 0xf5, 0x87, 0x73, 0xc7, 0xa7, 0x63, 0x19, 0xfd, 0xd1, 0x41,
0xea, 0xc1, 0x20, 0xac, 0x83, 0x4c, 0xc8, 0x76, 0xe5, 0x93, 0x16, 0x15, 0xb3, 0xec, 0x04, 0x4f,
0xd8, 0xa7, 0x41, 0xa0, 0x89, 0x31, 0xfd, 0x67, 0x9e, 0x2f, 0xd9, 0x13, 0xe3, 0xf7, 0x72, 0xd0,
0x14, 0xbb, 0x4b, 0xa5, 0xe9, 0x02, 0x6c, 0xe9, 0x3a, 0x47, 0xa4, 0x17, 0xc7, 0x72, 0x34, 0xa0,
0x81, 0xaa, 0x3d, 0xc5, 0xab, 0x70, 0xd5, 0x64, 0x8d, 0x01, 0xf7, 0x04, 0xbf, 0xf2, 0x3a, 0xd4,
0xe4, 0x15, 0xa0, 0xa9, 0x33, 0x91, 0x8f, 0xa2, 0xf1, 0x3b, 0x40, 0x87, 0xce, 0x44, 0xb2, 0x3a,
0xbe, 0x2d, 0x62, 0x7e, 0xe4, 0x90, 0xd5, 0x31, 0xed, 0x90, 0x1a, 0x7f, 0x90, 0x83, 0x65, 0xad,
0x2b, 0x62, 0xdf, 0x7e, 0x07, 0xea, 0xea, 0xa9, 0x11, 0xaa, 0x78, 0xec, 0x8d, 0x38, 0x8d, 0x8a,
0xb2, 0xd5, 0x46, 0x0a, 0x12, 0xb0, 0xc6, 0x8c, 0xed, 0x2b, 0x7e, 0x4f, 0x65, 0x3e, 0x95, 0x72,
0xf9, 0xd8, 0xbe, 0xda, 0xa3, 0x74, 0x30, 0x9f, 0x92, 0xbb, 0x50, 0x7f, 0x4e, 0xe9, 0x33, 0x85,
0xc0, 0x09, 0x3b, 0x30, 0x98, 0xc0, 0x30, 0xa0, 0x31, 0xf5, 0xdc, 0xf0, 0x5c, 0xa1, 0x08, 0xf9,
0x02, 0x81, 0x1c, 0xc7, 0xf8, 0xb7, 0x79, 0x58, 0xe1, 0x0a, 0x64, 0x61, 0x46, 0x10, 0xa4, 0xab,
0x05, 0x0b, 0x5c, 0xab, 0xcf, 0x89, 0xd7, 0xfe, 0x0d, 0x53, 0x7c, 0x93, 0x8f, 0x5f, 0x51, 0xe9,
0x2d, 0xc3, 0x85, 0x5c, 0x33, 0xfc, 0x85, 0xf4, 0xf0, 0x5f, 0x3f, 0xbc, 0x59, 0x4e, 0x05, 0xa5,
0x2c, 0xa7, 0x82, 0x57, 0x31, 0xe5, 0xa7, 0x02, 0x56, 0x94, 0xd3, 0x81, 0xa3, 0x1f, 0xc1, 0x46,
0x0c, 0x07, 0xa9, 0xb5, 0x73, 0xea, 0xa8, 0x17, 0x0f, 0x56, 0x35, 0xec, 0x81, 0x4c, 0xdb, 0x2e,
0x43, 0x29, 0x18, 0x79, 0x33, 0x74, 0x8e, 0x8f, 0x8f, 0xaa, 0x38, 0x26, 0x7e, 0x3b, 0x07, 0xad,
0xbd, 0x28, 0x02, 0xb7, 0x13, 0x84, 0x9e, 0xaf, 0x1e, 0x93, 0xb8, 0x0d, 0xc0, 0x1f, 0x68, 0x43,
0x35, 0x88, 0x08, 0x9d, 0x86, 0x10, 0x54, 0x82, 0xdc, 0x84, 0x0a, 0x75, 0xc7, 0x3c, 0x91, 0xaf,
0x86, 0x32, 0x75, 0xc7, 0x52, 0x85, 0x92, 0x3a, 0xe4, 0x1b, 0x71, 0xf6, 0x45, 0x04, 0x01, 0x62,
0xa3, 0x43, 0x2f, 0x90, 0xd9, 0x28, 0xaa, 0x20, 0x40, 0x87, 0xf6, 0x25, 0xde, 0x71, 0x08, 0x8c,
0x7f, 0x9c, 0x87, 0xa5, 0xa8, 0x7d, 0x3c, 0x0c, 0xda, 0xdd, 0x54, 0x40, 0x37, 0xe1, 0x0f, 0xa5,
0x68, 0xf8, 0x5d, 0xb1, 0x24, 0x1c, 0x26, 0xad, 0x69, 0xaa, 0xf5, 0x0a, 0xdf, 0xa0, 0x5d, 0x97,
0x18, 0x50, 0x93, 0x18, 0xde, 0x3c, 0xd4, 0x02, 0x5e, 0x57, 0x39, 0x4a, 0x7f, 0x1e, 0x32, 0xf1,
0xda, 0x9e, 0x32, 0x6e, 0x45, 0x08, 0xb8, 0x25, 0x7b, 0x1a, 0x76, 0xf1, 0x25, 0x40, 0x06, 0x66,
0xd9, 0xf8, 0x64, 0x32, 0x2c, 0x86, 0xdf, 0xe4, 0xd2, 0x16, 0x9f, 0x3d, 0x94, 0xb4, 0x74, 0x51,
0x84, 0xbf, 0x3f, 0xa4, 0x44, 0x91, 0xd7, 0xa1, 0xc6, 0x0b, 0x8f, 0x62, 0x94, 0x60, 0xf4, 0xc9,
0xb0, 0xeb, 0x62, 0xba, 0x50, 0x73, 0x7a, 0xf3, 0x98, 0xe6, 0x06, 0x78, 0x55, 0xf2, 0xd1, 0x36,
0xd5, 0x63, 0x4b, 0x19, 0x21, 0x6b, 0x0a, 0xd6, 0x0b, 0x18, 0xb7, 0x72, 0x33, 0x63, 0x76, 0x05,
0x31, 0xd8, 0x01, 0x2d, 0x5c, 0xbb, 0x9c, 0x04, 0x4e, 0x11, 0xd6, 0x25, 0xf5, 0x8d, 0x0f, 0xbd,
0xd9, 0x3c, 0x8d, 0x03, 0x22, 0x29, 0x9c, 0x4f, 0x74, 0x2c, 0x98, 0x0e, 0xf2, 0x74, 0x7c, 0xb6,
0xb9, 0x00, 0x7c, 0x04, 0x9b, 0x9d, 0x4b, 0x46, 0x58, 0x94, 0xb7, 0xff, 0xe8, 0xd9, 0x5c, 0xda,
0x47, 0x13, 0x56, 0x96, 0xdc, 0x2b, 0x59, 0x59, 0xc6, 0x3c, 0x84, 0x85, 0x2a, 0xeb, 0xc7, 0x29,
0x84, 0xeb, 0x97, 0x6c, 0xd7, 0x3a, 0xc1, 0x22, 0x64, 0xc4, 0x1c, 0x06, 0xe2, 0x85, 0x1a, 0x01,
0x2c, 0x1d, 0xce, 0x27, 0xa1, 0xb3, 0xa3, 0x40, 0xe4, 0x63, 0x91, 0x07, 0xeb, 0x91, 0xa3, 0x96,
0x59, 0x11, 0xa8, 0x8a, 0x70, 0xb0, 0xa6, 0xac, 0x20, 0x2b, 0x5d, 0xdf, 0xd2, 0x34, 0x5e, 0x83,
0x71, 0x13, 0x36, 0xa2, 0x2f, 0x3e, 0x6c, 0xf2, 0x44, 0xfa, 0x3b, 0x39, 0x7e, 0xef, 0x8a, 0xa7,
0x0d, 0x5c, 0x7b, 0x16, 0x9c, 0x7b, 0x21, 0xe9, 0xc0, 0x4a, 0xe0, 0xb8, 0x67, 0x13, 0xaa, 0x17,
0x1f, 0x88, 0x41, 0x58, 0x8b, 0xb7, 0x8d, 0x67, 0x0d, 0xcc, 0x65, 0x9e, 0x23, 0x2a, 0x2d, 0x20,
0xdb, 0xd7, 0x35, 0x32, 0x5a, 0x16, 0x89, 0xd1, 0x48, 0x37, 0xbe, 0x0b, 0x8b, 0xf1, 0x8a, 0xc8,
0xa7, 0x22, 0xf2, 0x4b, 0xd4, 0xaa, 0x42, 0x22, 0xee, 0x45, 0xb4, 0x20, 0x6a, 0xd1, 0xd8, 0x07,
0xc6, 0x5f, 0xcd, 0x41, 0xcb, 0xa4, 0x6c, 0xe5, 0x6a, 0xad, 0x94, 0x6b, 0xe6, 0x3b, 0xa9, 0x52,
0xaf, 0xef, 0xab, 0x0c, 0x28, 0x23, 0x5b, 0xf4, 0xde, 0xb5, 0x93, 0xb1, 0x7f, 0x23, 0xd5, 0xa3,
0xed, 0x0a, 0x2c, 0x70, 0x14, 0x63, 0x03, 0xd6, 0x44, 0x7b, 0x64, 0x5b, 0x22, 0x83, 0x7e, 0xac,
0xc6, 0x98, 0x41, 0x7f, 0x13, 0x5a, 0x3c, 0x40, 0x83, 0xde, 0x09, 0x91, 0x71, 0x17, 0xc8, 0xa1,
0x3d, 0xb2, 0x7d, 0xcf, 0x73, 0x8f, 0xa8, 0x2f, 0xfc, 0xf8, 0x91, 0x11, 0x45, 0x7b, 0xb7, 0xe4,
0x98, 0xf9, 0x97, 0x7c, 0x09, 0xc0, 0x73, 0xa5, 0x87, 0x20, 0xff, 0x32, 0x7c, 0x58, 0xd9, 0xb6,
0x9f, 0x51, 0x59, 0x92, 0x1c, 0xa2, 0x2f, 0xa0, 0x36, 0x53, 0x85, 0xca, 0x71, 0x97, 0x41, 0xb5,
0xd2, 0xd5, 0x9a, 0x3a, 0x36, 0xa3, 0x52, 0xa8, 0xb0, 0xc5, 0x30, 0x35, 0x63, 0x79, 0xe6, 0x33,
0xd0, 0x13, 0x7a, 0xd5, 0x1d, 0x1b, 0x0f, 0x61, 0x35, 0x5e, 0xa7, 0x20, 0x2d, 0x9b, 0x50, 0x99,
0x0a, 0x98, 0x68, 0xbd, 0xfa, 0x66, 0x32, 0x0b, 0x93, 0x3b, 0x65, 0x9e, 0xee, 0xae, 0x8a, 0xb5,
0xf0, 0x05, 0x6c, 0xa4, 0x52, 0x44, 0x81, 0x77, 0xa1, 0xae, 0x35, 0x84, 0x77, 0xa3, 0x68, 0x82,
0x6a, 0x49, 0x60, 0x7c, 0x0e, 0x1b, 0x5c, 0x6c, 0x8b, 0xb2, 0xcb, 0x21, 0x48, 0xf4, 0x22, 0x97,
0xec, 0xc5, 0xc7, 0x52, 0xd6, 0xd4, 0xb3, 0x46, 0x41, 0x2d, 0xc7, 0x98, 0x26, 0x9d, 0xbc, 0xe4,
0xa7, 0x71, 0x0c, 0xeb, 0xe9, 0xe1, 0x63, 0xed, 0xff, 0x89, 0x86, 0x5c, 0x0e, 0x4f, 0x94, 0xac,
0x86, 0xe7, 0xbf, 0xe6, 0xf8, 0xf8, 0xc4, 0x92, 0x44, 0x33, 0xc7, 0x40, 0xa6, 0x34, 0x3c, 0xf7,
0xc6, 0x56, 0xba, 0xe6, 0x47, 0xca, 0xc7, 0x2c, 0x33, 0xef, 0xd6, 0x21, 0x66, 0xd4, 0x52, 0xc4,
0x15, 0x8c, 0x69, 0x12, 0xbe, 0x39, 0x82, 0xf5, 0x6c, 0xe4, 0x0c, 0xcf, 0xac, 0x8f, 0xe2, 0xfc,
0xfc, 0xed, 0x6b, 0xbb, 0xcf, 0x9a, 0xa5, 0xb3, 0xf7, 0xbf, 0x5b, 0x81, 0xb2, 0x50, 0xd5, 0x90,
0x2d, 0x28, 0x8e, 0xa4, 0x97, 0x6f, 0x14, 0xd8, 0x54, 0xa4, 0xca, 0xff, 0x3b, 0xe8, 0xeb, 0xcb,
0xf0, 0xc8, 0x17, 0xb0, 0x18, 0x77, 0x74, 0x49, 0x04, 0x20, 0x8a, 0x7b, 0xa8, 0x34, 0x46, 0x09,
0x27, 0x82, 0x6a, 0xc4, 0x83, 0x71, 0xd6, 0xb4, 0x72, 0xae, 0x31, 0x69, 0x9e, 0xcb, 0xc4, 0xba,
0xe0, 0xdc, 0xb6, 0x1e, 0x3e, 0xfa, 0x44, 0x18, 0x15, 0x6a, 0x08, 0x1c, 0x9c, 0xdb, 0x0f, 0x1f,
0x7d, 0x92, 0x14, 0xd8, 0x44, 0xfc, 0x21, 0x4d, 0x60, 0x5b, 0x85, 0x12, 0x7f, 0x2e, 0x81, 0xbb,
0x6b, 0xf2, 0x0f, 0xa9, 0xce, 0x98, 0xfb, 0xd4, 0x12, 0xb7, 0x7d, 0xf8, 0x29, 0xca, 0x9f, 0xb6,
0x23, 0x22, 0x6d, 0x80, 0x49, 0x5c, 0x9d, 0xb8, 0x0e, 0x0b, 0xe7, 0xd1, 0xfb, 0x17, 0x0d, 0x53,
0x7c, 0x19, 0xff, 0xab, 0x04, 0x35, 0x6d, 0x50, 0x48, 0x1d, 0x2a, 0x66, 0x67, 0xd0, 0x31, 0xbf,
0xec, 0xec, 0x36, 0x6f, 0x90, 0x7b, 0xf0, 0x56, 0xb7, 0xb7, 0xd3, 0x37, 0xcd, 0xce, 0xce, 0xd0,
0xea, 0x9b, 0x96, 0x8c, 0xb7, 0x7b, 0xd4, 0x7e, 0x7a, 0xd8, 0xe9, 0x0d, 0xad, 0xdd, 0xce, 0xb0,
0xdd, 0x3d, 0x18, 0x34, 0x73, 0xe4, 0x35, 0x68, 0x45, 0x98, 0x32, 0xb9, 0x7d, 0xd8, 0x3f, 0xee,
0x0d, 0x9b, 0x79, 0x72, 0x07, 0x6e, 0xed, 0x75, 0x7b, 0xed, 0x03, 0x2b, 0xc2, 0xd9, 0x39, 0x18,
0x7e, 0x69, 0x75, 0x7e, 0xee, 0xa8, 0x6b, 0x3e, 0x6d, 0x16, 0xb2, 0x10, 0xf6, 0x87, 0x07, 0x3b,
0xb2, 0x84, 0x22, 0xb9, 0x09, 0x6b, 0x1c, 0x81, 0x67, 0xb1, 0x86, 0xfd, 0xbe, 0x35, 0xe8, 0xf7,
0x7b, 0xcd, 0x12, 0x59, 0x86, 0x46, 0xb7, 0xf7, 0x65, 0xfb, 0xa0, 0xbb, 0x6b, 0x99, 0x9d, 0xf6,
0xc1, 0x61, 0x73, 0x81, 0xac, 0xc0, 0x52, 0x12, 0xaf, 0xcc, 0x8a, 0x90, 0x78, 0xfd, 0x5e, 0xb7,
0xdf, 0xb3, 0xbe, 0xec, 0x98, 0x83, 0x6e, 0xbf, 0xd7, 0xac, 0x90, 0x75, 0x20, 0xf1, 0xa4, 0xfd,
0xc3, 0xf6, 0x4e, 0xb3, 0x4a, 0xd6, 0x60, 0x39, 0x0e, 0x7f, 0xd2, 0x79, 0xda, 0x04, 0xd2, 0x82,
0x55, 0xde, 0x30, 0x6b, 0xbb, 0x73, 0xd0, 0xff, 0xca, 0x3a, 0xec, 0xf6, 0xba, 0x87, 0xc7, 0x87,
0xcd, 0x1a, 0x46, 0x3d, 0xef, 0x74, 0xac, 0x6e, 0x6f, 0x70, 0xbc, 0xb7, 0xd7, 0xdd, 0xe9, 0x76,
0x7a, 0xc3, 0x66, 0x9d, 0xd7, 0x9c, 0xd5, 0xf1, 0x06, 0xcb, 0x20, 0x2e, 0xc4, 0x5a, 0xbb, 0xdd,
0x41, 0x7b, 0xfb, 0xa0, 0xb3, 0xdb, 0x5c, 0x24, 0xb7, 0xe1, 0xe6, 0xb0, 0x73, 0x78, 0xd4, 0x37,
0xdb, 0xe6, 0x53, 0x79, 0x61, 0xd6, 0xda, 0x6b, 0x77, 0x0f, 0x8e, 0xcd, 0x4e, 0x73, 0x89, 0xbc,
0x01, 0xb7, 0xcd, 0xce, 0x0f, 0x8e, 0xbb, 0x66, 0x67, 0xd7, 0xea, 0xf5, 0x77, 0x3b, 0xd6, 0x5e,
0xa7, 0x3d, 0x3c, 0x36, 0x3b, 0xd6, 0x61, 0x77, 0x30, 0xe8, 0xf6, 0x1e, 0x37, 0x9b, 0xe4, 0x2d,
0xb8, 0xab, 0x50, 0x54, 0x01, 0x09, 0xac, 0x65, 0xd6, 0x3f, 0x39, 0xa5, 0xbd, 0xce, 0xcf, 0x0d,
0xad, 0xa3, 0x4e, 0xc7, 0x6c, 0x12, 0xb2, 0x09, 0xeb, 0x51, 0xf5, 0xbc, 0x02, 0x51, 0xf7, 0x0a,
0x4b, 0x3b, 0xea, 0x98, 0x87, 0xed, 0x1e, 0x9b, 0xe0, 0x58, 0xda, 0x2a, 0x6b, 0x76, 0x94, 0x96,
0x6c, 0xf6, 0x1a, 0x21, 0xb0, 0xa8, 0xcd, 0xca, 0x5e, 0xdb, 0x6c, 0xae, 0x93, 0x25, 0xa8, 0x1d,
0x1e, 0x1d, 0x59, 0xc3, 0xee, 0x61, 0xa7, 0x7f, 0x3c, 0x6c, 0x6e, 0xa4, 0x67, 0xe9, 0xa8, 0xfd,
0xf4, 0xa0, 0xdf, 0xde, 0x6d, 0xb6, 0xc8, 0x1a, 0x34, 0xbb, 0xbd, 0x61, 0xc7, 0x64, 0xcb, 0x40,
0x96, 0xfa, 0xdf, 0xca, 0x64, 0x15, 0x96, 0x64, 0x27, 0x24, 0xf4, 0x8f, 0xca, 0x64, 0x03, 0xc8,
0x71, 0xcf, 0xec, 0xb4, 0x77, 0xd9, 0x98, 0xaa, 0x84, 0xff, 0x5e, 0x16, 0xe6, 0xe5, 0xdf, 0x2b,
0x28, 0x3e, 0x30, 0x72, 0x30, 0x8b, 0xbf, 0x65, 0x55, 0xd7, 0xde, 0xa0, 0x7a, 0xd9, 0x7b, 0xa7,
0x9a, 0x70, 0x5f, 0x48, 0x09, 0xf7, 0x29, 0xed, 0x51, 0x43, 0x97, 0x3c, 0xde, 0x84, 0xc6, 0x94,
0xbf, 0x6b, 0x25, 0x1e, 0x46, 0x01, 0xe1, 0x6d, 0xc9, 0x81, 0xfc, 0x55, 0x94, 0xd4, 0x83, 0x9f,
0xa5, 0xf4, 0x83, 0x9f, 0x59, 0x12, 0xe6, 0x42, 0x96, 0x84, 0x79, 0x1f, 0x96, 0x39, 0xd5, 0x72,
0x5c, 0x67, 0x2a, 0xf5, 0x36, 0xe2, 0xf9, 0x4c, 0xa4, 0x5e, 0x1c, 0x2e, 0x05, 0x5a, 0x29, 0xf4,
0x0a, 0xea, 0x52, 0x16, 0xf2, 0x6e, 0x4c, 0xd6, 0xe5, 0x44, 0x45, 0xc9, 0xba, 0xaa, 0x06, 0xfb,
0x32, 0xaa, 0xa1, 0xa6, 0xd5, 0xc0, 0xe1, 0x58, 0xc3, 0x7d, 0x58, 0xa6, 0x97, 0xa1, 0x6f, 0x5b,
0xde, 0xcc, 0xfe, 0xe1, 0x1c, 0x5d, 0x64, 0x6c, 0xd4, 0x22, 0xd5, 0xcd, 0x25, 0x4c, 0xe8, 0x23,
0x7c, 0xd7, 0x0e, 0x6d, 0xe3, 0x17, 0x01, 0xd4, 0x81, 0x8b, 0xcf, 0x90, 0xba, 0x9e, 0xbc, 0xe8,
0x5b, 0x37, 0xf9, 0x07, 0xce, 0x63, 0xe8, 0xf9, 0xf6, 0x19, 0xed, 0x4a, 0xab, 0x70, 0x04, 0x20,
0xb7, 0xa0, 0xe0, 0xcd, 0xa4, 0x2f, 0x62, 0x55, 0x46, 0xfa, 0x9f, 0x99, 0x0c, 0x6a, 0x7c, 0x02,
0xf9, 0xfe, 0xec, 0x5a, 0x2e, 0x0a, 0x5f, 0x5d, 0xe3, 0x4f, 0x2d, 0xe4, 0xd1, 0xff, 0x50, 0x7e,
0xde, 0xff, 0x8b, 0x50, 0xd3, 0x1e, 0x69, 0x23, 0x1b, 0xb0, 0xf2, 0x55, 0x77, 0xd8, 0xeb, 0x0c,
0x06, 0xd6, 0xd1, 0xf1, 0xf6, 0x93, 0xce, 0x53, 0x6b, 0xbf, 0x3d, 0xd8, 0x6f, 0xde, 0x60, 0x64,
0xa6, 0xd7, 0x19, 0x0c, 0x3b, 0xbb, 0x31, 0x78, 0x8e, 0xbc, 0x0e, 0x9b, 0xc7, 0xbd, 0xe3, 0x41,
0x67, 0xd7, 0xca, 0xca, 0x97, 0x67, 0xfb, 0x4a, 0xa4, 0x67, 0x64, 0x2f, 0xdc, 0xff, 0x25, 0x58,
0x8c, 0x47, 0xbb, 0x21, 0x00, 0x0b, 0x07, 0x9d, 0xc7, 0xed, 0x9d, 0xa7, 0xfc, 0x25, 0x87, 0xc1,
0xb0, 0x3d, 0xec, 0xee, 0x58, 0xe2, 0xe5, 0x06, 0x46, 0xc3, 0x72, 0xa4, 0x06, 0xe5, 0x76, 0x6f,
0x67, 0xbf, 0x6f, 0x0e, 0x9a, 0x79, 0xf2, 0x1a, 0x6c, 0xc8, 0x2d, 0xb4, 0xd3, 0x3f, 0x3c, 0xec,
0x0e, 0x91, 0x7c, 0x0f, 0x9f, 0x1e, 0xb1, 0x1d, 0x73, 0xdf, 0x86, 0x6a, 0xf4, 0xe8, 0x04, 0x92,
0xc4, 0xee, 0xb0, 0xdb, 0x1e, 0x46, 0xe7, 0x41, 0xf3, 0x06, 0xa3, 0xb8, 0x11, 0x18, 0x5f, 0x8e,
0x68, 0xe6, 0x78, 0x40, 0x00, 0x09, 0xe4, 0xb5, 0x37, 0xf3, 0x8c, 0x0c, 0x44, 0xd0, 0xed, 0xfe,
0x90, 0x75, 0xe1, 0x97, 0x61, 0x31, 0xfe, 0xb6, 0x03, 0x69, 0x42, 0x9d, 0xd5, 0xaf, 0x55, 0x01,
0xb0, 0xc0, 0x5b, 0xdc, 0xcc, 0x71, 0x9a, 0xbf, 0xd3, 0x3f, 0xec, 0xf6, 0x1e, 0xe3, 0x41, 0xd1,
0xcc, 0x33, 0x50, 0xff, 0x78, 0xf8, 0xb8, 0xaf, 0x40, 0x05, 0x96, 0x83, 0x77, 0xa7, 0x59, 0xbc,
0xff, 0x43, 0x58, 0x4e, 0xbd, 0x02, 0xc1, 0x5a, 0xdd, 0x3f, 0x1e, 0xee, 0xf4, 0x0f, 0xf5, 0x7a,
0x6a, 0x50, 0xde, 0x39, 0x68, 0x77, 0x0f, 0xd1, 0x50, 0xd3, 0x80, 0xea, 0x71, 0x4f, 0x7e, 0xe6,
0xe3, 0xef, 0x57, 0x14, 0x18, 0xf5, 0xda, 0xeb, 0x9a, 0x83, 0xa1, 0x35, 0x18, 0xb6, 0x1f, 0x77,
0x9a, 0x45, 0x96, 0x57, 0x92, 0xb2, 0xd2, 0xfd, 0xcf, 0x61, 0x31, 0xee, 0x38, 0x1f, 0xb7, 0xbf,
0x6d, 0xc2, 0xfa, 0x76, 0x67, 0xf8, 0x55, 0xa7, 0xd3, 0xc3, 0x29, 0xdf, 0xe9, 0xf4, 0x86, 0x66,
0xfb, 0xa0, 0x3b, 0x7c, 0xda, 0xcc, 0xdd, 0xff, 0x02, 0x9a, 0x49, 0xa7, 0x8f, 0x98, 0x97, 0xcc,
0x8b, 0xdc, 0x69, 0xee, 0xff, 0x87, 0x1c, 0xac, 0x66, 0x99, 0x07, 0xd9, 0xc2, 0x14, 0x84, 0x90,
0x9d, 0x94, 0x83, 0x7e, 0xcf, 0xea, 0xf5, 0x31, 0x7e, 0xfb, 0x26, 0xac, 0x27, 0x12, 0x64, 0x2f,
0x72, 0xe4, 0x16, 0x6c, 0xa4, 0x32, 0x59, 0x66, 0xff, 0x18, 0xe7, 0xb2, 0x05, 0xab, 0x89, 0xc4,
0x8e, 0x69, 0xf6, 0xcd, 0x66, 0x81, 0xbc, 0x07, 0xf7, 0x12, 0x29, 0x69, 0xfe, 0x40, 0xb2, 0x0f,
0x45, 0xf2, 0x0e, 0xbc, 0x99, 0xc2, 0x8e, 0x8e, 0x50, 0x6b, 0xbb, 0x7d, 0xc0, 0xba, 0xd7, 0x2c,
0xdd, 0xff, 0x83, 0x22, 0x40, 0x74, 0x5d, 0x96, 0xd5, 0xbf, 0xdb, 0x1e, 0xb6, 0x0f, 0xfa, 0x6c,
0xcf, 0x98, 0xfd, 0x21, 0x2b, 0xdd, 0xec, 0xfc, 0xa0, 0x79, 0x23, 0x33, 0xa5, 0x7f, 0xc4, 0x3a,
0xb4, 0x01, 0x2b, 0x7c, 0xfd, 0x1d, 0xb0, 0x6e, 0xb0, 0xe5, 0xc2, 0x9f, 0x02, 0x60, 0x4c, 0xc8,
0xf1, 0xd1, 0x9e, 0xd9, 0xef, 0x0d, 0xad, 0xc1, 0xfe, 0xf1, 0x70, 0x17, 0x5f, 0x16, 0xd8, 0x31,
0xbb, 0x47, 0xbc, 0xcc, 0xe2, 0x8b, 0x10, 0x58, 0xd1, 0x25, 0xb6, 0xc1, 0x1f, 0xf7, 0x07, 0x83,
0xee, 0x91, 0xf5, 0x83, 0xe3, 0x8e, 0xd9, 0xed, 0x0c, 0x30, 0xe3, 0x42, 0x06, 0x9c, 0xe1, 0x97,
0xd9, 0x9a, 0x1d, 0x1e, 0x7c, 0x29, 0x0e, 0x3a, 0x86, 0x5a, 0x89, 0x83, 0x18, 0x56, 0x95, 0xcd,
0x0e, 0x3b, 0x9c, 0x33, 0x4a, 0x86, 0x6b, 0xd2, 0x58, 0xbe, 0x1a, 0x3b, 0x4a, 0x53, 0x3b, 0x1f,
0xb3, 0xd5, 0xb3, 0x93, 0x58, 0x2e, 0xe4, 0x48, 0x14, 0xff, 0xb6, 0xbb, 0x6b, 0x62, 0x86, 0xc5,
0x14, 0x94, 0xe1, 0x2e, 0xb1, 0x45, 0xc8, 0x4e, 0x6f, 0x86, 0xd2, 0x94, 0x1f, 0x2c, 0x65, 0x99,
0xf5, 0xf8, 0xab, 0xe3, 0xc3, 0xed, 0xbe, 0x64, 0x03, 0x78, 0x7b, 0x49, 0x06, 0x9c, 0xe1, 0xaf,
0xe0, 0xd3, 0x0d, 0x9c, 0x1c, 0x21, 0xe2, 0xaa, 0x0e, 0x60, 0x18, 0x6b, 0x8c, 0x08, 0x4a, 0xc0,
0xcf, 0x77, 0xcc, 0xbe, 0xc5, 0xf8, 0x2c, 0xe4, 0x11, 0x19, 0xfe, 0xfa, 0xf5, 0xc9, 0x2c, 0xf7,
0xc6, 0xc3, 0x7f, 0xf1, 0x06, 0x54, 0xd5, 0x8d, 0x19, 0xf2, 0x7d, 0x68, 0xc4, 0xa2, 0x64, 0x90,
0x5b, 0xd9, 0xb1, 0x33, 0x50, 0x8a, 0xda, 0x7c, 0xed, 0x45, 0x81, 0x35, 0xc8, 0xa1, 0xa6, 0xb8,
0xe0, 0x85, 0xbd, 0x96, 0x54, 0x26, 0xc4, 0x4a, 0xbb, 0x7d, 0x4d, 0xaa, 0x28, 0xee, 0x09, 0xbe,
0x92, 0x80, 0x51, 0x25, 0xc5, 0xf1, 0x42, 0x6e, 0x47, 0x21, 0xeb, 0x75, 0xb8, 0x2c, 0x50, 0x8a,
0x89, 0x5a, 0xda, 0x2e, 0x0d, 0x6d, 0x67, 0x12, 0x90, 0x5d, 0xa8, 0x69, 0x0f, 0x0f, 0x93, 0x9b,
0xd7, 0xbe, 0x92, 0xbc, 0xb9, 0x99, 0x95, 0x24, 0x9a, 0xf4, 0x5d, 0xa8, 0xaa, 0x87, 0x57, 0xc9,
0x86, 0xf6, 0x30, 0xb0, 0xfe, 0x60, 0xed, 0x66, 0x2b, 0x9d, 0x20, 0xf2, 0xef, 0x42, 0x4d, 0x7b,
0x25, 0x55, 0xb5, 0x22, 0xfd, 0x46, 0xab, 0x6a, 0x45, 0xd6, 0xa3, 0xaa, 0x07, 0xb0, 0x26, 0xd4,
0x23, 0x27, 0xf4, 0xeb, 0x0c, 0x0f, 0x49, 0x0f, 0xcf, 0x83, 0x1c, 0xf9, 0x02, 0x2a, 0xf2, 0x6d,
0x5e, 0xb2, 0x9e, 0xfd, 0xd6, 0xf1, 0xe6, 0x46, 0x0a, 0x2e, 0x9a, 0xd2, 0x06, 0x88, 0x5e, 0x59,
0x25, 0xb2, 0xe3, 0xa9, 0xf7, 0x5c, 0xd5, 0xcc, 0x64, 0x3c, 0xc9, 0xba, 0x0b, 0x35, 0xed, 0x41,
0x55, 0x35, 0x26, 0xe9, 0xc7, 0x58, 0xd5, 0x98, 0x64, 0xbd, 0xbf, 0xfa, 0x7d, 0x68, 0xc4, 0x5e,
0x46, 0x55, 0xeb, 0x38, 0xeb, 0xdd, 0x55, 0xb5, 0x8e, 0xb3, 0x1f, 0x53, 0xdd, 0x85, 0x9a, 0xf6,
0x5a, 0xa9, 0x6a, 0x51, 0xfa, 0xc9, 0x54, 0xd5, 0xa2, 0x8c, 0xc7, 0x4d, 0xd9, 0x6e, 0x88, 0x3f,
0x55, 0xaa, 0x76, 0x43, 0xe6, 0x9b, 0xa7, 0x6a, 0x37, 0x64, 0xbf, 0x6f, 0xca, 0x96, 0x9e, 0x7a,
0x1e, 0x85, 0x6c, 0xc4, 0xb4, 0x12, 0xd1, 0x3b, 0x2b, 0x6a, 0xe9, 0xa5, 0x5f, 0x52, 0x79, 0x0c,
0x2b, 0x6a, 0xd1, 0xa8, 0xc7, 0x4d, 0x02, 0xd5, 0xa6, 0xcc, 0x27, 0x54, 0x36, 0x9b, 0xc9, 0xd4,
0x07, 0x39, 0xf2, 0x19, 0x94, 0xc5, 0x8b, 0x11, 0x64, 0x2d, 0xf9, 0x82, 0x04, 0x6f, 0xc4, 0x7a,
0xf6, 0xc3, 0x12, 0xe4, 0x08, 0x37, 0xb4, 0xfe, 0xa4, 0x83, 0xbe, 0x62, 0x33, 0x5e, 0x81, 0xd8,
0x7c, 0xfd, 0xba, 0xe4, 0xa8, 0xc4, 0xe4, 0x33, 0x24, 0xb7, 0xaf, 0x8b, 0xf6, 0x15, 0x2f, 0xf1,
0xba, 0xb0, 0xa4, 0x8f, 0xa1, 0xae, 0x3f, 0x53, 0x47, 0xf4, 0x7d, 0x98, 0x2c, 0xeb, 0x56, 0x66,
0x9a, 0x28, 0xe8, 0x4b, 0x58, 0x57, 0xe3, 0xad, 0x87, 0x9e, 0x0a, 0xc8, 0x9d, 0x8c, 0x80, 0x54,
0xb1, 0x51, 0xbf, 0x79, 0x6d, 0xc4, 0xaa, 0x07, 0x39, 0x24, 0xb2, 0xb1, 0x97, 0xa5, 0x22, 0x22,
0x9b, 0xf5, 0xa0, 0x56, 0x44, 0x64, 0xb3, 0x9f, 0xa3, 0x6a, 0xc3, 0x92, 0x16, 0x3a, 0x6b, 0x70,
0xe5, 0x8e, 0xd4, 0x7a, 0x4f, 0xc7, 0xd0, 0xdf, 0xcc, 0x52, 0xd2, 0x93, 0x1d, 0xa8, 0xe9, 0xd1,
0xb7, 0x5e, 0x90, 0x7d, 0x43, 0x4b, 0xd2, 0x43, 0x9b, 0x3f, 0xc8, 0x91, 0x03, 0x68, 0x26, 0x63,
0xe5, 0xaa, 0x2d, 0x9c, 0x15, 0x5f, 0x78, 0x33, 0x91, 0x18, 0x8b, 0xb0, 0xcb, 0xd6, 0x85, 0xa8,
0x9a, 0x3f, 0x0a, 0xeb, 0xf9, 0xc9, 0xa3, 0x88, 0xc3, 0xe5, 0x30, 0xa8, 0xd2, 0x12, 0xa9, 0xd8,
0xec, 0x7b, 0xb9, 0x07, 0x39, 0xb2, 0x07, 0xf5, 0x58, 0xa8, 0xc8, 0xd8, 0xe5, 0xad, 0x44, 0x37,
0x5b, 0x7a, 0x5a, 0xa2, 0x9f, 0x87, 0xb0, 0x18, 0x77, 0x3a, 0x51, 0x0d, 0xcb, 0xf4, 0x8c, 0x51,
0xd3, 0x97, 0xed, 0xa9, 0x42, 0x7e, 0x16, 0x6a, 0x8c, 0x26, 0x4b, 0xcf, 0x48, 0xa2, 0xd1, 0xe9,
0xe4, 0x9c, 0x71, 0x98, 0xd0, 0x9a, 0x17, 0xfe, 0x72, 0x3e, 0x87, 0xfd, 0xfa, 0x0e, 0x7f, 0x06,
0x5f, 0x3a, 0xc7, 0xb1, 0xf9, 0x7f, 0xd5, 0x42, 0xc8, 0x1e, 0xaf, 0x7c, 0xe8, 0xf1, 0x98, 0x0c,
0x37, 0x35, 0x1c, 0x01, 0x7b, 0xb5, 0x36, 0xb4, 0x79, 0x1b, 0x44, 0x9e, 0xd8, 0x1a, 0x7c, 0xc5,
0xb2, 0xc8, 0xa7, 0x00, 0x91, 0x53, 0x32, 0x49, 0xf8, 0xbd, 0xaa, 0x0d, 0x95, 0xe1, 0xb7, 0xdc,
0xe1, 0xfb, 0x5d, 0x39, 0xde, 0xea, 0x47, 0x72, 0xdc, 0x07, 0x38, 0x76, 0x24, 0x27, 0x8b, 0xf9,
0x08, 0x1a, 0x07, 0x9e, 0xf7, 0x6c, 0x3e, 0x53, 0x57, 0x75, 0xe2, 0x6e, 0x5f, 0xfb, 0x76, 0x70,
0xbe, 0x99, 0x68, 0x16, 0x69, 0xc3, 0xb2, 0x22, 0x11, 0x91, 0xe7, 0x6f, 0x1c, 0x29, 0x46, 0x18,
0x12, 0x05, 0x3c, 0xc8, 0x91, 0x87, 0x50, 0xdf, 0xa5, 0x23, 0x0c, 0x66, 0x83, 0x6e, 0x40, 0x2b,
0x31, 0x97, 0x12, 0xee, 0x3f, 0xb4, 0xd9, 0x88, 0x01, 0x25, 0x89, 0x8b, 0x1c, 0xdd, 0xf4, 0x33,
0x23, 0xee, 0x2d, 0x16, 0x23, 0x71, 0x29, 0x67, 0xb7, 0x2f, 0x61, 0x39, 0xe5, 0xec, 0xa5, 0xa8,
0xdb, 0x75, 0x0e, 0x68, 0x9b, 0x77, 0xaf, 0x47, 0x10, 0xe5, 0x7e, 0x0f, 0x1a, 0x3c, 0xd2, 0xfd,
0x09, 0xe5, 0xf7, 0xbe, 0x13, 0x71, 0x0c, 0xf5, 0x4b, 0xe5, 0x49, 0x92, 0xc4, 0x33, 0x3c, 0xc6,
0x37, 0xb7, 0xb4, 0x5b, 0xd5, 0x6a, 0x5e, 0xd3, 0x37, 0xbd, 0xd5, 0xbc, 0x66, 0x5d, 0xe0, 0xfe,
0x1c, 0x6a, 0x8f, 0x69, 0x28, 0xef, 0x29, 0x2b, 0xfe, 0x28, 0x71, 0x71, 0x79, 0x33, 0xe3, 0x76,
0x39, 0xf9, 0x04, 0xb3, 0xaa, 0x98, 0x1b, 0xeb, 0x5a, 0x2d, 0x7a, 0xd6, 0xa5, 0x04, 0x9c, 0x71,
0x1f, 0x5a, 0x38, 0x20, 0xd5, 0xf0, 0x74, 0xf8, 0x27, 0xd5, 0xf0, 0xac, 0xe8, 0x41, 0x3f, 0xcb,
0x47, 0x40, 0xbb, 0x19, 0x1d, 0xb1, 0x60, 0xc9, 0x4b, 0xd4, 0xaa, 0xf9, 0x3a, 0xfa, 0x23, 0x80,
0x41, 0xe8, 0xcd, 0x76, 0x6d, 0x3a, 0xf5, 0xdc, 0x88, 0x26, 0x44, 0x77, 0x72, 0xa3, 0x8d, 0xa8,
0x5d, 0xcc, 0x25, 0x5f, 0x69, 0xbc, 0x69, 0x6c, 0x4a, 0xe4, 0xb4, 0x5f, 0x7b, 0x6d, 0x57, 0x75,
0x27, 0xe3, 0xea, 0x2e, 0x12, 0x09, 0x88, 0x7c, 0xe9, 0x14, 0xa7, 0x99, 0x72, 0xd3, 0x53, 0x7b,
0x3d, 0xc3, 0xf1, 0xee, 0xbb, 0x50, 0x8d, 0x9c, 0x90, 0x36, 0xa2, 0xd8, 0x64, 0x31, 0x97, 0x25,
0x45, 0xbd, 0xd3, 0x0e, 0x40, 0x3d, 0x58, 0xe1, 0xcd, 0x51, 0xc7, 0x1f, 0xde, 0xd5, 0x54, 0x4f,
0xc6, 0xa5, 0x3d, 0x6f, 0xd4, 0xfe, 0xc9, 0xf2, 0x1f, 0x61, 0xfb, 0x27, 0xe5, 0x60, 0xa0, 0xf6,
0xcf, 0x75, 0x8e, 0x25, 0x6a, 0xff, 0x5c, 0xef, 0x9b, 0xd0, 0x83, 0x95, 0x0c, 0x57, 0x01, 0xf2,
0x86, 0x14, 0x6c, 0xae, 0x75, 0x23, 0xd8, 0xcc, 0x34, 0x29, 0x93, 0x21, 0x6c, 0xf0, 0x3c, 0xed,
0xc9, 0x24, 0x61, 0x99, 0x7e, 0x5d, 0xcb, 0x90, 0x61, 0x6d, 0x8f, 0xb1, 0x32, 0x09, 0x8b, 0x7b,
0x0f, 0x9a, 0x49, 0xa3, 0x2e, 0xb9, 0x1e, 0x7d, 0xf3, 0x4e, 0x8c, 0x65, 0x4f, 0x1b, 0x82, 0xc9,
0x97, 0xca, 0xb4, 0x9c, 0x68, 0xe3, 0x9d, 0xe8, 0xe9, 0xd3, 0x4c, 0x43, 0xb8, 0x92, 0x06, 0x32,
0x2d, 0xd3, 0xe4, 0xe7, 0x60, 0x23, 0xb9, 0xa2, 0x65, 0xc9, 0x77, 0xb3, 0x86, 0xeb, 0x5a, 0x56,
0x2e, 0xde, 0xa1, 0x07, 0x39, 0x46, 0x88, 0x75, 0x03, 0xb0, 0x5a, 0x48, 0x19, 0x96, 0x68, 0xb5,
0x90, 0x32, 0x2d, 0xc6, 0x47, 0xb0, 0x94, 0xb0, 0xfd, 0x2a, 0x36, 0x38, 0xdb, 0x5a, 0xac, 0xd8,
0xe0, 0xeb, 0x4c, 0xc6, 0x03, 0x68, 0x26, 0xad, 0xba, 0x6a, 0xae, 0xaf, 0xb1, 0x14, 0x6f, 0xde,
0xb9, 0x36, 0x3d, 0xde, 0x4c, 0xcd, 0xfe, 0x19, 0x6b, 0x66, 0xda, 0x6a, 0x1b, 0x6b, 0x66, 0x86,
0xf5, 0x75, 0xfb, 0x9d, 0x9f, 0xff, 0xd6, 0x99, 0x13, 0x9e, 0xcf, 0x4f, 0xb6, 0x46, 0xde, 0xf4,
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.

@ -2493,12 +2493,22 @@ message Hop {
/*
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
final hop payload of all non-zero payments in the HTLC set. If empty, a
regular single-shot payment is or was attempted.
the receiver will enforce that the same mpp_record is included in the final
hop payload of all non-zero payments in the HTLC set. If empty, a regular
single-shot payment is or was attempted.
*/
MPPRecord mpp_record = 10;
/*
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
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;
}
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
succession. This struct carries all the information required to craft the

@ -2536,6 +2536,23 @@
},
"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": {
"type": "object"
},
@ -4025,7 +4042,11 @@
},
"mpp_record": {
"$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": {
"type": "object",

@ -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)
}
}

@ -74,36 +74,6 @@ func testSendToRouteMultiPath(net *lntest.NetworkHarness, t *harnessTest) {
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.
sendRoutes := [][]*lntest.HarnessNode{
{ctx.carol, ctx.bob},
@ -114,7 +84,7 @@ func testSendToRouteMultiPath(net *lntest.NetworkHarness, t *harnessTest) {
responses := make(chan *lnrpc.HTLCAttempt, len(sendRoutes))
for _, hops := range sendRoutes {
// Build a route for the specified hops.
r, err := buildRoute(shardAmt, hops)
r, err := ctx.buildRoute(ctxb, shardAmt, net.Alice, hops)
if err != nil {
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
}

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

@ -129,6 +129,16 @@ const (
// transactions, which also imply anchor commitments.
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.
//
// 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",
WumboChannelsRequired: "wumbo-channels",
WumboChannelsOptional: "wumbo-channels",
AMPRequired: "amp",
AMPOptional: "amp",
}
// RawFeatureVector represents a set of feature bits as defined in BOLT-09. A

@ -9,19 +9,19 @@ import (
// AMPOnionType is the type used in the onion to reference the AMP fields:
// 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
// payments.
type AMP struct {
rootShare [32]byte
setID [32]byte
childIndex uint16
childIndex uint32
}
// NewAMP generate a new AMP record with the given root_share, set_id, and
// child_index.
func NewAMP(rootShare, setID [32]byte, childIndex uint16) *AMP {
func NewAMP(rootShare, setID [32]byte, childIndex uint32) *AMP {
return &AMP{
rootShare: rootShare,
setID: setID,
@ -40,7 +40,7 @@ func (a *AMP) SetID() [32]byte {
}
// ChildIndex returns the child index contained in the AMP record.
func (a *AMP) ChildIndex() uint16 {
func (a *AMP) ChildIndex() uint32 {
return a.childIndex
}
@ -55,7 +55,7 @@ func AMPEncoder(w io.Writer, val interface{}, buf *[8]byte) error {
return err
}
return tlv.ETUint16T(w, v.childIndex, buf)
return tlv.ETUint32T(w, v.childIndex, buf)
}
return tlv.NewTypeForEncodingErr(val, "AMP")
}
@ -69,7 +69,7 @@ const (
// maxAMPLength is the maximum legnth of a serialized AMP TLV record,
// which occurs when the truncated endoing of a child_index takes 2
// bytes.
maxAMPLength = 66
maxAMPLength = 68
)
// 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 tlv.DTUint16(r, &v.childIndex, buf, l-64)
return tlv.DTUint32(r, &v.childIndex, buf, l-minAMPLength)
}
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.
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.

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