Merge pull request #4440 from carlaKC/4165-ratelimit

chanfitness: Rate limit in memory events based on peer flap rate
This commit is contained in:
Carla Kirk-Cohen 2020-09-14 13:11:07 +02:00 committed by GitHub
commit db0802bc8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 2810 additions and 1662 deletions

@ -5,7 +5,7 @@ import (
"time"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/routing/route"
"github.com/lightningnetwork/lnd/clock"
)
type eventType int
@ -28,74 +28,244 @@ func (e eventType) String() string {
return "unknown"
}
// channelEvent is a a timestamped event which is observed on a per channel
// basis.
type channelEvent struct {
type event struct {
timestamp time.Time
eventType eventType
}
// chanEventLog stores all events that have occurred over a channel's lifetime.
type chanEventLog struct {
// channelPoint is the outpoint for the channel's funding transaction.
channelPoint wire.OutPoint
// peerLog tracks events for a peer and its channels. If we currently have no
// channels with the peer, it will simply track its current online state. If we
// do have channels open with the peer, it will track the peer's online and
// offline events so that we can calculate uptime for our channels. A single
// event log is used for these online and offline events, and uptime for a
// channel is calculated by examining a subsection of this log.
type peerLog struct {
// online stores whether the peer is currently online.
online bool
// peer is the compressed public key of the peer being monitored.
peer route.Vertex
// onlineEvents is a log of timestamped events observed for the peer
// that we have committed to allocating memory to.
onlineEvents []*event
// events is a log of timestamped events observed for the channel.
events []*channelEvent
// stagedEvent represents an event that is pending addition to the
// events list. It has not yet been added because we rate limit the
// frequency that we store events at. We need to store this value
// in the log (rather than just ignore events) so that we can flush the
// aggregate outcome to our event log once the rate limiting period has
// ended.
//
// Take the following example:
// - Peer online event recorded
// - Peer offline event, not recorded due to rate limit
// - No more events, we incorrectly believe our peer to be online
// Instead of skipping events, we stage the most recent event during the
// rate limited period so that we know what happened (on aggregate)
// while we were rate limiting events.
//
// Note that we currently only store offline/online events so we can
// use this field to track our online state. With the addition of other
// event types, we need to only stage online/offline events, or split
// them out.
stagedEvent *event
// now is expected to return the current time. It is supplied as an
// external function to enable deterministic unit tests.
now func() time.Time
// flapCount is the number of times this peer has been observed as
// going offline.
flapCount int
// openedAt tracks the first time this channel was seen. This is not
// necessarily the time that it confirmed on chain because channel events
// are not persisted at present.
openedAt time.Time
// lastFlap is the timestamp of the last flap we recorded for the peer.
// This value will be nil if we have never recorded a flap for the peer.
lastFlap *time.Time
// closedAt is the time that the channel was closed. If the channel has not
// been closed yet, it is zero.
closedAt time.Time
// clock allows creation of deterministic unit tests.
clock clock.Clock
// channels contains a set of currently open channels. Channels will be
// added and removed from this map as they are opened and closed.
channels map[wire.OutPoint]*channelInfo
}
// newEventLog creates an event log for a channel with the openedAt time set.
func newEventLog(channelPoint wire.OutPoint, peer route.Vertex,
now func() time.Time) *chanEventLog {
// newPeerLog creates a log for a peer, taking its historical flap count and
// last flap time as parameters. These values may be zero/nil if we have no
// record of historical flap count for the peer.
func newPeerLog(clock clock.Clock, flapCount int,
lastFlap *time.Time) *peerLog {
eventlog := &chanEventLog{
channelPoint: channelPoint,
peer: peer,
now: now,
openedAt: now(),
return &peerLog{
clock: clock,
flapCount: flapCount,
lastFlap: lastFlap,
channels: make(map[wire.OutPoint]*channelInfo),
}
}
// channelInfo contains information about a channel.
type channelInfo struct {
// openedAt tracks the first time this channel was seen. This is not
// necessarily the time that it confirmed on chain because channel
// events are not persisted at present.
openedAt time.Time
}
func newChannelInfo(openedAt time.Time) *channelInfo {
return &channelInfo{
openedAt: openedAt,
}
}
// onlineEvent records a peer online or offline event in the log and increments
// the peer's flap count.
func (p *peerLog) onlineEvent(online bool) {
eventTime := p.clock.Now()
// If we have a non-nil last flap time, potentially apply a cooldown
// factor to the peer's flap count before we rate limit it. This allows
// us to decrease the penalty for historical flaps over time, provided
// the peer has not flapped for a while.
if p.lastFlap != nil {
p.flapCount = cooldownFlapCount(
p.clock.Now(), p.flapCount, *p.lastFlap,
)
}
return eventlog
}
// Record flap count information and online state regardless of whether
// we have any channels open with this peer.
p.flapCount++
p.lastFlap = &eventTime
p.online = online
// close sets the closing time for an event log.
func (e *chanEventLog) close() {
e.closedAt = e.now()
}
// add appends an event with the given type and current time to the event log.
// The open time for the eventLog will be set to the event's timestamp if it is
// not set yet.
func (e *chanEventLog) add(eventType eventType) {
// If the channel is already closed, return early without adding an event.
if !e.closedAt.IsZero() {
// If we have no channels currently open with the peer, we do not want
// to commit resources to tracking their online state beyond a simple
// online boolean, so we exit early.
if p.channelCount() == 0 {
return
}
// Add the event to the eventLog with the current timestamp.
event := &channelEvent{
timestamp: e.now(),
p.addEvent(online, eventTime)
}
// addEvent records an online or offline event in our event log. and increments
// the peer's flap count.
func (p *peerLog) addEvent(online bool, time time.Time) {
eventType := peerOnlineEvent
if !online {
eventType = peerOfflineEvent
}
event := &event{
timestamp: time,
eventType: eventType,
}
e.events = append(e.events, event)
log.Debugf("Channel %v recording event: %v", e.channelPoint, eventType)
// If we have no staged events, we can just stage this event and return.
if p.stagedEvent == nil {
p.stagedEvent = event
return
}
// We get the amount of time we require between events according to
// peer flap count.
aggregation := getRateLimit(p.flapCount)
nextRecordTime := p.stagedEvent.timestamp.Add(aggregation)
flushEvent := nextRecordTime.Before(event.timestamp)
// If enough time has passed since our last staged event, we add our
// event to our in-memory list.
if flushEvent {
p.onlineEvents = append(p.onlineEvents, p.stagedEvent)
}
// Finally, we replace our staged event with the new event we received.
p.stagedEvent = event
}
// addChannel adds a channel to our log. If we have not tracked any online
// events for our peer yet, we create one with our peer's current online state
// so that we know the state that the peer had at channel start, which is
// required to calculate uptime over the channel's lifetime.
func (p *peerLog) addChannel(channelPoint wire.OutPoint) error {
_, ok := p.channels[channelPoint]
if ok {
return fmt.Errorf("channel: %v already present", channelPoint)
}
openTime := p.clock.Now()
p.channels[channelPoint] = newChannelInfo(openTime)
// If we do not have any online events tracked for our peer (which is
// the case when we have no other channels open with the peer), we add
// an event with the peer's current online state so that we know that
// starting state for this peer when a channel was connected (which
// allows us to calculate uptime over the lifetime of the channel).
if len(p.onlineEvents) == 0 {
p.addEvent(p.online, openTime)
}
return nil
}
// removeChannel removes a channel from our log. If we have no more channels
// with the peer after removing this one, we clear our list of events.
func (p *peerLog) removeChannel(channelPoint wire.OutPoint) error {
_, ok := p.channels[channelPoint]
if !ok {
return fmt.Errorf("channel: %v not present", channelPoint)
}
delete(p.channels, channelPoint)
// If we have no more channels in our event log, we can discard all of
// our online events in memory, since we don't need them anymore.
// TODO(carla): this could be done on a per channel basis.
if p.channelCount() == 0 {
p.onlineEvents = nil
p.stagedEvent = nil
}
return nil
}
// channelCount returns the number of channels that we currently have
// with the peer.
func (p *peerLog) channelCount() int {
return len(p.channels)
}
// channelUptime looks up a channel and returns the amount of time that the
// channel has been monitored for and its uptime over this period.
func (p *peerLog) channelUptime(channelPoint wire.OutPoint) (time.Duration,
time.Duration, error) {
channel, ok := p.channels[channelPoint]
if !ok {
return 0, 0, ErrChannelNotFound
}
now := p.clock.Now()
uptime, err := p.uptime(channel.openedAt, now)
if err != nil {
return 0, 0, err
}
return now.Sub(channel.openedAt), uptime, nil
}
// getFlapCount returns the peer's flap count and the timestamp that we last
// recorded a flap.
func (p *peerLog) getFlapCount() (int, *time.Time) {
return p.flapCount, p.lastFlap
}
// listEvents returns all of the events that our event log has tracked,
// including events that are staged for addition to our set of events but have
// not yet been committed to (because we rate limit and store only the aggregate
// outcome over a period).
func (p *peerLog) listEvents() []*event {
if p.stagedEvent == nil {
return p.onlineEvents
}
return append(p.onlineEvents, p.stagedEvent)
}
// onlinePeriod represents a period of time over which a peer was online.
@ -106,17 +276,25 @@ type onlinePeriod struct {
// getOnlinePeriods returns a list of all the periods that the event log has
// recorded the remote peer as being online. In the unexpected case where there
// are no events, the function returns early. Online periods are defined as a
// peer online event which is terminated by a peer offline event. This function
// expects the event log provided to be ordered by ascending timestamp.
func (e *chanEventLog) getOnlinePeriods() []*onlinePeriod {
// peer online event which is terminated by a peer offline event. If the event
// log ends on a peer online event, it appends a final period which is
// calculated until the present. This function expects the event log provided
// to be ordered by ascending timestamp, and can tolerate multiple consecutive
// online or offline events.
func (p *peerLog) getOnlinePeriods() []*onlinePeriod {
events := p.listEvents()
// Return early if there are no events, there are no online periods.
if len(e.events) == 0 {
if len(events) == 0 {
return nil
}
var (
lastOnline time.Time
offline bool
// lastEvent tracks the last event that we had that was of
// a different type to our own. It is used to determine the
// start time of our online periods when we experience an
// offline event, and to track our last recorded state.
lastEvent *event
onlinePeriods []*onlinePeriod
)
@ -126,57 +304,77 @@ func (e *chanEventLog) getOnlinePeriods() []*onlinePeriod {
// the online event and the present is not tracked. The type of the most
// recent event is tracked using the offline bool so that we can add a
// final online period if necessary.
for _, event := range e.events {
for _, event := range events {
switch event.eventType {
case peerOnlineEvent:
lastOnline = event.timestamp
offline = false
case peerOfflineEvent:
offline = true
// Do not add to uptime if there is no previous online timestamp,
// the event log has started with an offline event
if lastOnline.IsZero() {
continue
// If our previous event is nil, we just set it and
// break out of the switch.
if lastEvent == nil {
lastEvent = event
break
}
// The eventLog has recorded an offline event, having previously
// been online so we add an online period to to set of online periods.
onlinePeriods = append(onlinePeriods, &onlinePeriod{
start: lastOnline,
end: event.timestamp,
})
// If our previous event was an offline event, we update
// it to this event. We do not do this if it was an
// online event because duplicate online events would
// progress our online timestamp forward (rather than
// keep it at our earliest online event timestamp).
if lastEvent.eventType == peerOfflineEvent {
lastEvent = event
}
case peerOfflineEvent:
// If our previous event is nil, we just set it and
// break out of the switch since we cannot record an
// online period from this single event.
if lastEvent == nil {
lastEvent = event
break
}
// If the last event we saw was an online event, we
// add an online period to our set and progress our
// previous event to this offline event. We do not
// do this if we have had duplicate offline events
// because we would be tracking the most recent offline
// event (rather than keep it at our earliest offline
// event timestamp).
if lastEvent.eventType == peerOnlineEvent {
onlinePeriods = append(
onlinePeriods, &onlinePeriod{
start: lastEvent.timestamp,
end: event.timestamp,
},
)
lastEvent = event
}
}
}
// If the last event was an peer offline event, we do not need to calculate
// a final online period and can return online periods as is.
if offline {
// If the last event was an peer offline event, we do not need to
// calculate a final online period and can return online periods as is.
if lastEvent.eventType == peerOfflineEvent {
return onlinePeriods
}
// The log ended on an online event, so we need to add a final online event.
// If the channel is closed, this period is until channel closure. It it is
// still open, we calculate it until the present.
endTime := e.closedAt
if endTime.IsZero() {
endTime = e.now()
// The log ended on an online event, so we need to add a final online
// period which terminates at the present.
finalEvent := &onlinePeriod{
start: lastEvent.timestamp,
end: p.clock.Now(),
}
// Add the final online period to the set and return.
return append(onlinePeriods, &onlinePeriod{
start: lastOnline,
end: endTime,
})
return append(onlinePeriods, finalEvent)
}
// uptime calculates the total uptime we have recorded for a channel over the
// uptime calculates the total uptime we have recorded for a peer over the
// inclusive range specified. An error is returned if the end of the range is
// before the start or a zero end time is returned.
func (e *chanEventLog) uptime(start, end time.Time) (time.Duration, error) {
// Error if we are provided with an invalid range to calculate uptime for.
func (p *peerLog) uptime(start, end time.Time) (time.Duration, error) {
// Error if we are provided with an invalid range to calculate uptime
// for.
if end.Before(start) {
return 0, fmt.Errorf("end time: %v before start time: %v",
end, start)
@ -187,26 +385,28 @@ func (e *chanEventLog) uptime(start, end time.Time) (time.Duration, error) {
var uptime time.Duration
for _, p := range e.getOnlinePeriods() {
// The online period ends before the range we're looking at, so we can
// skip over it.
for _, p := range p.getOnlinePeriods() {
// The online period ends before the range we're looking at, so
// we can skip over it.
if p.end.Before(start) {
continue
}
// The online period starts after the range we're looking at, so can
// stop calculating uptime.
// The online period starts after the range we're looking at, so
// can stop calculating uptime.
if p.start.After(end) {
break
}
// If the online period starts before our range, shift the start time up
// so that we only calculate uptime from the start of our range.
// If the online period starts before our range, shift the start
// time up so that we only calculate uptime from the start of
// our range.
if p.start.Before(start) {
p.start = start
}
// If the online period ends before our range, shift the end time
// forward so that we only calculate uptime until the end of the range.
// If the online period ends before our range, shift the end
// time forward so that we only calculate uptime until the end
// of the range.
if p.end.After(end) {
p.end = end
}

@ -3,77 +3,269 @@ package chanfitness
import (
"testing"
"time"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/clock"
"github.com/stretchr/testify/require"
)
// TestAdd tests adding events to an event log. It tests the case where the
// channel is open, and should have an event added, and the case where it is
// closed and the event should not be added.
func TestAdd(t *testing.T) {
tests := []struct {
name string
eventLog *chanEventLog
event eventType
expected []eventType
}{
{
name: "Channel open",
eventLog: &chanEventLog{
now: time.Now,
},
event: peerOnlineEvent,
expected: []eventType{peerOnlineEvent},
},
{
name: "Channel closed, event not added",
eventLog: &chanEventLog{
now: time.Now,
},
event: peerOnlineEvent,
expected: []eventType{},
},
// TestPeerLog tests the functionality of the peer log struct.
func TestPeerLog(t *testing.T) {
clock := clock.NewTestClock(testNow)
peerLog := newPeerLog(clock, 0, nil)
// assertFlapCount is a helper that asserts that our peer's flap count
// and timestamp is set to expected values.
assertFlapCount := func(expectedCount int, expectedTs *time.Time) {
flapCount, flapTs := peerLog.getFlapCount()
require.Equal(t, expectedCount, flapCount)
require.Equal(t, expectedTs, flapTs)
}
for _, test := range tests {
test := test
require.Zero(t, peerLog.channelCount())
require.False(t, peerLog.online)
assertFlapCount(0, nil)
t.Run(test.name, func(t *testing.T) {
test.eventLog.add(test.event)
// Test that looking up an unknown channel fails.
_, _, err := peerLog.channelUptime(wire.OutPoint{Index: 1})
require.Error(t, err)
for i, e := range test.expected {
if test.eventLog.events[i].eventType != e {
t.Fatalf("Expected event type: %v, got: %v",
e, test.eventLog.events[i].eventType)
}
}
})
lastFlap := clock.Now()
// Add an offline event, since we have no channels, we do not expect
// to have any online periods recorded for our peer. However, we should
// increment our flap count for the peer.
peerLog.onlineEvent(false)
require.Len(t, peerLog.getOnlinePeriods(), 0)
assertFlapCount(1, &lastFlap)
// Bump our test clock's time by an hour so that we can create an online
// event with a distinct time.
lastFlap = testNow.Add(time.Hour)
clock.SetTime(lastFlap)
// Likewise, if we have an online event, nothing beyond the online state
// of our peer log should change, but our flap count should change.
peerLog.onlineEvent(true)
require.Len(t, peerLog.getOnlinePeriods(), 0)
assertFlapCount(2, &lastFlap)
// Add a channel and assert that we have one channel listed. Since this
// is the first channel we track for the peer, we expect an online
// event to be added, however, our flap count should not change because
// this is not a new online event, we are just copying one into our log
// for our purposes.
chan1 := wire.OutPoint{
Index: 1,
}
require.NoError(t, peerLog.addChannel(chan1))
require.Equal(t, 1, peerLog.channelCount())
assertFlapCount(2, &lastFlap)
// Assert that we can now successfully get our added channel.
_, _, err = peerLog.channelUptime(chan1)
require.NoError(t, err)
// Bump our test clock's time so that our current time is different to
// channel open time.
lastFlap = clock.Now().Add(time.Hour)
clock.SetTime(lastFlap)
// Now that we have added a channel and an hour has passed, we expect
// our uptime and lifetime to both equal an hour.
lifetime, uptime, err := peerLog.channelUptime(chan1)
require.NoError(t, err)
require.Equal(t, time.Hour, lifetime)
require.Equal(t, time.Hour, uptime)
// Add an offline event for our peer and assert that our flap count is
// incremented.
peerLog.onlineEvent(false)
assertFlapCount(3, &lastFlap)
// Now we add another channel to our store and assert that we now report
// two channels for this peer.
chan2 := wire.OutPoint{
Index: 2,
}
require.NoError(t, peerLog.addChannel(chan2))
require.Equal(t, 2, peerLog.channelCount())
// Progress our time again, so that our peer has now been offline for
// two hours.
now := lastFlap.Add(time.Hour * 2)
clock.SetTime(now)
// Our first channel should report as having been monitored for three
// hours, but only online for one of those hours.
lifetime, uptime, err = peerLog.channelUptime(chan1)
require.NoError(t, err)
require.Equal(t, time.Hour*3, lifetime)
require.Equal(t, time.Hour, uptime)
// Remove our first channel and check that we can still correctly query
// uptime for the second channel.
require.NoError(t, peerLog.removeChannel(chan1))
require.Equal(t, 1, peerLog.channelCount())
// Our second channel, which was created when our peer was offline,
// should report as having been monitored for two hours, but have zero
// uptime.
lifetime, uptime, err = peerLog.channelUptime(chan2)
require.NoError(t, err)
require.Equal(t, time.Hour*2, lifetime)
require.Equal(t, time.Duration(0), uptime)
// Finally, remove our second channel and assert that our peer cleans
// up its in memory set of events but keeps its flap count record.
require.NoError(t, peerLog.removeChannel(chan2))
require.Equal(t, 0, peerLog.channelCount())
require.Len(t, peerLog.onlineEvents, 0)
assertFlapCount(3, &lastFlap)
require.Len(t, peerLog.listEvents(), 0)
require.Nil(t, peerLog.stagedEvent)
}
// TestRateLimitAdd tests the addition of events to the event log with rate
// limiting in place.
func TestRateLimitAdd(t *testing.T) {
// Create a mock clock specifically for this test so that we can
// progress time without affecting the other tests.
mockedClock := clock.NewTestClock(testNow)
// Create a new peer log.
peerLog := newPeerLog(mockedClock, 0, nil)
require.Nil(t, peerLog.stagedEvent)
// Create a channel for our peer log, otherwise it will not track online
// events.
require.NoError(t, peerLog.addChannel(wire.OutPoint{}))
// First, we add an event to the event log. Since we have no previous
// events, we expect this event to staged immediately.
peerEvent := &event{
timestamp: testNow,
eventType: peerOfflineEvent,
}
peerLog.onlineEvent(false)
require.Equal(t, peerEvent, peerLog.stagedEvent)
// We immediately add another event to our event log. We expect our
// staged event to be replaced with this new event, because insufficient
// time has passed since our last event.
peerEvent = &event{
timestamp: testNow,
eventType: peerOnlineEvent,
}
peerLog.onlineEvent(true)
require.Equal(t, peerEvent, peerLog.stagedEvent)
// We get the amount of time that we need to pass before we record an
// event from our rate limiting tiers. We then progress our test clock
// to just after this point.
delta := getRateLimit(peerLog.flapCount)
newNow := testNow.Add(delta + 1)
mockedClock.SetTime(newNow)
// Now, when we add an event, we expect our staged event to be added
// to our events list and for our new event to be staged.
newEvent := &event{
timestamp: newNow,
eventType: peerOfflineEvent,
}
peerLog.onlineEvent(false)
require.Equal(t, []*event{peerEvent}, peerLog.onlineEvents)
require.Equal(t, newEvent, peerLog.stagedEvent)
// Now, we test the case where we add many events to our log. We expect
// our set of events to be untouched, but for our staged event to be
// updated.
nextEvent := &event{
timestamp: newNow,
eventType: peerOnlineEvent,
}
for i := 0; i < 5; i++ {
// We flip the kind of event for each type so that we can check
// that our staged event is definitely changing each time.
if i%2 == 0 {
nextEvent.eventType = peerOfflineEvent
} else {
nextEvent.eventType = peerOnlineEvent
}
online := nextEvent.eventType == peerOnlineEvent
peerLog.onlineEvent(online)
require.Equal(t, []*event{peerEvent}, peerLog.onlineEvents)
require.Equal(t, nextEvent, peerLog.stagedEvent)
}
// Now, we test the case where a peer's flap count is cooled down
// because it has not flapped for a while. Set our peer's flap count so
// that we fall within our second rate limiting tier and assert that we
// are at this level.
peerLog.flapCount = rateLimitScale + 1
rateLimit := getRateLimit(peerLog.flapCount)
require.Equal(t, rateLimits[1], rateLimit)
// Progress our clock to the point where we will have our flap count
// cooled.
newNow = mockedClock.Now().Add(flapCountCooldownPeriod)
mockedClock.SetTime(newNow)
// Add an online event, and expect it to be staged.
onlineEvent := &event{
timestamp: newNow,
eventType: peerOnlineEvent,
}
peerLog.onlineEvent(true)
require.Equal(t, onlineEvent, peerLog.stagedEvent)
// Progress our clock by the rate limit level that we will be on if
// our flap rate is cooled down to a lower level.
newNow = mockedClock.Now().Add(rateLimits[0] + 1)
mockedClock.SetTime(newNow)
// Add another event. We expect this event to be staged and our previous
// event to be flushed to the event log (because our cooldown has been
// applied).
offlineEvent := &event{
timestamp: newNow,
eventType: peerOfflineEvent,
}
peerLog.onlineEvent(false)
require.Equal(t, offlineEvent, peerLog.stagedEvent)
flushedEventIdx := len(peerLog.onlineEvents) - 1
require.Equal(
t, onlineEvent, peerLog.onlineEvents[flushedEventIdx],
)
}
// TestGetOnlinePeriod tests the getOnlinePeriod function. It tests the case
// where no events present, and the case where an additional online period
// must be added because the event log ends on an online event.
func TestGetOnlinePeriod(t *testing.T) {
// Set time for consistent testing.
now := time.Now()
fourHoursAgo := now.Add(time.Hour * -4)
threeHoursAgo := now.Add(time.Hour * -3)
twoHoursAgo := now.Add(time.Hour * -2)
oneHourAgo := now.Add(time.Hour * -1)
fourHoursAgo := testNow.Add(time.Hour * -4)
threeHoursAgo := testNow.Add(time.Hour * -3)
twoHoursAgo := testNow.Add(time.Hour * -2)
tests := []struct {
name string
events []*channelEvent
events []*event
expectedOnline []*onlinePeriod
openedAt time.Time
closedAt time.Time
}{
{
name: "No events",
name: "no events",
},
{
name: "Start on online period",
events: []*channelEvent{
name: "start on online period",
events: []*event{
{
timestamp: threeHoursAgo,
eventType: peerOnlineEvent,
@ -91,8 +283,8 @@ func TestGetOnlinePeriod(t *testing.T) {
},
},
{
name: "Start on offline period",
events: []*channelEvent{
name: "start on offline period",
events: []*event{
{
timestamp: fourHoursAgo,
eventType: peerOfflineEvent,
@ -100,8 +292,8 @@ func TestGetOnlinePeriod(t *testing.T) {
},
},
{
name: "End on an online period, channel not closed",
events: []*channelEvent{
name: "end on an online period",
events: []*event{
{
timestamp: fourHoursAgo,
eventType: peerOnlineEvent,
@ -110,25 +302,88 @@ func TestGetOnlinePeriod(t *testing.T) {
expectedOnline: []*onlinePeriod{
{
start: fourHoursAgo,
end: now,
end: testNow,
},
},
},
{
name: "End on an online period, channel closed",
events: []*channelEvent{
name: "duplicate online events",
events: []*event{
{
timestamp: fourHoursAgo,
eventType: peerOnlineEvent,
},
{
timestamp: threeHoursAgo,
eventType: peerOnlineEvent,
},
},
expectedOnline: []*onlinePeriod{
{
start: fourHoursAgo,
end: oneHourAgo,
end: testNow,
},
},
},
{
name: "duplicate offline events",
events: []*event{
{
timestamp: fourHoursAgo,
eventType: peerOfflineEvent,
},
{
timestamp: threeHoursAgo,
eventType: peerOfflineEvent,
},
},
expectedOnline: nil,
},
{
name: "duplicate online then offline",
events: []*event{
{
timestamp: fourHoursAgo,
eventType: peerOnlineEvent,
},
{
timestamp: threeHoursAgo,
eventType: peerOnlineEvent,
},
{
timestamp: twoHoursAgo,
eventType: peerOfflineEvent,
},
},
expectedOnline: []*onlinePeriod{
{
start: fourHoursAgo,
end: twoHoursAgo,
},
},
},
{
name: "duplicate offline then online",
events: []*event{
{
timestamp: fourHoursAgo,
eventType: peerOfflineEvent,
},
{
timestamp: threeHoursAgo,
eventType: peerOfflineEvent,
},
{
timestamp: twoHoursAgo,
eventType: peerOnlineEvent,
},
},
expectedOnline: []*onlinePeriod{
{
start: twoHoursAgo,
end: testNow,
},
},
closedAt: oneHourAgo,
},
}
@ -136,33 +391,16 @@ func TestGetOnlinePeriod(t *testing.T) {
test := test
t.Run(test.name, func(t *testing.T) {
score := &chanEventLog{
events: test.events,
now: func() time.Time {
return now
},
openedAt: test.openedAt,
closedAt: test.closedAt,
t.Parallel()
score := &peerLog{
onlineEvents: test.events,
clock: clock.NewTestClock(testNow),
}
online := score.getOnlinePeriods()
if len(online) != len(test.expectedOnline) {
t.Fatalf("Expectd: %v online periods, got: %v",
len(test.expectedOnline), len(online))
}
for i, o := range test.expectedOnline {
if online[i].start != o.start {
t.Errorf("Expected start: %v, got %v", o.start,
online[i].start)
}
if online[i].end != o.end {
t.Errorf("Expected end: %v, got %v", o.end,
online[i].end)
}
}
require.Equal(t, test.expectedOnline, online)
})
}
@ -170,48 +408,39 @@ func TestGetOnlinePeriod(t *testing.T) {
// TestUptime tests channel uptime calculation based on its event log.
func TestUptime(t *testing.T) {
// Set time for consistent testing.
now := time.Now()
fourHoursAgo := now.Add(time.Hour * -4)
threeHoursAgo := now.Add(time.Hour * -3)
twoHoursAgo := now.Add(time.Hour * -2)
oneHourAgo := now.Add(time.Hour * -1)
fourHoursAgo := testNow.Add(time.Hour * -4)
threeHoursAgo := testNow.Add(time.Hour * -3)
twoHoursAgo := testNow.Add(time.Hour * -2)
oneHourAgo := testNow.Add(time.Hour * -1)
tests := []struct {
name string
// opened at is the time the channel was recorded as being open, and is
// never expected to be zero.
openedAt time.Time
// events is the set of event log that we are calculating uptime
// for.
events []*event
// closed at is the tim the channel was recorded as being closed, and
// can have a zero value if the.
closedAt time.Time
// events is the set of event log that we are calculating uptime for.
events []*channelEvent
// startTime is the beginning of the period that we are calculating
// uptime for, it cannot have a zero value.
// startTime is the beginning of the period that we are
// calculating uptime for, it cannot have a zero value.
startTime time.Time
// endTime is the end of the period that we are calculating uptime for,
// it cannot have a zero value.
// endTime is the end of the period that we are calculating
// uptime for, it cannot have a zero value.
endTime time.Time
// expectedUptime is the amount of uptime we expect to be calculated
// over the period specified by startTime and endTime.
// expectedUptime is the amount of uptime we expect to be
// calculated over the period specified by startTime and
// endTime.
expectedUptime time.Duration
// expectErr is set to true if we expect an error to be returned when
// calling the uptime function
// expectErr is set to true if we expect an error to be returned
// when calling the uptime function.
expectErr bool
}{
{
name: "End before start",
endTime: threeHoursAgo,
startTime: now,
startTime: testNow,
expectErr: true,
},
{
@ -219,64 +448,20 @@ func TestUptime(t *testing.T) {
expectErr: true,
},
{
name: "Online event and closed",
openedAt: fourHoursAgo,
closedAt: oneHourAgo,
events: []*channelEvent{
name: "online event and no offline",
events: []*event{
{
timestamp: fourHoursAgo,
eventType: peerOnlineEvent,
},
},
startTime: fourHoursAgo,
endTime: now,
expectedUptime: time.Hour * 3,
},
{
name: "Online event and not closed",
openedAt: fourHoursAgo,
events: []*channelEvent{
{
timestamp: fourHoursAgo,
eventType: peerOnlineEvent,
},
},
startTime: fourHoursAgo,
endTime: now,
endTime: testNow,
expectedUptime: time.Hour * 4,
},
{
name: "Offline event and closed",
openedAt: fourHoursAgo,
closedAt: threeHoursAgo,
events: []*channelEvent{
{
timestamp: fourHoursAgo,
eventType: peerOfflineEvent,
},
},
startTime: fourHoursAgo,
endTime: now,
},
{
name: "Online event before close",
openedAt: fourHoursAgo,
closedAt: oneHourAgo,
events: []*channelEvent{
{
timestamp: twoHoursAgo,
eventType: peerOnlineEvent,
},
},
startTime: fourHoursAgo,
endTime: now,
expectedUptime: time.Hour,
},
{
name: "Online then offline event",
openedAt: fourHoursAgo,
closedAt: oneHourAgo,
events: []*channelEvent{
name: "online then offline event",
events: []*event{
{
timestamp: threeHoursAgo,
eventType: peerOnlineEvent,
@ -287,44 +472,40 @@ func TestUptime(t *testing.T) {
},
},
startTime: fourHoursAgo,
endTime: now,
endTime: testNow,
expectedUptime: time.Hour,
},
{
name: "Online event before uptime period",
openedAt: fourHoursAgo,
closedAt: oneHourAgo,
events: []*channelEvent{
name: "online event before uptime period",
events: []*event{
{
timestamp: threeHoursAgo,
eventType: peerOnlineEvent,
},
},
startTime: twoHoursAgo,
endTime: now,
expectedUptime: time.Hour,
},
{
name: "Offline event after uptime period",
openedAt: fourHoursAgo,
events: []*channelEvent{
{
timestamp: fourHoursAgo,
eventType: peerOnlineEvent,
},
{
timestamp: now.Add(time.Hour),
eventType: peerOfflineEvent,
},
},
startTime: twoHoursAgo,
endTime: now,
endTime: testNow,
expectedUptime: time.Hour * 2,
},
{
name: "All events within period",
openedAt: fourHoursAgo,
events: []*channelEvent{
name: "offline event after uptime period",
events: []*event{
{
timestamp: fourHoursAgo,
eventType: peerOnlineEvent,
},
{
timestamp: testNow.Add(time.Hour),
eventType: peerOfflineEvent,
},
},
startTime: twoHoursAgo,
endTime: testNow,
expectedUptime: time.Hour * 2,
},
{
name: "all events within period",
events: []*event{
{
timestamp: twoHoursAgo,
eventType: peerOnlineEvent,
@ -335,31 +516,30 @@ func TestUptime(t *testing.T) {
expectedUptime: time.Hour,
},
{
name: "Multiple online and offline",
openedAt: now.Add(time.Hour * -8),
events: []*channelEvent{
name: "multiple online and offline",
events: []*event{
{
timestamp: now.Add(time.Hour * -7),
timestamp: testNow.Add(time.Hour * -7),
eventType: peerOnlineEvent,
},
{
timestamp: now.Add(time.Hour * -6),
timestamp: testNow.Add(time.Hour * -6),
eventType: peerOfflineEvent,
},
{
timestamp: now.Add(time.Hour * -5),
timestamp: testNow.Add(time.Hour * -5),
eventType: peerOnlineEvent,
},
{
timestamp: now.Add(time.Hour * -4),
timestamp: testNow.Add(time.Hour * -4),
eventType: peerOfflineEvent,
},
{
timestamp: now.Add(time.Hour * -3),
timestamp: testNow.Add(time.Hour * -3),
eventType: peerOnlineEvent,
},
},
startTime: now.Add(time.Hour * -8),
startTime: testNow.Add(time.Hour * -8),
endTime: oneHourAgo,
expectedUptime: time.Hour * 4,
},
@ -369,27 +549,16 @@ func TestUptime(t *testing.T) {
test := test
t.Run(test.name, func(t *testing.T) {
score := &chanEventLog{
events: test.events,
now: func() time.Time {
return now
},
openedAt: test.openedAt,
closedAt: test.closedAt,
score := &peerLog{
onlineEvents: test.events,
clock: clock.NewTestClock(testNow),
}
uptime, err := score.uptime(test.startTime, test.endTime)
if test.expectErr && err == nil {
t.Fatal("Expected an error, got nil")
}
if !test.expectErr && err != nil {
t.Fatalf("Expcted no error, got: %v", err)
}
if uptime != test.expectedUptime {
t.Errorf("Expected uptime: %v, got: %v",
test.expectedUptime, uptime)
}
uptime, err := score.uptime(
test.startTime, test.endTime,
)
require.Equal(t, test.expectErr, err != nil)
require.Equal(t, test.expectedUptime, uptime)
})
}
}

@ -18,19 +18,31 @@ import (
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/channelnotifier"
"github.com/lightningnetwork/lnd/clock"
"github.com/lightningnetwork/lnd/peernotifier"
"github.com/lightningnetwork/lnd/routing/route"
"github.com/lightningnetwork/lnd/subscribe"
"github.com/lightningnetwork/lnd/ticker"
)
const (
// FlapCountFlushRate determines how often we write peer total flap
// count to disk.
FlapCountFlushRate = time.Hour
)
var (
// errShuttingDown is returned when the store cannot respond to a query because
// it has received the shutdown signal.
// errShuttingDown is returned when the store cannot respond to a query
// because it has received the shutdown signal.
errShuttingDown = errors.New("channel event store shutting down")
// ErrChannelNotFound is returned when a query is made for a channel that
// the event store does not have knowledge of.
// ErrChannelNotFound is returned when a query is made for a channel
// that the event store does not have knowledge of.
ErrChannelNotFound = errors.New("channel not found in event store")
// ErrPeerNotFound is returned when a query is made for a channel
// that has a peer that the event store is not currently tracking.
ErrPeerNotFound = errors.New("peer not found in event store")
)
// ChannelEventStore maintains a set of event logs for the node's channels to
@ -38,18 +50,14 @@ var (
type ChannelEventStore struct {
cfg *Config
// channels maps channel points to event logs.
channels map[wire.OutPoint]*chanEventLog
// peers tracks all of our currently monitored peers and their channels.
peers map[route.Vertex]peerMonitor
// peers tracks the current online status of peers based on online/offline
// events.
peers map[route.Vertex]bool
// chanInfoRequests serves requests for information about our channel.
chanInfoRequests chan channelInfoRequest
// lifespanRequests serves requests for the lifespan of channels.
lifespanRequests chan lifespanRequest
// uptimeRequests serves requests for the uptime of channels.
uptimeRequests chan uptimeRequest
// peerRequests serves requests for information about a peer.
peerRequests chan peerRequest
quit chan struct{}
@ -60,49 +68,58 @@ type ChannelEventStore struct {
// activity. All elements of the config must be non-nil for the event store to
// operate.
type Config struct {
// SubscribeChannelEvents provides a subscription client which provides a
// stream of channel events.
SubscribeChannelEvents func() (*subscribe.Client, error)
// SubscribeChannelEvents provides a subscription client which provides
// a stream of channel events.
SubscribeChannelEvents func() (subscribe.Subscription, error)
// SubscribePeerEvents provides a subscription client which provides a
// stream of peer online/offline events.
SubscribePeerEvents func() (*subscribe.Client, error)
SubscribePeerEvents func() (subscribe.Subscription, error)
// GetOpenChannels provides a list of existing open channels which is used
// to populate the ChannelEventStore with a set of channels on startup.
// GetOpenChannels provides a list of existing open channels which is
// used to populate the ChannelEventStore with a set of channels on
// startup.
GetOpenChannels func() ([]*channeldb.OpenChannel, error)
// Clock is the time source that the subsystem uses, provided here
// for ease of testing.
Clock clock.Clock
// WriteFlapCounts records the flap count for a set of peers on disk.
WriteFlapCount func(map[route.Vertex]*channeldb.FlapCount) error
// ReadFlapCount gets the flap count for a peer on disk.
ReadFlapCount func(route.Vertex) (*channeldb.FlapCount, error)
// FlapCountTicker is a ticker which controls how often we flush our
// peer's flap count to disk.
FlapCountTicker ticker.Ticker
}
// lifespanRequest contains the channel ID required to query the store for a
// channel's lifespan and a blocking response channel on which the result is
// sent.
type lifespanRequest struct {
// peerFlapCountMap is the map used to map peers to flap counts, declared here
// to allow shorter function signatures.
type peerFlapCountMap map[route.Vertex]*channeldb.FlapCount
type channelInfoRequest struct {
peer route.Vertex
channelPoint wire.OutPoint
responseChan chan lifespanResponse
responseChan chan channelInfoResponse
}
// lifespanResponse contains the response to a lifespanRequest and an error if
// one occurred.
type lifespanResponse struct {
start time.Time
end time.Time
err error
type channelInfoResponse struct {
info *ChannelInfo
err error
}
// uptimeRequest contains the parameters required to query the store for a
// channel's uptime and a blocking response channel on which the result is sent.
type uptimeRequest struct {
channelPoint wire.OutPoint
startTime time.Time
endTime time.Time
responseChan chan uptimeResponse
type peerRequest struct {
peer route.Vertex
responseChan chan peerResponse
}
// uptimeResponse contains the response to an uptimeRequest and an error if one
// occurred.
type uptimeResponse struct {
uptime time.Duration
err error
type peerResponse struct {
flapCount int
ts *time.Time
err error
}
// NewChannelEventStore initializes an event store with the config provided.
@ -111,10 +128,9 @@ type uptimeResponse struct {
func NewChannelEventStore(config *Config) *ChannelEventStore {
store := &ChannelEventStore{
cfg: config,
channels: make(map[wire.OutPoint]*chanEventLog),
peers: make(map[route.Vertex]bool),
lifespanRequests: make(chan lifespanRequest),
uptimeRequests: make(chan uptimeRequest),
peers: make(map[route.Vertex]peerMonitor),
chanInfoRequests: make(chan channelInfoRequest),
peerRequests: make(chan peerRequest),
quit: make(chan struct{}),
}
@ -140,7 +156,8 @@ func (c *ChannelEventStore) Start() error {
return err
}
// cancel should be called to cancel all subscriptions if an error occurs.
// cancel should be called to cancel all subscriptions if an error
// occurs.
cancel := func() {
channelClient.Cancel()
peerClient.Cancel()
@ -166,8 +183,8 @@ func (c *ChannelEventStore) Start() error {
return err
}
// Add existing channels to the channel store with an initial peer
// online or offline event.
// Add existing channels to the channel store with an initial
// peer online or offline event.
c.addChannel(ch.FundingOutpoint, peerKey)
}
@ -186,63 +203,98 @@ func (c *ChannelEventStore) Start() error {
func (c *ChannelEventStore) Stop() {
log.Info("Stopping event store")
c.cfg.FlapCountTicker.Stop()
// Stop the consume goroutine.
close(c.quit)
c.wg.Wait()
}
// addChannel adds a new channel to the ChannelEventStore's map of channels with
// an initial peer online state (if the peer is online). If the channel is
// already present in the map, the function returns early. This function should
// be called to add existing channels on startup and when open channel events
// are observed.
// addChannel checks whether we are already tracking a channel's peer, creates a
// new peer log to track it if we are not yet monitoring it, and adds the
// channel.
func (c *ChannelEventStore) addChannel(channelPoint wire.OutPoint,
peer route.Vertex) {
// Check for the unexpected case where the channel is already in the store.
_, ok := c.channels[channelPoint]
if ok {
log.Errorf("Channel %v duplicated in channel store", channelPoint)
peerMonitor, err := c.getPeerMonitor(peer)
if err != nil {
log.Error("could not create monitor: %v", err)
return
}
// Create an event log for the channel.
eventLog := newEventLog(channelPoint, peer, time.Now)
if err := peerMonitor.addChannel(channelPoint); err != nil {
log.Errorf("could not add channel: %v", err)
}
}
// If the peer is already online, add a peer online event to record
// the starting state of the peer.
if c.peers[peer] {
eventLog.add(peerOnlineEvent)
// getPeerMonitor tries to get an existing peer monitor from our in memory list,
// and falls back to creating a new monitor if it is not currently known.
func (c *ChannelEventStore) getPeerMonitor(peer route.Vertex) (peerMonitor,
error) {
peerMonitor, ok := c.peers[peer]
if ok {
return peerMonitor, nil
}
c.channels[channelPoint] = eventLog
var (
flapCount int
lastFlap *time.Time
)
historicalFlap, err := c.cfg.ReadFlapCount(peer)
switch err {
// If we do not have any records for this peer we set a 0 flap count
// and timestamp.
case channeldb.ErrNoPeerBucket:
case nil:
flapCount = int(historicalFlap.Count)
lastFlap = &historicalFlap.LastFlap
// Return if we get an unexpected error.
default:
return nil, err
}
peerMonitor = newPeerLog(c.cfg.Clock, flapCount, lastFlap)
c.peers[peer] = peerMonitor
return peerMonitor, nil
}
// closeChannel records a closed time for a channel, and returns early is the
// channel is not known to the event store.
func (c *ChannelEventStore) closeChannel(channelPoint wire.OutPoint) {
// Check for the unexpected case where the channel is unknown to the store.
eventLog, ok := c.channels[channelPoint]
// channel is not known to the event store. We log warnings (rather than errors)
// when we cannot find a peer/channel because channels that we restore from a
// static channel backup do not have their open notified, so the event store
// never learns about them, but they are closed using the regular flow so we
// will try to remove them on close. At present, we cannot easily distinguish
// between these closes and others.
func (c *ChannelEventStore) closeChannel(channelPoint wire.OutPoint,
peer route.Vertex) {
peerMonitor, ok := c.peers[peer]
if !ok {
log.Errorf("Close channel %v unknown to store", channelPoint)
log.Warnf("peer not known to store: %v", peer)
return
}
eventLog.close()
if err := peerMonitor.removeChannel(channelPoint); err != nil {
log.Warnf("could not remove channel: %v", err)
}
}
// peerEvent adds a peer online or offline event to all channels we currently
// have open with a peer.
func (c *ChannelEventStore) peerEvent(peer route.Vertex, event eventType) {
// Track current online status of peers in the channelEventStore.
c.peers[peer] = event == peerOnlineEvent
for _, eventLog := range c.channels {
if eventLog.peer == peer {
eventLog.add(event)
}
// peerEvent creates a peer monitor for a peer if we do not currently have
// one, and adds an online event to it.
func (c *ChannelEventStore) peerEvent(peer route.Vertex, online bool) {
peerMonitor, err := c.getPeerMonitor(peer)
if err != nil {
log.Error("could not create monitor: %v", err)
return
}
peerMonitor.onlineEvent(online)
}
// subscriptions abstracts away from subscription clients to allow for mocking.
@ -256,8 +308,22 @@ type subscriptions struct {
// the event store with channel and peer events, and serves requests for channel
// uptime and lifespan.
func (c *ChannelEventStore) consume(subscriptions *subscriptions) {
defer c.wg.Done()
defer subscriptions.cancel()
// Start our flap count ticker.
c.cfg.FlapCountTicker.Resume()
// On exit, we will cancel our subscriptions and write our most recent
// flap counts to disk. This ensures that we have consistent data in
// the case of a graceful shutdown. If we do not shutdown gracefully,
// our worst case is data from our last flap count tick (1H).
defer func() {
subscriptions.cancel()
if err := c.recordFlapCount(); err != nil {
log.Errorf("error recording flap on shutdown: %v", err)
}
c.wg.Done()
}()
// Consume events until the channel is closed.
for {
@ -265,68 +331,78 @@ func (c *ChannelEventStore) consume(subscriptions *subscriptions) {
// Process channel opened and closed events.
case e := <-subscriptions.channelUpdates:
switch event := e.(type) {
// A new channel has been opened, we must add the channel to the
// store and record a channel open event.
// A new channel has been opened, we must add the
// channel to the store and record a channel open event.
case channelnotifier.OpenChannelEvent:
compressed := event.Channel.IdentityPub.SerializeCompressed()
peerKey, err := route.NewVertexFromBytes(
event.Channel.IdentityPub.SerializeCompressed(),
compressed,
)
if err != nil {
log.Errorf("Could not get vertex from: %v",
event.Channel.IdentityPub.SerializeCompressed())
log.Errorf("Could not get vertex "+
"from: %v", compressed)
}
c.addChannel(event.Channel.FundingOutpoint, peerKey)
c.addChannel(
event.Channel.FundingOutpoint, peerKey,
)
// A channel has been closed, we must remove the channel from the
// store and record a channel closed event.
// A channel has been closed, we must remove the channel
// from the store and record a channel closed event.
case channelnotifier.ClosedChannelEvent:
c.closeChannel(event.CloseSummary.ChanPoint)
compressed := event.CloseSummary.RemotePub.SerializeCompressed()
peerKey, err := route.NewVertexFromBytes(
compressed,
)
if err != nil {
log.Errorf("Could not get vertex "+
"from: %v", compressed)
continue
}
c.closeChannel(
event.CloseSummary.ChanPoint, peerKey,
)
}
// Process peer online and offline events.
case e := <-subscriptions.peerUpdates:
switch event := e.(type) {
// We have reestablished a connection with our peer, and should
// record an online event for any channels with that peer.
// We have reestablished a connection with our peer,
// and should record an online event for any channels
// with that peer.
case peernotifier.PeerOnlineEvent:
c.peerEvent(event.PubKey, peerOnlineEvent)
c.peerEvent(event.PubKey, true)
// We have lost a connection with our peer, and should record an
// offline event for any channels with that peer.
// We have lost a connection with our peer, and should
// record an offline event for any channels with that
// peer.
case peernotifier.PeerOfflineEvent:
c.peerEvent(event.PubKey, peerOfflineEvent)
c.peerEvent(event.PubKey, false)
}
// Serve all requests for channel lifetime.
case req := <-c.lifespanRequests:
var resp lifespanResponse
channel, ok := c.channels[req.channelPoint]
if !ok {
resp.err = ErrChannelNotFound
} else {
resp.start = channel.openedAt
resp.end = channel.closedAt
}
case req := <-c.chanInfoRequests:
var resp channelInfoResponse
resp.info, resp.err = c.getChanInfo(req)
req.responseChan <- resp
// Serve requests for channel uptime.
case req := <-c.uptimeRequests:
var resp uptimeResponse
channel, ok := c.channels[req.channelPoint]
if !ok {
resp.err = ErrChannelNotFound
} else {
uptime, err := channel.uptime(req.startTime, req.endTime)
resp.uptime = uptime
resp.err = err
}
// Serve all requests for information about our peer.
case req := <-c.peerRequests:
var resp peerResponse
resp.flapCount, resp.ts, resp.err = c.flapCount(
req.peer,
)
req.responseChan <- resp
case <-c.cfg.FlapCountTicker.Ticks():
if err := c.recordFlapCount(); err != nil {
log.Errorf("could not record flap "+
"count: %v", err)
}
// Exit if the store receives the signal to shutdown.
case <-c.quit:
return
@ -334,65 +410,151 @@ func (c *ChannelEventStore) consume(subscriptions *subscriptions) {
}
}
// GetLifespan returns the opening and closing time observed for a channel and
// a boolean to indicate whether the channel is known the the event store. If
// the channel is still open, a zero close time is returned.
func (c *ChannelEventStore) GetLifespan(
channelPoint wire.OutPoint) (time.Time, time.Time, error) {
// ChannelInfo provides the set of information that the event store has recorded
// for a channel.
type ChannelInfo struct {
// Lifetime is the total amount of time we have monitored the channel
// for.
Lifetime time.Duration
request := lifespanRequest{
// Uptime is the total amount of time that the channel peer has been
// observed as online during the monitored lifespan.
Uptime time.Duration
}
// GetChanInfo gets all the information we have on a channel in the event store.
func (c *ChannelEventStore) GetChanInfo(channelPoint wire.OutPoint,
peer route.Vertex) (*ChannelInfo, error) {
request := channelInfoRequest{
peer: peer,
channelPoint: channelPoint,
responseChan: make(chan lifespanResponse),
responseChan: make(chan channelInfoResponse),
}
// Send a request for the channel's lifespan to the main event loop, or
// return early with an error if the store has already received a shutdown
// signal.
// Send a request for the channel's information to the main event loop,
// or return early with an error if the store has already received a
// shutdown signal.
select {
case c.lifespanRequests <- request:
case c.chanInfoRequests <- request:
case <-c.quit:
return time.Time{}, time.Time{}, errShuttingDown
return nil, errShuttingDown
}
// Return the response we receive on the response channel or exit early if
// the store is instructed to exit.
// Return the response we receive on the response channel or exit early
// if the store is instructed to exit.
select {
case resp := <-request.responseChan:
return resp.start, resp.end, resp.err
return resp.info, resp.err
case <-c.quit:
return time.Time{}, time.Time{}, errShuttingDown
return nil, errShuttingDown
}
}
// GetUptime returns the uptime of a channel over a period and an error if the
// channel cannot be found or the uptime calculation fails.
func (c *ChannelEventStore) GetUptime(channelPoint wire.OutPoint, startTime,
endTime time.Time) (time.Duration, error) {
// getChanInfo collects channel information for a channel. It gets uptime over
// the full lifetime of the channel.
func (c *ChannelEventStore) getChanInfo(req channelInfoRequest) (*ChannelInfo,
error) {
request := uptimeRequest{
channelPoint: channelPoint,
startTime: startTime,
endTime: endTime,
responseChan: make(chan uptimeResponse),
peerMonitor, ok := c.peers[req.peer]
if !ok {
return nil, ErrPeerNotFound
}
// Send a request for the channel's uptime to the main event loop, or
// return early with an error if the store has already received a shutdown
// signal.
lifetime, uptime, err := peerMonitor.channelUptime(req.channelPoint)
if err != nil {
return nil, err
}
return &ChannelInfo{
Lifetime: lifetime,
Uptime: uptime,
}, nil
}
// FlapCount returns the flap count we have for a peer and the timestamp of its
// last flap. If we do not have any flaps recorded for the peer, the last flap
// timestamp will be nil.
func (c *ChannelEventStore) FlapCount(peer route.Vertex) (int, *time.Time,
error) {
request := peerRequest{
peer: peer,
responseChan: make(chan peerResponse),
}
// Send a request for the peer's information to the main event loop,
// or return early with an error if the store has already received a
// shutdown signal.
select {
case c.uptimeRequests <- request:
case c.peerRequests <- request:
case <-c.quit:
return 0, errShuttingDown
return 0, nil, errShuttingDown
}
// Return the response we receive on the response channel or exit early if
// the store is instructed to exit.
// Return the response we receive on the response channel or exit early
// if the store is instructed to exit.
select {
case resp := <-request.responseChan:
return resp.uptime, resp.err
return resp.flapCount, resp.ts, resp.err
case <-c.quit:
return 0, errShuttingDown
return 0, nil, errShuttingDown
}
}
// flapCount gets our peer flap count and last flap timestamp from our in memory
// record of a peer, falling back to on disk if we are not currently tracking
// the peer. If we have no flap count recorded for the peer, a nil last flap
// time will be returned.
func (c *ChannelEventStore) flapCount(peer route.Vertex) (int, *time.Time,
error) {
// First check whether we are tracking this peer in memory, because this
// record will have the most accurate flap count. We do not fail if we
// can't find the peer in memory, because we may have previously
// recorded its flap count on disk.
peerMonitor, ok := c.peers[peer]
if ok {
count, ts := peerMonitor.getFlapCount()
return count, ts, nil
}
// Try to get our flap count from the database. If this value is not
// recorded, we return a nil last flap time to indicate that we have no
// record of the peer's flap count.
flapCount, err := c.cfg.ReadFlapCount(peer)
switch err {
case channeldb.ErrNoPeerBucket:
return 0, nil, nil
case nil:
return int(flapCount.Count), &flapCount.LastFlap, nil
default:
return 0, nil, err
}
}
// recordFlapCount will record our flap count for each peer that we are
// currently tracking, skipping peers that have a 0 flap count.
func (c *ChannelEventStore) recordFlapCount() error {
updates := make(peerFlapCountMap)
for peer, monitor := range c.peers {
flapCount, lastFlap := monitor.getFlapCount()
if lastFlap == nil {
continue
}
updates[peer] = &channeldb.FlapCount{
Count: uint32(flapCount),
LastFlap: *lastFlap,
}
}
log.Debugf("recording flap count for: %v peers", len(updates))
return c.cfg.WriteFlapCount(updates)
}

@ -2,38 +2,40 @@ package chanfitness
import (
"errors"
"math/big"
"testing"
"time"
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/channelnotifier"
"github.com/lightningnetwork/lnd/peernotifier"
"github.com/lightningnetwork/lnd/clock"
"github.com/lightningnetwork/lnd/routing/route"
"github.com/lightningnetwork/lnd/subscribe"
"github.com/stretchr/testify/require"
)
// testNow is the current time tests will use.
var testNow = time.Unix(1592465134, 0)
// TestStartStoreError tests the starting of the store in cases where the setup
// functions fail. It does not test the mechanics of consuming events because
// these are covered in a separate set of tests.
func TestStartStoreError(t *testing.T) {
// Ok and erroring subscribe functions are defined here to de-clutter tests.
okSubscribeFunc := func() (*subscribe.Client, error) {
return &subscribe.Client{
Cancel: func() {},
}, nil
// Ok and erroring subscribe functions are defined here to de-clutter
// tests.
okSubscribeFunc := func() (subscribe.Subscription, error) {
return newMockSubscription(t), nil
}
errSubscribeFunc := func() (client *subscribe.Client, e error) {
errSubscribeFunc := func() (subscribe.Subscription, error) {
return nil, errors.New("intentional test err")
}
tests := []struct {
name string
ChannelEvents func() (*subscribe.Client, error)
PeerEvents func() (*subscribe.Client, error)
ChannelEvents func() (subscribe.Subscription, error)
PeerEvents func() (subscribe.Subscription, error)
GetChannels func() ([]*channeldb.OpenChannel, error)
}{
{
@ -49,7 +51,7 @@ func TestStartStoreError(t *testing.T) {
name: "Get open channels fails",
ChannelEvents: okSubscribeFunc,
PeerEvents: okSubscribeFunc,
GetChannels: func() (channels []*channeldb.OpenChannel, e error) {
GetChannels: func() ([]*channeldb.OpenChannel, error) {
return nil, errors.New("intentional test err")
},
},
@ -59,15 +61,18 @@ func TestStartStoreError(t *testing.T) {
test := test
t.Run(test.name, func(t *testing.T) {
clock := clock.NewTestClock(testNow)
store := NewChannelEventStore(&Config{
SubscribeChannelEvents: test.ChannelEvents,
SubscribePeerEvents: test.PeerEvents,
GetOpenChannels: test.GetChannels,
Clock: clock,
})
err := store.Start()
// Check that we receive an error, because the test only checks for
// error cases.
// Check that we receive an error, because the test only
// checks for error cases.
if err == nil {
t.Fatalf("Expected error on startup, got: nil")
}
@ -75,29 +80,6 @@ func TestStartStoreError(t *testing.T) {
}
}
// getTestChannel returns a non-zero peer pubKey, serialized pubKey and channel
// outpoint for testing.
func getTestChannel(t *testing.T) (*btcec.PublicKey, route.Vertex,
wire.OutPoint) {
privKey, err := btcec.NewPrivateKey(btcec.S256())
if err != nil {
t.Fatalf("Error getting pubkey: %v", err)
}
pubKey, err := route.NewVertexFromBytes(
privKey.PubKey().SerializeCompressed(),
)
if err != nil {
t.Fatalf("Could not create vertex: %v", err)
}
return privKey.PubKey(), pubKey, wire.OutPoint{
Hash: [chainhash.HashSize]byte{1, 2, 3},
Index: 0,
}
}
// TestMonitorChannelEvents tests the store's handling of channel and peer
// events. It tests for the unexpected cases where we receive a channel open for
// an already known channel and but does not test for closing an unknown channel
@ -105,425 +87,257 @@ func getTestChannel(t *testing.T) (*btcec.PublicKey, route.Vertex,
// through an eventLog which does not exist. This test does not test handling
// of uptime and lifespan requests, as they are tested in their own tests.
func TestMonitorChannelEvents(t *testing.T) {
pubKey, vertex, chanPoint := getTestChannel(t)
var (
pubKey = &btcec.PublicKey{
X: big.NewInt(0),
Y: big.NewInt(1),
Curve: btcec.S256(),
}
tests := []struct {
name string
chan1 = wire.OutPoint{Index: 1}
chan2 = wire.OutPoint{Index: 2}
)
// generateEvents takes channels which represent the updates channels
// for subscription clients and passes events in the desired order.
// This function is intended to be blocking so that the test does not
// have a data race with event consumption, so the channels should not
// be buffered.
generateEvents func(channelEvents, peerEvents chan<- interface{})
peer1, err := route.NewVertexFromBytes(pubKey.SerializeCompressed())
require.NoError(t, err)
// expectedEvents is the expected set of event types in the store.
expectedEvents []eventType
}{
{
name: "Channel opened, peer comes online",
generateEvents: func(channelEvents, peerEvents chan<- interface{}) {
// Add an open channel event
channelEvents <- channelnotifier.OpenChannelEvent{
Channel: &channeldb.OpenChannel{
FundingOutpoint: chanPoint,
IdentityPub: pubKey,
},
}
t.Run("peer comes online after channel open", func(t *testing.T) {
gen := func(ctx *chanEventStoreTestCtx) {
ctx.sendChannelOpenedUpdate(pubKey, chan1)
ctx.peerEvent(peer1, true)
}
// Add a peer online event.
peerEvents <- peernotifier.PeerOnlineEvent{PubKey: vertex}
},
expectedEvents: []eventType{peerOnlineEvent},
},
{
name: "Duplicate channel open events",
generateEvents: func(channelEvents, peerEvents chan<- interface{}) {
// Add an open channel event
channelEvents <- channelnotifier.OpenChannelEvent{
Channel: &channeldb.OpenChannel{
FundingOutpoint: chanPoint,
IdentityPub: pubKey,
},
}
testEventStore(t, gen, peer1, 1)
})
// Add a peer online event.
peerEvents <- peernotifier.PeerOnlineEvent{PubKey: vertex}
t.Run("duplicate channel open events", func(t *testing.T) {
gen := func(ctx *chanEventStoreTestCtx) {
ctx.sendChannelOpenedUpdate(pubKey, chan1)
ctx.sendChannelOpenedUpdate(pubKey, chan1)
ctx.peerEvent(peer1, true)
}
// Add a duplicate channel open event.
channelEvents <- channelnotifier.OpenChannelEvent{
Channel: &channeldb.OpenChannel{
FundingOutpoint: chanPoint,
IdentityPub: pubKey,
},
}
},
expectedEvents: []eventType{peerOnlineEvent},
},
{
name: "Channel opened, peer already online",
generateEvents: func(channelEvents, peerEvents chan<- interface{}) {
// Add a peer online event.
peerEvents <- peernotifier.PeerOnlineEvent{PubKey: vertex}
testEventStore(t, gen, peer1, 1)
})
// Add an open channel event
channelEvents <- channelnotifier.OpenChannelEvent{
Channel: &channeldb.OpenChannel{
FundingOutpoint: chanPoint,
IdentityPub: pubKey,
},
}
},
expectedEvents: []eventType{peerOnlineEvent},
},
t.Run("peer online before channel created", func(t *testing.T) {
gen := func(ctx *chanEventStoreTestCtx) {
ctx.peerEvent(peer1, true)
ctx.sendChannelOpenedUpdate(pubKey, chan1)
}
{
name: "Channel opened, peer offline, closed",
generateEvents: func(channelEvents, peerEvents chan<- interface{}) {
// Add an open channel event
channelEvents <- channelnotifier.OpenChannelEvent{
Channel: &channeldb.OpenChannel{
FundingOutpoint: chanPoint,
IdentityPub: pubKey,
},
}
testEventStore(t, gen, peer1, 1)
})
// Add a peer online event.
peerEvents <- peernotifier.PeerOfflineEvent{PubKey: vertex}
t.Run("multiple channels for peer", func(t *testing.T) {
gen := func(ctx *chanEventStoreTestCtx) {
ctx.peerEvent(peer1, true)
ctx.sendChannelOpenedUpdate(pubKey, chan1)
// Add a close channel event.
channelEvents <- channelnotifier.ClosedChannelEvent{
CloseSummary: &channeldb.ChannelCloseSummary{
ChanPoint: chanPoint,
},
}
},
expectedEvents: []eventType{peerOfflineEvent},
},
{
name: "Event after channel close not recorded",
generateEvents: func(channelEvents, peerEvents chan<- interface{}) {
// Add an open channel event
channelEvents <- channelnotifier.OpenChannelEvent{
Channel: &channeldb.OpenChannel{
FundingOutpoint: chanPoint,
IdentityPub: pubKey,
},
}
ctx.peerEvent(peer1, false)
ctx.sendChannelOpenedUpdate(pubKey, chan2)
}
// Add a close channel event.
channelEvents <- channelnotifier.ClosedChannelEvent{
CloseSummary: &channeldb.ChannelCloseSummary{
ChanPoint: chanPoint,
},
}
testEventStore(t, gen, peer1, 2)
})
// Add a peer online event.
peerEvents <- peernotifier.PeerOfflineEvent{PubKey: vertex}
},
},
}
t.Run("multiple channels for peer, one closed", func(t *testing.T) {
gen := func(ctx *chanEventStoreTestCtx) {
ctx.peerEvent(peer1, true)
ctx.sendChannelOpenedUpdate(pubKey, chan1)
for _, test := range tests {
test := test
ctx.peerEvent(peer1, false)
ctx.sendChannelOpenedUpdate(pubKey, chan2)
t.Run(test.name, func(t *testing.T) {
// Create a store with the channels and online peers specified
// by the test.
store := NewChannelEventStore(&Config{})
ctx.closeChannel(chan1, pubKey)
ctx.peerEvent(peer1, true)
}
// Create channels which represent the subscriptions we have to peer
// and client events.
channelEvents := make(chan interface{})
peerEvents := make(chan interface{})
testEventStore(t, gen, peer1, 1)
})
store.wg.Add(1)
go store.consume(&subscriptions{
channelUpdates: channelEvents,
peerUpdates: peerEvents,
cancel: func() {},
})
// Add events to the store then kill the goroutine using store.Stop.
test.generateEvents(channelEvents, peerEvents)
store.Stop()
// Retrieve the eventLog for the channel and check that its
// contents are as expected.
eventLog, ok := store.channels[chanPoint]
if !ok {
t.Fatalf("Expected to find event store")
}
for i, e := range eventLog.events {
if test.expectedEvents[i] != e.eventType {
t.Fatalf("Expected type: %v, got: %v",
test.expectedEvents[i], e.eventType)
}
}
})
}
}
// TestGetLifetime tests the GetLifetime function for the cases where a channel
// testEventStore creates a new test contexts, generates a set of events for it
// and tests that it has the number of channels we expect.
func testEventStore(t *testing.T, generateEvents func(*chanEventStoreTestCtx),
peer route.Vertex, expectedChannels int) {
testCtx := newChanEventStoreTestCtx(t)
testCtx.start()
generateEvents(testCtx)
// Shutdown the store so that we can safely access the maps in our event
// store.
testCtx.stop()
// Get our peer and check that it has the channels we expect.
monitor, ok := testCtx.store.peers[peer]
require.True(t, ok)
require.Equal(t, expectedChannels, monitor.channelCount())
}
// TestStoreFlapCount tests flushing of flap counts to disk on timer ticks and
// on store shutdown.
func TestStoreFlapCount(t *testing.T) {
testCtx := newChanEventStoreTestCtx(t)
testCtx.start()
pubkey, _, _ := testCtx.createChannel()
testCtx.peerEvent(pubkey, false)
// Now, we tick our flap count ticker. We expect our main goroutine to
// flush our tick count to disk.
testCtx.tickFlapCount()
// Since we just tracked a offline event, we expect a single flap for
// our peer.
expectedUpdate := peerFlapCountMap{
pubkey: {
Count: 1,
LastFlap: testCtx.clock.Now(),
},
}
testCtx.assertFlapCountUpdated()
testCtx.assertFlapCountUpdates(expectedUpdate)
// Create three events for out peer, online/offline/online.
testCtx.peerEvent(pubkey, true)
testCtx.peerEvent(pubkey, false)
testCtx.peerEvent(pubkey, true)
// Trigger another write.
testCtx.tickFlapCount()
// Since we have processed 3 more events for our peer, we update our
// expected online map to have a flap count of 4 for this peer.
expectedUpdate[pubkey] = &channeldb.FlapCount{
Count: 4,
LastFlap: testCtx.clock.Now(),
}
testCtx.assertFlapCountUpdated()
testCtx.assertFlapCountUpdates(expectedUpdate)
testCtx.stop()
}
// TestGetChanInfo tests the GetChanInfo function for the cases where a channel
// is known and unknown to the store.
func TestGetLifetime(t *testing.T) {
now := time.Now()
func TestGetChanInfo(t *testing.T) {
ctx := newChanEventStoreTestCtx(t)
ctx.start()
tests := []struct {
name string
channelFound bool
channelPoint wire.OutPoint
opened time.Time
closed time.Time
expectedError error
}{
{
name: "Channel found",
channelFound: true,
opened: now,
closed: now.Add(time.Hour * -1),
expectedError: nil,
},
{
name: "Channel not found",
expectedError: ErrChannelNotFound,
},
}
// Make a note of the time that our mocked clock starts on.
now := ctx.clock.Now()
for _, test := range tests {
test := test
// Create mock vars for a channel but do not add them to our store yet.
peer, pk, channel := ctx.newChannel()
t.Run(test.name, func(t *testing.T) {
// Create and empty events store for testing.
store := NewChannelEventStore(&Config{})
// Send an online event for our peer, although we do not yet have an
// open channel.
ctx.peerEvent(peer, true)
// Start goroutine which consumes GetLifespan requests.
store.wg.Add(1)
go store.consume(&subscriptions{
channelUpdates: make(chan interface{}),
peerUpdates: make(chan interface{}),
cancel: func() {},
})
// Try to get info for a channel that has not been opened yet, we
// expect to get an error.
_, err := ctx.store.GetChanInfo(channel, peer)
require.Equal(t, ErrChannelNotFound, err)
// Stop the store's go routine.
defer store.Stop()
// Now we send our store a notification that a channel has been opened.
ctx.sendChannelOpenedUpdate(pk, channel)
// Add channel to eventStore if the test indicates that it should
// be present.
if test.channelFound {
store.channels[test.channelPoint] = &chanEventLog{
openedAt: test.opened,
closedAt: test.closed,
}
}
// Wait for our channel to be recognized by our store. We need to wait
// for the channel to be created so that we do not update our time
// before the channel open is processed.
require.Eventually(t, func() bool {
_, err = ctx.store.GetChanInfo(channel, peer)
return err == nil
}, timeout, time.Millisecond*20)
open, close, err := store.GetLifespan(test.channelPoint)
if test.expectedError != err {
t.Fatalf("Expected: %v, got: %v", test.expectedError, err)
}
// Increment our test clock by an hour.
now = now.Add(time.Hour)
ctx.clock.SetTime(now)
if open != test.opened {
t.Errorf("Expected: %v, got %v", test.opened, open)
}
// At this stage our channel has been open and online for an hour.
info, err := ctx.store.GetChanInfo(channel, peer)
require.NoError(t, err)
require.Equal(t, time.Hour, info.Lifetime)
require.Equal(t, time.Hour, info.Uptime)
if close != test.closed {
t.Errorf("Expected: %v, got %v", test.closed, close)
}
})
}
// Now we send a peer offline event for our channel.
ctx.peerEvent(peer, false)
// Since we have not bumped our mocked time, our uptime calculations
// should be the same, even though we've just processed an offline
// event.
info, err = ctx.store.GetChanInfo(channel, peer)
require.NoError(t, err)
require.Equal(t, time.Hour, info.Lifetime)
require.Equal(t, time.Hour, info.Uptime)
// Progress our time again. This time, our peer is currently tracked as
// being offline, so we expect our channel info to reflect that the peer
// has been offline for this period.
now = now.Add(time.Hour)
ctx.clock.SetTime(now)
info, err = ctx.store.GetChanInfo(channel, peer)
require.NoError(t, err)
require.Equal(t, time.Hour*2, info.Lifetime)
require.Equal(t, time.Hour, info.Uptime)
ctx.stop()
}
// TestGetUptime tests the getUptime call for channels known to the event store.
// It does not test the trivial case where a channel is unknown to the store,
// because this is simply a zero return if an item is not found in a map. It
// tests the unexpected edge cases where a tracked channel does not have any
// events recorded, and when a zero time is specified for the uptime range.
func TestGetUptime(t *testing.T) {
// Set time for deterministic unit tests.
now := time.Now()
// TestFlapCount tests querying the store for peer flap counts, covering the
// case where the peer is tracked in memory, and the case where we need to
// lookup the peer on disk.
func TestFlapCount(t *testing.T) {
clock := clock.NewTestClock(testNow)
twoHoursAgo := now.Add(time.Hour * -2)
fourHoursAgo := now.Add(time.Hour * -4)
var (
peer = route.Vertex{9, 9, 9}
peerFlapCount = 3
lastFlap = clock.Now()
)
tests := []struct {
name string
channelPoint wire.OutPoint
// events is the set of events we expect to find in the channel store.
events []*channelEvent
// openedAt is the time the channel is recorded as open by the store.
openedAt time.Time
// closedAt is the time the channel is recorded as closed by the store.
// If the channel is still open, this value is zero.
closedAt time.Time
// channelFound is true if we expect to find the channel in the store.
channelFound bool
// startTime specifies the beginning of the uptime range we want to
// calculate.
startTime time.Time
// endTime specified the end of the uptime range we want to calculate.
endTime time.Time
expectedUptime time.Duration
expectedError error
}{
{
name: "No events",
startTime: twoHoursAgo,
endTime: now,
channelFound: true,
expectedError: nil,
},
{
name: "50% Uptime",
events: []*channelEvent{
{
timestamp: fourHoursAgo,
eventType: peerOnlineEvent,
},
{
timestamp: twoHoursAgo,
eventType: peerOfflineEvent,
},
},
openedAt: fourHoursAgo,
expectedUptime: time.Hour * 2,
startTime: fourHoursAgo,
endTime: now,
channelFound: true,
expectedError: nil,
},
{
name: "Zero start time",
events: []*channelEvent{
{
timestamp: fourHoursAgo,
eventType: peerOnlineEvent,
},
},
openedAt: fourHoursAgo,
expectedUptime: time.Hour * 4,
endTime: now,
channelFound: true,
expectedError: nil,
},
{
name: "Channel not found",
startTime: twoHoursAgo,
endTime: now,
channelFound: false,
expectedError: ErrChannelNotFound,
},
// Create a test context with one peer's flap count already recorded,
// which mocks it already having its flap count stored on disk.
ctx := newChanEventStoreTestCtx(t)
ctx.flapUpdates[peer] = &channeldb.FlapCount{
Count: uint32(peerFlapCount),
LastFlap: lastFlap,
}
for _, test := range tests {
test := test
ctx.start()
t.Run(test.name, func(t *testing.T) {
// Set up event store with the events specified for the test and
// mocked time.
store := NewChannelEventStore(&Config{})
// Create test variables for a peer and channel, but do not add it to
// our store yet.
peer1 := route.Vertex{1, 2, 3}
// Start goroutine which consumes GetUptime requests.
store.wg.Add(1)
go store.consume(&subscriptions{
channelUpdates: make(chan interface{}),
peerUpdates: make(chan interface{}),
cancel: func() {},
})
// First, query for a peer that we have no record of in memory or on
// disk and confirm that we indicate that the peer was not found.
_, ts, err := ctx.store.FlapCount(peer1)
require.NoError(t, err)
require.Nil(t, ts)
// Stop the store's goroutine.
defer store.Stop()
// Send an online event for our peer.
ctx.peerEvent(peer1, true)
// Add the channel to the store if it is intended to be found.
if test.channelFound {
store.channels[test.channelPoint] = &chanEventLog{
events: test.events,
now: func() time.Time { return now },
openedAt: test.openedAt,
closedAt: test.closedAt,
}
}
// Assert that we now find a record of the peer with flap count = 1.
count, ts, err := ctx.store.FlapCount(peer1)
require.NoError(t, err)
require.Equal(t, lastFlap, *ts)
require.Equal(t, 1, count)
uptime, err := store.GetUptime(test.channelPoint, test.startTime, test.endTime)
if test.expectedError != err {
t.Fatalf("Expected: %v, got: %v", test.expectedError, err)
}
// Make a request for our peer that not tracked in memory, but does
// have its flap count stored on disk.
count, ts, err = ctx.store.FlapCount(peer)
require.NoError(t, err)
require.Equal(t, lastFlap, *ts)
require.Equal(t, peerFlapCount, count)
if uptime != test.expectedUptime {
t.Fatalf("Expected uptime percentage: %v, got %v",
test.expectedUptime, uptime)
}
})
}
}
// TestAddChannel tests that channels are added to the event store with
// appropriate timestamps. This test addresses a bug where offline channels
// did not have an opened time set, and checks that an online event is set for
// peers that are online at the time that a channel is opened.
func TestAddChannel(t *testing.T) {
_, vertex, chanPoint := getTestChannel(t)
tests := []struct {
name string
// peers maps peers to an online state.
peers map[route.Vertex]bool
expectedEvents []eventType
}{
{
name: "peer offline",
peers: make(map[route.Vertex]bool),
expectedEvents: []eventType{},
},
{
name: "peer online",
peers: map[route.Vertex]bool{
vertex: true,
},
expectedEvents: []eventType{peerOnlineEvent},
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
store := NewChannelEventStore(&Config{})
store.peers = test.peers
// Add channel to the store.
store.addChannel(chanPoint, vertex)
// Check that the eventLog is successfully added.
eventLog, ok := store.channels[chanPoint]
if !ok {
t.Fatalf("channel should be in store")
}
// Check that the eventLog contains the events we
// expect.
for i, e := range test.expectedEvents {
if e != eventLog.events[i].eventType {
t.Fatalf("expected: %v, got: %v",
e, eventLog.events[i].eventType)
}
}
// Ensure that open time is always set.
if eventLog.openedAt.IsZero() {
t.Fatalf("channel should have opened at set")
}
})
}
ctx.stop()
}

@ -0,0 +1,306 @@
package chanfitness
import (
"math/big"
"testing"
"time"
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/channelnotifier"
"github.com/lightningnetwork/lnd/clock"
"github.com/lightningnetwork/lnd/peernotifier"
"github.com/lightningnetwork/lnd/routing/route"
"github.com/lightningnetwork/lnd/subscribe"
"github.com/lightningnetwork/lnd/ticker"
"github.com/stretchr/testify/require"
)
// timeout is the amount of time we allow our blocking test calls.
var timeout = time.Second
// chanEventStoreTestCtx is a helper struct which can be used to test the
// channel event store.
type chanEventStoreTestCtx struct {
t *testing.T
store *ChannelEventStore
channelSubscription *mockSubscription
peerSubscription *mockSubscription
// testVarIdx is an index which will be used to deterministically add
// channels and public keys to our test context. We use a single value
// for a single pubkey + channel combination because its actual value
// does not matter.
testVarIdx int
// clock is the clock that our test store will use.
clock *clock.TestClock
// flapUpdates stores our most recent set of updates flap counts.
flapUpdates peerFlapCountMap
// flapCountUpdates is a channel which receives new flap counts.
flapCountUpdates chan peerFlapCountMap
// stopped is closed when our test context is fully shutdown. It is
// used to prevent calling of functions which can only be called after
// shutdown.
stopped chan struct{}
}
// newChanEventStoreTestCtx creates a test context which can be used to test
// the event store.
func newChanEventStoreTestCtx(t *testing.T) *chanEventStoreTestCtx {
testCtx := &chanEventStoreTestCtx{
t: t,
channelSubscription: newMockSubscription(t),
peerSubscription: newMockSubscription(t),
clock: clock.NewTestClock(testNow),
flapUpdates: make(peerFlapCountMap),
flapCountUpdates: make(chan peerFlapCountMap),
stopped: make(chan struct{}),
}
cfg := &Config{
Clock: testCtx.clock,
SubscribeChannelEvents: func() (subscribe.Subscription, error) {
return testCtx.channelSubscription, nil
},
SubscribePeerEvents: func() (subscribe.Subscription, error) {
return testCtx.peerSubscription, nil
},
GetOpenChannels: func() ([]*channeldb.OpenChannel, error) {
return nil, nil
},
WriteFlapCount: func(updates map[route.Vertex]*channeldb.FlapCount) error {
// Send our whole update map into the test context's
// updates channel. The test will need to assert flap
// count updated or this send will timeout.
select {
case testCtx.flapCountUpdates <- updates:
case <-time.After(timeout):
t.Fatalf("WriteFlapCount timeout")
}
return nil
},
ReadFlapCount: func(peer route.Vertex) (*channeldb.FlapCount, error) {
count, ok := testCtx.flapUpdates[peer]
if !ok {
return nil, channeldb.ErrNoPeerBucket
}
return count, nil
},
FlapCountTicker: ticker.NewForce(FlapCountFlushRate),
}
testCtx.store = NewChannelEventStore(cfg)
return testCtx
}
// start starts the test context's event store.
func (c *chanEventStoreTestCtx) start() {
require.NoError(c.t, c.store.Start())
}
// stop stops the channel event store's subscribe servers and the store itself.
func (c *chanEventStoreTestCtx) stop() {
// On shutdown of our event store, we write flap counts to disk. In our
// test context, this write function is blocked on asserting that the
// update has occurred. We stop our store in a goroutine so that we
// can shut it down and assert that it performs these on-shutdown
// updates. The stopped channel is used to ensure that we do not finish
// our test before this shutdown has completed.
go func() {
c.store.Stop()
close(c.stopped)
}()
// We write our flap count to disk on shutdown, assert that the most
// recent record that the server has is written on shutdown. Calling
// this assert unblocks the stop function above. We don't check values
// here, so that our tests don't all require providing an expected swap
// count, but at least assert that the write occurred.
c.assertFlapCountUpdated()
<-c.stopped
// Make sure that the cancel function was called for both of our
// subscription mocks.
c.channelSubscription.assertCancelled()
c.peerSubscription.assertCancelled()
}
// newChannel creates a new, unique test channel. Note that this function
// does not add it to the test event store, it just creates mocked values.
func (c *chanEventStoreTestCtx) newChannel() (route.Vertex, *btcec.PublicKey,
wire.OutPoint) {
// Create a pubkey for our channel peer.
pubKey := &btcec.PublicKey{
X: big.NewInt(int64(c.testVarIdx)),
Y: big.NewInt(int64(c.testVarIdx)),
Curve: btcec.S256(),
}
// Create vertex from our pubkey.
vertex, err := route.NewVertexFromBytes(pubKey.SerializeCompressed())
require.NoError(c.t, err)
// Create a channel point using our channel index, then increment it.
chanPoint := wire.OutPoint{
Hash: [chainhash.HashSize]byte{1, 2, 3},
Index: uint32(c.testVarIdx),
}
// Increment the index we use so that the next channel and pubkey we
// create will be unique.
c.testVarIdx++
return vertex, pubKey, chanPoint
}
// createChannel creates a new channel, notifies the event store that it has
// been created and returns the peer vertex, pubkey and channel point.
func (c *chanEventStoreTestCtx) createChannel() (route.Vertex, *btcec.PublicKey,
wire.OutPoint) {
vertex, pubKey, chanPoint := c.newChannel()
c.sendChannelOpenedUpdate(pubKey, chanPoint)
return vertex, pubKey, chanPoint
}
// closeChannel sends a close channel event to our subscribe server.
func (c *chanEventStoreTestCtx) closeChannel(channel wire.OutPoint,
peer *btcec.PublicKey) {
update := channelnotifier.ClosedChannelEvent{
CloseSummary: &channeldb.ChannelCloseSummary{
ChanPoint: channel,
RemotePub: peer,
},
}
c.channelSubscription.sendUpdate(update)
}
// tickFlapCount forces a tick for our flap count ticker with the current time.
func (c *chanEventStoreTestCtx) tickFlapCount() {
testTicker := c.store.cfg.FlapCountTicker.(*ticker.Force)
select {
case testTicker.Force <- c.store.cfg.Clock.Now():
case <-time.After(timeout):
c.t.Fatalf("could not tick flap count ticker")
}
}
// peerEvent sends a peer online or offline event to the store for the peer
// provided.
func (c *chanEventStoreTestCtx) peerEvent(peer route.Vertex, online bool) {
var update interface{}
if online {
update = peernotifier.PeerOnlineEvent{PubKey: peer}
} else {
update = peernotifier.PeerOfflineEvent{PubKey: peer}
}
c.peerSubscription.sendUpdate(update)
}
// sendChannelOpenedUpdate notifies the test event store that a channel has
// been opened.
func (c *chanEventStoreTestCtx) sendChannelOpenedUpdate(pubkey *btcec.PublicKey,
channel wire.OutPoint) {
update := channelnotifier.OpenChannelEvent{
Channel: &channeldb.OpenChannel{
FundingOutpoint: channel,
IdentityPub: pubkey,
},
}
c.channelSubscription.sendUpdate(update)
}
// assertFlapCountUpdated asserts that our store has made an attempt to write
// our current set of flap counts to disk and sets this value in our test ctx.
// Note that it does not check the values of the update.
func (c *chanEventStoreTestCtx) assertFlapCountUpdated() {
select {
case c.flapUpdates = <-c.flapCountUpdates:
case <-time.After(timeout):
c.t.Fatalf("assertFlapCountUpdated timeout")
}
}
// assertFlapCountUpdates asserts that out current record of flap counts is
// as expected.
func (c *chanEventStoreTestCtx) assertFlapCountUpdates(expected peerFlapCountMap) {
require.Equal(c.t, expected, c.flapUpdates)
}
// mockSubscription is a mock subscription client that blocks on sends into the
// updates channel. We use this mock rather than an actual subscribe client
// because they do not block, which makes tests race (because we have no way
// to guarantee that the test client consumes the update before shutdown).
type mockSubscription struct {
t *testing.T
updates chan interface{}
// Embed the subscription interface in this mock so that we satisfy it.
subscribe.Subscription
}
// newMockSubscription creates a mock subscription.
func newMockSubscription(t *testing.T) *mockSubscription {
return &mockSubscription{
t: t,
updates: make(chan interface{}),
}
}
// sendUpdate sends an update into our updates channel, mocking the dispatch of
// an update from a subscription server. This call will fail the test if the
// update is not consumed within our timeout.
func (m *mockSubscription) sendUpdate(update interface{}) {
select {
case m.updates <- update:
case <-time.After(timeout):
m.t.Fatalf("update: %v timeout", update)
}
}
// Updates returns the updates channel for the mock.
func (m *mockSubscription) Updates() <-chan interface{} {
return m.updates
}
// Cancel should be called in case the client no longer wants to subscribe for
// updates from the server.
func (m *mockSubscription) Cancel() {
close(m.updates)
}
// assertCancelled asserts that the cancel function has been called for this
// mock.
func (m *mockSubscription) assertCancelled() {
select {
case _, open := <-m.updates:
require.False(m.t, open, "subscription not cancelled")
case <-time.After(timeout):
m.t.Fatalf("assert cancelled timeout")
}
}

34
chanfitness/interface.go Normal file

@ -0,0 +1,34 @@
package chanfitness
import (
"time"
"github.com/btcsuite/btcd/wire"
)
// peerMonitor is an interface implemented by entities that monitor our peers
// online events and the channels we currently have open with them.
type peerMonitor interface {
// event adds an online or offline event.
onlineEvent(online bool)
// addChannel adds a new channel.
addChannel(channelPoint wire.OutPoint) error
// removeChannel removes a channel.
removeChannel(channelPoint wire.OutPoint) error
// channelCount returns the number of channels that we currently have
// with the peer.
channelCount() int
// channelUptime looks up a channel and returns the amount of time that
// the channel has been monitored for and its uptime over this period.
channelUptime(channelPoint wire.OutPoint) (time.Duration,
time.Duration, error)
// getFlapCount returns the peer's flap count and the timestamp that we
// last recorded a flap, which may be nil if we have never recorded a
// flap for this peer.
getFlapCount() (int, *time.Time)
}

82
chanfitness/rate_limit.go Normal file

@ -0,0 +1,82 @@
package chanfitness
import (
"math"
"time"
)
const (
// rateLimitScale is the number of events we allow per rate limited
// tier. Increasing this value makes our rate limiting more lenient,
// decreasing it makes us less lenient.
rateLimitScale = 200
// flapCountCooldownFactor is the factor by which we decrease a peer's
// flap count if they have not flapped for the cooldown period.
flapCountCooldownFactor = 0.95
// flapCountCooldownPeriod is the amount of time that we require a peer
// has not flapped for before we reduce their all time flap count using
// our cooldown factor.
flapCountCooldownPeriod = time.Hour * 8
)
// rateLimits is the set of rate limit tiers we apply to our peers based on
// their flap count. A peer can be placed in their tier by dividing their flap
// count by the rateLimitScale and returning the value at that index.
var rateLimits = []time.Duration{
time.Second,
time.Second * 5,
time.Second * 30,
time.Minute,
time.Minute * 30,
time.Hour,
}
// getRateLimit returns the value of the rate limited tier that we are on based
// on current flap count. If a peer's flap count exceeds the top tier, we just
// return our highest tier.
func getRateLimit(flapCount int) time.Duration {
// Figure out the tier we fall into based on our current flap count.
tier := flapCount / rateLimitScale
// If we have more events than our number of tiers, we just use the
// last tier
tierLen := len(rateLimits)
if tier >= tierLen {
tier = tierLen - 1
}
return rateLimits[tier]
}
// cooldownFlapCount takes a timestamped flap count, and returns its value
// scaled down by our cooldown factor if at least our cooldown period has
// elapsed since the peer last flapped. We do this because we store all-time
// flap count for peers, and want to allow downgrading of peers that have not
// flapped for a long time.
func cooldownFlapCount(now time.Time, flapCount int,
lastFlap time.Time) int {
// Calculate time since our last flap, and the number of times we need
// to apply our cooldown factor.
timeSinceFlap := now.Sub(lastFlap)
// If our cooldown period has not elapsed yet, we just return our flap
// count. We allow fractional cooldown periods once this period has
// elapsed, so we do not want to apply a fractional cooldown before the
// full cooldown period has elapsed.
if timeSinceFlap < flapCountCooldownPeriod {
return flapCount
}
// Get the factor by which we need to cooldown our flap count. If
// insufficient time has passed to cooldown our flap count. Use use a
// float so that we allow fractional cooldown periods.
cooldownPeriods := float64(timeSinceFlap) /
float64(flapCountCooldownPeriod)
effectiveFactor := math.Pow(flapCountCooldownFactor, cooldownPeriods)
return int(float64(flapCount) * effectiveFactor)
}

@ -0,0 +1,105 @@
package chanfitness
import (
"testing"
"time"
"github.com/stretchr/testify/require"
)
// TestGetRateLimit tests getting of our rate limit using the current constants.
// It creates test cases that are relative to our constants so that they
// can be adjusted without breaking the unit test.
func TestGetRateLimit(t *testing.T) {
tests := []struct {
name string
flapCount int
rateLimit time.Duration
}{
{
name: "zero flaps",
flapCount: 0,
rateLimit: rateLimits[0],
},
{
name: "middle tier",
flapCount: rateLimitScale * (len(rateLimits) / 2),
rateLimit: rateLimits[len(rateLimits)/2],
},
{
name: "last tier",
flapCount: rateLimitScale * (len(rateLimits) - 1),
rateLimit: rateLimits[len(rateLimits)-1],
},
{
name: "beyond last tier",
flapCount: rateLimitScale * (len(rateLimits) * 2),
rateLimit: rateLimits[len(rateLimits)-1],
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()
limit := getRateLimit(test.flapCount)
require.Equal(t, test.rateLimit, limit)
})
}
}
// TestCooldownFlapCount tests cooldown of all time flap counts.
func TestCooldownFlapCount(t *testing.T) {
tests := []struct {
name string
flapCount int
lastFlap time.Time
expected int
}{
{
name: "just flapped, do not cooldown",
flapCount: 1,
lastFlap: testNow,
expected: 1,
},
{
name: "period not elapsed, do not cooldown",
flapCount: 1,
lastFlap: testNow.Add(flapCountCooldownPeriod / 2 * -1),
expected: 1,
},
{
name: "rounded to 0",
flapCount: 1,
lastFlap: testNow.Add(flapCountCooldownPeriod * -1),
expected: 0,
},
{
name: "decreased to integer value",
flapCount: 10,
lastFlap: testNow.Add(flapCountCooldownPeriod * -1),
expected: 9,
},
{
name: "multiple cooldown periods",
flapCount: 10,
lastFlap: testNow.Add(flapCountCooldownPeriod * -3),
expected: 8,
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()
flapCount := cooldownFlapCount(
testNow, test.flapCount, test.lastFlap,
)
require.Equal(t, test.expected, flapCount)
})
}
}

@ -164,6 +164,12 @@ var (
number: 17,
migration: mig.CreateTLB(closeSummaryBucket),
},
{
// Create a top level bucket which holds information
// about our peers.
number: 18,
migration: mig.CreateTLB(peersBucket),
},
}
// Big endian is the preferred byte order, due to cursor scans over
@ -278,6 +284,7 @@ var topLevelBuckets = [][]byte{
invoiceBucket,
payAddrIndexBucket,
paymentsIndexBucket,
peersBucket,
nodeInfoBucket,
nodeBucket,
edgeBucket,

121
channeldb/peers.go Normal file

@ -0,0 +1,121 @@
package channeldb
import (
"bytes"
"errors"
"fmt"
"time"
"github.com/btcsuite/btcwallet/walletdb"
"github.com/lightningnetwork/lnd/routing/route"
)
var (
// peersBucket is the name of a top level bucket in which we store
// information about our peers. Information for different peers is
// stored in buckets keyed by their public key.
//
//
// peers-bucket
// |
// |-- <peer-pubkey>
// | |--flap-count-key: <ts><flap count>
// |
// |-- <peer-pubkey>
// | |--flap-count-key: <ts><flap count>
peersBucket = []byte("peers-bucket")
// flapCountKey is a key used in the peer pubkey sub-bucket that stores
// the timestamp of a peer's last flap count and its all time flap
// count.
flapCountKey = []byte("flap-count")
)
var (
// ErrNoPeerBucket is returned when we try to read entries for a peer
// that is not tracked.
ErrNoPeerBucket = errors.New("peer bucket not found")
)
// FlapCount contains information about a peer's flap count.
type FlapCount struct {
// Count provides the total flap count for a peer.
Count uint32
// LastFlap is the timestamp of the last flap recorded for a peer.
LastFlap time.Time
}
// WriteFlapCounts writes the flap count for a set of peers to disk, creating a
// bucket for the peer's pubkey if necessary. Note that this function overwrites
// the current value.
func (d *DB) WriteFlapCounts(flapCounts map[route.Vertex]*FlapCount) error {
return d.Update(func(tx walletdb.ReadWriteTx) error {
// Run through our set of flap counts and record them for
// each peer, creating a bucket for the peer pubkey if required.
for peer, flapCount := range flapCounts {
peers := tx.ReadWriteBucket(peersBucket)
peerBucket, err := peers.CreateBucketIfNotExists(
peer[:],
)
if err != nil {
return err
}
var b bytes.Buffer
err = serializeTime(&b, flapCount.LastFlap)
if err != nil {
return err
}
if err = WriteElement(&b, flapCount.Count); err != nil {
return err
}
err = peerBucket.Put(flapCountKey, b.Bytes())
if err != nil {
return err
}
}
return nil
})
}
// ReadFlapCount attempts to read the flap count for a peer, failing if the
// peer is not found or we do not have flap count stored.
func (d *DB) ReadFlapCount(pubkey route.Vertex) (*FlapCount, error) {
var flapCount FlapCount
if err := d.View(func(tx walletdb.ReadTx) error {
peers := tx.ReadBucket(peersBucket)
peerBucket := peers.NestedReadBucket(pubkey[:])
if peerBucket == nil {
return ErrNoPeerBucket
}
flapBytes := peerBucket.Get(flapCountKey)
if flapBytes == nil {
return fmt.Errorf("flap count not recorded for: %v",
pubkey)
}
var (
err error
r = bytes.NewReader(flapBytes)
)
flapCount.LastFlap, err = deserializeTime(r)
if err != nil {
return err
}
return ReadElements(r, &flapCount.Count)
}); err != nil {
return nil, err
}
return &flapCount, nil
}

50
channeldb/peers_test.go Normal file

@ -0,0 +1,50 @@
package channeldb
import (
"testing"
"time"
"github.com/lightningnetwork/lnd/routing/route"
"github.com/stretchr/testify/require"
)
// TestFlapCount tests lookup and writing of flap count to disk.
func TestFlapCount(t *testing.T) {
db, cleanup, err := MakeTestDB()
require.NoError(t, err)
defer cleanup()
// Try to read flap count for a peer that we have no records for.
_, err = db.ReadFlapCount(testPub)
require.Equal(t, ErrNoPeerBucket, err)
var (
testPub2 = route.Vertex{2, 2, 2}
peer1FlapCount = &FlapCount{
Count: 20,
LastFlap: time.Unix(100, 23),
}
peer2FlapCount = &FlapCount{
Count: 39,
LastFlap: time.Unix(200, 23),
}
)
peers := map[route.Vertex]*FlapCount{
testPub: peer1FlapCount,
testPub2: peer2FlapCount,
}
err = db.WriteFlapCounts(peers)
require.NoError(t, err)
// Lookup flap count for our first pubkey.
count, err := db.ReadFlapCount(testPub)
require.NoError(t, err)
require.Equal(t, peer1FlapCount, count)
// Lookup our flap count for the second peer.
count, err = db.ReadFlapCount(testPub2)
require.NoError(t, err)
require.Equal(t, peer2FlapCount, count)
}

@ -3728,10 +3728,20 @@ type Peer struct {
//are not persisted across lnd restarts. Note that these errors are only
//stored for peers that we have channels open with, to prevent peers from
//spamming us with errors at no cost.
Errors []*TimestampedError `protobuf:"bytes,12,rep,name=errors,proto3" json:"errors,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
Errors []*TimestampedError `protobuf:"bytes,12,rep,name=errors,proto3" json:"errors,omitempty"`
//
//The number of times we have recorded this peer going offline or coming
//online, recorded across restarts. Note that this value is decreased over
//time if the peer has not recently flapped, so that we can forgive peers
//with historically high flap counts.
FlapCount int32 `protobuf:"varint,13,opt,name=flap_count,json=flapCount,proto3" json:"flap_count,omitempty"`
//
//The timestamp of the last flap we observed for this peer. If this value is
//zero, we have not observed any flaps for this peer.
LastFlapNs int64 `protobuf:"varint,14,opt,name=last_flap_ns,json=lastFlapNs,proto3" json:"last_flap_ns,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Peer) Reset() { *m = Peer{} }
@ -3836,6 +3846,20 @@ func (m *Peer) GetErrors() []*TimestampedError {
return nil
}
func (m *Peer) GetFlapCount() int32 {
if m != nil {
return m.FlapCount
}
return 0
}
func (m *Peer) GetLastFlapNs() int64 {
if m != nil {
return m.LastFlapNs
}
return 0
}
type TimestampedError struct {
// The unix timestamp in seconds when the error occurred.
Timestamp uint64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
@ -12454,753 +12478,756 @@ func init() {
func init() { proto.RegisterFile("rpc.proto", fileDescriptor_77a6da22d6a3feb1) }
var fileDescriptor_77a6da22d6a3feb1 = []byte{
// 11936 bytes of a gzipped FileDescriptorProto
// 11972 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x7d, 0x59, 0x6c, 0x23, 0x49,
0x96, 0x58, 0xf1, 0x12, 0xc9, 0x47, 0x52, 0xa2, 0x42, 0x17, 0x4b, 0xd5, 0xd5, 0x55, 0x9d, 0xdd,
0xd3, 0x5d, 0x53, 0xdd, 0xa3, 0xae, 0xae, 0xee, 0xea, 0x63, 0xca, 0xdb, 0x33, 0x94, 0x44, 0x95,
0x38, 0x25, 0x91, 0x9a, 0x24, 0xd5, 0xbd, 0xbd, 0xd8, 0xdd, 0xdc, 0x14, 0x19, 0x92, 0xd2, 0x45,
0x66, 0xb2, 0x33, 0x93, 0x2a, 0x69, 0x0c, 0xff, 0xad, 0x0f, 0x2c, 0xd6, 0x06, 0x0c, 0x78, 0x0d,
0xf8, 0x58, 0xf8, 0x82, 0xed, 0xbf, 0x85, 0xe1, 0x5d, 0xfb, 0xcb, 0xdf, 0x5e, 0x18, 0xb0, 0x61,
0x18, 0x5e, 0xc3, 0x07, 0x16, 0x0b, 0x18, 0xb0, 0xd7, 0x1f, 0x06, 0x8c, 0x05, 0xec, 0x1f, 0x7f,
0x18, 0x30, 0x22, 0x5e, 0x44, 0x64, 0xe4, 0xa1, 0xaa, 0xea, 0x99, 0xf6, 0xfc, 0x48, 0x8c, 0xf7,
0x5e, 0xdc, 0x11, 0x2f, 0xde, 0x15, 0x91, 0x50, 0xf5, 0x67, 0xa3, 0xad, 0x99, 0xef, 0x85, 0x1e,
0x29, 0x4d, 0x5c, 0x7f, 0x36, 0x32, 0xfe, 0x38, 0x07, 0xc5, 0xe3, 0xf0, 0xd2, 0x23, 0x8f, 0xa0,
0x6e, 0x8f, 0xc7, 0x3e, 0x0d, 0x02, 0x2b, 0xbc, 0x9a, 0xd1, 0x56, 0xee, 0x6e, 0xee, 0xde, 0xe2,
0x43, 0xb2, 0xc5, 0xc9, 0xb6, 0xda, 0x88, 0x1a, 0x5e, 0xcd, 0xa8, 0x59, 0xb3, 0xa3, 0x04, 0x69,
0x41, 0x59, 0x24, 0x5b, 0xf9, 0xbb, 0xb9, 0x7b, 0x55, 0x53, 0x26, 0xc9, 0x6d, 0x00, 0x7b, 0xea,
0xcd, 0xdd, 0xd0, 0x0a, 0xec, 0xb0, 0x55, 0xb8, 0x9b, 0xbb, 0x57, 0x30, 0xab, 0x08, 0x19, 0xd8,
0x21, 0xb9, 0x05, 0xd5, 0xd9, 0x33, 0x2b, 0x18, 0xf9, 0xce, 0x2c, 0x6c, 0x15, 0x79, 0xd6, 0xca,
0xec, 0xd9, 0x80, 0xa7, 0xc9, 0xbb, 0x50, 0xf1, 0xe6, 0xe1, 0xcc, 0x73, 0xdc, 0xb0, 0x55, 0xba,
0x9b, 0xbb, 0x57, 0x7b, 0xb8, 0x24, 0x1a, 0xd2, 0x9f, 0x87, 0x47, 0x0c, 0x6c, 0x2a, 0x02, 0xf2,
0x16, 0x34, 0x46, 0x9e, 0x7b, 0xea, 0xf8, 0x53, 0x3b, 0x74, 0x3c, 0x37, 0x68, 0x2d, 0xf0, 0xba,
0xe2, 0x40, 0xe3, 0x5f, 0xe4, 0xa1, 0x36, 0xf4, 0x6d, 0x37, 0xb0, 0x47, 0x0c, 0x40, 0x36, 0xa0,
0x1c, 0x5e, 0x5a, 0xe7, 0x76, 0x70, 0xce, 0xbb, 0x5a, 0x35, 0x17, 0xc2, 0xcb, 0x7d, 0x3b, 0x38,
0x27, 0xeb, 0xb0, 0x80, 0xad, 0xe4, 0x1d, 0x2a, 0x98, 0x22, 0x45, 0xde, 0x85, 0x65, 0x77, 0x3e,
0xb5, 0xe2, 0x55, 0xb1, 0x6e, 0x95, 0xcc, 0xa6, 0x3b, 0x9f, 0xee, 0xe8, 0x70, 0xd6, 0xf9, 0x93,
0x89, 0x37, 0x7a, 0x86, 0x15, 0x60, 0xf7, 0xaa, 0x1c, 0xc2, 0xeb, 0x78, 0x03, 0xea, 0x02, 0x4d,
0x9d, 0xb3, 0x73, 0xec, 0x63, 0xc9, 0xac, 0x21, 0x01, 0x07, 0xb1, 0x12, 0x42, 0x67, 0x4a, 0xad,
0x20, 0xb4, 0xa7, 0x33, 0xd1, 0xa5, 0x2a, 0x83, 0x0c, 0x18, 0x80, 0xa3, 0xbd, 0xd0, 0x9e, 0x58,
0xa7, 0x94, 0x06, 0xad, 0xb2, 0x40, 0x33, 0xc8, 0x1e, 0xa5, 0x01, 0xf9, 0x0e, 0x2c, 0x8e, 0x69,
0x10, 0x5a, 0x62, 0x32, 0x68, 0xd0, 0xaa, 0xdc, 0x2d, 0xdc, 0xab, 0x9a, 0x0d, 0x06, 0x6d, 0x4b,
0x20, 0x79, 0x0d, 0xc0, 0xb7, 0x9f, 0x5b, 0x6c, 0x20, 0xe8, 0x65, 0xab, 0x8a, 0xb3, 0xe0, 0xdb,
0xcf, 0x87, 0x97, 0xfb, 0xf4, 0x92, 0xac, 0x42, 0x69, 0x62, 0x9f, 0xd0, 0x49, 0x0b, 0x38, 0x02,
0x13, 0xc6, 0x2f, 0xc1, 0xfa, 0x13, 0x1a, 0x6a, 0x43, 0x19, 0x98, 0xf4, 0xeb, 0x39, 0x0d, 0x42,
0xd6, 0xab, 0x20, 0xb4, 0xfd, 0x50, 0xf6, 0x2a, 0x87, 0xbd, 0xe2, 0xb0, 0xa8, 0x57, 0xd4, 0x1d,
0x4b, 0x82, 0x3c, 0x27, 0xa8, 0x52, 0x77, 0x8c, 0x68, 0xe3, 0x00, 0x88, 0x56, 0xf0, 0x2e, 0x0d,
0x6d, 0x67, 0x12, 0x90, 0x8f, 0xa1, 0x1e, 0x6a, 0xd5, 0xb5, 0x72, 0x77, 0x0b, 0xf7, 0x6a, 0x6a,
0x69, 0x6a, 0x19, 0xcc, 0x18, 0x9d, 0x71, 0x0e, 0x95, 0x3d, 0x4a, 0x0f, 0x9c, 0xa9, 0x13, 0x92,
0x75, 0x28, 0x9d, 0x3a, 0x97, 0x74, 0xcc, 0x1b, 0x55, 0xd8, 0xbf, 0x61, 0x62, 0x92, 0xdc, 0x01,
0xe0, 0x3f, 0xac, 0xa9, 0x5a, 0xa5, 0xfb, 0x37, 0xcc, 0x2a, 0x87, 0x1d, 0x06, 0x76, 0x48, 0x36,
0xa1, 0x3c, 0xa3, 0xfe, 0x88, 0xca, 0xf5, 0xb0, 0x7f, 0xc3, 0x94, 0x80, 0xed, 0x32, 0x94, 0x26,
0xac, 0x74, 0xe3, 0xf7, 0x4b, 0x50, 0x1b, 0x50, 0x77, 0x2c, 0x47, 0x82, 0x40, 0x91, 0x0d, 0x34,
0xaf, 0xac, 0x6e, 0xf2, 0xdf, 0xe4, 0x4d, 0xa8, 0xf1, 0x29, 0x09, 0x42, 0xdf, 0x71, 0xcf, 0x70,
0xb7, 0x6c, 0xe7, 0x5b, 0x39, 0x13, 0x18, 0x78, 0xc0, 0xa1, 0xa4, 0x09, 0x05, 0x7b, 0x2a, 0x77,
0x0b, 0xfb, 0x49, 0x6e, 0x42, 0xc5, 0x9e, 0x86, 0xd8, 0xbc, 0x3a, 0x07, 0x97, 0xed, 0x69, 0xc8,
0x9b, 0xf6, 0x06, 0xd4, 0x67, 0xf6, 0xd5, 0x94, 0xba, 0x61, 0xb4, 0xcc, 0xea, 0x66, 0x4d, 0xc0,
0xf8, 0x42, 0x7b, 0x08, 0x2b, 0x3a, 0x89, 0xac, 0xbc, 0xa4, 0x2a, 0x5f, 0xd6, 0xa8, 0x45, 0x1b,
0xde, 0x81, 0x25, 0x99, 0xc7, 0xc7, 0xfe, 0xf0, 0xe5, 0x57, 0x35, 0x17, 0x05, 0x58, 0xf6, 0xf2,
0x1e, 0x34, 0x4f, 0x1d, 0xd7, 0x9e, 0x58, 0xa3, 0x49, 0x78, 0x61, 0x8d, 0xe9, 0x24, 0xb4, 0xf9,
0x4a, 0x2c, 0x99, 0x8b, 0x1c, 0xbe, 0x33, 0x09, 0x2f, 0x76, 0x19, 0x94, 0xbc, 0x07, 0xd5, 0x53,
0x4a, 0x2d, 0x3e, 0x58, 0xad, 0x4a, 0x6c, 0x43, 0xcb, 0x19, 0x32, 0x2b, 0xa7, 0x72, 0xae, 0xde,
0x83, 0xa6, 0x37, 0x0f, 0xcf, 0x3c, 0xc7, 0x3d, 0xb3, 0x46, 0xe7, 0xb6, 0x6b, 0x39, 0x63, 0xbe,
0x36, 0x8b, 0xdb, 0xf9, 0x07, 0x39, 0x73, 0x51, 0xe2, 0x76, 0xce, 0x6d, 0xb7, 0x3b, 0x26, 0x6f,
0xc3, 0xd2, 0xc4, 0x0e, 0x42, 0xeb, 0xdc, 0x9b, 0x59, 0xb3, 0xf9, 0xc9, 0x33, 0x7a, 0xd5, 0x6a,
0xf0, 0x81, 0x68, 0x30, 0xf0, 0xbe, 0x37, 0x3b, 0xe2, 0x40, 0xb6, 0xf4, 0x78, 0x3b, 0xb1, 0x11,
0x6c, 0x49, 0x37, 0xcc, 0x2a, 0x83, 0x60, 0xa5, 0x5f, 0xc1, 0x0a, 0x9f, 0x9e, 0xd1, 0x3c, 0x08,
0xbd, 0xa9, 0xe5, 0xd3, 0x91, 0xe7, 0x8f, 0x83, 0x56, 0x8d, 0xaf, 0xb5, 0xef, 0x8a, 0xc6, 0x6a,
0x73, 0xbc, 0xb5, 0x4b, 0x83, 0x70, 0x87, 0x13, 0x9b, 0x48, 0xdb, 0x71, 0x43, 0xff, 0xca, 0x5c,
0x1e, 0x27, 0xe1, 0xe4, 0x3d, 0x20, 0xf6, 0x64, 0xe2, 0x3d, 0xb7, 0x02, 0x3a, 0x39, 0xb5, 0xc4,
0x20, 0xb6, 0x16, 0xef, 0xe6, 0xee, 0x55, 0xcc, 0x26, 0xc7, 0x0c, 0xe8, 0xe4, 0xf4, 0x08, 0xe1,
0xe4, 0x63, 0xe0, 0x9b, 0xd4, 0x3a, 0xa5, 0x76, 0x38, 0xf7, 0x69, 0xd0, 0x5a, 0xba, 0x5b, 0xb8,
0xb7, 0xf8, 0x70, 0x59, 0x8d, 0x17, 0x07, 0x6f, 0x3b, 0xa1, 0x59, 0x67, 0x74, 0x22, 0x1d, 0x6c,
0xee, 0xc2, 0x7a, 0x76, 0x93, 0xd8, 0xa2, 0x62, 0xa3, 0xc2, 0x16, 0x63, 0xd1, 0x64, 0x3f, 0xd9,
0xce, 0xbe, 0xb0, 0x27, 0x73, 0xca, 0x57, 0x61, 0xdd, 0xc4, 0xc4, 0xf7, 0xf3, 0x9f, 0xe6, 0x8c,
0xdf, 0xcb, 0x41, 0x1d, 0x7b, 0x19, 0xcc, 0x3c, 0x37, 0xa0, 0xe4, 0x4d, 0x68, 0xc8, 0xd5, 0x40,
0x7d, 0xdf, 0xf3, 0x05, 0xb7, 0x94, 0x2b, 0xaf, 0xc3, 0x60, 0xe4, 0xbb, 0xd0, 0x94, 0x44, 0x33,
0x9f, 0x3a, 0x53, 0xfb, 0x4c, 0x16, 0x2d, 0x97, 0xd2, 0x91, 0x00, 0x93, 0x0f, 0xa2, 0xf2, 0x7c,
0x6f, 0x1e, 0x52, 0xbe, 0xd6, 0x6b, 0x0f, 0xeb, 0xa2, 0x7b, 0x26, 0x83, 0xa9, 0xd2, 0x79, 0xea,
0x15, 0xd6, 0xb9, 0xf1, 0x5b, 0x39, 0x20, 0xac, 0xd9, 0x43, 0x0f, 0x0b, 0x88, 0x38, 0x52, 0x2c,
0x67, 0xee, 0x95, 0x77, 0x48, 0xfe, 0x45, 0x3b, 0xc4, 0x80, 0x12, 0xb6, 0xbd, 0x98, 0xd1, 0x76,
0x44, 0xfd, 0xa8, 0x58, 0x29, 0x34, 0x8b, 0xc6, 0x7f, 0x2e, 0xc0, 0x2a, 0x5b, 0xa7, 0x2e, 0x9d,
0xb4, 0x47, 0x23, 0x3a, 0x53, 0x7b, 0xe7, 0x0e, 0xd4, 0x5c, 0x6f, 0x4c, 0xe5, 0x8a, 0xc5, 0x86,
0x01, 0x03, 0x69, 0xcb, 0xf5, 0xdc, 0x76, 0x5c, 0x6c, 0x38, 0x0e, 0x66, 0x95, 0x43, 0x78, 0xb3,
0xdf, 0x86, 0xa5, 0x19, 0x75, 0xc7, 0xfa, 0x16, 0x29, 0xe0, 0xaa, 0x17, 0x60, 0xb1, 0x3b, 0xee,
0x40, 0xed, 0x74, 0x8e, 0x74, 0x8c, 0xb1, 0x14, 0xf9, 0x1a, 0x00, 0x01, 0x6a, 0x23, 0x7f, 0x99,
0xcd, 0x83, 0x73, 0x8e, 0x2d, 0x71, 0x6c, 0x99, 0xa5, 0x19, 0xea, 0x36, 0xc0, 0x78, 0x1e, 0x84,
0x62, 0xc7, 0x2c, 0x70, 0x64, 0x95, 0x41, 0x70, 0xc7, 0x7c, 0x0f, 0x56, 0xa6, 0xf6, 0xa5, 0xc5,
0xd7, 0x8e, 0xe5, 0xb8, 0xd6, 0xe9, 0x84, 0x33, 0xf5, 0x32, 0xa7, 0x6b, 0x4e, 0xed, 0xcb, 0x2f,
0x18, 0xa6, 0xeb, 0xee, 0x71, 0x38, 0x63, 0x2b, 0x23, 0x1c, 0x09, 0xcb, 0xa7, 0x01, 0xf5, 0x2f,
0x28, 0xe7, 0x04, 0x45, 0x73, 0x51, 0x80, 0x4d, 0x84, 0xb2, 0x16, 0x4d, 0x59, 0xbf, 0xc3, 0xc9,
0x08, 0xb7, 0xbd, 0x59, 0x9e, 0x3a, 0xee, 0x7e, 0x38, 0x19, 0xb1, 0xf3, 0x8a, 0xf1, 0x91, 0x19,
0xf5, 0xad, 0x67, 0xcf, 0xf9, 0x1e, 0x2e, 0x72, 0xbe, 0x71, 0x44, 0xfd, 0xa7, 0xcf, 0x99, 0x48,
0x31, 0x0a, 0x38, 0x23, 0xb2, 0xaf, 0x5a, 0x35, 0xbe, 0xc1, 0x2b, 0xa3, 0x80, 0xb1, 0x20, 0xfb,
0x8a, 0x6d, 0x42, 0xd6, 0x5a, 0x9b, 0xcf, 0x02, 0x1d, 0xf3, 0xe2, 0x03, 0xce, 0x51, 0x1b, 0xbc,
0xb1, 0x6d, 0x81, 0x60, 0xf5, 0x04, 0x6c, 0xd5, 0xcb, 0xc6, 0x9e, 0x4e, 0xec, 0xb3, 0x80, 0xb3,
0x94, 0x86, 0x59, 0x17, 0xc0, 0x3d, 0x06, 0x33, 0xbe, 0x84, 0xb5, 0xc4, 0xdc, 0x8a, 0x3d, 0xc3,
0x44, 0x08, 0x0e, 0xe1, 0xf3, 0x5a, 0x31, 0x45, 0x2a, 0x6b, 0xd2, 0xf2, 0x19, 0x93, 0x66, 0xfc,
0x76, 0x0e, 0xea, 0xa2, 0x64, 0x2e, 0xec, 0x90, 0x2d, 0x20, 0x72, 0x16, 0xc3, 0x4b, 0x67, 0x6c,
0x9d, 0x5c, 0x85, 0x34, 0xc0, 0x45, 0xb3, 0x7f, 0xc3, 0x6c, 0x0a, 0xdc, 0xf0, 0xd2, 0x19, 0x6f,
0x33, 0x0c, 0xb9, 0x0f, 0xcd, 0x18, 0x7d, 0x10, 0xfa, 0xb8, 0xa2, 0xf7, 0x6f, 0x98, 0x8b, 0x1a,
0xf5, 0x20, 0xf4, 0xd9, 0x1e, 0x61, 0xa2, 0xd4, 0x3c, 0xb4, 0x1c, 0x77, 0x4c, 0x2f, 0xf9, 0x32,
0x6a, 0x98, 0x35, 0x84, 0x75, 0x19, 0x68, 0x7b, 0x11, 0xea, 0x7a, 0x71, 0xc6, 0x19, 0x54, 0xa4,
0x1c, 0xc6, 0x05, 0x91, 0x44, 0x93, 0xcc, 0x6a, 0xa8, 0x5a, 0x72, 0x13, 0x2a, 0xf1, 0x16, 0x98,
0xe5, 0xf0, 0x95, 0x2b, 0x36, 0x3e, 0x87, 0xe6, 0x01, 0x5b, 0x3c, 0x2e, 0x5b, 0xac, 0x42, 0xae,
0x5c, 0x87, 0x05, 0x6d, 0xd3, 0x54, 0x4d, 0x91, 0x62, 0x67, 0xee, 0xb9, 0x17, 0x84, 0xa2, 0x16,
0xfe, 0xdb, 0xf8, 0xfd, 0x1c, 0x90, 0x4e, 0x10, 0x3a, 0x53, 0x3b, 0xa4, 0x7b, 0x54, 0xb1, 0x85,
0x3e, 0xd4, 0x59, 0x69, 0x43, 0xaf, 0x8d, 0x82, 0x1e, 0x0a, 0x14, 0xef, 0x8a, 0x6d, 0x9c, 0xce,
0xb0, 0xa5, 0x53, 0x23, 0x9b, 0x8f, 0x15, 0xc0, 0x76, 0x59, 0x68, 0xfb, 0x67, 0x34, 0xe4, 0xe2,
0xa1, 0x90, 0x6b, 0x00, 0x41, 0x4c, 0x30, 0xdc, 0xfc, 0x01, 0x2c, 0xa7, 0xca, 0xd0, 0xf9, 0x72,
0x35, 0x83, 0x2f, 0x17, 0x74, 0xbe, 0x6c, 0xc1, 0x4a, 0xac, 0x5d, 0x62, 0xa5, 0x6d, 0x40, 0x99,
0x6d, 0x08, 0x26, 0x1c, 0xe4, 0x50, 0x5a, 0x3d, 0xa5, 0x94, 0x89, 0xd7, 0xef, 0xc3, 0xea, 0x29,
0xa5, 0xbe, 0x1d, 0x72, 0x24, 0xdf, 0x31, 0x6c, 0x86, 0x44, 0xc1, 0xcb, 0x02, 0x37, 0xb0, 0xc3,
0x23, 0xea, 0xb3, 0x99, 0x32, 0xfe, 0x4f, 0x0e, 0x96, 0x18, 0x07, 0x3d, 0xb4, 0xdd, 0x2b, 0x39,
0x4e, 0x07, 0x99, 0xe3, 0x74, 0x4f, 0x3b, 0x0c, 0x35, 0xea, 0x6f, 0x3a, 0x48, 0x85, 0xe4, 0x20,
0x91, 0xbb, 0x50, 0x8f, 0xb5, 0xb5, 0xc4, 0xdb, 0x0a, 0x81, 0x6a, 0x64, 0x24, 0x91, 0x2e, 0x68,
0x12, 0xe9, 0xcf, 0x3e, 0xb8, 0x6f, 0x43, 0x33, 0xea, 0x8c, 0x18, 0x59, 0x02, 0x45, 0xb6, 0x50,
0x45, 0x01, 0xfc, 0xb7, 0xf1, 0x4f, 0x72, 0x48, 0xb8, 0xe3, 0x39, 0x91, 0xd4, 0x4b, 0xa0, 0xc8,
0xa4, 0x6c, 0x49, 0xc8, 0x7e, 0x5f, 0xab, 0x43, 0x7c, 0x0b, 0x43, 0x70, 0x13, 0x2a, 0x01, 0x13,
0xa1, 0xed, 0x09, 0x8e, 0x42, 0xc5, 0x2c, 0xb3, 0x74, 0x7b, 0x32, 0x89, 0x46, 0xa7, 0xac, 0xcb,
0xeb, 0xef, 0xc0, 0xb2, 0xd6, 0xe6, 0x17, 0xf4, 0xae, 0x07, 0xe4, 0xc0, 0x09, 0xc2, 0x63, 0x37,
0x98, 0x69, 0x42, 0xde, 0x2d, 0xa8, 0x32, 0x6e, 0xcc, 0xda, 0x1b, 0x08, 0x89, 0x9e, 0xb1, 0x67,
0xd6, 0xda, 0x80, 0x23, 0xed, 0x4b, 0x81, 0xcc, 0x0b, 0xa4, 0x7d, 0xc9, 0x91, 0xc6, 0xa7, 0xb0,
0x12, 0x2b, 0x4f, 0x54, 0xfd, 0x06, 0x94, 0xe6, 0xe1, 0xa5, 0x27, 0xc5, 0xf8, 0x9a, 0x58, 0x4d,
0x4c, 0x09, 0x35, 0x11, 0x63, 0x3c, 0x86, 0xe5, 0x1e, 0x7d, 0x2e, 0x36, 0xbc, 0x6c, 0xc8, 0xdb,
0x50, 0x7c, 0x89, 0x62, 0xca, 0xf1, 0xc6, 0x16, 0x10, 0x3d, 0xb3, 0xa8, 0x55, 0xd3, 0x53, 0x73,
0x31, 0x3d, 0xd5, 0x78, 0x1b, 0xc8, 0xc0, 0x39, 0x73, 0x0f, 0x69, 0x10, 0xd8, 0x67, 0x8a, 0x45,
0x34, 0xa1, 0x30, 0x0d, 0xce, 0x04, 0x3f, 0x63, 0x3f, 0x8d, 0x0f, 0x61, 0x25, 0x46, 0x27, 0x0a,
0x7e, 0x0d, 0xaa, 0x81, 0x73, 0xe6, 0x72, 0x21, 0x4c, 0x14, 0x1d, 0x01, 0x8c, 0x3d, 0x58, 0xfd,
0x82, 0xfa, 0xce, 0xe9, 0xd5, 0xcb, 0x8a, 0x8f, 0x97, 0x93, 0x4f, 0x96, 0xd3, 0x81, 0xb5, 0x44,
0x39, 0xa2, 0x7a, 0x5c, 0xd4, 0x62, 0x26, 0x2b, 0x26, 0x26, 0x34, 0x1e, 0x99, 0xd7, 0x79, 0xa4,
0x71, 0x0c, 0x64, 0xc7, 0x73, 0x5d, 0x3a, 0x0a, 0x8f, 0x28, 0xf5, 0x65, 0x63, 0xde, 0xd5, 0x56,
0x70, 0xed, 0xe1, 0x86, 0x18, 0xd9, 0x24, 0xe3, 0x15, 0x4b, 0x9b, 0x40, 0x71, 0x46, 0xfd, 0x29,
0x2f, 0xb8, 0x62, 0xf2, 0xdf, 0xc6, 0x1a, 0xac, 0xc4, 0x8a, 0xc5, 0xb6, 0x19, 0x0f, 0x60, 0x6d,
0xd7, 0x09, 0x46, 0xe9, 0x0a, 0x37, 0xa0, 0x3c, 0x9b, 0x9f, 0x58, 0x71, 0x1e, 0xfe, 0x94, 0x5e,
0x19, 0x2d, 0x58, 0x4f, 0xe6, 0x10, 0x65, 0xfd, 0x7a, 0x0e, 0x8a, 0xfb, 0xc3, 0x83, 0x1d, 0xb2,
0x09, 0x15, 0xc7, 0x1d, 0x79, 0x53, 0x26, 0xa4, 0x61, 0x9f, 0x55, 0xfa, 0xda, 0x6d, 0x77, 0x0b,
0xaa, 0x5c, 0xb6, 0x63, 0xea, 0xb5, 0x10, 0x93, 0x2a, 0x0c, 0x70, 0xe0, 0x8d, 0x9e, 0x31, 0xbd,
0x9e, 0x5e, 0xce, 0x1c, 0x9f, 0x6b, 0xee, 0x52, 0x33, 0x2d, 0xa2, 0x5c, 0x10, 0x21, 0x84, 0x82,
0xfa, 0xeb, 0x79, 0x20, 0xe2, 0x64, 0xde, 0xf1, 0xdc, 0x20, 0xf4, 0x6d, 0xc7, 0x0d, 0x83, 0xb8,
0xe4, 0x91, 0x4b, 0x48, 0x1e, 0xf7, 0xa0, 0xc9, 0x4f, 0x7b, 0x21, 0xf5, 0x70, 0x66, 0x9d, 0x8f,
0x24, 0x1f, 0x21, 0xf6, 0x30, 0xa6, 0xfd, 0x16, 0x2c, 0x46, 0x02, 0x97, 0x32, 0x9b, 0x14, 0xcd,
0xba, 0x12, 0xba, 0x04, 0x6b, 0x67, 0x9b, 0x4e, 0x4a, 0x12, 0x4a, 0x3b, 0x44, 0xd9, 0x6e, 0x79,
0x6a, 0x5f, 0x1e, 0x51, 0x29, 0xde, 0x71, 0x3d, 0xd1, 0x80, 0x86, 0x14, 0xa8, 0x90, 0x12, 0xe5,
0xbc, 0x9a, 0x90, 0xaa, 0x38, 0x4d, 0xb6, 0x78, 0xb4, 0x90, 0x2d, 0x1e, 0x19, 0xff, 0xa1, 0x0a,
0x65, 0x31, 0x0c, 0x28, 0xec, 0x84, 0xce, 0x05, 0x8d, 0x84, 0x1d, 0x96, 0x62, 0x22, 0x94, 0x4f,
0xa7, 0x5e, 0xa8, 0x64, 0x5c, 0x5c, 0x8a, 0x75, 0x04, 0x0a, 0x29, 0x57, 0x93, 0xb3, 0xd0, 0xda,
0x53, 0x40, 0xa2, 0x91, 0x2e, 0xfd, 0xdc, 0x82, 0xb2, 0x14, 0x97, 0x8a, 0x4a, 0x0d, 0x5c, 0x18,
0xa1, 0x80, 0xbb, 0x09, 0x95, 0x91, 0x3d, 0xb3, 0x47, 0x4e, 0x78, 0x25, 0xb8, 0xa5, 0x4a, 0xb3,
0xd2, 0x27, 0xde, 0xc8, 0x9e, 0x58, 0x27, 0xf6, 0xc4, 0x76, 0x47, 0x54, 0x98, 0x51, 0xea, 0x1c,
0xb8, 0x8d, 0x30, 0xf2, 0x1d, 0x58, 0x14, 0xed, 0x94, 0x54, 0x68, 0x4d, 0x11, 0xad, 0x97, 0x64,
0x4c, 0x1e, 0xf7, 0xa6, 0x6c, 0x5e, 0x4e, 0x29, 0x4a, 0xae, 0x05, 0xb3, 0x8a, 0x90, 0x3d, 0xca,
0x7b, 0x2b, 0xd0, 0xcf, 0x71, 0x05, 0x55, 0xb1, 0x2a, 0x04, 0x7e, 0x89, 0xd6, 0x8f, 0xb4, 0xf8,
0x5a, 0xd0, 0xc4, 0xd7, 0x77, 0x61, 0x79, 0xee, 0x06, 0x34, 0x0c, 0x27, 0x74, 0xac, 0xda, 0x52,
0xe3, 0x44, 0x4d, 0x85, 0x90, 0xcd, 0xd9, 0x82, 0x15, 0xb4, 0xff, 0x04, 0x76, 0xe8, 0x05, 0xe7,
0x4e, 0x60, 0x05, 0x4c, 0xa9, 0x44, 0x0b, 0xc1, 0x32, 0x47, 0x0d, 0x04, 0x66, 0x80, 0x5a, 0xe5,
0x46, 0x82, 0xde, 0xa7, 0x23, 0xea, 0x5c, 0xd0, 0x31, 0x17, 0x6d, 0x0b, 0xe6, 0x5a, 0x2c, 0x8f,
0x29, 0x90, 0x5c, 0x4f, 0x99, 0x4f, 0xad, 0xf9, 0x6c, 0x6c, 0x33, 0xf9, 0x6e, 0x11, 0xf5, 0x07,
0x77, 0x3e, 0x3d, 0x46, 0x08, 0x79, 0x00, 0x52, 0x78, 0x15, 0x6b, 0x66, 0x29, 0xc6, 0xd6, 0xd9,
0x9e, 0x35, 0xeb, 0x82, 0x02, 0x65, 0xeb, 0x3b, 0xfa, 0x66, 0x69, 0xb2, 0x15, 0xc6, 0xf5, 0xac,
0x68, 0xc3, 0xb4, 0xa0, 0x3c, 0xf3, 0x9d, 0x0b, 0x3b, 0xa4, 0xad, 0x65, 0x3c, 0xe1, 0x44, 0x92,
0x31, 0x49, 0xc7, 0x75, 0x42, 0xc7, 0x0e, 0x3d, 0xbf, 0x45, 0x38, 0x2e, 0x02, 0x90, 0xfb, 0xb0,
0xcc, 0xd7, 0x49, 0x10, 0xda, 0xe1, 0x3c, 0x10, 0x82, 0xfb, 0x0a, 0x5f, 0x50, 0x5c, 0xf5, 0x18,
0x70, 0x38, 0x97, 0xdd, 0xc9, 0x27, 0xb0, 0x8e, 0x4b, 0x23, 0xb5, 0x35, 0x57, 0xd9, 0x70, 0xf0,
0x16, 0xad, 0x70, 0x8a, 0x9d, 0xf8, 0x1e, 0xfd, 0x0c, 0x36, 0xc4, 0x72, 0x49, 0xe5, 0x5c, 0x53,
0x39, 0x57, 0x91, 0x24, 0x91, 0x75, 0x0b, 0x96, 0x59, 0xd3, 0x9c, 0x91, 0x25, 0x4a, 0x60, 0xbb,
0x62, 0x9d, 0xf5, 0x82, 0x67, 0x5a, 0x42, 0xa4, 0xc9, 0x71, 0x4f, 0xe9, 0x15, 0xf9, 0x1c, 0x96,
0x70, 0xf9, 0x70, 0xed, 0x94, 0x1f, 0x7e, 0x9b, 0xfc, 0xf0, 0x5b, 0x13, 0x83, 0xbb, 0xa3, 0xb0,
0xfc, 0xfc, 0x5b, 0x1c, 0xc5, 0xd2, 0x6c, 0x6b, 0x4c, 0x9c, 0x53, 0x1a, 0x3a, 0x53, 0xda, 0xda,
0xc0, 0xc5, 0x26, 0xd3, 0x6c, 0xd7, 0xce, 0x67, 0x1c, 0xd3, 0x42, 0x56, 0x89, 0x29, 0xbe, 0x8e,
0x27, 0x5e, 0x40, 0xa5, 0xe5, 0xb0, 0x75, 0x53, 0x6c, 0x48, 0x06, 0x94, 0x22, 0x38, 0xd3, 0x63,
0x50, 0x67, 0x54, 0xf6, 0xdd, 0x5b, 0x7c, 0x61, 0x34, 0x50, 0x75, 0x94, 0x36, 0x5e, 0x26, 0xee,
0x9c, 0xdb, 0xcf, 0x25, 0x53, 0x7d, 0x8d, 0x73, 0x13, 0x60, 0x20, 0x61, 0x0e, 0xdc, 0x83, 0x65,
0x31, 0x0b, 0x11, 0x33, 0x6d, 0xdd, 0xe6, 0xc7, 0xd0, 0x4d, 0xd9, 0xc7, 0x14, 0xb7, 0x35, 0x9b,
0x38, 0x2f, 0x1a, 0xff, 0xdd, 0x07, 0x22, 0x27, 0x45, 0x2b, 0xe8, 0xf5, 0x97, 0x15, 0xb4, 0x2c,
0xa6, 0x29, 0x02, 0x19, 0xbf, 0x9b, 0x43, 0xa9, 0x45, 0x50, 0x07, 0x9a, 0xbe, 0x8e, 0x7c, 0xcd,
0xf2, 0xdc, 0xc9, 0x95, 0x60, 0x75, 0x80, 0xa0, 0xbe, 0x3b, 0xe1, 0xbc, 0xc6, 0x71, 0x75, 0x12,
0x3c, 0x20, 0xeb, 0x12, 0xc8, 0x89, 0xee, 0x40, 0x6d, 0x36, 0x3f, 0x99, 0x38, 0x23, 0x24, 0x29,
0x60, 0x29, 0x08, 0xe2, 0x04, 0x6f, 0x40, 0x5d, 0xac, 0x75, 0xa4, 0x28, 0x72, 0x8a, 0x9a, 0x80,
0x71, 0x12, 0x7e, 0x00, 0x53, 0x9f, 0x33, 0xbb, 0xba, 0xc9, 0x7f, 0x1b, 0xdb, 0xb0, 0x1a, 0x6f,
0xb4, 0x90, 0x0e, 0xee, 0x43, 0x45, 0x70, 0x52, 0x69, 0xc9, 0x5a, 0x8c, 0x8f, 0x86, 0xa9, 0xf0,
0xc6, 0x7f, 0x2c, 0xc1, 0x8a, 0x1c, 0x23, 0x36, 0xd9, 0x83, 0xf9, 0x74, 0x6a, 0xfb, 0x19, 0x2c,
0x3a, 0xf7, 0x62, 0x16, 0x9d, 0x4f, 0xb1, 0xe8, 0xb8, 0x29, 0x03, 0x39, 0x7c, 0xdc, 0x94, 0xc1,
0x56, 0x17, 0x6a, 0x97, 0xba, 0xc1, 0xbc, 0x21, 0xc0, 0x43, 0x34, 0xcc, 0xa7, 0x0e, 0x94, 0x52,
0xc6, 0x81, 0xa2, 0x1f, 0x07, 0x0b, 0x89, 0xe3, 0xe0, 0x0d, 0xc0, 0x65, 0x2c, 0xd7, 0x63, 0x19,
0x15, 0x4e, 0x0e, 0x13, 0x0b, 0xf2, 0x1d, 0x58, 0x4a, 0x72, 0x60, 0x64, 0xf5, 0x8b, 0x19, 0xfc,
0xd7, 0x99, 0x52, 0x2e, 0x52, 0x68, 0xc4, 0x55, 0xc1, 0x7f, 0x9d, 0x29, 0x3d, 0xe0, 0x18, 0x49,
0xdf, 0x01, 0xc0, 0xba, 0xf9, 0x36, 0x06, 0xbe, 0x8d, 0xdf, 0x4e, 0xac, 0x4c, 0x6d, 0xd4, 0xb7,
0x58, 0x62, 0xee, 0x53, 0xbe, 0xaf, 0xab, 0x3c, 0x27, 0xdf, 0xd2, 0x9f, 0xc0, 0xa2, 0x37, 0xa3,
0xae, 0x15, 0x71, 0xc1, 0x1a, 0x2f, 0xaa, 0x29, 0x8a, 0xea, 0x4a, 0xb8, 0xd9, 0x60, 0x74, 0x2a,
0x49, 0x3e, 0xc3, 0x41, 0xa6, 0x5a, 0xce, 0xfa, 0x35, 0x39, 0x17, 0x39, 0x61, 0x94, 0xf5, 0x43,
0xa8, 0xf9, 0x34, 0xf0, 0x26, 0x73, 0xb4, 0xbe, 0x37, 0xf8, 0x3a, 0x92, 0xe6, 0x48, 0x53, 0x61,
0x4c, 0x9d, 0xca, 0xf8, 0x8d, 0x1c, 0xd4, 0xb4, 0x3e, 0x90, 0x35, 0x58, 0xde, 0xe9, 0xf7, 0x8f,
0x3a, 0x66, 0x7b, 0xd8, 0xfd, 0xa2, 0x63, 0xed, 0x1c, 0xf4, 0x07, 0x9d, 0xe6, 0x0d, 0x06, 0x3e,
0xe8, 0xef, 0xb4, 0x0f, 0xac, 0xbd, 0xbe, 0xb9, 0x23, 0xc1, 0x39, 0xb2, 0x0e, 0xc4, 0xec, 0x1c,
0xf6, 0x87, 0x9d, 0x18, 0x3c, 0x4f, 0x9a, 0x50, 0xdf, 0x36, 0x3b, 0xed, 0x9d, 0x7d, 0x01, 0x29,
0x90, 0x55, 0x68, 0xee, 0x1d, 0xf7, 0x76, 0xbb, 0xbd, 0x27, 0xd6, 0x4e, 0xbb, 0xb7, 0xd3, 0x39,
0xe8, 0xec, 0x36, 0x8b, 0xa4, 0x01, 0xd5, 0xf6, 0x76, 0xbb, 0xb7, 0xdb, 0xef, 0x75, 0x76, 0x9b,
0x25, 0xe3, 0x7f, 0xe4, 0x00, 0xa2, 0x86, 0x32, 0xbe, 0x1a, 0x35, 0x55, 0xf7, 0x76, 0xad, 0xa5,
0x3a, 0x85, 0x7c, 0xd5, 0x8f, 0xa5, 0xc9, 0x43, 0x28, 0x7b, 0xf3, 0x70, 0xe4, 0x4d, 0x51, 0x50,
0x5f, 0x7c, 0xd8, 0x4a, 0xe5, 0xeb, 0x23, 0xde, 0x94, 0x84, 0x31, 0x8f, 0x56, 0xe1, 0x65, 0x1e,
0xad, 0xb8, 0xeb, 0x0c, 0xe5, 0x3a, 0xcd, 0x75, 0x76, 0x1b, 0x20, 0x78, 0x4e, 0xe9, 0x8c, 0x1b,
0x63, 0xc4, 0x2e, 0xa8, 0x72, 0xc8, 0x90, 0xe9, 0x71, 0x7f, 0x94, 0x83, 0x35, 0xbe, 0x96, 0xc6,
0x49, 0x26, 0x76, 0x17, 0x6a, 0x23, 0xcf, 0x9b, 0x31, 0xd5, 0x3f, 0x92, 0xd7, 0x74, 0x10, 0x63,
0x50, 0xc8, 0x90, 0x4f, 0x3d, 0x7f, 0x44, 0x05, 0x0f, 0x03, 0x0e, 0xda, 0x63, 0x10, 0xb6, 0x87,
0xc4, 0x26, 0x44, 0x0a, 0x64, 0x61, 0x35, 0x84, 0x21, 0xc9, 0x3a, 0x2c, 0x9c, 0xf8, 0xd4, 0x1e,
0x9d, 0x0b, 0xee, 0x25, 0x52, 0xe4, 0xbb, 0x91, 0x51, 0x6a, 0xc4, 0xf6, 0xc4, 0x84, 0x62, 0xe3,
0x2b, 0xe6, 0x92, 0x80, 0xef, 0x08, 0x30, 0x3b, 0xe7, 0xed, 0x13, 0xdb, 0x1d, 0x7b, 0x2e, 0x1d,
0x0b, 0x2d, 0x37, 0x02, 0x18, 0x47, 0xb0, 0x9e, 0xec, 0x9f, 0xe0, 0x77, 0x1f, 0x6b, 0xfc, 0x0e,
0xd5, 0xcb, 0xcd, 0xeb, 0xf7, 0x98, 0xc6, 0xfb, 0xfe, 0x52, 0x11, 0x8a, 0x4c, 0xdd, 0xb8, 0x56,
0x33, 0xd1, 0xf5, 0xc7, 0x42, 0xca, 0xcf, 0xc9, 0x6d, 0x5f, 0x28, 0x80, 0x89, 0xc9, 0xe2, 0x10,
0x2e, 0x78, 0x29, 0xb4, 0x4f, 0x47, 0x17, 0x42, 0xf2, 0x46, 0xb4, 0x49, 0x47, 0x17, 0x5c, 0x9d,
0xb7, 0x43, 0xcc, 0x8b, 0xfc, 0xaa, 0x1c, 0xd8, 0x21, 0xcf, 0x29, 0x50, 0x3c, 0x5f, 0x59, 0xa1,
0x78, 0xae, 0x16, 0x94, 0x1d, 0xf7, 0xc4, 0x9b, 0xbb, 0x63, 0xce, 0x9e, 0x2a, 0xa6, 0x4c, 0x72,
0xb7, 0x2a, 0xe7, 0xa4, 0xec, 0x68, 0x47, 0x6e, 0x54, 0x61, 0x80, 0x21, 0x3b, 0xdc, 0x3f, 0x80,
0x6a, 0x70, 0xe5, 0x8e, 0x74, 0x1e, 0xb4, 0x2a, 0xc6, 0x87, 0xf5, 0x7e, 0x6b, 0x70, 0xe5, 0x8e,
0xf8, 0x8a, 0xaf, 0x04, 0xe2, 0x17, 0x79, 0x04, 0x15, 0xe5, 0x88, 0xc0, 0x13, 0xe4, 0xa6, 0x9e,
0x43, 0x7a, 0x1f, 0xd0, 0xde, 0xa3, 0x48, 0xc9, 0xfb, 0xb0, 0xc0, 0xbd, 0x05, 0x41, 0xab, 0xce,
0x33, 0x49, 0xa5, 0x92, 0x35, 0x83, 0x7b, 0x34, 0xe9, 0x98, 0x7b, 0x0e, 0x4c, 0x41, 0xb6, 0xf9,
0x14, 0x1a, 0xb1, 0xb2, 0x74, 0xfb, 0x4d, 0x03, 0xed, 0x37, 0x6f, 0xe9, 0xf6, 0x9b, 0xe8, 0x24,
0x13, 0xd9, 0x74, 0x7b, 0xce, 0x0f, 0xa0, 0x22, 0xbb, 0xc2, 0x58, 0xc6, 0x71, 0xef, 0x69, 0xaf,
0xff, 0x65, 0xcf, 0x1a, 0x7c, 0xd5, 0xdb, 0x69, 0xde, 0x20, 0x4b, 0x50, 0x6b, 0xef, 0x70, 0x2e,
0xc4, 0x01, 0x39, 0x46, 0x72, 0xd4, 0x1e, 0x0c, 0x14, 0x24, 0x6f, 0xec, 0x41, 0x33, 0xd9, 0x52,
0xb6, 0x26, 0x43, 0x09, 0x13, 0xbe, 0x94, 0x08, 0xc0, 0xf4, 0x70, 0x74, 0x8f, 0xa0, 0x96, 0x83,
0x09, 0xe3, 0x11, 0x34, 0xd9, 0xb9, 0xcc, 0x86, 0x4a, 0xf7, 0x92, 0x4e, 0x98, 0xe4, 0xac, 0xfb,
0x53, 0x2a, 0x66, 0x0d, 0x61, 0xbc, 0x2a, 0xe3, 0x63, 0x58, 0xd6, 0xb2, 0x45, 0x76, 0x13, 0x76,
0xd6, 0x27, 0xed, 0x26, 0x5c, 0x4b, 0x46, 0x8c, 0xb1, 0x01, 0x6b, 0x2c, 0xd9, 0xb9, 0xa0, 0x6e,
0x38, 0x98, 0x9f, 0xa0, 0x73, 0xdd, 0xf1, 0x5c, 0xa6, 0x3d, 0x57, 0x15, 0xe6, 0xfa, 0x45, 0xbe,
0x25, 0x4c, 0x2c, 0xc8, 0xd5, 0x36, 0xb5, 0x1a, 0x78, 0xc6, 0x2d, 0xfe, 0x37, 0x66, 0x6a, 0xa9,
0x2a, 0x10, 0x1b, 0xd6, 0xa3, 0x4e, 0xc7, 0xb4, 0xfa, 0xbd, 0x83, 0x6e, 0x8f, 0xf1, 0x76, 0x36,
0xac, 0x1c, 0xb0, 0xb7, 0xc7, 0x21, 0x39, 0xa3, 0x09, 0x8b, 0x4f, 0x68, 0xd8, 0x75, 0x4f, 0x3d,
0x31, 0x18, 0xc6, 0x5f, 0x58, 0x80, 0x25, 0x05, 0x8a, 0x4c, 0x35, 0x17, 0xd4, 0x0f, 0x1c, 0xcf,
0xe5, 0xea, 0x46, 0xd5, 0x94, 0x49, 0xc6, 0x9d, 0x84, 0x92, 0xc5, 0xa5, 0x84, 0x55, 0x8e, 0x15,
0x6a, 0x19, 0x17, 0x11, 0xde, 0x81, 0x25, 0x67, 0x4c, 0xdd, 0xd0, 0x09, 0xaf, 0xac, 0x98, 0x91,
0x78, 0x51, 0x82, 0x85, 0x98, 0xb0, 0x0a, 0x25, 0x7b, 0xe2, 0xd8, 0x32, 0x68, 0x01, 0x13, 0x0c,
0x3a, 0xf2, 0x26, 0x9e, 0xcf, 0xd5, 0x8e, 0xaa, 0x89, 0x09, 0xf2, 0x00, 0x56, 0x99, 0x0a, 0xa4,
0x5b, 0xee, 0x39, 0x83, 0x41, 0x7b, 0x35, 0x71, 0xe7, 0xd3, 0xa3, 0xc8, 0x7a, 0xcf, 0x30, 0x4c,
0x38, 0x60, 0x39, 0x84, 0x34, 0xa8, 0x32, 0xa0, 0x51, 0x61, 0xd9, 0x9d, 0x4f, 0xdb, 0x1c, 0xa3,
0xe8, 0x1f, 0xc2, 0x1a, 0xa3, 0x57, 0xf2, 0xa3, 0xca, 0xb1, 0xc4, 0x73, 0xb0, 0xc2, 0xba, 0x02,
0xa7, 0xf2, 0xdc, 0x82, 0x2a, 0xb6, 0x8a, 0x2d, 0x89, 0x12, 0x9a, 0x1c, 0x78, 0x53, 0xa8, 0x1f,
0xa4, 0xe2, 0x0b, 0x50, 0x8f, 0x4f, 0xc6, 0x17, 0x68, 0x11, 0x0a, 0x95, 0x64, 0x84, 0xc2, 0x43,
0x58, 0x3b, 0x61, 0x6b, 0xf4, 0x9c, 0xda, 0x63, 0xea, 0x5b, 0xd1, 0xca, 0x47, 0x6d, 0x71, 0x85,
0x21, 0xf7, 0x39, 0x4e, 0x6d, 0x14, 0x26, 0xc8, 0x31, 0xbe, 0x41, 0xc7, 0x56, 0xe8, 0x59, 0x5c,
0xbe, 0xe3, 0x1c, 0xa8, 0x62, 0x36, 0x10, 0x3c, 0xf4, 0x76, 0x18, 0x30, 0x4e, 0x77, 0xe6, 0xdb,
0xb3, 0x73, 0xa1, 0xcb, 0x29, 0xba, 0x27, 0x0c, 0x48, 0x5e, 0x83, 0x32, 0xdb, 0x13, 0x2e, 0x45,
0x77, 0x2d, 0x6a, 0x49, 0x12, 0x44, 0xde, 0x82, 0x05, 0x5e, 0x47, 0xd0, 0x6a, 0xf2, 0x0d, 0x51,
0x8f, 0x38, 0xbd, 0xe3, 0x9a, 0x02, 0xc7, 0xa4, 0xe5, 0xb9, 0xef, 0x20, 0x1b, 0xaa, 0x9a, 0xfc,
0x37, 0xf9, 0xa1, 0xc6, 0xd3, 0x56, 0x78, 0xde, 0xb7, 0x44, 0xde, 0xc4, 0x52, 0xbc, 0x8e, 0xbd,
0x7d, 0xab, 0xdc, 0xea, 0x47, 0xc5, 0x4a, 0xad, 0x59, 0x37, 0x5a, 0x3c, 0xac, 0xc2, 0xa4, 0x23,
0xef, 0x82, 0xfa, 0x57, 0xb1, 0x3d, 0x92, 0x83, 0x8d, 0x14, 0x2a, 0xf2, 0xce, 0xfa, 0x02, 0x6e,
0x4d, 0xbd, 0xb1, 0x3c, 0xd3, 0xeb, 0x12, 0x78, 0xe8, 0x8d, 0x99, 0xec, 0xb1, 0xac, 0x88, 0x4e,
0x1d, 0xd7, 0x09, 0xce, 0xe9, 0x58, 0x1c, 0xed, 0x4d, 0x89, 0xd8, 0x13, 0x70, 0x26, 0x40, 0xcf,
0x7c, 0xef, 0x4c, 0x9d, 0x74, 0x39, 0x53, 0xa5, 0x8d, 0x4f, 0xa0, 0x84, 0x33, 0xc8, 0x36, 0x0a,
0x9f, 0xdf, 0x9c, 0xd8, 0x28, 0x1c, 0xda, 0x82, 0xb2, 0x4b, 0xc3, 0xe7, 0x9e, 0xff, 0x4c, 0xba,
0x7a, 0x44, 0xd2, 0xf8, 0x09, 0xb7, 0x3b, 0xaa, 0xf8, 0x18, 0xb4, 0x1d, 0xb0, 0x25, 0x8c, 0x4b,
0x30, 0x38, 0xb7, 0x85, 0x29, 0xb4, 0xc2, 0x01, 0x83, 0x73, 0x3b, 0xb5, 0x84, 0xf3, 0xe9, 0x10,
0x99, 0xb7, 0x60, 0x51, 0x46, 0xe4, 0x04, 0xd6, 0x84, 0x9e, 0x86, 0x62, 0x4b, 0xd6, 0x45, 0x38,
0x4e, 0x70, 0x40, 0x4f, 0x43, 0xe3, 0x10, 0x96, 0xc5, 0xa6, 0xe9, 0xcf, 0xa8, 0xac, 0xfa, 0xd3,
0x2c, 0xa5, 0xa6, 0xf6, 0x70, 0x25, 0x2e, 0x2d, 0xa0, 0x5c, 0x16, 0xd3, 0x74, 0x8c, 0x1f, 0x47,
0x06, 0x40, 0x26, 0x4b, 0x88, 0xf2, 0x84, 0x6a, 0x21, 0x3d, 0x64, 0xd2, 0xd1, 0xac, 0x14, 0x18,
0x67, 0xcc, 0x46, 0x27, 0x98, 0x8f, 0x46, 0x32, 0x52, 0xaa, 0x62, 0xca, 0xa4, 0xf1, 0xef, 0x72,
0xb0, 0xc2, 0x0b, 0x93, 0x4a, 0x99, 0x38, 0x29, 0x7e, 0xea, 0x46, 0xb2, 0xf9, 0xd1, 0x05, 0x38,
0x4c, 0x7c, 0x73, 0xef, 0x43, 0x31, 0xe5, 0x7d, 0xf8, 0x2e, 0x34, 0xc7, 0x74, 0xe2, 0xf0, 0xa5,
0x24, 0xe5, 0x21, 0x14, 0x40, 0x97, 0x24, 0x5c, 0x18, 0x09, 0x8c, 0xbf, 0x96, 0x83, 0x65, 0x14,
0xb7, 0xb8, 0xd9, 0x45, 0x0c, 0xd4, 0x63, 0x69, 0x5f, 0x10, 0xec, 0x54, 0xf4, 0x29, 0x12, 0x43,
0x38, 0x14, 0x89, 0xf7, 0x6f, 0x08, 0xbb, 0x83, 0x80, 0x92, 0xef, 0x73, 0x45, 0xd2, 0xb5, 0x38,
0x50, 0x88, 0xd1, 0x37, 0x33, 0x04, 0x3c, 0x95, 0x9d, 0x69, 0x99, 0x2e, 0x07, 0x6d, 0x57, 0x60,
0x01, 0x8d, 0x58, 0xc6, 0x1e, 0x34, 0x62, 0xd5, 0xc4, 0x9c, 0x21, 0x75, 0x74, 0x86, 0xa4, 0x9c,
0x93, 0xf9, 0xb4, 0x73, 0xf2, 0x0a, 0x56, 0x4c, 0x6a, 0x8f, 0xaf, 0xf6, 0x3c, 0xff, 0x28, 0x38,
0x09, 0xf7, 0x50, 0x86, 0x65, 0x67, 0x90, 0xf2, 0xb8, 0xc7, 0x3c, 0x0e, 0xd2, 0xf1, 0x2a, 0xad,
0x28, 0xdf, 0x81, 0xc5, 0xc8, 0x35, 0xaf, 0x59, 0xad, 0x1b, 0xca, 0x3b, 0xcf, 0x8d, 0xd7, 0x4c,
0xdf, 0x0f, 0x4e, 0x42, 0x61, 0xb7, 0xe6, 0xbf, 0x8d, 0xff, 0x5d, 0x04, 0xc2, 0x56, 0x73, 0x62,
0xc1, 0x24, 0x82, 0x0a, 0xf2, 0xa9, 0xa0, 0x82, 0x07, 0x40, 0x34, 0x02, 0x19, 0xeb, 0x50, 0x50,
0xb1, 0x0e, 0xcd, 0x88, 0x56, 0x84, 0x3a, 0x3c, 0x80, 0x55, 0xa1, 0x10, 0xc4, 0x9b, 0x8a, 0x4b,
0x83, 0xa0, 0x66, 0x10, 0x6b, 0xaf, 0x0c, 0x28, 0x90, 0x86, 0xe6, 0x02, 0x06, 0x14, 0x48, 0x7b,
0x90, 0xb6, 0x00, 0x17, 0x5e, 0xba, 0x00, 0xcb, 0xa9, 0x05, 0xa8, 0xd9, 0x06, 0x2b, 0x71, 0xdb,
0x60, 0xca, 0xca, 0x8d, 0xd2, 0x6f, 0xcc, 0xca, 0x7d, 0x0f, 0x9a, 0xd2, 0x4e, 0xa4, 0x2c, 0x90,
0x18, 0x09, 0x24, 0x6c, 0xc0, 0x3b, 0xd2, 0x06, 0x19, 0x73, 0x7b, 0xd5, 0x12, 0x6e, 0xaf, 0x77,
0x61, 0x39, 0x60, 0xeb, 0xd7, 0x9a, 0xbb, 0x22, 0x1c, 0x90, 0x8e, 0xb9, 0x3a, 0x5d, 0x31, 0x9b,
0x1c, 0x71, 0x1c, 0xc1, 0xd3, 0x16, 0xb5, 0x46, 0x86, 0x45, 0xed, 0x51, 0xe4, 0x61, 0x0f, 0xce,
0x9d, 0x29, 0x17, 0x7c, 0xa2, 0x10, 0x37, 0x31, 0xc0, 0x83, 0x73, 0x67, 0x6a, 0xca, 0x70, 0x0e,
0x96, 0x20, 0x3b, 0x70, 0x47, 0xf4, 0x27, 0x23, 0x12, 0x03, 0x47, 0x61, 0x89, 0x4b, 0xaa, 0x9b,
0x48, 0x76, 0x98, 0x08, 0xca, 0x48, 0x0c, 0x0a, 0x2b, 0x04, 0x8d, 0xb8, 0x4d, 0x7d, 0x50, 0x0e,
0xed, 0x4b, 0x34, 0xfb, 0xff, 0xaf, 0x1c, 0x34, 0xd9, 0xb2, 0x8b, 0xed, 0xe8, 0xcf, 0x80, 0xf3,
0x9e, 0x57, 0xdc, 0xd0, 0x35, 0x46, 0x2b, 0xf7, 0xf3, 0x27, 0xc0, 0x37, 0xa8, 0xe5, 0xcd, 0xa8,
0x2b, 0xb6, 0x73, 0x2b, 0xbe, 0x9d, 0x23, 0x96, 0xbd, 0x7f, 0x03, 0xf5, 0x35, 0x06, 0x21, 0x9f,
0x41, 0x95, 0xed, 0x03, 0xbe, 0x28, 0x45, 0x80, 0xe8, 0xa6, 0xd2, 0xc1, 0x53, 0x5b, 0x92, 0x65,
0x9d, 0x89, 0x64, 0x56, 0x0c, 0x46, 0x31, 0x23, 0x06, 0x43, 0xe3, 0x17, 0xfb, 0x00, 0x4f, 0xe9,
0xd5, 0x81, 0x37, 0xe2, 0xd6, 0x90, 0xdb, 0x00, 0x6c, 0xeb, 0x9c, 0xda, 0x53, 0x47, 0xd8, 0x01,
0x4b, 0x66, 0xf5, 0x19, 0xbd, 0xda, 0xe3, 0x00, 0xb6, 0x6e, 0x18, 0x3a, 0x62, 0x1a, 0x25, 0xb3,
0xf2, 0x8c, 0x5e, 0x21, 0xc7, 0xb0, 0xa0, 0xf1, 0x94, 0x5e, 0xed, 0x52, 0x14, 0xcc, 0x3d, 0x9f,
0xad, 0x59, 0xdf, 0x7e, 0xce, 0x24, 0xf1, 0x58, 0xfc, 0x44, 0xcd, 0xb7, 0x9f, 0x3f, 0xa5, 0x57,
0x32, 0x96, 0xa3, 0xcc, 0xf0, 0x13, 0x6f, 0x24, 0x44, 0x09, 0x69, 0x7a, 0x89, 0x1a, 0x65, 0x2e,
0x3c, 0xe3, 0xbf, 0x8d, 0x3f, 0xc9, 0x41, 0x83, 0xb5, 0x9f, 0x9f, 0x02, 0x7c, 0x85, 0x88, 0x80,
0xc2, 0x5c, 0x14, 0x50, 0xf8, 0x50, 0x30, 0x51, 0x3c, 0x52, 0xf2, 0xd7, 0x1f, 0x29, 0x7c, 0x6e,
0xf0, 0x3c, 0xf9, 0x00, 0xaa, 0xc8, 0x05, 0x18, 0x5b, 0x29, 0xc4, 0x26, 0x38, 0xd6, 0x21, 0xb3,
0xc2, 0xc9, 0x9e, 0x62, 0xfc, 0x92, 0x66, 0xe5, 0xc6, 0x21, 0xae, 0xfa, 0xca, 0xb6, 0x9d, 0x31,
0x0d, 0xa5, 0x6b, 0xe2, 0x97, 0x74, 0x13, 0xf2, 0x42, 0xd2, 0x84, 0x6c, 0xb8, 0x50, 0x61, 0x53,
0xcd, 0x3b, 0x9b, 0x51, 0x68, 0x2e, 0xab, 0x50, 0x26, 0x78, 0xd8, 0xec, 0x0c, 0x62, 0x7c, 0x35,
0x2f, 0x04, 0x0f, 0x3b, 0xa0, 0xac, 0x20, 0xd6, 0x70, 0xd7, 0xb3, 0xb8, 0x4d, 0x56, 0x58, 0x2b,
0x2b, 0x66, 0xd5, 0xf5, 0x8e, 0x10, 0x60, 0xfc, 0xb9, 0x1c, 0xd4, 0xb4, 0xfd, 0xc8, 0x8d, 0xf4,
0x6a, 0x38, 0x71, 0xf3, 0xc6, 0x77, 0x40, 0x6c, 0x3e, 0xf6, 0x6f, 0x98, 0x8d, 0x51, 0x6c, 0x82,
0xb6, 0xc4, 0x52, 0xe6, 0x39, 0xf3, 0x31, 0xcb, 0x90, 0xec, 0x97, 0x5c, 0xbf, 0xec, 0xf7, 0xf6,
0x02, 0x14, 0x19, 0xa9, 0xf1, 0x18, 0x96, 0xb5, 0x66, 0xa0, 0xe5, 0xe4, 0x55, 0x07, 0xc0, 0xf8,
0x65, 0x95, 0x99, 0xd5, 0x81, 0x9e, 0x65, 0x19, 0x2a, 0x46, 0xc7, 0x38, 0x2e, 0x22, 0x24, 0x0d,
0x41, 0x7c, 0x64, 0x5e, 0x35, 0x7c, 0xe9, 0x57, 0x61, 0x45, 0x2b, 0x7d, 0xcf, 0x71, 0xed, 0x89,
0xf3, 0x13, 0x2e, 0x7e, 0x04, 0xce, 0x99, 0x9b, 0x28, 0x1f, 0x41, 0xdf, 0xa8, 0xfc, 0xbf, 0x9e,
0x87, 0x55, 0x51, 0x01, 0x0f, 0xfe, 0x75, 0x98, 0x4c, 0x79, 0x18, 0x9c, 0x91, 0xcf, 0xa0, 0xc1,
0xc6, 0xc6, 0xf2, 0xe9, 0x99, 0x13, 0x84, 0x54, 0x7a, 0xb4, 0x33, 0xd8, 0x28, 0x13, 0x2d, 0x18,
0xa9, 0x29, 0x28, 0xc9, 0x63, 0xa8, 0xf1, 0xac, 0x68, 0x99, 0x12, 0x13, 0xd1, 0x4a, 0x67, 0xc4,
0x81, 0xde, 0xbf, 0x61, 0x42, 0x10, 0x0d, 0xfb, 0x63, 0xa8, 0xf1, 0x39, 0xbc, 0xe0, 0x03, 0x99,
0xe0, 0x64, 0xa9, 0x81, 0x66, 0x99, 0x67, 0xd1, 0xb0, 0xb7, 0xa1, 0x81, 0xbc, 0x4c, 0x8c, 0x93,
0x08, 0x2a, 0xdc, 0x4c, 0x67, 0x97, 0x23, 0xc9, 0x1a, 0x3f, 0xd3, 0xd2, 0xdb, 0x55, 0x28, 0x87,
0xbe, 0x73, 0x76, 0x46, 0x7d, 0x63, 0x5d, 0x0d, 0x0d, 0x63, 0xd2, 0x74, 0x10, 0xd2, 0x19, 0x53,
0x16, 0x8c, 0x7f, 0x95, 0x83, 0x9a, 0x60, 0xbb, 0x3f, 0xb5, 0x1b, 0x7d, 0x33, 0x61, 0xc3, 0xac,
0x6a, 0x26, 0xcb, 0x77, 0x60, 0x69, 0xca, 0x34, 0x1b, 0xa6, 0x79, 0xc7, 0x7c, 0xe8, 0x8b, 0x12,
0x2c, 0x84, 0xf6, 0x2d, 0x58, 0xe1, 0x32, 0x7c, 0x60, 0x85, 0xce, 0xc4, 0x92, 0x48, 0x11, 0x01,
0xbf, 0x8c, 0xa8, 0xa1, 0x33, 0x39, 0x14, 0x08, 0x26, 0xca, 0x06, 0xa1, 0x7d, 0x46, 0xc5, 0xd6,
0xc7, 0x04, 0xd3, 0x96, 0x12, 0x4a, 0xb7, 0xd4, 0x96, 0xfe, 0xef, 0x32, 0x6c, 0xa4, 0x50, 0x42,
0x5b, 0x52, 0x4e, 0xd3, 0x89, 0x33, 0x3d, 0xf1, 0x94, 0xd1, 0x3e, 0xa7, 0x39, 0x4d, 0x0f, 0x18,
0x46, 0x1a, 0xed, 0x29, 0xac, 0xc9, 0x05, 0xc9, 0xad, 0xee, 0x4a, 0x2f, 0xcf, 0x73, 0xad, 0xf1,
0x83, 0xf8, 0x19, 0x97, 0xac, 0x4e, 0xc2, 0x75, 0x41, 0x6d, 0x65, 0x96, 0x82, 0x05, 0xe4, 0x4f,
0x43, 0x4b, 0xad, 0x7b, 0xa1, 0x44, 0x68, 0x46, 0x06, 0x56, 0xd3, 0x7b, 0x2f, 0xa9, 0x29, 0x66,
0x0e, 0xe5, 0x92, 0xdc, 0xba, 0xdc, 0x32, 0x58, 0xa0, 0xaa, 0xeb, 0x02, 0x5e, 0x97, 0x75, 0x71,
0xa5, 0x20, 0x5d, 0x63, 0xf1, 0x95, 0xfa, 0xc6, 0x4d, 0xbd, 0xb1, 0x6a, 0xcd, 0x5b, 0xa2, 0x60,
0x85, 0xd2, 0xeb, 0x3d, 0x87, 0xf5, 0xe7, 0xb6, 0x13, 0xca, 0x3e, 0x6a, 0x36, 0x8e, 0x12, 0xaf,
0xef, 0xe1, 0x4b, 0xea, 0xfb, 0x12, 0x33, 0xc7, 0xd4, 0xa4, 0xd5, 0xe7, 0x69, 0x60, 0xb0, 0xf9,
0x77, 0x0b, 0xb0, 0x18, 0x2f, 0x85, 0x31, 0x16, 0x71, 0x16, 0x49, 0xe9, 0x57, 0x88, 0xe4, 0xc2,
0xa1, 0xd4, 0x43, 0xa9, 0x37, 0xed, 0xea, 0xca, 0x67, 0xb8, 0xba, 0x74, 0x0f, 0x53, 0xe1, 0x65,
0x01, 0x07, 0xc5, 0x57, 0x0a, 0x38, 0x28, 0x65, 0x05, 0x1c, 0x7c, 0x78, 0xad, 0x87, 0x1a, 0xed,
0xc4, 0x99, 0xde, 0xe9, 0x47, 0xd7, 0x7b, 0xa7, 0x51, 0x96, 0xbe, 0xce, 0x33, 0xad, 0xf9, 0xd5,
0x2b, 0xd7, 0xf8, 0x85, 0x34, 0x4f, 0x7b, 0x86, 0x67, 0xba, 0xfa, 0x0d, 0x3c, 0xd3, 0x9b, 0x7f,
0x92, 0x03, 0x92, 0xde, 0x1d, 0xe4, 0x09, 0x7a, 0x11, 0x5d, 0x3a, 0x11, 0x9c, 0xfb, 0x7b, 0xaf,
0xb6, 0xc3, 0xe4, 0x82, 0x90, 0xb9, 0xc9, 0xfb, 0xb0, 0xa2, 0xdf, 0xd3, 0xd1, 0x6d, 0x08, 0x0d,
0x93, 0xe8, 0xa8, 0xc8, 0x1a, 0xa6, 0x45, 0x77, 0x14, 0x5f, 0x1a, 0xdd, 0x51, 0x7a, 0x69, 0x74,
0xc7, 0x42, 0x3c, 0xba, 0x63, 0xf3, 0xdf, 0xe6, 0x60, 0x25, 0x63, 0x11, 0x7f, 0x7b, 0x7d, 0x66,
0x6b, 0x2f, 0xc6, 0xd6, 0xf2, 0x62, 0xed, 0xe9, 0x1c, 0xed, 0x40, 0x5a, 0x50, 0xd9, 0x54, 0x04,
0xe2, 0xa4, 0xba, 0xff, 0x32, 0xee, 0x12, 0xe5, 0x30, 0xf5, 0xec, 0x9b, 0x7f, 0x3f, 0x0f, 0x35,
0x0d, 0xc9, 0x46, 0x11, 0x97, 0xac, 0x16, 0x5b, 0x88, 0x82, 0x23, 0xb7, 0x80, 0xdc, 0x01, 0xe1,
0x27, 0x42, 0x3c, 0x6e, 0x2e, 0x21, 0x25, 0x72, 0x82, 0x2d, 0x58, 0x91, 0x1e, 0x5e, 0x1a, 0x85,
0x1b, 0x8b, 0xb3, 0x46, 0x38, 0xeb, 0x45, 0x23, 0x39, 0xfd, 0xfb, 0x52, 0x39, 0x8d, 0xe6, 0x4e,
0xf3, 0x98, 0x2d, 0x8b, 0x30, 0x01, 0x31, 0x89, 0x6c, 0x9d, 0x7f, 0x00, 0x6b, 0x2a, 0x4e, 0x20,
0x96, 0x03, 0xfd, 0x32, 0x44, 0xc6, 0x03, 0x68, 0x59, 0x7e, 0x08, 0xb7, 0x13, 0x6d, 0x4a, 0x64,
0xc5, 0xb8, 0xf8, 0x9b, 0xb1, 0xd6, 0xe9, 0x25, 0x6c, 0xfe, 0x19, 0x68, 0xc4, 0x18, 0xe5, 0xb7,
0x37, 0xe5, 0x49, 0xab, 0x13, 0x8e, 0xa8, 0x6e, 0x75, 0xda, 0xfc, 0x9f, 0x05, 0x20, 0x69, 0x5e,
0xfd, 0xf3, 0x6c, 0x42, 0x7a, 0x61, 0x16, 0x32, 0x16, 0xe6, 0xff, 0x37, 0xf9, 0x21, 0x32, 0x7e,
0x6a, 0x6e, 0x7a, 0xdc, 0x9c, 0x4d, 0x85, 0x90, 0xad, 0xf8, 0x24, 0x19, 0xcc, 0x54, 0x89, 0x5d,
0x35, 0xd3, 0x04, 0xa8, 0x44, 0x4c, 0xd3, 0x31, 0x2c, 0xd8, 0xee, 0xe8, 0xdc, 0xf3, 0x05, 0x1f,
0xfc, 0x85, 0x6f, 0x7c, 0x7c, 0x6e, 0xb5, 0x79, 0x7e, 0x2e, 0xb5, 0x99, 0xa2, 0x30, 0xe3, 0x03,
0xa8, 0x69, 0x60, 0x52, 0x85, 0xd2, 0x41, 0xf7, 0x70, 0xbb, 0xdf, 0xbc, 0x41, 0x1a, 0x50, 0x35,
0x3b, 0x3b, 0xfd, 0x2f, 0x3a, 0x66, 0x67, 0xb7, 0x99, 0x23, 0x15, 0x28, 0x1e, 0xf4, 0x07, 0xc3,
0x66, 0xde, 0xd8, 0x84, 0x96, 0x28, 0x31, 0xed, 0x06, 0xfa, 0xad, 0xa2, 0x32, 0x5e, 0x72, 0xa4,
0xd0, 0xe0, 0x3f, 0x84, 0xba, 0x2e, 0xde, 0x88, 0x15, 0x91, 0x88, 0x14, 0x61, 0xba, 0xbb, 0xa7,
0xf1, 0xea, 0x1d, 0xc0, 0x38, 0x81, 0xb1, 0xca, 0x96, 0x8f, 0xc9, 0xad, 0x19, 0x0e, 0x57, 0xae,
0xfc, 0xc4, 0x96, 0xe1, 0x9f, 0x82, 0xc5, 0xb8, 0xcb, 0x43, 0x70, 0xa4, 0x2c, 0x7d, 0x94, 0xe5,
0x8e, 0xf9, 0x40, 0xc8, 0x0f, 0xa1, 0x99, 0x74, 0x99, 0x08, 0xe1, 0xf9, 0x9a, 0xfc, 0x4b, 0x4e,
0xdc, 0x8b, 0x42, 0xf6, 0x61, 0x35, 0x4b, 0xc0, 0xe3, 0xeb, 0xe3, 0x7a, 0x1b, 0x06, 0x49, 0x0b,
0x71, 0xe4, 0x53, 0xe1, 0x3a, 0x2b, 0xf1, 0xe9, 0x7f, 0x2b, 0x5e, 0xbf, 0x36, 0xd8, 0x5b, 0xf8,
0x4f, 0x73, 0xa2, 0x5d, 0x00, 0x44, 0x30, 0xd2, 0x84, 0x7a, 0xff, 0xa8, 0xd3, 0xb3, 0x76, 0xf6,
0xdb, 0xbd, 0x5e, 0xe7, 0xa0, 0x79, 0x83, 0x10, 0x58, 0xe4, 0xc1, 0x0e, 0xbb, 0x0a, 0x96, 0x63,
0x30, 0xe1, 0xc2, 0x94, 0xb0, 0x3c, 0x59, 0x85, 0x66, 0xb7, 0x97, 0x80, 0x16, 0x48, 0x0b, 0x56,
0x8f, 0x3a, 0x18, 0x1f, 0x11, 0x2b, 0xb7, 0xc8, 0x94, 0x06, 0xd1, 0x5d, 0xa6, 0x34, 0x7c, 0x69,
0x4f, 0x26, 0x34, 0x14, 0xfb, 0x40, 0xca, 0xd2, 0x7f, 0x23, 0x07, 0x6b, 0x09, 0x44, 0xe4, 0x77,
0x40, 0x49, 0x3a, 0x2e, 0x43, 0xd7, 0x39, 0x50, 0xee, 0xa6, 0x77, 0x61, 0x59, 0x99, 0xc1, 0x12,
0xa7, 0x52, 0x53, 0x21, 0x24, 0xf1, 0xfb, 0xb0, 0xa2, 0x59, 0xd3, 0x12, 0xbc, 0x82, 0x68, 0x28,
0x91, 0xc1, 0xd8, 0x50, 0xb7, 0x6f, 0x12, 0xad, 0x1e, 0xc3, 0x7a, 0x12, 0x11, 0x79, 0x16, 0xe3,
0xed, 0x95, 0x49, 0xf2, 0x20, 0xb1, 0x10, 0xe2, 0xad, 0xd5, 0x27, 0x5c, 0x56, 0xff, 0x3b, 0x0b,
0x40, 0x7e, 0x3c, 0xa7, 0xfe, 0x15, 0xbf, 0xf5, 0x15, 0xbc, 0x2c, 0xb4, 0x59, 0x1a, 0x62, 0xf2,
0xaf, 0x74, 0xb3, 0x33, 0xeb, 0x66, 0x65, 0xf1, 0xe5, 0x37, 0x2b, 0x4b, 0x2f, 0xbb, 0x59, 0xf9,
0x26, 0x34, 0x9c, 0x33, 0xd7, 0x63, 0xac, 0x90, 0x49, 0xc2, 0x41, 0x6b, 0xe1, 0x6e, 0xe1, 0x5e,
0xdd, 0xac, 0x0b, 0x20, 0x93, 0x83, 0x03, 0xf2, 0x38, 0x22, 0xa2, 0xe3, 0x33, 0x7e, 0xbb, 0x58,
0x67, 0x82, 0x9d, 0xf1, 0x19, 0x15, 0x76, 0x27, 0xae, 0x69, 0xc8, 0xcc, 0x0c, 0x1e, 0x90, 0xb7,
0x60, 0x31, 0xf0, 0xe6, 0x4c, 0xb1, 0x90, 0xc3, 0x80, 0xae, 0xc5, 0x3a, 0x42, 0x8f, 0xa4, 0xa3,
0x79, 0x65, 0x1e, 0x50, 0x6b, 0xea, 0x04, 0x01, 0x13, 0xcf, 0x46, 0x9e, 0x1b, 0xfa, 0xde, 0x44,
0x78, 0x0b, 0x97, 0xe7, 0x01, 0x3d, 0x44, 0xcc, 0x0e, 0x22, 0xc8, 0x47, 0x51, 0x93, 0x66, 0xb6,
0xe3, 0x07, 0x2d, 0xe0, 0x4d, 0x92, 0x3d, 0xe5, 0xf2, 0xbb, 0xed, 0xf8, 0xaa, 0x2d, 0x2c, 0x11,
0x24, 0x6e, 0x7c, 0xd6, 0x92, 0x37, 0x3e, 0x7f, 0x2d, 0xfb, 0xc6, 0x27, 0xc6, 0x37, 0x3d, 0x10,
0x45, 0xa7, 0xa7, 0xf8, 0x1b, 0x5d, 0xfc, 0x4c, 0x5f, 0x64, 0x5d, 0xfc, 0x26, 0x17, 0x59, 0x97,
0xb2, 0x2e, 0xb2, 0x7e, 0x00, 0x35, 0x7e, 0xc5, 0xd0, 0x3a, 0xe7, 0x51, 0x8e, 0xe8, 0xfd, 0x6c,
0xea, 0x77, 0x10, 0xf7, 0x1d, 0x37, 0x34, 0xc1, 0x97, 0x3f, 0x83, 0xf4, 0x9d, 0xd2, 0xe5, 0x9f,
0xe3, 0x9d, 0x52, 0x71, 0x15, 0x72, 0x0b, 0x2a, 0x72, 0x9e, 0x08, 0x81, 0xe2, 0xa9, 0xef, 0x4d,
0xa5, 0xc7, 0x85, 0xfd, 0x26, 0x8b, 0x90, 0x0f, 0x3d, 0x91, 0x39, 0x1f, 0x7a, 0xc6, 0xaf, 0x40,
0x4d, 0x5b, 0x6a, 0xe4, 0x0d, 0x34, 0x5b, 0x32, 0xdd, 0x4c, 0xc8, 0x96, 0x38, 0x8a, 0x55, 0x01,
0xed, 0x8e, 0x19, 0xbf, 0x19, 0x3b, 0x3e, 0xe5, 0xb7, 0xbf, 0x2d, 0x9f, 0x5e, 0x50, 0x3f, 0x90,
0x1e, 0xb0, 0xa6, 0x42, 0x98, 0x08, 0x37, 0x7e, 0x15, 0x56, 0x62, 0x73, 0x2b, 0x58, 0xc4, 0x5b,
0xb0, 0xc0, 0xc7, 0x4d, 0x86, 0x59, 0xc4, 0xef, 0x76, 0x0a, 0x1c, 0xbf, 0xe9, 0x8e, 0xce, 0x3b,
0x6b, 0xe6, 0x7b, 0x27, 0xbc, 0x92, 0x9c, 0x59, 0x13, 0xb0, 0x23, 0xdf, 0x3b, 0x31, 0xfe, 0xb0,
0x00, 0x85, 0x7d, 0x6f, 0xa6, 0x47, 0x46, 0xe6, 0x52, 0x91, 0x91, 0x42, 0xe1, 0xb4, 0x94, 0x42,
0x29, 0x64, 0x76, 0xee, 0xb6, 0x92, 0x4a, 0xe5, 0x3d, 0x58, 0x64, 0x7c, 0x22, 0xf4, 0x98, 0xc6,
0xfe, 0xdc, 0xf6, 0x51, 0x20, 0xc6, 0x40, 0xe3, 0xba, 0x3d, 0x0d, 0x87, 0xde, 0x1e, 0xc2, 0xc9,
0x2a, 0x14, 0x94, 0xfa, 0xc2, 0xd1, 0x2c, 0x49, 0xd6, 0x61, 0x81, 0xdf, 0x63, 0xb8, 0x12, 0x61,
0x02, 0x22, 0x45, 0xbe, 0x07, 0x2b, 0xf1, 0x72, 0x91, 0x15, 0x09, 0xd9, 0x48, 0x2f, 0x98, 0xf3,
0xa4, 0x9b, 0xc0, 0xf8, 0x08, 0xd2, 0x88, 0x70, 0xa4, 0x53, 0x4a, 0x39, 0x4a, 0x63, 0x7a, 0x95,
0x18, 0xd3, 0xbb, 0x03, 0xb5, 0x70, 0x72, 0x61, 0xcd, 0xec, 0xab, 0x89, 0x67, 0x8f, 0xc5, 0xfe,
0x86, 0x70, 0x72, 0x71, 0x84, 0x10, 0xf2, 0x3e, 0xc0, 0x74, 0x36, 0x13, 0x7b, 0x8f, 0xbb, 0x62,
0xa2, 0xa5, 0x7c, 0x78, 0x74, 0x84, 0x4b, 0xce, 0xac, 0x4e, 0x67, 0x33, 0xfc, 0x49, 0x76, 0x61,
0x31, 0xf3, 0x86, 0xf6, 0x6d, 0x19, 0x6f, 0xee, 0xcd, 0xb6, 0x32, 0x36, 0x67, 0x63, 0xa4, 0xc3,
0x36, 0x7f, 0x08, 0xe4, 0x67, 0xbc, 0x27, 0x3d, 0x84, 0xaa, 0x6a, 0x9f, 0x7e, 0xcd, 0x98, 0x5f,
0xa4, 0xa9, 0xc5, 0xae, 0x19, 0xb7, 0xc7, 0x63, 0x9f, 0xf1, 0x45, 0x3c, 0x30, 0x15, 0xcb, 0x07,
0xed, 0xc4, 0x14, 0x37, 0x35, 0x8c, 0xff, 0x92, 0x83, 0x12, 0xde, 0x79, 0x7e, 0x1b, 0x96, 0x90,
0x5e, 0x45, 0x99, 0x8a, 0xe0, 0x02, 0x3c, 0x77, 0x87, 0x22, 0xc0, 0x94, 0x6d, 0x0b, 0xed, 0x1d,
0x88, 0xbc, 0x9a, 0x79, 0xed, 0x2d, 0x88, 0x3b, 0x50, 0x55, 0x55, 0x6b, 0x4b, 0xa7, 0x22, 0x6b,
0x26, 0xaf, 0x43, 0xf1, 0xdc, 0x9b, 0x49, 0xcb, 0x0f, 0x44, 0x23, 0x69, 0x72, 0x78, 0xd4, 0x16,
0x56, 0x47, 0x74, 0x83, 0xa4, 0x20, 0xda, 0xc2, 0x2a, 0xe1, 0xcb, 0x20, 0xdd, 0xc7, 0x85, 0x8c,
0x3e, 0x1e, 0xc3, 0x12, 0xe3, 0x03, 0x5a, 0x84, 0xc3, 0xf5, 0x87, 0xe6, 0x77, 0x99, 0x84, 0x37,
0x9a, 0xcc, 0xc7, 0x54, 0xb7, 0xbd, 0xf1, 0x90, 0x41, 0x01, 0x97, 0x92, 0xb5, 0xf1, 0x3b, 0x39,
0xe4, 0x2f, 0xac, 0x5c, 0x72, 0x0f, 0x8a, 0xae, 0x8c, 0x86, 0x88, 0xe4, 0x38, 0x75, 0xa3, 0x89,
0xd1, 0x99, 0x9c, 0x82, 0x4d, 0x1d, 0x8f, 0x21, 0xd0, 0x4b, 0x6f, 0x98, 0x35, 0x77, 0x3e, 0x55,
0xa6, 0xab, 0xef, 0xc8, 0x6e, 0x25, 0xcc, 0x3e, 0xd8, 0x7b, 0xb5, 0x4d, 0xb7, 0xb4, 0xd8, 0xc3,
0x62, 0xec, 0xc4, 0x94, 0x52, 0xe0, 0xf8, 0x8c, 0x6a, 0x31, 0x87, 0xbf, 0x97, 0x87, 0x46, 0xac,
0x45, 0x3c, 0xf8, 0x92, 0x1d, 0x00, 0xe8, 0x77, 0x12, 0xf3, 0x0d, 0x0c, 0x24, 0x04, 0x75, 0x6d,
0x9c, 0xf2, 0xb1, 0x71, 0x52, 0xe1, 0x4c, 0x05, 0x3d, 0x9c, 0xe9, 0x01, 0x54, 0xa3, 0xf7, 0x3f,
0xe2, 0x4d, 0x62, 0xf5, 0xc9, 0x7b, 0x5d, 0x11, 0x51, 0x14, 0x00, 0x55, 0xd2, 0x03, 0xa0, 0x3e,
0xd7, 0xe2, 0x65, 0x16, 0x78, 0x31, 0x46, 0xd6, 0x88, 0xfe, 0x5c, 0xa2, 0x65, 0x8c, 0xc7, 0x50,
0xd3, 0x1a, 0xaf, 0xc7, 0x9c, 0xe4, 0x62, 0x31, 0x27, 0xea, 0x5e, 0x66, 0x3e, 0xba, 0x97, 0x69,
0xfc, 0xf9, 0x3c, 0x34, 0xd8, 0xfe, 0x72, 0xdc, 0xb3, 0x23, 0x6f, 0xe2, 0x8c, 0xb8, 0x1f, 0x4a,
0xed, 0x30, 0x21, 0x68, 0xc9, 0x7d, 0x26, 0xb6, 0x18, 0xca, 0x59, 0xfa, 0xa5, 0x74, 0x64, 0xd2,
0xea, 0x52, 0xba, 0x01, 0x0d, 0xc6, 0x18, 0xb9, 0x47, 0x29, 0x7a, 0x45, 0xc4, 0xac, 0x9d, 0x52,
0xba, 0x6d, 0x07, 0xc8, 0x21, 0xbf, 0x07, 0x2b, 0x8c, 0x86, 0xdf, 0xc7, 0x9d, 0x3a, 0x93, 0x89,
0x13, 0x5d, 0xd9, 0x2a, 0x98, 0xcd, 0x53, 0x4a, 0x4d, 0x3b, 0xa4, 0x87, 0x0c, 0x21, 0x1e, 0x1d,
0xa9, 0x8c, 0x9d, 0xc0, 0x3e, 0x89, 0x42, 0x64, 0x55, 0x9a, 0xfb, 0xb9, 0x85, 0x9f, 0x36, 0xda,
0x64, 0x45, 0xb3, 0x36, 0x45, 0x2f, 0x2d, 0xcf, 0x9f, 0x58, 0x49, 0xe5, 0xe4, 0x4a, 0x32, 0xfe,
0x79, 0x1e, 0x6a, 0xda, 0xb2, 0x7c, 0x95, 0xd3, 0xf5, 0x76, 0xca, 0x6f, 0x58, 0xd5, 0x5d, 0x84,
0x6f, 0xc6, 0xab, 0x2c, 0xa8, 0x7b, 0x3d, 0xfa, 0x02, 0xbe, 0x05, 0x55, 0xb6, 0xeb, 0x3e, 0xe0,
0x26, 0x58, 0xf1, 0xe8, 0x0f, 0x07, 0x1c, 0xcd, 0x4f, 0x24, 0xf2, 0x21, 0x47, 0x96, 0x22, 0xe4,
0x43, 0x86, 0x7c, 0x51, 0x5c, 0xff, 0x27, 0x50, 0x17, 0xa5, 0xf2, 0x39, 0xe5, 0xdd, 0x8d, 0x76,
0x7d, 0x6c, 0xbe, 0xcd, 0x1a, 0x56, 0x87, 0x93, 0x2f, 0x32, 0x3e, 0x94, 0x19, 0x2b, 0x2f, 0xcb,
0xf8, 0x10, 0x13, 0xc6, 0x9e, 0xba, 0x2a, 0xc1, 0x23, 0xd5, 0x24, 0x1f, 0x7b, 0x1f, 0x56, 0x24,
0xbb, 0x9a, 0xbb, 0xb6, 0xeb, 0x7a, 0x73, 0x77, 0x44, 0xe5, 0xd5, 0x4c, 0x22, 0x50, 0xc7, 0x11,
0xc6, 0x18, 0xab, 0x7b, 0xfe, 0x18, 0xf1, 0x76, 0x1f, 0x4a, 0x28, 0x97, 0xa3, 0xf0, 0x91, 0xcd,
0xb8, 0x90, 0x84, 0xdc, 0x83, 0x12, 0x8a, 0xe7, 0xf9, 0x6b, 0x99, 0x0d, 0x12, 0x18, 0x6d, 0x20,
0x2c, 0xe3, 0x21, 0x0d, 0x7d, 0x67, 0x14, 0x44, 0xb7, 0x3e, 0x4b, 0x4c, 0xff, 0xc4, 0xba, 0x22,
0xcb, 0x6d, 0x44, 0xc9, 0x75, 0x54, 0xa4, 0x61, 0x07, 0xd3, 0x4a, 0xac, 0x0c, 0x21, 0x2e, 0x4d,
0x60, 0xfd, 0x84, 0x86, 0xcf, 0x29, 0x75, 0x5d, 0x26, 0x0c, 0x8d, 0xa8, 0x1b, 0xfa, 0xf6, 0x84,
0x4d, 0x12, 0xf6, 0xe0, 0x51, 0xaa, 0xd4, 0xc8, 0x06, 0xb2, 0x1d, 0x65, 0xdc, 0x51, 0xf9, 0x90,
0x77, 0xac, 0x9d, 0x64, 0xe1, 0x36, 0x7f, 0x19, 0x36, 0xaf, 0xcf, 0x94, 0x71, 0xe3, 0xfb, 0x5e,
0x9c, 0xab, 0x28, 0x3f, 0xe0, 0xc4, 0xb3, 0x43, 0x6c, 0x8d, 0xce, 0x59, 0x7a, 0x50, 0xd3, 0x30,
0xd1, 0xd9, 0x9f, 0xe3, 0xc2, 0x1d, 0x26, 0xd8, 0x89, 0xe4, 0x7a, 0xfe, 0x94, 0xfb, 0xdd, 0xc6,
0x56, 0x54, 0x7a, 0xce, 0x5c, 0x8a, 0xe0, 0x3c, 0xc6, 0xc2, 0xd8, 0x82, 0x25, 0x2e, 0xd9, 0x6b,
0x07, 0xdd, 0x8b, 0x84, 0x41, 0x63, 0x15, 0x48, 0x0f, 0x79, 0x97, 0x1e, 0xfd, 0xf7, 0xef, 0x0b,
0x50, 0xd3, 0xc0, 0xec, 0x34, 0xe2, 0x21, 0x93, 0xd6, 0xd8, 0xb1, 0xa7, 0x54, 0x3a, 0x39, 0x1b,
0x66, 0x83, 0x43, 0x77, 0x05, 0x90, 0x9d, 0xc5, 0xf6, 0xc5, 0x99, 0xe5, 0xcd, 0x43, 0x6b, 0x4c,
0xcf, 0x7c, 0x2a, 0x5b, 0x59, 0xb7, 0x2f, 0xce, 0xfa, 0xf3, 0x70, 0x97, 0xc3, 0x18, 0x15, 0xe3,
0x25, 0x1a, 0x95, 0x88, 0xa0, 0x9b, 0xda, 0x97, 0x11, 0x95, 0x08, 0x35, 0xc5, 0x95, 0x59, 0x54,
0xa1, 0xa6, 0xa8, 0x2d, 0x26, 0x0f, 0xd0, 0x52, 0xfa, 0x00, 0xfd, 0x08, 0xd6, 0xf1, 0x00, 0x15,
0xac, 0xd9, 0x4a, 0xec, 0xe4, 0x55, 0x8e, 0x15, 0x9d, 0xd4, 0xc4, 0xde, 0x26, 0xeb, 0x81, 0x64,
0x4b, 0x81, 0xf3, 0x13, 0x64, 0x64, 0x39, 0x93, 0xf5, 0x4c, 0x14, 0x3e, 0x70, 0x7e, 0x42, 0x19,
0x25, 0x8f, 0xd5, 0xd1, 0x29, 0xc5, 0xad, 0x9d, 0xa9, 0xe3, 0x26, 0x29, 0xed, 0xcb, 0x38, 0x65,
0x55, 0x50, 0xda, 0x97, 0x3a, 0xe5, 0x23, 0xd8, 0x98, 0xd2, 0xb1, 0x63, 0xc7, 0x8b, 0xb5, 0x22,
0xc1, 0x6d, 0x15, 0xd1, 0x5a, 0x9e, 0x01, 0x2a, 0xee, 0x6c, 0x34, 0x7e, 0xe2, 0x4d, 0x4f, 0x1c,
0x94, 0x59, 0x30, 0x7a, 0xa8, 0x68, 0x2e, 0xba, 0xf3, 0xe9, 0x2f, 0x71, 0x30, 0xcb, 0x12, 0x18,
0x0d, 0xa8, 0x0d, 0x42, 0x6f, 0x26, 0xa7, 0x79, 0x11, 0xea, 0x98, 0x14, 0xf7, 0x9d, 0x6f, 0xc1,
0x4d, 0xce, 0x12, 0x86, 0xde, 0xcc, 0x9b, 0x78, 0x67, 0x57, 0x31, 0x3b, 0xde, 0xbf, 0xce, 0xc1,
0x4a, 0x0c, 0x2b, 0xd8, 0xeb, 0x47, 0xc8, 0xcf, 0xd4, 0x6d, 0xcd, 0x5c, 0xec, 0xaa, 0x0e, 0x9b,
0x2f, 0x24, 0x44, 0x66, 0x26, 0x6f, 0x70, 0xb6, 0xa3, 0x87, 0x59, 0x64, 0x46, 0x64, 0x29, 0xad,
0x34, 0x4b, 0x11, 0xf9, 0xe5, 0x93, 0x2d, 0xb2, 0x88, 0x5f, 0x10, 0x37, 0xab, 0xc6, 0xa2, 0xcb,
0x85, 0xf8, 0xdd, 0x0b, 0xdd, 0xe6, 0x27, 0x5b, 0x10, 0x19, 0x02, 0x03, 0xe3, 0xef, 0xe5, 0x00,
0xa2, 0xd6, 0xf1, 0xdb, 0x1f, 0x4a, 0x6e, 0xc9, 0xf1, 0xc0, 0x5d, 0x4d, 0x46, 0x79, 0x03, 0xea,
0x2a, 0xc6, 0x3b, 0x92, 0x84, 0x6a, 0x12, 0xc6, 0xc4, 0xa1, 0x77, 0x60, 0xe9, 0x6c, 0xe2, 0x9d,
0x70, 0x89, 0x55, 0xc8, 0x2d, 0x18, 0x3d, 0xb7, 0x88, 0x60, 0x29, 0x8d, 0x44, 0x72, 0x53, 0x31,
0x33, 0x0c, 0x5c, 0x97, 0x82, 0x8c, 0xbf, 0x92, 0x57, 0x81, 0xa4, 0xd1, 0x48, 0xbc, 0x58, 0xbd,
0xfb, 0x69, 0x42, 0x6d, 0x5e, 0xe4, 0x5e, 0x7c, 0x0c, 0x8b, 0x3e, 0x1e, 0x4a, 0xf2, 0xc4, 0x2a,
0xbe, 0xe0, 0xc4, 0x6a, 0xf8, 0x31, 0x49, 0xe7, 0xbb, 0xd0, 0xb4, 0xc7, 0x17, 0xd4, 0x0f, 0x1d,
0x6e, 0xad, 0xe7, 0xf2, 0xb1, 0x08, 0xdd, 0xd4, 0xe0, 0x5c, 0x10, 0x7d, 0x07, 0x96, 0xc4, 0x1d,
0x7c, 0x45, 0x29, 0x5e, 0x00, 0x8b, 0xc0, 0x8c, 0xd0, 0xf8, 0x47, 0x32, 0x72, 0x35, 0x3e, 0xbb,
0x2f, 0x1e, 0x15, 0xbd, 0x87, 0xf9, 0xb4, 0x03, 0x55, 0x2c, 0x24, 0xe1, 0x04, 0x10, 0xfc, 0x08,
0x81, 0xc2, 0x05, 0x10, 0x1f, 0xd6, 0xe2, 0xab, 0x0c, 0xab, 0xf1, 0x6f, 0x72, 0x50, 0xde, 0xf7,
0x66, 0xfb, 0x0e, 0xde, 0x7f, 0xe0, 0xdb, 0x44, 0xf9, 0xa8, 0x16, 0x58, 0x92, 0xc7, 0x05, 0xbd,
0xe0, 0x16, 0x63, 0xa6, 0x98, 0xd7, 0x88, 0x8b, 0x79, 0x9f, 0xc3, 0x2d, 0xee, 0x02, 0xf4, 0xbd,
0x99, 0xe7, 0xb3, 0xad, 0x6a, 0x4f, 0x50, 0xdc, 0xf3, 0xdc, 0xf0, 0x5c, 0xf2, 0xce, 0x9b, 0xa7,
0x94, 0x1e, 0x69, 0x14, 0x87, 0x8a, 0x80, 0xdf, 0x60, 0x9e, 0x84, 0x17, 0x16, 0x6a, 0xe8, 0x42,
0x1e, 0x45, 0x8e, 0xba, 0xc4, 0x10, 0x1d, 0x0e, 0xe7, 0x12, 0xa9, 0xf1, 0x29, 0x54, 0x95, 0xb1,
0x87, 0xbc, 0x0b, 0xd5, 0x73, 0x6f, 0x26, 0x2c, 0x42, 0xb9, 0xd8, 0x4d, 0x4f, 0xd1, 0x6b, 0xb3,
0x72, 0x8e, 0x3f, 0x02, 0xe3, 0x0f, 0xcb, 0x50, 0xee, 0xba, 0x17, 0x9e, 0x33, 0xe2, 0xb1, 0xaf,
0x53, 0x3a, 0xf5, 0xe4, 0x43, 0x20, 0xec, 0x37, 0x0f, 0xdd, 0x8a, 0xde, 0xf1, 0x2a, 0x88, 0xd0,
0x2d, 0xf5, 0x82, 0xd7, 0x1a, 0x2c, 0xf8, 0xfa, 0x43, 0x5c, 0x25, 0x9f, 0xdf, 0x18, 0x50, 0xe7,
0x65, 0x49, 0x7b, 0x5e, 0x85, 0x95, 0x85, 0x61, 0x89, 0x7c, 0xc8, 0xf0, 0x16, 0x72, 0x95, 0x43,
0xf8, 0x80, 0xbd, 0x06, 0x65, 0x71, 0xb1, 0x12, 0xaf, 0x79, 0x61, 0x88, 0xbf, 0x00, 0xf1, 0xd5,
0xe0, 0x53, 0x74, 0xe1, 0x2a, 0x41, 0xb6, 0x60, 0xd6, 0x25, 0x70, 0x97, 0xad, 0xb5, 0x3b, 0x50,
0x43, 0x7a, 0x24, 0xa9, 0x88, 0x90, 0x51, 0x0e, 0xe2, 0x04, 0x19, 0xef, 0xd9, 0x55, 0x33, 0xdf,
0xb3, 0xe3, 0xc1, 0xcd, 0x8a, 0xcb, 0x62, 0x17, 0x01, 0x5f, 0x31, 0xd3, 0xe0, 0xf2, 0x91, 0x48,
0x61, 0x53, 0xc1, 0x0b, 0xfa, 0xd2, 0xa6, 0xf2, 0x26, 0x34, 0x4e, 0xed, 0xc9, 0xe4, 0xc4, 0x1e,
0x3d, 0x43, 0x53, 0x40, 0x1d, 0xad, 0x9f, 0x12, 0xc8, 0x6d, 0x01, 0x77, 0xa0, 0xa6, 0xcd, 0x32,
0x8f, 0x07, 0x2d, 0x9a, 0x10, 0xcd, 0x6f, 0xd2, 0xc2, 0xb7, 0xf8, 0x0a, 0x16, 0x3e, 0x2d, 0x2e,
0x76, 0x29, 0x1e, 0x17, 0x7b, 0x8b, 0x73, 0x53, 0x11, 0x91, 0xd8, 0xc4, 0x27, 0xb3, 0xec, 0xf1,
0x98, 0x47, 0x24, 0x72, 0x43, 0x16, 0x0e, 0x1e, 0xe2, 0x97, 0x51, 0x97, 0x40, 0x18, 0x92, 0xdc,
0x46, 0x33, 0xf5, 0xcc, 0x76, 0xc6, 0xfc, 0x9a, 0x06, 0x5a, 0x0f, 0xca, 0xf6, 0x34, 0x3c, 0xb2,
0x9d, 0x31, 0xb9, 0x0b, 0x75, 0x89, 0xe6, 0xa7, 0xe3, 0x0a, 0x8e, 0xbf, 0x40, 0x0f, 0xf0, 0xf9,
0x09, 0x45, 0x31, 0x55, 0x37, 0xec, 0xcd, 0x9a, 0x20, 0xe1, 0xeb, 0xe0, 0x03, 0x1e, 0xe5, 0x13,
0x52, 0x7e, 0x87, 0x7e, 0xf1, 0xe1, 0x2d, 0x15, 0x7c, 0xc0, 0x57, 0xa9, 0xfc, 0x8f, 0xce, 0x31,
0xa4, 0x64, 0xc2, 0x1d, 0xfa, 0xe8, 0xd6, 0x63, 0xf2, 0xaf, 0x20, 0xe5, 0x3e, 0x3a, 0x24, 0x20,
0x9f, 0x6a, 0xfa, 0x6b, 0x8b, 0x13, 0xbf, 0x96, 0x28, 0xff, 0xba, 0x6b, 0x6c, 0xb7, 0x01, 0x9c,
0x80, 0x9d, 0x32, 0x01, 0x75, 0xc7, 0xfc, 0x2a, 0x7c, 0xc5, 0xac, 0x3a, 0xc1, 0x53, 0x04, 0x7c,
0xbb, 0x8a, 0x6d, 0x1b, 0xea, 0x7a, 0x37, 0x49, 0x05, 0x8a, 0xfd, 0xa3, 0x4e, 0xaf, 0x79, 0x83,
0xd4, 0xa0, 0x3c, 0xe8, 0x0c, 0x87, 0x07, 0xdc, 0xd3, 0x57, 0x87, 0x8a, 0xba, 0xe8, 0x9a, 0x67,
0xa9, 0xf6, 0xce, 0x4e, 0xe7, 0x68, 0xd8, 0xd9, 0x6d, 0x16, 0x7e, 0x54, 0xac, 0xe4, 0x9b, 0x05,
0xe3, 0x8f, 0x0a, 0x50, 0xd3, 0x46, 0xe1, 0xc5, 0xcc, 0xf8, 0x36, 0x00, 0xd7, 0x24, 0xa3, 0x80,
0xd5, 0xa2, 0x59, 0x65, 0x10, 0x9c, 0x7c, 0xdd, 0x47, 0x81, 0x6f, 0x91, 0x28, 0x1f, 0xc5, 0x9b,
0xd0, 0xc0, 0xd7, 0x42, 0x74, 0x7f, 0x6d, 0xc9, 0xac, 0x23, 0x50, 0xb0, 0x6a, 0x7e, 0x6d, 0x9e,
0x13, 0xf1, 0x0b, 0x89, 0xe2, 0x39, 0x23, 0x04, 0xf1, 0x2b, 0x89, 0xfc, 0x3e, 0x69, 0xe0, 0x4d,
0x2e, 0x28, 0x52, 0xa0, 0x44, 0x58, 0x13, 0xb0, 0xa1, 0x78, 0x92, 0x40, 0xf0, 0x43, 0xed, 0xde,
0x76, 0xc9, 0xac, 0x23, 0x50, 0x54, 0xf4, 0x3d, 0xb9, 0x80, 0x30, 0x7a, 0x65, 0x23, 0xbd, 0x1a,
0x62, 0x8b, 0xe7, 0x20, 0x65, 0x46, 0xac, 0xf2, 0x85, 0xf1, 0x9d, 0x74, 0xbe, 0x97, 0x9b, 0x13,
0xc9, 0xbb, 0x40, 0xa6, 0xb3, 0x99, 0x95, 0x61, 0xe0, 0x2b, 0x9a, 0x4b, 0xd3, 0xd9, 0x6c, 0xa8,
0xd9, 0xbf, 0xbe, 0x05, 0xdb, 0xe3, 0xd7, 0x40, 0xda, 0x6c, 0x03, 0xf3, 0x26, 0x2a, 0x55, 0x2c,
0x62, 0xcb, 0x39, 0x9d, 0x2d, 0x67, 0x70, 0xbf, 0x7c, 0x26, 0xf7, 0x7b, 0x11, 0x9f, 0x30, 0xf6,
0xa0, 0x76, 0xa4, 0x3d, 0x9a, 0x78, 0x97, 0x9d, 0x10, 0xf2, 0xb9, 0x44, 0x3c, 0x3b, 0xd0, 0xa6,
0xe8, 0x8b, 0x57, 0x12, 0xb5, 0xd6, 0xe4, 0xb5, 0xd6, 0x18, 0x7f, 0x27, 0x87, 0x8f, 0x4c, 0xa9,
0xc6, 0x47, 0xef, 0x34, 0x4a, 0xf7, 0x5b, 0xf4, 0xbc, 0x42, 0x4d, 0xba, 0xdd, 0xc4, 0xcb, 0x08,
0xbc, 0x69, 0x96, 0x77, 0x7a, 0x1a, 0x50, 0x19, 0xe3, 0x51, 0xe3, 0xb0, 0x3e, 0x07, 0x49, 0xe1,
0x9b, 0x49, 0xf8, 0x0e, 0x96, 0x1f, 0x88, 0xc0, 0x0e, 0x26, 0x7c, 0x1f, 0xda, 0x97, 0xa2, 0xd6,
0x80, 0x89, 0x20, 0xc2, 0x3f, 0x20, 0xaf, 0x17, 0xab, 0xb4, 0xf1, 0x37, 0xc5, 0x0b, 0x10, 0xc9,
0xf1, 0xbd, 0x0f, 0x15, 0x55, 0x6a, 0xfc, 0x84, 0x95, 0x94, 0x0a, 0xcf, 0xce, 0x71, 0x6e, 0x0c,
0x89, 0xb5, 0x18, 0x37, 0x17, 0xf7, 0xf1, 0x74, 0xb5, 0x56, 0xbf, 0x07, 0xe4, 0xd4, 0xf1, 0x93,
0xc4, 0xb8, 0xd9, 0x9a, 0x1c, 0xa3, 0x51, 0x1b, 0xc7, 0xb0, 0x22, 0xb9, 0x84, 0xa6, 0x11, 0xc4,
0x27, 0x2f, 0xf7, 0x12, 0x26, 0x9f, 0x4f, 0x31, 0x79, 0xe3, 0x37, 0x4a, 0x50, 0x96, 0x0f, 0x90,
0x66, 0x3d, 0x9a, 0x59, 0x8d, 0x3f, 0x9a, 0xd9, 0x8a, 0x3d, 0xa5, 0xc6, 0xa7, 0x5e, 0x9c, 0xf7,
0xef, 0x24, 0x8f, 0x6c, 0xcd, 0x57, 0x11, 0x3b, 0xb6, 0x85, 0xaf, 0xa2, 0x14, 0xf7, 0x55, 0x64,
0x3d, 0x24, 0x8a, 0xa2, 0x67, 0xea, 0x21, 0xd1, 0x5b, 0x80, 0x72, 0x84, 0x16, 0xdc, 0x56, 0xe1,
0x00, 0x71, 0x45, 0x5e, 0x13, 0x3b, 0x2a, 0x49, 0xb1, 0xe3, 0x95, 0x45, 0x82, 0x8f, 0x60, 0x01,
0x5f, 0x93, 0x11, 0xd7, 0xa5, 0xe5, 0xc1, 0x21, 0xc6, 0x4a, 0xfe, 0xc7, 0x0b, 0x11, 0xa6, 0xa0,
0xd5, 0x5f, 0xe5, 0xab, 0xc5, 0x5e, 0xe5, 0xd3, 0x7d, 0x28, 0xf5, 0xb8, 0x0f, 0xe5, 0x1e, 0x34,
0xd5, 0xc0, 0x71, 0x8b, 0xa4, 0x1b, 0x88, 0xbb, 0x96, 0x8b, 0x12, 0xce, 0xb8, 0x61, 0x2f, 0x88,
0x0e, 0xbe, 0xc5, 0xd8, 0xc1, 0xc7, 0x78, 0x55, 0x3b, 0x0c, 0xe9, 0x74, 0x16, 0xca, 0x83, 0x4f,
0x7b, 0xbb, 0x15, 0x67, 0x1e, 0x2f, 0x83, 0xc8, 0xe9, 0xc5, 0xd5, 0xb1, 0x0d, 0x8b, 0xa7, 0xb6,
0x33, 0x99, 0xfb, 0xd4, 0xf2, 0xa9, 0x1d, 0x78, 0x2e, 0xdf, 0xfc, 0xd1, 0x19, 0x2c, 0xba, 0xb8,
0x87, 0x34, 0x26, 0x27, 0x31, 0x1b, 0xa7, 0x7a, 0x92, 0x5f, 0xa9, 0xd2, 0x47, 0x82, 0x1d, 0x59,
0xe2, 0xd6, 0x35, 0xc6, 0xaa, 0x74, 0x7b, 0xd6, 0xde, 0x41, 0xf7, 0xc9, 0xfe, 0xb0, 0x99, 0x63,
0xc9, 0xc1, 0xf1, 0xce, 0x4e, 0xa7, 0xb3, 0xcb, 0x8f, 0x30, 0x80, 0x85, 0xbd, 0x76, 0xf7, 0x40,
0x1c, 0x60, 0xc5, 0x66, 0xc9, 0xf8, 0x67, 0x79, 0xa8, 0x69, 0xbd, 0x21, 0x8f, 0xd4, 0x24, 0xe0,
0x33, 0x0d, 0xb7, 0xd3, 0x3d, 0xde, 0x92, 0x1c, 0x5e, 0x9b, 0x05, 0xf5, 0x4a, 0x6b, 0xfe, 0xda,
0x57, 0x5a, 0xc9, 0xdb, 0xb0, 0x64, 0x63, 0x09, 0x6a, 0xd0, 0x85, 0x71, 0x5f, 0x80, 0xc5, 0x98,
0xbf, 0x2d, 0x9e, 0x8c, 0x10, 0xc7, 0x14, 0xa3, 0x2b, 0xca, 0xa0, 0x4d, 0x75, 0x52, 0xf1, 0xb9,
0x29, 0x8b, 0x91, 0x11, 0xce, 0x78, 0x75, 0xe0, 0x8b, 0xf1, 0x92, 0x68, 0xbc, 0x67, 0xa9, 0xad,
0xf0, 0xba, 0xa9, 0xd2, 0xc6, 0xc7, 0x00, 0x51, 0x7f, 0xe2, 0xc3, 0x77, 0x23, 0x3e, 0x7c, 0x39,
0x6d, 0xf8, 0xf2, 0xc6, 0x3f, 0x14, 0xac, 0x4b, 0xcc, 0x85, 0x32, 0xf5, 0x7d, 0x0f, 0xa4, 0xf1,
0xd1, 0xe2, 0x41, 0xde, 0xb3, 0x09, 0x0d, 0xe5, 0x55, 0xd1, 0x65, 0x81, 0xe9, 0x2a, 0x44, 0x8a,
0xd5, 0xe6, 0xd3, 0xac, 0xf6, 0x0d, 0xa8, 0xf3, 0x37, 0xc8, 0x44, 0x45, 0x82, 0x5d, 0xd5, 0xa6,
0xf6, 0xa5, 0xac, 0x3b, 0xc6, 0x63, 0x8b, 0x09, 0x1e, 0xfb, 0xb7, 0x72, 0xf8, 0x60, 0x4d, 0xd4,
0xd0, 0x88, 0xc9, 0xaa, 0x32, 0xe3, 0x4c, 0x56, 0x90, 0x9a, 0x0a, 0x7f, 0x0d, 0xe3, 0xcc, 0x67,
0x33, 0xce, 0x6c, 0x96, 0x5c, 0xc8, 0x64, 0xc9, 0xc6, 0x26, 0xb4, 0x76, 0x29, 0x1b, 0x8a, 0xf6,
0x64, 0x92, 0x18, 0x4b, 0xe3, 0x16, 0xdc, 0xcc, 0xc0, 0x09, 0xab, 0xcd, 0x6f, 0xe6, 0x60, 0xad,
0x8d, 0xef, 0x54, 0x7c, 0x6b, 0x77, 0x39, 0x3f, 0x83, 0x9b, 0x2a, 0x62, 0x5b, 0xbb, 0x22, 0xa6,
0x3f, 0x32, 0x24, 0x83, 0xbd, 0xb5, 0x7b, 0x0a, 0xec, 0xcc, 0x34, 0x5a, 0xb0, 0x9e, 0x6c, 0x8d,
0x68, 0xe8, 0x1e, 0x2c, 0xef, 0xd2, 0x93, 0xf9, 0xd9, 0x01, 0xbd, 0x88, 0xda, 0x48, 0xa0, 0x18,
0x9c, 0x7b, 0xcf, 0xc5, 0xc2, 0xe0, 0xbf, 0x79, 0x48, 0x27, 0xa3, 0xb1, 0x82, 0x19, 0x1d, 0x49,
0xab, 0x3f, 0x87, 0x0c, 0x66, 0x74, 0x64, 0x3c, 0x02, 0xa2, 0x97, 0x23, 0x66, 0x91, 0xa9, 0x64,
0xf3, 0x13, 0x2b, 0xb8, 0x0a, 0x42, 0x3a, 0x95, 0xd7, 0x1f, 0x21, 0x98, 0x9f, 0x0c, 0x10, 0x62,
0xbc, 0x03, 0xf5, 0x23, 0xfb, 0xca, 0xa4, 0x5f, 0x8b, 0x5b, 0x86, 0x1b, 0x50, 0x9e, 0xd9, 0x57,
0x8c, 0x17, 0x2b, 0x07, 0x20, 0x47, 0x1b, 0xff, 0xb8, 0x08, 0x0b, 0x48, 0x49, 0xee, 0xe2, 0xfb,
0xe9, 0x8e, 0xcb, 0x79, 0xa1, 0x3c, 0x95, 0x34, 0x50, 0xea, 0xe0, 0xca, 0xa7, 0x0f, 0x2e, 0x61,
0xad, 0x94, 0x8f, 0xa0, 0x49, 0x57, 0x8d, 0x3b, 0x9f, 0xca, 0x97, 0xcf, 0xe2, 0xef, 0x3c, 0x14,
0xa3, 0x77, 0xf7, 0xf1, 0x8e, 0x7b, 0xdc, 0x99, 0x1e, 0x29, 0x7e, 0xd8, 0x3a, 0x79, 0x1e, 0x8b,
0x33, 0x4b, 0x07, 0x65, 0x6a, 0x97, 0x65, 0x79, 0x75, 0x36, 0xae, 0x5d, 0xa6, 0xb4, 0xc8, 0xca,
0xcb, 0xb5, 0x48, 0x34, 0x63, 0xbe, 0x40, 0x8b, 0x84, 0x57, 0xd0, 0x22, 0x5f, 0xc1, 0x91, 0x7d,
0x13, 0x2a, 0x5c, 0xc8, 0xd2, 0x8e, 0x30, 0x26, 0x5c, 0xb1, 0x23, 0xec, 0x13, 0x4d, 0xcf, 0xc2,
0x28, 0x1a, 0xed, 0x0c, 0x31, 0xe9, 0xd7, 0x3f, 0x1f, 0x07, 0xe1, 0x57, 0x50, 0x16, 0x50, 0xb6,
0xa0, 0x5d, 0x7b, 0x2a, 0x9f, 0xd3, 0xe4, 0xbf, 0xd9, 0xb0, 0xf1, 0xc7, 0xef, 0xbe, 0x9e, 0x3b,
0x3e, 0x1d, 0xcb, 0x27, 0xb8, 0x1c, 0xbe, 0xbf, 0x19, 0x84, 0x75, 0x90, 0xe9, 0x7c, 0xae, 0xf7,
0xdc, 0x15, 0x7c, 0xab, 0xec, 0x04, 0x4f, 0x59, 0xd2, 0x20, 0xd0, 0xe4, 0x8f, 0xef, 0xce, 0x3c,
0x5f, 0x4a, 0x08, 0xc6, 0xef, 0xe6, 0xa0, 0x29, 0x76, 0x97, 0xc2, 0xe9, 0x2a, 0x57, 0xe9, 0xba,
0xa0, 0x8f, 0x17, 0x3f, 0xa8, 0x65, 0x40, 0x83, 0x5b, 0x9a, 0x94, 0xb8, 0x80, 0x96, 0xb2, 0x1a,
0x03, 0xee, 0x09, 0x91, 0xe1, 0x75, 0xa8, 0xc9, 0x80, 0xf3, 0xa9, 0x33, 0x91, 0x9f, 0xd8, 0xc0,
0x88, 0xf3, 0x43, 0x67, 0x22, 0xa5, 0x0d, 0xdf, 0x16, 0x57, 0xb9, 0x73, 0x5c, 0xda, 0x30, 0xed,
0x90, 0x1a, 0xff, 0x34, 0x07, 0xcb, 0x5a, 0x57, 0xc4, 0xbe, 0xfd, 0x3e, 0xd4, 0xd5, 0xab, 0xd7,
0x54, 0x89, 0xb9, 0x1b, 0x71, 0x1e, 0x15, 0x65, 0xab, 0x8d, 0x14, 0x24, 0x60, 0x8d, 0x19, 0xdb,
0x57, 0x18, 0x15, 0x3d, 0x9f, 0x4a, 0x4d, 0x72, 0x6c, 0x5f, 0xed, 0x51, 0x3a, 0x98, 0x4f, 0xc9,
0x5d, 0xa8, 0x3f, 0xa7, 0xf4, 0x99, 0x22, 0x40, 0xd6, 0x0b, 0x0c, 0x26, 0x28, 0x0c, 0x68, 0x4c,
0x3d, 0x37, 0x3c, 0x57, 0x24, 0x42, 0xc4, 0xe7, 0x40, 0xa4, 0x31, 0xfe, 0x20, 0x0f, 0x2b, 0x68,
0xcf, 0x14, 0x76, 0x64, 0xc1, 0xba, 0x5a, 0xb0, 0x80, 0xa6, 0x5d, 0x64, 0x5e, 0xfb, 0x37, 0x4c,
0x91, 0x26, 0x1f, 0xbd, 0xa2, 0x0d, 0x56, 0xde, 0x16, 0xbf, 0x66, 0xf8, 0x0b, 0xe9, 0xe1, 0xbf,
0x7e, 0x78, 0xb3, 0xbc, 0xca, 0xa5, 0x2c, 0xaf, 0xf2, 0xab, 0xf8, 0x72, 0x53, 0xf7, 0x9a, 0xcb,
0xe9, 0xd7, 0x3b, 0x1f, 0xc1, 0x46, 0x8c, 0x86, 0x73, 0x6b, 0xe7, 0xd4, 0xa1, 0xf2, 0x7d, 0xa0,
0x55, 0x8d, 0x7a, 0x20, 0x71, 0xdb, 0x65, 0x28, 0x05, 0x23, 0x6f, 0x46, 0x8d, 0x75, 0x58, 0x8d,
0x8f, 0xaa, 0x38, 0x26, 0x7e, 0x3b, 0x07, 0x2d, 0x11, 0x03, 0xe4, 0xb8, 0x67, 0xfb, 0x4e, 0x10,
0x7a, 0xbe, 0x7a, 0x1d, 0xfa, 0x36, 0x00, 0x7e, 0xee, 0x83, 0x2b, 0xee, 0xe2, 0x45, 0x1c, 0x0e,
0xe1, 0x6a, 0xfb, 0x4d, 0xa8, 0x50, 0x77, 0x8c, 0x48, 0x5c, 0x0d, 0x65, 0xea, 0x8e, 0xa5, 0xd2,
0x9f, 0x3a, 0x86, 0x1b, 0x71, 0x01, 0x43, 0xbc, 0xed, 0xc0, 0x46, 0x87, 0x5e, 0x70, 0x71, 0xa0,
0xa8, 0xde, 0x76, 0x38, 0xb4, 0x2f, 0x79, 0x44, 0x6d, 0x60, 0xfc, 0xd5, 0x3c, 0x2c, 0x45, 0xed,
0xc3, 0xd7, 0x6d, 0x5e, 0xfc, 0x4e, 0xcf, 0x5d, 0xb1, 0x1c, 0x1c, 0xa6, 0x2c, 0x69, 0x56, 0xde,
0x0a, 0x6e, 0xce, 0xae, 0x4b, 0x0c, 0xa8, 0x49, 0x0a, 0x6f, 0x1e, 0x6a, 0x2f, 0x8e, 0x56, 0x91,
0xa4, 0x3f, 0x0f, 0x99, 0x76, 0xcb, 0xd4, 0x7c, 0xc7, 0x15, 0xfa, 0x65, 0xc9, 0x9e, 0x86, 0x5d,
0xfe, 0x4d, 0x19, 0x06, 0x66, 0xd9, 0x70, 0x22, 0x19, 0x15, 0xa3, 0x6f, 0xa2, 0xb2, 0x83, 0x33,
0xc7, 0x15, 0x1d, 0x5d, 0x13, 0xc0, 0x67, 0xf0, 0x95, 0x26, 0xf0, 0x3a, 0xd4, 0xb0, 0xf0, 0xe8,
0x1a, 0x3b, 0x7f, 0xfe, 0x2b, 0xec, 0xba, 0x1c, 0x2f, 0x2c, 0x6e, 0xde, 0x3c, 0x66, 0x67, 0x00,
0xac, 0x8a, 0x87, 0xd8, 0xfc, 0x66, 0x0e, 0x6e, 0x66, 0x4c, 0x9b, 0xd8, 0xe5, 0x3b, 0xb0, 0x7c,
0xaa, 0x90, 0x72, 0x74, 0x71, 0xab, 0xaf, 0x4b, 0xb6, 0x1a, 0x1f, 0x53, 0xb3, 0x79, 0x1a, 0x07,
0x44, 0x1a, 0x2e, 0xce, 0x60, 0xec, 0x91, 0x04, 0x2e, 0x4e, 0xe1, 0x34, 0xa2, 0x72, 0x79, 0x04,
0x9b, 0x9d, 0x4b, 0xc6, 0x31, 0x54, 0x58, 0xee, 0xe8, 0xd9, 0x5c, 0x7a, 0xbe, 0x12, 0xd6, 0xfc,
0xdc, 0x2b, 0x59, 0xf3, 0xc7, 0x78, 0xcd, 0x59, 0x95, 0xf5, 0xd3, 0x14, 0xc2, 0x0f, 0x50, 0x96,
0xe7, 0x84, 0x17, 0x21, 0x5f, 0x4b, 0x60, 0x20, 0x2c, 0xd4, 0x08, 0x60, 0xe9, 0x70, 0x3e, 0x09,
0x9d, 0x1d, 0x05, 0x22, 0x1f, 0x89, 0x3c, 0xbc, 0x1e, 0x39, 0x6a, 0x99, 0x15, 0x81, 0xaa, 0x88,
0x0f, 0xd6, 0x94, 0x15, 0x64, 0xa5, 0xeb, 0x5b, 0x9a, 0xc6, 0x6b, 0x30, 0x6e, 0xc2, 0x46, 0x94,
0xc2, 0x61, 0x93, 0x47, 0xcd, 0xdf, 0xce, 0x61, 0xf8, 0x3e, 0xe2, 0x06, 0xae, 0x3d, 0x0b, 0xce,
0xbd, 0x90, 0x74, 0x60, 0x25, 0x70, 0xdc, 0xb3, 0x09, 0xd5, 0x8b, 0x0f, 0xc4, 0x20, 0xac, 0xc5,
0xdb, 0x86, 0x59, 0x03, 0x73, 0x19, 0x73, 0x44, 0xa5, 0x05, 0x64, 0xfb, 0xba, 0x46, 0x46, 0xcb,
0x22, 0x31, 0x1a, 0xe9, 0xc6, 0x77, 0x61, 0x31, 0x5e, 0x11, 0xf9, 0x44, 0xbc, 0x0e, 0x10, 0xb5,
0xaa, 0x90, 0xb8, 0x1b, 0x1d, 0x2d, 0x88, 0x5a, 0x34, 0xf6, 0x81, 0xf1, 0x97, 0x73, 0xd0, 0x32,
0x29, 0x5b, 0xb9, 0x5a, 0x2b, 0xe5, 0x9a, 0xf9, 0x7e, 0xaa, 0xd4, 0xeb, 0xfb, 0x2a, 0x1f, 0x1d,
0x90, 0x2d, 0x7a, 0xef, 0xda, 0xc9, 0xd8, 0xbf, 0x91, 0xea, 0xd1, 0x76, 0x05, 0x16, 0x90, 0xc4,
0xd8, 0x80, 0x35, 0xd1, 0x1e, 0xd9, 0x96, 0xc8, 0x55, 0x1b, 0xab, 0x31, 0xe6, 0xaa, 0xdd, 0x84,
0x16, 0xde, 0xf3, 0xd5, 0x3b, 0x21, 0x32, 0xee, 0x02, 0x39, 0xb4, 0x47, 0xb6, 0xef, 0x79, 0xee,
0x11, 0xf5, 0x45, 0x30, 0x34, 0x97, 0x30, 0xb9, 0x27, 0x53, 0x8a, 0xc2, 0x98, 0x92, 0xef, 0x2c,
0x7b, 0xae, 0x8c, 0xfd, 0xc2, 0x94, 0xe1, 0xc3, 0xca, 0xb6, 0xfd, 0x8c, 0xca, 0x92, 0xe4, 0x10,
0x3d, 0x86, 0xda, 0x4c, 0x15, 0x2a, 0xc7, 0x5d, 0x3e, 0x96, 0x92, 0xae, 0xd6, 0xd4, 0xa9, 0x19,
0x0b, 0xf2, 0x3d, 0x2f, 0xe4, 0x0f, 0x13, 0x48, 0x67, 0x98, 0x59, 0x65, 0xa0, 0xa7, 0xf4, 0xaa,
0x3b, 0x36, 0x1e, 0xc2, 0x6a, 0xbc, 0x4e, 0xc1, 0x5a, 0x36, 0xa1, 0x32, 0x15, 0x30, 0xd1, 0x7a,
0x95, 0x66, 0xca, 0x08, 0x53, 0xf9, 0x64, 0x9e, 0xee, 0xae, 0x52, 0xa9, 0x1e, 0xc3, 0x46, 0x0a,
0x23, 0x0a, 0xbc, 0x0b, 0x75, 0xad, 0x21, 0xd8, 0x8d, 0x22, 0x13, 0x59, 0x45, 0x4b, 0x02, 0xe3,
0x33, 0xd8, 0x40, 0x7d, 0x2c, 0xca, 0x2e, 0x87, 0x20, 0xd1, 0x8b, 0x5c, 0xb2, 0x17, 0x1f, 0x49,
0x35, 0x4f, 0xcf, 0x1a, 0x5d, 0x15, 0x18, 0x73, 0x9c, 0x0c, 0xdf, 0x91, 0x49, 0xe3, 0x18, 0xd6,
0xd3, 0xc3, 0xc7, 0xda, 0xff, 0x33, 0x0d, 0xb9, 0x1c, 0x9e, 0x08, 0xad, 0x86, 0xe7, 0xbf, 0xe6,
0x70, 0x7c, 0x62, 0x28, 0xd1, 0xcc, 0x31, 0x90, 0x29, 0x0d, 0xcf, 0xbd, 0xb1, 0x95, 0xae, 0xf9,
0x91, 0x8a, 0x1e, 0xca, 0xcc, 0xbb, 0x75, 0xc8, 0x33, 0x6a, 0x18, 0x11, 0xc7, 0x3e, 0x4d, 0xc2,
0x37, 0x47, 0xb0, 0x9e, 0x4d, 0x9c, 0x11, 0x73, 0xf3, 0x61, 0x5c, 0x50, 0xbf, 0x7d, 0x6d, 0xf7,
0x59, 0xb3, 0x74, 0xb9, 0xfd, 0xb7, 0x2a, 0x50, 0x16, 0x56, 0x12, 0xb2, 0x05, 0xc5, 0x91, 0x8c,
0xdf, 0x8c, 0x1e, 0xa2, 0x13, 0x58, 0xf9, 0x7f, 0x87, 0x47, 0x71, 0x32, 0x3a, 0xf2, 0x18, 0x16,
0xe3, 0x21, 0x0c, 0x89, 0x47, 0x2a, 0xe2, 0xb1, 0x07, 0x8d, 0x51, 0xc2, 0x59, 0x5d, 0x8d, 0x84,
0x2b, 0x94, 0x39, 0x2b, 0xe7, 0x9a, 0xf4, 0xe5, 0xb9, 0x4c, 0x5f, 0x0b, 0xce, 0x6d, 0xeb, 0xe1,
0xa3, 0x8f, 0xc5, 0x2b, 0x15, 0x35, 0x0e, 0x1c, 0x9c, 0xdb, 0x0f, 0x1f, 0x7d, 0x9c, 0xd4, 0xc4,
0xc4, 0x1b, 0x15, 0x9a, 0x26, 0xb6, 0x0a, 0x25, 0x7c, 0x8c, 0x1a, 0x03, 0xf1, 0x30, 0x41, 0x1e,
0xc0, 0xaa, 0x34, 0xbc, 0x89, 0x2b, 0x13, 0x78, 0x8a, 0x56, 0xf0, 0x96, 0xaa, 0xc0, 0x0d, 0x38,
0x0a, 0x4d, 0x75, 0xeb, 0xb0, 0x70, 0x1e, 0xbd, 0x2e, 0xde, 0x30, 0x45, 0xca, 0xf8, 0x83, 0x12,
0xd4, 0xb4, 0x41, 0x21, 0x75, 0xa8, 0x98, 0x9d, 0x41, 0xc7, 0xfc, 0xa2, 0xb3, 0xdb, 0xbc, 0x41,
0xee, 0xc1, 0x5b, 0xdd, 0xde, 0x4e, 0xdf, 0x34, 0x3b, 0x3b, 0x43, 0xab, 0x6f, 0x5a, 0xf2, 0x39,
0xc4, 0xa3, 0xf6, 0x57, 0x87, 0x9d, 0xde, 0xd0, 0xda, 0xed, 0x0c, 0xdb, 0xdd, 0x83, 0x41, 0x33,
0x47, 0x5e, 0x83, 0x56, 0x44, 0x29, 0xd1, 0xed, 0xc3, 0xfe, 0x71, 0x6f, 0xd8, 0xcc, 0x93, 0x3b,
0x70, 0x6b, 0xaf, 0xdb, 0x6b, 0x1f, 0x58, 0x11, 0xcd, 0xce, 0xc1, 0xf0, 0x0b, 0xab, 0xf3, 0x8b,
0x47, 0x5d, 0xf3, 0xab, 0x66, 0x21, 0x8b, 0x60, 0x7f, 0x78, 0xb0, 0x23, 0x4b, 0x28, 0x92, 0x9b,
0xb0, 0x86, 0x04, 0x98, 0xc5, 0x1a, 0xf6, 0xfb, 0xd6, 0xa0, 0xdf, 0xef, 0x35, 0x4b, 0x64, 0x19,
0x1a, 0xdd, 0xde, 0x17, 0xed, 0x83, 0xee, 0xae, 0x65, 0x76, 0xda, 0x07, 0x87, 0xcd, 0x05, 0xb2,
0x02, 0x4b, 0x49, 0xba, 0x32, 0x2b, 0x42, 0xd2, 0xf5, 0x7b, 0xdd, 0x7e, 0xcf, 0xfa, 0xa2, 0x63,
0x0e, 0xba, 0xfd, 0x5e, 0xb3, 0x42, 0xd6, 0x81, 0xc4, 0x51, 0xfb, 0x87, 0xed, 0x9d, 0x66, 0x95,
0xac, 0xc1, 0x72, 0x1c, 0xfe, 0xb4, 0xf3, 0x55, 0x13, 0x48, 0x0b, 0x56, 0xb1, 0x61, 0xd6, 0x76,
0xe7, 0xa0, 0xff, 0xa5, 0x75, 0xd8, 0xed, 0x75, 0x0f, 0x8f, 0x0f, 0x9b, 0x35, 0xfe, 0xa6, 0x6c,
0xa7, 0x63, 0x75, 0x7b, 0x83, 0xe3, 0xbd, 0xbd, 0xee, 0x4e, 0xb7, 0xd3, 0x1b, 0x36, 0xeb, 0x58,
0x73, 0x56, 0xc7, 0x1b, 0x2c, 0x83, 0xb8, 0x57, 0x65, 0xed, 0x76, 0x07, 0xed, 0xed, 0x83, 0xce,
0x6e, 0x73, 0x91, 0xdc, 0x86, 0x9b, 0xc3, 0xce, 0xe1, 0x51, 0xdf, 0x6c, 0x9b, 0x5f, 0xc9, 0x7b,
0x57, 0xd6, 0x5e, 0xbb, 0x7b, 0x70, 0x6c, 0x76, 0x9a, 0x4b, 0xe4, 0x0d, 0xb8, 0x6d, 0x76, 0x7e,
0x7c, 0xdc, 0x35, 0x3b, 0xbb, 0x56, 0xaf, 0xbf, 0xdb, 0xb1, 0xf6, 0x3a, 0xed, 0xe1, 0xb1, 0xd9,
0xb1, 0x0e, 0xbb, 0x83, 0x41, 0xb7, 0xf7, 0xa4, 0xd9, 0x24, 0x6f, 0xc1, 0x5d, 0x45, 0xa2, 0x0a,
0x48, 0x50, 0x2d, 0xb3, 0xfe, 0xc9, 0x29, 0xed, 0x75, 0x7e, 0x71, 0x68, 0x1d, 0x75, 0x3a, 0x66,
0x93, 0x90, 0x4d, 0x58, 0x8f, 0xaa, 0xc7, 0x0a, 0x44, 0xdd, 0x2b, 0x0c, 0x77, 0xd4, 0x31, 0x0f,
0xdb, 0x3d, 0x36, 0xc1, 0x31, 0xdc, 0x2a, 0x6b, 0x76, 0x84, 0x4b, 0x36, 0x7b, 0x8d, 0x10, 0x58,
0xd4, 0x66, 0x65, 0xaf, 0x6d, 0x36, 0xd7, 0xc9, 0x12, 0xd4, 0x0e, 0x8f, 0x8e, 0xac, 0x61, 0xf7,
0xb0, 0xd3, 0x3f, 0x1e, 0x36, 0x37, 0xc8, 0x1a, 0x34, 0xbb, 0xbd, 0x61, 0xc7, 0x64, 0x73, 0x2d,
0xb3, 0xfe, 0xb7, 0x32, 0x59, 0x85, 0x25, 0xd9, 0x52, 0x09, 0xfd, 0xe3, 0x32, 0xd9, 0x00, 0x72,
0xdc, 0x33, 0x3b, 0xed, 0x5d, 0x36, 0x70, 0x0a, 0xf1, 0xdf, 0xcb, 0xc2, 0x9d, 0xf9, 0xbb, 0x05,
0x25, 0xec, 0x45, 0xf1, 0x41, 0xf1, 0x4f, 0x6e, 0xd4, 0xb5, 0x4f, 0x65, 0xbc, 0xec, 0xc3, 0x59,
0x9a, 0x6a, 0x5e, 0x48, 0xa9, 0xe6, 0x29, 0xdb, 0x4f, 0x43, 0xd7, 0x1d, 0xde, 0x84, 0xc6, 0x14,
0x3f, 0xbf, 0x21, 0xde, 0x96, 0x07, 0x11, 0x2c, 0x87, 0x40, 0x7c, 0x58, 0x3e, 0xf5, 0xe5, 0xa8,
0x52, 0xfa, 0xcb, 0x51, 0x59, 0xfa, 0xe1, 0x42, 0x96, 0x7e, 0x78, 0x1f, 0x96, 0x91, 0x35, 0x39,
0xae, 0x33, 0x95, 0x56, 0x17, 0xd4, 0x22, 0x96, 0x38, 0x8b, 0x42, 0xb8, 0x54, 0x47, 0xa5, 0xca,
0x2a, 0x58, 0x48, 0x59, 0x68, 0xab, 0x31, 0x4d, 0x15, 0x39, 0x87, 0xd2, 0x54, 0x55, 0x0d, 0xf6,
0x65, 0x54, 0x43, 0x4d, 0xab, 0x01, 0xe1, 0xbc, 0x86, 0xfb, 0xb0, 0x4c, 0x2f, 0x43, 0xdf, 0xb6,
0xbc, 0x99, 0xfd, 0xf5, 0x9c, 0xc7, 0x5b, 0xd8, 0xdc, 0x06, 0x54, 0x37, 0x97, 0x38, 0xa2, 0xcf,
0xe1, 0xbb, 0x76, 0x68, 0x1b, 0xbf, 0x02, 0xa0, 0x4e, 0xd5, 0x31, 0x63, 0x80, 0xae, 0x27, 0xaf,
0xdd, 0xd5, 0x4d, 0x4c, 0xf0, 0x79, 0x0c, 0x3d, 0xdf, 0x3e, 0xa3, 0x5d, 0xf9, 0xd2, 0x4b, 0x04,
0x20, 0xb7, 0xa0, 0xe0, 0xcd, 0x64, 0x28, 0x59, 0x55, 0x3e, 0x96, 0x3c, 0x33, 0x19, 0xd4, 0xf8,
0x18, 0xf2, 0xfd, 0xd9, 0xb5, 0xa2, 0x52, 0x0b, 0xca, 0xf2, 0x5b, 0x91, 0x79, 0x1e, 0x3e, 0x26,
0x93, 0xf7, 0xff, 0x2c, 0xd4, 0xb4, 0x2f, 0xc6, 0x90, 0x0d, 0x58, 0xf9, 0xb2, 0x3b, 0xec, 0x75,
0x06, 0x03, 0xeb, 0xe8, 0x78, 0xfb, 0x69, 0xe7, 0x2b, 0x6b, 0xbf, 0x3d, 0xd8, 0x6f, 0xde, 0x60,
0xbc, 0xa4, 0xd7, 0x19, 0x0c, 0x3b, 0xbb, 0x31, 0x78, 0x8e, 0xbc, 0x0e, 0x9b, 0xc7, 0xbd, 0xe3,
0x41, 0x67, 0xd7, 0xca, 0xca, 0x97, 0x67, 0x9b, 0x47, 0xe0, 0x33, 0xb2, 0x17, 0xee, 0xff, 0x2a,
0x2c, 0xc6, 0x5f, 0x46, 0x20, 0x00, 0x0b, 0x07, 0x9d, 0x27, 0xed, 0x9d, 0xaf, 0xf0, 0x31, 0xec,
0xc1, 0xb0, 0x3d, 0xec, 0xee, 0x58, 0xe2, 0xf1, 0x6b, 0xc6, 0xa8, 0x72, 0xa4, 0x06, 0xe5, 0x76,
0x6f, 0x67, 0xbf, 0x6f, 0x0e, 0x9a, 0x79, 0xf2, 0x1a, 0x6c, 0xc8, 0x2d, 0xb4, 0xd3, 0x3f, 0x3c,
0xec, 0x0e, 0x39, 0x8f, 0x1e, 0x7e, 0x75, 0xc4, 0x76, 0xcc, 0x7d, 0x1b, 0xaa, 0xd1, 0xbb, 0xdd,
0x9c, 0xef, 0x75, 0x87, 0xdd, 0xf6, 0x30, 0x62, 0xfa, 0xcd, 0x1b, 0x8c, 0xad, 0x46, 0x60, 0xfe,
0xf8, 0x76, 0x33, 0x87, 0x97, 0x47, 0x25, 0x10, 0x6b, 0x6f, 0xe6, 0xd9, 0x5e, 0x8f, 0xa0, 0xdb,
0xfd, 0x21, 0xeb, 0xc2, 0xaf, 0xc1, 0x62, 0xfc, 0x79, 0x6c, 0xd2, 0x84, 0x3a, 0xab, 0x5f, 0xab,
0x02, 0x60, 0x01, 0x5b, 0xdc, 0xcc, 0x21, 0x63, 0xdf, 0xe9, 0x1f, 0x76, 0x7b, 0x4f, 0xf8, 0x69,
0xd0, 0xcc, 0x33, 0x50, 0xff, 0x78, 0xf8, 0xa4, 0xaf, 0x40, 0x05, 0x96, 0x03, 0xbb, 0xd3, 0x2c,
0xde, 0xff, 0x1a, 0x96, 0x53, 0x0f, 0x69, 0xb3, 0x56, 0xf7, 0x8f, 0x87, 0x3b, 0xfd, 0x43, 0xbd,
0x9e, 0x1a, 0x94, 0x77, 0x0e, 0xda, 0xdd, 0x43, 0xee, 0x08, 0x69, 0x40, 0xf5, 0xb8, 0x27, 0x93,
0xf9, 0xf8, 0x13, 0xe0, 0x05, 0xc6, 0xa2, 0xf6, 0xba, 0xe6, 0x60, 0x68, 0x0d, 0x86, 0xed, 0x27,
0x9d, 0x66, 0x91, 0xe5, 0x95, 0xfc, 0xaa, 0x74, 0xff, 0x33, 0x58, 0x8c, 0xc7, 0x3d, 0xc7, 0x1d,
0x58, 0x9b, 0xb0, 0xbe, 0xdd, 0x19, 0x7e, 0xd9, 0xe9, 0xf4, 0xf8, 0x94, 0xef, 0x74, 0x7a, 0x43,
0xb3, 0x7d, 0xd0, 0x1d, 0x7e, 0xd5, 0xcc, 0xdd, 0x7f, 0x0c, 0xcd, 0x64, 0x90, 0x41, 0x2c, 0x2a,
0xe3, 0x45, 0xe1, 0x1b, 0xf7, 0xff, 0x53, 0x0e, 0x56, 0xb3, 0xfc, 0x6b, 0x6c, 0x61, 0x0a, 0x46,
0xc8, 0x8e, 0xc3, 0x41, 0xbf, 0x67, 0xf5, 0xfa, 0xfc, 0x51, 0xdd, 0x4d, 0x58, 0x4f, 0x20, 0x64,
0x2f, 0x72, 0xe4, 0x16, 0x6c, 0xa4, 0x32, 0x59, 0x66, 0xff, 0x98, 0xcf, 0x65, 0x0b, 0x56, 0x13,
0xc8, 0x8e, 0x69, 0xf6, 0xcd, 0x66, 0x81, 0xbc, 0x07, 0xf7, 0x12, 0x98, 0xb4, 0x10, 0x20, 0x65,
0x84, 0x22, 0x79, 0x07, 0xde, 0x4c, 0x51, 0x47, 0xe7, 0xa4, 0xb5, 0xdd, 0x3e, 0x60, 0xdd, 0x6b,
0x96, 0xee, 0xff, 0x83, 0x02, 0x40, 0x74, 0xb1, 0x90, 0xd5, 0xbf, 0xdb, 0x1e, 0xb6, 0x0f, 0xfa,
0x6c, 0xcf, 0x98, 0xfd, 0x21, 0x2b, 0xdd, 0xec, 0xfc, 0xb8, 0x79, 0x23, 0x13, 0xd3, 0x3f, 0x62,
0x1d, 0xda, 0x80, 0x15, 0x5c, 0x7f, 0x07, 0xac, 0x1b, 0x6c, 0xb9, 0xf0, 0xf7, 0x99, 0xb9, 0xa4,
0x71, 0x7c, 0xb4, 0x67, 0xf6, 0x7b, 0x43, 0x6b, 0xb0, 0x7f, 0x3c, 0xdc, 0xe5, 0xaf, 0x3b, 0xef,
0x98, 0xdd, 0x23, 0x2c, 0xb3, 0xf8, 0x22, 0x02, 0x56, 0x74, 0x89, 0x6d, 0xf0, 0x27, 0xfd, 0xc1,
0xa0, 0x7b, 0x64, 0xfd, 0xf8, 0xb8, 0x63, 0x76, 0x3b, 0x03, 0x9e, 0x71, 0x21, 0x03, 0xce, 0xe8,
0xcb, 0x6c, 0xcd, 0x0e, 0x0f, 0xbe, 0x10, 0x02, 0x04, 0x23, 0xad, 0xc4, 0x41, 0x8c, 0xaa, 0xca,
0x66, 0x87, 0x9d, 0xc0, 0x19, 0x25, 0xc3, 0x35, 0x38, 0x96, 0xaf, 0xc6, 0x64, 0x8b, 0xd4, 0xce,
0xe7, 0xd9, 0xea, 0xd9, 0x28, 0x96, 0x8b, 0x8b, 0x1d, 0x4a, 0x48, 0xdb, 0xdd, 0x35, 0x79, 0x86,
0xc5, 0x14, 0x94, 0xd1, 0x2e, 0xb1, 0x45, 0xc8, 0x8e, 0x68, 0x46, 0xd2, 0x94, 0x09, 0x86, 0x59,
0x7e, 0xf8, 0x2f, 0xdf, 0x80, 0xaa, 0xba, 0x60, 0x40, 0x7e, 0x04, 0x8d, 0xd8, 0x8d, 0x6f, 0x22,
0x4d, 0xf8, 0x59, 0x17, 0xc4, 0x37, 0x5f, 0xcb, 0x46, 0x0a, 0xe5, 0xe4, 0x50, 0xb3, 0x06, 0x60,
0x61, 0xaf, 0x25, 0x35, 0xf4, 0x58, 0x69, 0xb7, 0xaf, 0xc1, 0x8a, 0xe2, 0x9e, 0xf2, 0xa7, 0xa2,
0xf5, 0x0f, 0x0f, 0x93, 0xdb, 0xd1, 0xbb, 0xbd, 0x19, 0x1f, 0x24, 0xde, 0xbc, 0x99, 0xfe, 0x44,
0xb0, 0xfc, 0xa6, 0xf0, 0x2e, 0xd4, 0xb4, 0xef, 0xe9, 0x91, 0x9b, 0xd7, 0x7e, 0xfb, 0x6f, 0x73,
0x33, 0x0b, 0x25, 0x9a, 0xf4, 0x39, 0x54, 0xd5, 0xb7, 0xd5, 0xc8, 0x86, 0xf6, 0x5d, 0x3c, 0xfd,
0x0b, 0x71, 0x9b, 0xad, 0x34, 0x42, 0xe4, 0xdf, 0x85, 0x9a, 0xf6, 0x89, 0x34, 0xd5, 0x8a, 0xf4,
0x67, 0xd8, 0x54, 0x2b, 0xb2, 0xbe, 0xa8, 0x76, 0x00, 0x6b, 0xc2, 0xe6, 0x70, 0x42, 0xbf, 0xc9,
0xf0, 0x64, 0x7c, 0x41, 0xf9, 0x41, 0x8e, 0x3c, 0x86, 0x8a, 0xfc, 0x18, 0x1e, 0x59, 0xcf, 0xfe,
0xd4, 0xdf, 0xe6, 0x46, 0x0a, 0x2e, 0x9a, 0xd2, 0x06, 0x88, 0x3e, 0xbe, 0x46, 0x64, 0xc7, 0x53,
0x1f, 0x73, 0x53, 0x33, 0x93, 0xf1, 0xa5, 0xb6, 0x5d, 0xa8, 0x69, 0xdf, 0x59, 0x53, 0x63, 0x92,
0xfe, 0x46, 0x9b, 0x1a, 0x93, 0xac, 0xcf, 0xb2, 0xfd, 0x08, 0x1a, 0xb1, 0x0f, 0xa6, 0xa9, 0x75,
0x9c, 0xf5, 0x39, 0x36, 0xb5, 0x8e, 0xb3, 0xbf, 0xb1, 0xb6, 0x0b, 0x35, 0xed, 0xf3, 0x66, 0xaa,
0x45, 0xe9, 0x2f, 0xa9, 0xa9, 0x16, 0x65, 0x7c, 0x0d, 0x8d, 0xed, 0x86, 0xf8, 0xb7, 0xcd, 0xd4,
0x6e, 0xc8, 0xfc, 0x48, 0x9a, 0xda, 0x0d, 0xd9, 0x1f, 0x44, 0x63, 0x4b, 0x4f, 0xbd, 0x11, 0x4f,
0x36, 0x62, 0xaa, 0x7e, 0xf4, 0xd8, 0xbc, 0x5a, 0x7a, 0xe9, 0xe7, 0xe4, 0x9f, 0xc0, 0x8a, 0x5a,
0x34, 0xea, 0x85, 0xf7, 0x40, 0xb5, 0x29, 0xf3, 0x1d, 0xf9, 0xcd, 0x66, 0x12, 0xfb, 0x20, 0x47,
0x3e, 0x85, 0xb2, 0x78, 0x36, 0x9b, 0xac, 0x25, 0x9f, 0xd1, 0xc6, 0x46, 0xac, 0x67, 0xbf, 0xae,
0x4d, 0x8e, 0xf8, 0x86, 0xd6, 0xdf, 0xb5, 0xd6, 0x57, 0x6c, 0xc6, 0x53, 0xd8, 0x9b, 0xaf, 0x5f,
0x87, 0x8e, 0x4a, 0x4c, 0xbe, 0xc5, 0x7e, 0xfb, 0xba, 0x97, 0x58, 0xe2, 0x25, 0x5e, 0xf7, 0x64,
0xdc, 0x13, 0xa8, 0xeb, 0x5f, 0xd6, 0x21, 0xfa, 0x3e, 0x4c, 0x96, 0x75, 0x2b, 0x13, 0x27, 0x0a,
0xfa, 0x02, 0xd6, 0xd5, 0x78, 0xeb, 0xcf, 0x82, 0x04, 0xe4, 0x4e, 0xc6, 0x63, 0x21, 0xb1, 0x51,
0xbf, 0x79, 0xed, 0x6b, 0x22, 0x0f, 0x72, 0x9c, 0xc9, 0xc6, 0x3e, 0x86, 0x11, 0x31, 0xd9, 0xac,
0x6f, 0x80, 0x44, 0x4c, 0x36, 0xfb, 0x0b, 0x1a, 0x6d, 0x58, 0xd2, 0x9e, 0x35, 0x19, 0x5c, 0xb9,
0x23, 0xb5, 0xde, 0xd3, 0x0f, 0x0e, 0x6f, 0x66, 0x59, 0xbe, 0xc9, 0x0e, 0xd4, 0xf4, 0x97, 0x51,
0x5e, 0x90, 0x7d, 0x43, 0x43, 0xe9, 0x6f, 0xca, 0x3e, 0xc8, 0x91, 0x03, 0x68, 0x26, 0xdf, 0x31,
0x54, 0x5b, 0x38, 0xeb, 0xed, 0xc7, 0xcd, 0x04, 0x32, 0xf6, 0xfa, 0x21, 0x5b, 0x17, 0xb1, 0x2f,
0xf5, 0x7a, 0x7e, 0xf2, 0x28, 0x8a, 0x7f, 0xc1, 0x57, 0x95, 0x96, 0xf5, 0xed, 0xe6, 0x7b, 0xb9,
0x07, 0x39, 0xb2, 0x07, 0xf5, 0xd8, 0x33, 0x5e, 0xb1, 0xbb, 0x2e, 0x89, 0x6e, 0xb6, 0x74, 0x5c,
0xa2, 0x9f, 0x87, 0xb0, 0x18, 0x0f, 0xd1, 0x50, 0x0d, 0xcb, 0x8c, 0x23, 0x51, 0xd3, 0x97, 0x1d,
0xd7, 0x41, 0x7e, 0x80, 0xdf, 0xa1, 0x97, 0xa1, 0x7c, 0x24, 0xfd, 0xdd, 0x72, 0x35, 0x67, 0xfa,
0x57, 0xbe, 0x8d, 0xc2, 0x5f, 0xcc, 0xe7, 0x78, 0xbf, 0xbe, 0x8f, 0x5f, 0x81, 0x95, 0xd1, 0x5c,
0x6c, 0xfe, 0x5f, 0xb5, 0x10, 0xb2, 0x87, 0x95, 0x8b, 0x6f, 0x70, 0x47, 0x9c, 0x3b, 0xf5, 0x5d,
0xee, 0x97, 0xb4, 0xa1, 0x8d, 0x6d, 0x10, 0x79, 0x62, 0x6b, 0xf0, 0x15, 0xcb, 0x22, 0x9f, 0x00,
0x44, 0x21, 0xb2, 0x24, 0x11, 0xa8, 0xa9, 0x36, 0x54, 0x46, 0x14, 0x6d, 0x07, 0xf7, 0xbb, 0x8a,
0x14, 0xd5, 0x8f, 0xe4, 0x78, 0xd0, 0x6a, 0xec, 0x48, 0x4e, 0x16, 0xf3, 0x21, 0x34, 0x0e, 0x3c,
0xef, 0xd9, 0x7c, 0xa6, 0xee, 0x59, 0xc4, 0xc3, 0x98, 0xf6, 0xed, 0xe0, 0x7c, 0x33, 0xd1, 0x2c,
0xd2, 0x86, 0x65, 0xc5, 0x22, 0xa2, 0x50, 0xd5, 0x38, 0x51, 0x8c, 0x31, 0x24, 0x0a, 0x78, 0x90,
0x23, 0x0f, 0xa1, 0xbe, 0x4b, 0x47, 0xfc, 0x99, 0x0d, 0x1e, 0x34, 0xb3, 0x12, 0x0b, 0xc0, 0xc0,
0x68, 0x9b, 0xcd, 0x46, 0x0c, 0x28, 0x59, 0x5c, 0x14, 0xb8, 0xa5, 0x9f, 0x19, 0xf1, 0xe8, 0xa7,
0x18, 0x8b, 0x4b, 0x05, 0x6f, 0x7d, 0x01, 0xcb, 0xa9, 0xd0, 0x28, 0xc5, 0xdd, 0xae, 0x0b, 0xa8,
0xda, 0xbc, 0x7b, 0x3d, 0x81, 0x28, 0xf7, 0x87, 0xd0, 0xc0, 0x27, 0x86, 0x4f, 0x28, 0x5e, 0x93,
0x4d, 0xbc, 0x31, 0xa5, 0xdf, 0xc1, 0x4d, 0xb2, 0x24, 0xcc, 0xf0, 0x84, 0x7f, 0x78, 0x44, 0xbb,
0x84, 0xaa, 0xe6, 0x35, 0x7d, 0x31, 0x56, 0xcd, 0x6b, 0xd6, 0x7d, 0xd7, 0xcf, 0xa0, 0xf6, 0x84,
0x86, 0xf2, 0x5a, 0xa7, 0x92, 0x8f, 0x12, 0xf7, 0x3c, 0x37, 0x33, 0x2e, 0xe3, 0x92, 0x8f, 0x79,
0x56, 0xf5, 0x44, 0xc1, 0xba, 0x56, 0x8b, 0x9e, 0x75, 0x29, 0x01, 0x67, 0xd2, 0x87, 0xf6, 0x50,
0x89, 0x6a, 0x78, 0xfa, 0x61, 0x1a, 0xd5, 0xf0, 0xac, 0x77, 0x4d, 0x7e, 0x80, 0x23, 0xa0, 0x5d,
0x24, 0x8d, 0x44, 0xb0, 0xe4, 0x9d, 0x53, 0xd5, 0x7c, 0x9d, 0xfc, 0x11, 0xc0, 0x20, 0xf4, 0x66,
0xbb, 0x36, 0x9d, 0x7a, 0x6e, 0xc4, 0x13, 0xa2, 0x2b, 0x8c, 0xd1, 0x46, 0xd4, 0xee, 0x31, 0x92,
0x2f, 0x35, 0xd9, 0x34, 0x36, 0x25, 0x72, 0xda, 0xaf, 0xbd, 0xe5, 0xa8, 0xba, 0x93, 0x71, 0xd3,
0x91, 0x33, 0x09, 0x88, 0x22, 0xcf, 0x94, 0xa4, 0x99, 0x0a, 0x6a, 0x53, 0x7b, 0x3d, 0x23, 0x4c,
0xed, 0x73, 0xa8, 0x46, 0x21, 0x3b, 0x1b, 0xd1, 0xab, 0x49, 0xb1, 0x00, 0x1f, 0xc5, 0xbd, 0xd3,
0xe1, 0x32, 0x3d, 0x58, 0xc1, 0xe6, 0xa8, 0xe3, 0x8f, 0x5f, 0xb4, 0x53, 0xdf, 0xcd, 0x49, 0xc7,
0xa9, 0xa8, 0xfd, 0x93, 0x15, 0x6d, 0xc1, 0xf6, 0x4f, 0xca, 0x6b, 0xaf, 0xf6, 0xcf, 0x75, 0x61,
0x18, 0x6a, 0xff, 0x5c, 0xef, 0xf0, 0xef, 0xc1, 0x4a, 0x86, 0xff, 0x9d, 0xbc, 0x21, 0x15, 0x9b,
0x6b, 0x7d, 0xf3, 0x9b, 0x99, 0x7e, 0x5a, 0x32, 0x84, 0x0d, 0xcc, 0xd3, 0x9e, 0x4c, 0x12, 0xee,
0xde, 0xd7, 0xb5, 0x0c, 0x19, 0x2e, 0xec, 0x98, 0x28, 0x93, 0x70, 0x63, 0xf7, 0xa0, 0x99, 0xf4,
0x94, 0x92, 0xeb, 0xc9, 0x37, 0xef, 0xc4, 0x44, 0xf6, 0xb4, 0x77, 0x95, 0x7c, 0xa1, 0xfc, 0xb5,
0x89, 0x36, 0xde, 0x89, 0xbe, 0xd6, 0x96, 0xe9, 0x5d, 0x56, 0xda, 0x40, 0xa6, 0xbb, 0x97, 0xfc,
0x22, 0x6c, 0x24, 0x57, 0xb4, 0x2c, 0xf9, 0x6e, 0xd6, 0x70, 0x5d, 0x2b, 0xca, 0xc5, 0x3b, 0xf4,
0x20, 0xc7, 0x18, 0xb1, 0xee, 0x55, 0x55, 0x0b, 0x29, 0xc3, 0xbd, 0xab, 0x16, 0x52, 0xa6, 0x1b,
0xf6, 0x08, 0x96, 0x12, 0x0e, 0x55, 0x25, 0x06, 0x67, 0xbb, 0x60, 0x95, 0x18, 0x7c, 0x9d, 0x1f,
0x76, 0x00, 0xcd, 0xa4, 0xab, 0x54, 0xcd, 0xf5, 0x35, 0xee, 0xd7, 0xcd, 0x3b, 0xd7, 0xe2, 0xe3,
0xcd, 0xd4, 0x9c, 0x8a, 0xb1, 0x66, 0xa6, 0x5d, 0xa1, 0xb1, 0x66, 0x66, 0xb8, 0x34, 0xb7, 0xdf,
0xf9, 0xa5, 0xef, 0x9c, 0x39, 0xe1, 0xf9, 0xfc, 0x64, 0x6b, 0xe4, 0x4d, 0xdf, 0x9f, 0x48, 0xab,
0x86, 0xb8, 0x77, 0xfe, 0xfe, 0xc4, 0x1d, 0xbf, 0xcf, 0x0b, 0x38, 0x59, 0x98, 0xf9, 0x5e, 0xe8,
0x7d, 0xf8, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x2f, 0xed, 0xbd, 0x5e, 0x11, 0x8b, 0x00, 0x00,
0x96, 0x58, 0xf1, 0x12, 0xc9, 0xc7, 0x43, 0x54, 0xe8, 0x62, 0xa9, 0xba, 0xba, 0xaa, 0xb3, 0x7b,
0xba, 0x6b, 0xaa, 0x7b, 0xd4, 0xd5, 0xd5, 0x5d, 0x7d, 0x4c, 0x79, 0x7b, 0x86, 0xa2, 0xa8, 0x12,
0xa7, 0x24, 0x52, 0x93, 0xa4, 0xba, 0xb7, 0x17, 0xbb, 0x9b, 0x9b, 0x22, 0x43, 0x52, 0xba, 0xc8,
0x4c, 0x76, 0x66, 0x52, 0x25, 0x8d, 0xe1, 0xbf, 0xf5, 0x81, 0xc5, 0xc2, 0x80, 0x01, 0xaf, 0x01,
0x1f, 0x0b, 0x5f, 0xb0, 0xfd, 0xb7, 0x30, 0xbc, 0x6b, 0x7f, 0xf9, 0xdb, 0x0b, 0x03, 0x3e, 0x60,
0x78, 0x0d, 0x1f, 0x58, 0x2c, 0x60, 0xc0, 0x5e, 0x7f, 0x18, 0x30, 0x16, 0xb0, 0x7f, 0xfc, 0x61,
0xc0, 0x88, 0x17, 0x47, 0x46, 0x26, 0x53, 0x55, 0xd5, 0x33, 0xed, 0xf9, 0x91, 0x18, 0xef, 0xbd,
0xb8, 0x23, 0x5e, 0xbc, 0x2b, 0x22, 0xa1, 0xec, 0xcf, 0x46, 0xdb, 0x33, 0xdf, 0x0b, 0x3d, 0x52,
0x98, 0xb8, 0xfe, 0x6c, 0x64, 0xfc, 0x71, 0x06, 0xf2, 0xc7, 0xe1, 0xa5, 0x47, 0x1e, 0x41, 0xd5,
0x1e, 0x8f, 0x7d, 0x1a, 0x04, 0x56, 0x78, 0x35, 0xa3, 0xcd, 0xcc, 0xdd, 0xcc, 0xbd, 0xfa, 0x43,
0xb2, 0x8d, 0x64, 0xdb, 0x2d, 0x8e, 0x1a, 0x5e, 0xcd, 0xa8, 0x59, 0xb1, 0xa3, 0x04, 0x69, 0x42,
0x51, 0x24, 0x9b, 0xd9, 0xbb, 0x99, 0x7b, 0x65, 0x53, 0x26, 0xc9, 0x6d, 0x00, 0x7b, 0xea, 0xcd,
0xdd, 0xd0, 0x0a, 0xec, 0xb0, 0x99, 0xbb, 0x9b, 0xb9, 0x97, 0x33, 0xcb, 0x1c, 0x32, 0xb0, 0x43,
0x72, 0x0b, 0xca, 0xb3, 0x67, 0x56, 0x30, 0xf2, 0x9d, 0x59, 0xd8, 0xcc, 0x63, 0xd6, 0xd2, 0xec,
0xd9, 0x00, 0xd3, 0xe4, 0x5d, 0x28, 0x79, 0xf3, 0x70, 0xe6, 0x39, 0x6e, 0xd8, 0x2c, 0xdc, 0xcd,
0xdc, 0xab, 0x3c, 0x5c, 0x16, 0x0d, 0xe9, 0xcf, 0xc3, 0x23, 0x06, 0x36, 0x15, 0x01, 0x79, 0x0b,
0x6a, 0x23, 0xcf, 0x3d, 0x75, 0xfc, 0xa9, 0x1d, 0x3a, 0x9e, 0x1b, 0x34, 0x97, 0xb0, 0xae, 0x38,
0xd0, 0xf8, 0xe7, 0x59, 0xa8, 0x0c, 0x7d, 0xdb, 0x0d, 0xec, 0x11, 0x03, 0x90, 0x4d, 0x28, 0x86,
0x97, 0xd6, 0xb9, 0x1d, 0x9c, 0x63, 0x57, 0xcb, 0xe6, 0x52, 0x78, 0xb9, 0x6f, 0x07, 0xe7, 0x64,
0x03, 0x96, 0x78, 0x2b, 0xb1, 0x43, 0x39, 0x53, 0xa4, 0xc8, 0xbb, 0xb0, 0xe2, 0xce, 0xa7, 0x56,
0xbc, 0x2a, 0xd6, 0xad, 0x82, 0xd9, 0x70, 0xe7, 0xd3, 0xb6, 0x0e, 0x67, 0x9d, 0x3f, 0x99, 0x78,
0xa3, 0x67, 0xbc, 0x02, 0xde, 0xbd, 0x32, 0x42, 0xb0, 0x8e, 0x37, 0xa0, 0x2a, 0xd0, 0xd4, 0x39,
0x3b, 0xe7, 0x7d, 0x2c, 0x98, 0x15, 0x4e, 0x80, 0x20, 0x56, 0x42, 0xe8, 0x4c, 0xa9, 0x15, 0x84,
0xf6, 0x74, 0x26, 0xba, 0x54, 0x66, 0x90, 0x01, 0x03, 0x20, 0xda, 0x0b, 0xed, 0x89, 0x75, 0x4a,
0x69, 0xd0, 0x2c, 0x0a, 0x34, 0x83, 0xec, 0x51, 0x1a, 0x90, 0xef, 0x40, 0x7d, 0x4c, 0x83, 0xd0,
0x12, 0x93, 0x41, 0x83, 0x66, 0xe9, 0x6e, 0xee, 0x5e, 0xd9, 0xac, 0x31, 0x68, 0x4b, 0x02, 0xc9,
0x6b, 0x00, 0xbe, 0xfd, 0xdc, 0x62, 0x03, 0x41, 0x2f, 0x9b, 0x65, 0x3e, 0x0b, 0xbe, 0xfd, 0x7c,
0x78, 0xb9, 0x4f, 0x2f, 0xc9, 0x1a, 0x14, 0x26, 0xf6, 0x09, 0x9d, 0x34, 0x01, 0x11, 0x3c, 0x61,
0xfc, 0x12, 0x6c, 0x3c, 0xa1, 0xa1, 0x36, 0x94, 0x81, 0x49, 0xbf, 0x9e, 0xd3, 0x20, 0x64, 0xbd,
0x0a, 0x42, 0xdb, 0x0f, 0x65, 0xaf, 0x32, 0xbc, 0x57, 0x08, 0x8b, 0x7a, 0x45, 0xdd, 0xb1, 0x24,
0xc8, 0x22, 0x41, 0x99, 0xba, 0x63, 0x8e, 0x36, 0x0e, 0x80, 0x68, 0x05, 0xef, 0xd2, 0xd0, 0x76,
0x26, 0x01, 0xf9, 0x18, 0xaa, 0xa1, 0x56, 0x5d, 0x33, 0x73, 0x37, 0x77, 0xaf, 0xa2, 0x96, 0xa6,
0x96, 0xc1, 0x8c, 0xd1, 0x19, 0xe7, 0x50, 0xda, 0xa3, 0xf4, 0xc0, 0x99, 0x3a, 0x21, 0xd9, 0x80,
0xc2, 0xa9, 0x73, 0x49, 0xc7, 0xd8, 0xa8, 0xdc, 0xfe, 0x0d, 0x93, 0x27, 0xc9, 0x1d, 0x00, 0xfc,
0x61, 0x4d, 0xd5, 0x2a, 0xdd, 0xbf, 0x61, 0x96, 0x11, 0x76, 0x18, 0xd8, 0x21, 0xd9, 0x82, 0xe2,
0x8c, 0xfa, 0x23, 0x2a, 0xd7, 0xc3, 0xfe, 0x0d, 0x53, 0x02, 0x76, 0x8a, 0x50, 0x98, 0xb0, 0xd2,
0x8d, 0xdf, 0x2f, 0x40, 0x65, 0x40, 0xdd, 0xb1, 0x1c, 0x09, 0x02, 0x79, 0x36, 0xd0, 0x58, 0x59,
0xd5, 0xc4, 0xdf, 0xe4, 0x4d, 0xa8, 0xe0, 0x94, 0x04, 0xa1, 0xef, 0xb8, 0x67, 0x7c, 0xb7, 0xec,
0x64, 0x9b, 0x19, 0x13, 0x18, 0x78, 0x80, 0x50, 0xd2, 0x80, 0x9c, 0x3d, 0x95, 0xbb, 0x85, 0xfd,
0x24, 0x37, 0xa1, 0x64, 0x4f, 0x43, 0xde, 0xbc, 0x2a, 0x82, 0x8b, 0xf6, 0x34, 0xc4, 0xa6, 0xbd,
0x01, 0xd5, 0x99, 0x7d, 0x35, 0xa5, 0x6e, 0x18, 0x2d, 0xb3, 0xaa, 0x59, 0x11, 0x30, 0x5c, 0x68,
0x0f, 0x61, 0x55, 0x27, 0x91, 0x95, 0x17, 0x54, 0xe5, 0x2b, 0x1a, 0xb5, 0x68, 0xc3, 0x3b, 0xb0,
0x2c, 0xf3, 0xf8, 0xbc, 0x3f, 0xb8, 0xfc, 0xca, 0x66, 0x5d, 0x80, 0x65, 0x2f, 0xef, 0x41, 0xe3,
0xd4, 0x71, 0xed, 0x89, 0x35, 0x9a, 0x84, 0x17, 0xd6, 0x98, 0x4e, 0x42, 0x1b, 0x57, 0x62, 0xc1,
0xac, 0x23, 0xbc, 0x3d, 0x09, 0x2f, 0x76, 0x19, 0x94, 0xbc, 0x07, 0xe5, 0x53, 0x4a, 0x2d, 0x1c,
0xac, 0x66, 0x29, 0xb6, 0xa1, 0xe5, 0x0c, 0x99, 0xa5, 0x53, 0x39, 0x57, 0xef, 0x41, 0xc3, 0x9b,
0x87, 0x67, 0x9e, 0xe3, 0x9e, 0x59, 0xa3, 0x73, 0xdb, 0xb5, 0x9c, 0x31, 0xae, 0xcd, 0xfc, 0x4e,
0xf6, 0x41, 0xc6, 0xac, 0x4b, 0x5c, 0xfb, 0xdc, 0x76, 0xbb, 0x63, 0xf2, 0x36, 0x2c, 0x4f, 0xec,
0x20, 0xb4, 0xce, 0xbd, 0x99, 0x35, 0x9b, 0x9f, 0x3c, 0xa3, 0x57, 0xcd, 0x1a, 0x0e, 0x44, 0x8d,
0x81, 0xf7, 0xbd, 0xd9, 0x11, 0x02, 0xd9, 0xd2, 0xc3, 0x76, 0xf2, 0x46, 0xb0, 0x25, 0x5d, 0x33,
0xcb, 0x0c, 0xc2, 0x2b, 0xfd, 0x0a, 0x56, 0x71, 0x7a, 0x46, 0xf3, 0x20, 0xf4, 0xa6, 0x96, 0x4f,
0x47, 0x9e, 0x3f, 0x0e, 0x9a, 0x15, 0x5c, 0x6b, 0xdf, 0x15, 0x8d, 0xd5, 0xe6, 0x78, 0x7b, 0x97,
0x06, 0x61, 0x1b, 0x89, 0x4d, 0x4e, 0xdb, 0x71, 0x43, 0xff, 0xca, 0x5c, 0x19, 0x27, 0xe1, 0xe4,
0x3d, 0x20, 0xf6, 0x64, 0xe2, 0x3d, 0xb7, 0x02, 0x3a, 0x39, 0xb5, 0xc4, 0x20, 0x36, 0xeb, 0x77,
0x33, 0xf7, 0x4a, 0x66, 0x03, 0x31, 0x03, 0x3a, 0x39, 0x3d, 0xe2, 0x70, 0xf2, 0x31, 0xe0, 0x26,
0xb5, 0x4e, 0xa9, 0x1d, 0xce, 0x7d, 0x1a, 0x34, 0x97, 0xef, 0xe6, 0xee, 0xd5, 0x1f, 0xae, 0xa8,
0xf1, 0x42, 0xf0, 0x8e, 0x13, 0x9a, 0x55, 0x46, 0x27, 0xd2, 0xc1, 0xd6, 0x2e, 0x6c, 0xa4, 0x37,
0x89, 0x2d, 0x2a, 0x36, 0x2a, 0x6c, 0x31, 0xe6, 0x4d, 0xf6, 0x93, 0xed, 0xec, 0x0b, 0x7b, 0x32,
0xa7, 0xb8, 0x0a, 0xab, 0x26, 0x4f, 0x7c, 0x3f, 0xfb, 0x69, 0xc6, 0xf8, 0xbd, 0x0c, 0x54, 0x79,
0x2f, 0x83, 0x99, 0xe7, 0x06, 0x94, 0xbc, 0x09, 0x35, 0xb9, 0x1a, 0xa8, 0xef, 0x7b, 0xbe, 0xe0,
0x96, 0x72, 0xe5, 0x75, 0x18, 0x8c, 0x7c, 0x17, 0x1a, 0x92, 0x68, 0xe6, 0x53, 0x67, 0x6a, 0x9f,
0xc9, 0xa2, 0xe5, 0x52, 0x3a, 0x12, 0x60, 0xf2, 0x41, 0x54, 0x9e, 0xef, 0xcd, 0x43, 0x8a, 0x6b,
0xbd, 0xf2, 0xb0, 0x2a, 0xba, 0x67, 0x32, 0x98, 0x2a, 0x1d, 0x53, 0xaf, 0xb0, 0xce, 0x8d, 0xdf,
0xca, 0x00, 0x61, 0xcd, 0x1e, 0x7a, 0xbc, 0x80, 0x88, 0x23, 0xc5, 0x72, 0x66, 0x5e, 0x79, 0x87,
0x64, 0x5f, 0xb4, 0x43, 0x0c, 0x28, 0xf0, 0xb6, 0xe7, 0x53, 0xda, 0xce, 0x51, 0x3f, 0xca, 0x97,
0x72, 0x8d, 0xbc, 0xf1, 0x9f, 0x73, 0xb0, 0xc6, 0xd6, 0xa9, 0x4b, 0x27, 0xad, 0xd1, 0x88, 0xce,
0xd4, 0xde, 0xb9, 0x03, 0x15, 0xd7, 0x1b, 0x53, 0xb9, 0x62, 0x79, 0xc3, 0x80, 0x81, 0xb4, 0xe5,
0x7a, 0x6e, 0x3b, 0x2e, 0x6f, 0x38, 0x1f, 0xcc, 0x32, 0x42, 0xb0, 0xd9, 0x6f, 0xc3, 0xf2, 0x8c,
0xba, 0x63, 0x7d, 0x8b, 0xe4, 0xf8, 0xaa, 0x17, 0x60, 0xb1, 0x3b, 0xee, 0x40, 0xe5, 0x74, 0xce,
0xe9, 0x18, 0x63, 0xc9, 0xe3, 0x1a, 0x00, 0x01, 0x6a, 0x71, 0xfe, 0x32, 0x9b, 0x07, 0xe7, 0x88,
0x2d, 0x20, 0xb6, 0xc8, 0xd2, 0x0c, 0x75, 0x1b, 0x60, 0x3c, 0x0f, 0x42, 0xb1, 0x63, 0x96, 0x10,
0x59, 0x66, 0x10, 0xbe, 0x63, 0xbe, 0x07, 0xab, 0x53, 0xfb, 0xd2, 0xc2, 0xb5, 0x63, 0x39, 0xae,
0x75, 0x3a, 0x41, 0xa6, 0x5e, 0x44, 0xba, 0xc6, 0xd4, 0xbe, 0xfc, 0x82, 0x61, 0xba, 0xee, 0x1e,
0xc2, 0x19, 0x5b, 0x19, 0xf1, 0x91, 0xb0, 0x7c, 0x1a, 0x50, 0xff, 0x82, 0x22, 0x27, 0xc8, 0x9b,
0x75, 0x01, 0x36, 0x39, 0x94, 0xb5, 0x68, 0xca, 0xfa, 0x1d, 0x4e, 0x46, 0x7c, 0xdb, 0x9b, 0xc5,
0xa9, 0xe3, 0xee, 0x87, 0x93, 0x11, 0x3b, 0xaf, 0x18, 0x1f, 0x99, 0x51, 0xdf, 0x7a, 0xf6, 0x1c,
0xf7, 0x70, 0x1e, 0xf9, 0xc6, 0x11, 0xf5, 0x9f, 0x3e, 0x67, 0x22, 0xc5, 0x28, 0x40, 0x46, 0x64,
0x5f, 0x35, 0x2b, 0xb8, 0xc1, 0x4b, 0xa3, 0x80, 0xb1, 0x20, 0xfb, 0x8a, 0x6d, 0x42, 0xd6, 0x5a,
0x1b, 0x67, 0x81, 0x8e, 0xb1, 0xf8, 0x00, 0x39, 0x6a, 0x0d, 0x1b, 0xdb, 0x12, 0x08, 0x56, 0x4f,
0xc0, 0x56, 0xbd, 0x6c, 0xec, 0xe9, 0xc4, 0x3e, 0x0b, 0x90, 0xa5, 0xd4, 0xcc, 0xaa, 0x00, 0xee,
0x31, 0x98, 0xf1, 0x25, 0xac, 0x27, 0xe6, 0x56, 0xec, 0x19, 0x26, 0x42, 0x20, 0x04, 0xe7, 0xb5,
0x64, 0x8a, 0x54, 0xda, 0xa4, 0x65, 0x53, 0x26, 0xcd, 0xf8, 0xed, 0x0c, 0x54, 0x45, 0xc9, 0x28,
0xec, 0x90, 0x6d, 0x20, 0x72, 0x16, 0xc3, 0x4b, 0x67, 0x6c, 0x9d, 0x5c, 0x85, 0x34, 0xe0, 0x8b,
0x66, 0xff, 0x86, 0xd9, 0x10, 0xb8, 0xe1, 0xa5, 0x33, 0xde, 0x61, 0x18, 0x72, 0x1f, 0x1a, 0x31,
0xfa, 0x20, 0xf4, 0xf9, 0x8a, 0xde, 0xbf, 0x61, 0xd6, 0x35, 0xea, 0x41, 0xe8, 0xb3, 0x3d, 0xc2,
0x44, 0xa9, 0x79, 0x68, 0x39, 0xee, 0x98, 0x5e, 0xe2, 0x32, 0xaa, 0x99, 0x15, 0x0e, 0xeb, 0x32,
0xd0, 0x4e, 0x1d, 0xaa, 0x7a, 0x71, 0xc6, 0x19, 0x94, 0xa4, 0x1c, 0x86, 0x82, 0x48, 0xa2, 0x49,
0x66, 0x39, 0x54, 0x2d, 0xb9, 0x09, 0xa5, 0x78, 0x0b, 0xcc, 0x62, 0xf8, 0xca, 0x15, 0x1b, 0x9f,
0x43, 0xe3, 0x80, 0x2d, 0x1e, 0x97, 0x2d, 0x56, 0x21, 0x57, 0x6e, 0xc0, 0x92, 0xb6, 0x69, 0xca,
0xa6, 0x48, 0xb1, 0x33, 0xf7, 0xdc, 0x0b, 0x42, 0x51, 0x0b, 0xfe, 0x36, 0x7e, 0x3f, 0x03, 0xa4,
0x13, 0x84, 0xce, 0xd4, 0x0e, 0xe9, 0x1e, 0x55, 0x6c, 0xa1, 0x0f, 0x55, 0x56, 0xda, 0xd0, 0x6b,
0x71, 0x41, 0x8f, 0x0b, 0x14, 0xef, 0x8a, 0x6d, 0xbc, 0x98, 0x61, 0x5b, 0xa7, 0xe6, 0x6c, 0x3e,
0x56, 0x00, 0xdb, 0x65, 0xa1, 0xed, 0x9f, 0xd1, 0x10, 0xc5, 0x43, 0x21, 0xd7, 0x00, 0x07, 0x31,
0xc1, 0x70, 0xeb, 0x07, 0xb0, 0xb2, 0x50, 0x86, 0xce, 0x97, 0xcb, 0x29, 0x7c, 0x39, 0xa7, 0xf3,
0x65, 0x0b, 0x56, 0x63, 0xed, 0x12, 0x2b, 0x6d, 0x13, 0x8a, 0x6c, 0x43, 0x30, 0xe1, 0x20, 0xc3,
0xa5, 0xd5, 0x53, 0x4a, 0x99, 0x78, 0xfd, 0x3e, 0xac, 0x9d, 0x52, 0xea, 0xdb, 0x21, 0x22, 0x71,
0xc7, 0xb0, 0x19, 0x12, 0x05, 0xaf, 0x08, 0xdc, 0xc0, 0x0e, 0x8f, 0xa8, 0xcf, 0x66, 0xca, 0xf8,
0x3f, 0x19, 0x58, 0x66, 0x1c, 0xf4, 0xd0, 0x76, 0xaf, 0xe4, 0x38, 0x1d, 0xa4, 0x8e, 0xd3, 0x3d,
0xed, 0x30, 0xd4, 0xa8, 0xbf, 0xe9, 0x20, 0xe5, 0x92, 0x83, 0x44, 0xee, 0x42, 0x35, 0xd6, 0xd6,
0x02, 0xb6, 0x15, 0x02, 0xd5, 0xc8, 0x48, 0x22, 0x5d, 0xd2, 0x24, 0xd2, 0x9f, 0x7d, 0x70, 0xdf,
0x86, 0x46, 0xd4, 0x19, 0x31, 0xb2, 0x04, 0xf2, 0x6c, 0xa1, 0x8a, 0x02, 0xf0, 0xb7, 0xf1, 0x8f,
0x33, 0x9c, 0xb0, 0xed, 0x39, 0x91, 0xd4, 0x4b, 0x20, 0xcf, 0xa4, 0x6c, 0x49, 0xc8, 0x7e, 0x5f,
0xab, 0x43, 0x7c, 0x0b, 0x43, 0x70, 0x13, 0x4a, 0x01, 0x13, 0xa1, 0xed, 0x09, 0x1f, 0x85, 0x92,
0x59, 0x64, 0xe9, 0xd6, 0x64, 0x12, 0x8d, 0x4e, 0x51, 0x97, 0xd7, 0xdf, 0x81, 0x15, 0xad, 0xcd,
0x2f, 0xe8, 0x5d, 0x0f, 0xc8, 0x81, 0x13, 0x84, 0xc7, 0x6e, 0x30, 0xd3, 0x84, 0xbc, 0x5b, 0x50,
0x66, 0xdc, 0x98, 0xb5, 0x37, 0x10, 0x12, 0x3d, 0x63, 0xcf, 0xac, 0xb5, 0x01, 0x22, 0xed, 0x4b,
0x81, 0xcc, 0x0a, 0xa4, 0x7d, 0x89, 0x48, 0xe3, 0x53, 0x58, 0x8d, 0x95, 0x27, 0xaa, 0x7e, 0x03,
0x0a, 0xf3, 0xf0, 0xd2, 0x93, 0x62, 0x7c, 0x45, 0xac, 0x26, 0xa6, 0x84, 0x9a, 0x1c, 0x63, 0x3c,
0x86, 0x95, 0x1e, 0x7d, 0x2e, 0x36, 0xbc, 0x6c, 0xc8, 0xdb, 0x90, 0x7f, 0x89, 0x62, 0x8a, 0x78,
0x63, 0x1b, 0x88, 0x9e, 0x59, 0xd4, 0xaa, 0xe9, 0xa9, 0x99, 0x98, 0x9e, 0x6a, 0xbc, 0x0d, 0x64,
0xe0, 0x9c, 0xb9, 0x87, 0x34, 0x08, 0xec, 0x33, 0xc5, 0x22, 0x1a, 0x90, 0x9b, 0x06, 0x67, 0x82,
0x9f, 0xb1, 0x9f, 0xc6, 0x87, 0xb0, 0x1a, 0xa3, 0x13, 0x05, 0xbf, 0x06, 0xe5, 0xc0, 0x39, 0x73,
0x51, 0x08, 0x13, 0x45, 0x47, 0x00, 0x63, 0x0f, 0xd6, 0xbe, 0xa0, 0xbe, 0x73, 0x7a, 0xf5, 0xb2,
0xe2, 0xe3, 0xe5, 0x64, 0x93, 0xe5, 0x74, 0x60, 0x3d, 0x51, 0x8e, 0xa8, 0x9e, 0x2f, 0x6a, 0x31,
0x93, 0x25, 0x93, 0x27, 0x34, 0x1e, 0x99, 0xd5, 0x79, 0xa4, 0x71, 0x0c, 0xa4, 0xed, 0xb9, 0x2e,
0x1d, 0x85, 0x47, 0x94, 0xfa, 0xb2, 0x31, 0xef, 0x6a, 0x2b, 0xb8, 0xf2, 0x70, 0x53, 0x8c, 0x6c,
0x92, 0xf1, 0x8a, 0xa5, 0x4d, 0x20, 0x3f, 0xa3, 0xfe, 0x14, 0x0b, 0x2e, 0x99, 0xf8, 0xdb, 0x58,
0x87, 0xd5, 0x58, 0xb1, 0xbc, 0x6d, 0xc6, 0x03, 0x58, 0xdf, 0x75, 0x82, 0xd1, 0x62, 0x85, 0x9b,
0x50, 0x9c, 0xcd, 0x4f, 0xac, 0x38, 0x0f, 0x7f, 0x4a, 0xaf, 0x8c, 0x26, 0x6c, 0x24, 0x73, 0x88,
0xb2, 0x7e, 0x3d, 0x03, 0xf9, 0xfd, 0xe1, 0x41, 0x9b, 0x6c, 0x41, 0xc9, 0x71, 0x47, 0xde, 0x94,
0x09, 0x69, 0xbc, 0xcf, 0x2a, 0x7d, 0xed, 0xb6, 0xbb, 0x05, 0x65, 0x94, 0xed, 0x98, 0x7a, 0x2d,
0xc4, 0xa4, 0x12, 0x03, 0x1c, 0x78, 0xa3, 0x67, 0x4c, 0xaf, 0xa7, 0x97, 0x33, 0xc7, 0x47, 0xcd,
0x5d, 0x6a, 0xa6, 0x79, 0x2e, 0x17, 0x44, 0x08, 0xa1, 0xa0, 0xfe, 0x7a, 0x16, 0x88, 0x38, 0x99,
0xdb, 0x9e, 0x1b, 0x84, 0xbe, 0xed, 0xb8, 0x61, 0x10, 0x97, 0x3c, 0x32, 0x09, 0xc9, 0xe3, 0x1e,
0x34, 0xf0, 0xb4, 0x17, 0x52, 0x0f, 0x32, 0xeb, 0x6c, 0x24, 0xf9, 0x08, 0xb1, 0x87, 0x31, 0xed,
0xb7, 0xa0, 0x1e, 0x09, 0x5c, 0xca, 0x6c, 0x92, 0x37, 0xab, 0x4a, 0xe8, 0x12, 0xac, 0x9d, 0x6d,
0x3a, 0x29, 0x49, 0x28, 0xed, 0x90, 0xcb, 0x76, 0x2b, 0x53, 0xfb, 0xf2, 0x88, 0x4a, 0xf1, 0x0e,
0xf5, 0x44, 0x03, 0x6a, 0x52, 0xa0, 0xe2, 0x94, 0x5c, 0xce, 0xab, 0x08, 0xa9, 0x0a, 0x69, 0xd2,
0xc5, 0xa3, 0xa5, 0x74, 0xf1, 0xc8, 0xf8, 0x0f, 0x65, 0x28, 0x8a, 0x61, 0xe0, 0xc2, 0x4e, 0xe8,
0x5c, 0xd0, 0x48, 0xd8, 0x61, 0x29, 0x26, 0x42, 0xf9, 0x74, 0xea, 0x85, 0x4a, 0xc6, 0xe5, 0x4b,
0xb1, 0xca, 0x81, 0x42, 0xca, 0xd5, 0xe4, 0x2c, 0x6e, 0xed, 0xc9, 0x71, 0xa2, 0x91, 0x2e, 0xfd,
0xdc, 0x82, 0xa2, 0x14, 0x97, 0xf2, 0x4a, 0x0d, 0x5c, 0x1a, 0x71, 0x01, 0x77, 0x0b, 0x4a, 0x23,
0x7b, 0x66, 0x8f, 0x9c, 0xf0, 0x4a, 0x70, 0x4b, 0x95, 0x66, 0xa5, 0x4f, 0xbc, 0x91, 0x3d, 0xb1,
0x4e, 0xec, 0x89, 0xed, 0x8e, 0xa8, 0x30, 0xa3, 0x54, 0x11, 0xb8, 0xc3, 0x61, 0xe4, 0x3b, 0x50,
0x17, 0xed, 0x94, 0x54, 0xdc, 0x9a, 0x22, 0x5a, 0x2f, 0xc9, 0x98, 0x3c, 0xee, 0x4d, 0xd9, 0xbc,
0x9c, 0x52, 0x2e, 0xb9, 0xe6, 0xcc, 0x32, 0x87, 0xec, 0x51, 0xec, 0xad, 0x40, 0x3f, 0xe7, 0x2b,
0xa8, 0xcc, 0xab, 0xe2, 0xc0, 0x2f, 0xb9, 0xf5, 0x63, 0x51, 0x7c, 0xcd, 0x69, 0xe2, 0xeb, 0xbb,
0xb0, 0x32, 0x77, 0x03, 0x1a, 0x86, 0x13, 0x3a, 0x56, 0x6d, 0xa9, 0x20, 0x51, 0x43, 0x21, 0x64,
0x73, 0xb6, 0x61, 0x95, 0xdb, 0x7f, 0x02, 0x3b, 0xf4, 0x82, 0x73, 0x27, 0xb0, 0x02, 0xa6, 0x54,
0x72, 0x0b, 0xc1, 0x0a, 0xa2, 0x06, 0x02, 0x33, 0xe0, 0x5a, 0xe5, 0x66, 0x82, 0xde, 0xa7, 0x23,
0xea, 0x5c, 0xd0, 0x31, 0x8a, 0xb6, 0x39, 0x73, 0x3d, 0x96, 0xc7, 0x14, 0x48, 0xd4, 0x53, 0xe6,
0x53, 0x6b, 0x3e, 0x1b, 0xdb, 0x4c, 0xbe, 0xab, 0x73, 0xfd, 0xc1, 0x9d, 0x4f, 0x8f, 0x39, 0x84,
0x3c, 0x00, 0x29, 0xbc, 0x8a, 0x35, 0xb3, 0x1c, 0x63, 0xeb, 0x6c, 0xcf, 0x9a, 0x55, 0x41, 0xc1,
0x65, 0xeb, 0x3b, 0xfa, 0x66, 0x69, 0xb0, 0x15, 0x86, 0x7a, 0x56, 0xb4, 0x61, 0x9a, 0x50, 0x9c,
0xf9, 0xce, 0x85, 0x1d, 0xd2, 0xe6, 0x0a, 0x3f, 0xe1, 0x44, 0x92, 0x31, 0x49, 0xc7, 0x75, 0x42,
0xc7, 0x0e, 0x3d, 0xbf, 0x49, 0x10, 0x17, 0x01, 0xc8, 0x7d, 0x58, 0xc1, 0x75, 0x12, 0x84, 0x76,
0x38, 0x0f, 0x84, 0xe0, 0xbe, 0x8a, 0x0b, 0x0a, 0x55, 0x8f, 0x01, 0xc2, 0x51, 0x76, 0x27, 0x9f,
0xc0, 0x06, 0x5f, 0x1a, 0x0b, 0x5b, 0x73, 0x8d, 0x0d, 0x07, 0xb6, 0x68, 0x15, 0x29, 0xda, 0xf1,
0x3d, 0xfa, 0x19, 0x6c, 0x8a, 0xe5, 0xb2, 0x90, 0x73, 0x5d, 0xe5, 0x5c, 0xe3, 0x24, 0x89, 0xac,
0xdb, 0xb0, 0xc2, 0x9a, 0xe6, 0x8c, 0x2c, 0x51, 0x02, 0xdb, 0x15, 0x1b, 0xac, 0x17, 0x98, 0x69,
0x99, 0x23, 0x4d, 0xc4, 0x3d, 0xa5, 0x57, 0xe4, 0x73, 0x58, 0xe6, 0xcb, 0x07, 0xb5, 0x53, 0x3c,
0xfc, 0xb6, 0xf0, 0xf0, 0x5b, 0x17, 0x83, 0xdb, 0x56, 0x58, 0x3c, 0xff, 0xea, 0xa3, 0x58, 0x9a,
0x6d, 0x8d, 0x89, 0x73, 0x4a, 0x43, 0x67, 0x4a, 0x9b, 0x9b, 0x7c, 0xb1, 0xc9, 0x34, 0xdb, 0xb5,
0xf3, 0x19, 0x62, 0x9a, 0x9c, 0x55, 0xf2, 0x14, 0xae, 0xe3, 0x89, 0x17, 0x50, 0x69, 0x39, 0x6c,
0xde, 0x14, 0x1b, 0x92, 0x01, 0xa5, 0x08, 0xce, 0xf4, 0x18, 0xae, 0x33, 0x2a, 0xfb, 0xee, 0x2d,
0x5c, 0x18, 0x35, 0xae, 0x3a, 0x4a, 0x1b, 0x2f, 0x13, 0x77, 0xce, 0xed, 0xe7, 0x92, 0xa9, 0xbe,
0x86, 0xdc, 0x04, 0x18, 0x48, 0x98, 0x03, 0xf7, 0x60, 0x45, 0xcc, 0x42, 0xc4, 0x4c, 0x9b, 0xb7,
0xf1, 0x18, 0xba, 0x29, 0xfb, 0xb8, 0xc0, 0x6d, 0xcd, 0x06, 0x9f, 0x17, 0x8d, 0xff, 0xee, 0x03,
0x91, 0x93, 0xa2, 0x15, 0xf4, 0xfa, 0xcb, 0x0a, 0x5a, 0x11, 0xd3, 0x14, 0x81, 0x8c, 0xdf, 0xcd,
0x70, 0xa9, 0x45, 0x50, 0x07, 0x9a, 0xbe, 0xce, 0xf9, 0x9a, 0xe5, 0xb9, 0x93, 0x2b, 0xc1, 0xea,
0x80, 0x83, 0xfa, 0xee, 0x04, 0x79, 0x8d, 0xe3, 0xea, 0x24, 0xfc, 0x80, 0xac, 0x4a, 0x20, 0x12,
0xdd, 0x81, 0xca, 0x6c, 0x7e, 0x32, 0x71, 0x46, 0x9c, 0x24, 0xc7, 0x4b, 0xe1, 0x20, 0x24, 0x78,
0x03, 0xaa, 0x62, 0xad, 0x73, 0x8a, 0x3c, 0x52, 0x54, 0x04, 0x0c, 0x49, 0xf0, 0x00, 0xa6, 0x3e,
0x32, 0xbb, 0xaa, 0x89, 0xbf, 0x8d, 0x1d, 0x58, 0x8b, 0x37, 0x5a, 0x48, 0x07, 0xf7, 0xa1, 0x24,
0x38, 0xa9, 0xb4, 0x64, 0xd5, 0xe3, 0xa3, 0x61, 0x2a, 0xbc, 0xf1, 0x1f, 0x0b, 0xb0, 0x2a, 0xc7,
0x88, 0x4d, 0xf6, 0x60, 0x3e, 0x9d, 0xda, 0x7e, 0x0a, 0x8b, 0xce, 0xbc, 0x98, 0x45, 0x67, 0x17,
0x58, 0x74, 0xdc, 0x94, 0xc1, 0x39, 0x7c, 0xdc, 0x94, 0xc1, 0x56, 0x17, 0xd7, 0x2e, 0x75, 0x83,
0x79, 0x4d, 0x80, 0x87, 0xdc, 0x30, 0xbf, 0x70, 0xa0, 0x14, 0x52, 0x0e, 0x14, 0xfd, 0x38, 0x58,
0x4a, 0x1c, 0x07, 0x6f, 0x00, 0x5f, 0xc6, 0x72, 0x3d, 0x16, 0xb9, 0xc2, 0x89, 0x30, 0xb1, 0x20,
0xdf, 0x81, 0xe5, 0x24, 0x07, 0xe6, 0xac, 0xbe, 0x9e, 0xc2, 0x7f, 0x9d, 0x29, 0x45, 0x91, 0x42,
0x23, 0x2e, 0x0b, 0xfe, 0xeb, 0x4c, 0xe9, 0x01, 0x62, 0x24, 0x7d, 0x07, 0x80, 0xd7, 0x8d, 0xdb,
0x18, 0x70, 0x1b, 0xbf, 0x9d, 0x58, 0x99, 0xda, 0xa8, 0x6f, 0xb3, 0xc4, 0xdc, 0xa7, 0xb8, 0xaf,
0xcb, 0x98, 0x13, 0xb7, 0xf4, 0x27, 0x50, 0xf7, 0x66, 0xd4, 0xb5, 0x22, 0x2e, 0x58, 0xc1, 0xa2,
0x1a, 0xa2, 0xa8, 0xae, 0x84, 0x9b, 0x35, 0x46, 0xa7, 0x92, 0xe4, 0x33, 0x3e, 0xc8, 0x54, 0xcb,
0x59, 0xbd, 0x26, 0x67, 0x1d, 0x09, 0xa3, 0xac, 0x1f, 0x42, 0xc5, 0xa7, 0x81, 0x37, 0x99, 0x73,
0xeb, 0x7b, 0x0d, 0xd7, 0x91, 0x34, 0x47, 0x9a, 0x0a, 0x63, 0xea, 0x54, 0xc6, 0x6f, 0x64, 0xa0,
0xa2, 0xf5, 0x81, 0xac, 0xc3, 0x4a, 0xbb, 0xdf, 0x3f, 0xea, 0x98, 0xad, 0x61, 0xf7, 0x8b, 0x8e,
0xd5, 0x3e, 0xe8, 0x0f, 0x3a, 0x8d, 0x1b, 0x0c, 0x7c, 0xd0, 0x6f, 0xb7, 0x0e, 0xac, 0xbd, 0xbe,
0xd9, 0x96, 0xe0, 0x0c, 0xd9, 0x00, 0x62, 0x76, 0x0e, 0xfb, 0xc3, 0x4e, 0x0c, 0x9e, 0x25, 0x0d,
0xa8, 0xee, 0x98, 0x9d, 0x56, 0x7b, 0x5f, 0x40, 0x72, 0x64, 0x0d, 0x1a, 0x7b, 0xc7, 0xbd, 0xdd,
0x6e, 0xef, 0x89, 0xd5, 0x6e, 0xf5, 0xda, 0x9d, 0x83, 0xce, 0x6e, 0x23, 0x4f, 0x6a, 0x50, 0x6e,
0xed, 0xb4, 0x7a, 0xbb, 0xfd, 0x5e, 0x67, 0xb7, 0x51, 0x30, 0xfe, 0x47, 0x06, 0x20, 0x6a, 0x28,
0xe3, 0xab, 0x51, 0x53, 0x75, 0x6f, 0xd7, 0xfa, 0x42, 0xa7, 0x38, 0x5f, 0xf5, 0x63, 0x69, 0xf2,
0x10, 0x8a, 0xde, 0x3c, 0x1c, 0x79, 0x53, 0x2e, 0xa8, 0xd7, 0x1f, 0x36, 0x17, 0xf2, 0xf5, 0x39,
0xde, 0x94, 0x84, 0x31, 0x8f, 0x56, 0xee, 0x65, 0x1e, 0xad, 0xb8, 0xeb, 0x8c, 0xcb, 0x75, 0x9a,
0xeb, 0xec, 0x36, 0x40, 0xf0, 0x9c, 0xd2, 0x19, 0x1a, 0x63, 0xc4, 0x2e, 0x28, 0x23, 0x64, 0xc8,
0xf4, 0xb8, 0x3f, 0xca, 0xc0, 0x3a, 0xae, 0xa5, 0x71, 0x92, 0x89, 0xdd, 0x85, 0xca, 0xc8, 0xf3,
0x66, 0x4c, 0xf5, 0x8f, 0xe4, 0x35, 0x1d, 0xc4, 0x18, 0x14, 0x67, 0xc8, 0xa7, 0x9e, 0x3f, 0xa2,
0x82, 0x87, 0x01, 0x82, 0xf6, 0x18, 0x84, 0xed, 0x21, 0xb1, 0x09, 0x39, 0x05, 0x67, 0x61, 0x15,
0x0e, 0xe3, 0x24, 0x1b, 0xb0, 0x74, 0xe2, 0x53, 0x7b, 0x74, 0x2e, 0xb8, 0x97, 0x48, 0x91, 0xef,
0x46, 0x46, 0xa9, 0x11, 0xdb, 0x13, 0x13, 0xca, 0x1b, 0x5f, 0x32, 0x97, 0x05, 0xbc, 0x2d, 0xc0,
0xec, 0x9c, 0xb7, 0x4f, 0x6c, 0x77, 0xec, 0xb9, 0x74, 0x2c, 0xb4, 0xdc, 0x08, 0x60, 0x1c, 0xc1,
0x46, 0xb2, 0x7f, 0x82, 0xdf, 0x7d, 0xac, 0xf1, 0x3b, 0xae, 0x5e, 0x6e, 0x5d, 0xbf, 0xc7, 0x34,
0xde, 0xf7, 0xaf, 0xf3, 0x90, 0x67, 0xea, 0xc6, 0xb5, 0x9a, 0x89, 0xae, 0x3f, 0xe6, 0x16, 0xfc,
0x9c, 0x68, 0xfb, 0xe2, 0x02, 0x98, 0x98, 0x2c, 0x84, 0xa0, 0xe0, 0xa5, 0xd0, 0x3e, 0x1d, 0x5d,
0x08, 0xc9, 0x9b, 0xa3, 0x4d, 0x3a, 0xba, 0x40, 0x75, 0xde, 0x0e, 0x79, 0x5e, 0xce, 0xaf, 0x8a,
0x81, 0x1d, 0x62, 0x4e, 0x81, 0xc2, 0x7c, 0x45, 0x85, 0xc2, 0x5c, 0x4d, 0x28, 0x3a, 0xee, 0x89,
0x37, 0x77, 0xc7, 0xc8, 0x9e, 0x4a, 0xa6, 0x4c, 0xa2, 0x5b, 0x15, 0x39, 0x29, 0x3b, 0xda, 0x39,
0x37, 0x2a, 0x31, 0xc0, 0x90, 0x1d, 0xee, 0x1f, 0x40, 0x39, 0xb8, 0x72, 0x47, 0x3a, 0x0f, 0x5a,
0x13, 0xe3, 0xc3, 0x7a, 0xbf, 0x3d, 0xb8, 0x72, 0x47, 0xb8, 0xe2, 0x4b, 0x81, 0xf8, 0x45, 0x1e,
0x41, 0x49, 0x39, 0x22, 0xf8, 0x09, 0x72, 0x53, 0xcf, 0x21, 0xbd, 0x0f, 0xdc, 0xde, 0xa3, 0x48,
0xc9, 0xfb, 0xb0, 0x84, 0xde, 0x82, 0xa0, 0x59, 0xc5, 0x4c, 0x52, 0xa9, 0x64, 0xcd, 0x40, 0x8f,
0x26, 0x1d, 0xa3, 0xe7, 0xc0, 0x14, 0x64, 0x6c, 0x98, 0x4e, 0x27, 0xf6, 0xcc, 0x1a, 0xa1, 0xfa,
0x56, 0xe3, 0x8e, 0x41, 0x06, 0x69, 0xa3, 0x06, 0x77, 0x17, 0xaa, 0xe8, 0xe4, 0x41, 0x1a, 0x97,
0xcb, 0xa1, 0x39, 0x13, 0x18, 0x6c, 0x6f, 0x62, 0xcf, 0x7a, 0xc1, 0xd6, 0x53, 0xa8, 0xc5, 0x1a,
0xa3, 0x1b, 0x80, 0x6a, 0xdc, 0x00, 0xf4, 0x96, 0x6e, 0x00, 0x8a, 0x8e, 0x42, 0x91, 0x4d, 0x37,
0x08, 0xfd, 0x00, 0x4a, 0x72, 0x2c, 0x18, 0xcf, 0x39, 0xee, 0x3d, 0xed, 0xf5, 0xbf, 0xec, 0x59,
0x83, 0xaf, 0x7a, 0xed, 0xc6, 0x0d, 0xb2, 0x0c, 0x95, 0x56, 0x1b, 0xd9, 0x18, 0x02, 0x32, 0x8c,
0xe4, 0xa8, 0x35, 0x18, 0x28, 0x48, 0xd6, 0xd8, 0x83, 0x46, 0xb2, 0xab, 0x6c, 0x51, 0x87, 0x12,
0x26, 0x9c, 0x31, 0x11, 0x80, 0x29, 0xf2, 0xdc, 0xbf, 0xc2, 0xd5, 0x24, 0x9e, 0x30, 0x1e, 0x41,
0x83, 0x1d, 0xec, 0x6c, 0xac, 0x75, 0x37, 0xeb, 0x84, 0x89, 0xde, 0xba, 0x43, 0xa6, 0x64, 0x56,
0x38, 0x0c, 0xab, 0x32, 0x3e, 0x86, 0x15, 0x2d, 0x5b, 0x64, 0x78, 0x61, 0xc2, 0x42, 0xd2, 0xf0,
0x82, 0x6a, 0x36, 0xc7, 0x18, 0x9b, 0xb0, 0xce, 0x92, 0x9d, 0x0b, 0xea, 0x86, 0x83, 0xf9, 0x09,
0xf7, 0xce, 0x3b, 0x9e, 0xcb, 0xd4, 0xef, 0xb2, 0xc2, 0x5c, 0xbf, 0x4b, 0xb6, 0x85, 0x8d, 0x86,
0xb3, 0xc5, 0x2d, 0xad, 0x06, 0xcc, 0xb8, 0x8d, 0x7f, 0x63, 0xb6, 0x9a, 0xb2, 0x02, 0xb1, 0x61,
0x3d, 0xea, 0x74, 0x4c, 0xab, 0xdf, 0x3b, 0xe8, 0xf6, 0xd8, 0xe1, 0xc0, 0x86, 0x15, 0x01, 0x7b,
0x7b, 0x08, 0xc9, 0x18, 0x0d, 0xa8, 0x3f, 0xa1, 0x61, 0xd7, 0x3d, 0xf5, 0xc4, 0x60, 0x18, 0x7f,
0x61, 0x09, 0x96, 0x15, 0x28, 0xb2, 0xf5, 0x5c, 0x50, 0x3f, 0x70, 0x3c, 0x17, 0xd7, 0x49, 0xd9,
0x94, 0x49, 0xc6, 0xde, 0x84, 0x96, 0x86, 0x62, 0xc6, 0x1a, 0x62, 0x85, 0x5e, 0x87, 0x32, 0xc6,
0x3b, 0xb0, 0xec, 0x8c, 0xa9, 0x1b, 0x3a, 0xe1, 0x95, 0x15, 0xb3, 0x32, 0xd7, 0x25, 0x58, 0xc8,
0x19, 0x6b, 0x50, 0xb0, 0x27, 0x8e, 0x2d, 0xa3, 0x1e, 0x78, 0x82, 0x41, 0x47, 0xde, 0xc4, 0xf3,
0x51, 0x6f, 0x29, 0x9b, 0x3c, 0x41, 0x1e, 0xc0, 0x1a, 0xd3, 0xa1, 0x74, 0xd3, 0x3f, 0x72, 0x28,
0x6e, 0xf0, 0x26, 0xee, 0x7c, 0x7a, 0x14, 0x99, 0xff, 0x19, 0x86, 0x49, 0x17, 0x2c, 0x87, 0x10,
0x27, 0x55, 0x06, 0x6e, 0x95, 0x58, 0x71, 0xe7, 0xd3, 0x16, 0x62, 0x14, 0xfd, 0x43, 0x58, 0x67,
0xf4, 0x4a, 0x00, 0x55, 0x39, 0x96, 0x31, 0x07, 0x2b, 0xac, 0x2b, 0x70, 0x2a, 0xcf, 0x2d, 0x28,
0xf3, 0x56, 0xb1, 0x25, 0x51, 0xe0, 0x36, 0x0b, 0x6c, 0x0a, 0xf5, 0x83, 0x85, 0x00, 0x05, 0x6e,
0x08, 0x48, 0x06, 0x28, 0x68, 0x21, 0x0e, 0xa5, 0x64, 0x88, 0xc3, 0x43, 0x58, 0x3f, 0x61, 0x6b,
0xf4, 0x9c, 0xda, 0x63, 0xea, 0x5b, 0xd1, 0xca, 0xe7, 0xea, 0xe6, 0x2a, 0x43, 0xee, 0x23, 0x4e,
0x6d, 0x14, 0x26, 0x09, 0x32, 0xc6, 0x43, 0xc7, 0x56, 0xe8, 0x59, 0x28, 0x20, 0x22, 0x0b, 0x2b,
0x99, 0x35, 0x0e, 0x1e, 0x7a, 0x6d, 0x06, 0x8c, 0xd3, 0x9d, 0xf9, 0xf6, 0xec, 0x5c, 0x28, 0x83,
0x8a, 0xee, 0x09, 0x03, 0x92, 0xd7, 0xa0, 0xc8, 0xf6, 0x84, 0x4b, 0xb9, 0xbf, 0x97, 0xab, 0x59,
0x12, 0x44, 0xde, 0x82, 0x25, 0xac, 0x23, 0x68, 0x36, 0x70, 0x43, 0x54, 0xa3, 0xa3, 0xc2, 0x71,
0x4d, 0x81, 0x63, 0xe2, 0xf6, 0xdc, 0x77, 0x38, 0x1f, 0x2b, 0x9b, 0xf8, 0x9b, 0xfc, 0x50, 0x63,
0x8a, 0xab, 0x98, 0xf7, 0x2d, 0x91, 0x37, 0xb1, 0x14, 0xaf, 0xe3, 0x8f, 0xdf, 0x2a, 0xb7, 0xfa,
0x51, 0xbe, 0x54, 0x69, 0x54, 0x8d, 0x26, 0xc6, 0x65, 0x98, 0x74, 0xe4, 0x5d, 0x50, 0xff, 0x2a,
0xb6, 0x47, 0x32, 0xb0, 0xb9, 0x80, 0x8a, 0xdc, 0xbb, 0xbe, 0x80, 0x5b, 0x53, 0x6f, 0x2c, 0x85,
0x82, 0xaa, 0x04, 0x1e, 0x7a, 0x63, 0x26, 0xbc, 0xac, 0x28, 0xa2, 0x53, 0xc7, 0x75, 0x82, 0x73,
0x3a, 0x16, 0xb2, 0x41, 0x43, 0x22, 0xf6, 0x04, 0x9c, 0x49, 0xe0, 0x33, 0xdf, 0x3b, 0x53, 0x47,
0x65, 0xc6, 0x54, 0x69, 0xe3, 0x13, 0x28, 0xf0, 0x19, 0x64, 0x1b, 0x05, 0xe7, 0x37, 0x23, 0x36,
0x0a, 0x42, 0x9b, 0x50, 0x74, 0x69, 0xf8, 0xdc, 0xf3, 0x9f, 0x49, 0x5f, 0x91, 0x48, 0x1a, 0x3f,
0x41, 0xc3, 0xa5, 0x0a, 0xb0, 0xe1, 0xc6, 0x07, 0xb6, 0x84, 0xf9, 0x12, 0x0c, 0xce, 0x6d, 0x61,
0x4b, 0x2d, 0x21, 0x60, 0x70, 0x6e, 0x2f, 0x2c, 0xe1, 0xec, 0x62, 0x8c, 0xcd, 0x5b, 0x50, 0x97,
0x21, 0x3d, 0x81, 0x35, 0xa1, 0xa7, 0xa1, 0xd8, 0x92, 0x55, 0x11, 0xcf, 0x13, 0x1c, 0xd0, 0xd3,
0xd0, 0x38, 0x84, 0x15, 0xb1, 0x69, 0xfa, 0x33, 0x2a, 0xab, 0xfe, 0x34, 0x4d, 0x2b, 0xaa, 0x3c,
0x5c, 0x8d, 0x8b, 0x1b, 0x5c, 0xb0, 0x8b, 0xa9, 0x4a, 0xc6, 0x8f, 0x23, 0x0b, 0x22, 0x13, 0x46,
0x44, 0x79, 0x42, 0x37, 0x91, 0x2e, 0x36, 0xe9, 0xa9, 0x56, 0x1a, 0x90, 0x33, 0x66, 0xa3, 0x13,
0xcc, 0x47, 0x23, 0x19, 0x6a, 0x55, 0x32, 0x65, 0xd2, 0xf8, 0x77, 0x19, 0x58, 0xc5, 0xc2, 0xa4,
0x56, 0x27, 0x4e, 0x8a, 0x9f, 0xba, 0x91, 0x6c, 0x7e, 0x74, 0x09, 0x90, 0x27, 0xbe, 0xb9, 0xfb,
0x22, 0xbf, 0xe0, 0xbe, 0xf8, 0x2e, 0x34, 0xc6, 0x74, 0xe2, 0xe0, 0x52, 0x92, 0x02, 0x15, 0x97,
0x60, 0x97, 0x25, 0x5c, 0x58, 0x19, 0x8c, 0xbf, 0x9a, 0x81, 0x15, 0x2e, 0xaf, 0xa1, 0xdd, 0x46,
0x0c, 0xd4, 0x63, 0x69, 0xa0, 0x10, 0xec, 0x54, 0xf4, 0x29, 0x92, 0x63, 0x10, 0xca, 0x89, 0xf7,
0x6f, 0x08, 0xc3, 0x85, 0x80, 0x92, 0xef, 0xa3, 0x26, 0xea, 0x5a, 0x08, 0x14, 0x72, 0xf8, 0xcd,
0x14, 0x09, 0x51, 0x65, 0x67, 0x6a, 0xaa, 0x8b, 0xa0, 0x9d, 0x12, 0x2c, 0x71, 0x2b, 0x98, 0xb1,
0x07, 0xb5, 0x58, 0x35, 0x31, 0x6f, 0x4a, 0x95, 0x7b, 0x53, 0x16, 0xbc, 0x9b, 0xd9, 0x45, 0xef,
0xe6, 0x15, 0xac, 0x9a, 0xd4, 0x1e, 0x5f, 0xed, 0x79, 0xfe, 0x51, 0x70, 0x12, 0xee, 0x71, 0x21,
0x98, 0x9d, 0x41, 0xca, 0x65, 0x1f, 0x73, 0x59, 0x48, 0xcf, 0xad, 0x34, 0xc3, 0x7c, 0x07, 0xea,
0x91, 0x6f, 0x5f, 0x33, 0x7b, 0xd7, 0x94, 0x7b, 0x1f, 0x65, 0x27, 0x02, 0xf9, 0x59, 0x70, 0x12,
0x0a, 0xc3, 0x37, 0xfe, 0x36, 0xfe, 0x77, 0x1e, 0x08, 0x5b, 0xcd, 0x89, 0x05, 0x93, 0x88, 0x4a,
0xc8, 0x2e, 0x44, 0x25, 0x3c, 0x00, 0xa2, 0x11, 0xc8, 0x60, 0x89, 0x9c, 0x0a, 0x96, 0x68, 0x44,
0xb4, 0x22, 0x56, 0xe2, 0x01, 0xac, 0x09, 0x8d, 0x22, 0xde, 0x54, 0xbe, 0x34, 0x08, 0x57, 0x2d,
0x62, 0xed, 0x95, 0x11, 0x09, 0xd2, 0x52, 0x9d, 0xe3, 0x11, 0x09, 0xd2, 0xa0, 0xa4, 0x2d, 0xc0,
0xa5, 0x97, 0x2e, 0xc0, 0xe2, 0xc2, 0x02, 0xd4, 0x8c, 0x8b, 0xa5, 0xb8, 0x71, 0x71, 0xc1, 0x4c,
0xce, 0xc5, 0xe7, 0x98, 0x99, 0xfc, 0x1e, 0x34, 0xa4, 0xa1, 0x49, 0x99, 0x30, 0x79, 0x28, 0x91,
0x30, 0x22, 0xb7, 0xa5, 0x11, 0x33, 0xe6, 0x37, 0xab, 0x24, 0xfc, 0x66, 0xef, 0xc2, 0x4a, 0xc0,
0xd6, 0xaf, 0x35, 0x77, 0x45, 0x3c, 0x21, 0x1d, 0xa3, 0x3e, 0x5e, 0x32, 0x1b, 0x88, 0x38, 0x8e,
0xe0, 0x8b, 0x26, 0xb9, 0x5a, 0x8a, 0x49, 0xee, 0x51, 0xe4, 0xa2, 0x0f, 0xce, 0x9d, 0x29, 0x0a,
0x3e, 0x51, 0x8c, 0x9c, 0x18, 0xe0, 0xc1, 0xb9, 0x33, 0x35, 0x65, 0x3c, 0x08, 0x4b, 0x90, 0x36,
0xdc, 0x11, 0xfd, 0x49, 0x09, 0xe5, 0xe0, 0xa3, 0xb0, 0x8c, 0x92, 0xea, 0x16, 0x27, 0x3b, 0x4c,
0x44, 0x75, 0x24, 0x06, 0x85, 0x15, 0xc2, 0xad, 0xc0, 0x0d, 0x7d, 0x50, 0x0e, 0xed, 0x4b, 0xee,
0x37, 0xf8, 0x5f, 0x19, 0x68, 0xb0, 0x65, 0x17, 0xdb, 0xd1, 0x9f, 0x01, 0xf2, 0x9e, 0x57, 0xdc,
0xd0, 0x15, 0x46, 0x2b, 0xf7, 0xf3, 0x27, 0x80, 0x1b, 0xd4, 0xf2, 0x66, 0xd4, 0x15, 0xdb, 0xb9,
0x19, 0xdf, 0xce, 0x11, 0xcb, 0xde, 0xbf, 0xc1, 0x15, 0x3e, 0x06, 0x21, 0x9f, 0x41, 0x99, 0xed,
0x03, 0x5c, 0x94, 0x22, 0xc2, 0x74, 0x4b, 0x29, 0xf1, 0x0b, 0x5b, 0x92, 0x65, 0x9d, 0x89, 0x64,
0x5a, 0x10, 0x47, 0x3e, 0x25, 0x88, 0x43, 0xe3, 0x17, 0xfb, 0x00, 0x4f, 0xe9, 0xd5, 0x81, 0x37,
0x42, 0x73, 0xca, 0x6d, 0x00, 0xb6, 0x75, 0x4e, 0xed, 0xa9, 0x23, 0x0c, 0x89, 0x05, 0xb3, 0xfc,
0x8c, 0x5e, 0xed, 0x21, 0x80, 0xad, 0x1b, 0x86, 0x8e, 0x98, 0x46, 0xc1, 0x2c, 0x3d, 0xa3, 0x57,
0x9c, 0x63, 0x58, 0x50, 0x7b, 0x4a, 0xaf, 0x76, 0x29, 0x17, 0xcc, 0x3d, 0x9f, 0xad, 0x59, 0xdf,
0x7e, 0xce, 0x24, 0xf1, 0x58, 0x00, 0x46, 0xc5, 0xb7, 0x9f, 0x3f, 0xa5, 0x57, 0x32, 0x18, 0xa4,
0xc8, 0xf0, 0x13, 0x6f, 0x24, 0x44, 0x09, 0x69, 0xbb, 0x89, 0x1a, 0x65, 0x2e, 0x3d, 0xc3, 0xdf,
0xc6, 0x9f, 0x64, 0xa0, 0xc6, 0xda, 0x8f, 0xa7, 0x00, 0xae, 0x10, 0x11, 0x91, 0x98, 0x89, 0x22,
0x12, 0x1f, 0x0a, 0x26, 0xca, 0x8f, 0x94, 0xec, 0xf5, 0x47, 0x0a, 0xce, 0x0d, 0x3f, 0x4f, 0x3e,
0x80, 0x32, 0xe7, 0x02, 0x8c, 0xad, 0xe4, 0x62, 0x13, 0x1c, 0xeb, 0x90, 0x59, 0x42, 0xb2, 0xa7,
0x3c, 0x00, 0x4a, 0x33, 0x93, 0xf3, 0x21, 0x2e, 0xfb, 0xca, 0x38, 0x9e, 0x32, 0x0d, 0x85, 0x6b,
0x02, 0xa0, 0x74, 0x1b, 0xf4, 0x52, 0xd2, 0x06, 0x6d, 0xb8, 0x50, 0x62, 0x53, 0x8d, 0x9d, 0x4d,
0x29, 0x34, 0x93, 0x56, 0x28, 0x13, 0x3c, 0x6c, 0x76, 0x06, 0x31, 0xbe, 0x9a, 0x15, 0x82, 0x87,
0x1d, 0x50, 0x56, 0x10, 0x6b, 0xb8, 0xeb, 0x59, 0x68, 0xd4, 0x15, 0xe6, 0xce, 0x92, 0x59, 0x76,
0xbd, 0x23, 0x0e, 0x30, 0xfe, 0x5c, 0x06, 0x2a, 0xda, 0x7e, 0x44, 0x2b, 0xbf, 0x1a, 0x4e, 0xbe,
0x79, 0xe3, 0x3b, 0x20, 0x36, 0x1f, 0xfb, 0x37, 0xcc, 0xda, 0x28, 0x36, 0x41, 0xdb, 0x62, 0x29,
0x63, 0xce, 0x6c, 0xcc, 0xb4, 0x24, 0xfb, 0x25, 0xd7, 0x2f, 0xfb, 0xbd, 0xb3, 0x04, 0x79, 0x46,
0x6a, 0x3c, 0x86, 0x15, 0xad, 0x19, 0xdc, 0xf4, 0xf2, 0xaa, 0x03, 0x60, 0xfc, 0xb2, 0xca, 0xcc,
0xea, 0xe0, 0xae, 0x69, 0x19, 0x6b, 0x46, 0xc7, 0x7c, 0x5c, 0x44, 0x4c, 0x1b, 0x07, 0xe1, 0xc8,
0xbc, 0x6a, 0xfc, 0xd3, 0xaf, 0xc2, 0xaa, 0x56, 0xfa, 0x9e, 0xe3, 0xda, 0x13, 0xe7, 0x27, 0x28,
0x7e, 0x04, 0xce, 0x99, 0x9b, 0x28, 0x9f, 0x83, 0xbe, 0x51, 0xf9, 0x7f, 0x2d, 0x0b, 0x6b, 0xa2,
0x02, 0x8c, 0x1e, 0x76, 0x98, 0x4c, 0x79, 0x18, 0x9c, 0x91, 0xcf, 0xa0, 0xc6, 0xc6, 0xc6, 0xf2,
0xe9, 0x99, 0x13, 0x84, 0x54, 0xba, 0xc4, 0x53, 0xd8, 0x28, 0x13, 0x2d, 0x18, 0xa9, 0x29, 0x28,
0xc9, 0x63, 0xa8, 0x60, 0x56, 0x6e, 0xda, 0x12, 0x13, 0xd1, 0x5c, 0xcc, 0xc8, 0x07, 0x7a, 0xff,
0x86, 0x09, 0x41, 0x34, 0xec, 0x8f, 0xa1, 0x82, 0x73, 0x78, 0x81, 0x03, 0x99, 0xe0, 0x64, 0x0b,
0x03, 0xcd, 0x32, 0xcf, 0xa2, 0x61, 0x6f, 0x41, 0x8d, 0xf3, 0x32, 0x31, 0x4e, 0x22, 0x2a, 0x71,
0x6b, 0x31, 0xbb, 0x1c, 0x49, 0xd6, 0xf8, 0x99, 0x96, 0xde, 0x29, 0x43, 0x31, 0xf4, 0x9d, 0xb3,
0x33, 0xea, 0x1b, 0x1b, 0x6a, 0x68, 0x18, 0x93, 0xa6, 0x83, 0x90, 0xce, 0x98, 0xb2, 0x60, 0xfc,
0xcb, 0x0c, 0x54, 0x04, 0xdb, 0xfd, 0xa9, 0xfd, 0xf0, 0x5b, 0x09, 0x23, 0x68, 0x59, 0xb3, 0x79,
0xbe, 0x03, 0xcb, 0x53, 0xa6, 0xd9, 0x30, 0xcd, 0x3b, 0xe6, 0x84, 0xaf, 0x4b, 0xb0, 0x10, 0xda,
0xb7, 0x61, 0x15, 0x65, 0xf8, 0xc0, 0x0a, 0x9d, 0x89, 0x25, 0x91, 0x22, 0x84, 0x7e, 0x85, 0xa3,
0x86, 0xce, 0xe4, 0x50, 0x20, 0x98, 0x28, 0x1b, 0x84, 0xf6, 0x19, 0x15, 0x5b, 0x9f, 0x27, 0x98,
0xb6, 0x94, 0x50, 0xba, 0xa5, 0xb6, 0xf4, 0x7f, 0x57, 0x60, 0x73, 0x01, 0x25, 0xb4, 0x25, 0xe5,
0x75, 0x9d, 0x38, 0xd3, 0x13, 0x4f, 0x59, 0xfd, 0x33, 0x9a, 0xd7, 0xf5, 0x80, 0x61, 0xa4, 0xd5,
0x9f, 0xc2, 0xba, 0x5c, 0x90, 0x68, 0xb6, 0x57, 0x7a, 0x79, 0x16, 0xb5, 0xc6, 0x0f, 0xe2, 0x67,
0x5c, 0xb2, 0x3a, 0x09, 0xd7, 0x05, 0xb5, 0xd5, 0xd9, 0x02, 0x2c, 0x20, 0x7f, 0x1a, 0x9a, 0x6a,
0xdd, 0x0b, 0x25, 0x42, 0x33, 0x32, 0xb0, 0x9a, 0xde, 0x7b, 0x49, 0x4d, 0x31, 0x7b, 0x2a, 0x4a,
0x72, 0x1b, 0x72, 0xcb, 0xf0, 0x02, 0x55, 0x5d, 0x17, 0xf0, 0xba, 0xac, 0x0b, 0x95, 0x82, 0xc5,
0x1a, 0xf3, 0xaf, 0xd4, 0x37, 0xb4, 0x15, 0xc7, 0xaa, 0x35, 0x6f, 0x89, 0x82, 0x15, 0x4a, 0xaf,
0xf7, 0x1c, 0x36, 0x9e, 0xdb, 0x4e, 0x28, 0xfb, 0xa8, 0xd9, 0x38, 0x0a, 0x58, 0xdf, 0xc3, 0x97,
0xd4, 0xf7, 0x25, 0xcf, 0x1c, 0x53, 0x93, 0xd6, 0x9e, 0x2f, 0x02, 0x83, 0xad, 0xbf, 0x93, 0x83,
0x7a, 0xbc, 0x14, 0xc6, 0x58, 0xc4, 0x59, 0x24, 0xa5, 0x5f, 0x21, 0x92, 0x0b, 0x8f, 0x54, 0x8f,
0x4b, 0xbd, 0x8b, 0xbe, 0xb2, 0x6c, 0x8a, 0xaf, 0x4c, 0x77, 0x51, 0xe5, 0x5e, 0x16, 0xb1, 0x90,
0x7f, 0xa5, 0x88, 0x85, 0x42, 0x5a, 0xc4, 0xc2, 0x87, 0xd7, 0xba, 0xb8, 0xb9, 0xa1, 0x39, 0xd5,
0xbd, 0xfd, 0xe8, 0x7a, 0xf7, 0x36, 0x97, 0xa5, 0xaf, 0x73, 0x6d, 0x6b, 0x8e, 0xf9, 0xd2, 0x35,
0x8e, 0x25, 0xcd, 0x55, 0x9f, 0xe2, 0xda, 0x2e, 0x7f, 0x03, 0xd7, 0xf6, 0xd6, 0x9f, 0x64, 0x80,
0x2c, 0xee, 0x0e, 0xf2, 0x84, 0xbb, 0x21, 0x5d, 0x3a, 0x11, 0x9c, 0xfb, 0x7b, 0xaf, 0xb6, 0xc3,
0xe4, 0x82, 0x90, 0xb9, 0xc9, 0xfb, 0xb0, 0xaa, 0x5f, 0xf4, 0xd1, 0x6d, 0x08, 0x35, 0x93, 0xe8,
0xa8, 0xc8, 0x1a, 0xa6, 0x85, 0x87, 0xe4, 0x5f, 0x1a, 0x1e, 0x52, 0x78, 0x69, 0x78, 0xc8, 0x52,
0x3c, 0x3c, 0x64, 0xeb, 0xdf, 0x66, 0x60, 0x35, 0x65, 0x11, 0x7f, 0x7b, 0x7d, 0x66, 0x6b, 0x2f,
0xc6, 0xd6, 0xb2, 0x62, 0xed, 0xe9, 0x1c, 0xed, 0x40, 0x5a, 0x50, 0xd9, 0x54, 0x04, 0xe2, 0xa4,
0xba, 0xff, 0x32, 0xee, 0x12, 0xe5, 0x30, 0xf5, 0xec, 0x5b, 0x7f, 0x2f, 0x0b, 0x15, 0x0d, 0xc9,
0x46, 0x91, 0x2f, 0x59, 0x2d, 0x38, 0x91, 0x0b, 0x8e, 0x68, 0x01, 0xb9, 0x03, 0xc2, 0xd1, 0xc4,
0xf1, 0x7c, 0x73, 0x09, 0x29, 0x11, 0x09, 0xb6, 0x61, 0x55, 0xba, 0x88, 0x69, 0x14, 0xaf, 0x2c,
0xce, 0x1a, 0xe1, 0xed, 0x17, 0x8d, 0x44, 0xfa, 0xf7, 0xa5, 0x72, 0x1a, 0xcd, 0x9d, 0xe6, 0x72,
0x5b, 0x11, 0x71, 0x06, 0x62, 0x12, 0xd9, 0x3a, 0xff, 0x00, 0xd6, 0x55, 0xa0, 0x41, 0x2c, 0x07,
0x77, 0xec, 0x10, 0x19, 0x50, 0xa0, 0x65, 0xf9, 0x21, 0xdc, 0x4e, 0xb4, 0x29, 0x91, 0x95, 0x07,
0xd6, 0xdf, 0x8c, 0xb5, 0x4e, 0x2f, 0x61, 0xeb, 0xcf, 0x40, 0x2d, 0xc6, 0x28, 0xbf, 0xbd, 0x29,
0x4f, 0x5a, 0x9d, 0xf8, 0x88, 0xea, 0x56, 0xa7, 0xad, 0xff, 0x99, 0x03, 0xb2, 0xc8, 0xab, 0x7f,
0x9e, 0x4d, 0x58, 0x5c, 0x98, 0xb9, 0x94, 0x85, 0xf9, 0xff, 0x4d, 0x7e, 0x88, 0x8c, 0x9f, 0x9a,
0x9f, 0x9f, 0x6f, 0xce, 0x86, 0x42, 0xc8, 0x56, 0x7c, 0x92, 0x8c, 0x86, 0x2a, 0xc5, 0xee, 0xaa,
0x69, 0x02, 0x54, 0x22, 0x28, 0xea, 0x18, 0x96, 0x6c, 0x77, 0x74, 0xee, 0xf9, 0x82, 0x0f, 0xfe,
0xc2, 0x37, 0x3e, 0x3e, 0xb7, 0x5b, 0x98, 0x1f, 0xa5, 0x36, 0x53, 0x14, 0x66, 0x7c, 0x00, 0x15,
0x0d, 0x4c, 0xca, 0x50, 0x38, 0xe8, 0x1e, 0xee, 0xf4, 0x1b, 0x37, 0x48, 0x0d, 0xca, 0x66, 0xa7,
0xdd, 0xff, 0xa2, 0x63, 0x76, 0x76, 0x1b, 0x19, 0x52, 0x82, 0xfc, 0x41, 0x7f, 0x30, 0x6c, 0x64,
0x8d, 0x2d, 0x68, 0x8a, 0x12, 0x17, 0xdd, 0x40, 0xbf, 0x95, 0x57, 0xc6, 0x4b, 0x44, 0x0a, 0x0d,
0xfe, 0x43, 0xa8, 0xea, 0xe2, 0x8d, 0x58, 0x11, 0x89, 0x50, 0x13, 0xa6, 0xbb, 0x7b, 0x1a, 0xaf,
0x6e, 0x03, 0x0f, 0x34, 0x18, 0xab, 0x6c, 0xd9, 0x98, 0xdc, 0x9a, 0xe2, 0xb1, 0x45, 0xe5, 0x27,
0xb6, 0x0c, 0xff, 0x14, 0xd4, 0xe3, 0x2e, 0x0f, 0xc1, 0x91, 0xd2, 0xf4, 0x51, 0x96, 0x3b, 0xe6,
0x03, 0x21, 0x3f, 0x84, 0x46, 0xd2, 0x65, 0x22, 0x84, 0xe7, 0x6b, 0xf2, 0x2f, 0x3b, 0x71, 0x2f,
0x0a, 0xd9, 0x87, 0xb5, 0x34, 0x01, 0x0f, 0xd7, 0xc7, 0xf5, 0x36, 0x0c, 0xb2, 0x28, 0xc4, 0x91,
0x4f, 0x85, 0xeb, 0xac, 0x80, 0xd3, 0xff, 0x56, 0xbc, 0x7e, 0x6d, 0xb0, 0xb7, 0xf9, 0x3f, 0xcd,
0x89, 0x76, 0x01, 0x10, 0xc1, 0x48, 0x03, 0xaa, 0xfd, 0xa3, 0x4e, 0xcf, 0x6a, 0xef, 0xb7, 0x7a,
0xbd, 0xce, 0x41, 0xe3, 0x06, 0x21, 0x50, 0xc7, 0x68, 0x89, 0x5d, 0x05, 0xcb, 0x30, 0x98, 0x70,
0x61, 0x4a, 0x58, 0x96, 0xac, 0x41, 0xa3, 0xdb, 0x4b, 0x40, 0x73, 0xa4, 0x09, 0x6b, 0x47, 0x1d,
0x1e, 0x60, 0x11, 0x2b, 0x37, 0xcf, 0x94, 0x06, 0xd1, 0x5d, 0xa6, 0x34, 0x7c, 0x69, 0x4f, 0x26,
0x34, 0x14, 0xfb, 0x40, 0xca, 0xd2, 0x7f, 0x3d, 0x03, 0xeb, 0x09, 0x44, 0xe4, 0x77, 0xe0, 0x92,
0x74, 0x5c, 0x86, 0xae, 0x22, 0x50, 0xee, 0xa6, 0x77, 0x61, 0x45, 0x99, 0xc1, 0x12, 0xa7, 0x52,
0x43, 0x21, 0x24, 0xf1, 0xfb, 0xb0, 0xaa, 0x59, 0xd3, 0x12, 0xbc, 0x82, 0x68, 0x28, 0x91, 0xc1,
0xd8, 0x54, 0xd7, 0x77, 0x12, 0xad, 0x1e, 0xc3, 0x46, 0x12, 0x11, 0x79, 0x16, 0xe3, 0xed, 0x95,
0x49, 0xf2, 0x20, 0xb1, 0x10, 0xe2, 0xad, 0xd5, 0x27, 0x5c, 0x56, 0xff, 0x3b, 0x4b, 0x40, 0x7e,
0x3c, 0xa7, 0xfe, 0x15, 0x5e, 0x1b, 0x0b, 0x5e, 0x16, 0x1b, 0x2d, 0x0d, 0x31, 0xd9, 0x57, 0xba,
0x1a, 0x9a, 0x76, 0x35, 0x33, 0xff, 0xf2, 0xab, 0x99, 0x85, 0x97, 0x5d, 0xcd, 0x7c, 0x13, 0x6a,
0xce, 0x99, 0xeb, 0x31, 0x56, 0xc8, 0x24, 0xe1, 0xa0, 0xb9, 0x74, 0x37, 0x77, 0xaf, 0x6a, 0x56,
0x05, 0x90, 0xc9, 0xc1, 0x01, 0x79, 0x1c, 0x11, 0xd1, 0xf1, 0x19, 0x5e, 0x4f, 0xd6, 0x99, 0x60,
0x67, 0x7c, 0x46, 0x85, 0xdd, 0x09, 0x35, 0x0d, 0x99, 0x99, 0xc1, 0x03, 0xf2, 0x16, 0xd4, 0x03,
0x6f, 0xce, 0x14, 0x0b, 0x39, 0x0c, 0xdc, 0xb5, 0x58, 0xe5, 0xd0, 0x23, 0xe9, 0x68, 0x5e, 0x9d,
0x07, 0xd4, 0x9a, 0x3a, 0x41, 0xc0, 0xc4, 0xb3, 0x91, 0xe7, 0x86, 0xbe, 0x37, 0x11, 0xde, 0xc2,
0x95, 0x79, 0x40, 0x0f, 0x39, 0xa6, 0xcd, 0x11, 0xe4, 0xa3, 0xa8, 0x49, 0x33, 0xdb, 0xf1, 0x83,
0x26, 0x60, 0x93, 0x64, 0x4f, 0x51, 0x7e, 0xb7, 0x1d, 0x5f, 0xb5, 0x85, 0x25, 0x82, 0xc4, 0x95,
0xd1, 0x4a, 0xf2, 0xca, 0xe8, 0xaf, 0xa5, 0x5f, 0x19, 0xe5, 0x01, 0x52, 0x0f, 0x44, 0xd1, 0x8b,
0x53, 0xfc, 0x8d, 0x6e, 0x8e, 0x2e, 0xde, 0x84, 0xad, 0x7f, 0x93, 0x9b, 0xb0, 0xcb, 0x69, 0x37,
0x61, 0x3f, 0x80, 0x0a, 0xde, 0x51, 0xb4, 0xce, 0x31, 0x4c, 0x92, 0x7b, 0x3f, 0x1b, 0xfa, 0x25,
0xc6, 0x7d, 0xc7, 0x0d, 0x4d, 0xf0, 0xe5, 0xcf, 0x60, 0xf1, 0x52, 0xea, 0xca, 0xcf, 0xf1, 0x52,
0xaa, 0xb8, 0x4b, 0xb9, 0x0d, 0x25, 0x39, 0x4f, 0x84, 0x40, 0xfe, 0xd4, 0xf7, 0xa6, 0xd2, 0xe3,
0xc2, 0x7e, 0x93, 0x3a, 0x64, 0x43, 0x4f, 0x64, 0xce, 0x86, 0x9e, 0xf1, 0x2b, 0x50, 0xd1, 0x96,
0x1a, 0x79, 0x83, 0x9b, 0x2d, 0x99, 0x6e, 0x26, 0x64, 0x4b, 0x3e, 0x8a, 0x65, 0x01, 0xed, 0x8e,
0x19, 0xbf, 0x19, 0x3b, 0x3e, 0xc5, 0xeb, 0xe3, 0x96, 0x4f, 0x2f, 0xa8, 0x1f, 0x48, 0x0f, 0x58,
0x43, 0x21, 0x4c, 0x0e, 0x37, 0x7e, 0x15, 0x56, 0x63, 0x73, 0x2b, 0x58, 0xc4, 0x5b, 0xb0, 0x84,
0xe3, 0x26, 0xc3, 0x2c, 0xe2, 0x97, 0x43, 0x05, 0x0e, 0xaf, 0xca, 0x73, 0xe7, 0x9d, 0x35, 0xf3,
0xbd, 0x13, 0xac, 0x24, 0x63, 0x56, 0x04, 0xec, 0xc8, 0xf7, 0x4e, 0x8c, 0x3f, 0xcc, 0x41, 0x6e,
0xdf, 0x9b, 0xe9, 0xa1, 0x95, 0x99, 0x85, 0xd0, 0x4a, 0xa1, 0x70, 0x5a, 0x4a, 0xa1, 0x14, 0x32,
0x3b, 0xba, 0xad, 0xa4, 0x52, 0x79, 0x0f, 0xea, 0x8c, 0x4f, 0x84, 0x1e, 0xd3, 0xd8, 0x9f, 0xdb,
0x3e, 0x17, 0x88, 0x79, 0xa4, 0x72, 0xd5, 0x9e, 0x86, 0x43, 0x6f, 0x8f, 0xc3, 0xc9, 0x1a, 0xe4,
0x94, 0xfa, 0x82, 0x68, 0x96, 0x24, 0x1b, 0xb0, 0x84, 0x17, 0x21, 0xae, 0x44, 0x98, 0x80, 0x48,
0x91, 0xef, 0xc1, 0x6a, 0xbc, 0x5c, 0xce, 0x8a, 0x84, 0x6c, 0xa4, 0x17, 0x8c, 0x3c, 0xe9, 0x26,
0x30, 0x3e, 0xc2, 0x69, 0x44, 0x3c, 0xd3, 0x29, 0xa5, 0x88, 0xd2, 0x98, 0x5e, 0x29, 0xc6, 0xf4,
0xee, 0x40, 0x25, 0x9c, 0x5c, 0x58, 0x33, 0xfb, 0x6a, 0xe2, 0xd9, 0x63, 0xb1, 0xbf, 0x21, 0x9c,
0x5c, 0x1c, 0x71, 0x08, 0x79, 0x1f, 0x60, 0x3a, 0x9b, 0x89, 0xbd, 0x87, 0xae, 0x98, 0x68, 0x29,
0x1f, 0x1e, 0x1d, 0xf1, 0x25, 0x67, 0x96, 0xa7, 0xb3, 0x19, 0xff, 0x49, 0x76, 0xa1, 0x9e, 0x7a,
0xc5, 0xfb, 0xb6, 0x0c, 0x58, 0xf7, 0x66, 0xdb, 0x29, 0x9b, 0xb3, 0x36, 0xd2, 0x61, 0x5b, 0x3f,
0x04, 0xf2, 0x33, 0x5e, 0xb4, 0x1e, 0x42, 0x59, 0xb5, 0x4f, 0xbf, 0xa7, 0x8c, 0x37, 0x71, 0x2a,
0xb1, 0x7b, 0xca, 0xad, 0xf1, 0xd8, 0x67, 0x7c, 0x91, 0x1f, 0x98, 0x8a, 0xe5, 0x83, 0x76, 0x62,
0x8a, 0xab, 0x1e, 0xc6, 0x7f, 0xc9, 0x40, 0x81, 0x5f, 0x9a, 0x7e, 0x1b, 0x96, 0x39, 0xbd, 0x0a,
0x53, 0x15, 0xc1, 0x05, 0xfc, 0xdc, 0x1d, 0x8a, 0x08, 0x55, 0xb6, 0x2d, 0xb4, 0x87, 0x24, 0xb2,
0x6a, 0xe6, 0xb5, 0xc7, 0x24, 0xee, 0x40, 0x59, 0x55, 0xad, 0x2d, 0x9d, 0x92, 0xac, 0x99, 0xbc,
0x0e, 0xf9, 0x73, 0x6f, 0x26, 0x2d, 0x3f, 0x10, 0x8d, 0xa4, 0x89, 0xf0, 0xa8, 0x2d, 0xac, 0x8e,
0xe8, 0x0a, 0x4a, 0x4e, 0xb4, 0x85, 0x55, 0x82, 0xcb, 0x60, 0xb1, 0x8f, 0x4b, 0x29, 0x7d, 0x3c,
0x86, 0x65, 0xc6, 0x07, 0xb4, 0x08, 0x87, 0xeb, 0x0f, 0xcd, 0xef, 0x32, 0x09, 0x6f, 0x34, 0x99,
0x8f, 0xa9, 0x6e, 0x7b, 0xc3, 0x98, 0x43, 0x01, 0x97, 0x92, 0xb5, 0xf1, 0x3b, 0x19, 0xce, 0x5f,
0x58, 0xb9, 0xe4, 0x1e, 0xe4, 0x5d, 0x19, 0x0d, 0x11, 0xc9, 0x71, 0xea, 0x4a, 0x14, 0xa3, 0x33,
0x91, 0x82, 0x4d, 0x1d, 0xc6, 0x10, 0xe8, 0xa5, 0xd7, 0xcc, 0x8a, 0x3b, 0x9f, 0x2a, 0xd3, 0xd5,
0x77, 0x64, 0xb7, 0x12, 0x66, 0x1f, 0xde, 0x7b, 0xb5, 0x4d, 0xb7, 0xb5, 0xe0, 0xc5, 0x7c, 0xec,
0xc4, 0x94, 0x52, 0xe0, 0xf8, 0x8c, 0x6a, 0x41, 0x8b, 0xbf, 0x97, 0x85, 0x5a, 0xac, 0x45, 0x18,
0xbd, 0xc9, 0x0e, 0x00, 0xee, 0x77, 0x12, 0xf3, 0x8d, 0x41, 0x72, 0x42, 0x50, 0xd7, 0xc6, 0x29,
0x1b, 0x1b, 0x27, 0x15, 0xce, 0x94, 0xd3, 0xc3, 0x99, 0x1e, 0x40, 0x39, 0x7a, 0x40, 0x24, 0xde,
0x24, 0x56, 0x9f, 0xbc, 0x18, 0x16, 0x11, 0x45, 0x01, 0x50, 0x05, 0x3d, 0x00, 0xea, 0x73, 0x2d,
0x5e, 0x66, 0x09, 0x8b, 0x31, 0xd2, 0x46, 0xf4, 0xe7, 0x12, 0x2d, 0x63, 0x3c, 0x86, 0x8a, 0xd6,
0x78, 0x3d, 0xe6, 0x24, 0x13, 0x8b, 0x39, 0x51, 0x17, 0x3b, 0xb3, 0xd1, 0xc5, 0x4e, 0xe3, 0xcf,
0x67, 0xa1, 0xc6, 0xf6, 0x97, 0xe3, 0x9e, 0x1d, 0x79, 0x13, 0x67, 0x84, 0x7e, 0x28, 0xb5, 0xc3,
0x84, 0xa0, 0x25, 0xf7, 0x99, 0xd8, 0x62, 0x5c, 0xce, 0xd2, 0x6f, 0xb5, 0x73, 0x26, 0xad, 0x6e,
0xb5, 0x1b, 0x50, 0x63, 0x8c, 0x11, 0x3d, 0x4a, 0xd1, 0x33, 0x24, 0x66, 0xe5, 0x94, 0xd2, 0x1d,
0x3b, 0xe0, 0x1c, 0xf2, 0x7b, 0xb0, 0xca, 0x68, 0xf0, 0x42, 0xef, 0xd4, 0x99, 0x4c, 0x9c, 0xe8,
0xce, 0x57, 0xce, 0x6c, 0x9c, 0x52, 0x6a, 0xda, 0x21, 0x3d, 0x64, 0x08, 0xf1, 0x6a, 0x49, 0x69,
0xec, 0x04, 0xf6, 0x49, 0x14, 0x63, 0xab, 0xd2, 0xe8, 0xe7, 0x16, 0x7e, 0xda, 0x68, 0x93, 0xe5,
0xcd, 0xca, 0x94, 0x7b, 0x69, 0x31, 0x7f, 0x62, 0x25, 0x15, 0x93, 0x2b, 0xc9, 0xf8, 0x67, 0x59,
0xa8, 0x68, 0xcb, 0xf2, 0x55, 0x4e, 0xd7, 0xdb, 0x0b, 0x7e, 0xc3, 0xb2, 0xee, 0x22, 0x7c, 0x33,
0x5e, 0x65, 0x4e, 0x5d, 0x0c, 0xd2, 0x17, 0xf0, 0x2d, 0x28, 0xb3, 0x5d, 0xf7, 0x01, 0x9a, 0x60,
0xc5, 0xab, 0x41, 0x08, 0x38, 0x9a, 0x9f, 0x48, 0xe4, 0x43, 0x44, 0x16, 0x22, 0xe4, 0x43, 0x86,
0x7c, 0xd1, 0xc5, 0x80, 0x4f, 0xa0, 0x2a, 0x4a, 0xc5, 0x39, 0xc5, 0xee, 0x46, 0xbb, 0x3e, 0x36,
0xdf, 0x66, 0x85, 0x57, 0xc7, 0x27, 0x5f, 0x64, 0x7c, 0x28, 0x33, 0x96, 0x5e, 0x96, 0xf1, 0x21,
0x4f, 0x18, 0x7b, 0xea, 0xae, 0x05, 0x46, 0xaa, 0x49, 0x3e, 0xf6, 0x3e, 0xac, 0x4a, 0x76, 0x35,
0x77, 0x6d, 0xd7, 0xf5, 0xe6, 0xee, 0x88, 0xca, 0xbb, 0x9d, 0x44, 0xa0, 0x8e, 0x23, 0x8c, 0x31,
0x56, 0x0f, 0x05, 0xf0, 0x88, 0xb7, 0xfb, 0x50, 0xe0, 0x72, 0x39, 0x17, 0x3e, 0xd2, 0x19, 0x17,
0x27, 0x21, 0xf7, 0xa0, 0xc0, 0xc5, 0xf3, 0xec, 0xb5, 0xcc, 0x86, 0x13, 0x18, 0x2d, 0x20, 0x2c,
0xe3, 0x21, 0x0d, 0x7d, 0x67, 0x14, 0x44, 0xd7, 0x46, 0x0b, 0x4c, 0xff, 0xe4, 0x75, 0x45, 0x96,
0xdb, 0x88, 0x12, 0x75, 0x54, 0x4e, 0xc3, 0x0e, 0xa6, 0xd5, 0x58, 0x19, 0x42, 0x5c, 0x9a, 0xc0,
0xc6, 0x09, 0x0d, 0x9f, 0x53, 0xea, 0xba, 0x4c, 0x18, 0x1a, 0x51, 0x37, 0xf4, 0xed, 0x09, 0x9b,
0x24, 0xde, 0x83, 0x47, 0x0b, 0xa5, 0x46, 0x36, 0x90, 0x9d, 0x28, 0x63, 0x5b, 0xe5, 0xe3, 0xbc,
0x63, 0xfd, 0x24, 0x0d, 0xb7, 0xf5, 0xcb, 0xb0, 0x75, 0x7d, 0xa6, 0x94, 0x2b, 0xe3, 0xf7, 0xe2,
0x5c, 0x45, 0xf9, 0x01, 0x27, 0x9e, 0x1d, 0xf2, 0xd6, 0xe8, 0x9c, 0xa5, 0x07, 0x15, 0x0d, 0x13,
0x9d, 0xfd, 0x19, 0x14, 0xee, 0x78, 0x82, 0x9d, 0x48, 0xae, 0xe7, 0x4f, 0xd1, 0xef, 0x36, 0xb6,
0xa2, 0xd2, 0x33, 0xe6, 0x72, 0x04, 0xc7, 0x18, 0x0b, 0x63, 0x1b, 0x96, 0x51, 0xb2, 0xd7, 0x0e,
0xba, 0x17, 0x09, 0x83, 0xc6, 0x1a, 0x90, 0x1e, 0xe7, 0x5d, 0x7a, 0xf4, 0xdf, 0xbf, 0xcf, 0x41,
0x45, 0x03, 0xb3, 0xd3, 0x08, 0x43, 0x26, 0xad, 0xb1, 0x63, 0x4f, 0xa9, 0x74, 0x72, 0xd6, 0xcc,
0x1a, 0x42, 0x77, 0x05, 0x90, 0x9d, 0xc5, 0xf6, 0xc5, 0x99, 0xe5, 0xcd, 0x43, 0x6b, 0x4c, 0xcf,
0x7c, 0x2a, 0x5b, 0x59, 0xb5, 0x2f, 0xce, 0xfa, 0xf3, 0x70, 0x17, 0x61, 0x8c, 0x8a, 0xf1, 0x12,
0x8d, 0x4a, 0x44, 0xd0, 0x4d, 0xed, 0xcb, 0x88, 0x4a, 0x84, 0x9a, 0xf2, 0x95, 0x99, 0x57, 0xa1,
0xa6, 0x5c, 0x5b, 0x4c, 0x1e, 0xa0, 0x85, 0xc5, 0x03, 0xf4, 0x23, 0xd8, 0xe0, 0x07, 0xa8, 0x60,
0xcd, 0x56, 0x62, 0x27, 0xaf, 0x21, 0x56, 0x74, 0x52, 0x13, 0x7b, 0x1b, 0xac, 0x07, 0x92, 0x2d,
0x05, 0xce, 0x4f, 0x38, 0x23, 0xcb, 0x98, 0xac, 0x67, 0xa2, 0xf0, 0x81, 0xf3, 0x13, 0xca, 0x28,
0x31, 0x56, 0x47, 0xa7, 0x14, 0xd7, 0x7e, 0xa6, 0x8e, 0x9b, 0xa4, 0xb4, 0x2f, 0xe3, 0x94, 0x65,
0x41, 0x69, 0x5f, 0xea, 0x94, 0x8f, 0x60, 0x73, 0x4a, 0xc7, 0x8e, 0x1d, 0x2f, 0xd6, 0x8a, 0x04,
0xb7, 0x35, 0x8e, 0xd6, 0xf2, 0x0c, 0xb8, 0xe2, 0xce, 0x46, 0xe3, 0x27, 0xde, 0xf4, 0xc4, 0xe1,
0x32, 0x0b, 0x8f, 0x1e, 0xca, 0x9b, 0x75, 0x77, 0x3e, 0xfd, 0x25, 0x04, 0xb3, 0x2c, 0x81, 0x51,
0x83, 0xca, 0x20, 0xf4, 0x66, 0x72, 0x9a, 0xeb, 0x50, 0xe5, 0x49, 0x71, 0x61, 0xfa, 0x16, 0xdc,
0x44, 0x96, 0x30, 0xf4, 0x66, 0xde, 0xc4, 0x3b, 0xbb, 0x8a, 0xd9, 0xf1, 0xfe, 0x55, 0x06, 0x56,
0x63, 0x58, 0xc1, 0x5e, 0x3f, 0xe2, 0xfc, 0x4c, 0x5d, 0xf7, 0xcc, 0xc4, 0xee, 0xfa, 0xb0, 0xf9,
0xe2, 0x84, 0x9c, 0x99, 0xc9, 0x2b, 0xa0, 0xad, 0xe8, 0x65, 0x17, 0x99, 0x91, 0xb3, 0x94, 0xe6,
0x22, 0x4b, 0x11, 0xf9, 0xe5, 0x9b, 0x2f, 0xb2, 0x88, 0x5f, 0x10, 0x57, 0xb3, 0xc6, 0xa2, 0xcb,
0xb9, 0xf8, 0xe5, 0x0d, 0xdd, 0xe6, 0x27, 0x5b, 0x10, 0x19, 0x02, 0x03, 0xe3, 0xef, 0x66, 0x00,
0xa2, 0xd6, 0xe1, 0xf5, 0x11, 0x25, 0xb7, 0x64, 0x30, 0x70, 0x57, 0x93, 0x51, 0xde, 0x80, 0xaa,
0x8a, 0xf1, 0x8e, 0x24, 0xa1, 0x8a, 0x84, 0x31, 0x71, 0xe8, 0x1d, 0x58, 0x3e, 0x9b, 0x78, 0x27,
0x28, 0xb1, 0x0a, 0xb9, 0x85, 0x47, 0xcf, 0xd5, 0x39, 0x58, 0x4a, 0x23, 0x91, 0xdc, 0x94, 0x4f,
0x0d, 0x03, 0xd7, 0xa5, 0x20, 0xe3, 0x2f, 0x67, 0x55, 0x20, 0x69, 0x34, 0x12, 0x2f, 0x56, 0xef,
0x7e, 0x9a, 0x50, 0x9b, 0x17, 0xb9, 0x17, 0x1f, 0x43, 0xdd, 0xe7, 0x87, 0x92, 0x3c, 0xb1, 0xf2,
0x2f, 0x38, 0xb1, 0x6a, 0x7e, 0x4c, 0xd2, 0xf9, 0x2e, 0x34, 0xec, 0xf1, 0x05, 0xf5, 0x43, 0x07,
0xad, 0xf5, 0x28, 0x1f, 0x8b, 0xd0, 0x4d, 0x0d, 0x8e, 0x82, 0xe8, 0x3b, 0xb0, 0x2c, 0x2e, 0xf1,
0x2b, 0x4a, 0xf1, 0x84, 0x58, 0x04, 0x66, 0x84, 0xc6, 0x3f, 0x94, 0x91, 0xab, 0xf1, 0xd9, 0x7d,
0xf1, 0xa8, 0xe8, 0x3d, 0xcc, 0x2e, 0x3a, 0x50, 0xc5, 0x42, 0x12, 0x4e, 0x00, 0xc1, 0x8f, 0x38,
0x50, 0xb8, 0x00, 0xe2, 0xc3, 0x9a, 0x7f, 0x95, 0x61, 0x35, 0xfe, 0x4d, 0x06, 0x8a, 0xfb, 0xde,
0x6c, 0xdf, 0xe1, 0xf7, 0x1f, 0x70, 0x9b, 0x28, 0x1f, 0xd5, 0x12, 0x4b, 0x62, 0x5c, 0xd0, 0x0b,
0xae, 0x41, 0xa6, 0x8a, 0x79, 0xb5, 0xb8, 0x98, 0xf7, 0x39, 0xdc, 0x42, 0x17, 0xa0, 0xef, 0xcd,
0x3c, 0x9f, 0x6d, 0x55, 0x7b, 0xc2, 0xc5, 0x3d, 0xcf, 0x0d, 0xcf, 0x25, 0xef, 0xbc, 0x79, 0x4a,
0xe9, 0x91, 0x46, 0x71, 0xa8, 0x08, 0xf0, 0x0a, 0xf4, 0x24, 0xbc, 0xb0, 0xb8, 0x86, 0x2e, 0xe4,
0x51, 0xce, 0x51, 0x97, 0x19, 0xa2, 0x83, 0x70, 0x94, 0x48, 0x8d, 0x4f, 0xa1, 0xac, 0x8c, 0x3d,
0xe4, 0x5d, 0x28, 0x9f, 0x7b, 0x33, 0x61, 0x11, 0xca, 0xc4, 0xae, 0x8a, 0x8a, 0x5e, 0x9b, 0xa5,
0x73, 0xfe, 0x23, 0x30, 0xfe, 0xb0, 0x08, 0xc5, 0xae, 0x7b, 0xe1, 0x39, 0x23, 0x8c, 0x7d, 0x9d,
0xd2, 0xa9, 0x27, 0x5f, 0x12, 0x61, 0xbf, 0x31, 0x74, 0x2b, 0x7a, 0x08, 0x2c, 0x27, 0x42, 0xb7,
0xd4, 0x13, 0x60, 0xeb, 0xb0, 0xe4, 0xeb, 0x2f, 0x79, 0x15, 0x7c, 0xbc, 0x31, 0xa0, 0xce, 0xcb,
0x82, 0xf6, 0x3e, 0x0b, 0x2b, 0x8b, 0x87, 0x25, 0xe2, 0x90, 0xf1, 0x6b, 0xcc, 0x65, 0x84, 0xe0,
0x80, 0xbd, 0x06, 0x45, 0x71, 0x33, 0x93, 0xdf, 0x13, 0xe3, 0x21, 0xfe, 0x02, 0x84, 0xab, 0xc1,
0xa7, 0xdc, 0x85, 0xab, 0x04, 0xd9, 0x9c, 0x59, 0x95, 0xc0, 0x5d, 0xb6, 0xd6, 0xee, 0x40, 0x85,
0xd3, 0x73, 0x92, 0x92, 0x08, 0x19, 0x45, 0x10, 0x12, 0xa4, 0x3c, 0x88, 0x57, 0x4e, 0x7d, 0x10,
0x0f, 0x83, 0x9b, 0x15, 0x97, 0xe5, 0x5d, 0x04, 0xfe, 0x0c, 0x9a, 0x06, 0x97, 0xaf, 0x4c, 0x0a,
0x9b, 0x0a, 0xbf, 0xe1, 0x2f, 0x6d, 0x2a, 0x6f, 0x42, 0xed, 0xd4, 0x9e, 0x4c, 0x4e, 0xec, 0xd1,
0x33, 0x6e, 0x0a, 0xa8, 0x72, 0xeb, 0xa7, 0x04, 0xa2, 0x2d, 0xe0, 0x0e, 0x54, 0xb4, 0x59, 0xc6,
0x78, 0xd0, 0xbc, 0x09, 0xd1, 0xfc, 0x26, 0x2d, 0x7c, 0xf5, 0x57, 0xb0, 0xf0, 0x69, 0x71, 0xb1,
0xcb, 0xf1, 0xb8, 0xd8, 0x5b, 0xc8, 0x4d, 0x45, 0x44, 0x62, 0x83, 0xbf, 0xb9, 0x65, 0x8f, 0xc7,
0x18, 0x91, 0x88, 0x86, 0x2c, 0x3e, 0x78, 0x1c, 0xbf, 0xc2, 0x75, 0x09, 0x0e, 0xe3, 0x24, 0xb7,
0xb9, 0x99, 0x7a, 0x66, 0x3b, 0x63, 0xbc, 0xa6, 0xc1, 0xad, 0x07, 0x45, 0x7b, 0x1a, 0x1e, 0xd9,
0xce, 0x98, 0xdc, 0x85, 0xaa, 0x44, 0xe3, 0xe9, 0xb8, 0xca, 0xc7, 0x5f, 0xa0, 0x07, 0xfc, 0xfd,
0x0a, 0x45, 0x31, 0x55, 0x57, 0xf4, 0xcd, 0x8a, 0x20, 0xc1, 0x75, 0xf0, 0x01, 0x46, 0xf9, 0x84,
0x14, 0x2f, 0xe1, 0xd7, 0x1f, 0xde, 0x52, 0xc1, 0x07, 0xb8, 0x4a, 0xe5, 0x7f, 0xee, 0x1c, 0xe3,
0x94, 0x4c, 0xb8, 0xe3, 0x3e, 0xba, 0x8d, 0x98, 0xfc, 0x2b, 0x48, 0xd1, 0x47, 0xc7, 0x09, 0xc8,
0xa7, 0x9a, 0xfe, 0xda, 0x44, 0xe2, 0xd7, 0x12, 0xe5, 0x5f, 0x77, 0x0f, 0xee, 0x36, 0x80, 0x13,
0xb0, 0x53, 0x26, 0xa0, 0xee, 0x18, 0xef, 0xd2, 0x97, 0xcc, 0xb2, 0x13, 0x3c, 0xe5, 0x80, 0x6f,
0x57, 0xb1, 0x6d, 0x41, 0x55, 0xef, 0x26, 0x29, 0x41, 0xbe, 0x7f, 0xd4, 0xe9, 0x35, 0x6e, 0x90,
0x0a, 0x14, 0x07, 0x9d, 0xe1, 0xf0, 0x00, 0x3d, 0x7d, 0x55, 0x28, 0xa9, 0x9b, 0xb2, 0x59, 0x96,
0x6a, 0xb5, 0xdb, 0x9d, 0xa3, 0x61, 0x67, 0xb7, 0x91, 0xfb, 0x51, 0xbe, 0x94, 0x6d, 0xe4, 0x8c,
0x3f, 0xca, 0x41, 0x45, 0x1b, 0x85, 0x17, 0x33, 0xe3, 0xdb, 0x00, 0xa8, 0x49, 0x46, 0x01, 0xab,
0x79, 0xb3, 0xcc, 0x20, 0x7c, 0xf2, 0x75, 0x1f, 0x05, 0x7f, 0xcc, 0x44, 0xf9, 0x28, 0xde, 0x84,
0x1a, 0x7f, 0x6e, 0x44, 0xf7, 0xd7, 0x16, 0xcc, 0x2a, 0x07, 0x0a, 0x56, 0x8d, 0xf7, 0xee, 0x91,
0x08, 0x6f, 0x34, 0x8a, 0xf7, 0x90, 0x38, 0x08, 0xef, 0x34, 0xe2, 0x85, 0xd4, 0xc0, 0x9b, 0x5c,
0x50, 0x4e, 0xc1, 0x25, 0xc2, 0x8a, 0x80, 0x0d, 0xc5, 0x9b, 0x06, 0x82, 0x1f, 0x6a, 0x17, 0xbf,
0x0b, 0x66, 0x95, 0x03, 0x45, 0x45, 0xdf, 0x93, 0x0b, 0x88, 0x47, 0xaf, 0x6c, 0x2e, 0xae, 0x86,
0xd8, 0xe2, 0x39, 0x58, 0x30, 0x23, 0x96, 0x71, 0x61, 0x7c, 0x67, 0x31, 0xdf, 0xcb, 0xcd, 0x89,
0xe4, 0x5d, 0x20, 0xd3, 0xd9, 0xcc, 0x4a, 0x31, 0xf0, 0xe5, 0xcd, 0xe5, 0xe9, 0x6c, 0x36, 0xd4,
0xec, 0x5f, 0xdf, 0x82, 0xed, 0xf1, 0x6b, 0x20, 0x2d, 0xb6, 0x81, 0xb1, 0x89, 0x4a, 0x15, 0x8b,
0xd8, 0x72, 0x46, 0x67, 0xcb, 0x29, 0xdc, 0x2f, 0x9b, 0xca, 0xfd, 0x5e, 0xc4, 0x27, 0x8c, 0x3d,
0xa8, 0x1c, 0x69, 0xaf, 0x2e, 0xde, 0x65, 0x27, 0x84, 0x7c, 0x6f, 0x91, 0x9f, 0x1d, 0xdc, 0xa6,
0xe8, 0x8b, 0x67, 0x16, 0xb5, 0xd6, 0x64, 0xb5, 0xd6, 0x18, 0x7f, 0x3b, 0xc3, 0x5f, 0xa9, 0x52,
0x8d, 0x8f, 0x1e, 0x7a, 0x94, 0xee, 0xb7, 0xe8, 0x7d, 0x86, 0x8a, 0x74, 0xbb, 0x89, 0xa7, 0x15,
0xb0, 0x69, 0x96, 0x77, 0x7a, 0x1a, 0x50, 0x19, 0xe3, 0x51, 0x41, 0x58, 0x1f, 0x41, 0x52, 0xf8,
0x66, 0x12, 0xbe, 0xc3, 0xcb, 0x0f, 0x44, 0x60, 0x07, 0x13, 0xbe, 0x0f, 0xed, 0x4b, 0x51, 0x6b,
0xc0, 0x44, 0x10, 0xe1, 0x1f, 0x90, 0xf7, 0x93, 0x55, 0xda, 0xf8, 0x1b, 0xe2, 0x09, 0x89, 0xe4,
0xf8, 0xde, 0x87, 0x92, 0x2a, 0x35, 0x7e, 0xc2, 0x4a, 0x4a, 0x85, 0x67, 0xe7, 0x38, 0x1a, 0x43,
0x62, 0x2d, 0xe6, 0x9b, 0x0b, 0x7d, 0x3c, 0x5d, 0xad, 0xd5, 0xef, 0x01, 0x39, 0x75, 0xfc, 0x24,
0x31, 0xdf, 0x6c, 0x0d, 0xc4, 0x68, 0xd4, 0xc6, 0x31, 0xac, 0x4a, 0x2e, 0xa1, 0x69, 0x04, 0xf1,
0xc9, 0xcb, 0xbc, 0x84, 0xc9, 0x67, 0x17, 0x98, 0xbc, 0xf1, 0x1b, 0x05, 0x28, 0xca, 0x17, 0x4c,
0xd3, 0x5e, 0xdd, 0x2c, 0xc7, 0x5f, 0xdd, 0x6c, 0xc6, 0xde, 0x62, 0xc3, 0xa9, 0x17, 0xe7, 0xfd,
0x3b, 0xc9, 0x23, 0x5b, 0xf3, 0x55, 0xc4, 0x8e, 0x6d, 0xe1, 0xab, 0x28, 0xc4, 0x7d, 0x15, 0x69,
0x2f, 0x91, 0x72, 0xd1, 0x73, 0xe1, 0x25, 0xd2, 0x5b, 0xc0, 0xe5, 0x08, 0x2d, 0xb8, 0xad, 0x84,
0x00, 0x71, 0xc7, 0x5e, 0x13, 0x3b, 0x4a, 0x49, 0xb1, 0xe3, 0x95, 0x45, 0x82, 0x8f, 0x60, 0x89,
0x3f, 0x47, 0x23, 0xee, 0x5b, 0xcb, 0x83, 0x43, 0x8c, 0x95, 0xfc, 0xcf, 0x2f, 0x44, 0x98, 0x82,
0x56, 0x7f, 0xd6, 0xaf, 0x12, 0x7b, 0xd6, 0x4f, 0xf7, 0xa1, 0x54, 0xe3, 0x3e, 0x94, 0x7b, 0xd0,
0x50, 0x03, 0x87, 0x16, 0x49, 0x37, 0x10, 0x77, 0x2d, 0xeb, 0x12, 0xce, 0xb8, 0x61, 0x2f, 0x88,
0x0e, 0xbe, 0x7a, 0xec, 0xe0, 0x63, 0xbc, 0xaa, 0x15, 0x86, 0x74, 0x3a, 0x0b, 0xe5, 0xc1, 0xa7,
0x3d, 0xfe, 0xca, 0x67, 0x9e, 0x5f, 0x06, 0x91, 0xd3, 0xcb, 0x57, 0xc7, 0x0e, 0xd4, 0x4f, 0x6d,
0x67, 0x32, 0xf7, 0xa9, 0xe5, 0x53, 0x3b, 0xf0, 0x5c, 0xdc, 0xfc, 0xd1, 0x19, 0x2c, 0xba, 0xb8,
0xc7, 0x69, 0x4c, 0x24, 0x31, 0x6b, 0xa7, 0x7a, 0x12, 0xaf, 0x54, 0xe9, 0x23, 0xc1, 0x8e, 0x2c,
0x71, 0xeb, 0x9a, 0xc7, 0xaa, 0x74, 0x7b, 0xd6, 0xde, 0x41, 0xf7, 0xc9, 0xfe, 0xb0, 0x91, 0x61,
0xc9, 0xc1, 0x71, 0xbb, 0xdd, 0xe9, 0xec, 0xe2, 0x11, 0x06, 0xb0, 0xb4, 0xd7, 0xea, 0x1e, 0x88,
0x03, 0x2c, 0xdf, 0x28, 0x18, 0xff, 0x34, 0x0b, 0x15, 0xad, 0x37, 0xe4, 0x91, 0x9a, 0x04, 0xfe,
0xce, 0xc3, 0xed, 0xc5, 0x1e, 0x6f, 0x4b, 0x0e, 0xaf, 0xcd, 0x82, 0x7a, 0xe6, 0x35, 0x7b, 0xed,
0x33, 0xaf, 0xe4, 0x6d, 0x58, 0xb6, 0x79, 0x09, 0x6a, 0xd0, 0x85, 0x71, 0x5f, 0x80, 0xc5, 0x98,
0xbf, 0x2d, 0xde, 0x9c, 0x10, 0xc7, 0x14, 0xa3, 0xcb, 0xcb, 0xa0, 0x4d, 0x75, 0x52, 0xe1, 0xdc,
0x14, 0xc5, 0xc8, 0x08, 0x67, 0xbc, 0x3a, 0xf0, 0xc5, 0x78, 0x49, 0x34, 0xbf, 0x67, 0xa9, 0xad,
0xf0, 0xaa, 0xa9, 0xd2, 0xc6, 0xc7, 0x00, 0x51, 0x7f, 0xe2, 0xc3, 0x77, 0x23, 0x3e, 0x7c, 0x19,
0x6d, 0xf8, 0xb2, 0xc6, 0x3f, 0x10, 0xac, 0x4b, 0xcc, 0x85, 0x32, 0xf5, 0x7d, 0x0f, 0xa4, 0xf1,
0xd1, 0xc2, 0x20, 0xef, 0xd9, 0x84, 0x86, 0xf2, 0xaa, 0xe8, 0x8a, 0xc0, 0x74, 0x15, 0x62, 0x81,
0xd5, 0x66, 0x17, 0x59, 0xed, 0x1b, 0x50, 0xc5, 0x47, 0xcc, 0x44, 0x45, 0x82, 0x5d, 0x55, 0xa6,
0xf6, 0xa5, 0xac, 0x3b, 0xc6, 0x63, 0xf3, 0x09, 0x1e, 0xfb, 0x37, 0x33, 0xfc, 0xc5, 0x9b, 0xa8,
0xa1, 0x11, 0x93, 0x55, 0x65, 0xc6, 0x99, 0xac, 0x20, 0x35, 0x15, 0xfe, 0x1a, 0xc6, 0x99, 0x4d,
0x67, 0x9c, 0xe9, 0x2c, 0x39, 0x97, 0xca, 0x92, 0x8d, 0x2d, 0x68, 0xee, 0x52, 0x36, 0x14, 0xad,
0xc9, 0x24, 0x31, 0x96, 0xc6, 0x2d, 0xb8, 0x99, 0x82, 0x13, 0x56, 0x9b, 0xdf, 0xcc, 0xc0, 0x7a,
0x8b, 0x3f, 0x74, 0xf1, 0xad, 0xdd, 0xe5, 0xfc, 0x0c, 0x6e, 0xaa, 0x88, 0x6d, 0xed, 0x8a, 0x98,
0xfe, 0x4a, 0x91, 0x0c, 0xf6, 0xd6, 0xee, 0x29, 0xb0, 0x33, 0xd3, 0x68, 0xc2, 0x46, 0xb2, 0x35,
0xa2, 0xa1, 0x7b, 0xb0, 0xb2, 0x4b, 0x4f, 0xe6, 0x67, 0x07, 0xf4, 0x22, 0x6a, 0x23, 0x81, 0x7c,
0x70, 0xee, 0x3d, 0x17, 0x0b, 0x03, 0x7f, 0x63, 0x48, 0x27, 0xa3, 0xb1, 0x82, 0x19, 0x1d, 0x49,
0xab, 0x3f, 0x42, 0x06, 0x33, 0x3a, 0x32, 0x1e, 0x01, 0xd1, 0xcb, 0x11, 0xb3, 0xc8, 0x54, 0xb2,
0xf9, 0x89, 0x15, 0x5c, 0x05, 0x21, 0x9d, 0xca, 0xeb, 0x8f, 0x10, 0xcc, 0x4f, 0x06, 0x1c, 0x62,
0xbc, 0x03, 0xd5, 0x23, 0xfb, 0xca, 0xa4, 0x5f, 0x8b, 0x5b, 0x86, 0x9b, 0x50, 0x9c, 0xd9, 0x57,
0x8c, 0x17, 0x2b, 0x07, 0x20, 0xa2, 0x8d, 0x7f, 0x94, 0x87, 0x25, 0x4e, 0x49, 0xee, 0xf2, 0x07,
0xd8, 0x1d, 0x17, 0x79, 0xa1, 0x3c, 0x95, 0x34, 0xd0, 0xc2, 0xc1, 0x95, 0x5d, 0x3c, 0xb8, 0x84,
0xb5, 0x52, 0xbe, 0xa2, 0x26, 0x5d, 0x35, 0xee, 0x7c, 0x2a, 0x9f, 0x4e, 0x8b, 0xbf, 0xf3, 0x90,
0x8f, 0x1e, 0xee, 0xe7, 0x77, 0xdc, 0xe3, 0xce, 0xf4, 0x48, 0xf1, 0xe3, 0xad, 0x93, 0xe7, 0xb1,
0x38, 0xb3, 0x74, 0x50, 0xaa, 0x76, 0x59, 0x94, 0x57, 0x67, 0xe3, 0xda, 0xe5, 0x82, 0x16, 0x59,
0x7a, 0xb9, 0x16, 0xc9, 0xcd, 0x98, 0x2f, 0xd0, 0x22, 0xe1, 0x15, 0xb4, 0xc8, 0x57, 0x70, 0x64,
0xdf, 0x84, 0x12, 0x0a, 0x59, 0xda, 0x11, 0xc6, 0x84, 0x2b, 0x76, 0x84, 0x7d, 0xa2, 0xe9, 0x59,
0x3c, 0x8a, 0x46, 0x3b, 0x43, 0x4c, 0xfa, 0xf5, 0xcf, 0xc7, 0x41, 0xf8, 0x15, 0x14, 0x05, 0x94,
0x2d, 0x68, 0xd7, 0x9e, 0xca, 0xf7, 0x38, 0xf1, 0x37, 0x1b, 0x36, 0x7c, 0x3d, 0xef, 0xeb, 0xb9,
0xe3, 0xd3, 0xb1, 0x7c, 0xc3, 0xcb, 0xc1, 0xfd, 0xcd, 0x20, 0xac, 0x83, 0x4c, 0xe7, 0x73, 0xbd,
0xe7, 0xae, 0xe0, 0x5b, 0x45, 0x27, 0x78, 0xca, 0x92, 0x06, 0x81, 0x06, 0xbe, 0xde, 0x3b, 0xf3,
0x7c, 0x29, 0x21, 0x18, 0xbf, 0x9b, 0x81, 0x86, 0xd8, 0x5d, 0x0a, 0xa7, 0xab, 0x5c, 0x85, 0xeb,
0x82, 0x3e, 0x5e, 0xfc, 0x22, 0x97, 0x01, 0x35, 0xb4, 0x34, 0x29, 0x71, 0x81, 0x5b, 0xca, 0x2a,
0x0c, 0xb8, 0x27, 0x44, 0x86, 0xd7, 0xa1, 0x22, 0x03, 0xce, 0xa7, 0xce, 0x44, 0x7e, 0xa3, 0x83,
0x47, 0x9c, 0x1f, 0x3a, 0x13, 0x29, 0x6d, 0xf8, 0xb6, 0xb8, 0xca, 0x9d, 0x41, 0x69, 0xc3, 0xb4,
0x43, 0x6a, 0xfc, 0x93, 0x0c, 0xac, 0x68, 0x5d, 0x11, 0xfb, 0xf6, 0xfb, 0x50, 0x55, 0xcf, 0x66,
0x53, 0x25, 0xe6, 0x6e, 0xc6, 0x79, 0x54, 0x94, 0xad, 0x32, 0x52, 0x90, 0x80, 0x35, 0x66, 0x6c,
0x5f, 0xf1, 0xa8, 0xe8, 0xf9, 0x54, 0x6a, 0x92, 0x63, 0xfb, 0x6a, 0x8f, 0xd2, 0xc1, 0x7c, 0x4a,
0xee, 0x42, 0xf5, 0x39, 0xa5, 0xcf, 0x14, 0x01, 0x67, 0xbd, 0xc0, 0x60, 0x82, 0xc2, 0x80, 0xda,
0xd4, 0x73, 0xc3, 0x73, 0x45, 0x22, 0x44, 0x7c, 0x04, 0x72, 0x1a, 0xe3, 0x0f, 0xb2, 0xb0, 0xca,
0xed, 0x99, 0xc2, 0x8e, 0x2c, 0x58, 0x57, 0x13, 0x96, 0xb8, 0x69, 0x97, 0x33, 0xaf, 0xfd, 0x1b,
0xa6, 0x48, 0x93, 0x8f, 0x5e, 0xd1, 0x06, 0x2b, 0x6f, 0x8b, 0x5f, 0x33, 0xfc, 0xb9, 0xc5, 0xe1,
0xbf, 0x7e, 0x78, 0xd3, 0xbc, 0xca, 0x85, 0x34, 0xaf, 0xf2, 0xab, 0xf8, 0x72, 0x17, 0xee, 0x35,
0x17, 0x17, 0x9f, 0xff, 0x7c, 0x04, 0x9b, 0x31, 0x1a, 0xe4, 0xd6, 0xce, 0xa9, 0x43, 0xe5, 0x03,
0x43, 0x6b, 0x1a, 0xf5, 0x40, 0xe2, 0x76, 0x8a, 0x50, 0x08, 0x46, 0xde, 0x8c, 0x1a, 0x1b, 0xb0,
0x16, 0x1f, 0x55, 0x71, 0x4c, 0xfc, 0x76, 0x06, 0x9a, 0x22, 0x06, 0xc8, 0x71, 0xcf, 0xf6, 0x9d,
0x20, 0xf4, 0x7c, 0xf5, 0xbc, 0xf4, 0x6d, 0x00, 0xfe, 0xbd, 0x10, 0x54, 0xdc, 0xc5, 0x8b, 0x38,
0x08, 0x41, 0xb5, 0xfd, 0x26, 0x94, 0xa8, 0x3b, 0xe6, 0x48, 0xbe, 0x1a, 0x8a, 0xd4, 0x1d, 0x4b,
0xa5, 0x7f, 0xe1, 0x18, 0xae, 0xc5, 0x05, 0x0c, 0xf1, 0xb6, 0x03, 0x1b, 0x1d, 0x7a, 0x81, 0xe2,
0x40, 0x5e, 0xbd, 0xed, 0x70, 0x68, 0x5f, 0x62, 0x44, 0x6d, 0x60, 0xfc, 0x95, 0x2c, 0x2c, 0x47,
0xed, 0xe3, 0xaf, 0xdb, 0xbc, 0xf8, 0x9d, 0x9e, 0xbb, 0x62, 0x39, 0x38, 0x4c, 0x59, 0xd2, 0xac,
0xbc, 0x25, 0xbe, 0x39, 0xbb, 0x2e, 0x31, 0xa0, 0x22, 0x29, 0xbc, 0x79, 0xa8, 0x3d, 0x59, 0x5a,
0xe6, 0x24, 0xfd, 0x79, 0xc8, 0xb4, 0x5b, 0xa6, 0xe6, 0x3b, 0xae, 0xd0, 0x2f, 0x0b, 0xf6, 0x34,
0xec, 0xe2, 0x47, 0x69, 0x18, 0x98, 0x65, 0xe3, 0x13, 0xc9, 0xa8, 0x18, 0x7d, 0x83, 0x2b, 0x3b,
0x7c, 0xe6, 0x50, 0xd1, 0xd1, 0x35, 0x01, 0xfe, 0x8e, 0xbe, 0xd2, 0x04, 0x5e, 0x87, 0x0a, 0x2f,
0x3c, 0xba, 0xc6, 0x8e, 0xef, 0x87, 0x85, 0x5d, 0x17, 0xf1, 0xc2, 0xe2, 0xe6, 0xcd, 0x63, 0x76,
0x06, 0xe0, 0x55, 0x61, 0x88, 0xcd, 0x6f, 0x66, 0xe0, 0x66, 0xca, 0xb4, 0x89, 0x5d, 0xde, 0x86,
0x95, 0x53, 0x85, 0x94, 0xa3, 0xcb, 0xb7, 0xfa, 0x86, 0x64, 0xab, 0xf1, 0x31, 0x35, 0x1b, 0xa7,
0x71, 0x40, 0xa4, 0xe1, 0xf2, 0x19, 0x8c, 0x3d, 0x92, 0x80, 0xe2, 0x14, 0x9f, 0x46, 0xae, 0x5c,
0x1e, 0xc1, 0x56, 0xe7, 0x92, 0x71, 0x0c, 0x15, 0x96, 0x3b, 0x7a, 0x36, 0x97, 0x9e, 0xaf, 0x84,
0x35, 0x3f, 0xf3, 0x4a, 0xd6, 0xfc, 0x31, 0xbf, 0xe6, 0xac, 0xca, 0xfa, 0x69, 0x0a, 0xc1, 0x03,
0x94, 0xe5, 0x39, 0xc1, 0x22, 0xe4, 0x6b, 0x09, 0x0c, 0xc4, 0x0b, 0x35, 0x02, 0x58, 0x3e, 0x9c,
0x4f, 0x42, 0xa7, 0xad, 0x40, 0xe4, 0x23, 0x91, 0x07, 0xeb, 0x91, 0xa3, 0x96, 0x5a, 0x11, 0xa8,
0x8a, 0x70, 0xb0, 0xa6, 0xac, 0x20, 0x6b, 0xb1, 0xbe, 0xe5, 0x69, 0xbc, 0x06, 0xe3, 0x26, 0x6c,
0x46, 0x29, 0x3e, 0x6c, 0xf2, 0xa8, 0xf9, 0x5b, 0x19, 0x1e, 0xbe, 0xcf, 0x71, 0x03, 0xd7, 0x9e,
0x05, 0xe7, 0x5e, 0x48, 0x3a, 0xb0, 0x1a, 0x38, 0xee, 0xd9, 0x84, 0xea, 0xc5, 0x07, 0x62, 0x10,
0xd6, 0xe3, 0x6d, 0xe3, 0x59, 0x03, 0x73, 0x85, 0xe7, 0x88, 0x4a, 0x0b, 0xc8, 0xce, 0x75, 0x8d,
0x8c, 0x96, 0x45, 0x62, 0x34, 0x16, 0x1b, 0xdf, 0x85, 0x7a, 0xbc, 0x22, 0xf2, 0x89, 0x78, 0x1d,
0x20, 0x6a, 0x55, 0x2e, 0x71, 0x37, 0x3a, 0x5a, 0x10, 0x95, 0x68, 0xec, 0x03, 0xe3, 0x2f, 0x65,
0xa0, 0x69, 0x52, 0xb6, 0x72, 0xb5, 0x56, 0xca, 0x35, 0xf3, 0xfd, 0x85, 0x52, 0xaf, 0xef, 0xab,
0x7c, 0x74, 0x40, 0xb6, 0xe8, 0xbd, 0x6b, 0x27, 0x63, 0xff, 0xc6, 0x42, 0x8f, 0x76, 0x4a, 0xb0,
0xc4, 0x49, 0x8c, 0x4d, 0x58, 0x17, 0xed, 0x91, 0x6d, 0x89, 0x5c, 0xb5, 0xb1, 0x1a, 0x63, 0xae,
0xda, 0x2d, 0x68, 0xf2, 0x7b, 0xbe, 0x7a, 0x27, 0x44, 0xc6, 0x5d, 0x20, 0x87, 0xf6, 0xc8, 0xf6,
0x3d, 0xcf, 0x3d, 0xa2, 0xbe, 0x08, 0x86, 0x46, 0x09, 0x13, 0x3d, 0x99, 0x52, 0x14, 0xe6, 0x29,
0xf9, 0x50, 0xb3, 0xe7, 0xca, 0xd8, 0x2f, 0x9e, 0x32, 0x7c, 0x58, 0xdd, 0xb1, 0x9f, 0x51, 0x59,
0x92, 0x1c, 0xa2, 0xc7, 0x50, 0x99, 0xa9, 0x42, 0xe5, 0xb8, 0xcb, 0xc7, 0x52, 0x16, 0xab, 0x35,
0x75, 0x6a, 0xc6, 0x82, 0x7c, 0xcf, 0x0b, 0xf1, 0x61, 0x02, 0xe9, 0x0c, 0x33, 0xcb, 0x0c, 0xf4,
0x94, 0x5e, 0x75, 0xc7, 0xc6, 0x43, 0x58, 0x8b, 0xd7, 0x29, 0x58, 0xcb, 0x16, 0x94, 0xa6, 0x02,
0x26, 0x5a, 0xaf, 0xd2, 0x4c, 0x19, 0x61, 0x2a, 0x9f, 0xcc, 0xd3, 0xdd, 0x55, 0x2a, 0xd5, 0x63,
0xd8, 0x5c, 0xc0, 0x88, 0x02, 0xef, 0x42, 0x55, 0x6b, 0x08, 0xef, 0x46, 0x9e, 0x89, 0xac, 0xa2,
0x25, 0x81, 0xf1, 0x19, 0x6c, 0x72, 0x7d, 0x2c, 0xca, 0x2e, 0x87, 0x20, 0xd1, 0x8b, 0x4c, 0xb2,
0x17, 0x1f, 0x49, 0x35, 0x4f, 0xcf, 0x1a, 0x5d, 0x15, 0x18, 0x23, 0x4e, 0x86, 0xef, 0xc8, 0xa4,
0x71, 0x0c, 0x1b, 0x8b, 0xc3, 0xc7, 0xda, 0xff, 0x33, 0x0d, 0xb9, 0x1c, 0x9e, 0x08, 0xad, 0x86,
0xe7, 0xbf, 0x66, 0xf8, 0xf8, 0xc4, 0x50, 0xa2, 0x99, 0x63, 0x20, 0x53, 0x1a, 0x9e, 0x7b, 0x63,
0x6b, 0xb1, 0xe6, 0x47, 0x2a, 0x7a, 0x28, 0x35, 0xef, 0xf6, 0x21, 0x66, 0xd4, 0x30, 0x22, 0x8e,
0x7d, 0x9a, 0x84, 0x6f, 0x8d, 0x60, 0x23, 0x9d, 0x38, 0x25, 0xe6, 0xe6, 0xc3, 0xb8, 0xa0, 0x7e,
0xfb, 0xda, 0xee, 0xb3, 0x66, 0xe9, 0x72, 0xfb, 0x6f, 0x95, 0xa0, 0x28, 0xac, 0x24, 0x64, 0x1b,
0xf2, 0x23, 0x19, 0xbf, 0x19, 0x3d, 0x44, 0x27, 0xb0, 0xf2, 0x7f, 0x1b, 0xa3, 0x38, 0x19, 0x1d,
0x79, 0x0c, 0xf5, 0x78, 0x08, 0x43, 0xe2, 0x91, 0x8a, 0x78, 0xec, 0x41, 0x6d, 0x94, 0x70, 0x56,
0x97, 0x23, 0xe1, 0x8a, 0xcb, 0x9c, 0xa5, 0x73, 0x4d, 0xfa, 0xf2, 0x5c, 0xa6, 0xaf, 0x05, 0xe7,
0xb6, 0xf5, 0xf0, 0xd1, 0xc7, 0xe2, 0x95, 0x8a, 0x0a, 0x02, 0x07, 0xe7, 0xf6, 0xc3, 0x47, 0x1f,
0x27, 0x35, 0x31, 0xf1, 0x46, 0x85, 0xa6, 0x89, 0xad, 0x41, 0x81, 0xbf, 0x66, 0xcd, 0x03, 0xf1,
0x78, 0x82, 0x3c, 0x80, 0x35, 0x69, 0x78, 0x13, 0x57, 0x26, 0xf8, 0x29, 0x5a, 0xe2, 0xb7, 0x54,
0x05, 0x6e, 0x80, 0x28, 0x6e, 0xaa, 0xdb, 0x80, 0xa5, 0xf3, 0xe8, 0x79, 0xf2, 0x9a, 0x29, 0x52,
0xc6, 0x1f, 0x14, 0xa0, 0xa2, 0x0d, 0x0a, 0xa9, 0x42, 0xc9, 0xec, 0x0c, 0x3a, 0xe6, 0x17, 0x9d,
0xdd, 0xc6, 0x0d, 0x72, 0x0f, 0xde, 0xea, 0xf6, 0xda, 0x7d, 0xd3, 0xec, 0xb4, 0x87, 0x56, 0xdf,
0xb4, 0xe4, 0x73, 0x88, 0x47, 0xad, 0xaf, 0x0e, 0x3b, 0xbd, 0xa1, 0xb5, 0xdb, 0x19, 0xb6, 0xba,
0x07, 0x83, 0x46, 0x86, 0xbc, 0x06, 0xcd, 0x88, 0x52, 0xa2, 0x5b, 0x87, 0xfd, 0xe3, 0xde, 0xb0,
0x91, 0x25, 0x77, 0xe0, 0xd6, 0x5e, 0xb7, 0xd7, 0x3a, 0xb0, 0x22, 0x9a, 0xf6, 0xc1, 0xf0, 0x0b,
0xab, 0xf3, 0x8b, 0x47, 0x5d, 0xf3, 0xab, 0x46, 0x2e, 0x8d, 0x60, 0x7f, 0x78, 0xd0, 0x96, 0x25,
0xe4, 0xc9, 0x4d, 0x58, 0xe7, 0x04, 0x3c, 0x8b, 0x35, 0xec, 0xf7, 0xad, 0x41, 0xbf, 0xdf, 0x6b,
0x14, 0xc8, 0x0a, 0xd4, 0xba, 0xbd, 0x2f, 0x5a, 0x07, 0xdd, 0x5d, 0xcb, 0xec, 0xb4, 0x0e, 0x0e,
0x1b, 0x4b, 0x64, 0x15, 0x96, 0x93, 0x74, 0x45, 0x56, 0x84, 0xa4, 0xeb, 0xf7, 0xba, 0xfd, 0x9e,
0xf5, 0x45, 0xc7, 0x1c, 0x74, 0xfb, 0xbd, 0x46, 0x89, 0x6c, 0x00, 0x89, 0xa3, 0xf6, 0x0f, 0x5b,
0xed, 0x46, 0x99, 0xac, 0xc3, 0x4a, 0x1c, 0xfe, 0xb4, 0xf3, 0x55, 0x03, 0x48, 0x13, 0xd6, 0x78,
0xc3, 0xac, 0x9d, 0xce, 0x41, 0xff, 0x4b, 0xeb, 0xb0, 0xdb, 0xeb, 0x1e, 0x1e, 0x1f, 0x36, 0x2a,
0xf8, 0x28, 0x6d, 0xa7, 0x63, 0x75, 0x7b, 0x83, 0xe3, 0xbd, 0xbd, 0x6e, 0xbb, 0xdb, 0xe9, 0x0d,
0x1b, 0x55, 0x5e, 0x73, 0x5a, 0xc7, 0x6b, 0x2c, 0x83, 0xb8, 0x57, 0x65, 0xed, 0x76, 0x07, 0xad,
0x9d, 0x83, 0xce, 0x6e, 0xa3, 0x4e, 0x6e, 0xc3, 0xcd, 0x61, 0xe7, 0xf0, 0xa8, 0x6f, 0xb6, 0xcc,
0xaf, 0xe4, 0xbd, 0x2b, 0x6b, 0xaf, 0xd5, 0x3d, 0x38, 0x36, 0x3b, 0x8d, 0x65, 0xf2, 0x06, 0xdc,
0x36, 0x3b, 0x3f, 0x3e, 0xee, 0x9a, 0x9d, 0x5d, 0xab, 0xd7, 0xdf, 0xed, 0x58, 0x7b, 0x9d, 0xd6,
0xf0, 0xd8, 0xec, 0x58, 0x87, 0xdd, 0xc1, 0xa0, 0xdb, 0x7b, 0xd2, 0x68, 0x90, 0xb7, 0xe0, 0xae,
0x22, 0x51, 0x05, 0x24, 0xa8, 0x56, 0x58, 0xff, 0xe4, 0x94, 0xf6, 0x3a, 0xbf, 0x38, 0xb4, 0x8e,
0x3a, 0x1d, 0xb3, 0x41, 0xc8, 0x16, 0x6c, 0x44, 0xd5, 0xf3, 0x0a, 0x44, 0xdd, 0xab, 0x0c, 0x77,
0xd4, 0x31, 0x0f, 0x5b, 0x3d, 0x36, 0xc1, 0x31, 0xdc, 0x1a, 0x6b, 0x76, 0x84, 0x4b, 0x36, 0x7b,
0x9d, 0x10, 0xa8, 0x6b, 0xb3, 0xb2, 0xd7, 0x32, 0x1b, 0x1b, 0x64, 0x19, 0x2a, 0x87, 0x47, 0x47,
0xd6, 0xb0, 0x7b, 0xd8, 0xe9, 0x1f, 0x0f, 0x1b, 0x9b, 0x64, 0x1d, 0x1a, 0xdd, 0xde, 0xb0, 0x63,
0xb2, 0xb9, 0x96, 0x59, 0xff, 0x5b, 0x91, 0xac, 0xc1, 0xb2, 0x6c, 0xa9, 0x84, 0xfe, 0x71, 0x91,
0x6c, 0x02, 0x39, 0xee, 0x99, 0x9d, 0xd6, 0x2e, 0x1b, 0x38, 0x85, 0xf8, 0xef, 0x45, 0xe1, 0xce,
0xfc, 0xdd, 0x9c, 0x12, 0xf6, 0xa2, 0xf8, 0xa0, 0xf8, 0x37, 0x3b, 0xaa, 0xda, 0xb7, 0x36, 0x5e,
0xf6, 0xe5, 0x2d, 0x4d, 0x35, 0xcf, 0x2d, 0xa8, 0xe6, 0x0b, 0xb6, 0x9f, 0x9a, 0xae, 0x3b, 0xbc,
0x09, 0xb5, 0x29, 0xff, 0x7e, 0x87, 0x78, 0x9c, 0x1e, 0x44, 0xb0, 0x1c, 0x07, 0xf2, 0x97, 0xe9,
0x17, 0x3e, 0x3d, 0x55, 0x58, 0xfc, 0xf4, 0x54, 0x9a, 0x7e, 0xb8, 0x94, 0xa6, 0x1f, 0xde, 0x87,
0x15, 0xce, 0x9a, 0x1c, 0xd7, 0x99, 0x4a, 0xab, 0x0b, 0xd7, 0x22, 0x96, 0x91, 0x45, 0x71, 0xb8,
0x54, 0x47, 0xa5, 0xca, 0x2a, 0x58, 0x48, 0x51, 0x68, 0xab, 0x31, 0x4d, 0x95, 0x73, 0x0e, 0xa5,
0xa9, 0xaa, 0x1a, 0xec, 0xcb, 0xa8, 0x86, 0x8a, 0x56, 0x03, 0x87, 0x63, 0x0d, 0xf7, 0x61, 0x85,
0x5e, 0x86, 0xbe, 0x6d, 0x79, 0x33, 0xfb, 0xeb, 0x39, 0xc6, 0x5b, 0xd8, 0x68, 0x03, 0xaa, 0x9a,
0xcb, 0x88, 0xe8, 0x23, 0x7c, 0xd7, 0x0e, 0x6d, 0xe3, 0x57, 0x00, 0xd4, 0xa9, 0x3a, 0x66, 0x0c,
0xd0, 0xf5, 0xe4, 0xb5, 0xbb, 0xaa, 0xc9, 0x13, 0x38, 0x8f, 0xa1, 0xe7, 0xdb, 0x67, 0xb4, 0x2b,
0x5f, 0x7a, 0x89, 0x00, 0xe4, 0x16, 0xe4, 0xbc, 0x99, 0x0c, 0x25, 0x2b, 0xcb, 0xd7, 0x96, 0x67,
0x26, 0x83, 0x1a, 0x1f, 0x43, 0xb6, 0x3f, 0xbb, 0x56, 0x54, 0x6a, 0x42, 0x51, 0x7e, 0x6c, 0x32,
0x8b, 0xe1, 0x63, 0x32, 0x79, 0xff, 0xcf, 0x42, 0x45, 0xfb, 0xe4, 0x0c, 0xd9, 0x84, 0xd5, 0x2f,
0xbb, 0xc3, 0x5e, 0x67, 0x30, 0xb0, 0x8e, 0x8e, 0x77, 0x9e, 0x76, 0xbe, 0xb2, 0xf6, 0x5b, 0x83,
0xfd, 0xc6, 0x0d, 0xc6, 0x4b, 0x7a, 0x9d, 0xc1, 0xb0, 0xb3, 0x1b, 0x83, 0x67, 0xc8, 0xeb, 0xb0,
0x75, 0xdc, 0x3b, 0x1e, 0x74, 0x76, 0xad, 0xb4, 0x7c, 0x59, 0xb6, 0x79, 0x04, 0x3e, 0x25, 0x7b,
0xee, 0xfe, 0xaf, 0x42, 0x3d, 0xfe, 0x32, 0x02, 0x01, 0x58, 0x3a, 0xe8, 0x3c, 0x69, 0xb5, 0xbf,
0xe2, 0xaf, 0x69, 0x0f, 0x86, 0xad, 0x61, 0xb7, 0x6d, 0x89, 0xd7, 0xb3, 0x19, 0xa3, 0xca, 0x90,
0x0a, 0x14, 0x5b, 0xbd, 0xf6, 0x7e, 0xdf, 0x1c, 0x34, 0xb2, 0xe4, 0x35, 0xd8, 0x94, 0x5b, 0xa8,
0xdd, 0x3f, 0x3c, 0xec, 0x0e, 0x91, 0x47, 0x0f, 0xbf, 0x3a, 0x62, 0x3b, 0xe6, 0xbe, 0x0d, 0xe5,
0xe8, 0xe1, 0x6f, 0xe4, 0x7b, 0xdd, 0x61, 0xb7, 0x35, 0x8c, 0x98, 0x7e, 0xe3, 0x06, 0x63, 0xab,
0x11, 0x18, 0x5f, 0xef, 0x6e, 0x64, 0xf8, 0xe5, 0x51, 0x09, 0xe4, 0xb5, 0x37, 0xb2, 0x6c, 0xaf,
0x47, 0xd0, 0x9d, 0xfe, 0x90, 0x75, 0xe1, 0xd7, 0xa0, 0x1e, 0x7f, 0x5f, 0x9b, 0x34, 0xa0, 0xca,
0xea, 0xd7, 0xaa, 0x00, 0x58, 0xe2, 0x2d, 0x6e, 0x64, 0x38, 0x63, 0x6f, 0xf7, 0x0f, 0xbb, 0xbd,
0x27, 0x78, 0x1a, 0x34, 0xb2, 0x0c, 0xd4, 0x3f, 0x1e, 0x3e, 0xe9, 0x2b, 0x50, 0x8e, 0xe5, 0xe0,
0xdd, 0x69, 0xe4, 0xef, 0x7f, 0x0d, 0x2b, 0x0b, 0x2f, 0x71, 0xb3, 0x56, 0xf7, 0x8f, 0x87, 0xed,
0xfe, 0xa1, 0x5e, 0x4f, 0x05, 0x8a, 0xed, 0x83, 0x56, 0xf7, 0x10, 0x1d, 0x21, 0x35, 0x28, 0x1f,
0xf7, 0x64, 0x32, 0x1b, 0x7f, 0x43, 0x3c, 0xc7, 0x58, 0xd4, 0x5e, 0xd7, 0x1c, 0x0c, 0xad, 0xc1,
0xb0, 0xf5, 0xa4, 0xd3, 0xc8, 0xb3, 0xbc, 0x92, 0x5f, 0x15, 0xee, 0x7f, 0x06, 0xf5, 0x78, 0xdc,
0x73, 0xdc, 0x81, 0xb5, 0x05, 0x1b, 0x3b, 0x9d, 0xe1, 0x97, 0x9d, 0x4e, 0x0f, 0xa7, 0xbc, 0xdd,
0xe9, 0x0d, 0xcd, 0xd6, 0x41, 0x77, 0xf8, 0x55, 0x23, 0x73, 0xff, 0x31, 0x34, 0x92, 0x41, 0x06,
0xb1, 0xa8, 0x8c, 0x17, 0x85, 0x6f, 0xdc, 0xff, 0x4f, 0x19, 0x58, 0x4b, 0xf3, 0xaf, 0xb1, 0x85,
0x29, 0x18, 0x21, 0x3b, 0x0e, 0x07, 0xfd, 0x9e, 0xd5, 0xeb, 0xe3, 0xa3, 0xba, 0x5b, 0xb0, 0x91,
0x40, 0xc8, 0x5e, 0x64, 0xc8, 0x2d, 0xd8, 0x5c, 0xc8, 0x64, 0x99, 0xfd, 0x63, 0x9c, 0xcb, 0x26,
0xac, 0x25, 0x90, 0x1d, 0xd3, 0xec, 0x9b, 0x8d, 0x1c, 0x79, 0x0f, 0xee, 0x25, 0x30, 0x8b, 0x42,
0x80, 0x94, 0x11, 0xf2, 0xe4, 0x1d, 0x78, 0x73, 0x81, 0x3a, 0x3a, 0x27, 0xad, 0x9d, 0xd6, 0x01,
0xeb, 0x5e, 0xa3, 0x70, 0xff, 0xef, 0xe7, 0x00, 0xa2, 0x8b, 0x85, 0xac, 0xfe, 0xdd, 0xd6, 0xb0,
0x75, 0xd0, 0x67, 0x7b, 0xc6, 0xec, 0x0f, 0x59, 0xe9, 0x66, 0xe7, 0xc7, 0x8d, 0x1b, 0xa9, 0x98,
0xfe, 0x11, 0xeb, 0xd0, 0x26, 0xac, 0xf2, 0xf5, 0x77, 0xc0, 0xba, 0xc1, 0x96, 0x0b, 0xbe, 0xcf,
0x8c, 0x92, 0xc6, 0xf1, 0xd1, 0x9e, 0xd9, 0xef, 0x0d, 0xad, 0xc1, 0xfe, 0xf1, 0x70, 0x17, 0x5f,
0x77, 0x6e, 0x9b, 0xdd, 0x23, 0x5e, 0x66, 0xfe, 0x45, 0x04, 0xac, 0xe8, 0x02, 0xdb, 0xe0, 0x4f,
0xfa, 0x83, 0x41, 0xf7, 0xc8, 0xfa, 0xf1, 0x71, 0xc7, 0xec, 0x76, 0x06, 0x98, 0x71, 0x29, 0x05,
0xce, 0xe8, 0x8b, 0x6c, 0xcd, 0x0e, 0x0f, 0xbe, 0x10, 0x02, 0x04, 0x23, 0x2d, 0xc5, 0x41, 0x8c,
0xaa, 0xcc, 0x66, 0x87, 0x9d, 0xc0, 0x29, 0x25, 0xc3, 0x35, 0x38, 0x96, 0xaf, 0xc2, 0x64, 0x8b,
0x85, 0x9d, 0x8f, 0xd9, 0xaa, 0xe9, 0x28, 0x96, 0x0b, 0xc5, 0x0e, 0x25, 0xa4, 0xed, 0xee, 0x9a,
0x98, 0xa1, 0xbe, 0x00, 0x65, 0xb4, 0xcb, 0x6c, 0x11, 0xb2, 0x23, 0x9a, 0x91, 0x34, 0x64, 0x82,
0x61, 0x56, 0x1e, 0xfe, 0x8b, 0x37, 0xa0, 0xac, 0x2e, 0x18, 0x90, 0x1f, 0x41, 0x2d, 0x76, 0xe3,
0x9b, 0x48, 0x13, 0x7e, 0xda, 0x05, 0xf1, 0xad, 0xd7, 0xd2, 0x91, 0x42, 0x39, 0x39, 0xd4, 0xac,
0x01, 0xbc, 0xb0, 0xd7, 0x92, 0x1a, 0x7a, 0xac, 0xb4, 0xdb, 0xd7, 0x60, 0x45, 0x71, 0x4f, 0xf1,
0xa9, 0x68, 0xfd, 0xcb, 0xc5, 0xe4, 0x76, 0xf4, 0x6e, 0x6f, 0xca, 0x17, 0x8d, 0xb7, 0x6e, 0x2e,
0x7e, 0x63, 0x58, 0x7e, 0x94, 0x78, 0x17, 0x2a, 0xda, 0x07, 0xf9, 0xc8, 0xcd, 0x6b, 0x3f, 0x1e,
0xb8, 0xb5, 0x95, 0x86, 0x12, 0x4d, 0xfa, 0x1c, 0xca, 0xea, 0xe3, 0x6c, 0x64, 0x53, 0xfb, 0xb0,
0x9e, 0xfe, 0x89, 0xb9, 0xad, 0xe6, 0x22, 0x42, 0xe4, 0xdf, 0x85, 0x8a, 0xf6, 0x8d, 0x35, 0xd5,
0x8a, 0xc5, 0xef, 0xb8, 0xa9, 0x56, 0xa4, 0x7d, 0x92, 0xed, 0x00, 0xd6, 0x85, 0xcd, 0xe1, 0x84,
0x7e, 0x93, 0xe1, 0x49, 0xf9, 0x04, 0xf3, 0x83, 0x0c, 0x79, 0x0c, 0x25, 0xf9, 0x35, 0x3d, 0xb2,
0x91, 0xfe, 0xad, 0xc0, 0xad, 0xcd, 0x05, 0xb8, 0x68, 0x4a, 0x0b, 0x20, 0xfa, 0x7a, 0x1b, 0x91,
0x1d, 0x5f, 0xf8, 0x1a, 0x9c, 0x9a, 0x99, 0x94, 0x4f, 0xbd, 0xed, 0x42, 0x45, 0xfb, 0x50, 0x9b,
0x1a, 0x93, 0xc5, 0x8f, 0xbc, 0xa9, 0x31, 0x49, 0xfb, 0xae, 0xdb, 0x8f, 0xa0, 0x16, 0xfb, 0xe2,
0x9a, 0x5a, 0xc7, 0x69, 0xdf, 0x73, 0x53, 0xeb, 0x38, 0xfd, 0x23, 0x6d, 0xbb, 0x50, 0xd1, 0xbe,
0x8f, 0xa6, 0x5a, 0xb4, 0xf8, 0x29, 0x36, 0xd5, 0xa2, 0x94, 0xcf, 0xa9, 0xb1, 0xdd, 0x10, 0xff,
0x38, 0x9a, 0xda, 0x0d, 0xa9, 0x5f, 0x59, 0x53, 0xbb, 0x21, 0xfd, 0x8b, 0x6a, 0x6c, 0xe9, 0xa9,
0x37, 0xe2, 0xc9, 0x66, 0x4c, 0xd5, 0x8f, 0x1e, 0x9b, 0x57, 0x4b, 0x6f, 0xf1, 0x39, 0xf9, 0x27,
0xb0, 0xaa, 0x16, 0x8d, 0x7a, 0xe1, 0x3d, 0x50, 0x6d, 0x4a, 0x7d, 0x47, 0x7e, 0xab, 0x91, 0xc4,
0x3e, 0xc8, 0x90, 0x4f, 0xa1, 0x28, 0x9e, 0xcd, 0x26, 0xeb, 0xc9, 0x67, 0xb4, 0x79, 0x23, 0x36,
0xd2, 0x5f, 0xd7, 0x26, 0x47, 0xb8, 0xa1, 0xf5, 0x77, 0xad, 0xf5, 0x15, 0x9b, 0xf2, 0x14, 0xf6,
0xd6, 0xeb, 0xd7, 0xa1, 0xa3, 0x12, 0x93, 0x6f, 0xb1, 0xdf, 0xbe, 0xee, 0x25, 0x96, 0x78, 0x89,
0xd7, 0x3d, 0x19, 0xf7, 0x04, 0xaa, 0xfa, 0xa7, 0x79, 0x88, 0xbe, 0x0f, 0x93, 0x65, 0xdd, 0x4a,
0xc5, 0x89, 0x82, 0xbe, 0x80, 0x0d, 0x35, 0xde, 0xfa, 0xb3, 0x20, 0x01, 0xb9, 0x93, 0xf2, 0x58,
0x48, 0x6c, 0xd4, 0x6f, 0x5e, 0xfb, 0x9a, 0xc8, 0x83, 0x0c, 0x32, 0xd9, 0xd8, 0xd7, 0x34, 0x22,
0x26, 0x9b, 0xf6, 0x11, 0x91, 0x88, 0xc9, 0xa6, 0x7f, 0x82, 0xa3, 0x05, 0xcb, 0xda, 0xb3, 0x26,
0x83, 0x2b, 0x77, 0xa4, 0xd6, 0xfb, 0xe2, 0x83, 0xc3, 0x5b, 0x69, 0x96, 0x6f, 0xd2, 0x86, 0x8a,
0xfe, 0x32, 0xca, 0x0b, 0xb2, 0x6f, 0x6a, 0x28, 0xfd, 0x4d, 0xd9, 0x07, 0x19, 0x72, 0x00, 0x8d,
0xe4, 0x3b, 0x86, 0x6a, 0x0b, 0xa7, 0xbd, 0xfd, 0xb8, 0x95, 0x40, 0xc6, 0x5e, 0x3f, 0x64, 0xeb,
0x22, 0xf6, 0xa9, 0x5f, 0xcf, 0x4f, 0x1e, 0x45, 0xf1, 0x4f, 0x00, 0xab, 0xd2, 0xd2, 0x3e, 0xfe,
0x7c, 0x2f, 0xf3, 0x20, 0x43, 0xf6, 0xa0, 0x1a, 0x7b, 0xc6, 0x2b, 0x76, 0xd7, 0x25, 0xd1, 0xcd,
0xa6, 0x8e, 0x4b, 0xf4, 0xf3, 0x10, 0xea, 0xf1, 0x10, 0x0d, 0xd5, 0xb0, 0xd4, 0x38, 0x12, 0x35,
0x7d, 0xe9, 0x71, 0x1d, 0xe4, 0x07, 0xfc, 0x43, 0xf6, 0x32, 0x94, 0x8f, 0x2c, 0x7e, 0xf8, 0x5c,
0xcd, 0x99, 0xfe, 0x99, 0x70, 0x23, 0xf7, 0x17, 0xb3, 0x19, 0xec, 0xd7, 0xf7, 0xf9, 0x67, 0x64,
0x65, 0x34, 0x17, 0x9b, 0xff, 0x57, 0x2d, 0x84, 0xec, 0xf1, 0xca, 0xc5, 0x47, 0xbc, 0x23, 0xce,
0xbd, 0xf0, 0x61, 0xef, 0x97, 0xb4, 0xa1, 0xc5, 0xdb, 0x20, 0xf2, 0xc4, 0xd6, 0xe0, 0x2b, 0x96,
0x45, 0x3e, 0x01, 0x88, 0x42, 0x64, 0x49, 0x22, 0x50, 0x53, 0x6d, 0xa8, 0x94, 0x28, 0xda, 0x0e,
0xdf, 0xef, 0x2a, 0x52, 0x54, 0x3f, 0x92, 0xe3, 0x41, 0xab, 0xb1, 0x23, 0x39, 0x59, 0xcc, 0x87,
0x50, 0x3b, 0xf0, 0xbc, 0x67, 0xf3, 0x99, 0xba, 0x67, 0x11, 0x0f, 0x63, 0xda, 0xb7, 0x83, 0xf3,
0xad, 0x44, 0xb3, 0x48, 0x0b, 0x56, 0x14, 0x8b, 0x88, 0x42, 0x55, 0xe3, 0x44, 0x31, 0xc6, 0x90,
0x28, 0xe0, 0x41, 0x86, 0x3c, 0x84, 0xea, 0x2e, 0x1d, 0xe1, 0x33, 0x1b, 0x18, 0x34, 0xb3, 0x1a,
0x0b, 0xc0, 0xe0, 0xd1, 0x36, 0x5b, 0xb5, 0x18, 0x50, 0xb2, 0xb8, 0x28, 0x70, 0x4b, 0x3f, 0x33,
0xe2, 0xd1, 0x4f, 0x31, 0x16, 0xb7, 0x10, 0xbc, 0xf5, 0x05, 0xac, 0x2c, 0x84, 0x46, 0x29, 0xee,
0x76, 0x5d, 0x40, 0xd5, 0xd6, 0xdd, 0xeb, 0x09, 0x44, 0xb9, 0x3f, 0x84, 0x1a, 0x7f, 0x62, 0xf8,
0x84, 0xf2, 0x6b, 0xb2, 0x89, 0x37, 0xa6, 0xf4, 0x3b, 0xb8, 0x49, 0x96, 0xc4, 0x33, 0x3c, 0xc1,
0x0f, 0x8f, 0x68, 0x97, 0x50, 0xd5, 0xbc, 0x2e, 0x5e, 0x8c, 0x55, 0xf3, 0x9a, 0x76, 0xdf, 0xf5,
0x33, 0xa8, 0x3c, 0xa1, 0xa1, 0xbc, 0xd6, 0xa9, 0xe4, 0xa3, 0xc4, 0x3d, 0xcf, 0xad, 0x94, 0xcb,
0xb8, 0xe4, 0x63, 0xcc, 0xaa, 0x9e, 0x28, 0xd8, 0xd0, 0x6a, 0xd1, 0xb3, 0x2e, 0x27, 0xe0, 0x4c,
0xfa, 0xd0, 0x1e, 0x2a, 0x51, 0x0d, 0x5f, 0x7c, 0x98, 0x46, 0x35, 0x3c, 0xed, 0x5d, 0x93, 0x1f,
0xf0, 0x11, 0xd0, 0x2e, 0x92, 0x46, 0x22, 0x58, 0xf2, 0xce, 0xa9, 0x6a, 0xbe, 0x4e, 0xfe, 0x08,
0x60, 0x10, 0x7a, 0xb3, 0x5d, 0x9b, 0x4e, 0x3d, 0x37, 0xe2, 0x09, 0xd1, 0x15, 0xc6, 0x68, 0x23,
0x6a, 0xf7, 0x18, 0xc9, 0x97, 0x9a, 0x6c, 0x1a, 0x9b, 0x12, 0x39, 0xed, 0xd7, 0xde, 0x72, 0x54,
0xdd, 0x49, 0xb9, 0xe9, 0x88, 0x4c, 0x02, 0xa2, 0xc8, 0x33, 0x25, 0x69, 0x2e, 0x04, 0xb5, 0xa9,
0xbd, 0x9e, 0x12, 0xa6, 0xf6, 0x39, 0x94, 0xa3, 0x90, 0x9d, 0xcd, 0xe8, 0xd5, 0xa4, 0x58, 0x80,
0x8f, 0xe2, 0xde, 0x8b, 0xe1, 0x32, 0x3d, 0x58, 0xe5, 0xcd, 0x51, 0xc7, 0x1f, 0x5e, 0xb4, 0x53,
0xdf, 0xcd, 0x59, 0x8c, 0x53, 0x51, 0xfb, 0x27, 0x2d, 0xda, 0x82, 0xed, 0x9f, 0x05, 0xaf, 0xbd,
0xda, 0x3f, 0xd7, 0x85, 0x61, 0xa8, 0xfd, 0x73, 0xbd, 0xc3, 0xbf, 0x07, 0xab, 0x29, 0xfe, 0x77,
0xf2, 0x86, 0x54, 0x6c, 0xae, 0xf5, 0xcd, 0x6f, 0xa5, 0xfa, 0x69, 0xc9, 0x10, 0x36, 0x79, 0x9e,
0xd6, 0x64, 0x92, 0x70, 0xf7, 0xbe, 0xae, 0x65, 0x48, 0x71, 0x61, 0xc7, 0x44, 0x99, 0x84, 0x1b,
0xbb, 0x07, 0x8d, 0xa4, 0xa7, 0x94, 0x5c, 0x4f, 0xbe, 0x75, 0x27, 0x26, 0xb2, 0x2f, 0x7a, 0x57,
0xc9, 0x17, 0xca, 0x5f, 0x9b, 0x68, 0xe3, 0x9d, 0xe8, 0x73, 0x6f, 0xa9, 0xde, 0x65, 0xa5, 0x0d,
0xa4, 0xba, 0x7b, 0xc9, 0x2f, 0xc2, 0x66, 0x72, 0x45, 0xcb, 0x92, 0xef, 0xa6, 0x0d, 0xd7, 0xb5,
0xa2, 0x5c, 0xbc, 0x43, 0x0f, 0x32, 0x8c, 0x11, 0xeb, 0x5e, 0x55, 0xb5, 0x90, 0x52, 0xdc, 0xbb,
0x6a, 0x21, 0xa5, 0xba, 0x61, 0x8f, 0x60, 0x39, 0xe1, 0x50, 0x55, 0x62, 0x70, 0xba, 0x0b, 0x56,
0x89, 0xc1, 0xd7, 0xf9, 0x61, 0x07, 0xd0, 0x48, 0xba, 0x4a, 0xd5, 0x5c, 0x5f, 0xe3, 0x7e, 0xdd,
0xba, 0x73, 0x2d, 0x3e, 0xde, 0x4c, 0xcd, 0xa9, 0x18, 0x6b, 0xe6, 0xa2, 0x2b, 0x34, 0xd6, 0xcc,
0x14, 0x97, 0xe6, 0xce, 0x3b, 0xbf, 0xf4, 0x9d, 0x33, 0x27, 0x3c, 0x9f, 0x9f, 0x6c, 0x8f, 0xbc,
0xe9, 0xfb, 0x13, 0x69, 0xd5, 0x10, 0xf7, 0xce, 0xdf, 0x9f, 0xb8, 0xe3, 0xf7, 0xb1, 0x80, 0x93,
0xa5, 0x99, 0xef, 0x85, 0xde, 0x87, 0xff, 0x2f, 0x00, 0x00, 0xff, 0xff, 0xe7, 0x1e, 0xb6, 0xde,
0x52, 0x8b, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.

@ -1415,6 +1415,20 @@ message Peer {
spamming us with errors at no cost.
*/
repeated TimestampedError errors = 12;
/*
The number of times we have recorded this peer going offline or coming
online, recorded across restarts. Note that this value is decreased over
time if the peer has not recently flapped, so that we can forgive peers
with historically high flap counts.
*/
int32 flap_count = 13;
/*
The timestamp of the last flap we observed for this peer. If this value is
zero, we have not observed any flaps for this peer.
*/
int64 last_flap_ns = 14;
}
message TimestampedError {

@ -4800,6 +4800,16 @@
"$ref": "#/definitions/lnrpcTimestampedError"
},
"description": "The latest errors received from our peer with timestamps, limited to the 10\nmost recent errors. These errors are tracked across peer connections, but\nare not persisted across lnd restarts. Note that these errors are only\nstored for peers that we have channels open with, to prevent peers from\nspamming us with errors at no cost."
},
"flap_count": {
"type": "integer",
"format": "int32",
"description": "The number of times we have recorded this peer going offline or coming\nonline, recorded across restarts. Note that this value is decreased over\ntime if the peer has not recently flapped, so that we can forgive peers\nwith historically high flap counts."
},
"last_flap_ns": {
"type": "string",
"format": "int64",
"description": "The timestamp of the last flap we observed for this peer. If this value is\nzero, we have not observed any flaps for this peer."
}
}
},

@ -2720,6 +2720,30 @@ func (r *rpcServer) ListPeers(ctx context.Context,
rpcPeer.Errors = append(rpcPeer.Errors, rpcErr)
}
// If the server has started, we can query the event store
// for our peer's flap count. If we do so when the server has
// not started, the request will block.
if r.server.Started() {
vertex, err := route.NewVertexFromBytes(nodePub[:])
if err != nil {
return nil, err
}
flap, ts, err := r.server.chanEventStore.FlapCount(
vertex,
)
if err != nil {
return nil, err
}
// If our timestamp is non-nil, we have values for our
// peer's flap count, so we set them.
if ts != nil {
rpcPeer.FlapCount = int32(flap)
rpcPeer.LastFlapNs = ts.UnixNano()
}
}
resp.Peers = append(resp.Peers, rpcPeer)
}
@ -3555,42 +3579,33 @@ func createRPCOpenChannel(r *rpcServer, graph *channeldb.ChannelGraph,
return channel, nil
}
// Get the lifespan observed by the channel event store. If the channel is
// not known to the channel event store, return early because we cannot
// calculate any further uptime information.
peer, err := route.NewVertexFromBytes(nodePub.SerializeCompressed())
if err != nil {
return nil, err
}
// Query the event store for additional information about the channel.
// Do not fail if it is not available, because there is a potential
// race between a channel being added to our node and the event store
// being notified of it.
outpoint := dbChannel.FundingOutpoint
startTime, endTime, err := r.server.chanEventStore.GetLifespan(outpoint)
info, err := r.server.chanEventStore.GetChanInfo(outpoint, peer)
switch err {
// If the store does not know about the channel, we just log it.
case chanfitness.ErrChannelNotFound:
rpcsLog.Infof("channel: %v not found by channel event store",
outpoint)
return channel, nil
// If we got our channel info, we further populate the channel.
case nil:
// If there is no error getting lifespan, continue to uptime
// calculation.
channel.Uptime = int64(info.Uptime.Seconds())
channel.Lifetime = int64(info.Lifetime.Seconds())
// If we get an unexpected error, we return it.
default:
return nil, err
}
// If endTime is zero, the channel is still open, progress endTime to
// the present so we can calculate lifetime.
if endTime.IsZero() {
endTime = time.Now()
}
channel.Lifetime = int64(endTime.Sub(startTime).Seconds())
// Once we have successfully obtained channel lifespan, we know that the
// channel is known to the event store, so we can return any non-nil error
// that occurs.
uptime, err := r.server.chanEventStore.GetUptime(
outpoint, startTime, endTime,
)
if err != nil {
return nil, err
}
channel.Uptime = int64(uptime.Seconds())
return channel, nil
}

@ -60,6 +60,7 @@ import (
"github.com/lightningnetwork/lnd/routing"
"github.com/lightningnetwork/lnd/routing/localchans"
"github.com/lightningnetwork/lnd/routing/route"
"github.com/lightningnetwork/lnd/subscribe"
"github.com/lightningnetwork/lnd/sweep"
"github.com/lightningnetwork/lnd/ticker"
"github.com/lightningnetwork/lnd/tor"
@ -1203,9 +1204,17 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
// Create a channel event store which monitors all open channels.
s.chanEventStore = chanfitness.NewChannelEventStore(&chanfitness.Config{
SubscribeChannelEvents: s.channelNotifier.SubscribeChannelEvents,
SubscribePeerEvents: s.peerNotifier.SubscribePeerEvents,
GetOpenChannels: s.remoteChanDB.FetchAllOpenChannels,
SubscribeChannelEvents: func() (subscribe.Subscription, error) {
return s.channelNotifier.SubscribeChannelEvents()
},
SubscribePeerEvents: func() (subscribe.Subscription, error) {
return s.peerNotifier.SubscribePeerEvents()
},
GetOpenChannels: s.remoteChanDB.FetchAllOpenChannels,
Clock: clock.NewDefaultClock(),
ReadFlapCount: s.remoteChanDB.ReadFlapCount,
WriteFlapCount: s.remoteChanDB.WriteFlapCounts,
FlapCountTicker: ticker.New(chanfitness.FlapCountFlushRate),
})
if cfg.WtClient.Active {

17
subscribe/interface.go Normal file

@ -0,0 +1,17 @@
package subscribe
// Subscription is an interface implemented by subscriptions to a server
// providing updates.
type Subscription interface {
// Updates returns a read-only channel where the updates the client has
// subscribed to will be delivered.
Updates() <-chan interface{}
// Quit is a channel that will be closed in case the server decides to
// no longer deliver updates to this client.
Quit() <-chan struct{}
// Cancel should be called in case the client no longer wants to
// subscribe for updates from the server.
Cancel()
}

@ -14,9 +14,9 @@ var ErrServerShuttingDown = errors.New("subscription server shutting down")
// Client is used to get notified about updates the caller has subscribed to,
type Client struct {
// Cancel should be called in case the client no longer wants to
// cancel should be called in case the client no longer wants to
// subscribe for updates from the server.
Cancel func()
cancel func()
updates *queue.ConcurrentQueue
quit chan struct{}
@ -34,6 +34,12 @@ func (c *Client) Quit() <-chan struct{} {
return c.quit
}
// Cancel should be called in case the client no longer wants to
// subscribe for updates from the server.
func (c *Client) Cancel() {
c.cancel()
}
// Server is a struct that manages a set of subscriptions and their
// corresponding clients. Any update will be delivered to all active clients.
type Server struct {
@ -118,7 +124,7 @@ func (s *Server) Subscribe() (*Client, error) {
client := &Client{
updates: queue.NewConcurrentQueue(20),
quit: make(chan struct{}),
Cancel: func() {
cancel: func() {
select {
case s.clientUpdates <- &clientUpdate{
cancel: true,