kill plugin processes when grafana shuts down

This commit is contained in:
bergquist
2017-12-07 16:59:35 +01:00
parent a2d47427ba
commit e1d4bf2607
15 changed files with 619 additions and 246 deletions
+310 -70
View File
@@ -8,16 +8,21 @@ It is generated from these files:
tsdb_plugin.proto
It has these top-level messages:
TsdbRequest
TsdbQuery
TsdbResponse
Query
Timerange
Response
QueryResult
DatasourceInfo
TsdbSeries
Point
*/
package proto
import proto1 "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import google_protobuf "github.com/golang/protobuf/ptypes/timestamp"
import (
context "golang.org/x/net/context"
@@ -36,55 +41,143 @@ var _ = math.Inf
const _ = proto1.ProtoPackageIsVersion2 // please upgrade the proto package
// Message represents a simple message sent to the Echo service.
type TsdbRequest struct {
From int64 `protobuf:"varint,1,opt,name=from" json:"from,omitempty"`
To int64 `protobuf:"varint,2,opt,name=to" json:"to,omitempty"`
Queries []*TsdbQuery `protobuf:"bytes,3,rep,name=queries" json:"queries,omitempty"`
type TsdbQuery struct {
Timerange *Timerange `protobuf:"bytes,1,opt,name=timerange" json:"timerange,omitempty"`
Datasource *DatasourceInfo `protobuf:"bytes,2,opt,name=datasource" json:"datasource,omitempty"`
Queries []*Query `protobuf:"bytes,3,rep,name=queries" json:"queries,omitempty"`
}
func (m *TsdbRequest) Reset() { *m = TsdbRequest{} }
func (m *TsdbRequest) String() string { return proto1.CompactTextString(m) }
func (*TsdbRequest) ProtoMessage() {}
func (*TsdbRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *TsdbQuery) Reset() { *m = TsdbQuery{} }
func (m *TsdbQuery) String() string { return proto1.CompactTextString(m) }
func (*TsdbQuery) ProtoMessage() {}
func (*TsdbQuery) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *TsdbRequest) GetFrom() int64 {
func (m *TsdbQuery) GetTimerange() *Timerange {
if m != nil {
return m.From
return m.Timerange
}
return 0
return nil
}
func (m *TsdbRequest) GetTo() int64 {
func (m *TsdbQuery) GetDatasource() *DatasourceInfo {
if m != nil {
return m.To
return m.Datasource
}
return 0
return nil
}
func (m *TsdbRequest) GetQueries() []*TsdbQuery {
func (m *TsdbQuery) GetQueries() []*Query {
if m != nil {
return m.Queries
}
return nil
}
type TsdbQuery struct {
QueryJson string `protobuf:"bytes,1,opt,name=queryJson" json:"queryJson,omitempty"`
type Query struct {
RefId string `protobuf:"bytes,1,opt,name=refId" json:"refId,omitempty"`
ModelJson string `protobuf:"bytes,2,opt,name=modelJson" json:"modelJson,omitempty"`
MaxDataPoints int64 `protobuf:"varint,3,opt,name=MaxDataPoints" json:"MaxDataPoints,omitempty"`
IntervalMs int64 `protobuf:"varint,4,opt,name=intervalMs" json:"intervalMs,omitempty"`
Datasource *DatasourceInfo `protobuf:"bytes,5,opt,name=datasource" json:"datasource,omitempty"`
}
func (m *TsdbQuery) Reset() { *m = TsdbQuery{} }
func (m *TsdbQuery) String() string { return proto1.CompactTextString(m) }
func (*TsdbQuery) ProtoMessage() {}
func (*TsdbQuery) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *Query) Reset() { *m = Query{} }
func (m *Query) String() string { return proto1.CompactTextString(m) }
func (*Query) ProtoMessage() {}
func (*Query) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *TsdbQuery) GetQueryJson() string {
func (m *Query) GetRefId() string {
if m != nil {
return m.QueryJson
return m.RefId
}
return ""
}
type TsdbResponse struct {
func (m *Query) GetModelJson() string {
if m != nil {
return m.ModelJson
}
return ""
}
func (m *Query) GetMaxDataPoints() int64 {
if m != nil {
return m.MaxDataPoints
}
return 0
}
func (m *Query) GetIntervalMs() int64 {
if m != nil {
return m.IntervalMs
}
return 0
}
func (m *Query) GetDatasource() *DatasourceInfo {
if m != nil {
return m.Datasource
}
return nil
}
type Timerange struct {
From string `protobuf:"bytes,1,opt,name=from" json:"from,omitempty"`
To string `protobuf:"bytes,2,opt,name=to" json:"to,omitempty"`
Now *google_protobuf.Timestamp `protobuf:"bytes,3,opt,name=now" json:"now,omitempty"`
}
func (m *Timerange) Reset() { *m = Timerange{} }
func (m *Timerange) String() string { return proto1.CompactTextString(m) }
func (*Timerange) ProtoMessage() {}
func (*Timerange) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (m *Timerange) GetFrom() string {
if m != nil {
return m.From
}
return ""
}
func (m *Timerange) GetTo() string {
if m != nil {
return m.To
}
return ""
}
func (m *Timerange) GetNow() *google_protobuf.Timestamp {
if m != nil {
return m.Now
}
return nil
}
type Response struct {
Message string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"`
Results []*QueryResult `protobuf:"bytes,2,rep,name=results" json:"results,omitempty"`
}
func (m *Response) Reset() { *m = Response{} }
func (m *Response) String() string { return proto1.CompactTextString(m) }
func (*Response) ProtoMessage() {}
func (*Response) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
func (m *Response) GetMessage() string {
if m != nil {
return m.Message
}
return ""
}
func (m *Response) GetResults() []*QueryResult {
if m != nil {
return m.Results
}
return nil
}
type QueryResult struct {
Error string `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"`
ErrorString string `protobuf:"bytes,2,opt,name=errorString" json:"errorString,omitempty"`
RefId string `protobuf:"bytes,3,opt,name=refId" json:"refId,omitempty"`
@@ -92,54 +185,136 @@ type TsdbResponse struct {
Series []*TsdbSeries `protobuf:"bytes,5,rep,name=series" json:"series,omitempty"`
}
func (m *TsdbResponse) Reset() { *m = TsdbResponse{} }
func (m *TsdbResponse) String() string { return proto1.CompactTextString(m) }
func (*TsdbResponse) ProtoMessage() {}
func (*TsdbResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (m *QueryResult) Reset() { *m = QueryResult{} }
func (m *QueryResult) String() string { return proto1.CompactTextString(m) }
func (*QueryResult) ProtoMessage() {}
func (*QueryResult) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
func (m *TsdbResponse) GetError() string {
func (m *QueryResult) GetError() string {
if m != nil {
return m.Error
}
return ""
}
func (m *TsdbResponse) GetErrorString() string {
func (m *QueryResult) GetErrorString() string {
if m != nil {
return m.ErrorString
}
return ""
}
func (m *TsdbResponse) GetRefId() string {
func (m *QueryResult) GetRefId() string {
if m != nil {
return m.RefId
}
return ""
}
func (m *TsdbResponse) GetMetaJson() string {
func (m *QueryResult) GetMetaJson() string {
if m != nil {
return m.MetaJson
}
return ""
}
func (m *TsdbResponse) GetSeries() []*TsdbSeries {
func (m *QueryResult) GetSeries() []*TsdbSeries {
if m != nil {
return m.Series
}
return nil
}
type DatasourceInfo struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
Type string `protobuf:"bytes,2,opt,name=type" json:"type,omitempty"`
Access string `protobuf:"bytes,3,opt,name=access" json:"access,omitempty"`
Url string `protobuf:"bytes,4,opt,name=url" json:"url,omitempty"`
BasicAuth bool `protobuf:"varint,5,opt,name=basicAuth" json:"basicAuth,omitempty"`
BasicAuthUser string `protobuf:"bytes,6,opt,name=basicAuthUser" json:"basicAuthUser,omitempty"`
BasicAuthPassword string `protobuf:"bytes,7,opt,name=basicAuthPassword" json:"basicAuthPassword,omitempty"`
JsonData string `protobuf:"bytes,8,opt,name=jsonData" json:"jsonData,omitempty"`
SecureJsonData string `protobuf:"bytes,9,opt,name=secureJsonData" json:"secureJsonData,omitempty"`
}
func (m *DatasourceInfo) Reset() { *m = DatasourceInfo{} }
func (m *DatasourceInfo) String() string { return proto1.CompactTextString(m) }
func (*DatasourceInfo) ProtoMessage() {}
func (*DatasourceInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
func (m *DatasourceInfo) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func (m *DatasourceInfo) GetType() string {
if m != nil {
return m.Type
}
return ""
}
func (m *DatasourceInfo) GetAccess() string {
if m != nil {
return m.Access
}
return ""
}
func (m *DatasourceInfo) GetUrl() string {
if m != nil {
return m.Url
}
return ""
}
func (m *DatasourceInfo) GetBasicAuth() bool {
if m != nil {
return m.BasicAuth
}
return false
}
func (m *DatasourceInfo) GetBasicAuthUser() string {
if m != nil {
return m.BasicAuthUser
}
return ""
}
func (m *DatasourceInfo) GetBasicAuthPassword() string {
if m != nil {
return m.BasicAuthPassword
}
return ""
}
func (m *DatasourceInfo) GetJsonData() string {
if m != nil {
return m.JsonData
}
return ""
}
func (m *DatasourceInfo) GetSecureJsonData() string {
if m != nil {
return m.SecureJsonData
}
return ""
}
type TsdbSeries struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
Tags map[string]string `protobuf:"bytes,2,rep,name=tags" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
Points []*Point `protobuf:"bytes,3,rep,name=points" json:"points,omitempty"`
}
func (m *TsdbSeries) Reset() { *m = TsdbSeries{} }
func (m *TsdbSeries) String() string { return proto1.CompactTextString(m) }
func (*TsdbSeries) ProtoMessage() {}
func (*TsdbSeries) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
func (*TsdbSeries) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
func (m *TsdbSeries) GetName() string {
if m != nil {
@@ -148,11 +323,53 @@ func (m *TsdbSeries) GetName() string {
return ""
}
func (m *TsdbSeries) GetTags() map[string]string {
if m != nil {
return m.Tags
}
return nil
}
func (m *TsdbSeries) GetPoints() []*Point {
if m != nil {
return m.Points
}
return nil
}
type Point struct {
Timestamp *google_protobuf.Timestamp `protobuf:"bytes,1,opt,name=timestamp" json:"timestamp,omitempty"`
Value float64 `protobuf:"fixed64,2,opt,name=value" json:"value,omitempty"`
}
func (m *Point) Reset() { *m = Point{} }
func (m *Point) String() string { return proto1.CompactTextString(m) }
func (*Point) ProtoMessage() {}
func (*Point) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
func (m *Point) GetTimestamp() *google_protobuf.Timestamp {
if m != nil {
return m.Timestamp
}
return nil
}
func (m *Point) GetValue() float64 {
if m != nil {
return m.Value
}
return 0
}
func init() {
proto1.RegisterType((*TsdbRequest)(nil), "plugins.TsdbRequest")
proto1.RegisterType((*TsdbQuery)(nil), "plugins.TsdbQuery")
proto1.RegisterType((*TsdbResponse)(nil), "plugins.TsdbResponse")
proto1.RegisterType((*Query)(nil), "plugins.Query")
proto1.RegisterType((*Timerange)(nil), "plugins.Timerange")
proto1.RegisterType((*Response)(nil), "plugins.Response")
proto1.RegisterType((*QueryResult)(nil), "plugins.QueryResult")
proto1.RegisterType((*DatasourceInfo)(nil), "plugins.DatasourceInfo")
proto1.RegisterType((*TsdbSeries)(nil), "plugins.TsdbSeries")
proto1.RegisterType((*Point)(nil), "plugins.Point")
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -166,7 +383,7 @@ const _ = grpc.SupportPackageIsVersion4
// Client API for TsdbPlugin service
type TsdbPluginClient interface {
Get(ctx context.Context, in *TsdbRequest, opts ...grpc.CallOption) (*TsdbResponse, error)
Query(ctx context.Context, in *TsdbQuery, opts ...grpc.CallOption) (*Response, error)
}
type tsdbPluginClient struct {
@@ -177,9 +394,9 @@ func NewTsdbPluginClient(cc *grpc.ClientConn) TsdbPluginClient {
return &tsdbPluginClient{cc}
}
func (c *tsdbPluginClient) Get(ctx context.Context, in *TsdbRequest, opts ...grpc.CallOption) (*TsdbResponse, error) {
out := new(TsdbResponse)
err := grpc.Invoke(ctx, "/plugins.TsdbPlugin/Get", in, out, c.cc, opts...)
func (c *tsdbPluginClient) Query(ctx context.Context, in *TsdbQuery, opts ...grpc.CallOption) (*Response, error) {
out := new(Response)
err := grpc.Invoke(ctx, "/plugins.TsdbPlugin/Query", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
@@ -189,27 +406,27 @@ func (c *tsdbPluginClient) Get(ctx context.Context, in *TsdbRequest, opts ...grp
// Server API for TsdbPlugin service
type TsdbPluginServer interface {
Get(context.Context, *TsdbRequest) (*TsdbResponse, error)
Query(context.Context, *TsdbQuery) (*Response, error)
}
func RegisterTsdbPluginServer(s *grpc.Server, srv TsdbPluginServer) {
s.RegisterService(&_TsdbPlugin_serviceDesc, srv)
}
func _TsdbPlugin_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(TsdbRequest)
func _TsdbPlugin_Query_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(TsdbQuery)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TsdbPluginServer).Get(ctx, in)
return srv.(TsdbPluginServer).Query(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/plugins.TsdbPlugin/Get",
FullMethod: "/plugins.TsdbPlugin/Query",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TsdbPluginServer).Get(ctx, req.(*TsdbRequest))
return srv.(TsdbPluginServer).Query(ctx, req.(*TsdbQuery))
}
return interceptor(ctx, in, info, handler)
}
@@ -219,8 +436,8 @@ var _TsdbPlugin_serviceDesc = grpc.ServiceDesc{
HandlerType: (*TsdbPluginServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Get",
Handler: _TsdbPlugin_Get_Handler,
MethodName: "Query",
Handler: _TsdbPlugin_Query_Handler,
},
},
Streams: []grpc.StreamDesc{},
@@ -230,23 +447,46 @@ var _TsdbPlugin_serviceDesc = grpc.ServiceDesc{
func init() { proto1.RegisterFile("tsdb_plugin.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 280 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x51, 0xc1, 0x4e, 0x83, 0x40,
0x10, 0x0d, 0x50, 0x8a, 0x0c, 0xc6, 0xc4, 0xb1, 0x26, 0xa4, 0xf1, 0x40, 0x38, 0xd5, 0x68, 0x38,
0xe0, 0x0f, 0x18, 0x2f, 0x46, 0x4f, 0xba, 0xf5, 0xe4, 0xa5, 0x29, 0x61, 0xda, 0x90, 0x08, 0x4b,
0x77, 0x97, 0x43, 0x3f, 0xc8, 0xff, 0x34, 0xcc, 0xae, 0xad, 0xf5, 0xc4, 0xbc, 0xb7, 0x6f, 0xde,
0xcc, 0x1b, 0xe0, 0xd2, 0xe8, 0xba, 0x5a, 0xf5, 0x5f, 0xc3, 0xb6, 0xe9, 0x8a, 0x5e, 0x49, 0x23,
0x31, 0xb2, 0x48, 0xe7, 0x2b, 0x48, 0x3e, 0x74, 0x5d, 0x09, 0xda, 0x0d, 0xa4, 0x0d, 0x22, 0x4c,
0x36, 0x4a, 0xb6, 0xa9, 0x97, 0x79, 0x8b, 0x40, 0x70, 0x8d, 0x17, 0xe0, 0x1b, 0x99, 0xfa, 0xcc,
0xf8, 0x46, 0xe2, 0x3d, 0x44, 0xbb, 0x81, 0x54, 0x43, 0x3a, 0x0d, 0xb2, 0x60, 0x91, 0x94, 0x58,
0x38, 0xb7, 0x62, 0xb4, 0x7a, 0x1f, 0x48, 0xed, 0xc5, 0xaf, 0x24, 0xbf, 0x85, 0xf8, 0xc0, 0xe2,
0x0d, 0xc4, 0x23, 0xbf, 0x7f, 0xd5, 0xb2, 0xe3, 0x19, 0xb1, 0x38, 0x12, 0xf9, 0xb7, 0x07, 0xe7,
0x76, 0x19, 0xdd, 0xcb, 0x4e, 0x13, 0xce, 0x20, 0x24, 0xa5, 0xa4, 0x72, 0x52, 0x0b, 0x30, 0x83,
0x84, 0x8b, 0xa5, 0x51, 0x4d, 0xb7, 0xe5, 0xc5, 0x62, 0xf1, 0x97, 0x1a, 0xfb, 0x14, 0x6d, 0x5e,
0xea, 0x34, 0xb0, 0x7d, 0x0c, 0x70, 0x0e, 0x67, 0x2d, 0x99, 0x35, 0xcf, 0x9e, 0xf0, 0xc3, 0x01,
0xe3, 0x1d, 0x4c, 0xb5, 0x8d, 0x14, 0x72, 0xa4, 0xab, 0x93, 0x48, 0x4b, 0x7e, 0x12, 0x4e, 0x92,
0x67, 0x00, 0x47, 0x76, 0x3c, 0x59, 0xb7, 0x6e, 0xc9, 0xed, 0xc8, 0x75, 0xf9, 0x68, 0x15, 0x6f,
0xec, 0x81, 0x25, 0x04, 0xcf, 0x64, 0x70, 0x76, 0xe2, 0xe9, 0x2e, 0x3e, 0xbf, 0xfe, 0xc7, 0xda,
0xe8, 0x4f, 0xd1, 0x67, 0xc8, 0x7f, 0xaa, 0x9a, 0xf2, 0xe7, 0xe1, 0x27, 0x00, 0x00, 0xff, 0xff,
0x11, 0xda, 0x61, 0xe4, 0xc5, 0x01, 0x00, 0x00,
// 652 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0x4d, 0x6f, 0xd4, 0x3a,
0x14, 0x55, 0xe6, 0x3b, 0x77, 0xf4, 0x46, 0xaf, 0x7e, 0xd5, 0x23, 0x1a, 0xf1, 0x51, 0x45, 0xa8,
0x1a, 0x89, 0x2a, 0x85, 0x61, 0xd1, 0x0a, 0xb1, 0x01, 0xc1, 0xa2, 0x95, 0x2a, 0x15, 0x77, 0x10,
0x12, 0x12, 0x42, 0x9e, 0x89, 0x27, 0x04, 0x92, 0x78, 0xb0, 0x9d, 0x96, 0xf9, 0x27, 0x2c, 0x59,
0xf0, 0x13, 0x58, 0xf1, 0xeb, 0x90, 0x6f, 0xec, 0x64, 0xa6, 0x54, 0x88, 0x55, 0xee, 0x3d, 0xf7,
0xd8, 0x39, 0x3e, 0xf7, 0xda, 0xb0, 0xa3, 0x55, 0x3c, 0x7f, 0xbf, 0xca, 0xca, 0x24, 0x2d, 0xa2,
0x95, 0x14, 0x5a, 0x90, 0x7e, 0x95, 0xa9, 0xf1, 0xbd, 0x44, 0x88, 0x24, 0xe3, 0x87, 0x08, 0xcf,
0xcb, 0xe5, 0xa1, 0x4e, 0x73, 0xae, 0x34, 0xcb, 0x57, 0x15, 0x33, 0xfc, 0xe6, 0x81, 0x3f, 0x53,
0xf1, 0xfc, 0x55, 0xc9, 0xe5, 0x9a, 0x3c, 0x04, 0xdf, 0x10, 0x24, 0x2b, 0x12, 0x1e, 0x78, 0x7b,
0xde, 0x64, 0x38, 0x25, 0x91, 0xdd, 0x2b, 0x9a, 0xb9, 0x0a, 0x6d, 0x48, 0xe4, 0x08, 0x20, 0x66,
0x9a, 0x29, 0x51, 0xca, 0x05, 0x0f, 0x5a, 0xb8, 0xe4, 0x56, 0xbd, 0xe4, 0x45, 0x5d, 0x3a, 0x29,
0x96, 0x82, 0x6e, 0x50, 0xc9, 0x04, 0xfa, 0x9f, 0x4b, 0x2e, 0x53, 0xae, 0x82, 0xf6, 0x5e, 0x7b,
0x32, 0x9c, 0x8e, 0xea, 0x55, 0xa8, 0x85, 0xba, 0x72, 0xf8, 0xd3, 0x83, 0x6e, 0x25, 0x6f, 0x17,
0xba, 0x92, 0x2f, 0x4f, 0x62, 0x94, 0xe6, 0xd3, 0x2a, 0x21, 0xb7, 0xc1, 0xcf, 0x45, 0xcc, 0xb3,
0x53, 0x25, 0x0a, 0x54, 0xe0, 0xd3, 0x06, 0x20, 0xf7, 0xe1, 0x9f, 0x33, 0xf6, 0xc5, 0x08, 0x39,
0x17, 0x69, 0xa1, 0xcd, 0xdf, 0xbc, 0x49, 0x9b, 0x6e, 0x83, 0xe4, 0x2e, 0x40, 0x5a, 0x68, 0x2e,
0x2f, 0x59, 0x76, 0xa6, 0x82, 0x0e, 0x52, 0x36, 0x90, 0x6b, 0xc7, 0xec, 0xfe, 0xf5, 0x31, 0xc3,
0x77, 0xe0, 0xd7, 0xbe, 0x11, 0x02, 0x9d, 0xa5, 0x14, 0xb9, 0x95, 0x8f, 0x31, 0x19, 0x41, 0x4b,
0x0b, 0x2b, 0xbb, 0xa5, 0x05, 0x39, 0x80, 0x76, 0x21, 0xae, 0x50, 0xe5, 0x70, 0x3a, 0x8e, 0xaa,
0xfe, 0x45, 0xae, 0x7f, 0xd8, 0x04, 0xec, 0x1f, 0x35, 0xb4, 0x70, 0x06, 0x03, 0xca, 0xd5, 0x4a,
0x14, 0x8a, 0x93, 0x00, 0xfa, 0x39, 0x57, 0x8a, 0xd9, 0xd6, 0xf9, 0xd4, 0xa5, 0x24, 0x82, 0xbe,
0xe4, 0xaa, 0xcc, 0xb4, 0x0a, 0x5a, 0xe8, 0xf5, 0xee, 0x35, 0xaf, 0xb1, 0x48, 0x1d, 0x29, 0xfc,
0xee, 0xc1, 0x70, 0xa3, 0x60, 0x7c, 0xe7, 0x52, 0x0a, 0xe9, 0x7c, 0xc7, 0x84, 0xec, 0xc1, 0x10,
0x83, 0x0b, 0x2d, 0xd3, 0x22, 0xb1, 0x47, 0xd8, 0x84, 0x9a, 0x7e, 0xb5, 0x37, 0xfb, 0x35, 0x86,
0x41, 0xce, 0x35, 0xc3, 0x76, 0x75, 0xb0, 0x50, 0xe7, 0xe4, 0x01, 0xf4, 0x54, 0x35, 0x14, 0x5d,
0x14, 0xfa, 0x5f, 0x33, 0x7d, 0x2a, 0x9e, 0x5f, 0x60, 0x89, 0x5a, 0x4a, 0xf8, 0xb5, 0x05, 0xa3,
0x6d, 0xeb, 0x8d, 0xc3, 0x05, 0xcb, 0x9d, 0x01, 0x18, 0x1b, 0x4c, 0xaf, 0x57, 0xdc, 0x0a, 0xc4,
0x98, 0xfc, 0x0f, 0x3d, 0xb6, 0x58, 0x70, 0xa5, 0xac, 0x34, 0x9b, 0x91, 0x7f, 0xa1, 0x5d, 0xca,
0xcc, 0xca, 0x32, 0xa1, 0x99, 0xae, 0x39, 0x53, 0xe9, 0xe2, 0x59, 0xa9, 0x3f, 0x60, 0xe3, 0x07,
0xb4, 0x01, 0xcc, 0x74, 0xd5, 0xc9, 0x6b, 0xc5, 0x65, 0xd0, 0xc3, 0x95, 0xdb, 0x20, 0x39, 0x80,
0x9d, 0x1a, 0x38, 0x67, 0x4a, 0x5d, 0x09, 0x19, 0x07, 0x7d, 0x64, 0xfe, 0x5e, 0x30, 0xfe, 0x7c,
0x54, 0xa2, 0x30, 0x27, 0x0b, 0x06, 0x95, 0x3f, 0x2e, 0x27, 0xfb, 0x30, 0x52, 0x7c, 0x51, 0x4a,
0x7e, 0xea, 0x18, 0x3e, 0x32, 0xae, 0xa1, 0xe1, 0x0f, 0x0f, 0xa0, 0x71, 0xec, 0x46, 0x5b, 0x1e,
0x41, 0x47, 0xb3, 0xc4, 0x4d, 0xc4, 0x9d, 0x1b, 0x8c, 0x8e, 0x66, 0x2c, 0x51, 0x2f, 0x0b, 0x2d,
0xd7, 0x14, 0xa9, 0x64, 0x1f, 0x7a, 0x2b, 0x77, 0x89, 0xb6, 0xaf, 0x2c, 0x5e, 0x23, 0x6a, 0xab,
0xe3, 0x23, 0xf0, 0xeb, 0xa5, 0xc6, 0xd2, 0x4f, 0x7c, 0x6d, 0x7f, 0x6d, 0x42, 0x33, 0x16, 0x97,
0x2c, 0x2b, 0x5d, 0x47, 0xaa, 0xe4, 0x49, 0xeb, 0xd8, 0x0b, 0xdf, 0x40, 0x17, 0x77, 0x22, 0xc7,
0xd5, 0x43, 0x84, 0x93, 0x6e, 0x1f, 0xa2, 0x3f, 0xdd, 0x85, 0x86, 0xbc, 0xbd, 0xb9, 0x67, 0x37,
0x9f, 0x3e, 0xad, 0xec, 0x38, 0x47, 0xb9, 0x24, 0x72, 0x0f, 0x0a, 0xd9, 0x3a, 0x35, 0x62, 0xe3,
0x9d, 0x1a, 0x73, 0x37, 0xeb, 0x79, 0xff, 0x6d, 0xb7, 0xfa, 0x69, 0x0f, 0x3f, 0x8f, 0x7f, 0x05,
0x00, 0x00, 0xff, 0xff, 0x56, 0x20, 0xfa, 0x8b, 0x73, 0x05, 0x00, 0x00,
}