Merge pull request #3390 from joostjager/invoice-circuits

channeldb+cnct+invoices: track invoice htlcs
This commit is contained in:
Olaoluwa Osuntokun 2019-09-04 19:51:37 -07:00 committed by GitHub
commit 7eca7b02a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 1993 additions and 1010 deletions

@ -108,7 +108,7 @@ func WriteElement(w io.Writer, element interface{}) error {
return err
}
case uint64:
case int64, uint64:
if err := binary.Write(w, byteOrder, e); err != nil {
return err
}
@ -280,7 +280,7 @@ func ReadElement(r io.Reader, element interface{}) error {
return err
}
case *uint64:
case *int64, *uint64:
if err := binary.Read(r, byteOrder, e); err != nil {
return err
}

@ -110,6 +110,11 @@ var (
number: 10,
migration: migrateRouteSerialization,
},
{
// Add invoice htlc and cltv delta fields.
number: 11,
migration: migrateInvoices,
},
}
// Big endian is the preferred byte order, due to cursor scans over
@ -124,6 +129,7 @@ type DB struct {
*bbolt.DB
dbPath string
graph *ChannelGraph
now func() time.Time
}
// Open opens an existing channeldb. Any necessary schemas migrations due to
@ -157,6 +163,7 @@ func Open(dbPath string, modifiers ...OptionModifier) (*DB, error) {
chanDB := &DB{
DB: bdb,
dbPath: dbPath,
now: time.Now,
}
chanDB.graph = newChannelGraph(
chanDB, opts.RejectCacheSize, opts.ChannelCacheSize,

@ -24,6 +24,8 @@ func randInvoice(value lnwire.MilliSatoshi) (*Invoice, error) {
PaymentPreimage: pre,
Value: value,
},
Htlcs: map[CircuitKey]*InvoiceHTLC{},
Expiry: 4000,
}
i.Memo = []byte("memo")
i.Receipt = []byte("receipt")
@ -59,6 +61,7 @@ func TestInvoiceWorkflow(t *testing.T) {
// Use single second precision to avoid false positive test
// failures due to the monotonic time component.
CreationDate: time.Unix(time.Now().Unix(), 0),
Htlcs: map[CircuitKey]*InvoiceHTLC{},
}
fakeInvoice.Memo = []byte("memo")
fakeInvoice.Receipt = []byte("receipt")
@ -99,9 +102,7 @@ func TestInvoiceWorkflow(t *testing.T) {
// now have the settled bit toggle to true and a non-default
// SettledDate
payAmt := fakeInvoice.Terms.Value * 2
_, err = db.AcceptOrSettleInvoice(
paymentHash, payAmt, checkHtlcParameters,
)
_, err = db.UpdateInvoice(paymentHash, getUpdateInvoice(payAmt))
if err != nil {
t.Fatalf("unable to settle invoice: %v", err)
}
@ -264,8 +265,8 @@ func TestInvoiceAddTimeSeries(t *testing.T) {
paymentHash := invoice.Terms.PaymentPreimage.Hash()
_, err := db.AcceptOrSettleInvoice(
paymentHash, 0, checkHtlcParameters,
_, err := db.UpdateInvoice(
paymentHash, getUpdateInvoice(0),
)
if err != nil {
t.Fatalf("unable to settle invoice: %v", err)
@ -332,6 +333,7 @@ func TestDuplicateSettleInvoice(t *testing.T) {
if err != nil {
t.Fatalf("unable to make test db: %v", err)
}
db.now = func() time.Time { return time.Unix(1, 0) }
// We'll start out by creating an invoice and writing it to the DB.
amt := lnwire.NewMSatFromSatoshis(1000)
@ -347,8 +349,8 @@ func TestDuplicateSettleInvoice(t *testing.T) {
}
// With the invoice in the DB, we'll now attempt to settle the invoice.
dbInvoice, err := db.AcceptOrSettleInvoice(
payHash, amt, checkHtlcParameters,
dbInvoice, err := db.UpdateInvoice(
payHash, getUpdateInvoice(amt),
)
if err != nil {
t.Fatalf("unable to settle invoice: %v", err)
@ -360,6 +362,14 @@ func TestDuplicateSettleInvoice(t *testing.T) {
invoice.Terms.State = ContractSettled
invoice.AmtPaid = amt
invoice.SettleDate = dbInvoice.SettleDate
invoice.Htlcs = map[CircuitKey]*InvoiceHTLC{
{}: {
Amt: amt,
AcceptTime: time.Unix(1, 0),
ResolveTime: time.Unix(1, 0),
State: HtlcStateSettled,
},
}
// We should get back the exact same invoice that we just inserted.
if !reflect.DeepEqual(dbInvoice, invoice) {
@ -369,8 +379,8 @@ func TestDuplicateSettleInvoice(t *testing.T) {
// If we try to settle the invoice again, then we should get the very
// same invoice back, but with an error this time.
dbInvoice, err = db.AcceptOrSettleInvoice(
payHash, amt, checkHtlcParameters,
dbInvoice, err = db.UpdateInvoice(
payHash, getUpdateInvoice(amt),
)
if err != ErrInvoiceAlreadySettled {
t.Fatalf("expected ErrInvoiceAlreadySettled")
@ -416,8 +426,8 @@ func TestQueryInvoices(t *testing.T) {
// We'll only settle half of all invoices created.
if i%2 == 0 {
_, err := db.AcceptOrSettleInvoice(
paymentHash, i, checkHtlcParameters,
_, err := db.UpdateInvoice(
paymentHash, getUpdateInvoice(i),
)
if err != nil {
t.Fatalf("unable to settle invoice: %v", err)
@ -661,10 +671,24 @@ func TestQueryInvoices(t *testing.T) {
}
}
func checkHtlcParameters(invoice *Invoice) error {
if invoice.Terms.State == ContractSettled {
return ErrInvoiceAlreadySettled
}
// getUpdateInvoice returns an invoice update callback that, when called,
// settles the invoice with the given amount.
func getUpdateInvoice(amt lnwire.MilliSatoshi) InvoiceUpdateCallback {
return func(invoice *Invoice) (*InvoiceUpdateDesc, error) {
if invoice.Terms.State == ContractSettled {
return nil, ErrInvoiceAlreadySettled
}
return nil
update := &InvoiceUpdateDesc{
Preimage: invoice.Terms.PaymentPreimage,
State: ContractSettled,
Htlcs: map[CircuitKey]*HtlcAcceptDesc{
{}: {
Amt: amt,
},
},
}
return update, nil
}
}

@ -12,6 +12,7 @@ import (
"github.com/coreos/bbolt"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/tlv"
)
var (
@ -92,6 +93,17 @@ const (
// TODO(halseth): determine the max length payment request when field
// lengths are final.
MaxPaymentRequestSize = 4096
// A set of tlv type definitions used to serialize invoice htlcs to the
// database.
chanIDType tlv.Type = 1
htlcIDType tlv.Type = 3
amtType tlv.Type = 5
acceptHeightType tlv.Type = 7
acceptTimeType tlv.Type = 9
resolveTimeType tlv.Type = 11
expiryHeightType tlv.Type = 13
stateType tlv.Type = 15
)
// ContractState describes the state the invoice is in.
@ -172,6 +184,13 @@ type Invoice struct {
// for this invoice can be stored.
PaymentRequest []byte
// FinalCltvDelta is the minimum required number of blocks before htlc
// expiry when the invoice is accepted.
FinalCltvDelta int32
// Expiry defines how long after creation this invoice should expire.
Expiry time.Duration
// CreationDate is the exact time the invoice was created.
CreationDate time.Time
@ -209,8 +228,85 @@ type Invoice struct {
// that the invoice originally didn't specify an amount, or the sender
// overpaid.
AmtPaid lnwire.MilliSatoshi
// Htlcs records all htlcs that paid to this invoice. Some of these
// htlcs may have been marked as cancelled.
Htlcs map[CircuitKey]*InvoiceHTLC
}
// HtlcState defines the states an htlc paying to an invoice can be in.
type HtlcState uint8
const (
// HtlcStateAccepted indicates the htlc is locked-in, but not resolved.
HtlcStateAccepted HtlcState = iota
// HtlcStateCancelled indicates the htlc is cancelled back to the
// sender.
HtlcStateCancelled
// HtlcStateSettled indicates the htlc is settled.
HtlcStateSettled
)
// InvoiceHTLC contains details about an htlc paying to this invoice.
type InvoiceHTLC struct {
// Amt is the amount that is carried by this htlc.
Amt lnwire.MilliSatoshi
// AcceptHeight is the block height at which the invoice registry
// decided to accept this htlc as a payment to the invoice. At this
// height, the invoice cltv delay must have been met.
AcceptHeight uint32
// AcceptTime is the wall clock time at which the invoice registry
// decided to accept the htlc.
AcceptTime time.Time
// ResolveTime is the wall clock time at which the invoice registry
// decided to settle the htlc.
ResolveTime time.Time
// Expiry is the expiry height of this htlc.
Expiry uint32
// State indicates the state the invoice htlc is currently in. A
// cancelled htlc isn't just removed from the invoice htlcs map, because
// we need AcceptedHeight to properly cancel the htlc back.
State HtlcState
}
// HtlcAcceptDesc describes the details of a newly accepted htlc.
type HtlcAcceptDesc struct {
// AcceptHeight is the block height at which this htlc was accepted.
AcceptHeight int32
// Amt is the amount that is carried by this htlc.
Amt lnwire.MilliSatoshi
// Expiry is the expiry height of this htlc.
Expiry uint32
}
// InvoiceUpdateDesc describes the changes that should be applied to the
// invoice.
type InvoiceUpdateDesc struct {
// State is the new state that this invoice should progress to.
State ContractState
// Htlcs describes the changes that need to be made to the invoice htlcs
// in the database. Htlc map entries with their value set should be
// added. If the map value is nil, the htlc should be cancelled.
Htlcs map[CircuitKey]*HtlcAcceptDesc
// Preimage must be set to the preimage when state is settled.
Preimage lntypes.Preimage
}
// InvoiceUpdateCallback is a callback used in the db transaction to update the
// invoice.
type InvoiceUpdateCallback = func(invoice *Invoice) (*InvoiceUpdateDesc, error)
func validateInvoice(i *Invoice) error {
if len(i.Memo) > MaxMemoSize {
return fmt.Errorf("max length a memo is %v, and invoice "+
@ -624,21 +720,17 @@ func (d *DB) QueryInvoices(q InvoiceQuery) (InvoiceSlice, error) {
return resp, nil
}
// AcceptOrSettleInvoice attempts to mark an invoice corresponding to the passed
// payment hash as settled. If an invoice matching the passed payment hash
// doesn't existing within the database, then the action will fail with a "not
// found" error.
// UpdateInvoice attempts to update an invoice corresponding to the passed
// payment hash. If an invoice matching the passed payment hash doesn't exist
// within the database, then the action will fail with a "not found" error.
//
// When the preimage for the invoice is unknown (hold invoice), the invoice is
// marked as accepted.
//
// TODO: Store invoice cltv as separate field in database so that it doesn't
// need to be decoded from the payment request.
func (d *DB) AcceptOrSettleInvoice(paymentHash [32]byte,
amtPaid lnwire.MilliSatoshi,
checkHtlcParameters func(invoice *Invoice) error) (*Invoice, error) {
// The update is performed inside the same database transaction that fetches the
// invoice and is therefore atomic. The fields to update are controlled by the
// supplied callback.
func (d *DB) UpdateInvoice(paymentHash lntypes.Hash,
callback InvoiceUpdateCallback) (*Invoice, error) {
var settledInvoice *Invoice
var updatedInvoice *Invoice
err := d.Update(func(tx *bbolt.Tx) error {
invoices, err := tx.CreateBucketIfNotExists(invoiceBucket)
if err != nil {
@ -664,49 +756,9 @@ func (d *DB) AcceptOrSettleInvoice(paymentHash [32]byte,
return ErrInvoiceNotFound
}
settledInvoice, err = acceptOrSettleInvoice(
invoices, settleIndex, invoiceNum, amtPaid,
checkHtlcParameters,
)
return err
})
return settledInvoice, err
}
// SettleHoldInvoice sets the preimage of a hodl invoice and marks the invoice
// as settled.
func (d *DB) SettleHoldInvoice(preimage lntypes.Preimage) (*Invoice, error) {
var updatedInvoice *Invoice
hash := preimage.Hash()
err := d.Update(func(tx *bbolt.Tx) error {
invoices, err := tx.CreateBucketIfNotExists(invoiceBucket)
if err != nil {
return err
}
invoiceIndex, err := invoices.CreateBucketIfNotExists(
invoiceIndexBucket,
)
if err != nil {
return err
}
settleIndex, err := invoices.CreateBucketIfNotExists(
settleIndexBucket,
)
if err != nil {
return err
}
// Check the invoice index to see if an invoice paying to this
// hash exists within the DB.
invoiceNum := invoiceIndex.Get(hash[:])
if invoiceNum == nil {
return ErrInvoiceNotFound
}
updatedInvoice, err = settleHoldInvoice(
invoices, settleIndex, invoiceNum, preimage,
updatedInvoice, err = d.updateInvoice(
paymentHash, invoices, settleIndex, invoiceNum,
callback,
)
return err
@ -715,37 +767,6 @@ func (d *DB) SettleHoldInvoice(preimage lntypes.Preimage) (*Invoice, error) {
return updatedInvoice, err
}
// CancelInvoice attempts to cancel the invoice corresponding to the passed
// payment hash.
func (d *DB) CancelInvoice(paymentHash lntypes.Hash) (*Invoice, error) {
var canceledInvoice *Invoice
err := d.Update(func(tx *bbolt.Tx) error {
invoices, err := tx.CreateBucketIfNotExists(invoiceBucket)
if err != nil {
return err
}
invoiceIndex, err := invoices.CreateBucketIfNotExists(
invoiceIndexBucket,
)
if err != nil {
return err
}
// Check the invoice index to see if an invoice paying to this
// hash exists within the DB.
invoiceNum := invoiceIndex.Get(paymentHash[:])
if invoiceNum == nil {
return ErrInvoiceNotFound
}
canceledInvoice, err = cancelInvoice(invoices, invoiceNum)
return err
})
return canceledInvoice, err
}
// InvoicesSettledSince can be used by callers to catch up any settled invoices
// they missed within the settled invoice time series. We'll return all known
// settled invoice that have a settle index higher than the passed
@ -855,7 +876,7 @@ func putInvoice(invoices, invoiceIndex, addIndex *bbolt.Bucket,
// Finally, serialize the invoice itself to be written to the disk.
var buf bytes.Buffer
if err := serializeInvoice(&buf, i); err != nil {
return 0, nil
return 0, err
}
if err := invoices.Put(invoiceKey[:], buf.Bytes()); err != nil {
@ -865,6 +886,11 @@ func putInvoice(invoices, invoiceIndex, addIndex *bbolt.Bucket,
return nextAddSeqNo, nil
}
// serializeInvoice serializes an invoice to a writer.
//
// Note: this function is in use for a migration. Before making changes that
// would modify the on disk format, make a copy of the original code and store
// it with the migration.
func serializeInvoice(w io.Writer, i *Invoice) error {
if err := wire.WriteVarBytes(w, 0, i.Memo[:]); err != nil {
return err
@ -876,6 +902,14 @@ func serializeInvoice(w io.Writer, i *Invoice) error {
return err
}
if err := binary.Write(w, byteOrder, i.FinalCltvDelta); err != nil {
return err
}
if err := binary.Write(w, byteOrder, int64(i.Expiry)); err != nil {
return err
}
birthBytes, err := i.CreationDate.MarshalBinary()
if err != nil {
return err
@ -918,6 +952,57 @@ func serializeInvoice(w io.Writer, i *Invoice) error {
return err
}
if err := serializeHtlcs(w, i.Htlcs); err != nil {
return err
}
return nil
}
// serializeHtlcs serializes a map containing circuit keys and invoice htlcs to
// a writer.
func serializeHtlcs(w io.Writer, htlcs map[CircuitKey]*InvoiceHTLC) error {
for key, htlc := range htlcs {
// Encode the htlc in a tlv stream.
chanID := key.ChanID.ToUint64()
amt := uint64(htlc.Amt)
acceptTime := uint64(htlc.AcceptTime.UnixNano())
resolveTime := uint64(htlc.ResolveTime.UnixNano())
state := uint8(htlc.State)
tlvStream, err := tlv.NewStream(
tlv.MakePrimitiveRecord(chanIDType, &chanID),
tlv.MakePrimitiveRecord(htlcIDType, &key.HtlcID),
tlv.MakePrimitiveRecord(amtType, &amt),
tlv.MakePrimitiveRecord(
acceptHeightType, &htlc.AcceptHeight,
),
tlv.MakePrimitiveRecord(acceptTimeType, &acceptTime),
tlv.MakePrimitiveRecord(resolveTimeType, &resolveTime),
tlv.MakePrimitiveRecord(expiryHeightType, &htlc.Expiry),
tlv.MakePrimitiveRecord(stateType, &state),
)
if err != nil {
return err
}
var b bytes.Buffer
if err := tlvStream.Encode(&b); err != nil {
return err
}
// Write the length of the tlv stream followed by the stream
// bytes.
err = binary.Write(w, byteOrder, uint64(b.Len()))
if err != nil {
return err
}
if _, err := w.Write(b.Bytes()); err != nil {
return err
}
}
return nil
}
@ -951,6 +1036,16 @@ func deserializeInvoice(r io.Reader) (Invoice, error) {
return invoice, err
}
if err := binary.Read(r, byteOrder, &invoice.FinalCltvDelta); err != nil {
return invoice, err
}
var expiry int64
if err := binary.Read(r, byteOrder, &expiry); err != nil {
return invoice, err
}
invoice.Expiry = time.Duration(expiry)
birthBytes, err := wire.ReadVarBytes(r, 0, 300, "birth")
if err != nil {
return invoice, err
@ -990,38 +1085,204 @@ func deserializeInvoice(r io.Reader) (Invoice, error) {
return invoice, err
}
invoice.Htlcs, err = deserializeHtlcs(r)
if err != nil {
return Invoice{}, err
}
return invoice, nil
}
func acceptOrSettleInvoice(invoices, settleIndex *bbolt.Bucket,
invoiceNum []byte, amtPaid lnwire.MilliSatoshi,
checkHtlcParameters func(invoice *Invoice) error) (
*Invoice, error) {
// deserializeHtlcs reads a list of invoice htlcs from a reader and returns it
// as a map.
func deserializeHtlcs(r io.Reader) (map[CircuitKey]*InvoiceHTLC, error) {
htlcs := make(map[CircuitKey]*InvoiceHTLC, 0)
for {
// Read the length of the tlv stream for this htlc.
var streamLen uint64
if err := binary.Read(r, byteOrder, &streamLen); err != nil {
if err == io.EOF {
break
}
return nil, err
}
streamBytes := make([]byte, streamLen)
if _, err := r.Read(streamBytes); err != nil {
return nil, err
}
streamReader := bytes.NewReader(streamBytes)
// Decode the contents into the htlc fields.
var (
htlc InvoiceHTLC
key CircuitKey
chanID uint64
state uint8
acceptTime, resolveTime uint64
amt uint64
)
tlvStream, err := tlv.NewStream(
tlv.MakePrimitiveRecord(chanIDType, &chanID),
tlv.MakePrimitiveRecord(htlcIDType, &key.HtlcID),
tlv.MakePrimitiveRecord(amtType, &amt),
tlv.MakePrimitiveRecord(
acceptHeightType, &htlc.AcceptHeight,
),
tlv.MakePrimitiveRecord(acceptTimeType, &acceptTime),
tlv.MakePrimitiveRecord(resolveTimeType, &resolveTime),
tlv.MakePrimitiveRecord(expiryHeightType, &htlc.Expiry),
tlv.MakePrimitiveRecord(stateType, &state),
)
if err != nil {
return nil, err
}
if err := tlvStream.Decode(streamReader); err != nil {
return nil, err
}
key.ChanID = lnwire.NewShortChanIDFromInt(chanID)
htlc.AcceptTime = time.Unix(0, int64(acceptTime))
htlc.ResolveTime = time.Unix(0, int64(resolveTime))
htlc.State = HtlcState(state)
htlc.Amt = lnwire.MilliSatoshi(amt)
htlcs[key] = &htlc
}
return htlcs, nil
}
// copySlice allocates a new slice and copies the source into it.
func copySlice(src []byte) []byte {
dest := make([]byte, len(src))
copy(dest, src)
return dest
}
// copyInvoice makes a deep copy of the supplied invoice.
func copyInvoice(src *Invoice) *Invoice {
dest := Invoice{
Memo: copySlice(src.Memo),
Receipt: copySlice(src.Receipt),
PaymentRequest: copySlice(src.PaymentRequest),
FinalCltvDelta: src.FinalCltvDelta,
CreationDate: src.CreationDate,
SettleDate: src.SettleDate,
Terms: src.Terms,
AddIndex: src.AddIndex,
SettleIndex: src.SettleIndex,
AmtPaid: src.AmtPaid,
Htlcs: make(
map[CircuitKey]*InvoiceHTLC, len(src.Htlcs),
),
}
for k, v := range src.Htlcs {
dest.Htlcs[k] = v
}
return &dest
}
// 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, settleIndex *bbolt.Bucket,
invoiceNum []byte, callback InvoiceUpdateCallback) (*Invoice, error) {
invoice, err := fetchInvoice(invoiceNum, invoices)
if err != nil {
return nil, err
}
// If the invoice is still open, check the htlc parameters.
if err := checkHtlcParameters(&invoice); err != nil {
preUpdateState := invoice.Terms.State
// Create deep copy to prevent any accidental modification in the
// callback.
copy := copyInvoice(&invoice)
// Call the callback and obtain the update descriptor.
update, err := callback(copy)
if err != nil {
return &invoice, err
}
// Check to see if we can settle or this is an hold invoice and we need
// to wait for the preimage.
holdInvoice := invoice.Terms.PaymentPreimage == UnknownPreimage
if holdInvoice {
invoice.Terms.State = ContractAccepted
} else {
err := setSettleFields(settleIndex, invoiceNum, &invoice)
// Update invoice state.
invoice.Terms.State = update.State
now := d.now()
// Update htlc set.
for key, htlcUpdate := range update.Htlcs {
htlc, ok := invoice.Htlcs[key]
// No update means the htlc needs to be cancelled.
if htlcUpdate == nil {
if !ok {
return nil, fmt.Errorf("unknown htlc %v", key)
}
if htlc.State == HtlcStateSettled {
return nil, fmt.Errorf("cannot cancel a " +
"settled htlc")
}
htlc.State = HtlcStateCancelled
htlc.ResolveTime = now
invoice.AmtPaid -= htlc.Amt
continue
}
// Add new htlc paying to the invoice.
if ok {
return nil, fmt.Errorf("htlc %v already exists", key)
}
htlc = &InvoiceHTLC{
Amt: htlcUpdate.Amt,
Expiry: htlcUpdate.Expiry,
AcceptHeight: uint32(htlcUpdate.AcceptHeight),
AcceptTime: now,
}
if preUpdateState == ContractSettled {
htlc.State = HtlcStateSettled
htlc.ResolveTime = now
} else {
htlc.State = HtlcStateAccepted
}
invoice.Htlcs[key] = htlc
invoice.AmtPaid += htlc.Amt
}
// If invoice moved to the settled state, update settle index and settle
// time.
if preUpdateState != invoice.Terms.State &&
invoice.Terms.State == ContractSettled {
if update.Preimage.Hash() != hash {
return nil, fmt.Errorf("preimage does not match")
}
invoice.Terms.PaymentPreimage = update.Preimage
// Settle all accepted htlcs.
for _, htlc := range invoice.Htlcs {
if htlc.State != HtlcStateAccepted {
continue
}
htlc.State = HtlcStateSettled
htlc.ResolveTime = now
}
err := setSettleFields(settleIndex, invoiceNum, &invoice, now)
if err != nil {
return nil, err
}
}
invoice.AmtPaid = amtPaid
var buf bytes.Buffer
if err := serializeInvoice(&buf, &invoice); err != nil {
return nil, err
@ -1035,7 +1296,7 @@ func acceptOrSettleInvoice(invoices, settleIndex *bbolt.Bucket,
}
func setSettleFields(settleIndex *bbolt.Bucket, invoiceNum []byte,
invoice *Invoice) error {
invoice *Invoice, now time.Time) error {
// Now that we know the invoice hasn't already been settled, we'll
// update the settle index so we can place this settle event in the
@ -1052,77 +1313,8 @@ func setSettleFields(settleIndex *bbolt.Bucket, invoiceNum []byte,
}
invoice.Terms.State = ContractSettled
invoice.SettleDate = time.Now()
invoice.SettleDate = now
invoice.SettleIndex = nextSettleSeqNo
return nil
}
func settleHoldInvoice(invoices, settleIndex *bbolt.Bucket,
invoiceNum []byte, preimage lntypes.Preimage) (*Invoice,
error) {
invoice, err := fetchInvoice(invoiceNum, invoices)
if err != nil {
return nil, err
}
switch invoice.Terms.State {
case ContractOpen:
return &invoice, ErrInvoiceStillOpen
case ContractCanceled:
return &invoice, ErrInvoiceAlreadyCanceled
case ContractSettled:
return &invoice, ErrInvoiceAlreadySettled
}
invoice.Terms.PaymentPreimage = preimage
err = setSettleFields(settleIndex, invoiceNum, &invoice)
if err != nil {
return nil, err
}
var buf bytes.Buffer
if err := serializeInvoice(&buf, &invoice); err != nil {
return nil, err
}
if err := invoices.Put(invoiceNum[:], buf.Bytes()); err != nil {
return nil, err
}
return &invoice, nil
}
func cancelInvoice(invoices *bbolt.Bucket, invoiceNum []byte) (
*Invoice, error) {
invoice, err := fetchInvoice(invoiceNum, invoices)
if err != nil {
return nil, err
}
switch invoice.Terms.State {
case ContractSettled:
return &invoice, ErrInvoiceAlreadySettled
case ContractCanceled:
return &invoice, ErrInvoiceAlreadyCanceled
}
invoice.Terms.State = ContractCanceled
// Set AmtPaid back to 0, in case the invoice was already accepted.
invoice.AmtPaid = 0
var buf bytes.Buffer
if err := serializeInvoice(&buf, &invoice); err != nil {
return nil, err
}
if err := invoices.Put(invoiceNum[:], buf.Bytes()); err != nil {
return nil, err
}
return &invoice, nil
}

@ -177,7 +177,7 @@ func fetchPaymentStatusTx(tx *bbolt.Tx, paymentHash [32]byte) (PaymentStatus, er
func serializeOutgoingPayment(w io.Writer, p *outgoingPayment) error {
var scratch [8]byte
if err := serializeInvoice(w, &p.Invoice); err != nil {
if err := serializeInvoiceLegacy(w, &p.Invoice); err != nil {
return err
}
@ -218,7 +218,7 @@ func deserializeOutgoingPayment(r io.Reader) (*outgoingPayment, error) {
p := &outgoingPayment{}
inv, err := deserializeInvoice(r)
inv, err := deserializeInvoiceLegacy(r)
if err != nil {
return nil, err
}

@ -0,0 +1,225 @@
package channeldb
import (
"bytes"
"encoding/binary"
"fmt"
"io"
bitcoinCfg "github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/wire"
"github.com/coreos/bbolt"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/zpay32"
litecoinCfg "github.com/ltcsuite/ltcd/chaincfg"
)
// migrateInvoices adds invoice htlcs and a separate cltv delta field to the
// invoices.
func migrateInvoices(tx *bbolt.Tx) error {
log.Infof("Migrating invoices to new invoice format")
invoiceB := tx.Bucket(invoiceBucket)
if invoiceB == nil {
return nil
}
// Iterate through the entire key space of the top-level invoice bucket.
// If key with a non-nil value stores the next invoice ID which maps to
// the corresponding invoice. Store those keys first, because it isn't
// safe to modify the bucket inside a ForEach loop.
var invoiceKeys [][]byte
err := invoiceB.ForEach(func(k, v []byte) error {
if v == nil {
return nil
}
invoiceKeys = append(invoiceKeys, k)
return nil
})
if err != nil {
return err
}
nets := []*bitcoinCfg.Params{
&bitcoinCfg.MainNetParams, &bitcoinCfg.SimNetParams,
&bitcoinCfg.RegressionNetParams, &bitcoinCfg.TestNet3Params,
}
ltcNets := []*litecoinCfg.Params{
&litecoinCfg.MainNetParams, &litecoinCfg.SimNetParams,
&litecoinCfg.RegressionNetParams, &litecoinCfg.TestNet4Params,
}
for _, net := range ltcNets {
var convertedNet bitcoinCfg.Params
convertedNet.Bech32HRPSegwit = net.Bech32HRPSegwit
nets = append(nets, &convertedNet)
}
// Iterate over all stored keys and migrate the invoices.
for _, k := range invoiceKeys {
v := invoiceB.Get(k)
// Deserialize the invoice with the deserializing function that
// was in use for this version of the database.
invoiceReader := bytes.NewReader(v)
invoice, err := deserializeInvoiceLegacy(invoiceReader)
if err != nil {
return err
}
// Try to decode the payment request for every possible net to
// avoid passing a the active network to channeldb. This would
// be a layering violation, while this migration is only running
// once and will likely be removed in the future.
var payReq *zpay32.Invoice
for _, net := range nets {
payReq, err = zpay32.Decode(
string(invoice.PaymentRequest), net,
)
if err == nil {
break
}
}
if payReq == nil {
return fmt.Errorf("cannot decode payreq")
}
invoice.FinalCltvDelta = int32(payReq.MinFinalCLTVExpiry())
invoice.Expiry = payReq.Expiry()
// Serialize the invoice in the new format and use it to replace
// the old invoice in the database.
var buf bytes.Buffer
if err := serializeInvoice(&buf, &invoice); err != nil {
return err
}
err = invoiceB.Put(k, buf.Bytes())
if err != nil {
return err
}
}
log.Infof("Migration of invoices completed!")
return nil
}
func deserializeInvoiceLegacy(r io.Reader) (Invoice, error) {
var err error
invoice := Invoice{}
// TODO(roasbeef): use read full everywhere
invoice.Memo, err = wire.ReadVarBytes(r, 0, MaxMemoSize, "")
if err != nil {
return invoice, err
}
invoice.Receipt, err = wire.ReadVarBytes(r, 0, MaxReceiptSize, "")
if err != nil {
return invoice, err
}
invoice.PaymentRequest, err = wire.ReadVarBytes(r, 0, MaxPaymentRequestSize, "")
if err != nil {
return invoice, err
}
birthBytes, err := wire.ReadVarBytes(r, 0, 300, "birth")
if err != nil {
return invoice, err
}
if err := invoice.CreationDate.UnmarshalBinary(birthBytes); err != nil {
return invoice, err
}
settledBytes, err := wire.ReadVarBytes(r, 0, 300, "settled")
if err != nil {
return invoice, err
}
if err := invoice.SettleDate.UnmarshalBinary(settledBytes); err != nil {
return invoice, err
}
if _, err := io.ReadFull(r, invoice.Terms.PaymentPreimage[:]); err != nil {
return invoice, err
}
var scratch [8]byte
if _, err := io.ReadFull(r, scratch[:]); err != nil {
return invoice, err
}
invoice.Terms.Value = lnwire.MilliSatoshi(byteOrder.Uint64(scratch[:]))
if err := binary.Read(r, byteOrder, &invoice.Terms.State); err != nil {
return invoice, err
}
if err := binary.Read(r, byteOrder, &invoice.AddIndex); err != nil {
return invoice, err
}
if err := binary.Read(r, byteOrder, &invoice.SettleIndex); err != nil {
return invoice, err
}
if err := binary.Read(r, byteOrder, &invoice.AmtPaid); err != nil {
return invoice, err
}
return invoice, nil
}
// serializeInvoiceLegacy serializes an invoice in the format of the previous db
// version.
func serializeInvoiceLegacy(w io.Writer, i *Invoice) error {
if err := wire.WriteVarBytes(w, 0, i.Memo[:]); err != nil {
return err
}
if err := wire.WriteVarBytes(w, 0, i.Receipt[:]); err != nil {
return err
}
if err := wire.WriteVarBytes(w, 0, i.PaymentRequest[:]); err != nil {
return err
}
birthBytes, err := i.CreationDate.MarshalBinary()
if err != nil {
return err
}
if err := wire.WriteVarBytes(w, 0, birthBytes); err != nil {
return err
}
settleBytes, err := i.SettleDate.MarshalBinary()
if err != nil {
return err
}
if err := wire.WriteVarBytes(w, 0, settleBytes); err != nil {
return err
}
if _, err := w.Write(i.Terms.PaymentPreimage[:]); err != nil {
return err
}
var scratch [8]byte
byteOrder.PutUint64(scratch[:], uint64(i.Terms.Value))
if _, err := w.Write(scratch[:]); err != nil {
return err
}
if err := binary.Write(w, byteOrder, i.Terms.State); err != nil {
return err
}
if err := binary.Write(w, byteOrder, i.AddIndex); err != nil {
return err
}
if err := binary.Write(w, byteOrder, i.SettleIndex); err != nil {
return err
}
if err := binary.Write(w, byteOrder, int64(i.AmtPaid)); err != nil {
return err
}
return nil
}

@ -0,0 +1,166 @@
package channeldb
import (
"bytes"
"fmt"
"testing"
"time"
"github.com/btcsuite/btcd/btcec"
bitcoinCfg "github.com/btcsuite/btcd/chaincfg"
"github.com/coreos/bbolt"
"github.com/lightningnetwork/lnd/zpay32"
litecoinCfg "github.com/ltcsuite/ltcd/chaincfg"
)
var (
testPrivKeyBytes = []byte{
0x2b, 0xd8, 0x06, 0xc9, 0x7f, 0x0e, 0x00, 0xaf,
0x1a, 0x1f, 0xc3, 0x32, 0x8f, 0xa7, 0x63, 0xa9,
0x26, 0x97, 0x23, 0xc8, 0xdb, 0x8f, 0xac, 0x4f,
0x93, 0xaf, 0x71, 0xdb, 0x18, 0x6d, 0x6e, 0x90,
}
testCltvDelta = int32(50)
)
// TestMigrateInvoices checks that invoices are migrated correctly.
func TestMigrateInvoices(t *testing.T) {
t.Parallel()
payReqBtc, err := getPayReq(&bitcoinCfg.MainNetParams)
if err != nil {
t.Fatal(err)
}
var ltcNetParams bitcoinCfg.Params
ltcNetParams.Bech32HRPSegwit = litecoinCfg.MainNetParams.Bech32HRPSegwit
payReqLtc, err := getPayReq(&ltcNetParams)
if err != nil {
t.Fatal(err)
}
invoices := []Invoice{
{
PaymentRequest: []byte(payReqBtc),
},
{
PaymentRequest: []byte(payReqLtc),
},
}
beforeMigrationFunc := func(d *DB) {
err := d.Update(func(tx *bbolt.Tx) error {
invoicesBucket, err := tx.CreateBucketIfNotExists(
invoiceBucket,
)
if err != nil {
return err
}
invoiceNum := uint32(1)
for _, invoice := range invoices {
var invoiceKey [4]byte
byteOrder.PutUint32(invoiceKey[:], invoiceNum)
invoiceNum++
var buf bytes.Buffer
err := serializeInvoiceLegacy(&buf, &invoice)
if err != nil {
return err
}
err = invoicesBucket.Put(
invoiceKey[:], buf.Bytes(),
)
if err != nil {
return err
}
}
return nil
})
if err != nil {
t.Fatal(err)
}
}
// Verify that all invoices were migrated.
afterMigrationFunc := func(d *DB) {
meta, err := d.FetchMeta(nil)
if err != nil {
t.Fatal(err)
}
if meta.DbVersionNumber != 1 {
t.Fatal("migration 'invoices' wasn't applied")
}
dbInvoices, err := d.FetchAllInvoices(false)
if err != nil {
t.Fatalf("unable to fetch invoices: %v", err)
}
if len(invoices) != len(dbInvoices) {
t.Fatalf("expected %d invoices, got %d", len(invoices),
len(dbInvoices))
}
for _, dbInvoice := range dbInvoices {
if dbInvoice.FinalCltvDelta != testCltvDelta {
t.Fatal("incorrect final cltv delta")
}
if dbInvoice.Expiry != 3600*time.Second {
t.Fatal("incorrect expiry")
}
if len(dbInvoice.Htlcs) != 0 {
t.Fatal("expected no htlcs after migration")
}
}
}
applyMigration(t,
beforeMigrationFunc,
afterMigrationFunc,
migrateInvoices,
false)
}
// signDigestCompact generates a test signature to be used in the generation of
// test payment requests.
func signDigestCompact(hash []byte) ([]byte, error) {
// Should the signature reference a compressed public key or not.
isCompressedKey := true
privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), testPrivKeyBytes)
// btcec.SignCompact returns a pubkey-recoverable signature
sig, err := btcec.SignCompact(
btcec.S256(), privKey, hash, isCompressedKey,
)
if err != nil {
return nil, fmt.Errorf("can't sign the hash: %v", err)
}
return sig, nil
}
// getPayReq creates a payment request for the given net.
func getPayReq(net *bitcoinCfg.Params) (string, error) {
options := []func(*zpay32.Invoice){
zpay32.CLTVExpiry(uint64(testCltvDelta)),
zpay32.Description("test"),
}
payReq, err := zpay32.NewInvoice(
net, [32]byte{}, time.Unix(1, 0), options...,
)
if err != nil {
return "", err
}
return payReq.Encode(
zpay32.MessageSigner{
SignCompact: signDigestCompact,
},
)
}

@ -168,7 +168,7 @@ func migrateInvoiceTimeSeries(tx *bbolt.Tx) error {
invoiceBytesCopy = append(invoiceBytesCopy, padding...)
invoiceReader := bytes.NewReader(invoiceBytesCopy)
invoice, err := deserializeInvoice(invoiceReader)
invoice, err := deserializeInvoiceLegacy(invoiceReader)
if err != nil {
return fmt.Errorf("unable to decode invoice: %v", err)
}
@ -227,7 +227,7 @@ func migrateInvoiceTimeSeries(tx *bbolt.Tx) error {
// We've fully migrated an invoice, so we'll now update the
// invoice in-place.
var b bytes.Buffer
if err := serializeInvoice(&b, &invoice); err != nil {
if err := serializeInvoiceLegacy(&b, &invoice); err != nil {
return err
}

@ -479,7 +479,7 @@ func (c *ChannelArbitrator) relaunchResolvers() error {
"resolvers", c.cfg.ChanPoint, len(unresolvedContracts))
for _, resolver := range unresolvedContracts {
supplementResolver(resolver, htlcMap)
c.supplementResolver(resolver, htlcMap)
}
c.launchResolvers(unresolvedContracts)
@ -489,24 +489,22 @@ func (c *ChannelArbitrator) relaunchResolvers() error {
// supplementResolver takes a resolver as it is restored from the log and fills
// in missing data from the htlcMap.
func supplementResolver(resolver ContractResolver,
func (c *ChannelArbitrator) supplementResolver(resolver ContractResolver,
htlcMap map[wire.OutPoint]*channeldb.HTLC) error {
switch r := resolver.(type) {
case *htlcSuccessResolver:
return supplementSuccessResolver(r, htlcMap)
return c.supplementSuccessResolver(r, htlcMap)
case *htlcIncomingContestResolver:
return supplementSuccessResolver(
&r.htlcSuccessResolver, htlcMap,
)
return c.supplementIncomingContestResolver(r, htlcMap)
case *htlcTimeoutResolver:
return supplementTimeoutResolver(r, htlcMap)
return c.supplementTimeoutResolver(r, htlcMap)
case *htlcOutgoingContestResolver:
return supplementTimeoutResolver(
return c.supplementTimeoutResolver(
&r.htlcTimeoutResolver, htlcMap,
)
}
@ -514,9 +512,33 @@ func supplementResolver(resolver ContractResolver,
return nil
}
// supplementSuccessResolver takes a htlcIncomingContestResolver as it is
// restored from the log and fills in missing data from the htlcMap.
func (c *ChannelArbitrator) supplementIncomingContestResolver(
r *htlcIncomingContestResolver,
htlcMap map[wire.OutPoint]*channeldb.HTLC) error {
res := r.htlcResolution
htlcPoint := res.HtlcPoint()
htlc, ok := htlcMap[htlcPoint]
if !ok {
return errors.New(
"htlc for incoming contest resolver unavailable",
)
}
r.htlcAmt = htlc.Amt
r.circuitKey = channeldb.CircuitKey{
ChanID: c.cfg.ShortChanID,
HtlcID: htlc.HtlcIndex,
}
return nil
}
// supplementSuccessResolver takes a htlcSuccessResolver as it is restored from
// the log and fills in missing data from the htlcMap.
func supplementSuccessResolver(r *htlcSuccessResolver,
func (c *ChannelArbitrator) supplementSuccessResolver(r *htlcSuccessResolver,
htlcMap map[wire.OutPoint]*channeldb.HTLC) error {
res := r.htlcResolution
@ -533,7 +555,7 @@ func supplementSuccessResolver(r *htlcSuccessResolver,
// supplementTimeoutResolver takes a htlcSuccessResolver as it is restored from
// the log and fills in missing data from the htlcMap.
func supplementTimeoutResolver(r *htlcTimeoutResolver,
func (c *ChannelArbitrator) supplementTimeoutResolver(r *htlcTimeoutResolver,
htlcMap map[wire.OutPoint]*channeldb.HTLC) error {
res := r.htlcResolution
@ -1326,7 +1348,7 @@ func (c *ChannelArbitrator) isPreimageAvailable(hash lntypes.Hash) (bool,
// than the invoice cltv delta. We don't want to go to chain only to
// have the incoming contest resolver decide that we don't want to
// settle this invoice.
invoice, _, err := c.cfg.Registry.LookupInvoice(hash)
invoice, err := c.cfg.Registry.LookupInvoice(hash)
switch err {
case nil:
case channeldb.ErrInvoiceNotFound, channeldb.ErrNoInvoicesCreated:
@ -1723,9 +1745,15 @@ func (c *ChannelArbitrator) prepContractResolutions(
continue
}
circuitKey := channeldb.CircuitKey{
HtlcID: htlc.HtlcIndex,
ChanID: c.cfg.ShortChanID,
}
resKit.Quit = make(chan struct{})
resolver := &htlcIncomingContestResolver{
htlcExpiry: htlc.RefundTimeout,
circuitKey: circuitKey,
htlcSuccessResolver: htlcSuccessResolver{
htlcResolution: resolution,
broadcastHeight: height,

@ -27,6 +27,9 @@ type htlcIncomingContestResolver struct {
// successfully.
htlcExpiry uint32
// circuitKey describes the incoming htlc that is being resolved.
circuitKey channeldb.CircuitKey
// htlcSuccessResolver is the inner resolver that may be utilized if we
// learn of the preimage.
htlcSuccessResolver
@ -166,7 +169,7 @@ func (h *htlcIncomingContestResolver) Resolve() (ContractResolver, error) {
// identical to HTLC resolution in the link.
event, err := h.Registry.NotifyExitHopHtlc(
h.payHash, h.htlcAmt, h.htlcExpiry, currentHeight,
hodlChan, nil,
h.circuitKey, hodlChan, nil,
)
switch err {
case channeldb.ErrInvoiceNotFound:

@ -10,10 +10,8 @@ import (
// Registry is an interface which represents the invoice registry.
type Registry interface {
// LookupInvoice attempts to look up an invoice according to its 32
// byte payment hash. This method should also reutrn the min final CLTV
// delta for this invoice. We'll use this to ensure that the HTLC
// extended to us gives us enough time to settle as we prescribe.
LookupInvoice(lntypes.Hash) (channeldb.Invoice, uint32, error)
// byte payment hash.
LookupInvoice(lntypes.Hash) (channeldb.Invoice, error)
// NotifyExitHopHtlc attempts to mark an invoice as settled. If the
// invoice is a debug invoice, then this method is a noop as debug
@ -22,7 +20,7 @@ type Registry interface {
// the resolution is sent on the passed in hodlChan later.
NotifyExitHopHtlc(payHash lntypes.Hash, paidAmount lnwire.MilliSatoshi,
expiry uint32, currentHeight int32,
hodlChan chan<- interface{},
circuitKey channeldb.CircuitKey, hodlChan chan<- interface{},
eob []byte) (*invoices.HodlEvent, error)
// HodlUnsubscribeAll unsubscribes from all hodl events.

@ -23,7 +23,8 @@ type mockRegistry struct {
func (r *mockRegistry) NotifyExitHopHtlc(payHash lntypes.Hash,
paidAmount lnwire.MilliSatoshi, expiry uint32, currentHeight int32,
hodlChan chan<- interface{}, eob []byte) (*invoices.HodlEvent, error) {
circuitKey channeldb.CircuitKey, hodlChan chan<- interface{},
eob []byte) (*invoices.HodlEvent, error) {
r.notifyChan <- notifyExitHopData{
hodlChan: hodlChan,
@ -38,8 +39,8 @@ func (r *mockRegistry) NotifyExitHopHtlc(payHash lntypes.Hash,
func (r *mockRegistry) HodlUnsubscribeAll(subscriber chan<- interface{}) {}
func (r *mockRegistry) LookupInvoice(lntypes.Hash) (channeldb.Invoice, uint32,
func (r *mockRegistry) LookupInvoice(lntypes.Hash) (channeldb.Invoice,
error) {
return channeldb.Invoice{}, 0, channeldb.ErrInvoiceNotFound
return channeldb.Invoice{}, channeldb.ErrInvoiceNotFound
}

@ -14,10 +14,8 @@ import (
// which may search, lookup and settle invoices.
type InvoiceDatabase interface {
// LookupInvoice attempts to look up an invoice according to its 32
// byte payment hash. This method should also reutrn the min final CLTV
// delta for this invoice. We'll use this to ensure that the HTLC
// extended to us gives us enough time to settle as we prescribe.
LookupInvoice(lntypes.Hash) (channeldb.Invoice, uint32, error)
// byte payment hash.
LookupInvoice(lntypes.Hash) (channeldb.Invoice, error)
// NotifyExitHopHtlc attempts to mark an invoice as settled. If the
// invoice is a debug invoice, then this method is a noop as debug
@ -28,7 +26,7 @@ type InvoiceDatabase interface {
// for decoding purposes.
NotifyExitHopHtlc(payHash lntypes.Hash, paidAmount lnwire.MilliSatoshi,
expiry uint32, currentHeight int32,
hodlChan chan<- interface{},
circuitKey channeldb.CircuitKey, hodlChan chan<- interface{},
eob []byte) (*invoices.HodlEvent, error)
// CancelInvoice attempts to cancel the invoice corresponding to the

@ -2878,9 +2878,14 @@ func (l *channelLink) processExitHop(pd *lnwallet.PaymentDescriptor,
// receive back a resolution event.
invoiceHash := lntypes.Hash(pd.RHash)
circuitKey := channeldb.CircuitKey{
ChanID: l.ShortChanID(),
HtlcID: pd.HtlcIndex,
}
event, err := l.cfg.Registry.NotifyExitHopHtlc(
invoiceHash, pd.Amount, pd.Timeout, int32(heightNow),
l.hodlQueue.ChanIn(), eob,
circuitKey, l.hodlQueue.ChanIn(), eob,
)
switch err {

@ -238,7 +238,7 @@ func TestChannelLinkSingleHopPayment(t *testing.T) {
// Check that alice invoice was settled and bandwidth of HTLC
// links was changed.
invoice, _, err := receiver.registry.LookupInvoice(rhash)
invoice, err := receiver.registry.LookupInvoice(rhash)
if err != nil {
t.Fatalf("unable to get invoice: %v", err)
}
@ -498,7 +498,7 @@ func testChannelLinkMultiHopPayment(t *testing.T,
// Check that Carol invoice was settled and bandwidth of HTLC
// links were changed.
invoice, _, err := receiver.registry.LookupInvoice(rhash)
invoice, err := receiver.registry.LookupInvoice(rhash)
if err != nil {
t.Fatalf("unable to get invoice: %v", err)
}
@ -912,7 +912,7 @@ func TestUpdateForwardingPolicy(t *testing.T) {
// Carol's invoice should now be shown as settled as the payment
// succeeded.
invoice, _, err := n.carolServer.registry.LookupInvoice(payResp)
invoice, err := n.carolServer.registry.LookupInvoice(payResp)
if err != nil {
t.Fatalf("unable to get invoice: %v", err)
}
@ -1030,7 +1030,7 @@ func TestChannelLinkMultiHopInsufficientPayment(t *testing.T) {
// Check that alice invoice wasn't settled and bandwidth of htlc
// links hasn't been changed.
invoice, _, err := receiver.registry.LookupInvoice(rhash)
invoice, err := receiver.registry.LookupInvoice(rhash)
if err != nil {
t.Fatalf("unable to get invoice: %v", err)
}
@ -1215,7 +1215,7 @@ func TestChannelLinkMultiHopUnknownNextHop(t *testing.T) {
// Check that alice invoice wasn't settled and bandwidth of htlc
// links hasn't been changed.
invoice, _, err := receiver.registry.LookupInvoice(rhash)
invoice, err := receiver.registry.LookupInvoice(rhash)
if err != nil {
t.Fatalf("unable to get invoice: %v", err)
}
@ -1330,7 +1330,7 @@ func TestChannelLinkMultiHopDecodeError(t *testing.T) {
// Check that alice invoice wasn't settled and bandwidth of htlc
// links hasn't been changed.
invoice, _, err := receiver.registry.LookupInvoice(rhash)
invoice, err := receiver.registry.LookupInvoice(rhash)
if err != nil {
t.Fatalf("unable to get invoice: %v", err)
}
@ -3455,7 +3455,7 @@ func TestChannelRetransmission(t *testing.T) {
// Check that alice invoice wasn't settled and
// bandwidth of htlc links hasn't been changed.
invoice, _, err = receiver.registry.LookupInvoice(rhash)
invoice, err = receiver.registry.LookupInvoice(rhash)
if err != nil {
err = errors.Errorf("unable to get invoice: %v", err)
continue
@ -3974,7 +3974,7 @@ func TestChannelLinkAcceptOverpay(t *testing.T) {
// Even though we sent 2x what was asked for, Carol should still have
// accepted the payment and marked it as settled.
invoice, _, err := receiver.registry.LookupInvoice(rhash)
invoice, err := receiver.registry.LookupInvoice(rhash)
if err != nil {
t.Fatalf("unable to get invoice: %v", err)
}

@ -768,13 +768,9 @@ func newMockRegistry(minDelta uint32) *mockInvoiceRegistry {
panic(err)
}
decodeExpiry := func(invoice string) (uint32, error) {
return testInvoiceCltvExpiry, nil
}
finalCltvRejectDelta := int32(5)
registry := invoices.NewRegistry(cdb, decodeExpiry, finalCltvRejectDelta)
registry := invoices.NewRegistry(cdb, finalCltvRejectDelta)
registry.Start()
return &mockInvoiceRegistry{
@ -783,7 +779,9 @@ func newMockRegistry(minDelta uint32) *mockInvoiceRegistry {
}
}
func (i *mockInvoiceRegistry) LookupInvoice(rHash lntypes.Hash) (channeldb.Invoice, uint32, error) {
func (i *mockInvoiceRegistry) LookupInvoice(rHash lntypes.Hash) (
channeldb.Invoice, error) {
return i.registry.LookupInvoice(rHash)
}
@ -793,10 +791,11 @@ func (i *mockInvoiceRegistry) SettleHodlInvoice(preimage lntypes.Preimage) error
func (i *mockInvoiceRegistry) NotifyExitHopHtlc(rhash lntypes.Hash,
amt lnwire.MilliSatoshi, expiry uint32, currentHeight int32,
hodlChan chan<- interface{}, eob []byte) (*invoices.HodlEvent, error) {
circuitKey channeldb.CircuitKey, hodlChan chan<- interface{},
eob []byte) (*invoices.HodlEvent, error) {
event, err := i.registry.NotifyExitHopHtlc(
rhash, amt, expiry, currentHeight, hodlChan, eob,
rhash, amt, expiry, currentHeight, circuitKey, hodlChan, eob,
)
if err != nil {
return nil, err

@ -557,6 +557,7 @@ func generatePaymentWithPreimage(invoiceAmt, htlcAmt lnwire.MilliSatoshi,
Value: invoiceAmt,
PaymentPreimage: preimage,
},
FinalCltvDelta: testInvoiceCltvExpiry,
}
htlc := &lnwire.UpdateAddHTLC{

@ -2,7 +2,6 @@ package invoices
import (
"errors"
"fmt"
"sync"
"sync/atomic"
@ -25,6 +24,13 @@ var (
// ErrShuttingDown is returned when an operation failed because the
// invoice registry is shutting down.
ErrShuttingDown = errors.New("invoice registry shutting down")
// errNoUpdate is returned when no invoice updated is required.
errNoUpdate = errors.New("no update needed")
// errReplayedHtlc is returned if the htlc is already recorded on the
// invoice.
errReplayedHtlc = errors.New("replayed htlc")
)
// HodlEvent describes how an htlc should be resolved. If HodlEvent.Preimage is
@ -58,10 +64,6 @@ type InvoiceRegistry struct {
// new single invoice subscriptions are carried.
invoiceEvents chan interface{}
// decodeFinalCltvExpiry is a function used to decode the final expiry
// value from the payment request.
decodeFinalCltvExpiry func(invoice string) (uint32, error)
// subscriptions is a map from a payment hash to a list of subscribers.
// It is used for efficient notification of links.
hodlSubscriptions map[lntypes.Hash]map[chan<- interface{}]struct{}
@ -85,8 +87,7 @@ type InvoiceRegistry struct {
// wraps the persistent on-disk invoice storage with an additional in-memory
// layer. The in-memory layer is in place such that debug invoices can be added
// which are volatile yet available system wide within the daemon.
func NewRegistry(cdb *channeldb.DB, decodeFinalCltvExpiry func(invoice string) (
uint32, error), finalCltvRejectDelta int32) *InvoiceRegistry {
func NewRegistry(cdb *channeldb.DB, finalCltvRejectDelta int32) *InvoiceRegistry {
return &InvoiceRegistry{
cdb: cdb,
@ -97,7 +98,6 @@ func NewRegistry(cdb *channeldb.DB, decodeFinalCltvExpiry func(invoice string) (
invoiceEvents: make(chan interface{}, 100),
hodlSubscriptions: make(map[lntypes.Hash]map[chan<- interface{}]struct{}),
hodlReverseSubscriptions: make(map[chan<- interface{}]map[lntypes.Hash]struct{}),
decodeFinalCltvExpiry: decodeFinalCltvExpiry,
finalCltvRejectDelta: finalCltvRejectDelta,
quit: make(chan struct{}),
}
@ -404,76 +404,15 @@ func (i *InvoiceRegistry) AddInvoice(invoice *channeldb.Invoice,
}
// LookupInvoice looks up an invoice by its payment hash (R-Hash), if found
// then we're able to pull the funds pending within an HTLC. We'll also return
// what the expected min final CLTV delta is, pre-parsed from the payment
// request. This may be used by callers to determine if an HTLC is well formed
// according to the cltv delta.
// then we're able to pull the funds pending within an HTLC.
//
// TODO(roasbeef): ignore if settled?
func (i *InvoiceRegistry) LookupInvoice(rHash lntypes.Hash) (channeldb.Invoice, uint32, error) {
func (i *InvoiceRegistry) LookupInvoice(rHash lntypes.Hash) (channeldb.Invoice,
error) {
// We'll check the database to see if there's an existing matching
// invoice.
invoice, err := i.cdb.LookupInvoice(rHash)
if err != nil {
return channeldb.Invoice{}, 0, err
}
expiry, err := i.decodeFinalCltvExpiry(string(invoice.PaymentRequest))
if err != nil {
return channeldb.Invoice{}, 0, err
}
return invoice, expiry, nil
}
// checkHtlcParameters is a callback used inside invoice db transactions to
// atomically check-and-update an invoice.
func (i *InvoiceRegistry) checkHtlcParameters(invoice *channeldb.Invoice,
amtPaid lnwire.MilliSatoshi, htlcExpiry uint32, currentHeight int32) error {
// If the invoice is already canceled, there is no further checking to
// do.
if invoice.Terms.State == channeldb.ContractCanceled {
return channeldb.ErrInvoiceAlreadyCanceled
}
// If a payment has already been made, we only accept more payments if
// the amount is the exact same. This prevents probing with small
// amounts on settled invoices to find out the receiver node.
if invoice.AmtPaid != 0 && amtPaid != invoice.AmtPaid {
return ErrInvoiceAmountTooLow
}
// Return early in case the invoice was already accepted or settled. We
// don't want to check the expiry again, because it may be that we are
// just restarting.
switch invoice.Terms.State {
case channeldb.ContractAccepted:
return channeldb.ErrInvoiceAlreadyAccepted
case channeldb.ContractSettled:
return channeldb.ErrInvoiceAlreadySettled
}
// The invoice is still open. Check the expiry.
expiry, err := i.decodeFinalCltvExpiry(string(invoice.PaymentRequest))
if err != nil {
return err
}
if htlcExpiry < uint32(currentHeight+i.finalCltvRejectDelta) {
return ErrInvoiceExpiryTooSoon
}
if htlcExpiry < uint32(currentHeight)+expiry {
return ErrInvoiceExpiryTooSoon
}
// If an invoice amount is specified, check that enough is paid.
if invoice.Terms.Value > 0 && amtPaid < invoice.Terms.Value {
return ErrInvoiceAmountTooLow
}
return nil
return i.cdb.LookupInvoice(rHash)
}
// NotifyExitHopHtlc attempts to mark an invoice as settled. If the invoice is a
@ -489,108 +428,155 @@ func (i *InvoiceRegistry) checkHtlcParameters(invoice *channeldb.Invoice,
// prevent deadlock.
func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash,
amtPaid lnwire.MilliSatoshi, expiry uint32, currentHeight int32,
hodlChan chan<- interface{}, eob []byte) (*HodlEvent, error) {
circuitKey channeldb.CircuitKey, hodlChan chan<- interface{},
eob []byte) (*HodlEvent, error) {
i.Lock()
defer i.Unlock()
debugLog := func(s string) {
log.Debugf("Invoice(%x): %v, amt=%v, expiry=%v",
rHash[:], s, amtPaid, expiry)
log.Debugf("Invoice(%x): %v, amt=%v, expiry=%v, circuit=%v",
rHash[:], s, amtPaid, expiry, circuitKey)
}
// If this isn't a debug invoice, then we'll attempt to settle an
// invoice matching this rHash on disk (if one exists).
invoice, err := i.cdb.AcceptOrSettleInvoice(
rHash, amtPaid,
func(inv *channeldb.Invoice) error {
return i.checkHtlcParameters(
inv, amtPaid, expiry, currentHeight,
)
},
)
switch err {
// Default is to not update subscribers after the invoice update.
updateSubscribers := false
// If invoice is already settled, settle htlc. This means we accept more
// payments to the same invoice hash.
//
// NOTE: Though our recovery and forwarding logic is predominately
// batched, settling invoices happens iteratively. We may reject one of
// two payments for the same rhash at first, but then restart and reject
// both after seeing that the invoice has been settled. Without any
// record of which one settles first, it is ambiguous as to which one
// actually settled the invoice. Thus, by accepting all payments, we
// eliminate the race condition that can lead to this inconsistency.
//
// TODO(conner): track ownership of settlements to properly recover from
// failures? or add batch invoice settlement
case channeldb.ErrInvoiceAlreadySettled:
debugLog("accepting duplicate payment to settled invoice")
updateInvoice := func(inv *channeldb.Invoice) (
*channeldb.InvoiceUpdateDesc, error) {
// Don't update the invoice when this is a replayed htlc.
htlc, ok := inv.Htlcs[circuitKey]
if ok {
switch htlc.State {
case channeldb.HtlcStateCancelled:
debugLog("replayed htlc to canceled invoice")
case channeldb.HtlcStateAccepted:
debugLog("replayed htlc to accepted invoice")
case channeldb.HtlcStateSettled:
debugLog("replayed htlc to settled invoice")
default:
return nil, errors.New("unexpected htlc state")
}
return nil, errNoUpdate
}
// If the invoice is already canceled, there is no further
// checking to do.
if inv.Terms.State == channeldb.ContractCanceled {
debugLog("invoice already canceled")
return nil, errNoUpdate
}
// If an invoice amount is specified, check that enough
// is paid. Also check this for duplicate payments if
// the invoice is already settled or accepted.
if inv.Terms.Value > 0 && amtPaid < inv.Terms.Value {
debugLog("amount too low")
return nil, errNoUpdate
}
// The invoice is still open. Check the expiry.
if expiry < uint32(currentHeight+i.finalCltvRejectDelta) {
debugLog("expiry too soon")
return nil, errNoUpdate
}
if expiry < uint32(currentHeight+inv.FinalCltvDelta) {
debugLog("expiry too soon")
return nil, errNoUpdate
}
// Record HTLC in the invoice database.
newHtlcs := map[channeldb.CircuitKey]*channeldb.HtlcAcceptDesc{
circuitKey: {
Amt: amtPaid,
Expiry: expiry,
AcceptHeight: currentHeight,
},
}
update := channeldb.InvoiceUpdateDesc{
Htlcs: newHtlcs,
}
// Don't update invoice state if we are accepting a duplicate
// payment. We do accept or settle the HTLC.
switch inv.Terms.State {
case channeldb.ContractAccepted:
debugLog("accepting duplicate payment to accepted invoice")
update.State = channeldb.ContractAccepted
return &update, nil
case channeldb.ContractSettled:
debugLog("accepting duplicate payment to settled invoice")
update.State = channeldb.ContractSettled
return &update, nil
}
// Check to see if we can settle or this is an hold invoice and
// we need to wait for the preimage.
holdInvoice := inv.Terms.PaymentPreimage == channeldb.UnknownPreimage
if holdInvoice {
debugLog("accepted")
update.State = channeldb.ContractAccepted
} else {
debugLog("settled")
update.Preimage = inv.Terms.PaymentPreimage
update.State = channeldb.ContractSettled
}
updateSubscribers = true
return &update, nil
}
// We'll attempt to settle an invoice matching this rHash on disk (if
// one exists). The callback will set the resolution action that is
// returned to the link or contract resolver.
invoice, err := i.cdb.UpdateInvoice(rHash, updateInvoice)
if err != nil && err != errNoUpdate {
debugLog(err.Error())
return nil, err
}
if updateSubscribers {
i.notifyClients(rHash, invoice, invoice.Terms.State)
}
// Inspect latest htlc state on the invoice.
invoiceHtlc, ok := invoice.Htlcs[circuitKey]
// If it isn't recorded, cancel htlc.
if !ok {
return &HodlEvent{
Hash: rHash,
}, nil
}
switch invoiceHtlc.State {
case channeldb.HtlcStateCancelled:
return &HodlEvent{
Hash: rHash,
}, nil
case channeldb.HtlcStateSettled:
return &HodlEvent{
Hash: rHash,
Preimage: &invoice.Terms.PaymentPreimage,
}, nil
// If invoice is already canceled, cancel htlc.
case channeldb.ErrInvoiceAlreadyCanceled:
debugLog("invoice already canceled")
return &HodlEvent{
Hash: rHash,
}, nil
// If invoice is already accepted, add this htlc to the list of
// subscribers.
case channeldb.ErrInvoiceAlreadyAccepted:
debugLog("accepting duplicate payment to accepted invoice")
case channeldb.HtlcStateAccepted:
i.hodlSubscribe(hodlChan, rHash)
return nil, nil
// If there are not enough blocks left, cancel the htlc.
case ErrInvoiceExpiryTooSoon:
debugLog("expiry too soon")
return &HodlEvent{
Hash: rHash,
}, nil
// If there are not enough blocks left, cancel the htlc.
case ErrInvoiceAmountTooLow:
debugLog("amount too low")
return &HodlEvent{
Hash: rHash,
}, nil
// If this call settled the invoice, settle the htlc. Otherwise
// subscribe for a future hodl event.
case nil:
i.notifyClients(rHash, invoice, invoice.Terms.State)
switch invoice.Terms.State {
case channeldb.ContractSettled:
debugLog("settled")
return &HodlEvent{
Hash: rHash,
Preimage: &invoice.Terms.PaymentPreimage,
}, nil
case channeldb.ContractAccepted:
debugLog("accepted")
// Subscribe to updates to this invoice.
i.hodlSubscribe(hodlChan, rHash)
return nil, nil
default:
return nil, fmt.Errorf("unexpected invoice state %v",
invoice.Terms.State)
}
default:
debugLog(err.Error())
return nil, err
panic("unknown action")
}
}
@ -599,13 +585,31 @@ func (i *InvoiceRegistry) SettleHodlInvoice(preimage lntypes.Preimage) error {
i.Lock()
defer i.Unlock()
invoice, err := i.cdb.SettleHoldInvoice(preimage)
updateInvoice := func(invoice *channeldb.Invoice) (
*channeldb.InvoiceUpdateDesc, error) {
switch invoice.Terms.State {
case channeldb.ContractOpen:
return nil, channeldb.ErrInvoiceStillOpen
case channeldb.ContractCanceled:
return nil, channeldb.ErrInvoiceAlreadyCanceled
case channeldb.ContractSettled:
return nil, channeldb.ErrInvoiceAlreadySettled
}
return &channeldb.InvoiceUpdateDesc{
State: channeldb.ContractSettled,
Preimage: preimage,
}, nil
}
hash := preimage.Hash()
invoice, err := i.cdb.UpdateInvoice(hash, updateInvoice)
if err != nil {
log.Errorf("SettleHodlInvoice with preimage %v: %v", preimage, err)
return err
}
hash := preimage.Hash()
log.Debugf("Invoice(%v): settled with preimage %v", hash,
invoice.Terms.PaymentPreimage)
@ -626,7 +630,32 @@ func (i *InvoiceRegistry) CancelInvoice(payHash lntypes.Hash) error {
log.Debugf("Invoice(%v): canceling invoice", payHash)
invoice, err := i.cdb.CancelInvoice(payHash)
updateInvoice := func(invoice *channeldb.Invoice) (
*channeldb.InvoiceUpdateDesc, error) {
switch invoice.Terms.State {
case channeldb.ContractSettled:
return nil, channeldb.ErrInvoiceAlreadySettled
case channeldb.ContractCanceled:
return nil, channeldb.ErrInvoiceAlreadyCanceled
}
// Mark individual held htlcs as cancelled.
canceledHtlcs := make(
map[channeldb.CircuitKey]*channeldb.HtlcAcceptDesc,
)
for key := range invoice.Htlcs {
canceledHtlcs[key] = nil
}
// Move invoice to the canceled state.
return &channeldb.InvoiceUpdateDesc{
Htlcs: canceledHtlcs,
State: channeldb.ContractCanceled,
}, nil
}
invoice, err := i.cdb.UpdateInvoice(payHash, updateInvoice)
// Implement idempotency by returning success if the invoice was already
// canceled.

@ -21,17 +21,15 @@ var (
hash = preimage.Hash()
testInvoiceExpiry = uint32(3)
testHtlcExpiry = uint32(5)
testCurrentHeight = int32(0)
testInvoiceCltvDelta = uint32(4)
testFinalCltvRejectDelta = int32(3)
testFinalCltvRejectDelta = int32(4)
testCurrentHeight = int32(1)
)
func decodeExpiry(payReq string) (uint32, error) {
return uint32(testInvoiceExpiry), nil
}
var (
testInvoice = &channeldb.Invoice{
Terms: channeldb.ContractTerm{
@ -48,7 +46,7 @@ func newTestContext(t *testing.T) (*InvoiceRegistry, func()) {
}
// Instantiate and start the invoice registry.
registry := NewRegistry(cdb, decodeExpiry, testFinalCltvRejectDelta)
registry := NewRegistry(cdb, testFinalCltvRejectDelta)
err = registry.Start()
if err != nil {
@ -62,6 +60,15 @@ func newTestContext(t *testing.T) (*InvoiceRegistry, func()) {
}
}
func getCircuitKey(htlcID uint64) channeldb.CircuitKey {
return channeldb.CircuitKey{
ChanID: lnwire.ShortChannelID{
BlockHeight: 1, TxIndex: 2, TxPosition: 3,
},
HtlcID: htlcID,
}
}
// TestSettleInvoice tests settling of an invoice and related notifications.
func TestSettleInvoice(t *testing.T) {
registry, cleanup := newTestContext(t)
@ -119,7 +126,8 @@ func TestSettleInvoice(t *testing.T) {
// Settle invoice with a slightly higher amount.
amtPaid := lnwire.MilliSatoshi(100500)
_, err = registry.NotifyExitHopHtlc(
hash, amtPaid, testInvoiceExpiry, 0, hodlChan, nil,
hash, amtPaid, testHtlcExpiry, testCurrentHeight,
getCircuitKey(0), hodlChan, nil,
)
if err != nil {
t.Fatal(err)
@ -151,11 +159,11 @@ func TestSettleInvoice(t *testing.T) {
t.Fatal("no update received")
}
// Try to settle again. We need this idempotent behaviour after a
// restart.
// Try to settle again with the same htlc id. We need this idempotent
// behaviour after a restart.
event, err := registry.NotifyExitHopHtlc(
hash, amtPaid, testInvoiceExpiry, testCurrentHeight, hodlChan,
nil,
hash, amtPaid, testHtlcExpiry, testCurrentHeight,
getCircuitKey(0), hodlChan, nil,
)
if err != nil {
t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err)
@ -164,12 +172,25 @@ func TestSettleInvoice(t *testing.T) {
t.Fatal("expected settle event")
}
// Try to settle again with a higher amount. This should result in a
// cancel event because after a restart the amount should still be the
// same. New HTLCs with a different amount should be rejected.
// Try to settle again with a new higher-valued htlc. This payment
// should also be accepted, to prevent any change in behaviour for a
// paid invoice that may open up a probe vector.
event, err = registry.NotifyExitHopHtlc(
hash, amtPaid+600, testInvoiceExpiry, testCurrentHeight,
hodlChan, nil,
hash, amtPaid+600, testHtlcExpiry, testCurrentHeight,
getCircuitKey(1), hodlChan, nil,
)
if err != nil {
t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err)
}
if event.Preimage == nil {
t.Fatal("expected settle event")
}
// Try to settle again with a lower amount. This should fail just as it
// would have failed if it were the first payment.
event, err = registry.NotifyExitHopHtlc(
hash, amtPaid-600, testHtlcExpiry, testCurrentHeight,
getCircuitKey(2), hodlChan, nil,
)
if err != nil {
t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err)
@ -178,26 +199,14 @@ func TestSettleInvoice(t *testing.T) {
t.Fatal("expected cancel event")
}
// Try to settle again with a lower amount. This should show the same
// behaviour as settling with a higher amount.
event, err = registry.NotifyExitHopHtlc(
hash, amtPaid-600, testInvoiceExpiry, testCurrentHeight,
hodlChan, nil,
)
if err != nil {
t.Fatalf("unexpected NotifyExitHopHtlc error: %v", err)
}
if event.Preimage != nil {
t.Fatal("expected cancel event")
}
// Check that settled amount remains unchanged.
inv, _, err := registry.LookupInvoice(hash)
// Check that settled amount is equal to the sum of values of the htlcs
// 0 and 1.
inv, err := registry.LookupInvoice(hash)
if err != nil {
t.Fatal(err)
}
if inv.AmtPaid != amtPaid {
t.Fatal("expected amount to be unchanged")
if inv.AmtPaid != amtPaid+amtPaid+600 {
t.Fatal("amount incorrect")
}
// Try to cancel.
@ -305,7 +314,8 @@ func TestCancelInvoice(t *testing.T) {
// succeed.
hodlChan := make(chan interface{})
event, err := registry.NotifyExitHopHtlc(
hash, amt, testInvoiceExpiry, testCurrentHeight, hodlChan, nil,
hash, amt, testHtlcExpiry, testCurrentHeight,
getCircuitKey(0), hodlChan, nil,
)
if err != nil {
t.Fatal("expected settlement of a canceled invoice to succeed")
@ -324,7 +334,7 @@ func TestHoldInvoice(t *testing.T) {
defer cleanup()
// Instantiate and start the invoice registry.
registry := NewRegistry(cdb, decodeExpiry, testFinalCltvRejectDelta)
registry := NewRegistry(cdb, testFinalCltvRejectDelta)
err = registry.Start()
if err != nil {
@ -381,26 +391,52 @@ func TestHoldInvoice(t *testing.T) {
// NotifyExitHopHtlc without a preimage present in the invoice registry
// should be possible.
event, err := registry.NotifyExitHopHtlc(
hash, amtPaid, testInvoiceExpiry, testCurrentHeight, hodlChan,
nil,
hash, amtPaid, testHtlcExpiry, testCurrentHeight,
getCircuitKey(0), hodlChan, nil,
)
if err != nil {
t.Fatalf("expected settle to succeed but got %v", err)
}
if event != nil {
t.Fatalf("unexpect direct settle")
t.Fatalf("expected htlc to be held")
}
// Test idempotency.
event, err = registry.NotifyExitHopHtlc(
hash, amtPaid, testInvoiceExpiry, testCurrentHeight, hodlChan,
nil,
hash, amtPaid, testHtlcExpiry, testCurrentHeight,
getCircuitKey(0), hodlChan, nil,
)
if err != nil {
t.Fatalf("expected settle to succeed but got %v", err)
}
if event != nil {
t.Fatalf("unexpect direct settle")
t.Fatalf("expected htlc to be held")
}
// Test replay at a higher height. We expect the same result because it
// is a replay.
event, err = registry.NotifyExitHopHtlc(
hash, amtPaid, testHtlcExpiry, testCurrentHeight+10,
getCircuitKey(0), hodlChan, nil,
)
if err != nil {
t.Fatalf("expected settle to succeed but got %v", err)
}
if event != nil {
t.Fatalf("expected htlc to be held")
}
// Test a new htlc coming in that doesn't meet the final cltv delta
// requirement. It should be rejected.
event, err = registry.NotifyExitHopHtlc(
hash, amtPaid, 1, testCurrentHeight,
getCircuitKey(1), hodlChan, nil,
)
if err != nil {
t.Fatalf("expected settle to succeed but got %v", err)
}
if event == nil || event.Preimage != nil {
t.Fatalf("expected htlc to be cancelled")
}
// We expect the accepted state to be sent to the single invoice
@ -433,6 +469,10 @@ func TestHoldInvoice(t *testing.T) {
t.Fatalf("expected state ContractSettled, but got %v",
settledInvoice.Terms.State)
}
if settledInvoice.AmtPaid != amtPaid {
t.Fatalf("expected amount to be %v, but got %v",
amtPaid, settledInvoice.AmtPaid)
}
update = <-subscription.Updates
if update.Terms.State != channeldb.ContractSettled {
@ -490,7 +530,8 @@ func TestUnknownInvoice(t *testing.T) {
hodlChan := make(chan interface{})
amt := lnwire.MilliSatoshi(100000)
_, err := registry.NotifyExitHopHtlc(
hash, amt, testInvoiceExpiry, testCurrentHeight, hodlChan, nil,
hash, amt, testHtlcExpiry, testCurrentHeight,
getCircuitKey(0), hodlChan, nil,
)
if err != channeldb.ErrInvoiceNotFound {
t.Fatal("expected invoice not found error")

@ -394,6 +394,8 @@ func AddInvoice(ctx context.Context, cfg *AddInvoiceConfig,
Memo: []byte(invoice.Memo),
Receipt: invoice.Receipt,
PaymentRequest: []byte(payReqString),
FinalCltvDelta: int32(payReq.MinFinalCLTVExpiry()),
Expiry: payReq.Expiry(),
Terms: channeldb.ContractTerm{
Value: amtMSat,
PaymentPreimage: paymentPreimage,

@ -36,13 +36,6 @@ func CreateRPCInvoice(invoice *channeldb.Invoice,
settleDate = invoice.SettleDate.Unix()
}
// Expiry time will default to 3600 seconds if not specified
// explicitly.
expiry := int64(decoded.Expiry().Seconds())
// The expiry will default to 9 blocks if not specified explicitly.
cltvExpiry := decoded.MinFinalCLTVExpiry()
// Convert between the `lnrpc` and `routing` types.
routeHints := CreateRPCRouteHints(decoded.RouteHints)
@ -67,6 +60,38 @@ func CreateRPCInvoice(invoice *channeldb.Invoice,
invoice.Terms.State)
}
rpcHtlcs := make([]*lnrpc.InvoiceHTLC, 0, len(invoice.Htlcs))
for key, htlc := range invoice.Htlcs {
var state lnrpc.InvoiceHTLCState
switch htlc.State {
case channeldb.HtlcStateAccepted:
state = lnrpc.InvoiceHTLCState_ACCEPTED
case channeldb.HtlcStateSettled:
state = lnrpc.InvoiceHTLCState_SETTLED
case channeldb.HtlcStateCancelled:
state = lnrpc.InvoiceHTLCState_CANCELLED
default:
return nil, fmt.Errorf("unknown state %v", htlc.State)
}
rpcHtlc := lnrpc.InvoiceHTLC{
ChanId: key.ChanID.ToUint64(),
HtlcIndex: key.HtlcID,
AcceptHeight: int32(htlc.AcceptHeight),
AcceptTime: htlc.AcceptTime.Unix(),
ExpiryHeight: int32(htlc.Expiry),
AmtMsat: uint64(htlc.Amt),
State: state,
}
// Only report resolved times if htlc is resolved.
if htlc.State != channeldb.HtlcStateAccepted {
rpcHtlc.ResolveTime = htlc.ResolveTime.Unix()
}
rpcHtlcs = append(rpcHtlcs, &rpcHtlc)
}
rpcInvoice := &lnrpc.Invoice{
Memo: string(invoice.Memo[:]),
Receipt: invoice.Receipt[:],
@ -77,8 +102,8 @@ func CreateRPCInvoice(invoice *channeldb.Invoice,
Settled: isSettled,
PaymentRequest: paymentRequest,
DescriptionHash: descHash,
Expiry: expiry,
CltvExpiry: cltvExpiry,
Expiry: int64(invoice.Expiry.Seconds()),
CltvExpiry: uint64(invoice.FinalCltvDelta),
FallbackAddr: fallbackAddr,
RouteHints: routeHints,
AddIndex: invoice.AddIndex,
@ -88,6 +113,7 @@ func CreateRPCInvoice(invoice *channeldb.Invoice,
AmtPaidMsat: int64(invoice.AmtPaid),
AmtPaid: int64(invoice.AmtPaid),
State: state,
Htlcs: rpcHtlcs,
}
if preimage != channeldb.UnknownPreimage {

@ -59,6 +59,34 @@ func (AddressType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{0}
}
type InvoiceHTLCState int32
const (
InvoiceHTLCState_ACCEPTED InvoiceHTLCState = 0
InvoiceHTLCState_SETTLED InvoiceHTLCState = 1
InvoiceHTLCState_CANCELLED InvoiceHTLCState = 2
)
var InvoiceHTLCState_name = map[int32]string{
0: "ACCEPTED",
1: "SETTLED",
2: "CANCELLED",
}
var InvoiceHTLCState_value = map[string]int32{
"ACCEPTED": 0,
"SETTLED": 1,
"CANCELLED": 2,
}
func (x InvoiceHTLCState) String() string {
return proto.EnumName(InvoiceHTLCState_name, int32(x))
}
func (InvoiceHTLCState) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{1}
}
type ChannelCloseSummary_ClosureType int32
const (
@ -220,7 +248,7 @@ func (x Payment_PaymentStatus) String() string {
}
func (Payment_PaymentStatus) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_77a6da22d6a3feb1, []int{99, 0}
return fileDescriptor_77a6da22d6a3feb1, []int{100, 0}
}
type GenSeedRequest struct {
@ -6604,10 +6632,12 @@ type Invoice struct {
AmtPaidMsat int64 `protobuf:"varint,20,opt,name=amt_paid_msat,proto3" json:"amt_paid_msat,omitempty"`
//*
//The state the invoice is in.
State Invoice_InvoiceState `protobuf:"varint,21,opt,name=state,proto3,enum=lnrpc.Invoice_InvoiceState" json:"state,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
State Invoice_InvoiceState `protobuf:"varint,21,opt,name=state,proto3,enum=lnrpc.Invoice_InvoiceState" json:"state,omitempty"`
/// List of HTLCs paying to this invoice [EXPERIMENTAL].
Htlcs []*InvoiceHTLC `protobuf:"bytes,22,rep,name=htlcs,proto3" json:"htlcs,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Invoice) Reset() { *m = Invoice{} }
@ -6785,6 +6815,117 @@ func (m *Invoice) GetState() Invoice_InvoiceState {
return Invoice_OPEN
}
func (m *Invoice) GetHtlcs() []*InvoiceHTLC {
if m != nil {
return m.Htlcs
}
return nil
}
/// Details of an HTLC that paid to an invoice
type InvoiceHTLC struct {
/// Short channel id over which the htlc was received.
ChanId uint64 `protobuf:"varint,1,opt,name=chan_id,proto3" json:"chan_id,omitempty"`
/// Index identifying the htlc on the channel.
HtlcIndex uint64 `protobuf:"varint,2,opt,name=htlc_index,proto3" json:"htlc_index,omitempty"`
/// The amount of the htlc in msat.
AmtMsat uint64 `protobuf:"varint,3,opt,name=amt_msat,proto3" json:"amt_msat,omitempty"`
/// Block height at which this htlc was accepted.
AcceptHeight int32 `protobuf:"varint,4,opt,name=accept_height,proto3" json:"accept_height,omitempty"`
/// Time at which this htlc was accepted.
AcceptTime int64 `protobuf:"varint,5,opt,name=accept_time,proto3" json:"accept_time,omitempty"`
/// Time at which this htlc was settled or cancelled.
ResolveTime int64 `protobuf:"varint,6,opt,name=resolve_time,proto3" json:"resolve_time,omitempty"`
/// Block height at which this htlc expires.
ExpiryHeight int32 `protobuf:"varint,7,opt,name=expiry_height,proto3" json:"expiry_height,omitempty"`
/// Current state the htlc is in.
State InvoiceHTLCState `protobuf:"varint,8,opt,name=state,proto3,enum=lnrpc.InvoiceHTLCState" json:"state,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
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{94}
}
func (m *InvoiceHTLC) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_InvoiceHTLC.Unmarshal(m, b)
}
func (m *InvoiceHTLC) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_InvoiceHTLC.Marshal(b, m, deterministic)
}
func (m *InvoiceHTLC) XXX_Merge(src proto.Message) {
xxx_messageInfo_InvoiceHTLC.Merge(m, src)
}
func (m *InvoiceHTLC) XXX_Size() int {
return xxx_messageInfo_InvoiceHTLC.Size(m)
}
func (m *InvoiceHTLC) XXX_DiscardUnknown() {
xxx_messageInfo_InvoiceHTLC.DiscardUnknown(m)
}
var xxx_messageInfo_InvoiceHTLC proto.InternalMessageInfo
func (m *InvoiceHTLC) GetChanId() uint64 {
if m != nil {
return m.ChanId
}
return 0
}
func (m *InvoiceHTLC) GetHtlcIndex() uint64 {
if m != nil {
return m.HtlcIndex
}
return 0
}
func (m *InvoiceHTLC) GetAmtMsat() uint64 {
if m != nil {
return m.AmtMsat
}
return 0
}
func (m *InvoiceHTLC) GetAcceptHeight() int32 {
if m != nil {
return m.AcceptHeight
}
return 0
}
func (m *InvoiceHTLC) GetAcceptTime() int64 {
if m != nil {
return m.AcceptTime
}
return 0
}
func (m *InvoiceHTLC) GetResolveTime() int64 {
if m != nil {
return m.ResolveTime
}
return 0
}
func (m *InvoiceHTLC) GetExpiryHeight() int32 {
if m != nil {
return m.ExpiryHeight
}
return 0
}
func (m *InvoiceHTLC) GetState() InvoiceHTLCState {
if m != nil {
return m.State
}
return InvoiceHTLCState_ACCEPTED
}
type AddInvoiceResponse struct {
RHash []byte `protobuf:"bytes,1,opt,name=r_hash,proto3" json:"r_hash,omitempty"`
//*
@ -6807,7 +6948,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{94}
return fileDescriptor_77a6da22d6a3feb1, []int{95}
}
func (m *AddInvoiceResponse) XXX_Unmarshal(b []byte) error {
@ -6865,7 +7006,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{95}
return fileDescriptor_77a6da22d6a3feb1, []int{96}
}
func (m *PaymentHash) XXX_Unmarshal(b []byte) error {
@ -6922,7 +7063,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{96}
return fileDescriptor_77a6da22d6a3feb1, []int{97}
}
func (m *ListInvoiceRequest) XXX_Unmarshal(b []byte) error {
@ -6993,7 +7134,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{97}
return fileDescriptor_77a6da22d6a3feb1, []int{98}
}
func (m *ListInvoiceResponse) XXX_Unmarshal(b []byte) error {
@ -7057,7 +7198,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{98}
return fileDescriptor_77a6da22d6a3feb1, []int{99}
}
func (m *InvoiceSubscription) XXX_Unmarshal(b []byte) error {
@ -7126,7 +7267,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{99}
return fileDescriptor_77a6da22d6a3feb1, []int{100}
}
func (m *Payment) XXX_Unmarshal(b []byte) error {
@ -7248,7 +7389,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{100}
return fileDescriptor_77a6da22d6a3feb1, []int{101}
}
func (m *ListPaymentsRequest) XXX_Unmarshal(b []byte) error {
@ -7288,7 +7429,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{101}
return fileDescriptor_77a6da22d6a3feb1, []int{102}
}
func (m *ListPaymentsResponse) XXX_Unmarshal(b []byte) error {
@ -7326,7 +7467,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{102}
return fileDescriptor_77a6da22d6a3feb1, []int{103}
}
func (m *DeleteAllPaymentsRequest) XXX_Unmarshal(b []byte) error {
@ -7357,7 +7498,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{103}
return fileDescriptor_77a6da22d6a3feb1, []int{104}
}
func (m *DeleteAllPaymentsResponse) XXX_Unmarshal(b []byte) error {
@ -7389,7 +7530,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{104}
return fileDescriptor_77a6da22d6a3feb1, []int{105}
}
func (m *AbandonChannelRequest) XXX_Unmarshal(b []byte) error {
@ -7427,7 +7568,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{105}
return fileDescriptor_77a6da22d6a3feb1, []int{106}
}
func (m *AbandonChannelResponse) XXX_Unmarshal(b []byte) error {
@ -7460,7 +7601,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{106}
return fileDescriptor_77a6da22d6a3feb1, []int{107}
}
func (m *DebugLevelRequest) XXX_Unmarshal(b []byte) error {
@ -7506,7 +7647,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{107}
return fileDescriptor_77a6da22d6a3feb1, []int{108}
}
func (m *DebugLevelResponse) XXX_Unmarshal(b []byte) error {
@ -7546,7 +7687,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{108}
return fileDescriptor_77a6da22d6a3feb1, []int{109}
}
func (m *PayReqString) XXX_Unmarshal(b []byte) error {
@ -7594,7 +7735,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{109}
return fileDescriptor_77a6da22d6a3feb1, []int{110}
}
func (m *PayReq) XXX_Unmarshal(b []byte) error {
@ -7695,7 +7836,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{110}
return fileDescriptor_77a6da22d6a3feb1, []int{111}
}
func (m *FeeReportRequest) XXX_Unmarshal(b []byte) error {
@ -7734,7 +7875,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{111}
return fileDescriptor_77a6da22d6a3feb1, []int{112}
}
func (m *ChannelFeeReport) XXX_Unmarshal(b []byte) error {
@ -7801,7 +7942,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{112}
return fileDescriptor_77a6da22d6a3feb1, []int{113}
}
func (m *FeeReportResponse) XXX_Unmarshal(b []byte) error {
@ -7870,7 +8011,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{113}
return fileDescriptor_77a6da22d6a3feb1, []int{114}
}
func (m *PolicyUpdateRequest) XXX_Unmarshal(b []byte) error {
@ -7967,7 +8108,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{114}
return fileDescriptor_77a6da22d6a3feb1, []int{115}
}
func (m *PolicyUpdateResponse) XXX_Unmarshal(b []byte) error {
@ -8006,7 +8147,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{115}
return fileDescriptor_77a6da22d6a3feb1, []int{116}
}
func (m *ForwardingHistoryRequest) XXX_Unmarshal(b []byte) error {
@ -8079,7 +8220,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{116}
return fileDescriptor_77a6da22d6a3feb1, []int{117}
}
func (m *ForwardingEvent) XXX_Unmarshal(b []byte) error {
@ -8163,7 +8304,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{117}
return fileDescriptor_77a6da22d6a3feb1, []int{118}
}
func (m *ForwardingHistoryResponse) XXX_Unmarshal(b []byte) error {
@ -8210,7 +8351,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{118}
return fileDescriptor_77a6da22d6a3feb1, []int{119}
}
func (m *ExportChannelBackupRequest) XXX_Unmarshal(b []byte) error {
@ -8256,7 +8397,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{119}
return fileDescriptor_77a6da22d6a3feb1, []int{120}
}
func (m *ChannelBackup) XXX_Unmarshal(b []byte) error {
@ -8309,7 +8450,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{120}
return fileDescriptor_77a6da22d6a3feb1, []int{121}
}
func (m *MultiChanBackup) XXX_Unmarshal(b []byte) error {
@ -8354,7 +8495,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{121}
return fileDescriptor_77a6da22d6a3feb1, []int{122}
}
func (m *ChanBackupExportRequest) XXX_Unmarshal(b []byte) error {
@ -8393,7 +8534,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{122}
return fileDescriptor_77a6da22d6a3feb1, []int{123}
}
func (m *ChanBackupSnapshot) XXX_Unmarshal(b []byte) error {
@ -8441,7 +8582,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{123}
return fileDescriptor_77a6da22d6a3feb1, []int{124}
}
func (m *ChannelBackups) XXX_Unmarshal(b []byte) error {
@ -8483,7 +8624,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{124}
return fileDescriptor_77a6da22d6a3feb1, []int{125}
}
func (m *RestoreChanBackupRequest) XXX_Unmarshal(b []byte) error {
@ -8559,7 +8700,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{125}
return fileDescriptor_77a6da22d6a3feb1, []int{126}
}
func (m *RestoreBackupResponse) XXX_Unmarshal(b []byte) error {
@ -8590,7 +8731,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{126}
return fileDescriptor_77a6da22d6a3feb1, []int{127}
}
func (m *ChannelBackupSubscription) XXX_Unmarshal(b []byte) error {
@ -8621,7 +8762,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{127}
return fileDescriptor_77a6da22d6a3feb1, []int{128}
}
func (m *VerifyChanBackupResponse) XXX_Unmarshal(b []byte) error {
@ -8644,6 +8785,7 @@ var xxx_messageInfo_VerifyChanBackupResponse proto.InternalMessageInfo
func init() {
proto.RegisterEnum("lnrpc.AddressType", AddressType_name, AddressType_value)
proto.RegisterEnum("lnrpc.InvoiceHTLCState", InvoiceHTLCState_name, InvoiceHTLCState_value)
proto.RegisterEnum("lnrpc.ChannelCloseSummary_ClosureType", ChannelCloseSummary_ClosureType_name, ChannelCloseSummary_ClosureType_value)
proto.RegisterEnum("lnrpc.Peer_SyncType", Peer_SyncType_name, Peer_SyncType_value)
proto.RegisterEnum("lnrpc.ChannelEventUpdate_UpdateType", ChannelEventUpdate_UpdateType_name, ChannelEventUpdate_UpdateType_value)
@ -8753,6 +8895,7 @@ func init() {
proto.RegisterType((*HopHint)(nil), "lnrpc.HopHint")
proto.RegisterType((*RouteHint)(nil), "lnrpc.RouteHint")
proto.RegisterType((*Invoice)(nil), "lnrpc.Invoice")
proto.RegisterType((*InvoiceHTLC)(nil), "lnrpc.InvoiceHTLC")
proto.RegisterType((*AddInvoiceResponse)(nil), "lnrpc.AddInvoiceResponse")
proto.RegisterType((*PaymentHash)(nil), "lnrpc.PaymentHash")
proto.RegisterType((*ListInvoiceRequest)(nil), "lnrpc.ListInvoiceRequest")
@ -8792,515 +8935,523 @@ func init() {
func init() { proto.RegisterFile("rpc.proto", fileDescriptor_77a6da22d6a3feb1) }
var fileDescriptor_77a6da22d6a3feb1 = []byte{
// 8125 bytes of a gzipped FileDescriptorProto
// 8246 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x7d, 0x6d, 0x6c, 0x24, 0xd9,
0xb5, 0x90, 0xab, 0x3f, 0xec, 0xee, 0xd3, 0xed, 0xee, 0xf6, 0xb5, 0xc7, 0xee, 0xe9, 0x9d, 0x9d,
0x9d, 0xad, 0xcc, 0xdb, 0x99, 0x4c, 0xf6, 0xd9, 0xb3, 0x93, 0x64, 0x99, 0xb7, 0xf3, 0xc2, 0xc3,
0x63, 0x7b, 0xc6, 0x93, 0x78, 0x3d, 0x4e, 0xd9, 0x93, 0x21, 0xc9, 0x43, 0x9d, 0x72, 0xf7, 0x75,
0xbb, 0x32, 0xd5, 0x55, 0x9d, 0xaa, 0x6a, 0x7b, 0x3a, 0xcb, 0xf2, 0x03, 0x21, 0x84, 0x9e, 0x84,
0x50, 0x40, 0x20, 0x40, 0x20, 0xa4, 0x04, 0x21, 0x9e, 0xf8, 0x01, 0xfc, 0x00, 0x81, 0x14, 0x89,
0x9f, 0xfc, 0x42, 0x08, 0xbd, 0x9f, 0x48, 0x3c, 0x21, 0x90, 0x50, 0xc4, 0x3f, 0x24, 0xfe, 0xa3,
0x7b, 0xee, 0x47, 0xdd, 0x5b, 0x55, 0x3d, 0x9e, 0x49, 0xc2, 0xfb, 0xe5, 0xbe, 0xe7, 0x9c, 0xba,
0x9f, 0xe7, 0x9c, 0x7b, 0xce, 0xb9, 0xe7, 0x5e, 0x43, 0x3d, 0x9a, 0x0c, 0x36, 0x27, 0x51, 0x98,
0x84, 0xa4, 0xea, 0x07, 0xd1, 0x64, 0xd0, 0xbb, 0x31, 0x0a, 0xc3, 0x91, 0x4f, 0xb7, 0xdc, 0x89,
0xb7, 0xe5, 0x06, 0x41, 0x98, 0xb8, 0x89, 0x17, 0x06, 0x31, 0x27, 0xb2, 0x7f, 0x04, 0xad, 0xa7,
0x34, 0x38, 0xa6, 0x74, 0xe8, 0xd0, 0x9f, 0x4c, 0x69, 0x9c, 0x90, 0xaf, 0xc1, 0x8a, 0x4b, 0x7f,
0x4a, 0xe9, 0xb0, 0x3f, 0x71, 0xe3, 0x78, 0x72, 0x1e, 0xb9, 0x31, 0xed, 0x5a, 0xb7, 0xac, 0xbb,
0x4d, 0xa7, 0xc3, 0x11, 0x47, 0x0a, 0x4e, 0x3e, 0x84, 0x66, 0xcc, 0x48, 0x69, 0x90, 0x44, 0xe1,
0x64, 0xd6, 0x2d, 0x21, 0x5d, 0x83, 0xc1, 0xf6, 0x38, 0xc8, 0xf6, 0xa1, 0xad, 0x5a, 0x88, 0x27,
0x61, 0x10, 0x53, 0x72, 0x1f, 0xd6, 0x06, 0xde, 0xe4, 0x9c, 0x46, 0x7d, 0xfc, 0x78, 0x1c, 0xd0,
0x71, 0x18, 0x78, 0x83, 0xae, 0x75, 0xab, 0x7c, 0xb7, 0xee, 0x10, 0x8e, 0x63, 0x5f, 0x7c, 0x2e,
0x30, 0xe4, 0x0e, 0xb4, 0x69, 0xc0, 0xe1, 0x74, 0x88, 0x5f, 0x89, 0xa6, 0x5a, 0x29, 0x98, 0x7d,
0x60, 0xff, 0x8d, 0x12, 0xac, 0x3c, 0x0b, 0xbc, 0xe4, 0xa5, 0xeb, 0xfb, 0x34, 0x91, 0x63, 0xba,
0x03, 0xed, 0x4b, 0x04, 0xe0, 0x98, 0x2e, 0xc3, 0x68, 0x28, 0x46, 0xd4, 0xe2, 0xe0, 0x23, 0x01,
0x9d, 0xdb, 0xb3, 0xd2, 0xdc, 0x9e, 0x15, 0x4e, 0x57, 0x79, 0xce, 0x74, 0xdd, 0x81, 0x76, 0x44,
0x07, 0xe1, 0x05, 0x8d, 0x66, 0xfd, 0x4b, 0x2f, 0x18, 0x86, 0x97, 0xdd, 0xca, 0x2d, 0xeb, 0x6e,
0xd5, 0x69, 0x49, 0xf0, 0x4b, 0x84, 0x92, 0xc7, 0xd0, 0x1e, 0x9c, 0xbb, 0x41, 0x40, 0xfd, 0xfe,
0xa9, 0x3b, 0x78, 0x35, 0x9d, 0xc4, 0xdd, 0xea, 0x2d, 0xeb, 0x6e, 0xe3, 0xc1, 0xf5, 0x4d, 0x5c,
0xd5, 0xcd, 0x9d, 0x73, 0x37, 0x78, 0x8c, 0x98, 0xe3, 0xc0, 0x9d, 0xc4, 0xe7, 0x61, 0xe2, 0xb4,
0xc4, 0x17, 0x1c, 0x1c, 0xdb, 0x6b, 0x40, 0xf4, 0x99, 0xe0, 0x73, 0x6f, 0xff, 0x0b, 0x0b, 0x56,
0x5f, 0x04, 0x7e, 0x38, 0x78, 0xf5, 0x6b, 0x4e, 0x51, 0xc1, 0x18, 0x4a, 0x6f, 0x3b, 0x86, 0xf2,
0xbb, 0x8e, 0x61, 0x1d, 0xd6, 0xcc, 0xce, 0x8a, 0x51, 0x50, 0xb8, 0xc6, 0xbe, 0x1e, 0x51, 0xd9,
0x2d, 0x39, 0x8c, 0xaf, 0x42, 0x67, 0x30, 0x8d, 0x22, 0x1a, 0xe4, 0xc6, 0xd1, 0x16, 0x70, 0x35,
0x90, 0x0f, 0xa1, 0x19, 0xd0, 0xcb, 0x94, 0x4c, 0xf0, 0x6e, 0x40, 0x2f, 0x25, 0x89, 0xdd, 0x85,
0xf5, 0x6c, 0x33, 0xa2, 0x03, 0xff, 0xdd, 0x82, 0xca, 0x8b, 0xe4, 0x75, 0x48, 0x36, 0xa1, 0x92,
0xcc, 0x26, 0x5c, 0x42, 0x5a, 0x0f, 0x88, 0x18, 0xda, 0xf6, 0x70, 0x18, 0xd1, 0x38, 0x3e, 0x99,
0x4d, 0xa8, 0xd3, 0x74, 0x79, 0xa1, 0xcf, 0xe8, 0x48, 0x17, 0x96, 0x44, 0x19, 0x1b, 0xac, 0x3b,
0xb2, 0x48, 0x6e, 0x02, 0xb8, 0xe3, 0x70, 0x1a, 0x24, 0xfd, 0xd8, 0x4d, 0x70, 0xaa, 0xca, 0x8e,
0x06, 0x21, 0x37, 0xa0, 0x3e, 0x79, 0xd5, 0x8f, 0x07, 0x91, 0x37, 0x49, 0x90, 0x6d, 0xea, 0x4e,
0x0a, 0x20, 0x5f, 0x83, 0x5a, 0x38, 0x4d, 0x26, 0xa1, 0x17, 0x24, 0x82, 0x55, 0xda, 0xa2, 0x2f,
0xcf, 0xa7, 0xc9, 0x11, 0x03, 0x3b, 0x8a, 0x80, 0xdc, 0x86, 0xe5, 0x41, 0x18, 0x9c, 0x79, 0xd1,
0x98, 0x2b, 0x83, 0xee, 0x22, 0xb6, 0x66, 0x02, 0xed, 0x7f, 0x5f, 0x82, 0xc6, 0x49, 0xe4, 0x06,
0xb1, 0x3b, 0x60, 0x00, 0xd6, 0xf5, 0xe4, 0x75, 0xff, 0xdc, 0x8d, 0xcf, 0x71, 0xb4, 0x75, 0x47,
0x16, 0xc9, 0x3a, 0x2c, 0xf2, 0x8e, 0xe2, 0x98, 0xca, 0x8e, 0x28, 0x91, 0x8f, 0x61, 0x25, 0x98,
0x8e, 0xfb, 0x66, 0x5b, 0x65, 0xe4, 0x96, 0x3c, 0x82, 0x4d, 0xc0, 0x29, 0x5b, 0x6b, 0xde, 0x04,
0x1f, 0xa1, 0x06, 0x21, 0x36, 0x34, 0x45, 0x89, 0x7a, 0xa3, 0x73, 0x3e, 0xcc, 0xaa, 0x63, 0xc0,
0x58, 0x1d, 0x89, 0x37, 0xa6, 0xfd, 0x38, 0x71, 0xc7, 0x13, 0x31, 0x2c, 0x0d, 0x82, 0xf8, 0x30,
0x71, 0xfd, 0xfe, 0x19, 0xa5, 0x71, 0x77, 0x49, 0xe0, 0x15, 0x84, 0x7c, 0x04, 0xad, 0x21, 0x8d,
0x93, 0xbe, 0x58, 0x14, 0x1a, 0x77, 0x6b, 0x28, 0xfa, 0x19, 0x28, 0xab, 0x27, 0x72, 0x2f, 0xfb,
0x6c, 0x02, 0xe8, 0xeb, 0x6e, 0x9d, 0xf7, 0x35, 0x85, 0x30, 0xce, 0x79, 0x4a, 0x13, 0x6d, 0xf6,
0x62, 0xc1, 0xa1, 0xf6, 0x01, 0x10, 0x0d, 0xbc, 0x4b, 0x13, 0xd7, 0xf3, 0x63, 0xf2, 0x29, 0x34,
0x13, 0x8d, 0x18, 0x55, 0x61, 0x43, 0xb1, 0x93, 0xf6, 0x81, 0x63, 0xd0, 0xd9, 0x4f, 0xa1, 0xf6,
0x84, 0xd2, 0x03, 0x6f, 0xec, 0x25, 0x64, 0x1d, 0xaa, 0x67, 0xde, 0x6b, 0xca, 0x19, 0xbe, 0xbc,
0xbf, 0xe0, 0xf0, 0x22, 0xe9, 0xc1, 0xd2, 0x84, 0x46, 0x03, 0x2a, 0x97, 0x67, 0x7f, 0xc1, 0x91,
0x80, 0xc7, 0x4b, 0x50, 0xf5, 0xd9, 0xc7, 0xf6, 0xaf, 0xca, 0xd0, 0x38, 0xa6, 0x81, 0x12, 0x24,
0x02, 0x15, 0x36, 0x64, 0x21, 0x3c, 0xf8, 0x9b, 0x7c, 0x00, 0x0d, 0x9c, 0x86, 0x38, 0x89, 0xbc,
0x60, 0x24, 0xf8, 0x17, 0x18, 0xe8, 0x18, 0x21, 0xa4, 0x03, 0x65, 0x77, 0x2c, 0x79, 0x97, 0xfd,
0x64, 0x42, 0x36, 0x71, 0x67, 0x63, 0x26, 0x8f, 0x6a, 0x55, 0x9b, 0x4e, 0x43, 0xc0, 0xf6, 0xd9,
0xb2, 0x6e, 0xc2, 0xaa, 0x4e, 0x22, 0x6b, 0xaf, 0x62, 0xed, 0x2b, 0x1a, 0xa5, 0x68, 0xe4, 0x0e,
0xb4, 0x25, 0x7d, 0xc4, 0x3b, 0x8b, 0xeb, 0x5c, 0x77, 0x5a, 0x02, 0x2c, 0x87, 0x70, 0x17, 0x3a,
0x67, 0x5e, 0xe0, 0xfa, 0xfd, 0x81, 0x9f, 0x5c, 0xf4, 0x87, 0xd4, 0x4f, 0x5c, 0x5c, 0xf1, 0xaa,
0xd3, 0x42, 0xf8, 0x8e, 0x9f, 0x5c, 0xec, 0x32, 0x28, 0xf9, 0x18, 0xea, 0x67, 0x94, 0xf6, 0x71,
0x26, 0xba, 0x35, 0x43, 0x7a, 0xe4, 0xec, 0x3a, 0xb5, 0x33, 0x39, 0xcf, 0x77, 0xa1, 0x13, 0x4e,
0x93, 0x51, 0xe8, 0x05, 0xa3, 0x3e, 0xd3, 0x57, 0x7d, 0x6f, 0x88, 0x1c, 0x50, 0x71, 0x5a, 0x12,
0xce, 0xb4, 0xc6, 0xb3, 0x21, 0x79, 0x1f, 0x00, 0xdb, 0xe6, 0x15, 0xc3, 0x2d, 0xeb, 0xee, 0xb2,
0x53, 0x67, 0x10, 0x5e, 0xd1, 0x67, 0x50, 0xc3, 0xf9, 0x4c, 0xfc, 0x8b, 0x6e, 0x03, 0x17, 0xfc,
0x03, 0xd1, 0xaa, 0xb6, 0x12, 0x9b, 0xbb, 0x34, 0x4e, 0x4e, 0xfc, 0x0b, 0xb6, 0x9f, 0xce, 0x9c,
0xa5, 0x21, 0x2f, 0xf5, 0x3e, 0x83, 0xa6, 0x8e, 0x60, 0x53, 0xff, 0x8a, 0xce, 0x70, 0xb9, 0x2a,
0x0e, 0xfb, 0x49, 0xd6, 0xa0, 0x7a, 0xe1, 0xfa, 0x53, 0x2a, 0x14, 0x1b, 0x2f, 0x7c, 0x56, 0x7a,
0x68, 0xd9, 0xff, 0xce, 0x82, 0x26, 0x6f, 0x41, 0x6c, 0xc8, 0xb7, 0x61, 0x59, 0x4e, 0x29, 0x8d,
0xa2, 0x30, 0x12, 0xf2, 0x6d, 0x02, 0xc9, 0x3d, 0xe8, 0x48, 0xc0, 0x24, 0xa2, 0xde, 0xd8, 0x1d,
0xc9, 0xba, 0x73, 0x70, 0xf2, 0x20, 0xad, 0x31, 0x0a, 0xa7, 0x09, 0x15, 0xaa, 0xbf, 0x29, 0xc6,
0xe7, 0x30, 0x98, 0x63, 0x92, 0x30, 0xf9, 0x2e, 0xe0, 0x15, 0x03, 0x66, 0xff, 0xcc, 0x02, 0xc2,
0xba, 0x7e, 0x12, 0xf2, 0x2a, 0xc4, 0x52, 0x67, 0xd9, 0xcc, 0x7a, 0x6b, 0x36, 0x2b, 0xcd, 0x63,
0x33, 0x1b, 0xaa, 0xbc, 0xe7, 0x95, 0x82, 0x9e, 0x73, 0xd4, 0xb7, 0x2b, 0xb5, 0x72, 0xa7, 0x62,
0xff, 0xdc, 0x82, 0xe6, 0x0e, 0xdf, 0xb7, 0x50, 0xd1, 0x92, 0xfb, 0x40, 0xce, 0xa6, 0xc1, 0x90,
0xf1, 0x47, 0xf2, 0xda, 0x1b, 0xf6, 0x4f, 0x67, 0x09, 0x8d, 0x79, 0x9f, 0xf6, 0x17, 0x9c, 0x02,
0x1c, 0xf9, 0x18, 0x3a, 0x06, 0x34, 0x4e, 0x22, 0xde, 0xb3, 0xfd, 0x05, 0x27, 0x87, 0x61, 0x13,
0xc5, 0x54, 0xf9, 0x34, 0xe9, 0x7b, 0xc1, 0x90, 0xbe, 0xc6, 0xb9, 0x5d, 0x76, 0x0c, 0xd8, 0xe3,
0x16, 0x34, 0xf5, 0xef, 0xec, 0x1f, 0x43, 0x4d, 0x6e, 0x04, 0xa8, 0x04, 0x33, 0xfd, 0x72, 0x34,
0x08, 0xe9, 0x41, 0xcd, 0xec, 0x85, 0x53, 0x7b, 0x97, 0xb6, 0xed, 0x3f, 0x0f, 0x9d, 0x03, 0xa6,
0x8d, 0x03, 0x2f, 0x18, 0x89, 0x9d, 0x90, 0x6d, 0x11, 0x93, 0xe9, 0xa9, 0x64, 0xd1, 0xba, 0x23,
0x4a, 0x4c, 0xcf, 0x9c, 0x87, 0x71, 0x22, 0xda, 0xc1, 0xdf, 0xf6, 0x7f, 0xb4, 0x80, 0xec, 0xc5,
0x89, 0x37, 0x76, 0x13, 0xfa, 0x84, 0xaa, 0x45, 0x7e, 0x0e, 0x4d, 0x56, 0xdb, 0x49, 0xb8, 0xcd,
0xf7, 0x1a, 0xae, 0x23, 0xbf, 0x26, 0x16, 0x26, 0xff, 0xc1, 0xa6, 0x4e, 0xcd, 0xc5, 0xc7, 0xa8,
0x80, 0xe9, 0xb3, 0xc4, 0x8d, 0x46, 0x34, 0xc1, 0x8d, 0x48, 0x98, 0x31, 0xc0, 0x41, 0x3b, 0x61,
0x70, 0xd6, 0xfb, 0x03, 0x58, 0xc9, 0xd5, 0xa1, 0x4b, 0x5a, 0xbd, 0x40, 0xd2, 0xca, 0xba, 0xa4,
0x0d, 0x60, 0xd5, 0xe8, 0x97, 0x90, 0xb7, 0x2e, 0x2c, 0x31, 0x7d, 0xc3, 0xf6, 0x79, 0xd4, 0xd5,
0x8e, 0x2c, 0x92, 0x07, 0xb0, 0x76, 0x46, 0x69, 0xe4, 0x26, 0x58, 0xec, 0x4f, 0x68, 0x84, 0x6b,
0x22, 0x6a, 0x2e, 0xc4, 0xd9, 0xff, 0xc3, 0x82, 0x36, 0x93, 0x89, 0xcf, 0xdd, 0x60, 0x26, 0xe7,
0xea, 0xa0, 0x70, 0xae, 0xee, 0x6a, 0xea, 0x45, 0xa3, 0x7e, 0xd7, 0x89, 0x2a, 0x67, 0x27, 0x8a,
0xdc, 0x82, 0xa6, 0xd1, 0xdd, 0x2a, 0xdf, 0x58, 0x63, 0x37, 0x39, 0xa2, 0xd1, 0xe3, 0x59, 0x42,
0x7f, 0xf3, 0xa9, 0xfc, 0x08, 0x3a, 0x69, 0xb7, 0xc5, 0x3c, 0x12, 0xa8, 0x30, 0xc6, 0x14, 0x15,
0xe0, 0x6f, 0xfb, 0x1f, 0x59, 0x9c, 0x70, 0x27, 0xf4, 0xd4, 0xa6, 0xcb, 0x08, 0xd9, 0xde, 0x2d,
0x09, 0xd9, 0xef, 0xb9, 0x46, 0xcb, 0x6f, 0x3e, 0x58, 0x72, 0x1d, 0x6a, 0x31, 0x0d, 0x86, 0x7d,
0xd7, 0xf7, 0x71, 0x6f, 0xaa, 0x39, 0x4b, 0xac, 0xbc, 0xed, 0xfb, 0xf6, 0x1d, 0x58, 0xd1, 0x7a,
0xf7, 0x86, 0x71, 0x1c, 0x02, 0x39, 0xf0, 0xe2, 0xe4, 0x45, 0x10, 0x4f, 0xb4, 0x3d, 0xed, 0x3d,
0xa8, 0x8f, 0xbd, 0x00, 0x7b, 0xc6, 0x25, 0xb7, 0xea, 0xd4, 0xc6, 0x5e, 0xc0, 0xfa, 0x15, 0x23,
0xd2, 0x7d, 0x2d, 0x90, 0x25, 0x81, 0x74, 0x5f, 0x23, 0xd2, 0x7e, 0x08, 0xab, 0x46, 0x7d, 0xa2,
0xe9, 0x0f, 0xa1, 0x3a, 0x4d, 0x5e, 0x87, 0xd2, 0xe2, 0x68, 0x08, 0x0e, 0x61, 0xb6, 0xad, 0xc3,
0x31, 0xf6, 0x23, 0x58, 0x39, 0xa4, 0x97, 0x42, 0x90, 0x65, 0x47, 0x3e, 0xba, 0xd2, 0xee, 0x45,
0xbc, 0xbd, 0x09, 0x44, 0xff, 0x38, 0x15, 0x00, 0x69, 0x05, 0x5b, 0x86, 0x15, 0x6c, 0x7f, 0x04,
0xe4, 0xd8, 0x1b, 0x05, 0x9f, 0xd3, 0x38, 0x76, 0x47, 0x4a, 0xf4, 0x3b, 0x50, 0x1e, 0xc7, 0x23,
0xa1, 0xaa, 0xd8, 0x4f, 0xfb, 0xeb, 0xb0, 0x6a, 0xd0, 0x89, 0x8a, 0x6f, 0x40, 0x3d, 0xf6, 0x46,
0x81, 0x9b, 0x4c, 0x23, 0x2a, 0xaa, 0x4e, 0x01, 0xf6, 0x13, 0x58, 0xfb, 0x1e, 0x8d, 0xbc, 0xb3,
0xd9, 0x55, 0xd5, 0x9b, 0xf5, 0x94, 0xb2, 0xf5, 0xec, 0xc1, 0xb5, 0x4c, 0x3d, 0xa2, 0x79, 0xce,
0xbe, 0x62, 0x25, 0x6b, 0x0e, 0x2f, 0x68, 0xba, 0xaf, 0xa4, 0xeb, 0x3e, 0xfb, 0x05, 0x90, 0x9d,
0x30, 0x08, 0xe8, 0x20, 0x39, 0xa2, 0x34, 0x4a, 0x1d, 0xf0, 0x94, 0x57, 0x1b, 0x0f, 0x36, 0xc4,
0xcc, 0x66, 0x15, 0xaa, 0x60, 0x62, 0x02, 0x95, 0x09, 0x8d, 0xc6, 0x58, 0x71, 0xcd, 0xc1, 0xdf,
0xf6, 0x35, 0x58, 0x35, 0xaa, 0x15, 0x2e, 0xcb, 0x27, 0x70, 0x6d, 0xd7, 0x8b, 0x07, 0xf9, 0x06,
0xbb, 0xb0, 0x34, 0x99, 0x9e, 0xf6, 0x53, 0x49, 0x94, 0x45, 0x66, 0xc5, 0x66, 0x3f, 0x11, 0x95,
0xfd, 0x75, 0x0b, 0x2a, 0xfb, 0x27, 0x07, 0x3b, 0x6c, 0xaf, 0xf0, 0x82, 0x41, 0x38, 0x66, 0x7b,
0x29, 0x1f, 0xb4, 0x2a, 0xcf, 0x95, 0xb0, 0x1b, 0x50, 0xc7, 0x2d, 0x98, 0x19, 0xee, 0xc2, 0x57,
0x4e, 0x01, 0xcc, 0x69, 0xa0, 0xaf, 0x27, 0x5e, 0x84, 0x5e, 0x81, 0xb4, 0xf5, 0x2b, 0xb8, 0xcd,
0xe4, 0x11, 0xf6, 0x2f, 0x17, 0x61, 0x49, 0x6c, 0xbe, 0xd8, 0xde, 0x20, 0xf1, 0x2e, 0xa8, 0xe8,
0x89, 0x28, 0x31, 0xf3, 0x26, 0xa2, 0xe3, 0x30, 0xa1, 0x7d, 0x63, 0x19, 0x4c, 0x20, 0x3a, 0x45,
0xc2, 0x5f, 0xe5, 0x6e, 0x54, 0x99, 0x53, 0x19, 0x40, 0x36, 0x59, 0xd2, 0xe6, 0xab, 0xa0, 0xad,
0x25, 0x8b, 0x6c, 0x26, 0x06, 0xee, 0xc4, 0x1d, 0x78, 0xc9, 0x4c, 0xa8, 0x04, 0x55, 0x66, 0x75,
0xfb, 0xe1, 0xc0, 0x65, 0x9e, 0xb0, 0xef, 0x06, 0x03, 0x2a, 0x1d, 0x2e, 0x03, 0xc8, 0x9c, 0x0f,
0xd1, 0x25, 0x49, 0xc6, 0x1d, 0x94, 0x0c, 0x94, 0xed, 0xdf, 0x83, 0x70, 0x3c, 0xf6, 0x12, 0xe6,
0xb3, 0xa0, 0xbd, 0x5a, 0x76, 0x34, 0x08, 0x77, 0xef, 0xb0, 0x74, 0xc9, 0x67, 0xaf, 0x2e, 0xdd,
0x3b, 0x0d, 0xc8, 0x6a, 0x61, 0xbb, 0x0e, 0x53, 0x63, 0xaf, 0x2e, 0xd1, 0x38, 0x2d, 0x3b, 0x1a,
0x84, 0xad, 0xc3, 0x34, 0x88, 0x69, 0x92, 0xf8, 0x74, 0xa8, 0x3a, 0xd4, 0x40, 0xb2, 0x3c, 0x82,
0xdc, 0x87, 0x55, 0xee, 0x46, 0xc5, 0x6e, 0x12, 0xc6, 0xe7, 0x5e, 0xdc, 0x8f, 0x99, 0xc3, 0xd1,
0x44, 0xfa, 0x22, 0x14, 0x79, 0x08, 0x1b, 0x19, 0x70, 0x44, 0x07, 0xd4, 0xbb, 0xa0, 0xc3, 0xee,
0x32, 0x7e, 0x35, 0x0f, 0x4d, 0x6e, 0x41, 0x83, 0x79, 0x8f, 0xd3, 0xc9, 0xd0, 0x65, 0x06, 0x4c,
0x0b, 0xd7, 0x41, 0x07, 0x91, 0x4f, 0x60, 0x79, 0x42, 0xb9, 0xf5, 0x73, 0x9e, 0xf8, 0x83, 0xb8,
0xdb, 0x36, 0xb4, 0x1b, 0xe3, 0x5c, 0xc7, 0xa4, 0x60, 0x4c, 0x39, 0x88, 0xd1, 0x4d, 0x70, 0x67,
0xdd, 0x8e, 0x30, 0xd5, 0x25, 0x00, 0x65, 0x24, 0xf2, 0x2e, 0xdc, 0x84, 0x76, 0x57, 0xb8, 0x42,
0x17, 0x45, 0xf6, 0x9d, 0x17, 0x78, 0x89, 0xe7, 0x26, 0x61, 0xd4, 0x25, 0x88, 0x4b, 0x01, 0x6c,
0x12, 0x91, 0x3f, 0xe2, 0xc4, 0x4d, 0xa6, 0x71, 0xff, 0xcc, 0x77, 0x47, 0x71, 0x77, 0x95, 0xdb,
0x9c, 0x39, 0x04, 0xf9, 0x14, 0xd6, 0x39, 0x47, 0x20, 0x2a, 0xa2, 0x31, 0x8d, 0x2e, 0xb8, 0x99,
0xb0, 0x86, 0x33, 0x32, 0x07, 0xcb, 0xa6, 0x52, 0xb0, 0x48, 0xee, 0xc3, 0x6b, 0x7c, 0x2a, 0xe7,
0xa0, 0xed, 0x7f, 0x62, 0xf1, 0x6d, 0x41, 0x88, 0x90, 0x52, 0xef, 0x1f, 0x40, 0x83, 0x0b, 0x4f,
0x3f, 0x0c, 0xfc, 0x99, 0x90, 0x27, 0xe0, 0xa0, 0xe7, 0x81, 0x3f, 0x23, 0x5f, 0x81, 0x65, 0x2f,
0xd0, 0x49, 0xb8, 0x06, 0x6a, 0x4a, 0x20, 0x12, 0x7d, 0x00, 0x8d, 0xc9, 0xf4, 0xd4, 0xf7, 0x06,
0x9c, 0xa4, 0xcc, 0x6b, 0xe1, 0x20, 0x24, 0x60, 0x76, 0x3b, 0x9f, 0x47, 0x4e, 0x51, 0x41, 0x8a,
0x86, 0x80, 0x31, 0x12, 0xfb, 0x31, 0xac, 0x99, 0x1d, 0x14, 0xaa, 0xf6, 0x1e, 0xd4, 0x84, 0x64,
0xc6, 0xc2, 0x79, 0x6a, 0x69, 0x71, 0xa5, 0x80, 0xfa, 0x8e, 0xc2, 0xdb, 0xff, 0xb6, 0x02, 0xab,
0x02, 0xba, 0xe3, 0x87, 0x31, 0x3d, 0x9e, 0x8e, 0xc7, 0x6e, 0x54, 0x20, 0xf2, 0xd6, 0x15, 0x22,
0x5f, 0x32, 0x45, 0x9e, 0x09, 0xe2, 0xb9, 0xeb, 0x05, 0xdc, 0xe9, 0xe0, 0xfa, 0x42, 0x83, 0x90,
0xbb, 0xd0, 0x1e, 0xf8, 0x61, 0xcc, 0x8d, 0x70, 0x3d, 0xac, 0x91, 0x05, 0xe7, 0x55, 0x54, 0xb5,
0x48, 0x45, 0xe9, 0x2a, 0x66, 0x31, 0xa3, 0x62, 0x6c, 0x68, 0xb2, 0x4a, 0xa9, 0xd4, 0x98, 0x4b,
0xdc, 0x30, 0xd7, 0x61, 0xac, 0x3f, 0x59, 0x81, 0xe6, 0xda, 0xa3, 0x5d, 0x24, 0xce, 0xde, 0x98,
0xa2, 0x46, 0xd6, 0xa8, 0xeb, 0x42, 0x9c, 0xf3, 0x28, 0xf2, 0x84, 0xf9, 0xba, 0xac, 0x2d, 0x34,
0x0b, 0x00, 0xcd, 0x82, 0x8f, 0xcc, 0x15, 0xd1, 0xe7, 0x7e, 0x93, 0x15, 0xa6, 0x11, 0x45, 0x53,
0x41, 0xfb, 0xd2, 0xfe, 0x23, 0x0b, 0x1a, 0x1a, 0x8e, 0x5c, 0x83, 0x95, 0x9d, 0xe7, 0xcf, 0x8f,
0xf6, 0x9c, 0xed, 0x93, 0x67, 0xdf, 0xdb, 0xeb, 0xef, 0x1c, 0x3c, 0x3f, 0xde, 0xeb, 0x2c, 0x30,
0xf0, 0xc1, 0xf3, 0x9d, 0xed, 0x83, 0xfe, 0x93, 0xe7, 0xce, 0x8e, 0x04, 0x5b, 0x64, 0x1d, 0x88,
0xb3, 0xf7, 0xf9, 0xf3, 0x93, 0x3d, 0x03, 0x5e, 0x22, 0x1d, 0x68, 0x3e, 0x76, 0xf6, 0xb6, 0x77,
0xf6, 0x05, 0xa4, 0x4c, 0xd6, 0xa0, 0xf3, 0xe4, 0xc5, 0xe1, 0xee, 0xb3, 0xc3, 0xa7, 0xfd, 0x9d,
0xed, 0xc3, 0x9d, 0xbd, 0x83, 0xbd, 0xdd, 0x4e, 0x85, 0x2c, 0x43, 0x7d, 0xfb, 0xf1, 0xf6, 0xe1,
0xee, 0xf3, 0xc3, 0xbd, 0xdd, 0x4e, 0xd5, 0xfe, 0x6f, 0x16, 0x5c, 0xc3, 0x5e, 0x0f, 0xb3, 0x02,
0x72, 0x0b, 0x1a, 0x83, 0x30, 0x9c, 0x30, 0x73, 0x3c, 0xdd, 0x70, 0x74, 0x10, 0x63, 0x7e, 0x2e,
0xae, 0x67, 0x61, 0x34, 0xa0, 0x42, 0x3e, 0x00, 0x41, 0x4f, 0x18, 0x84, 0x31, 0xbf, 0x58, 0x5e,
0x4e, 0xc1, 0xc5, 0xa3, 0xc1, 0x61, 0x9c, 0x64, 0x1d, 0x16, 0x4f, 0x23, 0xea, 0x0e, 0xce, 0x85,
0x64, 0x88, 0x12, 0xf9, 0x6a, 0xea, 0x2f, 0x0e, 0xd8, 0xec, 0xfb, 0x74, 0x88, 0x1c, 0x53, 0x73,
0xda, 0x02, 0xbe, 0x23, 0xc0, 0x4c, 0x3f, 0xb9, 0xa7, 0x6e, 0x30, 0x0c, 0x03, 0x3a, 0x14, 0xc6,
0x68, 0x0a, 0xb0, 0x8f, 0x60, 0x3d, 0x3b, 0x3e, 0x21, 0x5f, 0x9f, 0x6a, 0xf2, 0xc5, 0x6d, 0xc3,
0xde, 0xfc, 0xd5, 0xd4, 0x64, 0xed, 0x4f, 0x4b, 0x50, 0x61, 0xa6, 0xc2, 0x7c, 0xb3, 0x42, 0xb7,
0xfe, 0xca, 0xb9, 0x18, 0x28, 0xba, 0xa0, 0x7c, 0xf3, 0xe0, 0x1b, 0xac, 0x06, 0x49, 0xf1, 0x11,
0x1d, 0x5c, 0xe0, 0x88, 0x15, 0x9e, 0x41, 0x98, 0x80, 0x30, 0xd3, 0x1c, 0xbf, 0x16, 0x02, 0x22,
0xcb, 0x12, 0x87, 0x5f, 0x2e, 0xa5, 0x38, 0xfc, 0xae, 0x0b, 0x4b, 0x5e, 0x70, 0x1a, 0x4e, 0x83,
0x21, 0x0a, 0x44, 0xcd, 0x91, 0x45, 0x8c, 0xba, 0xa2, 0xa0, 0x7a, 0x63, 0xc9, 0xfe, 0x29, 0x80,
0x3c, 0x80, 0x7a, 0x3c, 0x0b, 0x06, 0x3a, 0xcf, 0xaf, 0x89, 0x59, 0x62, 0x73, 0xb0, 0x79, 0x3c,
0x0b, 0x06, 0xc8, 0xe1, 0x29, 0x99, 0xfd, 0x07, 0x50, 0x93, 0x60, 0xc6, 0x96, 0x2f, 0x0e, 0xbf,
0x73, 0xf8, 0xfc, 0xe5, 0x61, 0xff, 0xf8, 0xfb, 0x87, 0x3b, 0x9d, 0x05, 0xd2, 0x86, 0xc6, 0xf6,
0x0e, 0x72, 0x3a, 0x02, 0x2c, 0x46, 0x72, 0xb4, 0x7d, 0x7c, 0xac, 0x20, 0x25, 0x9b, 0x30, 0xf7,
0x3a, 0x46, 0x7b, 0x4c, 0x45, 0x15, 0x3f, 0x85, 0x15, 0x0d, 0x96, 0xda, 0xf6, 0x13, 0x06, 0xc8,
0xd8, 0xf6, 0x68, 0xc8, 0x71, 0x8c, 0xdd, 0x81, 0xd6, 0x53, 0x9a, 0x3c, 0x0b, 0xce, 0x42, 0x59,
0xd3, 0xff, 0xaa, 0x40, 0x5b, 0x81, 0x44, 0x45, 0x77, 0xa1, 0xed, 0x0d, 0x69, 0x90, 0x78, 0xc9,
0xac, 0x6f, 0x78, 0xf1, 0x59, 0x30, 0x33, 0x80, 0x5d, 0xdf, 0x73, 0x65, 0x70, 0x9b, 0x17, 0x98,
0x57, 0xcb, 0x76, 0x67, 0xb9, 0xe1, 0x2a, 0xbe, 0xe2, 0xc1, 0x83, 0x42, 0x1c, 0xd3, 0x40, 0x0c,
0x2e, 0xb6, 0x18, 0xf5, 0x09, 0x37, 0x04, 0x8b, 0x50, 0x6c, 0xa9, 0x78, 0x4d, 0x6c, 0xc8, 0x55,
0xbe, 0x83, 0x2b, 0x40, 0x2e, 0x7a, 0xbc, 0xc8, 0xf5, 0x63, 0x36, 0x7a, 0xac, 0x45, 0xa0, 0x6b,
0xb9, 0x08, 0x34, 0xd3, 0x9f, 0xb3, 0x60, 0x40, 0x87, 0xfd, 0x24, 0xec, 0xa3, 0x9e, 0x47, 0x96,
0xa8, 0x39, 0x59, 0x30, 0xb9, 0x01, 0x4b, 0x09, 0x8d, 0x93, 0x80, 0xf2, 0xb0, 0x5f, 0xed, 0x71,
0xa9, 0x6b, 0x39, 0x12, 0xc4, 0xac, 0xf6, 0x69, 0xe4, 0xc5, 0xdd, 0x26, 0xc6, 0x96, 0xf1, 0x37,
0xf9, 0x06, 0x5c, 0x3b, 0xa5, 0x71, 0xd2, 0x3f, 0xa7, 0xee, 0x90, 0x46, 0xc8, 0x5e, 0x3c, 0x88,
0xcd, 0x8d, 0xa1, 0x62, 0x24, 0x63, 0xdc, 0x0b, 0x1a, 0xc5, 0x5e, 0x18, 0xa0, 0x19, 0x54, 0x77,
0x64, 0x91, 0xd5, 0xc7, 0x06, 0xaf, 0x36, 0x69, 0x35, 0x83, 0x6d, 0x1c, 0x78, 0x31, 0x92, 0xdc,
0x86, 0x45, 0x1c, 0x40, 0xdc, 0xed, 0x20, 0xcf, 0x34, 0x53, 0x99, 0xf7, 0x02, 0x47, 0xe0, 0xd8,
0x2a, 0x0f, 0x42, 0x3f, 0x8c, 0xd0, 0x16, 0xaa, 0x3b, 0xbc, 0x60, 0xce, 0xce, 0x28, 0x72, 0x27,
0xe7, 0xc2, 0x1e, 0xca, 0x82, 0xbf, 0x5d, 0xa9, 0x35, 0x3a, 0x4d, 0xfb, 0xcf, 0x41, 0x15, 0xab,
0xc5, 0xea, 0x70, 0x32, 0x2d, 0x51, 0x1d, 0x42, 0xbb, 0xb0, 0x14, 0xd0, 0xe4, 0x32, 0x8c, 0x5e,
0xc9, 0x93, 0x12, 0x51, 0xb4, 0x7f, 0x8a, 0x7e, 0x93, 0x3a, 0x39, 0x78, 0x81, 0x46, 0x1f, 0xf3,
0x7e, 0xf9, 0x52, 0xc5, 0xe7, 0xae, 0x70, 0xe5, 0x6a, 0x08, 0x38, 0x3e, 0x77, 0x99, 0xae, 0x35,
0x56, 0x9f, 0x7b, 0xc7, 0x0d, 0x84, 0xed, 0xf3, 0xc5, 0xbf, 0x0d, 0x2d, 0x79, 0x26, 0x11, 0xf7,
0x7d, 0x7a, 0x96, 0xc8, 0xd8, 0x56, 0x30, 0x1d, 0xa3, 0x0b, 0x7d, 0x40, 0xcf, 0x12, 0xfb, 0x10,
0x56, 0x84, 0xfe, 0x7b, 0x3e, 0xa1, 0xb2, 0xe9, 0xdf, 0x2b, 0xb2, 0x23, 0x1a, 0x0f, 0x56, 0x4d,
0x85, 0xc9, 0x4f, 0x61, 0x4c, 0x4a, 0xdb, 0x01, 0xa2, 0xeb, 0x53, 0x51, 0xa1, 0xd8, 0xcc, 0x65,
0xf4, 0x4e, 0x0c, 0xc7, 0x80, 0xb1, 0xf9, 0x89, 0xa7, 0x83, 0x81, 0x3c, 0x49, 0xaa, 0x39, 0xb2,
0x68, 0xff, 0x73, 0x0b, 0x56, 0xb1, 0x36, 0x69, 0x09, 0x89, 0x3d, 0xeb, 0xe1, 0x3b, 0x74, 0xb3,
0x39, 0xd0, 0x23, 0x9a, 0x6b, 0x50, 0xd5, 0x77, 0x31, 0x5e, 0x78, 0xf7, 0x48, 0x49, 0x25, 0x1b,
0x29, 0xb1, 0xff, 0xbe, 0x05, 0x2b, 0x7c, 0x23, 0x41, 0x3b, 0x58, 0x0c, 0xff, 0xf7, 0x61, 0x99,
0x5b, 0x04, 0x42, 0x2b, 0x88, 0x8e, 0xa6, 0xaa, 0x15, 0xa1, 0x9c, 0x78, 0x7f, 0xc1, 0x31, 0x89,
0xc9, 0x23, 0xb4, 0xca, 0x82, 0x3e, 0x42, 0x0b, 0xce, 0x1c, 0xcd, 0xb9, 0xde, 0x5f, 0x70, 0x34,
0xf2, 0xc7, 0x35, 0x58, 0xe4, 0x4e, 0x84, 0xfd, 0x14, 0x96, 0x8d, 0x86, 0x8c, 0x28, 0x4d, 0x93,
0x47, 0x69, 0x72, 0xe1, 0xd0, 0x52, 0x41, 0x38, 0xf4, 0x5f, 0x97, 0x81, 0x30, 0x66, 0xc9, 0xac,
0x06, 0xf3, 0x62, 0xc2, 0xa1, 0xe1, 0x93, 0x36, 0x1d, 0x1d, 0x44, 0x36, 0x81, 0x68, 0x45, 0x19,
0xb1, 0xe6, 0x5b, 0x66, 0x01, 0x86, 0xa9, 0x59, 0x61, 0x71, 0x08, 0xdb, 0x40, 0x78, 0xdf, 0x7c,
0xda, 0x0b, 0x71, 0x6c, 0x57, 0x9c, 0x4c, 0xe3, 0x73, 0xf4, 0x15, 0x84, 0xd7, 0x2a, 0xcb, 0xd9,
0xf5, 0x5d, 0xbc, 0x72, 0x7d, 0x97, 0x72, 0x91, 0x30, 0xcd, 0x6f, 0xaa, 0x99, 0x7e, 0xd3, 0x6d,
0x58, 0x1e, 0x33, 0x3b, 0x39, 0xf1, 0x07, 0xfd, 0x31, 0x6b, 0x5d, 0x38, 0xa9, 0x06, 0x90, 0xdc,
0x83, 0x8e, 0x74, 0x5d, 0x94, 0x73, 0xc6, 0xcf, 0x51, 0x72, 0x70, 0xa6, 0xff, 0xd3, 0xd8, 0x58,
0x03, 0x3b, 0x9b, 0x02, 0x98, 0x27, 0x16, 0x33, 0x0e, 0xe9, 0x4f, 0x03, 0x71, 0xec, 0x48, 0x87,
0xe8, 0x9e, 0xd6, 0x9c, 0x3c, 0xc2, 0xfe, 0xdb, 0x16, 0x74, 0xd8, 0x9a, 0x19, 0x6c, 0xf9, 0x19,
0xa0, 0x54, 0xbc, 0x25, 0x57, 0x1a, 0xb4, 0xe4, 0x21, 0xd4, 0xb1, 0x1c, 0x4e, 0x68, 0x20, 0x78,
0xb2, 0x6b, 0xf2, 0x64, 0xaa, 0x4f, 0xf6, 0x17, 0x9c, 0x94, 0x58, 0xe3, 0xc8, 0xff, 0x6c, 0x41,
0x43, 0xb4, 0xf2, 0x6b, 0xc7, 0x5e, 0x7a, 0xda, 0x39, 0x31, 0xe7, 0xa4, 0xf4, 0x58, 0xf8, 0x2e,
0xb4, 0xc7, 0x6e, 0x32, 0x8d, 0xd8, 0x7e, 0x6e, 0xc4, 0x5d, 0xb2, 0x60, 0xb6, 0x39, 0xa3, 0xea,
0x8c, 0xfb, 0x89, 0xe7, 0xf7, 0x25, 0x56, 0x9c, 0xc8, 0x16, 0xa1, 0x98, 0x06, 0x89, 0x13, 0x77,
0x44, 0xc5, 0xbe, 0xcb, 0x0b, 0x76, 0x17, 0xd6, 0xc5, 0x80, 0x32, 0xf6, 0xb5, 0xfd, 0x2f, 0x97,
0x61, 0x23, 0x87, 0x52, 0xf9, 0x23, 0x22, 0xa0, 0xe0, 0x7b, 0xe3, 0xd3, 0x50, 0x39, 0x27, 0x96,
0x1e, 0x6b, 0x30, 0x50, 0x64, 0x04, 0xd7, 0xa4, 0x81, 0xc1, 0xe6, 0x34, 0xdd, 0x0c, 0x4b, 0xb8,
0xcb, 0x7d, 0x62, 0x2e, 0x61, 0xb6, 0x41, 0x09, 0xd7, 0x85, 0xb8, 0xb8, 0x3e, 0x72, 0x0e, 0x5d,
0x65, 0xc9, 0x08, 0x65, 0xad, 0x59, 0x3b, 0xac, 0xad, 0x8f, 0xaf, 0x68, 0xcb, 0x30, 0xc7, 0x9d,
0xb9, 0xb5, 0x91, 0x19, 0xdc, 0x94, 0x38, 0xd4, 0xc6, 0xf9, 0xf6, 0x2a, 0x6f, 0x35, 0x36, 0x74,
0x34, 0xcc, 0x46, 0xaf, 0xa8, 0x98, 0xfc, 0x18, 0xd6, 0x2f, 0x5d, 0x2f, 0x91, 0xdd, 0xd2, 0x6c,
0x8b, 0x2a, 0x36, 0xf9, 0xe0, 0x8a, 0x26, 0x5f, 0xf2, 0x8f, 0x8d, 0x2d, 0x6a, 0x4e, 0x8d, 0xbd,
0x5f, 0x96, 0xa0, 0x65, 0xd6, 0xc3, 0xd8, 0x54, 0xc8, 0xbe, 0xd4, 0x81, 0xd2, 0x1a, 0xcd, 0x80,
0xf3, 0xfe, 0x7d, 0xa9, 0xc8, 0xbf, 0xd7, 0xbd, 0xea, 0xf2, 0x55, 0x81, 0xbb, 0xca, 0xdb, 0x05,
0xee, 0xaa, 0x85, 0x81, 0xbb, 0xf9, 0xf1, 0x9d, 0xc5, 0x5f, 0x37, 0xbe, 0xb3, 0xf4, 0xc6, 0xf8,
0x4e, 0xef, 0xff, 0x5a, 0x40, 0xf2, 0xdc, 0x4b, 0x9e, 0xf2, 0x90, 0x46, 0x40, 0x7d, 0xa1, 0xc4,
0x7e, 0xf7, 0xed, 0x24, 0x40, 0xae, 0x96, 0xfc, 0x9a, 0x89, 0xa2, 0x9e, 0xc4, 0xa1, 0x9b, 0x57,
0xcb, 0x4e, 0x11, 0x2a, 0x13, 0xbc, 0xac, 0x5c, 0x1d, 0xbc, 0xac, 0x5e, 0x1d, 0xbc, 0x5c, 0xcc,
0x06, 0x2f, 0x7b, 0x7f, 0xcd, 0x82, 0xd5, 0x02, 0x36, 0xfb, 0xed, 0x0d, 0x9c, 0x31, 0x86, 0xa1,
0x7d, 0x4a, 0x82, 0x31, 0x74, 0x60, 0xef, 0x2f, 0xc3, 0xb2, 0x21, 0x5a, 0xbf, 0xbd, 0xf6, 0xb3,
0x16, 0x22, 0xe7, 0x6c, 0x03, 0xd6, 0xfb, 0xdf, 0x25, 0x20, 0x79, 0xf1, 0xfe, 0x33, 0xed, 0x43,
0x7e, 0x9e, 0xca, 0x05, 0xf3, 0xf4, 0xff, 0x75, 0xe7, 0xf9, 0x18, 0x56, 0x44, 0x66, 0x9a, 0x16,
0xc8, 0xe2, 0x1c, 0x93, 0x47, 0x30, 0x1b, 0xd9, 0x8c, 0x1c, 0xd7, 0x8c, 0x4c, 0x1c, 0x6d, 0xfb,
0xcd, 0x04, 0x90, 0xed, 0x1e, 0x74, 0xc5, 0x0c, 0xed, 0x5d, 0xd0, 0x20, 0x39, 0x9e, 0x9e, 0xf2,
0xd4, 0x2c, 0x2f, 0x0c, 0xec, 0x7f, 0x53, 0x56, 0x66, 0x3e, 0x22, 0x85, 0x41, 0xf1, 0x0d, 0x68,
0xea, 0xdb, 0x87, 0x58, 0x8e, 0x4c, 0x1c, 0x93, 0x99, 0x12, 0x3a, 0x15, 0xd9, 0x85, 0x16, 0x2a,
0xc9, 0xa1, 0xfa, 0xae, 0x84, 0xdf, 0xbd, 0x21, 0x3e, 0xb3, 0xbf, 0xe0, 0x64, 0xbe, 0x21, 0xdf,
0x82, 0x96, 0xe9, 0xfc, 0x09, 0xab, 0xa4, 0xc8, 0x1b, 0x60, 0x9f, 0x9b, 0xc4, 0x64, 0x1b, 0x3a,
0x59, 0xef, 0x51, 0x64, 0x4a, 0xcc, 0xa9, 0x20, 0x47, 0x4e, 0x1e, 0x8a, 0x23, 0xc4, 0x2a, 0xc6,
0x4d, 0x6e, 0x9b, 0x9f, 0x69, 0xd3, 0xb4, 0xc9, 0xff, 0x68, 0x87, 0x8a, 0x7f, 0x08, 0x90, 0xc2,
0x48, 0x07, 0x9a, 0xcf, 0x8f, 0xf6, 0x0e, 0xfb, 0x3b, 0xfb, 0xdb, 0x87, 0x87, 0x7b, 0x07, 0x9d,
0x05, 0x42, 0xa0, 0x85, 0x61, 0xbe, 0x5d, 0x05, 0xb3, 0x18, 0x4c, 0x04, 0x56, 0x24, 0xac, 0x44,
0xd6, 0xa0, 0xf3, 0xec, 0x30, 0x03, 0x2d, 0x3f, 0xae, 0x2b, 0xf9, 0xb0, 0xd7, 0x61, 0x8d, 0x67,
0x1e, 0x3e, 0xe6, 0xec, 0x21, 0xad, 0x93, 0x7f, 0x6c, 0xc1, 0xb5, 0x0c, 0x22, 0x4d, 0xa5, 0xe1,
0x06, 0x88, 0x69, 0x95, 0x98, 0x40, 0x3c, 0x16, 0x90, 0xb6, 0x66, 0x46, 0x83, 0xe4, 0x11, 0x8c,
0xe7, 0x35, 0xdb, 0x34, 0x23, 0x49, 0x45, 0x28, 0x7b, 0x83, 0xe7, 0x47, 0x62, 0x26, 0xa5, 0xd1,
0xf1, 0x33, 0x9e, 0xd1, 0xa8, 0x23, 0xd2, 0x23, 0x59, 0xb3, 0xcb, 0xb2, 0xc8, 0xdc, 0x0a, 0xc3,
0xd8, 0x31, 0xfb, 0x5b, 0x88, 0xb3, 0xff, 0xa8, 0x02, 0xe4, 0xbb, 0x53, 0x1a, 0xcd, 0x30, 0x5f,
0x46, 0x45, 0x4d, 0x37, 0xb2, 0x31, 0xc1, 0xc5, 0xc9, 0xf4, 0xf4, 0x3b, 0x74, 0x26, 0x33, 0xc7,
0x4a, 0x69, 0xe6, 0x58, 0x51, 0xf6, 0x56, 0xe5, 0xea, 0xec, 0xad, 0xea, 0x55, 0xd9, 0x5b, 0x5f,
0x81, 0x65, 0x6f, 0x14, 0x84, 0x4c, 0xe6, 0x99, 0x9d, 0x10, 0x77, 0x17, 0x6f, 0x95, 0x99, 0x6f,
0x2d, 0x80, 0x87, 0x0c, 0x46, 0x1e, 0xa5, 0x44, 0x74, 0x38, 0xc2, 0x4c, 0x41, 0x5d, 0x0b, 0xec,
0x0d, 0x47, 0xf4, 0x20, 0x1c, 0xb8, 0x49, 0x18, 0x61, 0x60, 0x47, 0x7e, 0xcc, 0xe0, 0x31, 0xb9,
0x0d, 0xad, 0x38, 0x9c, 0x32, 0xcb, 0x49, 0x8e, 0x95, 0x47, 0x92, 0x9a, 0x1c, 0x7a, 0xc4, 0x47,
0xbc, 0x09, 0xab, 0xd3, 0x98, 0xf6, 0xc7, 0x5e, 0x1c, 0xb3, 0xdd, 0x71, 0x10, 0x06, 0x49, 0x14,
0xfa, 0x22, 0x9e, 0xb4, 0x32, 0x8d, 0xe9, 0xe7, 0x1c, 0xb3, 0xc3, 0x11, 0xe4, 0x1b, 0x69, 0x97,
0x26, 0xae, 0x17, 0xc5, 0x5d, 0xc0, 0x2e, 0xc9, 0x91, 0xb2, 0x7e, 0x1f, 0xb9, 0x5e, 0xa4, 0xfa,
0xc2, 0x0a, 0x31, 0xd9, 0xce, 0xa5, 0x98, 0xc9, 0x98, 0x7c, 0x7e, 0x75, 0x7e, 0xfb, 0x99, 0x66,
0x22, 0x41, 0x6a, 0x13, 0x6a, 0xb2, 0x7b, 0xcc, 0x89, 0x3e, 0x8b, 0xc2, 0xb1, 0x74, 0xa2, 0xd9,
0x6f, 0xd2, 0x82, 0x52, 0x12, 0x8a, 0x8f, 0x4b, 0x49, 0x68, 0x7f, 0x1f, 0x1a, 0xda, 0x0c, 0x63,
0x16, 0x9d, 0x30, 0xd8, 0x84, 0xf7, 0x5d, 0xe1, 0xfe, 0x51, 0x40, 0xfd, 0x67, 0x43, 0xf2, 0x35,
0x58, 0x19, 0x7a, 0x11, 0xc5, 0x84, 0xc8, 0x7e, 0x44, 0x2f, 0x68, 0x14, 0xcb, 0x38, 0x45, 0x47,
0x21, 0x1c, 0x0e, 0xb7, 0x1f, 0xc1, 0xaa, 0x31, 0x70, 0x25, 0xb5, 0x8b, 0x98, 0xd1, 0x25, 0x43,
0xa5, 0x66, 0xb6, 0x97, 0xc0, 0xd9, 0xff, 0xac, 0x0c, 0xe5, 0xfd, 0x70, 0xa2, 0x1f, 0x08, 0x59,
0xe6, 0x81, 0x90, 0x30, 0x38, 0xfb, 0xca, 0x9e, 0x14, 0x56, 0x81, 0x01, 0x24, 0xf7, 0xa0, 0xe5,
0x8e, 0x93, 0x7e, 0x12, 0x32, 0x03, 0xfb, 0xd2, 0x8d, 0x86, 0x5c, 0x94, 0x91, 0x95, 0x32, 0x18,
0xb2, 0x06, 0x65, 0x65, 0x27, 0x21, 0x01, 0x2b, 0x32, 0xef, 0x0e, 0x8f, 0xc2, 0x67, 0x22, 0xce,
0x29, 0x4a, 0x4c, 0x53, 0x98, 0xdf, 0x73, 0xd7, 0x9a, 0xef, 0x76, 0x45, 0x28, 0x66, 0xfc, 0x32,
0xe1, 0x19, 0xa7, 0xb6, 0xa4, 0x2a, 0xeb, 0x11, 0xfc, 0x9a, 0x19, 0xc1, 0xbf, 0x05, 0x8d, 0xc4,
0xbf, 0xe8, 0x4f, 0xdc, 0x99, 0x1f, 0xba, 0x43, 0xc1, 0xb4, 0x3a, 0x88, 0xfc, 0x3e, 0xa7, 0x60,
0x1b, 0x6c, 0x34, 0x94, 0xcc, 0x2a, 0x77, 0xa8, 0xfd, 0x70, 0xb2, 0x79, 0xe2, 0x5f, 0x38, 0x1c,
0xc9, 0xf9, 0x4d, 0x27, 0xef, 0x7d, 0x0b, 0xda, 0x19, 0xfc, 0x3b, 0x25, 0x38, 0xfe, 0xca, 0x82,
0x2a, 0x2e, 0x1d, 0x33, 0x2c, 0xb8, 0xe6, 0x55, 0x47, 0x56, 0x58, 0xc3, 0xb2, 0x93, 0x05, 0x13,
0xdb, 0xc8, 0x0c, 0x2e, 0xa9, 0xf9, 0xd6, 0xb3, 0x83, 0x6f, 0x41, 0x9d, 0x97, 0x54, 0x96, 0x2b,
0x92, 0xa4, 0x40, 0x72, 0x13, 0x2a, 0xe7, 0xe1, 0x44, 0xfa, 0x5e, 0x90, 0x8e, 0xd7, 0x41, 0x78,
0xda, 0x1f, 0x56, 0x1f, 0x9f, 0x75, 0x6e, 0xdf, 0x66, 0xc1, 0xcc, 0xa7, 0x50, 0xd5, 0xea, 0xab,
0x98, 0x81, 0xda, 0x2f, 0xa0, 0xcd, 0x84, 0x4b, 0x0b, 0xe1, 0xcf, 0xd7, 0xb2, 0x5f, 0x65, 0x9b,
0xf6, 0xc0, 0x9f, 0x0e, 0xa9, 0xee, 0x01, 0x63, 0x88, 0x56, 0xc0, 0xa5, 0xed, 0x67, 0xff, 0x2b,
0x8b, 0x0b, 0x2d, 0xab, 0x97, 0xdc, 0x85, 0x0a, 0xd3, 0x95, 0x99, 0x80, 0x87, 0x4a, 0x49, 0x61,
0x74, 0x0e, 0x52, 0x30, 0x93, 0x10, 0x83, 0xa8, 0x7a, 0xed, 0x3c, 0x84, 0x9a, 0xba, 0x8f, 0x6a,
0x64, 0x19, 0xaf, 0x2b, 0x03, 0x25, 0x9b, 0xda, 0x09, 0x54, 0xc5, 0xd0, 0xbf, 0xd2, 0x46, 0x18,
0x8e, 0xa8, 0x76, 0xf2, 0xf4, 0xc7, 0x16, 0x2c, 0x1b, 0x7d, 0x62, 0x6c, 0xea, 0xbb, 0x71, 0x22,
0xd2, 0x02, 0xc4, 0xca, 0xeb, 0x20, 0x9d, 0xc5, 0x4b, 0x26, 0x8b, 0xab, 0x93, 0x8c, 0xb2, 0x7e,
0x92, 0x71, 0x1f, 0xea, 0x69, 0x6a, 0xb8, 0xd9, 0x29, 0xd6, 0xa2, 0x4c, 0xce, 0x49, 0x89, 0xd2,
0x58, 0x79, 0x55, 0x8b, 0x95, 0xdb, 0x8f, 0xa0, 0xa1, 0xd1, 0xeb, 0xb1, 0x6e, 0xcb, 0x88, 0x75,
0xab, 0xcc, 0xb5, 0x52, 0x9a, 0xb9, 0x66, 0xff, 0xac, 0x04, 0xcb, 0x8c, 0xbd, 0xbd, 0x60, 0x74,
0x14, 0xfa, 0xde, 0x60, 0x86, 0x6c, 0x25, 0x39, 0x59, 0xec, 0x95, 0x92, 0xcd, 0x4d, 0x30, 0x93,
0x77, 0x19, 0x61, 0x13, 0xca, 0x49, 0x95, 0x99, 0xf6, 0x62, 0xb2, 0x7f, 0xea, 0xc6, 0x42, 0x21,
0x08, 0x5b, 0xdd, 0x00, 0x32, 0x1d, 0xc3, 0x00, 0x98, 0x87, 0x38, 0xf6, 0x7c, 0xdf, 0xe3, 0xb4,
0xdc, 0x93, 0x2b, 0x42, 0xb1, 0x36, 0x87, 0x5e, 0xec, 0x9e, 0xa6, 0xa7, 0x94, 0xaa, 0x8c, 0x61,
0x40, 0xf7, 0xb5, 0x16, 0x06, 0x5c, 0x44, 0x01, 0x37, 0x81, 0xd9, 0x85, 0x5c, 0xca, 0x2d, 0xa4,
0xfd, 0x1f, 0x4a, 0xd0, 0xd0, 0xd8, 0x42, 0x1c, 0xcd, 0x9b, 0x9b, 0x86, 0x06, 0x91, 0x78, 0x23,
0x2e, 0xa0, 0x41, 0xc8, 0x6d, 0xb3, 0x45, 0x3c, 0x0a, 0x40, 0x61, 0x37, 0xd8, 0xe7, 0x06, 0xd4,
0x19, 0xdb, 0x7f, 0x82, 0x41, 0x08, 0x71, 0x27, 0x43, 0x01, 0x24, 0xf6, 0x01, 0x62, 0xab, 0x29,
0x16, 0x01, 0x6f, 0x3c, 0xcc, 0x7f, 0x08, 0x4d, 0x51, 0x0d, 0xae, 0x2f, 0x0e, 0x38, 0x15, 0x3c,
0x63, 0xed, 0x1d, 0x83, 0x52, 0x7e, 0xf9, 0x40, 0x7e, 0x59, 0xbb, 0xea, 0x4b, 0x49, 0x69, 0x3f,
0x55, 0x39, 0x12, 0x4f, 0x23, 0x77, 0x72, 0x2e, 0x95, 0xc9, 0x7d, 0x58, 0x95, 0x3a, 0x63, 0x1a,
0xb8, 0x41, 0x10, 0x4e, 0x83, 0x01, 0x95, 0x09, 0x6e, 0x45, 0x28, 0x7b, 0xa8, 0xd2, 0xa1, 0xb1,
0x22, 0x72, 0x0f, 0xaa, 0xdc, 0xd2, 0xe2, 0x7b, 0x6b, 0xb1, 0xfa, 0xe0, 0x24, 0xe4, 0x2e, 0x54,
0xb9, 0xc1, 0x55, 0x9a, 0x2b, 0xf0, 0x9c, 0xc0, 0xbe, 0x07, 0x6d, 0xcc, 0xb2, 0x37, 0xf5, 0x9e,
0xb9, 0x2f, 0x2f, 0x0e, 0x30, 0x0f, 0xdf, 0x5e, 0x03, 0x72, 0xc8, 0xe5, 0x49, 0x3f, 0xe9, 0xfc,
0x55, 0x19, 0x1a, 0x1a, 0x98, 0xe9, 0x25, 0x3c, 0x9e, 0xea, 0x0f, 0x3d, 0x77, 0x4c, 0x13, 0x1a,
0x09, 0x19, 0xca, 0x40, 0x19, 0x9d, 0x7b, 0x31, 0xea, 0x87, 0xd3, 0xa4, 0x3f, 0xa4, 0xa3, 0x88,
0xf2, 0x0d, 0x88, 0x6d, 0xdd, 0x06, 0x94, 0xd1, 0x31, 0x2e, 0xd6, 0xe8, 0xf8, 0x81, 0x52, 0x06,
0x2a, 0xcf, 0x2d, 0xf9, 0x1c, 0x55, 0xd2, 0x73, 0x4b, 0x3e, 0x23, 0x59, 0x8d, 0x5a, 0x2d, 0xd0,
0xa8, 0x9f, 0xc2, 0x3a, 0xd7, 0x9d, 0x42, 0x6b, 0xf4, 0x33, 0x8c, 0x35, 0x07, 0x4b, 0xee, 0x41,
0x87, 0xf5, 0x59, 0x8a, 0x45, 0xec, 0xfd, 0x94, 0xcb, 0x96, 0xe5, 0xe4, 0xe0, 0x8c, 0x16, 0x83,
0xe9, 0x3a, 0x2d, 0x4f, 0x1e, 0xc9, 0xc1, 0x91, 0xd6, 0x7d, 0x6d, 0xd2, 0xd6, 0x05, 0x6d, 0x06,
0x4e, 0x1e, 0xc2, 0xc6, 0x98, 0x0e, 0x3d, 0xd7, 0xac, 0x02, 0x63, 0x5b, 0x3c, 0x27, 0x6d, 0x1e,
0x9a, 0xb5, 0xc2, 0x66, 0xe1, 0xa7, 0xe1, 0xf8, 0xd4, 0xe3, 0x1b, 0x1a, 0x0f, 0xfb, 0x57, 0x9c,
0x1c, 0xdc, 0x5e, 0x86, 0xc6, 0x71, 0x12, 0x4e, 0xe4, 0xd2, 0xb7, 0xa0, 0xc9, 0x8b, 0x22, 0x9d,
0xf1, 0x3d, 0xb8, 0x8e, 0xbc, 0x7a, 0x12, 0x4e, 0x42, 0x3f, 0x1c, 0xcd, 0x0c, 0xe7, 0xfd, 0x3f,
0x59, 0xb0, 0x6a, 0x60, 0x53, 0xef, 0x1d, 0x23, 0x8d, 0x32, 0x0f, 0x8d, 0xb3, 0xf7, 0x8a, 0xb6,
0x1d, 0x70, 0x42, 0x7e, 0xa8, 0xf3, 0x42, 0xa4, 0xa6, 0x6d, 0xa7, 0xd7, 0xe2, 0xe4, 0x87, 0x9c,
0xd7, 0xbb, 0x79, 0x5e, 0x17, 0xdf, 0xcb, 0x5b, 0x71, 0xb2, 0x8a, 0x6f, 0x89, 0x54, 0x9f, 0xa1,
0x18, 0x74, 0xd9, 0x4c, 0xcf, 0xd0, 0x83, 0x3d, 0xb2, 0x07, 0x03, 0x05, 0x8c, 0xed, 0x9f, 0x5b,
0x00, 0x69, 0xef, 0x30, 0x41, 0x44, 0x6d, 0x69, 0xfc, 0x0a, 0xa6, 0xb6, 0x7d, 0x7d, 0x08, 0x4d,
0x75, 0xc6, 0x9f, 0xee, 0x92, 0x0d, 0x09, 0x63, 0x56, 0xc5, 0x1d, 0x68, 0x8f, 0xfc, 0xf0, 0x14,
0xad, 0x17, 0xcc, 0x8f, 0x8d, 0x45, 0x52, 0x67, 0x8b, 0x83, 0x9f, 0x08, 0x68, 0xba, 0xa5, 0x56,
0xf4, 0x2d, 0xb5, 0x78, 0x83, 0xfc, 0x9b, 0x25, 0x75, 0xd0, 0x9a, 0xce, 0xc4, 0x5c, 0x09, 0x27,
0x0f, 0x72, 0xea, 0x7c, 0xce, 0xb9, 0x26, 0x3a, 0x0e, 0x47, 0x57, 0xc6, 0x7d, 0x1f, 0x41, 0x2b,
0xe2, 0xba, 0x52, 0x2a, 0xd2, 0xca, 0x1b, 0x14, 0xe9, 0x72, 0x64, 0xec, 0xc6, 0x5f, 0x85, 0x8e,
0x3b, 0xbc, 0xa0, 0x51, 0xe2, 0x61, 0x1c, 0x0c, 0x4d, 0x27, 0x3e, 0xb8, 0xb6, 0x06, 0x47, 0x0b,
0xe5, 0x0e, 0xb4, 0x45, 0x7a, 0xad, 0xa2, 0x14, 0x97, 0x99, 0x52, 0x30, 0x23, 0xb4, 0x7f, 0x21,
0xcf, 0x74, 0xcd, 0x95, 0x9d, 0x3f, 0x23, 0xfa, 0xe8, 0x4a, 0x99, 0xd1, 0x7d, 0x45, 0x9c, 0xaf,
0x0e, 0x65, 0xb0, 0xad, 0xac, 0x25, 0x8b, 0x0d, 0xc5, 0x79, 0xb8, 0x39, 0xa5, 0x95, 0xb7, 0x99,
0x52, 0xfb, 0x4f, 0x2c, 0x58, 0xda, 0x0f, 0x27, 0xfb, 0x22, 0x6d, 0x0e, 0xc5, 0x43, 0xe5, 0xb5,
0xcb, 0xe2, 0x1b, 0x12, 0xea, 0x0a, 0x2d, 0x90, 0xe5, 0xac, 0x05, 0xf2, 0x17, 0xe0, 0x3d, 0x0c,
0xf5, 0x46, 0xe1, 0x24, 0x8c, 0x98, 0x88, 0xba, 0x3e, 0x37, 0x37, 0xc2, 0x20, 0x39, 0x97, 0x2a,
0xf4, 0x4d, 0x24, 0x18, 0x7f, 0xf1, 0x93, 0x8b, 0x3e, 0x77, 0x9b, 0x84, 0xc5, 0xc4, 0x35, 0x6b,
0x1e, 0x61, 0xff, 0x1e, 0xd4, 0xd1, 0x9b, 0xc0, 0x61, 0x7d, 0x0c, 0xf5, 0xf3, 0x70, 0xd2, 0x3f,
0xf7, 0x82, 0x44, 0x8a, 0x7c, 0x2b, 0x35, 0xf3, 0xf7, 0x71, 0x42, 0x14, 0x81, 0xfd, 0x77, 0x17,
0x61, 0xe9, 0x59, 0x70, 0x11, 0x7a, 0x03, 0x3c, 0x3f, 0x1e, 0xd3, 0x71, 0x28, 0xb3, 0xfc, 0xd9,
0x6f, 0x72, 0x03, 0x96, 0x30, 0xad, 0x75, 0xc2, 0x99, 0xb6, 0xc9, 0xf3, 0x44, 0x04, 0x08, 0x6f,
0x19, 0xa6, 0x77, 0xad, 0xb8, 0x50, 0x69, 0x10, 0xe6, 0x06, 0x46, 0xfa, 0x5d, 0x29, 0x51, 0x4a,
0x3d, 0xa3, 0xaa, 0x76, 0x8b, 0x82, 0xb5, 0x25, 0xd2, 0xfc, 0x78, 0x1e, 0x18, 0x6f, 0x4b, 0x80,
0xd0, 0x75, 0x8d, 0x28, 0x0f, 0xd5, 0x2b, 0x23, 0x8b, 0xb9, 0xae, 0x3a, 0x90, 0x19, 0x62, 0xfc,
0x03, 0x4e, 0xc3, 0x37, 0x00, 0x1d, 0xc4, 0x4c, 0xd1, 0xec, 0xf5, 0x3c, 0x7e, 0x3d, 0x32, 0x0b,
0x66, 0xfa, 0x7b, 0x48, 0x95, 0x9a, 0xe5, 0xe3, 0x00, 0x7e, 0x9f, 0x2c, 0x0b, 0xd7, 0x1c, 0x5e,
0x9e, 0x81, 0x2c, 0x1d, 0x5e, 0xc6, 0x30, 0xae, 0xef, 0x9f, 0xba, 0x83, 0x57, 0x78, 0x3b, 0x13,
0x4f, 0x74, 0xeb, 0x8e, 0x09, 0xc4, 0x64, 0xbd, 0x74, 0x55, 0x31, 0xa3, 0xa6, 0xe2, 0xe8, 0x20,
0xf2, 0x00, 0x1a, 0xe8, 0xe4, 0x8b, 0x75, 0x6d, 0xe1, 0xba, 0x76, 0xf4, 0x28, 0x00, 0xae, 0xac,
0x4e, 0xa4, 0x9f, 0x6d, 0xb7, 0x73, 0x39, 0xc1, 0xee, 0x70, 0x28, 0x52, 0x02, 0x3a, 0x3c, 0x60,
0xa1, 0x00, 0x6c, 0x47, 0x17, 0x13, 0xc6, 0x09, 0x56, 0x90, 0xc0, 0x80, 0x91, 0x9b, 0x50, 0x63,
0x1e, 0xde, 0xc4, 0xf5, 0x86, 0x98, 0x44, 0xc3, 0x1d, 0x4d, 0x05, 0x63, 0x75, 0xc8, 0xdf, 0xb8,
0x55, 0xae, 0xe2, 0xac, 0x18, 0x30, 0x36, 0x37, 0xaa, 0x3c, 0x4e, 0x93, 0x88, 0x4d, 0x20, 0xf9,
0x04, 0x0f, 0x66, 0x13, 0x8a, 0x99, 0xc2, 0xad, 0x07, 0xef, 0x89, 0x31, 0x0b, 0xa6, 0x95, 0x7f,
0x8f, 0x19, 0x89, 0xc3, 0x29, 0xed, 0x6d, 0x68, 0xea, 0x60, 0x52, 0x83, 0xca, 0xf3, 0xa3, 0xbd,
0xc3, 0xce, 0x02, 0x69, 0xc0, 0xd2, 0xf1, 0xde, 0xc9, 0xc9, 0xc1, 0xde, 0x6e, 0xc7, 0x22, 0x4d,
0xa8, 0xa9, 0xcc, 0xca, 0x12, 0x2b, 0x6d, 0xef, 0xec, 0xec, 0x1d, 0x9d, 0xec, 0xed, 0x76, 0xca,
0x76, 0x02, 0x64, 0x7b, 0x38, 0x14, 0xb5, 0xa8, 0x30, 0x4c, 0xca, 0xcf, 0x96, 0xc1, 0xcf, 0x05,
0x3c, 0x55, 0x2a, 0xe6, 0xa9, 0x37, 0xce, 0xbc, 0xbd, 0x07, 0x8d, 0x23, 0xed, 0x4a, 0x20, 0x8a,
0x97, 0xbc, 0x0c, 0x28, 0xc4, 0x52, 0x83, 0x68, 0xdd, 0x29, 0xe9, 0xdd, 0xb1, 0xff, 0xa9, 0xc5,
0xef, 0xe6, 0xa8, 0xee, 0xf3, 0xb6, 0x6d, 0x68, 0xaa, 0x58, 0x68, 0x9a, 0x34, 0x6d, 0xc0, 0x18,
0x0d, 0x76, 0xa5, 0x1f, 0x9e, 0x9d, 0xc5, 0x54, 0xa6, 0x38, 0x1a, 0x30, 0x69, 0xd7, 0x30, 0x4b,
0xc9, 0xe3, 0x2d, 0xc4, 0x22, 0xd5, 0x31, 0x07, 0x67, 0x5a, 0x5e, 0x84, 0xbc, 0x64, 0x72, 0xa7,
0x2a, 0xab, 0xdc, 0xee, 0xec, 0x2c, 0xdf, 0x83, 0x9a, 0xaa, 0xd7, 0x54, 0x60, 0x92, 0x52, 0xe1,
0x99, 0xa2, 0x44, 0x7f, 0xc7, 0xe8, 0x34, 0x57, 0xda, 0x79, 0x04, 0xd9, 0x04, 0x72, 0xe6, 0x45,
0x59, 0xf2, 0x32, 0x92, 0x17, 0x60, 0xec, 0x97, 0xb0, 0x2a, 0x19, 0x49, 0x33, 0xb8, 0xcc, 0x45,
0xb4, 0xae, 0x12, 0x9f, 0x52, 0x5e, 0x7c, 0xec, 0x3f, 0x2d, 0xc3, 0x92, 0x58, 0xe9, 0xdc, 0xb5,
0x52, 0xbe, 0xce, 0x06, 0x8c, 0x74, 0x8d, 0x6b, 0x67, 0x28, 0x6b, 0x42, 0x69, 0xe6, 0xd4, 0x62,
0xb9, 0x48, 0x2d, 0x12, 0xa8, 0x4c, 0xdc, 0xe4, 0x1c, 0x23, 0x02, 0x75, 0x07, 0x7f, 0xcb, 0xc8,
0x5d, 0xd5, 0x8c, 0xdc, 0x15, 0x5d, 0xa2, 0xe5, 0x3b, 0x7e, 0xfe, 0x12, 0xed, 0x0d, 0xa8, 0x63,
0x27, 0xb4, 0x83, 0xde, 0x14, 0xc0, 0xb8, 0x97, 0x17, 0x50, 0xb6, 0xc5, 0x2d, 0x90, 0x14, 0xf2,
0x0e, 0x8a, 0xf8, 0x1b, 0xb0, 0xc8, 0xaf, 0x21, 0x88, 0x14, 0xd6, 0x1b, 0xf2, 0xb0, 0x8b, 0xd3,
0xc9, 0xbf, 0x3c, 0x17, 0xc6, 0x11, 0xb4, 0xfa, 0x25, 0xc6, 0x86, 0x79, 0x89, 0x51, 0x8f, 0x29,
0x36, 0xcd, 0x98, 0xa2, 0xfd, 0x04, 0x96, 0x8d, 0xea, 0x98, 0xca, 0x10, 0x29, 0xb0, 0x9d, 0x05,
0xb2, 0x0c, 0xf5, 0x67, 0x87, 0xfd, 0x27, 0x07, 0xcf, 0x9e, 0xee, 0x9f, 0x74, 0x2c, 0x56, 0x3c,
0x7e, 0xb1, 0xb3, 0xb3, 0xb7, 0xb7, 0x8b, 0x2a, 0x04, 0x60, 0xf1, 0xc9, 0xf6, 0xb3, 0x03, 0x54,
0x20, 0xbb, 0x9c, 0xb7, 0x45, 0x5d, 0xea, 0x80, 0xe1, 0x77, 0x81, 0x48, 0x97, 0x14, 0x53, 0x61,
0x26, 0x3e, 0x4d, 0x64, 0x76, 0xf6, 0x8a, 0xc0, 0x3c, 0x53, 0x08, 0x79, 0xb9, 0x20, 0xad, 0x25,
0x15, 0x11, 0x31, 0x49, 0x59, 0x11, 0x11, 0xa4, 0x8e, 0xc2, 0xdb, 0x3d, 0xe8, 0xee, 0x52, 0x56,
0xdb, 0xb6, 0xef, 0x67, 0xba, 0xc3, 0xfc, 0x8a, 0x02, 0x9c, 0x70, 0x3a, 0xbe, 0x0b, 0xd7, 0xb6,
0x79, 0x22, 0xf6, 0x6f, 0x2b, 0x4f, 0xcf, 0xee, 0xc2, 0x7a, 0xb6, 0x4a, 0xd1, 0xd8, 0x13, 0x58,
0xd9, 0xa5, 0xa7, 0xd3, 0xd1, 0x01, 0xbd, 0x48, 0x1b, 0x22, 0x50, 0x89, 0xcf, 0xc3, 0x4b, 0x31,
0x3f, 0xf8, 0x9b, 0xbc, 0x0f, 0xe0, 0x33, 0x9a, 0x7e, 0x3c, 0xa1, 0x03, 0x79, 0xf5, 0x0d, 0x21,
0xc7, 0x13, 0x3a, 0xb0, 0x3f, 0x05, 0xa2, 0xd7, 0x23, 0xe6, 0x8b, 0x99, 0x05, 0xd3, 0xd3, 0x7e,
0x3c, 0x8b, 0x13, 0x3a, 0x96, 0x77, 0xfa, 0x74, 0x90, 0x7d, 0x07, 0x9a, 0x47, 0xee, 0xcc, 0xa1,
0x3f, 0x11, 0xd7, 0xab, 0x37, 0x60, 0x69, 0xe2, 0xce, 0x18, 0x0b, 0xaa, 0x18, 0x25, 0xa2, 0xed,
0xff, 0x53, 0x82, 0x45, 0x4e, 0xc9, 0x6a, 0x1d, 0xd2, 0x38, 0xf1, 0x02, 0x94, 0x34, 0x59, 0xab,
0x06, 0xca, 0xc9, 0x76, 0xa9, 0x40, 0xb6, 0x85, 0x03, 0x2d, 0xaf, 0x11, 0x09, 0x01, 0x36, 0x60,
0x4c, 0xd2, 0xd2, 0x84, 0x5b, 0x1e, 0xc9, 0x4a, 0x01, 0x99, 0x68, 0x7b, 0x6a, 0x7c, 0xf0, 0xfe,
0x49, 0xb5, 0x25, 0xc4, 0x58, 0x07, 0x15, 0x9a, 0x38, 0x4b, 0x5c, 0xda, 0x73, 0x26, 0x4e, 0xce,
0x94, 0xa9, 0xbd, 0x85, 0x29, 0xc3, 0xbd, 0xea, 0x37, 0x99, 0x32, 0xf0, 0x16, 0xa6, 0x8c, 0x4d,
0xa0, 0x83, 0xf7, 0x93, 0x99, 0xb1, 0x2c, 0x79, 0xf7, 0x1f, 0x58, 0xd0, 0x11, 0x5c, 0xa4, 0x70,
0xe4, 0x43, 0xc3, 0x29, 0x28, 0xbc, 0x2e, 0x73, 0x1b, 0x96, 0xd1, 0x54, 0x57, 0x2a, 0x40, 0x9c,
0x81, 0x18, 0x40, 0x36, 0x0e, 0x99, 0xae, 0x31, 0xf6, 0x7c, 0xb1, 0x28, 0x3a, 0x48, 0x6a, 0x91,
0xc8, 0x15, 0x89, 0xa3, 0x96, 0xa3, 0xca, 0xf6, 0x2f, 0x2d, 0x58, 0xd1, 0x3a, 0x2c, 0xb8, 0xf0,
0x11, 0x48, 0x69, 0xe0, 0x41, 0x7c, 0x2e, 0xb9, 0x1b, 0xa6, 0xd8, 0xa4, 0x9f, 0x19, 0xc4, 0xb8,
0x98, 0xee, 0x0c, 0x3b, 0x18, 0x4f, 0xc7, 0x62, 0x57, 0xd1, 0x41, 0x8c, 0x91, 0x2e, 0x29, 0x7d,
0xa5, 0x48, 0xf8, 0xbe, 0x66, 0xc0, 0x30, 0x9c, 0xc9, 0x5c, 0x0c, 0x45, 0x54, 0x11, 0xe1, 0x4c,
0x1d, 0x68, 0xff, 0x57, 0x0b, 0x56, 0xb9, 0xaf, 0x28, 0xfc, 0x73, 0x75, 0x13, 0x73, 0x91, 0xbb,
0xcc, 0x5c, 0x22, 0xf7, 0x17, 0x1c, 0x51, 0x26, 0xdf, 0x7c, 0x4b, 0xff, 0x56, 0x65, 0xb3, 0xce,
0x59, 0x8b, 0x72, 0xd1, 0x5a, 0xbc, 0x61, 0xa6, 0x8b, 0x22, 0xcb, 0xd5, 0xc2, 0xc8, 0xf2, 0xe3,
0x25, 0xa8, 0xc6, 0x83, 0x70, 0x42, 0xed, 0x75, 0x58, 0x33, 0x07, 0x27, 0x54, 0xd0, 0xcf, 0x2d,
0xe8, 0x3e, 0xe1, 0x67, 0x4f, 0x5e, 0x30, 0xda, 0xf7, 0xe2, 0x24, 0x8c, 0xd4, 0x85, 0xf5, 0x9b,
0x00, 0x71, 0xe2, 0x46, 0x09, 0xbf, 0x68, 0x21, 0xe2, 0xb5, 0x29, 0x84, 0xf5, 0x91, 0x06, 0x43,
0x8e, 0xe5, 0x6b, 0xa3, 0xca, 0x39, 0xa3, 0x4a, 0x78, 0xb3, 0x86, 0x69, 0xf2, 0x11, 0xcf, 0xee,
0x66, 0xc6, 0x13, 0xbd, 0x40, 0xbd, 0xce, 0xdd, 0xc4, 0x0c, 0xd4, 0xfe, 0x2f, 0x16, 0xb4, 0xd3,
0x4e, 0x62, 0x16, 0x82, 0xa9, 0x1d, 0x84, 0x3d, 0x92, 0x6a, 0x07, 0x19, 0x49, 0xf6, 0x98, 0x81,
0x22, 0xfa, 0xa6, 0x41, 0x50, 0x62, 0x45, 0x29, 0x9c, 0x4a, 0x8b, 0x4f, 0x07, 0xf1, 0x5c, 0x4d,
0x66, 0x1a, 0x09, 0x33, 0x4f, 0x94, 0xf0, 0x9e, 0xcc, 0x38, 0xc1, 0xaf, 0x78, 0x54, 0x5c, 0x16,
0x49, 0x87, 0xdb, 0x16, 0x4b, 0xfc, 0x30, 0x8c, 0xd9, 0x15, 0xfa, 0x9e, 0x5b, 0xe3, 0xf3, 0xa3,
0xf6, 0xdc, 0xbf, 0x65, 0xc1, 0xf5, 0x82, 0x89, 0x17, 0x52, 0xb3, 0x0b, 0x2b, 0x67, 0x0a, 0x29,
0x27, 0x87, 0x8b, 0xce, 0xba, 0x3c, 0x46, 0x37, 0x27, 0xc4, 0xc9, 0x7f, 0xa0, 0x0c, 0x45, 0x3e,
0xdd, 0x46, 0x36, 0x74, 0x1e, 0x61, 0x1f, 0x41, 0x6f, 0xef, 0x35, 0x13, 0xc2, 0x1d, 0xfd, 0xbd,
0x27, 0xc9, 0x0b, 0x0f, 0x72, 0x4a, 0xe6, 0xea, 0xc8, 0xc3, 0x19, 0x2c, 0x1b, 0x75, 0x91, 0xaf,
0xbf, 0x6d, 0x25, 0xba, 0xbc, 0xc8, 0xb5, 0xe2, 0x0f, 0x56, 0xc9, 0x9c, 0x6c, 0x0d, 0x64, 0x5f,
0x40, 0xfb, 0xf3, 0xa9, 0x9f, 0x78, 0xe9, 0xe3, 0x55, 0xe4, 0x9b, 0xe2, 0x23, 0xac, 0x42, 0x4e,
0x5d, 0x61, 0x53, 0x3a, 0x1d, 0x9b, 0xb1, 0x31, 0xab, 0xa9, 0x9f, 0x6f, 0x31, 0x8f, 0xb0, 0xaf,
0xc3, 0x46, 0xda, 0x24, 0x9f, 0x3b, 0xa9, 0xa8, 0x7f, 0x61, 0xf1, 0xe4, 0x22, 0xf3, 0x2d, 0x2d,
0xf2, 0x14, 0x56, 0x63, 0x2f, 0x18, 0xf9, 0x54, 0xaf, 0x27, 0x16, 0x33, 0x71, 0xcd, 0xec, 0x9e,
0x78, 0x6f, 0xcb, 0x29, 0xfa, 0x82, 0x31, 0x48, 0x71, 0x47, 0x53, 0x06, 0xc9, 0x4c, 0x49, 0xd1,
0x00, 0xbe, 0x0d, 0x2d, 0xb3, 0x31, 0xf2, 0x50, 0xa4, 0x53, 0xa7, 0x3d, 0xd3, 0x8f, 0x07, 0x4c,
0xce, 0x30, 0x28, 0xed, 0x9f, 0x59, 0xd0, 0x75, 0x28, 0x63, 0x63, 0xaa, 0x35, 0x2a, 0xb8, 0xe7,
0x51, 0xae, 0xda, 0xf9, 0x03, 0x56, 0x69, 0xda, 0x72, 0xac, 0x9b, 0x73, 0x17, 0x65, 0x7f, 0xa1,
0x60, 0x54, 0x8f, 0x6b, 0xb0, 0x28, 0xc6, 0xb7, 0x01, 0xd7, 0x44, 0x97, 0x64, 0x77, 0xd2, 0xd8,
0xb2, 0xd1, 0xa8, 0x11, 0x5b, 0xee, 0x41, 0x97, 0xbf, 0x24, 0xa0, 0x8f, 0x83, 0x7f, 0x78, 0xef,
0x4b, 0x68, 0x68, 0xef, 0x29, 0x90, 0x0d, 0x58, 0x7d, 0xf9, 0xec, 0xe4, 0x70, 0xef, 0xf8, 0xb8,
0x7f, 0xf4, 0xe2, 0xf1, 0x77, 0xf6, 0xbe, 0xdf, 0xdf, 0xdf, 0x3e, 0xde, 0xef, 0x2c, 0x90, 0x75,
0x20, 0x87, 0x7b, 0xc7, 0x27, 0x7b, 0xbb, 0x06, 0xdc, 0x22, 0x37, 0xa1, 0xf7, 0xe2, 0xf0, 0xc5,
0xf1, 0xde, 0x6e, 0xbf, 0xe8, 0xbb, 0x12, 0x79, 0x1f, 0xae, 0x0b, 0x7c, 0xc1, 0xe7, 0xe5, 0x07,
0x3f, 0x2b, 0x43, 0x8b, 0xe7, 0x38, 0xf1, 0x27, 0xd8, 0x68, 0x44, 0x3e, 0x87, 0x25, 0xf1, 0x96,
0x1f, 0x91, 0xf3, 0x69, 0xbe, 0x1e, 0xd8, 0x5b, 0xcf, 0x82, 0xc5, 0x24, 0xac, 0xfe, 0xd5, 0x3f,
0xf9, 0x9f, 0x7f, 0xa7, 0xb4, 0x4c, 0x1a, 0x5b, 0x17, 0x9f, 0x6c, 0x8d, 0x68, 0x10, 0xb3, 0x3a,
0xfe, 0x10, 0x20, 0x7d, 0xa1, 0x8e, 0x74, 0x95, 0x13, 0x9a, 0x79, 0xbe, 0xaf, 0x77, 0xbd, 0x00,
0x23, 0xea, 0xbd, 0x8e, 0xf5, 0xae, 0xda, 0x2d, 0x56, 0xaf, 0x17, 0x78, 0x09, 0x7f, 0xad, 0xee,
0x33, 0xeb, 0x1e, 0x19, 0x42, 0x53, 0x7f, 0x3b, 0x8e, 0xc8, 0xf8, 0x78, 0xc1, 0xeb, 0x77, 0xbd,
0xf7, 0x0a, 0x71, 0x72, 0x01, 0xb1, 0x8d, 0x6b, 0x76, 0x87, 0xb5, 0x31, 0x45, 0x8a, 0xb4, 0x15,
0x9f, 0xb3, 0x75, 0xfa, 0x44, 0x1c, 0xb9, 0xa1, 0x71, 0x5a, 0xee, 0x81, 0xba, 0xde, 0xfb, 0x73,
0xb0, 0xa2, 0xad, 0xf7, 0xb1, 0xad, 0x0d, 0x9b, 0xb0, 0xb6, 0x06, 0x48, 0x23, 0x1f, 0xa8, 0xfb,
0xcc, 0xba, 0xf7, 0xe0, 0xef, 0x7d, 0x04, 0x75, 0x75, 0x6e, 0x46, 0x7e, 0x0c, 0xcb, 0x46, 0x12,
0x1a, 0x91, 0xc3, 0x28, 0xca, 0x59, 0xeb, 0xdd, 0x28, 0x46, 0x8a, 0x86, 0x6f, 0x62, 0xc3, 0x5d,
0xb2, 0xce, 0x1a, 0x16, 0x59, 0x5c, 0x5b, 0x98, 0x4e, 0xc9, 0x6f, 0x63, 0xbd, 0xd2, 0xc4, 0x97,
0x37, 0x76, 0x23, 0x2b, 0x51, 0x46, 0x6b, 0xef, 0xcf, 0xc1, 0x8a, 0xe6, 0x6e, 0x60, 0x73, 0xeb,
0x64, 0x4d, 0x6f, 0x4e, 0x9d, 0x67, 0x51, 0xbc, 0x82, 0xa8, 0xbf, 0x9e, 0x46, 0xde, 0x57, 0x8c,
0x55, 0xf4, 0xaa, 0x9a, 0x62, 0x91, 0xfc, 0xd3, 0x6a, 0x76, 0x17, 0x9b, 0x22, 0x04, 0x97, 0x4f,
0x7f, 0x3c, 0x8d, 0x9c, 0x42, 0x43, 0x7b, 0x9d, 0x87, 0x5c, 0x9f, 0xfb, 0x92, 0x50, 0xaf, 0x57,
0x84, 0x2a, 0x1a, 0x8a, 0x5e, 0xff, 0x16, 0xdb, 0x97, 0x7f, 0x08, 0x75, 0xf5, 0xde, 0x0b, 0xd9,
0xd0, 0xde, 0xdf, 0xd1, 0xdf, 0xa7, 0xe9, 0x75, 0xf3, 0x88, 0x22, 0xe6, 0xd3, 0x6b, 0x67, 0xcc,
0xf7, 0x12, 0x1a, 0xda, 0x9b, 0x2e, 0x6a, 0x00, 0xf9, 0x77, 0x63, 0xd4, 0x00, 0x0a, 0x9e, 0x80,
0xb1, 0x57, 0xb0, 0x89, 0x06, 0xa9, 0x23, 0x7f, 0x27, 0xaf, 0xc3, 0x98, 0x1c, 0xc0, 0x35, 0xa1,
0xa6, 0x4e, 0xe9, 0xbb, 0x2c, 0x43, 0xc1, 0x83, 0x75, 0xf7, 0x2d, 0xf2, 0x08, 0x6a, 0xf2, 0xe9,
0x1e, 0xb2, 0x5e, 0xfc, 0x04, 0x51, 0x6f, 0x23, 0x07, 0x17, 0xe6, 0xc9, 0xf7, 0x01, 0xd2, 0x07,
0x64, 0x94, 0x92, 0xc8, 0x3d, 0x48, 0xa3, 0x38, 0x20, 0xff, 0xda, 0x8c, 0xbd, 0x8e, 0x03, 0xec,
0x10, 0x54, 0x12, 0x01, 0xbd, 0x94, 0xb7, 0x8d, 0x7f, 0x04, 0x0d, 0xed, 0x0d, 0x19, 0x35, 0x7d,
0xf9, 0xf7, 0x67, 0xd4, 0xf4, 0x15, 0x3c, 0x39, 0x63, 0xf7, 0xb0, 0xf6, 0x35, 0xbb, 0xcd, 0x6a,
0x8f, 0xbd, 0x51, 0x30, 0xe6, 0x04, 0x6c, 0x81, 0xce, 0x61, 0xd9, 0x78, 0x28, 0x46, 0x49, 0x68,
0xd1, 0x33, 0x34, 0x4a, 0x42, 0x0b, 0xdf, 0x96, 0x91, 0x7c, 0x66, 0xaf, 0xb0, 0x76, 0x2e, 0x90,
0x44, 0x6b, 0xe9, 0x07, 0xd0, 0xd0, 0x1e, 0x7d, 0x51, 0x63, 0xc9, 0xbf, 0x2f, 0xa3, 0xc6, 0x52,
0xf4, 0x46, 0xcc, 0x1a, 0xb6, 0xd1, 0xb2, 0x91, 0x15, 0xf0, 0xde, 0x2c, 0xab, 0xfb, 0xc7, 0xd0,
0x32, 0x9f, 0x81, 0x51, 0xb2, 0x5f, 0xf8, 0xa0, 0x8c, 0x92, 0xfd, 0x39, 0x6f, 0xc7, 0x08, 0x96,
0xbe, 0xb7, 0xaa, 0x1a, 0xd9, 0xfa, 0x42, 0x64, 0xdd, 0x7c, 0x49, 0xbe, 0xcb, 0x14, 0x9c, 0xb8,
0xc8, 0x4c, 0x36, 0x34, 0xae, 0xd5, 0xaf, 0x3b, 0x2b, 0x79, 0xc9, 0xdd, 0x79, 0x36, 0x99, 0x99,
0xdf, 0xfc, 0xc5, 0x5d, 0x0b, 0x2f, 0x34, 0x6b, 0xbb, 0x96, 0x7e, 0xe7, 0x59, 0xdb, 0xb5, 0x8c,
0x7b, 0xcf, 0xd9, 0x5d, 0x2b, 0xf1, 0x58, 0x1d, 0x01, 0xb4, 0x33, 0x89, 0xf2, 0x4a, 0x2a, 0x8a,
0xef, 0x32, 0xf5, 0x6e, 0xbe, 0x39, 0xbf, 0xde, 0xd4, 0x20, 0x52, 0x09, 0x6e, 0xc9, 0x9b, 0x63,
0x7f, 0x09, 0x9a, 0xfa, 0x03, 0x18, 0x44, 0x17, 0xe5, 0x6c, 0x4b, 0xef, 0x15, 0xe2, 0xcc, 0xc5,
0x25, 0x4d, 0xbd, 0x19, 0xf2, 0x3d, 0x58, 0x57, 0xa2, 0xae, 0xe7, 0x5e, 0xc7, 0xe4, 0x83, 0x82,
0x8c, 0x6c, 0xdd, 0x78, 0xe9, 0x5d, 0x9f, 0x9b, 0xb2, 0x7d, 0xdf, 0x62, 0x4c, 0x63, 0xbe, 0x2c,
0x90, 0x6e, 0x18, 0x45, 0x0f, 0x2a, 0xa4, 0x1b, 0x46, 0xe1, 0x73, 0x04, 0x92, 0x69, 0xc8, 0xaa,
0x31, 0x47, 0xfc, 0xc0, 0x92, 0xfc, 0x00, 0xda, 0xda, 0xed, 0x96, 0xe3, 0x59, 0x30, 0x50, 0x02,
0x90, 0xbf, 0x78, 0xd9, 0x2b, 0x32, 0xcd, 0xed, 0x0d, 0xac, 0x7f, 0xc5, 0x36, 0x26, 0x87, 0x31,
0xff, 0x0e, 0x34, 0xf4, 0x9b, 0x33, 0x6f, 0xa8, 0x77, 0x43, 0x43, 0xe9, 0xf7, 0x06, 0xef, 0x5b,
0xe4, 0x1f, 0x5a, 0xd0, 0x34, 0xee, 0xa1, 0x18, 0x87, 0xf5, 0x99, 0x7a, 0xba, 0x3a, 0x4e, 0xaf,
0xc8, 0x76, 0xb0, 0x93, 0x07, 0xf7, 0xbe, 0x6d, 0x4c, 0xc2, 0x17, 0x46, 0xfc, 0x65, 0x33, 0xfb,
0x5c, 0xe0, 0x97, 0x59, 0x02, 0xfd, 0x72, 0xea, 0x97, 0xf7, 0x2d, 0xf2, 0xc7, 0x16, 0xb4, 0xcc,
0xa8, 0xa1, 0x5a, 0xaa, 0xc2, 0xf8, 0xa4, 0x5a, 0xaa, 0x39, 0xa1, 0xc6, 0x1f, 0x60, 0x2f, 0x4f,
0xee, 0x39, 0x46, 0x2f, 0xc5, 0x9b, 0x13, 0xbf, 0x59, 0x6f, 0xc9, 0x67, 0xfc, 0x95, 0x52, 0x19,
0xdb, 0x27, 0xf9, 0xf7, 0x32, 0xd5, 0xf2, 0xea, 0x2f, 0x5c, 0xde, 0xb5, 0xee, 0x5b, 0xe4, 0x47,
0xfc, 0x99, 0x3c, 0x19, 0x7e, 0x66, 0x5c, 0xf2, 0xb6, 0xdf, 0xdb, 0xb7, 0x71, 0x4c, 0x37, 0xed,
0xeb, 0xc6, 0x98, 0xb2, 0xfb, 0xf1, 0x36, 0xef, 0x9d, 0x78, 0x9c, 0x32, 0xdd, 0x50, 0x72, 0x0f,
0x56, 0xce, 0xef, 0xe4, 0x98, 0x77, 0x52, 0x90, 0x1b, 0xac, 0xfc, 0x96, 0xd5, 0xd8, 0xf7, 0xb0,
0xaf, 0xb7, 0xed, 0x0f, 0xe6, 0xf6, 0x75, 0x0b, 0x63, 0x7f, 0xac, 0xc7, 0x47, 0x00, 0xe9, 0x39,
0x1c, 0xc9, 0x9c, 0x03, 0x29, 0x01, 0xcf, 0x1f, 0xd5, 0x99, 0xf2, 0x22, 0x8f, 0x8b, 0x58, 0x8d,
0x3f, 0xe4, 0xea, 0xea, 0x99, 0x3c, 0x41, 0xd2, 0x8d, 0x12, 0xf3, 0xc0, 0xcc, 0x30, 0x4a, 0xb2,
0xf5, 0x1b, 0xca, 0x4a, 0x1d, 0x47, 0xbd, 0x80, 0xe5, 0x83, 0x30, 0x7c, 0x35, 0x9d, 0xa8, 0x33,
0x75, 0x33, 0x2c, 0xbf, 0xef, 0xc6, 0xe7, 0xbd, 0xcc, 0x28, 0xec, 0x5b, 0x58, 0x55, 0x8f, 0x74,
0xb5, 0xaa, 0xb6, 0xbe, 0x48, 0xcf, 0xf9, 0xbe, 0x24, 0x2e, 0xac, 0x28, 0x1d, 0xa8, 0x3a, 0xde,
0x33, 0xab, 0x31, 0x34, 0x5f, 0xb6, 0x09, 0xc3, 0x7a, 0x96, 0xbd, 0xdd, 0x8a, 0x65, 0x9d, 0xf7,
0x2d, 0x72, 0x04, 0xcd, 0x5d, 0x3a, 0xc0, 0x2c, 0x78, 0x8c, 0x6d, 0xaf, 0xa6, 0x1d, 0x57, 0x41,
0xf1, 0xde, 0xb2, 0x01, 0x34, 0xf7, 0x85, 0x89, 0x3b, 0x8b, 0xe8, 0x4f, 0xb6, 0xbe, 0x10, 0x51,
0xf3, 0x2f, 0xe5, 0xbe, 0x20, 0x8f, 0x15, 0x8c, 0x7d, 0x21, 0x73, 0x0e, 0x61, 0xec, 0x0b, 0xb9,
0x73, 0x08, 0x63, 0xaa, 0xe5, 0xb1, 0x06, 0xf1, 0x61, 0x25, 0x77, 0x74, 0xa1, 0xb6, 0x84, 0x79,
0x07, 0x1e, 0xbd, 0x5b, 0xf3, 0x09, 0xcc, 0xd6, 0xee, 0x99, 0xad, 0x1d, 0xc3, 0xf2, 0x2e, 0xe5,
0x93, 0xc5, 0x93, 0x06, 0x33, 0x97, 0x99, 0xf4, 0x94, 0xc4, 0xac, 0x02, 0x47, 0x9c, 0xb9, 0xf1,
0x63, 0xc6, 0x1e, 0xf9, 0x21, 0x34, 0x9e, 0xd2, 0x44, 0x66, 0x09, 0x2a, 0xd3, 0x33, 0x93, 0x36,
0xd8, 0x2b, 0x48, 0x32, 0x34, 0x79, 0x06, 0x6b, 0xdb, 0xa2, 0xc3, 0x11, 0xe5, 0xca, 0xa9, 0xef,
0x0d, 0xbf, 0x24, 0x7f, 0x11, 0x2b, 0x57, 0x29, 0xd2, 0xeb, 0x5a, 0xda, 0x97, 0x5e, 0x79, 0x3b,
0x03, 0x2f, 0xaa, 0x39, 0x08, 0x87, 0x54, 0x33, 0x81, 0x02, 0x68, 0x68, 0x77, 0x14, 0x94, 0x00,
0xe5, 0x2f, 0x6c, 0x28, 0x01, 0x2a, 0xb8, 0xd2, 0x60, 0xdf, 0xc5, 0x76, 0x6c, 0x72, 0x2b, 0x6d,
0x87, 0x5f, 0x63, 0x48, 0x5b, 0xda, 0xfa, 0xc2, 0x1d, 0x27, 0x5f, 0x92, 0x97, 0xf8, 0x06, 0x8c,
0x9e, 0x09, 0x99, 0xda, 0xd2, 0xd9, 0xa4, 0x49, 0x35, 0x59, 0x1a, 0xca, 0xb4, 0xaf, 0x79, 0x53,
0x68, 0x29, 0x7d, 0x13, 0xe0, 0x38, 0x09, 0x27, 0xbb, 0x2e, 0x1d, 0x87, 0x41, 0xaa, 0x6b, 0xd3,
0x3c, 0xbc, 0x54, 0x7f, 0x69, 0xc9, 0x78, 0xe4, 0xa5, 0xe6, 0x7c, 0x18, 0x89, 0xa4, 0x92, 0xb9,
0xe6, 0xa6, 0xea, 0xa9, 0x09, 0x29, 0x48, 0xd7, 0xbb, 0x6f, 0x91, 0x6d, 0x80, 0xf4, 0xec, 0x4a,
0xb9, 0x12, 0xb9, 0x63, 0x31, 0xa5, 0xf6, 0x0a, 0x0e, 0xba, 0x8e, 0xa0, 0x9e, 0x1e, 0x86, 0x6c,
0xa4, 0xb7, 0x8c, 0x8c, 0xa3, 0x13, 0xb5, 0x83, 0xe7, 0x8e, 0x28, 0xec, 0x0e, 0x4e, 0x15, 0x90,
0x1a, 0x9b, 0x2a, 0x3c, 0x77, 0xf0, 0x60, 0x95, 0x77, 0x50, 0x99, 0x23, 0x98, 0x43, 0x26, 0x47,
0x52, 0x70, 0x4c, 0xa0, 0xa4, 0xb9, 0x30, 0xca, 0x6e, 0x44, 0x44, 0x18, 0xb7, 0xf2, 0xfc, 0x35,
0xa6, 0x9a, 0xc7, 0xb0, 0x92, 0x0b, 0x03, 0x2b, 0x91, 0x9e, 0x17, 0x99, 0x57, 0x22, 0x3d, 0x37,
0x82, 0x6c, 0x5f, 0xc3, 0x26, 0xdb, 0x36, 0xa0, 0x07, 0x74, 0xe9, 0x25, 0x83, 0x73, 0xd6, 0xdc,
0x2f, 0x2c, 0x58, 0x2d, 0x88, 0xf2, 0x92, 0x0f, 0xa5, 0x33, 0x3d, 0x37, 0x02, 0xdc, 0x2b, 0x0c,
0x02, 0xda, 0xc7, 0xd8, 0xce, 0xe7, 0xe4, 0x3b, 0xc6, 0xc6, 0xc6, 0xe3, 0x6f, 0x42, 0x32, 0xdf,
0x68, 0x54, 0x14, 0x5a, 0x14, 0x3f, 0x81, 0x0d, 0xde, 0x91, 0x6d, 0xdf, 0xcf, 0x04, 0x28, 0x6f,
0xe6, 0xfe, 0x51, 0x81, 0x11, 0x78, 0xed, 0xcd, 0xff, 0x47, 0x06, 0x73, 0xcc, 0x55, 0xde, 0x55,
0x32, 0x85, 0x4e, 0x36, 0xe8, 0x47, 0xe6, 0xd7, 0xd5, 0xfb, 0xc0, 0x70, 0x0b, 0xf3, 0x81, 0x42,
0xfb, 0x77, 0xb0, 0xb1, 0x0f, 0xec, 0x5e, 0xd1, 0xbc, 0x70, 0x4f, 0x91, 0xad, 0xc7, 0x5f, 0x51,
0x11, 0xca, 0xcc, 0x38, 0x65, 0x03, 0xf3, 0x42, 0xaa, 0xca, 0x31, 0x2d, 0x0e, 0x70, 0x7e, 0x84,
0xcd, 0xdf, 0xb2, 0xdf, 0x2b, 0x6a, 0x3e, 0xe2, 0x9f, 0x70, 0x17, 0x75, 0x23, 0x2b, 0xd7, 0xb2,
0x07, 0xb7, 0x8a, 0xd6, 0x7b, 0xae, 0xaf, 0x91, 0x99, 0xeb, 0x85, 0xfb, 0xd6, 0xe3, 0x3b, 0x3f,
0xf8, 0x9d, 0x91, 0x97, 0x9c, 0x4f, 0x4f, 0x37, 0x07, 0xe1, 0x78, 0xcb, 0x97, 0x21, 0x32, 0x91,
0xf1, 0xbc, 0xe5, 0x07, 0xc3, 0x2d, 0xfc, 0xfe, 0x74, 0x11, 0xff, 0xef, 0xc9, 0xd7, 0xff, 0x5f,
0x00, 0x00, 0x00, 0xff, 0xff, 0x77, 0xa0, 0xa0, 0x17, 0x29, 0x65, 0x00, 0x00,
0x9d, 0xad, 0xcc, 0xdb, 0x99, 0x38, 0x1b, 0x7b, 0x76, 0x92, 0x2c, 0xf3, 0x76, 0x12, 0x1e, 0x1e,
0xdb, 0x33, 0x9e, 0xc4, 0xeb, 0x71, 0xca, 0x9e, 0x0c, 0x49, 0x1e, 0xea, 0x94, 0xbb, 0xaf, 0xdb,
0x95, 0xa9, 0xae, 0xea, 0x54, 0x55, 0xdb, 0xd3, 0x59, 0x96, 0x1f, 0x08, 0x21, 0xf4, 0x24, 0x84,
0x02, 0x12, 0x02, 0x04, 0x42, 0x4a, 0x9e, 0x10, 0x4f, 0xfc, 0x00, 0x7e, 0x80, 0x40, 0x8a, 0xf4,
0x7e, 0xf2, 0x0b, 0x21, 0xf4, 0x7e, 0x22, 0xf1, 0x84, 0x40, 0x42, 0x11, 0xff, 0x90, 0xf8, 0x8f,
0xee, 0xb9, 0x1f, 0x75, 0x6f, 0x55, 0xf5, 0xcc, 0x6c, 0xb2, 0xf0, 0xcb, 0x7d, 0xcf, 0x39, 0x75,
0x3f, 0xcf, 0x39, 0xf7, 0x9c, 0x73, 0xcf, 0xbd, 0x86, 0x7a, 0x34, 0x19, 0x6c, 0x4d, 0xa2, 0x30,
0x09, 0x49, 0xd5, 0x0f, 0xa2, 0xc9, 0xa0, 0x77, 0x63, 0x14, 0x86, 0x23, 0x9f, 0x6e, 0xbb, 0x13,
0x6f, 0xdb, 0x0d, 0x82, 0x30, 0x71, 0x13, 0x2f, 0x0c, 0x62, 0x4e, 0x64, 0xff, 0x04, 0x5a, 0x4f,
0x68, 0x70, 0x42, 0xe9, 0xd0, 0xa1, 0x3f, 0x9b, 0xd2, 0x38, 0x21, 0x5f, 0x83, 0x15, 0x97, 0xfe,
0x9c, 0xd2, 0x61, 0x7f, 0xe2, 0xc6, 0xf1, 0xe4, 0x22, 0x72, 0x63, 0xda, 0xb5, 0x6e, 0x59, 0x77,
0x9b, 0x4e, 0x87, 0x23, 0x8e, 0x15, 0x9c, 0xbc, 0x0f, 0xcd, 0x98, 0x91, 0xd2, 0x20, 0x89, 0xc2,
0xc9, 0xac, 0x5b, 0x42, 0xba, 0x06, 0x83, 0xed, 0x73, 0x90, 0xed, 0x43, 0x5b, 0xb5, 0x10, 0x4f,
0xc2, 0x20, 0xa6, 0xe4, 0x1e, 0xac, 0x0d, 0xbc, 0xc9, 0x05, 0x8d, 0xfa, 0xf8, 0xf1, 0x38, 0xa0,
0xe3, 0x30, 0xf0, 0x06, 0x5d, 0xeb, 0x56, 0xf9, 0x6e, 0xdd, 0x21, 0x1c, 0xc7, 0xbe, 0xf8, 0x54,
0x60, 0xc8, 0x1d, 0x68, 0xd3, 0x80, 0xc3, 0xe9, 0x10, 0xbf, 0x12, 0x4d, 0xb5, 0x52, 0x30, 0xfb,
0xc0, 0xfe, 0x5b, 0x25, 0x58, 0x79, 0x1a, 0x78, 0xc9, 0x0b, 0xd7, 0xf7, 0x69, 0x22, 0xc7, 0x74,
0x07, 0xda, 0x57, 0x08, 0xc0, 0x31, 0x5d, 0x85, 0xd1, 0x50, 0x8c, 0xa8, 0xc5, 0xc1, 0xc7, 0x02,
0x3a, 0xb7, 0x67, 0xa5, 0xb9, 0x3d, 0x2b, 0x9c, 0xae, 0xf2, 0x9c, 0xe9, 0xba, 0x03, 0xed, 0x88,
0x0e, 0xc2, 0x4b, 0x1a, 0xcd, 0xfa, 0x57, 0x5e, 0x30, 0x0c, 0xaf, 0xba, 0x95, 0x5b, 0xd6, 0xdd,
0xaa, 0xd3, 0x92, 0xe0, 0x17, 0x08, 0x25, 0x8f, 0xa0, 0x3d, 0xb8, 0x70, 0x83, 0x80, 0xfa, 0xfd,
0x33, 0x77, 0xf0, 0x72, 0x3a, 0x89, 0xbb, 0xd5, 0x5b, 0xd6, 0xdd, 0xc6, 0xfd, 0xeb, 0x5b, 0xb8,
0xaa, 0x5b, 0xbb, 0x17, 0x6e, 0xf0, 0x08, 0x31, 0x27, 0x81, 0x3b, 0x89, 0x2f, 0xc2, 0xc4, 0x69,
0x89, 0x2f, 0x38, 0x38, 0xb6, 0xd7, 0x80, 0xe8, 0x33, 0xc1, 0xe7, 0xde, 0xfe, 0x17, 0x16, 0xac,
0x3e, 0x0f, 0xfc, 0x70, 0xf0, 0xf2, 0xb7, 0x9c, 0xa2, 0x82, 0x31, 0x94, 0xde, 0x76, 0x0c, 0xe5,
0x2f, 0x3a, 0x86, 0x75, 0x58, 0x33, 0x3b, 0x2b, 0x46, 0x41, 0xe1, 0x1a, 0xfb, 0x7a, 0x44, 0x65,
0xb7, 0xe4, 0x30, 0xbe, 0x0a, 0x9d, 0xc1, 0x34, 0x8a, 0x68, 0x90, 0x1b, 0x47, 0x5b, 0xc0, 0xd5,
0x40, 0xde, 0x87, 0x66, 0x40, 0xaf, 0x52, 0x32, 0xc1, 0xbb, 0x01, 0xbd, 0x92, 0x24, 0x76, 0x17,
0xd6, 0xb3, 0xcd, 0x88, 0x0e, 0xfc, 0x37, 0x0b, 0x2a, 0xcf, 0x93, 0x57, 0x21, 0xd9, 0x82, 0x4a,
0x32, 0x9b, 0x70, 0x09, 0x69, 0xdd, 0x27, 0x62, 0x68, 0x3b, 0xc3, 0x61, 0x44, 0xe3, 0xf8, 0x74,
0x36, 0xa1, 0x4e, 0xd3, 0xe5, 0x85, 0x3e, 0xa3, 0x23, 0x5d, 0x58, 0x12, 0x65, 0x6c, 0xb0, 0xee,
0xc8, 0x22, 0xb9, 0x09, 0xe0, 0x8e, 0xc3, 0x69, 0x90, 0xf4, 0x63, 0x37, 0xc1, 0xa9, 0x2a, 0x3b,
0x1a, 0x84, 0xdc, 0x80, 0xfa, 0xe4, 0x65, 0x3f, 0x1e, 0x44, 0xde, 0x24, 0x41, 0xb6, 0xa9, 0x3b,
0x29, 0x80, 0x7c, 0x0d, 0x6a, 0xe1, 0x34, 0x99, 0x84, 0x5e, 0x90, 0x08, 0x56, 0x69, 0x8b, 0xbe,
0x3c, 0x9b, 0x26, 0xc7, 0x0c, 0xec, 0x28, 0x02, 0x72, 0x1b, 0x96, 0x07, 0x61, 0x70, 0xee, 0x45,
0x63, 0xae, 0x0c, 0xba, 0x8b, 0xd8, 0x9a, 0x09, 0xb4, 0xff, 0x7d, 0x09, 0x1a, 0xa7, 0x91, 0x1b,
0xc4, 0xee, 0x80, 0x01, 0x58, 0xd7, 0x93, 0x57, 0xfd, 0x0b, 0x37, 0xbe, 0xc0, 0xd1, 0xd6, 0x1d,
0x59, 0x24, 0xeb, 0xb0, 0xc8, 0x3b, 0x8a, 0x63, 0x2a, 0x3b, 0xa2, 0x44, 0x3e, 0x84, 0x95, 0x60,
0x3a, 0xee, 0x9b, 0x6d, 0x95, 0x91, 0x5b, 0xf2, 0x08, 0x36, 0x01, 0x67, 0x6c, 0xad, 0x79, 0x13,
0x7c, 0x84, 0x1a, 0x84, 0xd8, 0xd0, 0x14, 0x25, 0xea, 0x8d, 0x2e, 0xf8, 0x30, 0xab, 0x8e, 0x01,
0x63, 0x75, 0x24, 0xde, 0x98, 0xf6, 0xe3, 0xc4, 0x1d, 0x4f, 0xc4, 0xb0, 0x34, 0x08, 0xe2, 0xc3,
0xc4, 0xf5, 0xfb, 0xe7, 0x94, 0xc6, 0xdd, 0x25, 0x81, 0x57, 0x10, 0xf2, 0x01, 0xb4, 0x86, 0x34,
0x4e, 0xfa, 0x62, 0x51, 0x68, 0xdc, 0xad, 0xa1, 0xe8, 0x67, 0xa0, 0xac, 0x9e, 0xc8, 0xbd, 0xea,
0xb3, 0x09, 0xa0, 0xaf, 0xba, 0x75, 0xde, 0xd7, 0x14, 0xc2, 0x38, 0xe7, 0x09, 0x4d, 0xb4, 0xd9,
0x8b, 0x05, 0x87, 0xda, 0x87, 0x40, 0x34, 0xf0, 0x1e, 0x4d, 0x5c, 0xcf, 0x8f, 0xc9, 0xc7, 0xd0,
0x4c, 0x34, 0x62, 0x54, 0x85, 0x0d, 0xc5, 0x4e, 0xda, 0x07, 0x8e, 0x41, 0x67, 0x3f, 0x81, 0xda,
0x63, 0x4a, 0x0f, 0xbd, 0xb1, 0x97, 0x90, 0x75, 0xa8, 0x9e, 0x7b, 0xaf, 0x28, 0x67, 0xf8, 0xf2,
0xc1, 0x82, 0xc3, 0x8b, 0xa4, 0x07, 0x4b, 0x13, 0x1a, 0x0d, 0xa8, 0x5c, 0x9e, 0x83, 0x05, 0x47,
0x02, 0x1e, 0x2d, 0x41, 0xd5, 0x67, 0x1f, 0xdb, 0xbf, 0x29, 0x43, 0xe3, 0x84, 0x06, 0x4a, 0x90,
0x08, 0x54, 0xd8, 0x90, 0x85, 0xf0, 0xe0, 0x6f, 0xf2, 0x1e, 0x34, 0x70, 0x1a, 0xe2, 0x24, 0xf2,
0x82, 0x91, 0xe0, 0x5f, 0x60, 0xa0, 0x13, 0x84, 0x90, 0x0e, 0x94, 0xdd, 0xb1, 0xe4, 0x5d, 0xf6,
0x93, 0x09, 0xd9, 0xc4, 0x9d, 0x8d, 0x99, 0x3c, 0xaa, 0x55, 0x6d, 0x3a, 0x0d, 0x01, 0x3b, 0x60,
0xcb, 0xba, 0x05, 0xab, 0x3a, 0x89, 0xac, 0xbd, 0x8a, 0xb5, 0xaf, 0x68, 0x94, 0xa2, 0x91, 0x3b,
0xd0, 0x96, 0xf4, 0x11, 0xef, 0x2c, 0xae, 0x73, 0xdd, 0x69, 0x09, 0xb0, 0x1c, 0xc2, 0x5d, 0xe8,
0x9c, 0x7b, 0x81, 0xeb, 0xf7, 0x07, 0x7e, 0x72, 0xd9, 0x1f, 0x52, 0x3f, 0x71, 0x71, 0xc5, 0xab,
0x4e, 0x0b, 0xe1, 0xbb, 0x7e, 0x72, 0xb9, 0xc7, 0xa0, 0xe4, 0x43, 0xa8, 0x9f, 0x53, 0xda, 0xc7,
0x99, 0xe8, 0xd6, 0x0c, 0xe9, 0x91, 0xb3, 0xeb, 0xd4, 0xce, 0xe5, 0x3c, 0xdf, 0x85, 0x4e, 0x38,
0x4d, 0x46, 0xa1, 0x17, 0x8c, 0xfa, 0x4c, 0x5f, 0xf5, 0xbd, 0x21, 0x72, 0x40, 0xc5, 0x69, 0x49,
0x38, 0xd3, 0x1a, 0x4f, 0x87, 0xe4, 0x5d, 0x00, 0x6c, 0x9b, 0x57, 0x0c, 0xb7, 0xac, 0xbb, 0xcb,
0x4e, 0x9d, 0x41, 0x78, 0x45, 0x9f, 0x40, 0x0d, 0xe7, 0x33, 0xf1, 0x2f, 0xbb, 0x0d, 0x5c, 0xf0,
0xf7, 0x44, 0xab, 0xda, 0x4a, 0x6c, 0xed, 0xd1, 0x38, 0x39, 0xf5, 0x2f, 0xd9, 0x7e, 0x3a, 0x73,
0x96, 0x86, 0xbc, 0xd4, 0xfb, 0x04, 0x9a, 0x3a, 0x82, 0x4d, 0xfd, 0x4b, 0x3a, 0xc3, 0xe5, 0xaa,
0x38, 0xec, 0x27, 0x59, 0x83, 0xea, 0xa5, 0xeb, 0x4f, 0xa9, 0x50, 0x6c, 0xbc, 0xf0, 0x49, 0xe9,
0x81, 0x65, 0xff, 0x3b, 0x0b, 0x9a, 0xbc, 0x05, 0xb1, 0x21, 0xdf, 0x86, 0x65, 0x39, 0xa5, 0x34,
0x8a, 0xc2, 0x48, 0xc8, 0xb7, 0x09, 0x24, 0x9b, 0xd0, 0x91, 0x80, 0x49, 0x44, 0xbd, 0xb1, 0x3b,
0x92, 0x75, 0xe7, 0xe0, 0xe4, 0x7e, 0x5a, 0x63, 0x14, 0x4e, 0x13, 0x2a, 0x54, 0x7f, 0x53, 0x8c,
0xcf, 0x61, 0x30, 0xc7, 0x24, 0x61, 0xf2, 0x5d, 0xc0, 0x2b, 0x06, 0xcc, 0xfe, 0x85, 0x05, 0x84,
0x75, 0xfd, 0x34, 0xe4, 0x55, 0x88, 0xa5, 0xce, 0xb2, 0x99, 0xf5, 0xd6, 0x6c, 0x56, 0x9a, 0xc7,
0x66, 0x36, 0x54, 0x79, 0xcf, 0x2b, 0x05, 0x3d, 0xe7, 0xa8, 0xef, 0x56, 0x6a, 0xe5, 0x4e, 0xc5,
0xfe, 0xa5, 0x05, 0xcd, 0x5d, 0xbe, 0x6f, 0xa1, 0xa2, 0x25, 0xf7, 0x80, 0x9c, 0x4f, 0x83, 0x21,
0xe3, 0x8f, 0xe4, 0x95, 0x37, 0xec, 0x9f, 0xcd, 0x12, 0x1a, 0xf3, 0x3e, 0x1d, 0x2c, 0x38, 0x05,
0x38, 0xf2, 0x21, 0x74, 0x0c, 0x68, 0x9c, 0x44, 0xbc, 0x67, 0x07, 0x0b, 0x4e, 0x0e, 0xc3, 0x26,
0x8a, 0xa9, 0xf2, 0x69, 0xd2, 0xf7, 0x82, 0x21, 0x7d, 0x85, 0x73, 0xbb, 0xec, 0x18, 0xb0, 0x47,
0x2d, 0x68, 0xea, 0xdf, 0xd9, 0x3f, 0x85, 0x9a, 0xdc, 0x08, 0x50, 0x09, 0x66, 0xfa, 0xe5, 0x68,
0x10, 0xd2, 0x83, 0x9a, 0xd9, 0x0b, 0xa7, 0xf6, 0x45, 0xda, 0xb6, 0xff, 0x22, 0x74, 0x0e, 0x99,
0x36, 0x0e, 0xbc, 0x60, 0x24, 0x76, 0x42, 0xb6, 0x45, 0x4c, 0xa6, 0x67, 0x92, 0x45, 0xeb, 0x8e,
0x28, 0x31, 0x3d, 0x73, 0x11, 0xc6, 0x89, 0x68, 0x07, 0x7f, 0xdb, 0xff, 0xc1, 0x02, 0xb2, 0x1f,
0x27, 0xde, 0xd8, 0x4d, 0xe8, 0x63, 0xaa, 0x16, 0xf9, 0x19, 0x34, 0x59, 0x6d, 0xa7, 0xe1, 0x0e,
0xdf, 0x6b, 0xb8, 0x8e, 0xfc, 0x9a, 0x58, 0x98, 0xfc, 0x07, 0x5b, 0x3a, 0x35, 0x17, 0x1f, 0xa3,
0x02, 0xa6, 0xcf, 0x12, 0x37, 0x1a, 0xd1, 0x04, 0x37, 0x22, 0x61, 0xc6, 0x00, 0x07, 0xed, 0x86,
0xc1, 0x79, 0xef, 0x0f, 0x60, 0x25, 0x57, 0x87, 0x2e, 0x69, 0xf5, 0x02, 0x49, 0x2b, 0xeb, 0x92,
0x36, 0x80, 0x55, 0xa3, 0x5f, 0x42, 0xde, 0xba, 0xb0, 0xc4, 0xf4, 0x0d, 0xdb, 0xe7, 0x51, 0x57,
0x3b, 0xb2, 0x48, 0xee, 0xc3, 0xda, 0x39, 0xa5, 0x91, 0x9b, 0x60, 0xb1, 0x3f, 0xa1, 0x11, 0xae,
0x89, 0xa8, 0xb9, 0x10, 0x67, 0xff, 0x77, 0x0b, 0xda, 0x4c, 0x26, 0x3e, 0x75, 0x83, 0x99, 0x9c,
0xab, 0xc3, 0xc2, 0xb9, 0xba, 0xab, 0xa9, 0x17, 0x8d, 0xfa, 0x8b, 0x4e, 0x54, 0x39, 0x3b, 0x51,
0xe4, 0x16, 0x34, 0x8d, 0xee, 0x56, 0xf9, 0xc6, 0x1a, 0xbb, 0xc9, 0x31, 0x8d, 0x1e, 0xcd, 0x12,
0xfa, 0xbb, 0x4f, 0xe5, 0x07, 0xd0, 0x49, 0xbb, 0x2d, 0xe6, 0x91, 0x40, 0x85, 0x31, 0xa6, 0xa8,
0x00, 0x7f, 0xdb, 0xff, 0xd8, 0xe2, 0x84, 0xbb, 0xa1, 0xa7, 0x36, 0x5d, 0x46, 0xc8, 0xf6, 0x6e,
0x49, 0xc8, 0x7e, 0xcf, 0x35, 0x5a, 0x7e, 0xf7, 0xc1, 0x92, 0xeb, 0x50, 0x8b, 0x69, 0x30, 0xec,
0xbb, 0xbe, 0x8f, 0x7b, 0x53, 0xcd, 0x59, 0x62, 0xe5, 0x1d, 0xdf, 0xb7, 0xef, 0xc0, 0x8a, 0xd6,
0xbb, 0xd7, 0x8c, 0xe3, 0x08, 0xc8, 0xa1, 0x17, 0x27, 0xcf, 0x83, 0x78, 0xa2, 0xed, 0x69, 0xef,
0x40, 0x7d, 0xec, 0x05, 0xd8, 0x33, 0x2e, 0xb9, 0x55, 0xa7, 0x36, 0xf6, 0x02, 0xd6, 0xaf, 0x18,
0x91, 0xee, 0x2b, 0x81, 0x2c, 0x09, 0xa4, 0xfb, 0x0a, 0x91, 0xf6, 0x03, 0x58, 0x35, 0xea, 0x13,
0x4d, 0xbf, 0x0f, 0xd5, 0x69, 0xf2, 0x2a, 0x94, 0x16, 0x47, 0x43, 0x70, 0x08, 0xb3, 0x6d, 0x1d,
0x8e, 0xb1, 0x1f, 0xc2, 0xca, 0x11, 0xbd, 0x12, 0x82, 0x2c, 0x3b, 0xf2, 0xc1, 0x1b, 0xed, 0x5e,
0xc4, 0xdb, 0x5b, 0x40, 0xf4, 0x8f, 0x53, 0x01, 0x90, 0x56, 0xb0, 0x65, 0x58, 0xc1, 0xf6, 0x07,
0x40, 0x4e, 0xbc, 0x51, 0xf0, 0x29, 0x8d, 0x63, 0x77, 0xa4, 0x44, 0xbf, 0x03, 0xe5, 0x71, 0x3c,
0x12, 0xaa, 0x8a, 0xfd, 0xb4, 0xbf, 0x01, 0xab, 0x06, 0x9d, 0xa8, 0xf8, 0x06, 0xd4, 0x63, 0x6f,
0x14, 0xb8, 0xc9, 0x34, 0xa2, 0xa2, 0xea, 0x14, 0x60, 0x3f, 0x86, 0xb5, 0x1f, 0xd0, 0xc8, 0x3b,
0x9f, 0xbd, 0xa9, 0x7a, 0xb3, 0x9e, 0x52, 0xb6, 0x9e, 0x7d, 0xb8, 0x96, 0xa9, 0x47, 0x34, 0xcf,
0xd9, 0x57, 0xac, 0x64, 0xcd, 0xe1, 0x05, 0x4d, 0xf7, 0x95, 0x74, 0xdd, 0x67, 0x3f, 0x07, 0xb2,
0x1b, 0x06, 0x01, 0x1d, 0x24, 0xc7, 0x94, 0x46, 0xa9, 0x03, 0x9e, 0xf2, 0x6a, 0xe3, 0xfe, 0x86,
0x98, 0xd9, 0xac, 0x42, 0x15, 0x4c, 0x4c, 0xa0, 0x32, 0xa1, 0xd1, 0x18, 0x2b, 0xae, 0x39, 0xf8,
0xdb, 0xbe, 0x06, 0xab, 0x46, 0xb5, 0xc2, 0x65, 0xf9, 0x08, 0xae, 0xed, 0x79, 0xf1, 0x20, 0xdf,
0x60, 0x17, 0x96, 0x26, 0xd3, 0xb3, 0x7e, 0x2a, 0x89, 0xb2, 0xc8, 0xac, 0xd8, 0xec, 0x27, 0xa2,
0xb2, 0xbf, 0x69, 0x41, 0xe5, 0xe0, 0xf4, 0x70, 0x97, 0xed, 0x15, 0x5e, 0x30, 0x08, 0xc7, 0x6c,
0x2f, 0xe5, 0x83, 0x56, 0xe5, 0xb9, 0x12, 0x76, 0x03, 0xea, 0xb8, 0x05, 0x33, 0xc3, 0x5d, 0xf8,
0xca, 0x29, 0x80, 0x39, 0x0d, 0xf4, 0xd5, 0xc4, 0x8b, 0xd0, 0x2b, 0x90, 0xb6, 0x7e, 0x05, 0xb7,
0x99, 0x3c, 0xc2, 0xfe, 0xf5, 0x22, 0x2c, 0x89, 0xcd, 0x17, 0xdb, 0x1b, 0x24, 0xde, 0x25, 0x15,
0x3d, 0x11, 0x25, 0x66, 0xde, 0x44, 0x74, 0x1c, 0x26, 0xb4, 0x6f, 0x2c, 0x83, 0x09, 0x44, 0xa7,
0x48, 0xf8, 0xab, 0xdc, 0x8d, 0x2a, 0x73, 0x2a, 0x03, 0xc8, 0x26, 0x4b, 0xda, 0x7c, 0x15, 0xb4,
0xb5, 0x64, 0x91, 0xcd, 0xc4, 0xc0, 0x9d, 0xb8, 0x03, 0x2f, 0x99, 0x09, 0x95, 0xa0, 0xca, 0xac,
0x6e, 0x3f, 0x1c, 0xb8, 0xcc, 0x13, 0xf6, 0xdd, 0x60, 0x40, 0xa5, 0xc3, 0x65, 0x00, 0x99, 0xf3,
0x21, 0xba, 0x24, 0xc9, 0xb8, 0x83, 0x92, 0x81, 0xb2, 0xfd, 0x7b, 0x10, 0x8e, 0xc7, 0x5e, 0xc2,
0x7c, 0x16, 0xb4, 0x57, 0xcb, 0x8e, 0x06, 0xe1, 0xee, 0x1d, 0x96, 0xae, 0xf8, 0xec, 0xd5, 0xa5,
0x7b, 0xa7, 0x01, 0x59, 0x2d, 0x6c, 0xd7, 0x61, 0x6a, 0xec, 0xe5, 0x15, 0x1a, 0xa7, 0x65, 0x47,
0x83, 0xb0, 0x75, 0x98, 0x06, 0x31, 0x4d, 0x12, 0x9f, 0x0e, 0x55, 0x87, 0x1a, 0x48, 0x96, 0x47,
0x90, 0x7b, 0xb0, 0xca, 0xdd, 0xa8, 0xd8, 0x4d, 0xc2, 0xf8, 0xc2, 0x8b, 0xfb, 0x31, 0x73, 0x38,
0x9a, 0x48, 0x5f, 0x84, 0x22, 0x0f, 0x60, 0x23, 0x03, 0x8e, 0xe8, 0x80, 0x7a, 0x97, 0x74, 0xd8,
0x5d, 0xc6, 0xaf, 0xe6, 0xa1, 0xc9, 0x2d, 0x68, 0x30, 0xef, 0x71, 0x3a, 0x19, 0xba, 0xcc, 0x80,
0x69, 0xe1, 0x3a, 0xe8, 0x20, 0xf2, 0x11, 0x2c, 0x4f, 0x28, 0xb7, 0x7e, 0x2e, 0x12, 0x7f, 0x10,
0x77, 0xdb, 0x86, 0x76, 0x63, 0x9c, 0xeb, 0x98, 0x14, 0x8c, 0x29, 0x07, 0x31, 0xba, 0x09, 0xee,
0xac, 0xdb, 0x11, 0xa6, 0xba, 0x04, 0xa0, 0x8c, 0x44, 0xde, 0xa5, 0x9b, 0xd0, 0xee, 0x0a, 0x57,
0xe8, 0xa2, 0xc8, 0xbe, 0xf3, 0x02, 0x2f, 0xf1, 0xdc, 0x24, 0x8c, 0xba, 0x04, 0x71, 0x29, 0x80,
0x4d, 0x22, 0xf2, 0x47, 0x9c, 0xb8, 0xc9, 0x34, 0xee, 0x9f, 0xfb, 0xee, 0x28, 0xee, 0xae, 0x72,
0x9b, 0x33, 0x87, 0x20, 0x1f, 0xc3, 0x3a, 0xe7, 0x08, 0x44, 0x45, 0x34, 0xa6, 0xd1, 0x25, 0x37,
0x13, 0xd6, 0x70, 0x46, 0xe6, 0x60, 0xd9, 0x54, 0x0a, 0x16, 0xc9, 0x7d, 0x78, 0x8d, 0x4f, 0xe5,
0x1c, 0xb4, 0xfd, 0x4f, 0x2d, 0xbe, 0x2d, 0x08, 0x11, 0x52, 0xea, 0xfd, 0x3d, 0x68, 0x70, 0xe1,
0xe9, 0x87, 0x81, 0x3f, 0x13, 0xf2, 0x04, 0x1c, 0xf4, 0x2c, 0xf0, 0x67, 0xe4, 0x2b, 0xb0, 0xec,
0x05, 0x3a, 0x09, 0xd7, 0x40, 0x4d, 0x09, 0x44, 0xa2, 0xf7, 0xa0, 0x31, 0x99, 0x9e, 0xf9, 0xde,
0x80, 0x93, 0x94, 0x79, 0x2d, 0x1c, 0x84, 0x04, 0xcc, 0x6e, 0xe7, 0xf3, 0xc8, 0x29, 0x2a, 0x48,
0xd1, 0x10, 0x30, 0x46, 0x62, 0x3f, 0x82, 0x35, 0xb3, 0x83, 0x42, 0xd5, 0x6e, 0x42, 0x4d, 0x48,
0x66, 0x2c, 0x9c, 0xa7, 0x96, 0x16, 0x57, 0x0a, 0xa8, 0xef, 0x28, 0xbc, 0xfd, 0x6f, 0x2b, 0xb0,
0x2a, 0xa0, 0xbb, 0x7e, 0x18, 0xd3, 0x93, 0xe9, 0x78, 0xec, 0x46, 0x05, 0x22, 0x6f, 0xbd, 0x41,
0xe4, 0x4b, 0xa6, 0xc8, 0x33, 0x41, 0xbc, 0x70, 0xbd, 0x80, 0x3b, 0x1d, 0x5c, 0x5f, 0x68, 0x10,
0x72, 0x17, 0xda, 0x03, 0x3f, 0x8c, 0xb9, 0x11, 0xae, 0x87, 0x35, 0xb2, 0xe0, 0xbc, 0x8a, 0xaa,
0x16, 0xa9, 0x28, 0x5d, 0xc5, 0x2c, 0x66, 0x54, 0x8c, 0x0d, 0x4d, 0x56, 0x29, 0x95, 0x1a, 0x73,
0x89, 0x1b, 0xe6, 0x3a, 0x8c, 0xf5, 0x27, 0x2b, 0xd0, 0x5c, 0x7b, 0xb4, 0x8b, 0xc4, 0xd9, 0x1b,
0x53, 0xd4, 0xc8, 0x1a, 0x75, 0x5d, 0x88, 0x73, 0x1e, 0x45, 0x1e, 0x33, 0x5f, 0x97, 0xb5, 0x85,
0x66, 0x01, 0xa0, 0x59, 0xf0, 0x81, 0xb9, 0x22, 0xfa, 0xdc, 0x6f, 0xb1, 0xc2, 0x34, 0xa2, 0x68,
0x2a, 0x68, 0x5f, 0xda, 0x7f, 0x64, 0x41, 0x43, 0xc3, 0x91, 0x6b, 0xb0, 0xb2, 0xfb, 0xec, 0xd9,
0xf1, 0xbe, 0xb3, 0x73, 0xfa, 0xf4, 0x07, 0xfb, 0xfd, 0xdd, 0xc3, 0x67, 0x27, 0xfb, 0x9d, 0x05,
0x06, 0x3e, 0x7c, 0xb6, 0xbb, 0x73, 0xd8, 0x7f, 0xfc, 0xcc, 0xd9, 0x95, 0x60, 0x8b, 0xac, 0x03,
0x71, 0xf6, 0x3f, 0x7d, 0x76, 0xba, 0x6f, 0xc0, 0x4b, 0xa4, 0x03, 0xcd, 0x47, 0xce, 0xfe, 0xce,
0xee, 0x81, 0x80, 0x94, 0xc9, 0x1a, 0x74, 0x1e, 0x3f, 0x3f, 0xda, 0x7b, 0x7a, 0xf4, 0xa4, 0xbf,
0xbb, 0x73, 0xb4, 0xbb, 0x7f, 0xb8, 0xbf, 0xd7, 0xa9, 0x90, 0x65, 0xa8, 0xef, 0x3c, 0xda, 0x39,
0xda, 0x7b, 0x76, 0xb4, 0xbf, 0xd7, 0xa9, 0xda, 0xff, 0xd5, 0x82, 0x6b, 0xd8, 0xeb, 0x61, 0x56,
0x40, 0x6e, 0x41, 0x63, 0x10, 0x86, 0x13, 0x66, 0x8e, 0xa7, 0x1b, 0x8e, 0x0e, 0x62, 0xcc, 0xcf,
0xc5, 0xf5, 0x3c, 0x8c, 0x06, 0x54, 0xc8, 0x07, 0x20, 0xe8, 0x31, 0x83, 0x30, 0xe6, 0x17, 0xcb,
0xcb, 0x29, 0xb8, 0x78, 0x34, 0x38, 0x8c, 0x93, 0xac, 0xc3, 0xe2, 0x59, 0x44, 0xdd, 0xc1, 0x85,
0x90, 0x0c, 0x51, 0x22, 0x5f, 0x4d, 0xfd, 0xc5, 0x01, 0x9b, 0x7d, 0x9f, 0x0e, 0x91, 0x63, 0x6a,
0x4e, 0x5b, 0xc0, 0x77, 0x05, 0x98, 0xe9, 0x27, 0xf7, 0xcc, 0x0d, 0x86, 0x61, 0x40, 0x87, 0xc2,
0x18, 0x4d, 0x01, 0xf6, 0x31, 0xac, 0x67, 0xc7, 0x27, 0xe4, 0xeb, 0x63, 0x4d, 0xbe, 0xb8, 0x6d,
0xd8, 0x9b, 0xbf, 0x9a, 0x9a, 0xac, 0xfd, 0x79, 0x09, 0x2a, 0xcc, 0x54, 0x98, 0x6f, 0x56, 0xe8,
0xd6, 0x5f, 0x39, 0x17, 0x03, 0x45, 0x17, 0x94, 0x6f, 0x1e, 0x7c, 0x83, 0xd5, 0x20, 0x29, 0x3e,
0xa2, 0x83, 0x4b, 0x1c, 0xb1, 0xc2, 0x33, 0x08, 0x13, 0x10, 0x66, 0x9a, 0xe3, 0xd7, 0x42, 0x40,
0x64, 0x59, 0xe2, 0xf0, 0xcb, 0xa5, 0x14, 0x87, 0xdf, 0x75, 0x61, 0xc9, 0x0b, 0xce, 0xc2, 0x69,
0x30, 0x44, 0x81, 0xa8, 0x39, 0xb2, 0x88, 0x51, 0x57, 0x14, 0x54, 0x6f, 0x2c, 0xd9, 0x3f, 0x05,
0x90, 0xfb, 0x50, 0x8f, 0x67, 0xc1, 0x40, 0xe7, 0xf9, 0x35, 0x31, 0x4b, 0x6c, 0x0e, 0xb6, 0x4e,
0x66, 0xc1, 0x00, 0x39, 0x3c, 0x25, 0xb3, 0xff, 0x00, 0x6a, 0x12, 0xcc, 0xd8, 0xf2, 0xf9, 0xd1,
0xf7, 0x8e, 0x9e, 0xbd, 0x38, 0xea, 0x9f, 0xfc, 0xf0, 0x68, 0xb7, 0xb3, 0x40, 0xda, 0xd0, 0xd8,
0xd9, 0x45, 0x4e, 0x47, 0x80, 0xc5, 0x48, 0x8e, 0x77, 0x4e, 0x4e, 0x14, 0xa4, 0x64, 0x13, 0xe6,
0x5e, 0xc7, 0x68, 0x8f, 0xa9, 0xa8, 0xe2, 0xc7, 0xb0, 0xa2, 0xc1, 0x52, 0xdb, 0x7e, 0xc2, 0x00,
0x19, 0xdb, 0x1e, 0x0d, 0x39, 0x8e, 0xb1, 0x3b, 0xd0, 0x7a, 0x42, 0x93, 0xa7, 0xc1, 0x79, 0x28,
0x6b, 0xfa, 0x9f, 0x15, 0x68, 0x2b, 0x90, 0xa8, 0xe8, 0x2e, 0xb4, 0xbd, 0x21, 0x0d, 0x12, 0x2f,
0x99, 0xf5, 0x0d, 0x2f, 0x3e, 0x0b, 0x66, 0x06, 0xb0, 0xeb, 0x7b, 0xae, 0x0c, 0x6e, 0xf3, 0x02,
0xf3, 0x6a, 0xd9, 0xee, 0x2c, 0x37, 0x5c, 0xc5, 0x57, 0x3c, 0x78, 0x50, 0x88, 0x63, 0x1a, 0x88,
0xc1, 0xc5, 0x16, 0xa3, 0x3e, 0xe1, 0x86, 0x60, 0x11, 0x8a, 0x2d, 0x15, 0xaf, 0x89, 0x0d, 0xb9,
0xca, 0x77, 0x70, 0x05, 0xc8, 0x45, 0x8f, 0x17, 0xb9, 0x7e, 0xcc, 0x46, 0x8f, 0xb5, 0x08, 0x74,
0x2d, 0x17, 0x81, 0x66, 0xfa, 0x73, 0x16, 0x0c, 0xe8, 0xb0, 0x9f, 0x84, 0x7d, 0xd4, 0xf3, 0xc8,
0x12, 0x35, 0x27, 0x0b, 0x26, 0x37, 0x60, 0x29, 0xa1, 0x71, 0x12, 0x50, 0x1e, 0xf6, 0xab, 0x3d,
0x2a, 0x75, 0x2d, 0x47, 0x82, 0x98, 0xd5, 0x3e, 0x8d, 0xbc, 0xb8, 0xdb, 0xc4, 0xd8, 0x32, 0xfe,
0x26, 0xdf, 0x84, 0x6b, 0x67, 0x34, 0x4e, 0xfa, 0x17, 0xd4, 0x1d, 0xd2, 0x08, 0xd9, 0x8b, 0x07,
0xb1, 0xb9, 0x31, 0x54, 0x8c, 0x64, 0x8c, 0x7b, 0x49, 0xa3, 0xd8, 0x0b, 0x03, 0x34, 0x83, 0xea,
0x8e, 0x2c, 0xb2, 0xfa, 0xd8, 0xe0, 0xd5, 0x26, 0xad, 0x66, 0xb0, 0x8d, 0x03, 0x2f, 0x46, 0x92,
0xdb, 0xb0, 0x88, 0x03, 0x88, 0xbb, 0x1d, 0xe4, 0x99, 0x66, 0x2a, 0xf3, 0x5e, 0xe0, 0x08, 0x1c,
0x5b, 0xe5, 0x41, 0xe8, 0x87, 0x11, 0xda, 0x42, 0x75, 0x87, 0x17, 0xcc, 0xd9, 0x19, 0x45, 0xee,
0xe4, 0x42, 0xd8, 0x43, 0x59, 0xf0, 0x77, 0x2b, 0xb5, 0x46, 0xa7, 0x69, 0xff, 0x05, 0xa8, 0x62,
0xb5, 0x58, 0x1d, 0x4e, 0xa6, 0x25, 0xaa, 0x43, 0x68, 0x17, 0x96, 0x02, 0x9a, 0x5c, 0x85, 0xd1,
0x4b, 0x79, 0x52, 0x22, 0x8a, 0xf6, 0xcf, 0xd1, 0x6f, 0x52, 0x27, 0x07, 0xcf, 0xd1, 0xe8, 0x63,
0xde, 0x2f, 0x5f, 0xaa, 0xf8, 0xc2, 0x15, 0xae, 0x5c, 0x0d, 0x01, 0x27, 0x17, 0x2e, 0xd3, 0xb5,
0xc6, 0xea, 0x73, 0xef, 0xb8, 0x81, 0xb0, 0x03, 0xbe, 0xf8, 0xb7, 0xa1, 0x25, 0xcf, 0x24, 0xe2,
0xbe, 0x4f, 0xcf, 0x13, 0x19, 0xdb, 0x0a, 0xa6, 0x63, 0x74, 0xa1, 0x0f, 0xe9, 0x79, 0x62, 0x1f,
0xc1, 0x8a, 0xd0, 0x7f, 0xcf, 0x26, 0x54, 0x36, 0xfd, 0xfb, 0x45, 0x76, 0x44, 0xe3, 0xfe, 0xaa,
0xa9, 0x30, 0xf9, 0x29, 0x8c, 0x49, 0x69, 0x3b, 0x40, 0x74, 0x7d, 0x2a, 0x2a, 0x14, 0x9b, 0xb9,
0x8c, 0xde, 0x89, 0xe1, 0x18, 0x30, 0x36, 0x3f, 0xf1, 0x74, 0x30, 0x90, 0x27, 0x49, 0x35, 0x47,
0x16, 0xed, 0x7f, 0x6e, 0xc1, 0x2a, 0xd6, 0x26, 0x2d, 0x21, 0xb1, 0x67, 0x3d, 0xf8, 0x02, 0xdd,
0x6c, 0x0e, 0xf4, 0x88, 0xe6, 0x1a, 0x54, 0xf5, 0x5d, 0x8c, 0x17, 0xbe, 0x78, 0xa4, 0xa4, 0x92,
0x8d, 0x94, 0xd8, 0xff, 0xc0, 0x82, 0x15, 0xbe, 0x91, 0xa0, 0x1d, 0x2c, 0x86, 0xff, 0x6d, 0x58,
0xe6, 0x16, 0x81, 0xd0, 0x0a, 0xa2, 0xa3, 0xa9, 0x6a, 0x45, 0x28, 0x27, 0x3e, 0x58, 0x70, 0x4c,
0x62, 0xf2, 0x10, 0xad, 0xb2, 0xa0, 0x8f, 0xd0, 0x82, 0x33, 0x47, 0x73, 0xae, 0x0f, 0x16, 0x1c,
0x8d, 0xfc, 0x51, 0x0d, 0x16, 0xb9, 0x13, 0x61, 0x3f, 0x81, 0x65, 0xa3, 0x21, 0x23, 0x4a, 0xd3,
0xe4, 0x51, 0x9a, 0x5c, 0x38, 0xb4, 0x54, 0x10, 0x0e, 0xfd, 0xd7, 0x65, 0x20, 0x8c, 0x59, 0x32,
0xab, 0xc1, 0xbc, 0x98, 0x70, 0x68, 0xf8, 0xa4, 0x4d, 0x47, 0x07, 0x91, 0x2d, 0x20, 0x5a, 0x51,
0x46, 0xac, 0xf9, 0x96, 0x59, 0x80, 0x61, 0x6a, 0x56, 0x58, 0x1c, 0xc2, 0x36, 0x10, 0xde, 0x37,
0x9f, 0xf6, 0x42, 0x1c, 0xdb, 0x15, 0x27, 0xd3, 0xf8, 0x02, 0x7d, 0x05, 0xe1, 0xb5, 0xca, 0x72,
0x76, 0x7d, 0x17, 0xdf, 0xb8, 0xbe, 0x4b, 0xb9, 0x48, 0x98, 0xe6, 0x37, 0xd5, 0x4c, 0xbf, 0xe9,
0x36, 0x2c, 0x8f, 0x99, 0x9d, 0x9c, 0xf8, 0x83, 0xfe, 0x98, 0xb5, 0x2e, 0x9c, 0x54, 0x03, 0x48,
0x36, 0xa1, 0x23, 0x5d, 0x17, 0xe5, 0x9c, 0xf1, 0x73, 0x94, 0x1c, 0x9c, 0xe9, 0xff, 0x34, 0x36,
0xd6, 0xc0, 0xce, 0xa6, 0x00, 0xe6, 0x89, 0xc5, 0x8c, 0x43, 0xfa, 0xd3, 0x40, 0x1c, 0x3b, 0xd2,
0x21, 0xba, 0xa7, 0x35, 0x27, 0x8f, 0xb0, 0xff, 0xae, 0x05, 0x1d, 0xb6, 0x66, 0x06, 0x5b, 0x7e,
0x02, 0x28, 0x15, 0x6f, 0xc9, 0x95, 0x06, 0x2d, 0x79, 0x00, 0x75, 0x2c, 0x87, 0x13, 0x1a, 0x08,
0x9e, 0xec, 0x9a, 0x3c, 0x99, 0xea, 0x93, 0x83, 0x05, 0x27, 0x25, 0xd6, 0x38, 0xf2, 0x3f, 0x59,
0xd0, 0x10, 0xad, 0xfc, 0xd6, 0xb1, 0x97, 0x9e, 0x76, 0x4e, 0xcc, 0x39, 0x29, 0x3d, 0x16, 0xbe,
0x0b, 0xed, 0xb1, 0x9b, 0x4c, 0x23, 0xb6, 0x9f, 0x1b, 0x71, 0x97, 0x2c, 0x98, 0x6d, 0xce, 0xa8,
0x3a, 0xe3, 0x7e, 0xe2, 0xf9, 0x7d, 0x89, 0x15, 0x27, 0xb2, 0x45, 0x28, 0xa6, 0x41, 0xe2, 0xc4,
0x1d, 0x51, 0xb1, 0xef, 0xf2, 0x82, 0xdd, 0x85, 0x75, 0x31, 0xa0, 0x8c, 0x7d, 0x6d, 0xff, 0xcb,
0x65, 0xd8, 0xc8, 0xa1, 0x54, 0xfe, 0x88, 0x08, 0x28, 0xf8, 0xde, 0xf8, 0x2c, 0x54, 0xce, 0x89,
0xa5, 0xc7, 0x1a, 0x0c, 0x14, 0x19, 0xc1, 0x35, 0x69, 0x60, 0xb0, 0x39, 0x4d, 0x37, 0xc3, 0x12,
0xee, 0x72, 0x1f, 0x99, 0x4b, 0x98, 0x6d, 0x50, 0xc2, 0x75, 0x21, 0x2e, 0xae, 0x8f, 0x5c, 0x40,
0x57, 0x59, 0x32, 0x42, 0x59, 0x6b, 0xd6, 0x0e, 0x6b, 0xeb, 0xc3, 0x37, 0xb4, 0x65, 0x98, 0xe3,
0xce, 0xdc, 0xda, 0xc8, 0x0c, 0x6e, 0x4a, 0x1c, 0x6a, 0xe3, 0x7c, 0x7b, 0x95, 0xb7, 0x1a, 0x1b,
0x3a, 0x1a, 0x66, 0xa3, 0x6f, 0xa8, 0x98, 0xfc, 0x14, 0xd6, 0xaf, 0x5c, 0x2f, 0x91, 0xdd, 0xd2,
0x6c, 0x8b, 0x2a, 0x36, 0x79, 0xff, 0x0d, 0x4d, 0xbe, 0xe0, 0x1f, 0x1b, 0x5b, 0xd4, 0x9c, 0x1a,
0x7b, 0xbf, 0x2e, 0x41, 0xcb, 0xac, 0x87, 0xb1, 0xa9, 0x90, 0x7d, 0xa9, 0x03, 0xa5, 0x35, 0x9a,
0x01, 0xe7, 0xfd, 0xfb, 0x52, 0x91, 0x7f, 0xaf, 0x7b, 0xd5, 0xe5, 0x37, 0x05, 0xee, 0x2a, 0x6f,
0x17, 0xb8, 0xab, 0x16, 0x06, 0xee, 0xe6, 0xc7, 0x77, 0x16, 0x7f, 0xdb, 0xf8, 0xce, 0xd2, 0x6b,
0xe3, 0x3b, 0xbd, 0xff, 0x63, 0x01, 0xc9, 0x73, 0x2f, 0x79, 0xc2, 0x43, 0x1a, 0x01, 0xf5, 0x85,
0x12, 0xfb, 0xfa, 0xdb, 0x49, 0x80, 0x5c, 0x2d, 0xf9, 0x35, 0x13, 0x45, 0x3d, 0x89, 0x43, 0x37,
0xaf, 0x96, 0x9d, 0x22, 0x54, 0x26, 0x78, 0x59, 0x79, 0x73, 0xf0, 0xb2, 0xfa, 0xe6, 0xe0, 0xe5,
0x62, 0x36, 0x78, 0xd9, 0xfb, 0x1b, 0x16, 0xac, 0x16, 0xb0, 0xd9, 0x97, 0x37, 0x70, 0xc6, 0x18,
0x86, 0xf6, 0x29, 0x09, 0xc6, 0xd0, 0x81, 0xbd, 0xbf, 0x0a, 0xcb, 0x86, 0x68, 0x7d, 0x79, 0xed,
0x67, 0x2d, 0x44, 0xce, 0xd9, 0x06, 0xac, 0xf7, 0xbf, 0x4a, 0x40, 0xf2, 0xe2, 0xfd, 0xff, 0xb5,
0x0f, 0xf9, 0x79, 0x2a, 0x17, 0xcc, 0xd3, 0xff, 0xd3, 0x9d, 0xe7, 0x43, 0x58, 0x11, 0x99, 0x69,
0x5a, 0x20, 0x8b, 0x73, 0x4c, 0x1e, 0xc1, 0x6c, 0x64, 0x33, 0x72, 0x5c, 0x33, 0x32, 0x71, 0xb4,
0xed, 0x37, 0x13, 0x40, 0xb6, 0x7b, 0xd0, 0x15, 0x33, 0xb4, 0x7f, 0x49, 0x83, 0xe4, 0x64, 0x7a,
0xc6, 0x53, 0xb3, 0xbc, 0x30, 0xb0, 0xff, 0x4d, 0x59, 0x99, 0xf9, 0x88, 0x14, 0x06, 0xc5, 0x37,
0xa1, 0xa9, 0x6f, 0x1f, 0x62, 0x39, 0x32, 0x71, 0x4c, 0x66, 0x4a, 0xe8, 0x54, 0x64, 0x0f, 0x5a,
0xa8, 0x24, 0x87, 0xea, 0xbb, 0x12, 0x7e, 0xf7, 0x9a, 0xf8, 0xcc, 0xc1, 0x82, 0x93, 0xf9, 0x86,
0x7c, 0x07, 0x5a, 0xa6, 0xf3, 0x27, 0xac, 0x92, 0x22, 0x6f, 0x80, 0x7d, 0x6e, 0x12, 0x93, 0x1d,
0xe8, 0x64, 0xbd, 0x47, 0x91, 0x29, 0x31, 0xa7, 0x82, 0x1c, 0x39, 0x79, 0x20, 0x8e, 0x10, 0xab,
0x18, 0x37, 0xb9, 0x6d, 0x7e, 0xa6, 0x4d, 0xd3, 0x16, 0xff, 0xa3, 0x1d, 0x2a, 0xfe, 0x21, 0x40,
0x0a, 0x23, 0x1d, 0x68, 0x3e, 0x3b, 0xde, 0x3f, 0xea, 0xef, 0x1e, 0xec, 0x1c, 0x1d, 0xed, 0x1f,
0x76, 0x16, 0x08, 0x81, 0x16, 0x86, 0xf9, 0xf6, 0x14, 0xcc, 0x62, 0x30, 0x11, 0x58, 0x91, 0xb0,
0x12, 0x59, 0x83, 0xce, 0xd3, 0xa3, 0x0c, 0xb4, 0xfc, 0xa8, 0xae, 0xe4, 0xc3, 0x5e, 0x87, 0x35,
0x9e, 0x79, 0xf8, 0x88, 0xb3, 0x87, 0xb4, 0x4e, 0xfe, 0x89, 0x05, 0xd7, 0x32, 0x88, 0x34, 0x95,
0x86, 0x1b, 0x20, 0xa6, 0x55, 0x62, 0x02, 0xf1, 0x58, 0x40, 0xda, 0x9a, 0x19, 0x0d, 0x92, 0x47,
0x30, 0x9e, 0xd7, 0x6c, 0xd3, 0x8c, 0x24, 0x15, 0xa1, 0xec, 0x0d, 0x9e, 0x1f, 0x89, 0x99, 0x94,
0x46, 0xc7, 0xcf, 0x79, 0x46, 0xa3, 0x8e, 0x48, 0x8f, 0x64, 0xcd, 0x2e, 0xcb, 0x22, 0x73, 0x2b,
0x0c, 0x63, 0xc7, 0xec, 0x6f, 0x21, 0xce, 0xfe, 0xa3, 0x0a, 0x90, 0xef, 0x4f, 0x69, 0x34, 0xc3,
0x7c, 0x19, 0x15, 0x35, 0xdd, 0xc8, 0xc6, 0x04, 0x17, 0x27, 0xd3, 0xb3, 0xef, 0xd1, 0x99, 0xcc,
0x1c, 0x2b, 0xa5, 0x99, 0x63, 0x45, 0xd9, 0x5b, 0x95, 0x37, 0x67, 0x6f, 0x55, 0xdf, 0x94, 0xbd,
0xf5, 0x15, 0x58, 0xf6, 0x46, 0x41, 0xc8, 0x64, 0x9e, 0xd9, 0x09, 0x71, 0x77, 0xf1, 0x56, 0x99,
0xf9, 0xd6, 0x02, 0x78, 0xc4, 0x60, 0xe4, 0x61, 0x4a, 0x44, 0x87, 0x23, 0xcc, 0x14, 0xd4, 0xb5,
0xc0, 0xfe, 0x70, 0x44, 0x0f, 0xc3, 0x81, 0x9b, 0x84, 0x11, 0x06, 0x76, 0xe4, 0xc7, 0x0c, 0x1e,
0x93, 0xdb, 0xd0, 0x8a, 0xc3, 0x29, 0xb3, 0x9c, 0xe4, 0x58, 0x79, 0x24, 0xa9, 0xc9, 0xa1, 0xc7,
0x7c, 0xc4, 0x5b, 0xb0, 0x3a, 0x8d, 0x69, 0x7f, 0xec, 0xc5, 0x31, 0xdb, 0x1d, 0x07, 0x61, 0x90,
0x44, 0xa1, 0x2f, 0xe2, 0x49, 0x2b, 0xd3, 0x98, 0x7e, 0xca, 0x31, 0xbb, 0x1c, 0x41, 0xbe, 0x99,
0x76, 0x69, 0xe2, 0x7a, 0x51, 0xdc, 0x05, 0xec, 0x92, 0x1c, 0x29, 0xeb, 0xf7, 0xb1, 0xeb, 0x45,
0xaa, 0x2f, 0xac, 0x10, 0x93, 0x9d, 0x5c, 0x8a, 0x99, 0x8c, 0xc9, 0xe7, 0x57, 0xe7, 0xcb, 0xcf,
0x34, 0x13, 0x09, 0x52, 0x5b, 0x50, 0x93, 0xdd, 0x63, 0x4e, 0xf4, 0x79, 0x14, 0x8e, 0xa5, 0x13,
0xcd, 0x7e, 0x93, 0x16, 0x94, 0x92, 0x50, 0x7c, 0x5c, 0x4a, 0x42, 0xfb, 0x87, 0xd0, 0xd0, 0x66,
0x18, 0xb3, 0xe8, 0x84, 0xc1, 0x26, 0xbc, 0xef, 0x0a, 0xf7, 0x8f, 0x02, 0xea, 0x3f, 0x1d, 0x92,
0xaf, 0xc1, 0xca, 0xd0, 0x8b, 0x28, 0x26, 0x44, 0xf6, 0x23, 0x7a, 0x49, 0xa3, 0x58, 0xc6, 0x29,
0x3a, 0x0a, 0xe1, 0x70, 0xb8, 0xfd, 0x10, 0x56, 0x8d, 0x81, 0x2b, 0xa9, 0x5d, 0xc4, 0x8c, 0x2e,
0x19, 0x2a, 0x35, 0xb3, 0xbd, 0x04, 0xce, 0xfe, 0x67, 0x65, 0x28, 0x1f, 0x84, 0x13, 0xfd, 0x40,
0xc8, 0x32, 0x0f, 0x84, 0x84, 0xc1, 0xd9, 0x57, 0xf6, 0xa4, 0xb0, 0x0a, 0x0c, 0x20, 0xd9, 0x84,
0x96, 0x3b, 0x4e, 0xfa, 0x49, 0xc8, 0x0c, 0xec, 0x2b, 0x37, 0x1a, 0x72, 0x51, 0x46, 0x56, 0xca,
0x60, 0xc8, 0x1a, 0x94, 0x95, 0x9d, 0x84, 0x04, 0xac, 0xc8, 0xbc, 0x3b, 0x3c, 0x0a, 0x9f, 0x89,
0x38, 0xa7, 0x28, 0x31, 0x4d, 0x61, 0x7e, 0xcf, 0x5d, 0x6b, 0xbe, 0xdb, 0x15, 0xa1, 0x98, 0xf1,
0xcb, 0x84, 0x67, 0x9c, 0xda, 0x92, 0xaa, 0xac, 0x47, 0xf0, 0x6b, 0x66, 0x04, 0xff, 0x16, 0x34,
0x12, 0xff, 0xb2, 0x3f, 0x71, 0x67, 0x7e, 0xe8, 0x0e, 0x05, 0xd3, 0xea, 0x20, 0xf2, 0x6d, 0x4e,
0xc1, 0x36, 0xd8, 0x68, 0x28, 0x99, 0x55, 0xee, 0x50, 0x07, 0xe1, 0x64, 0xeb, 0xd4, 0xbf, 0x74,
0x38, 0x92, 0xf3, 0x9b, 0x4e, 0xde, 0xfb, 0x0e, 0xb4, 0x33, 0xf8, 0x2f, 0x94, 0xe0, 0xf8, 0x1b,
0x0b, 0xaa, 0xb8, 0x74, 0xcc, 0xb0, 0xe0, 0x9a, 0x57, 0x1d, 0x59, 0x61, 0x0d, 0xcb, 0x4e, 0x16,
0x4c, 0x6c, 0x23, 0x33, 0xb8, 0xa4, 0xe6, 0x5b, 0xcf, 0x0e, 0xbe, 0x05, 0x75, 0x5e, 0x52, 0x59,
0xae, 0x48, 0x92, 0x02, 0xc9, 0x4d, 0xa8, 0x5c, 0x84, 0x13, 0xe9, 0x7b, 0x41, 0x3a, 0x5e, 0x07,
0xe1, 0x69, 0x7f, 0x58, 0x7d, 0x7c, 0xd6, 0xb9, 0x7d, 0x9b, 0x05, 0x33, 0x9f, 0x42, 0x55, 0xab,
0xaf, 0x62, 0x06, 0x6a, 0x3f, 0x87, 0x36, 0x13, 0x2e, 0x2d, 0x84, 0x3f, 0x5f, 0xcb, 0x7e, 0x95,
0x6d, 0xda, 0x03, 0x7f, 0x3a, 0xa4, 0xba, 0x07, 0x8c, 0x21, 0x5a, 0x01, 0x97, 0xb6, 0x9f, 0xfd,
0xaf, 0x2c, 0x2e, 0xb4, 0xac, 0x5e, 0x72, 0x17, 0x2a, 0x4c, 0x57, 0x66, 0x02, 0x1e, 0x2a, 0x25,
0x85, 0xd1, 0x39, 0x48, 0xc1, 0x4c, 0x42, 0x0c, 0xa2, 0xea, 0xb5, 0xf3, 0x10, 0x6a, 0xea, 0x3e,
0xaa, 0x91, 0x65, 0xbc, 0xae, 0x0c, 0x94, 0x6c, 0x69, 0x27, 0x50, 0x15, 0x43, 0xff, 0x4a, 0x1b,
0x61, 0x38, 0xa2, 0xda, 0xc9, 0xd3, 0x9f, 0x58, 0xb0, 0x6c, 0xf4, 0x89, 0xb1, 0xa9, 0xef, 0xc6,
0x89, 0x48, 0x0b, 0x10, 0x2b, 0xaf, 0x83, 0x74, 0x16, 0x2f, 0x99, 0x2c, 0xae, 0x4e, 0x32, 0xca,
0xfa, 0x49, 0xc6, 0x3d, 0xa8, 0xa7, 0xa9, 0xe1, 0x66, 0xa7, 0x58, 0x8b, 0x32, 0x39, 0x27, 0x25,
0x4a, 0x63, 0xe5, 0x55, 0x2d, 0x56, 0x6e, 0x3f, 0x84, 0x86, 0x46, 0xaf, 0xc7, 0xba, 0x2d, 0x23,
0xd6, 0xad, 0x32, 0xd7, 0x4a, 0x69, 0xe6, 0x9a, 0xfd, 0x8b, 0x12, 0x2c, 0x33, 0xf6, 0xf6, 0x82,
0xd1, 0x71, 0xe8, 0x7b, 0x83, 0x19, 0xb2, 0x95, 0xe4, 0x64, 0xb1, 0x57, 0x4a, 0x36, 0x37, 0xc1,
0x4c, 0xde, 0x65, 0x84, 0x4d, 0x28, 0x27, 0x55, 0x66, 0xda, 0x8b, 0xc9, 0xfe, 0x99, 0x1b, 0x0b,
0x85, 0x20, 0x6c, 0x75, 0x03, 0xc8, 0x74, 0x0c, 0x03, 0x60, 0x1e, 0xe2, 0xd8, 0xf3, 0x7d, 0x8f,
0xd3, 0x72, 0x4f, 0xae, 0x08, 0xc5, 0xda, 0x1c, 0x7a, 0xb1, 0x7b, 0x96, 0x9e, 0x52, 0xaa, 0x32,
0x86, 0x01, 0xdd, 0x57, 0x5a, 0x18, 0x70, 0x11, 0x05, 0xdc, 0x04, 0x66, 0x17, 0x72, 0x29, 0xb7,
0x90, 0xf6, 0x9f, 0x96, 0xa0, 0xa1, 0xb1, 0x85, 0x38, 0x9a, 0x37, 0x37, 0x0d, 0x0d, 0x22, 0xf1,
0x46, 0x5c, 0x40, 0x83, 0x90, 0xdb, 0x66, 0x8b, 0x78, 0x14, 0x80, 0xc2, 0x6e, 0xb0, 0xcf, 0x0d,
0xa8, 0x33, 0xb6, 0xff, 0x08, 0x83, 0x10, 0xe2, 0x4e, 0x86, 0x02, 0x48, 0xec, 0x7d, 0xc4, 0x56,
0x53, 0x2c, 0x02, 0x5e, 0x7b, 0x98, 0xff, 0x00, 0x9a, 0xa2, 0x1a, 0x5c, 0x5f, 0x1c, 0x70, 0x2a,
0x78, 0xc6, 0xda, 0x3b, 0x06, 0xa5, 0xfc, 0xf2, 0xbe, 0xfc, 0xb2, 0xf6, 0xa6, 0x2f, 0x25, 0xa5,
0xfd, 0x44, 0xe5, 0x48, 0x3c, 0x89, 0xdc, 0xc9, 0x85, 0x54, 0x26, 0xf7, 0x60, 0x55, 0xea, 0x8c,
0x69, 0xe0, 0x06, 0x41, 0x38, 0x0d, 0x06, 0x54, 0x26, 0xb8, 0x15, 0xa1, 0xec, 0xa1, 0x4a, 0x87,
0xc6, 0x8a, 0xc8, 0x26, 0x54, 0xb9, 0xa5, 0xc5, 0xf7, 0xd6, 0x62, 0xf5, 0xc1, 0x49, 0xc8, 0x5d,
0xa8, 0x72, 0x83, 0xab, 0x34, 0x57, 0xe0, 0x39, 0x81, 0xbd, 0x09, 0x6d, 0xcc, 0xb2, 0x37, 0xf5,
0x9e, 0xb9, 0x2f, 0x2f, 0x0e, 0x30, 0x0f, 0xdf, 0x5e, 0x03, 0x72, 0xc4, 0xe5, 0x49, 0x3f, 0xe9,
0xfc, 0x4d, 0x19, 0x1a, 0x1a, 0x98, 0xe9, 0x25, 0x3c, 0x9e, 0xea, 0x0f, 0x3d, 0x77, 0x4c, 0x13,
0x1a, 0x09, 0x19, 0xca, 0x40, 0x19, 0x9d, 0x7b, 0x39, 0xea, 0x87, 0xd3, 0xa4, 0x3f, 0xa4, 0xa3,
0x88, 0xf2, 0x0d, 0x88, 0x6d, 0xdd, 0x06, 0x94, 0xd1, 0x31, 0x2e, 0xd6, 0xe8, 0xf8, 0x81, 0x52,
0x06, 0x2a, 0xcf, 0x2d, 0xf9, 0x1c, 0x55, 0xd2, 0x73, 0x4b, 0x3e, 0x23, 0x59, 0x8d, 0x5a, 0x2d,
0xd0, 0xa8, 0x1f, 0xc3, 0x3a, 0xd7, 0x9d, 0x42, 0x6b, 0xf4, 0x33, 0x8c, 0x35, 0x07, 0x4b, 0x36,
0xa1, 0xc3, 0xfa, 0x2c, 0xc5, 0x22, 0xf6, 0x7e, 0xce, 0x65, 0xcb, 0x72, 0x72, 0x70, 0x46, 0x8b,
0xc1, 0x74, 0x9d, 0x96, 0x27, 0x8f, 0xe4, 0xe0, 0x48, 0xeb, 0xbe, 0x32, 0x69, 0xeb, 0x82, 0x36,
0x03, 0x27, 0x0f, 0x60, 0x63, 0x4c, 0x87, 0x9e, 0x6b, 0x56, 0x81, 0xb1, 0x2d, 0x9e, 0x93, 0x36,
0x0f, 0xcd, 0x5a, 0x61, 0xb3, 0xf0, 0xf3, 0x70, 0x7c, 0xe6, 0xf1, 0x0d, 0x8d, 0x87, 0xfd, 0x2b,
0x4e, 0x0e, 0x6e, 0x2f, 0x43, 0xe3, 0x24, 0x09, 0x27, 0x72, 0xe9, 0x5b, 0xd0, 0xe4, 0x45, 0x91,
0xce, 0xf8, 0x0e, 0x5c, 0x47, 0x5e, 0x3d, 0x0d, 0x27, 0xa1, 0x1f, 0x8e, 0x66, 0x86, 0xf3, 0xfe,
0x1f, 0x2d, 0x58, 0x35, 0xb0, 0xa9, 0xf7, 0x8e, 0x91, 0x46, 0x99, 0x87, 0xc6, 0xd9, 0x7b, 0x45,
0xdb, 0x0e, 0x38, 0x21, 0x3f, 0xd4, 0x79, 0x2e, 0x52, 0xd3, 0x76, 0xd2, 0x6b, 0x71, 0xf2, 0x43,
0xce, 0xeb, 0xdd, 0x3c, 0xaf, 0x8b, 0xef, 0xe5, 0xad, 0x38, 0x59, 0xc5, 0x77, 0x44, 0xaa, 0xcf,
0x50, 0x0c, 0xba, 0x6c, 0xa6, 0x67, 0xe8, 0xc1, 0x1e, 0xd9, 0x83, 0x81, 0x02, 0xc6, 0xf6, 0x2f,
0x2d, 0x80, 0xb4, 0x77, 0x98, 0x20, 0xa2, 0xb6, 0x34, 0x7e, 0x05, 0x53, 0xdb, 0xbe, 0xde, 0x87,
0xa6, 0x3a, 0xe3, 0x4f, 0x77, 0xc9, 0x86, 0x84, 0x31, 0xab, 0xe2, 0x0e, 0xb4, 0x47, 0x7e, 0x78,
0x86, 0xd6, 0x0b, 0xe6, 0xc7, 0xc6, 0x22, 0xa9, 0xb3, 0xc5, 0xc1, 0x8f, 0x05, 0x34, 0xdd, 0x52,
0x2b, 0xfa, 0x96, 0x5a, 0xbc, 0x41, 0xfe, 0xed, 0x92, 0x3a, 0x68, 0x4d, 0x67, 0x62, 0xae, 0x84,
0x93, 0xfb, 0x39, 0x75, 0x3e, 0xe7, 0x5c, 0x13, 0x1d, 0x87, 0xe3, 0x37, 0xc6, 0x7d, 0x1f, 0x42,
0x2b, 0xe2, 0xba, 0x52, 0x2a, 0xd2, 0xca, 0x6b, 0x14, 0xe9, 0x72, 0x64, 0xec, 0xc6, 0x5f, 0x85,
0x8e, 0x3b, 0xbc, 0xa4, 0x51, 0xe2, 0x61, 0x1c, 0x0c, 0x4d, 0x27, 0x3e, 0xb8, 0xb6, 0x06, 0x47,
0x0b, 0xe5, 0x0e, 0xb4, 0x45, 0x7a, 0xad, 0xa2, 0x14, 0x97, 0x99, 0x52, 0x30, 0x23, 0xb4, 0x7f,
0x25, 0xcf, 0x74, 0xcd, 0x95, 0x9d, 0x3f, 0x23, 0xfa, 0xe8, 0x4a, 0x99, 0xd1, 0x7d, 0x45, 0x9c,
0xaf, 0x0e, 0x65, 0xb0, 0xad, 0xac, 0x25, 0x8b, 0x0d, 0xc5, 0x79, 0xb8, 0x39, 0xa5, 0x95, 0xb7,
0x99, 0x52, 0xfb, 0xcf, 0x2c, 0x58, 0x3a, 0x08, 0x27, 0x07, 0x22, 0x6d, 0x0e, 0xc5, 0x43, 0xe5,
0xb5, 0xcb, 0xe2, 0x6b, 0x12, 0xea, 0x0a, 0x2d, 0x90, 0xe5, 0xac, 0x05, 0xf2, 0x97, 0xe0, 0x1d,
0x0c, 0xf5, 0x46, 0xe1, 0x24, 0x8c, 0x98, 0x88, 0xba, 0x3e, 0x37, 0x37, 0xc2, 0x20, 0xb9, 0x90,
0x2a, 0xf4, 0x75, 0x24, 0x18, 0x7f, 0xf1, 0x93, 0xcb, 0x3e, 0x77, 0x9b, 0x84, 0xc5, 0xc4, 0x35,
0x6b, 0x1e, 0x61, 0xff, 0x3e, 0xd4, 0xd1, 0x9b, 0xc0, 0x61, 0x7d, 0x08, 0xf5, 0x8b, 0x70, 0xd2,
0xbf, 0xf0, 0x82, 0x44, 0x8a, 0x7c, 0x2b, 0x35, 0xf3, 0x0f, 0x70, 0x42, 0x14, 0x81, 0xfd, 0xa7,
0x8b, 0xb0, 0xf4, 0x34, 0xb8, 0x0c, 0xbd, 0x01, 0x9e, 0x1f, 0x8f, 0xe9, 0x38, 0x94, 0x59, 0xfe,
0xec, 0x37, 0xb9, 0x01, 0x4b, 0x98, 0xd6, 0x3a, 0xe1, 0x4c, 0xdb, 0xe4, 0x79, 0x22, 0x02, 0x84,
0xb7, 0x0c, 0xd3, 0xbb, 0x56, 0x5c, 0xa8, 0x34, 0x08, 0x73, 0x03, 0x23, 0xfd, 0xae, 0x94, 0x28,
0xa5, 0x9e, 0x51, 0x55, 0xbb, 0x45, 0xc1, 0xda, 0x12, 0x69, 0x7e, 0x3c, 0x0f, 0x8c, 0xb7, 0x25,
0x40, 0xe8, 0xba, 0x46, 0x94, 0x87, 0xea, 0x95, 0x91, 0xc5, 0x5c, 0x57, 0x1d, 0xc8, 0x0c, 0x31,
0xfe, 0x01, 0xa7, 0xe1, 0x1b, 0x80, 0x0e, 0x62, 0xa6, 0x68, 0xf6, 0x7a, 0x1e, 0xbf, 0x1e, 0x99,
0x05, 0x33, 0xfd, 0x3d, 0xa4, 0x4a, 0xcd, 0xf2, 0x71, 0x00, 0xbf, 0x4f, 0x96, 0x85, 0x6b, 0x0e,
0x2f, 0xcf, 0x40, 0x96, 0x0e, 0x2f, 0x63, 0x18, 0xd7, 0xf7, 0xcf, 0xdc, 0xc1, 0x4b, 0xbc, 0x9d,
0x89, 0x27, 0xba, 0x75, 0xc7, 0x04, 0x62, 0xb2, 0x5e, 0xba, 0xaa, 0x98, 0x51, 0x53, 0x71, 0x74,
0x10, 0xb9, 0x0f, 0x0d, 0x74, 0xf2, 0xc5, 0xba, 0xb6, 0x70, 0x5d, 0x3b, 0x7a, 0x14, 0x00, 0x57,
0x56, 0x27, 0xd2, 0xcf, 0xb6, 0xdb, 0xb9, 0x9c, 0x60, 0x77, 0x38, 0x14, 0x29, 0x01, 0x1d, 0x1e,
0xb0, 0x50, 0x00, 0xb6, 0xa3, 0x8b, 0x09, 0xe3, 0x04, 0x2b, 0x48, 0x60, 0xc0, 0xc8, 0x4d, 0xa8,
0x31, 0x0f, 0x6f, 0xe2, 0x7a, 0x43, 0x4c, 0xa2, 0xe1, 0x8e, 0xa6, 0x82, 0xb1, 0x3a, 0xe4, 0x6f,
0xdc, 0x2a, 0x57, 0x71, 0x56, 0x0c, 0x18, 0x9b, 0x1b, 0x55, 0x1e, 0xa7, 0x49, 0xc4, 0x26, 0x90,
0x7c, 0x84, 0x07, 0xb3, 0x09, 0xc5, 0x4c, 0xe1, 0xd6, 0xfd, 0x77, 0xc4, 0x98, 0x05, 0xd3, 0xca,
0xbf, 0x27, 0x8c, 0xc4, 0xe1, 0x94, 0xcc, 0x48, 0xe3, 0xb1, 0xf1, 0x75, 0xc3, 0x48, 0x13, 0xa4,
0x18, 0x1b, 0xe7, 0x04, 0xf6, 0x0e, 0x34, 0xf5, 0x0a, 0x48, 0x0d, 0x2a, 0xcf, 0x8e, 0xf7, 0x8f,
0x3a, 0x0b, 0xa4, 0x01, 0x4b, 0x27, 0xfb, 0xa7, 0xa7, 0x87, 0xfb, 0x7b, 0x1d, 0x8b, 0x34, 0xa1,
0xa6, 0x72, 0x30, 0x4b, 0xac, 0xb4, 0xb3, 0xbb, 0xbb, 0x7f, 0x7c, 0xba, 0xbf, 0xd7, 0x29, 0xdb,
0x7f, 0x5c, 0x82, 0x86, 0x56, 0xf3, 0x6b, 0x82, 0x2f, 0x37, 0x01, 0xd0, 0x63, 0x48, 0x33, 0x31,
0x2a, 0x8e, 0x06, 0x61, 0x1a, 0x51, 0xf9, 0xd2, 0x65, 0xc4, 0xaa, 0x32, 0xce, 0xd5, 0x60, 0x40,
0x27, 0x89, 0x7e, 0xfc, 0x50, 0x75, 0x4c, 0x20, 0xe3, 0x23, 0x01, 0xc0, 0x74, 0x40, 0x2e, 0x5d,
0x3a, 0x88, 0xad, 0x4b, 0x44, 0xe3, 0xd0, 0xbf, 0xa4, 0x9c, 0x84, 0xdb, 0x5f, 0x06, 0x8c, 0xb5,
0x25, 0xd4, 0x8b, 0x96, 0xaa, 0x5b, 0x75, 0x4c, 0x20, 0xf9, 0xba, 0x5c, 0x97, 0x1a, 0xae, 0xcb,
0x46, 0x7e, 0x92, 0xf5, 0x35, 0xb1, 0x13, 0x20, 0x3b, 0xc3, 0xa1, 0xc0, 0xaa, 0xb8, 0x56, 0xaa,
0x20, 0x2c, 0x43, 0x41, 0x14, 0x08, 0x69, 0xa9, 0x58, 0x48, 0x5f, 0xcb, 0xca, 0xf6, 0x3e, 0x34,
0x8e, 0xb5, 0x3b, 0x96, 0xa8, 0xaf, 0xe4, 0xed, 0x4a, 0xa1, 0xe7, 0x34, 0x88, 0xd6, 0x9d, 0x92,
0xde, 0x1d, 0xfb, 0x8f, 0x2d, 0x7e, 0xd9, 0x49, 0x75, 0x9f, 0xb7, 0x6d, 0x43, 0x53, 0x05, 0x97,
0xd3, 0x2c, 0x74, 0x03, 0xc6, 0x68, 0xb0, 0x2b, 0xfd, 0xf0, 0xfc, 0x3c, 0xa6, 0x32, 0x67, 0xd4,
0x80, 0x49, 0x43, 0x91, 0x99, 0x9e, 0x1e, 0x6f, 0x21, 0x16, 0xb9, 0xa3, 0x39, 0x38, 0x63, 0x12,
0x11, 0x43, 0x94, 0xd9, 0xb2, 0xaa, 0xac, 0x92, 0xe5, 0xb3, 0xb3, 0xbc, 0x09, 0x35, 0x55, 0xaf,
0xb9, 0x23, 0x48, 0x4a, 0x85, 0x67, 0x3b, 0x0f, 0x3a, 0x90, 0x46, 0xa7, 0x39, 0xaf, 0xe6, 0x11,
0x64, 0x0b, 0xc8, 0xb9, 0x17, 0x65, 0xc9, 0x39, 0xf3, 0x16, 0x60, 0xec, 0x17, 0xb0, 0x2a, 0xe5,
0x4d, 0xb3, 0x60, 0xcd, 0x45, 0xb4, 0xde, 0xa4, 0x8f, 0x4a, 0x79, 0x7d, 0x64, 0xff, 0x79, 0x19,
0x96, 0xc4, 0x4a, 0xe7, 0xee, 0xe9, 0xf2, 0x75, 0x36, 0x60, 0xa4, 0x6b, 0xdc, 0xe3, 0x43, 0xe5,
0x25, 0x76, 0xa1, 0xdc, 0x3e, 0x53, 0x2e, 0xda, 0x67, 0x08, 0x54, 0x26, 0x6e, 0x72, 0x81, 0x21,
0x96, 0xba, 0x83, 0xbf, 0x65, 0x28, 0xb4, 0x6a, 0x86, 0x42, 0x8b, 0x6e, 0x25, 0x73, 0x13, 0x2a,
0x7f, 0x2b, 0xf9, 0x06, 0xd4, 0xb1, 0x13, 0xda, 0xc9, 0x79, 0x0a, 0x60, 0xdc, 0xcb, 0x0b, 0xa8,
0x21, 0xc4, 0xb5, 0x9a, 0x14, 0xf2, 0x05, 0x76, 0xb6, 0x6f, 0xc2, 0x22, 0xbf, 0xd7, 0x21, 0x72,
0x82, 0x6f, 0xc8, 0xd3, 0x43, 0x4e, 0x27, 0xff, 0xf2, 0xe4, 0x22, 0x47, 0xd0, 0xea, 0xb7, 0x42,
0x1b, 0xe6, 0xad, 0x50, 0x3d, 0x48, 0xdb, 0x34, 0x83, 0xb4, 0xf6, 0x63, 0x58, 0x36, 0xaa, 0x63,
0x9a, 0x55, 0xe4, 0x14, 0x77, 0x16, 0xc8, 0x32, 0xd4, 0x9f, 0x1e, 0xf5, 0x1f, 0x1f, 0x3e, 0x7d,
0x72, 0x70, 0xda, 0xb1, 0x58, 0xf1, 0xe4, 0xf9, 0xee, 0xee, 0xfe, 0xfe, 0x1e, 0x6a, 0x5a, 0x80,
0xc5, 0xc7, 0x3b, 0x4f, 0x0f, 0x51, 0xcf, 0xee, 0x71, 0xde, 0x16, 0x75, 0xa9, 0x13, 0x9b, 0xaf,
0x03, 0x91, 0x3e, 0x3e, 0xe6, 0x16, 0x4d, 0x7c, 0x9a, 0xc8, 0x74, 0xf7, 0x15, 0x81, 0x79, 0xaa,
0x10, 0xf2, 0xb6, 0x46, 0x5a, 0x4b, 0x2a, 0x22, 0x62, 0x92, 0xb2, 0x22, 0x22, 0x48, 0x1d, 0x85,
0xb7, 0x7b, 0xd0, 0xdd, 0xa3, 0xac, 0xb6, 0x1d, 0xdf, 0xcf, 0x74, 0x87, 0x39, 0x6a, 0x05, 0x38,
0xe1, 0xc5, 0x7d, 0x1f, 0xae, 0xed, 0xf0, 0xcc, 0xf6, 0x2f, 0x2b, 0xf1, 0xd1, 0xee, 0xc2, 0x7a,
0xb6, 0x4a, 0xd1, 0xd8, 0x63, 0x58, 0xd9, 0xa3, 0x67, 0xd3, 0xd1, 0x21, 0xbd, 0x4c, 0x1b, 0x22,
0x50, 0x89, 0x2f, 0xc2, 0x2b, 0x31, 0x3f, 0xf8, 0x9b, 0xbc, 0x0b, 0xe0, 0x33, 0x9a, 0x7e, 0x3c,
0xa1, 0x03, 0x79, 0x97, 0x10, 0x21, 0x27, 0x13, 0x3a, 0xb0, 0x3f, 0x06, 0xa2, 0xd7, 0x23, 0xe6,
0x8b, 0xd9, 0x59, 0xd3, 0xb3, 0x7e, 0x3c, 0x8b, 0x13, 0x3a, 0x96, 0x97, 0x24, 0x75, 0x90, 0x7d,
0x07, 0x9a, 0xc7, 0xee, 0xcc, 0xa1, 0x3f, 0x13, 0xf7, 0xd5, 0x37, 0x60, 0x69, 0xe2, 0xce, 0x18,
0x0b, 0xaa, 0xa0, 0x2f, 0xa2, 0xed, 0xff, 0x5d, 0x82, 0x45, 0x4e, 0xc9, 0x6a, 0x1d, 0xd2, 0x38,
0xf1, 0x02, 0x94, 0x34, 0x59, 0xab, 0x06, 0xca, 0xc9, 0x76, 0xa9, 0x40, 0xb6, 0x45, 0x44, 0x42,
0xde, 0xcb, 0x12, 0x02, 0x6c, 0xc0, 0x98, 0xa4, 0xa5, 0x19, 0xcc, 0x3c, 0x34, 0x98, 0x02, 0x32,
0xc7, 0x17, 0xa9, 0x35, 0xc7, 0xfb, 0x27, 0xd5, 0x96, 0x10, 0x63, 0x1d, 0x54, 0x68, 0x33, 0x2e,
0x71, 0x69, 0xcf, 0xd9, 0x8c, 0x39, 0xdb, 0xb0, 0xf6, 0x16, 0xb6, 0x21, 0x0f, 0x53, 0xbc, 0xce,
0x36, 0x84, 0xb7, 0xb0, 0x0d, 0x6d, 0x02, 0x1d, 0xbc, 0xf0, 0xcd, 0xbc, 0x0f, 0xc9, 0xbb, 0xff,
0xd0, 0x82, 0x8e, 0xe0, 0x22, 0x85, 0x23, 0xef, 0x1b, 0x5e, 0x56, 0xe1, 0xfd, 0xa3, 0xdb, 0xb0,
0x8c, 0xbe, 0x8f, 0x52, 0x01, 0xe2, 0x50, 0xc9, 0x00, 0xb2, 0x71, 0xc8, 0xfc, 0x97, 0xb1, 0xe7,
0x8b, 0x45, 0xd1, 0x41, 0x52, 0x8b, 0x44, 0xae, 0xc8, 0xc4, 0xb5, 0x1c, 0x55, 0xb6, 0x7f, 0x6d,
0xc1, 0x8a, 0xd6, 0x61, 0xc1, 0x85, 0x0f, 0x41, 0x4a, 0x03, 0x3f, 0x15, 0xe1, 0x92, 0xbb, 0x61,
0x8a, 0x4d, 0xfa, 0x99, 0x41, 0x8c, 0x8b, 0xe9, 0xce, 0xb0, 0x83, 0xf1, 0x74, 0x2c, 0x76, 0x15,
0x1d, 0xc4, 0x18, 0xe9, 0x8a, 0xd2, 0x97, 0x8a, 0x84, 0xef, 0x6b, 0x06, 0x0c, 0xe3, 0xc3, 0xcc,
0x67, 0x53, 0x44, 0x15, 0x11, 0x1f, 0xd6, 0x81, 0xf6, 0x7f, 0xb1, 0x60, 0x95, 0x3b, 0xdf, 0x22,
0xe0, 0xa1, 0xae, 0xb6, 0x2e, 0xf2, 0x18, 0x04, 0x97, 0xc8, 0x83, 0x05, 0x47, 0x94, 0xc9, 0xb7,
0xde, 0x32, 0x60, 0xa0, 0xd2, 0x83, 0xe7, 0xac, 0x45, 0xb9, 0x68, 0x2d, 0x5e, 0x33, 0xd3, 0x45,
0xa1, 0xfa, 0x6a, 0x61, 0xa8, 0xfe, 0xd1, 0x12, 0x54, 0xe3, 0x41, 0x38, 0xa1, 0xf6, 0x3a, 0xac,
0x99, 0x83, 0x13, 0x2a, 0xe8, 0x97, 0x16, 0x74, 0x1f, 0xf3, 0xc3, 0x3c, 0x2f, 0x18, 0x1d, 0x78,
0x71, 0x12, 0x46, 0xea, 0x05, 0x80, 0x9b, 0x00, 0x71, 0xe2, 0x46, 0xc2, 0x54, 0x15, 0x01, 0xf0,
0x14, 0xc2, 0xfa, 0x48, 0x83, 0x21, 0xc7, 0xf2, 0xb5, 0x51, 0xe5, 0x9c, 0x51, 0x25, 0xc2, 0x03,
0x86, 0x69, 0xf2, 0x01, 0x4f, 0x97, 0x67, 0xc6, 0x13, 0xbd, 0x44, 0xbd, 0xce, 0xfd, 0xee, 0x0c,
0xd4, 0xfe, 0xcf, 0x16, 0xb4, 0xd3, 0x4e, 0x62, 0x5a, 0x87, 0xa9, 0x1d, 0x84, 0x3d, 0x92, 0x6a,
0x07, 0x19, 0x9a, 0xf7, 0x98, 0x81, 0x22, 0xed, 0xf8, 0x14, 0x82, 0x12, 0x2b, 0x4a, 0xe1, 0x54,
0x5a, 0x7c, 0x3a, 0x88, 0x27, 0xbf, 0x32, 0xd3, 0x48, 0x98, 0x79, 0xa2, 0x84, 0x17, 0x8f, 0xc6,
0x09, 0x7e, 0xc5, 0x8f, 0x19, 0x64, 0x91, 0x74, 0xb8, 0x6d, 0xb1, 0xc4, 0x4f, 0x17, 0x99, 0x5d,
0xa1, 0xef, 0xb9, 0x35, 0x3e, 0x3f, 0x6a, 0xcf, 0xfd, 0x3b, 0x16, 0x5c, 0x2f, 0x98, 0x78, 0x21,
0x35, 0x7b, 0xb0, 0x72, 0xae, 0x90, 0x72, 0x72, 0xb8, 0xe8, 0xac, 0xcb, 0xbc, 0x04, 0x73, 0x42,
0x9c, 0xfc, 0x07, 0xca, 0x50, 0xe4, 0xd3, 0x6d, 0xa4, 0x97, 0xe7, 0x11, 0xf6, 0x31, 0xf4, 0xf6,
0x5f, 0x31, 0x21, 0xdc, 0xd5, 0x1f, 0xd0, 0x92, 0xbc, 0x70, 0x3f, 0xa7, 0x64, 0xde, 0x1c, 0xca,
0x39, 0x87, 0x65, 0xa3, 0x2e, 0xf2, 0x8d, 0xb7, 0xad, 0x44, 0x97, 0x17, 0xb9, 0x56, 0xfc, 0x05,
0x30, 0x99, 0xe4, 0xae, 0x81, 0xec, 0x4b, 0x68, 0x7f, 0x3a, 0xf5, 0x13, 0x2f, 0x7d, 0x0d, 0x8c,
0x7c, 0x4b, 0x7c, 0x84, 0x55, 0xc8, 0xa9, 0x2b, 0x6c, 0x4a, 0xa7, 0x63, 0x33, 0x36, 0x66, 0x35,
0xf5, 0xf3, 0x2d, 0xe6, 0x11, 0xf6, 0x75, 0xd8, 0x48, 0x9b, 0xe4, 0x73, 0x27, 0x15, 0xf5, 0xaf,
0x2c, 0x9e, 0xad, 0x65, 0x3e, 0x4e, 0x46, 0x9e, 0xc0, 0x6a, 0xec, 0x05, 0x23, 0x9f, 0xea, 0xf5,
0xc4, 0x62, 0x26, 0xae, 0x99, 0xdd, 0x13, 0x0f, 0x98, 0x39, 0x45, 0x5f, 0x30, 0x06, 0x29, 0xee,
0x68, 0xca, 0x20, 0x99, 0x29, 0x29, 0x1a, 0xc0, 0x77, 0xa1, 0x65, 0x36, 0x46, 0x1e, 0x88, 0xfc,
0xf4, 0xb4, 0x67, 0xfa, 0x79, 0x8b, 0xc9, 0x19, 0x06, 0xa5, 0xfd, 0x0b, 0x0b, 0xba, 0x0e, 0x65,
0x6c, 0x4c, 0xb5, 0x46, 0x05, 0xf7, 0x3c, 0xcc, 0x55, 0x3b, 0x7f, 0xc0, 0x2a, 0xef, 0x5d, 0x8e,
0x75, 0x6b, 0xee, 0xa2, 0x1c, 0x2c, 0x14, 0x8c, 0xea, 0x51, 0x0d, 0x16, 0xc5, 0xf8, 0x36, 0xe0,
0x9a, 0xe8, 0x92, 0xec, 0x4e, 0x1a, 0xac, 0x37, 0x1a, 0x35, 0x82, 0xf5, 0x3d, 0xe8, 0xf2, 0xa7,
0x19, 0xf4, 0x71, 0xf0, 0x0f, 0x37, 0x3f, 0x87, 0x86, 0xf6, 0x40, 0x05, 0xd9, 0x80, 0xd5, 0x17,
0x4f, 0x4f, 0x8f, 0xf6, 0x4f, 0x4e, 0xfa, 0xc7, 0xcf, 0x1f, 0x7d, 0x6f, 0xff, 0x87, 0xfd, 0x83,
0x9d, 0x93, 0x83, 0xce, 0x02, 0x59, 0x07, 0x72, 0xb4, 0x7f, 0x72, 0xba, 0xbf, 0x67, 0xc0, 0x2d,
0x72, 0x13, 0x7a, 0xcf, 0x8f, 0x9e, 0x9f, 0xec, 0xef, 0xf5, 0x8b, 0xbe, 0x2b, 0x91, 0x77, 0xe1,
0xba, 0xc0, 0x17, 0x7c, 0x5e, 0xde, 0xfc, 0x36, 0x74, 0xb2, 0xde, 0xbb, 0x11, 0xeb, 0xc8, 0x04,
0x45, 0x96, 0xa1, 0xce, 0x83, 0x22, 0x18, 0x15, 0xb9, 0xff, 0x8b, 0x32, 0xb4, 0x78, 0xca, 0x19,
0x7f, 0x11, 0x8f, 0x46, 0xe4, 0x53, 0x58, 0x12, 0x4f, 0x2b, 0x12, 0xb9, 0x1a, 0xe6, 0x63, 0x8e,
0xbd, 0xf5, 0x2c, 0x58, 0x4c, 0xe1, 0xea, 0x5f, 0xff, 0xb3, 0xff, 0xf1, 0xf7, 0x4a, 0xcb, 0xa4,
0xb1, 0x7d, 0xf9, 0xd1, 0xf6, 0x88, 0x06, 0x31, 0xab, 0xe3, 0x0f, 0x01, 0xd2, 0x07, 0x03, 0x49,
0x57, 0xb9, 0xb0, 0x99, 0xd7, 0x14, 0x7b, 0xd7, 0x0b, 0x30, 0xa2, 0xde, 0xeb, 0x58, 0xef, 0xaa,
0xdd, 0x62, 0xf5, 0x7a, 0x81, 0x97, 0xf0, 0xc7, 0x03, 0x3f, 0xb1, 0x36, 0xc9, 0x10, 0x9a, 0xfa,
0x53, 0x7e, 0x44, 0x1e, 0x57, 0x14, 0x3c, 0x46, 0xd8, 0x7b, 0xa7, 0x10, 0x27, 0x97, 0x1f, 0xdb,
0xb8, 0x66, 0x77, 0x58, 0x1b, 0x53, 0xa4, 0x48, 0x5b, 0xf1, 0xb9, 0x50, 0xa4, 0x2f, 0xf6, 0x91,
0x1b, 0x1a, 0x9f, 0xe6, 0xde, 0x0b, 0xec, 0xbd, 0x3b, 0x07, 0x2b, 0xda, 0x7a, 0x17, 0xdb, 0xda,
0xb0, 0x09, 0x6b, 0x6b, 0x80, 0x34, 0xf2, 0xbd, 0xc0, 0x4f, 0xac, 0xcd, 0xfb, 0x7f, 0xff, 0x03,
0xa8, 0xab, 0x63, 0x4c, 0xf2, 0x53, 0x58, 0x36, 0x72, 0x02, 0x89, 0x1c, 0x46, 0x51, 0x0a, 0x61,
0xef, 0x46, 0x31, 0x52, 0x34, 0x7c, 0x13, 0x1b, 0xee, 0x92, 0x75, 0xd6, 0xb0, 0x48, 0xaa, 0xdb,
0xc6, 0xec, 0x56, 0x7e, 0x39, 0xee, 0xa5, 0x26, 0xfc, 0xbc, 0xb1, 0x1b, 0x59, 0x79, 0x34, 0x5a,
0x7b, 0x77, 0x0e, 0x56, 0x34, 0x77, 0x03, 0x9b, 0x5b, 0x27, 0x6b, 0x7a, 0x73, 0xea, 0x78, 0x91,
0xe2, 0x8d, 0x50, 0xfd, 0x31, 0x3b, 0xf2, 0xae, 0x62, 0xac, 0xa2, 0x47, 0xee, 0x14, 0x8b, 0xe4,
0x5f, 0xba, 0xb3, 0xbb, 0xd8, 0x14, 0x21, 0xb8, 0x7c, 0xfa, 0x5b, 0x76, 0xe4, 0x0c, 0x1a, 0xda,
0x63, 0x49, 0xe4, 0xfa, 0xdc, 0x87, 0x9d, 0x7a, 0xbd, 0x22, 0x54, 0xd1, 0x50, 0xf4, 0xfa, 0xb7,
0xd9, 0xae, 0xfe, 0x63, 0xa8, 0xab, 0xe7, 0x77, 0xc8, 0x86, 0xf6, 0x1c, 0x92, 0xfe, 0x5c, 0x50,
0xaf, 0x9b, 0x47, 0x14, 0x31, 0x9f, 0x5e, 0x3b, 0x63, 0xbe, 0x17, 0xd0, 0xd0, 0x9e, 0xd8, 0x51,
0x03, 0xc8, 0x3f, 0xe3, 0xa3, 0x06, 0x50, 0xf0, 0x22, 0x8f, 0xbd, 0x82, 0x4d, 0x34, 0x48, 0x1d,
0xf9, 0x3b, 0x79, 0x15, 0xc6, 0xe4, 0x10, 0xae, 0x09, 0x25, 0x77, 0x46, 0xbf, 0xc8, 0x32, 0x14,
0xbc, 0x1f, 0x78, 0xcf, 0x22, 0x0f, 0xa1, 0x26, 0x5f, 0x52, 0x22, 0xeb, 0xc5, 0x2f, 0x42, 0xf5,
0x36, 0x72, 0x70, 0x61, 0xdc, 0xfc, 0x10, 0x20, 0x7d, 0xcf, 0x47, 0x29, 0x89, 0xdc, 0xfb, 0x40,
0x8a, 0x03, 0xf2, 0x8f, 0xff, 0xd8, 0xeb, 0x38, 0xc0, 0x0e, 0x41, 0x25, 0x11, 0xd0, 0x2b, 0x79,
0xf9, 0xfb, 0x27, 0xd0, 0xd0, 0x9e, 0xf4, 0x51, 0xd3, 0x97, 0x7f, 0x0e, 0x48, 0x4d, 0x5f, 0xc1,
0x0b, 0x40, 0x76, 0x0f, 0x6b, 0x5f, 0xb3, 0xdb, 0xac, 0xf6, 0xd8, 0x1b, 0x05, 0x63, 0x4e, 0xc0,
0x16, 0xe8, 0x02, 0x96, 0x8d, 0x77, 0x7b, 0x94, 0x84, 0x16, 0xbd, 0x0a, 0xa4, 0x24, 0xb4, 0xf0,
0xa9, 0x1f, 0xc9, 0x67, 0xf6, 0x0a, 0x6b, 0xe7, 0x12, 0x49, 0xb4, 0x96, 0x7e, 0x04, 0x0d, 0xed,
0x0d, 0x1e, 0x35, 0x96, 0xfc, 0x73, 0x3f, 0x6a, 0x2c, 0x45, 0x4f, 0xf6, 0xac, 0x61, 0x1b, 0x2d,
0x1b, 0x59, 0x01, 0xaf, 0x31, 0xb3, 0xba, 0x7f, 0x0a, 0x2d, 0xf3, 0x55, 0x1e, 0x25, 0xfb, 0x85,
0xef, 0xfb, 0x28, 0xd9, 0x9f, 0xf3, 0x94, 0x8f, 0x60, 0xe9, 0xcd, 0x55, 0xd5, 0xc8, 0xf6, 0x67,
0x22, 0x09, 0xea, 0x73, 0xf2, 0x7d, 0xa6, 0xe0, 0xc4, 0xbd, 0x72, 0xb2, 0xa1, 0x71, 0xad, 0x7e,
0xfb, 0x5c, 0xc9, 0x4b, 0xee, 0x0a, 0xba, 0xc9, 0xcc, 0xfc, 0x22, 0x36, 0xee, 0x5a, 0x78, 0xbf,
0x5c, 0xdb, 0xb5, 0xf4, 0x2b, 0xe8, 0xda, 0xae, 0x65, 0x5c, 0x43, 0xcf, 0xee, 0x5a, 0x89, 0xc7,
0xea, 0x08, 0xa0, 0x9d, 0xb9, 0xb7, 0xa0, 0xa4, 0xa2, 0xf8, 0x6a, 0x59, 0xef, 0xe6, 0xeb, 0xaf,
0x3b, 0x98, 0x1a, 0x44, 0x2a, 0xc1, 0x6d, 0x79, 0x91, 0xef, 0xaf, 0x40, 0x53, 0x7f, 0x8f, 0x84,
0xe8, 0xa2, 0x9c, 0x6d, 0xe9, 0x9d, 0x42, 0x9c, 0xb9, 0xb8, 0xa4, 0xa9, 0x37, 0x43, 0x7e, 0x00,
0xeb, 0x4a, 0xd4, 0xf5, 0x54, 0xf8, 0x98, 0xbc, 0x57, 0x90, 0x20, 0xaf, 0x9b, 0x3e, 0xbd, 0xeb,
0x73, 0x33, 0xe8, 0xef, 0x59, 0x8c, 0x69, 0xcc, 0x87, 0x1e, 0xd2, 0x0d, 0xa3, 0xe8, 0x7d, 0x8b,
0x74, 0xc3, 0x28, 0x7c, 0x1d, 0x42, 0x32, 0x0d, 0x59, 0x35, 0xe6, 0x88, 0x9f, 0x1f, 0x93, 0x1f,
0x41, 0x5b, 0xbb, 0x6c, 0x74, 0x32, 0x0b, 0x06, 0x4a, 0x00, 0xf2, 0xf7, 0x60, 0x7b, 0x45, 0x86,
0xbd, 0xbd, 0x81, 0xf5, 0xaf, 0xd8, 0xc6, 0xe4, 0x30, 0xe6, 0xdf, 0x85, 0x86, 0x7e, 0x91, 0xe9,
0x35, 0xf5, 0x6e, 0x68, 0x28, 0xfd, 0x1a, 0xe7, 0x3d, 0x8b, 0xfc, 0x23, 0x0b, 0x9a, 0xc6, 0xb5,
0x20, 0x23, 0x77, 0x22, 0x53, 0x4f, 0x57, 0xc7, 0xe9, 0x15, 0xd9, 0x0e, 0x76, 0xf2, 0x70, 0xf3,
0xbb, 0xc6, 0x24, 0x7c, 0x66, 0x44, 0x6f, 0xb6, 0xb2, 0xaf, 0x37, 0x7e, 0x9e, 0x25, 0xd0, 0xef,
0x0a, 0x7f, 0x7e, 0xcf, 0x22, 0x7f, 0x62, 0x41, 0xcb, 0x8c, 0x39, 0xaa, 0xa5, 0x2a, 0x8c, 0x6e,
0xaa, 0xa5, 0x9a, 0x13, 0xa8, 0xfc, 0x11, 0xf6, 0xf2, 0x74, 0xd3, 0x31, 0x7a, 0x29, 0x9e, 0x00,
0xf9, 0xdd, 0x7a, 0x4b, 0x3e, 0xe1, 0x8f, 0xc6, 0xca, 0x93, 0x01, 0x92, 0x7f, 0xbe, 0x54, 0x2d,
0xaf, 0xfe, 0xe0, 0xe8, 0x5d, 0xeb, 0x9e, 0x45, 0x7e, 0xc2, 0x5f, 0x2d, 0x94, 0xc1, 0x6b, 0xc6,
0x25, 0x6f, 0xfb, 0xbd, 0x7d, 0x1b, 0xc7, 0x74, 0xd3, 0xbe, 0x6e, 0x8c, 0x29, 0xbb, 0x1f, 0xef,
0xf0, 0xde, 0x89, 0xb7, 0x42, 0xd3, 0x0d, 0x25, 0xf7, 0x7e, 0xe8, 0xfc, 0x4e, 0x8e, 0x79, 0x27,
0x05, 0xb9, 0xc1, 0xca, 0x6f, 0x59, 0x8d, 0xbd, 0x89, 0x7d, 0xbd, 0x6d, 0xbf, 0x37, 0xb7, 0xaf,
0xdb, 0x18, 0x39, 0x64, 0x3d, 0x3e, 0x06, 0x48, 0x4f, 0xf1, 0x48, 0xe6, 0x14, 0x49, 0x09, 0x78,
0xfe, 0xa0, 0xcf, 0x94, 0x17, 0x79, 0xd8, 0xc4, 0x6a, 0xfc, 0x31, 0x57, 0x57, 0x4f, 0xe5, 0xf9,
0x93, 0x6e, 0x94, 0x98, 0xc7, 0x6d, 0x86, 0x51, 0x92, 0xad, 0xdf, 0x50, 0x56, 0xea, 0x30, 0xeb,
0x39, 0x2c, 0x1f, 0x86, 0xe1, 0xcb, 0xe9, 0x44, 0xa5, 0x38, 0x98, 0x41, 0xfd, 0x03, 0x37, 0xbe,
0xe8, 0x65, 0x46, 0x61, 0xdf, 0xc2, 0xaa, 0x7a, 0xa4, 0xab, 0x55, 0xb5, 0xfd, 0x59, 0x7a, 0x4a,
0xf8, 0x39, 0x71, 0x61, 0x45, 0xe9, 0x40, 0xd5, 0xf1, 0x9e, 0x59, 0x8d, 0xa1, 0xf9, 0xb2, 0x4d,
0x18, 0xd6, 0xb3, 0xec, 0xed, 0x76, 0x2c, 0xeb, 0xbc, 0x67, 0x91, 0x63, 0x68, 0xee, 0xd1, 0x01,
0x5e, 0x4a, 0xc0, 0xc8, 0xf8, 0x6a, 0xda, 0x71, 0x15, 0x52, 0xef, 0x2d, 0x1b, 0x40, 0x73, 0x5f,
0x98, 0xb8, 0xb3, 0x88, 0xfe, 0x6c, 0xfb, 0x33, 0x11, 0x73, 0xff, 0x5c, 0xee, 0x0b, 0xf2, 0x50,
0xc2, 0xd8, 0x17, 0x32, 0xa7, 0x18, 0xc6, 0xbe, 0x90, 0x3b, 0xc5, 0x30, 0xa6, 0x5a, 0x1e, 0x8a,
0x10, 0x1f, 0x56, 0x72, 0x07, 0x1f, 0x6a, 0x4b, 0x98, 0x77, 0x5c, 0xd2, 0xbb, 0x35, 0x9f, 0xc0,
0x6c, 0x6d, 0xd3, 0x6c, 0xed, 0x04, 0x96, 0xf7, 0x28, 0x9f, 0x2c, 0x9e, 0xc3, 0x99, 0xb9, 0x5b,
0xa6, 0x67, 0x88, 0x66, 0x15, 0x38, 0xe2, 0xcc, 0x8d, 0x1f, 0x13, 0x28, 0xc9, 0x8f, 0xa1, 0xf1,
0x84, 0x26, 0x32, 0x69, 0x53, 0x99, 0x9e, 0x99, 0x2c, 0xce, 0x5e, 0x41, 0xce, 0xa7, 0xc9, 0x33,
0x58, 0xdb, 0x36, 0x1d, 0x8e, 0x28, 0x57, 0x4e, 0x7d, 0x6f, 0xf8, 0x39, 0xf9, 0xcb, 0x58, 0xb9,
0xca, 0x58, 0x5f, 0xd7, 0xb2, 0xf0, 0xf4, 0xca, 0xdb, 0x19, 0x78, 0x51, 0xcd, 0x41, 0x38, 0xa4,
0x9a, 0x09, 0x14, 0x40, 0x43, 0xbb, 0x32, 0xa2, 0x04, 0x28, 0x7f, 0x7f, 0x46, 0x09, 0x50, 0xc1,
0x0d, 0x13, 0xfb, 0x2e, 0xb6, 0x63, 0x93, 0x5b, 0x69, 0x3b, 0xfc, 0x56, 0x49, 0xda, 0xd2, 0xf6,
0x67, 0xee, 0x38, 0xf9, 0x9c, 0xbc, 0xc0, 0x27, 0x79, 0xf4, 0xc4, 0xd4, 0xd4, 0x96, 0xce, 0xe6,
0xb0, 0xaa, 0xc9, 0xd2, 0x50, 0xa6, 0x7d, 0xcd, 0x9b, 0x42, 0x4b, 0xe9, 0x5b, 0x00, 0x27, 0x49,
0x38, 0xd9, 0x73, 0xe9, 0x38, 0x0c, 0x52, 0x5d, 0x9b, 0xa6, 0x45, 0xa6, 0xfa, 0x4b, 0xcb, 0x8d,
0x24, 0x2f, 0x34, 0xe7, 0xc3, 0xc8, 0xeb, 0x95, 0xcc, 0x35, 0x37, 0x73, 0x52, 0x4d, 0x48, 0x41,
0xf6, 0xe4, 0x3d, 0x8b, 0xec, 0x00, 0xa4, 0x27, 0x5f, 0xca, 0x95, 0xc8, 0x1d, 0xaa, 0x29, 0xb5,
0x57, 0x70, 0x4c, 0x76, 0x0c, 0xf5, 0xf4, 0x28, 0x65, 0x23, 0xbd, 0xf4, 0x65, 0x1c, 0xbc, 0xa8,
0x1d, 0x3c, 0x77, 0xc0, 0x61, 0x77, 0x70, 0xaa, 0x80, 0xd4, 0xd8, 0x54, 0xe1, 0xa9, 0x85, 0x07,
0xab, 0xbc, 0x83, 0xca, 0x1c, 0xc1, 0x94, 0x3e, 0x39, 0x92, 0x82, 0x43, 0x06, 0x25, 0xcd, 0x85,
0x31, 0x7a, 0x23, 0x22, 0xc2, 0xb8, 0x95, 0xa7, 0x13, 0x32, 0xd5, 0x3c, 0x86, 0x95, 0x5c, 0x10,
0x59, 0x89, 0xf4, 0xbc, 0xb8, 0xbe, 0x12, 0xe9, 0xb9, 0xf1, 0x67, 0xfb, 0x1a, 0x36, 0xd9, 0xb6,
0x01, 0x3d, 0xa0, 0x2b, 0x2f, 0x19, 0x5c, 0xb0, 0xe6, 0x7e, 0x65, 0xc1, 0x6a, 0x41, 0x8c, 0x98,
0xbc, 0x2f, 0x9d, 0xe9, 0xb9, 0xf1, 0xe3, 0x5e, 0x61, 0x08, 0xd1, 0x3e, 0xc1, 0x76, 0x3e, 0x25,
0xdf, 0x33, 0x36, 0x36, 0x1e, 0xbd, 0x13, 0x92, 0xf9, 0x5a, 0xa3, 0xa2, 0xd0, 0xa2, 0xf8, 0x19,
0x6c, 0xf0, 0x8e, 0xec, 0xf8, 0x7e, 0x26, 0xbc, 0x79, 0x33, 0xf7, 0x7f, 0x23, 0x8c, 0xb0, 0x6d,
0x6f, 0xfe, 0xff, 0x95, 0x98, 0x63, 0xae, 0xf2, 0xae, 0x92, 0x29, 0x74, 0xb2, 0x21, 0x43, 0x32,
0xbf, 0xae, 0xde, 0x7b, 0x86, 0x5b, 0x98, 0x0f, 0x33, 0xda, 0xbf, 0x87, 0x8d, 0xbd, 0x67, 0xf7,
0x8a, 0xe6, 0x85, 0x7b, 0x8a, 0x6c, 0x3d, 0xfe, 0x9a, 0x8a, 0x6f, 0x66, 0xc6, 0x29, 0x1b, 0x98,
0x17, 0x90, 0x55, 0x8e, 0x69, 0x71, 0x78, 0xf4, 0x03, 0x6c, 0xfe, 0x96, 0xfd, 0x4e, 0x51, 0xf3,
0x11, 0xff, 0x84, 0xbb, 0xa8, 0x1b, 0x59, 0xb9, 0x96, 0x3d, 0xb8, 0x55, 0xb4, 0xde, 0x73, 0x7d,
0x8d, 0xcc, 0x5c, 0x2f, 0xdc, 0xb3, 0x1e, 0xdd, 0xf9, 0xd1, 0xef, 0x8d, 0xbc, 0xe4, 0x62, 0x7a,
0xb6, 0x35, 0x08, 0xc7, 0xdb, 0xbe, 0x0c, 0x91, 0x89, 0x04, 0xf4, 0x6d, 0x3f, 0x18, 0x6e, 0xe3,
0xf7, 0x67, 0x8b, 0xf8, 0x6f, 0x68, 0xbe, 0xf1, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x98, 0x77,
0x63, 0x94, 0xb8, 0x66, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.

@ -2117,6 +2117,42 @@ message Invoice {
The state the invoice is in.
*/
InvoiceState state = 21 [json_name = "state"];
/// List of HTLCs paying to this invoice [EXPERIMENTAL].
repeated InvoiceHTLC htlcs = 22 [json_name = "htlcs"];
}
enum InvoiceHTLCState {
ACCEPTED = 0;
SETTLED = 1;
CANCELLED = 2;
}
/// Details of an HTLC that paid to an invoice
message InvoiceHTLC {
/// Short channel id over which the htlc was received.
uint64 chan_id = 1 [json_name = "chan_id"];
/// Index identifying the htlc on the channel.
uint64 htlc_index = 2 [json_name = "htlc_index"];
/// The amount of the htlc in msat.
uint64 amt_msat = 3 [json_name = "amt_msat"];
/// Block height at which this htlc was accepted.
int32 accept_height = 4 [json_name = "accept_height"];
/// Time at which this htlc was accepted.
int64 accept_time = 5 [json_name = "accept_time"];
/// Time at which this htlc was settled or cancelled.
int64 resolve_time = 6 [json_name = "resolve_time"];
/// Block height at which this htlc expires.
int32 expiry_height = 7 [json_name = "expiry_height"];
/// Current state the htlc is in.
InvoiceHTLCState state = 8 [json_name = "state"];
}
message AddInvoiceResponse {

@ -2489,9 +2489,70 @@
"state": {
"$ref": "#/definitions/InvoiceInvoiceState",
"description": "*\nThe state the invoice is in."
},
"htlcs": {
"type": "array",
"items": {
"$ref": "#/definitions/lnrpcInvoiceHTLC"
},
"description": "/ List of HTLCs paying to this invoice [EXPERIMENTAL]."
}
}
},
"lnrpcInvoiceHTLC": {
"type": "object",
"properties": {
"chan_id": {
"type": "string",
"format": "uint64",
"description": "/ Short channel id over which the htlc was received."
},
"htlc_index": {
"type": "string",
"format": "uint64",
"description": "/ Index identifying the htlc on the channel."
},
"amt_msat": {
"type": "string",
"format": "uint64",
"description": "/ The amount of the htlc in msat."
},
"accept_height": {
"type": "integer",
"format": "int32",
"description": "/ Block height at which this htlc was accepted."
},
"accept_time": {
"type": "string",
"format": "int64",
"description": "/ Time at which this htlc was accepted."
},
"resolve_time": {
"type": "string",
"format": "int64",
"description": "/ Time at which this htlc was settled or cancelled."
},
"expiry_height": {
"type": "integer",
"format": "int32",
"description": "/ Block height at which this htlc expires."
},
"state": {
"$ref": "#/definitions/lnrpcInvoiceHTLCState",
"description": "/ Current state the htlc is in."
}
},
"title": "/ Details of an HTLC that paid to an invoice"
},
"lnrpcInvoiceHTLCState": {
"type": "string",
"enum": [
"ACCEPTED",
"SETTLED",
"CANCELLED"
],
"default": "ACCEPTED"
},
"lnrpcLightningAddress": {
"type": "object",
"properties": {

@ -3496,7 +3496,7 @@ func (r *rpcServer) LookupInvoice(ctx context.Context,
rpcsLog.Tracef("[lookupinvoice] searching for invoice %x", payHash[:])
invoice, _, err := r.server.invoices.LookupInvoice(payHash)
invoice, err := r.server.invoices.LookupInvoice(payHash)
if err != nil {
return nil, err
}

@ -55,7 +55,6 @@ import (
"github.com/lightningnetwork/lnd/watchtower/wtclient"
"github.com/lightningnetwork/lnd/watchtower/wtdb"
"github.com/lightningnetwork/lnd/watchtower/wtpolicy"
"github.com/lightningnetwork/lnd/zpay32"
)
const (
@ -347,14 +346,6 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB,
readBufferPool, cfg.Workers.Read, pool.DefaultWorkerTimeout,
)
decodeFinalCltvExpiry := func(payReq string) (uint32, error) {
invoice, err := zpay32.Decode(payReq, activeNetParams.Params)
if err != nil {
return 0, err
}
return uint32(invoice.MinFinalCLTVExpiry()), nil
}
s := &server{
chanDB: chanDB,
cc: cc,
@ -364,8 +355,7 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB,
chansToRestore: chansToRestore,
invoices: invoices.NewRegistry(
chanDB, decodeFinalCltvExpiry,
defaultFinalCltvRejectDelta,
chanDB, defaultFinalCltvRejectDelta,
),
channelNotifier: channelnotifier.New(chanDB),