Commit 0b9683e1 authored by Matt Butcher's avatar Matt Butcher

feat(tiller): add release server stub

parent 88580563
...@@ -2,6 +2,7 @@ syntax = "proto3"; ...@@ -2,6 +2,7 @@ syntax = "proto3";
package hapi.chart; package hapi.chart;
import "hapi/chart/config.proto";
import "hapi/chart/metadata.proto"; import "hapi/chart/metadata.proto";
import "hapi/chart/template.proto"; import "hapi/chart/template.proto";
...@@ -13,12 +14,16 @@ option go_package = "chart"; ...@@ -13,12 +14,16 @@ option go_package = "chart";
// optionally parameterizable templates, and zero or more charts (dependencies). // optionally parameterizable templates, and zero or more charts (dependencies).
// //
message Chart { message Chart {
// TODO // Contents of the Chartfile.
hapi.chart.Metadata metadata = 1; hapi.chart.Metadata metadata = 1;
// TODO // Templates for this chart.
hapi.chart.Templates templates = 2; hapi.chart.Templates templates = 2;
// TODO // Charts that this chart depends on.
repeated Chart dependencies = 3; repeated Chart dependencies = 3;
// Default config for this template.
hapi.chart.Config values = 4;
} }
...@@ -10,4 +10,5 @@ option go_package = "chart"; ...@@ -10,4 +10,5 @@ option go_package = "chart";
// A config supplies values to the parametrizable templates of a chart. // A config supplies values to the parametrizable templates of a chart.
// //
message Config { message Config {
string raw = 1;
} }
...@@ -2,6 +2,8 @@ syntax = "proto3"; ...@@ -2,6 +2,8 @@ syntax = "proto3";
package hapi.services.tiller; package hapi.services.tiller;
import "hapi/chart/chart.proto";
import "hapi/chart/config.proto";
import "hapi/release/release.proto"; import "hapi/release/release.proto";
import "hapi/release/status.proto"; import "hapi/release/status.proto";
...@@ -163,6 +165,10 @@ message UpdateReleaseResponse { ...@@ -163,6 +165,10 @@ message UpdateReleaseResponse {
// TODO // TODO
// //
message InstallReleaseRequest { message InstallReleaseRequest {
// Chart is the protobuf representation of a chart.
hapi.chart.Chart chart = 1;
// Values is a string containing (unparsed) TOML values.
hapi.chart.Config values = 2;
} }
// //
...@@ -171,6 +177,7 @@ message InstallReleaseRequest { ...@@ -171,6 +177,7 @@ message InstallReleaseRequest {
// TODO // TODO
// //
message InstallReleaseResponse { message InstallReleaseResponse {
hapi.release.Release release = 1;
} }
// //
......
package main
import (
"errors"
"github.com/deis/tiller/cmd/tiller/environment"
"github.com/deis/tiller/pkg/proto/hapi/services"
ctx "golang.org/x/net/context"
)
func init() {
srv := &releaseServer{
env: env,
}
services.RegisterReleaseServiceServer(rootServer, srv)
}
type releaseServer struct {
env *environment.Environment
}
// errNotImplemented is a temporary error for uninmplemented callbacks.
var errNotImplemented = errors.New("not implemented")
func (s *releaseServer) ListReleases(req *services.ListReleasesRequest, stream services.ReleaseService_ListReleasesServer) error {
return errNotImplemented
}
func (s *releaseServer) GetReleaseStatus(c ctx.Context, req *services.GetReleaseStatusRequest) (*services.GetReleaseStatusResponse, error) {
return nil, errNotImplemented
}
func (s *releaseServer) GetReleaseContent(c ctx.Context, req *services.GetReleaseContentRequest) (*services.GetReleaseContentResponse, error) {
return nil, errNotImplemented
}
func (s *releaseServer) UpdateRelease(c ctx.Context, req *services.UpdateReleaseRequest) (*services.UpdateReleaseResponse, error) {
return nil, errNotImplemented
}
func (s *releaseServer) InstallRelease(c ctx.Context, req *services.InstallReleaseRequest) (*services.InstallReleaseResponse, error) {
return &services.InstallReleaseResponse{}, errNotImplemented
}
func (s *releaseServer) UninstallRelease(c ctx.Context, req *services.UninstallReleaseRequest) (*services.UninstallReleaseResponse, error) {
return nil, errNotImplemented
}
package main
import (
"net"
"github.com/deis/tiller/cmd/tiller/environment"
"github.com/deis/tiller/pkg/hapi"
ctx "golang.org/x/net/context"
"google.golang.org/grpc"
)
type server struct {
Environment *environment.Environment
}
// newServer creates a new server with the default environment.
//
// TODO: This can take a configuration object of some sort so that we can
// initialize the environment with the correct stuff.
func newServer() *server {
return &server{
Environment: environment.New(),
}
}
func (s *server) Ready(c ctx.Context, req *hapi.PingRequest) (*hapi.PingResponse, error) {
return &hapi.PingResponse{Status: "OK"}, nil
}
// startServer starts a new gRPC server listening on the given address.
//
// addr must conform to the requirements of "net.Listen".
func startServer(addr string) error {
lstn, err := net.Listen("tcp", addr)
if err != nil {
return nil
}
hserver := newServer()
srv := grpc.NewServer()
hapi.RegisterProbeServer(srv, hserver)
srv.Serve(lstn)
return nil
}
...@@ -13,18 +13,17 @@ import ( ...@@ -13,18 +13,17 @@ import (
var _ environment.Engine = &engine.Engine{} var _ environment.Engine = &engine.Engine{}
var _ environment.ReleaseStorage = storage.NewMemory() var _ environment.ReleaseStorage = storage.NewMemory()
func TestNewServer(t *testing.T) { func TestInit(t *testing.T) {
defer func() { defer func() {
if recover() != nil { if recover() != nil {
t.Fatalf("Panic trapped. Check EngineYard.Default()") t.Fatalf("Panic trapped. Check EngineYard.Default()")
} }
}() }()
s := newServer()
// This will panic if it is not correct. // This will panic if it is not correct.
s.Environment.EngineYard.Default() env.EngineYard.Default()
e, ok := s.Environment.EngineYard.Get(environment.GoTplEngine) e, ok := env.EngineYard.Get(environment.GoTplEngine)
if !ok { if !ok {
t.Fatalf("Could not find GoTplEngine") t.Fatalf("Could not find GoTplEngine")
} }
......
...@@ -2,11 +2,20 @@ package main ...@@ -2,11 +2,20 @@ package main
import ( import (
"fmt" "fmt"
"net"
"os" "os"
"github.com/codegangsta/cli" "github.com/codegangsta/cli"
"github.com/deis/tiller/cmd/tiller/environment"
"google.golang.org/grpc"
) )
// rootServer is the root gRPC server.
//
// Each gRPC service registers itself to this server during init().
var rootServer *grpc.Server = grpc.NewServer()
var env = environment.New()
func main() { func main() {
app := cli.NewApp() app := cli.NewApp()
app.Name = "tiller" app.Name = "tiller"
...@@ -17,7 +26,16 @@ func main() { ...@@ -17,7 +26,16 @@ func main() {
} }
func start(c *cli.Context) { func start(c *cli.Context) {
if err := startServer(":44134"); err != nil { addr := ":44134"
lstn, err := net.Listen("tcp", addr)
if err != nil {
fmt.Fprintf(os.Stderr, "Server died: %s\n", err)
os.Exit(1)
}
fmt.Printf("Tiller is running on %s\n", addr)
if err := rootServer.Serve(lstn); err != nil {
fmt.Fprintf(os.Stderr, "Server died: %s\n", err) fmt.Fprintf(os.Stderr, "Server died: %s\n", err)
os.Exit(1) os.Exit(1)
} }
......
...@@ -40,12 +40,14 @@ const _ = proto.ProtoPackageIsVersion1 ...@@ -40,12 +40,14 @@ const _ = proto.ProtoPackageIsVersion1
// optionally parameterizable templates, and zero or more charts (dependencies). // optionally parameterizable templates, and zero or more charts (dependencies).
// //
type Chart struct { type Chart struct {
// TODO // Contents of the Chartfile.
Metadata *Metadata `protobuf:"bytes,1,opt,name=metadata" json:"metadata,omitempty"` Metadata *Metadata `protobuf:"bytes,1,opt,name=metadata" json:"metadata,omitempty"`
// TODO // Templates for this chart.
Templates *Templates `protobuf:"bytes,2,opt,name=templates" json:"templates,omitempty"` Templates *Templates `protobuf:"bytes,2,opt,name=templates" json:"templates,omitempty"`
// TODO // Charts that this chart depends on.
Dependencies []*Chart `protobuf:"bytes,3,rep,name=dependencies" json:"dependencies,omitempty"` Dependencies []*Chart `protobuf:"bytes,3,rep,name=dependencies" json:"dependencies,omitempty"`
// Default config for this template.
Values *Config `protobuf:"bytes,4,opt,name=values" json:"values,omitempty"`
} }
func (m *Chart) Reset() { *m = Chart{} } func (m *Chart) Reset() { *m = Chart{} }
...@@ -74,21 +76,30 @@ func (m *Chart) GetDependencies() []*Chart { ...@@ -74,21 +76,30 @@ func (m *Chart) GetDependencies() []*Chart {
return nil return nil
} }
func (m *Chart) GetValues() *Config {
if m != nil {
return m.Values
}
return nil
}
func init() { func init() {
proto.RegisterType((*Chart)(nil), "hapi.chart.Chart") proto.RegisterType((*Chart)(nil), "hapi.chart.Chart")
} }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 169 bytes of a gzipped FileDescriptorProto // 200 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0xcb, 0x48, 0x2c, 0xc8, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0xcb, 0x48, 0x2c, 0xc8,
0xd4, 0x4f, 0xce, 0x48, 0x2c, 0x2a, 0x81, 0x90, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x5c, 0xd4, 0x4f, 0xce, 0x48, 0x2c, 0x2a, 0x81, 0x90, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x5c,
0x20, 0x71, 0x3d, 0xb0, 0x88, 0x94, 0x24, 0x92, 0x9a, 0xdc, 0xd4, 0x92, 0xc4, 0x94, 0xc4, 0x92, 0x20, 0x71, 0x3d, 0xb0, 0x88, 0x94, 0x38, 0xb2, 0x9a, 0xfc, 0xbc, 0xb4, 0xcc, 0x74, 0x88, 0x22,
0x44, 0x88, 0x32, 0x14, 0xa9, 0x92, 0xd4, 0xdc, 0x82, 0x9c, 0xc4, 0x92, 0x54, 0x88, 0x94, 0xd2, 0x29, 0x49, 0x24, 0x89, 0xdc, 0xd4, 0x92, 0xc4, 0x94, 0xc4, 0x92, 0x44, 0x2c, 0x52, 0x25, 0xa9,
0x52, 0x46, 0x2e, 0x56, 0x67, 0x90, 0x84, 0x90, 0x01, 0x17, 0x07, 0x4c, 0x9b, 0x04, 0xa3, 0x02, 0xb9, 0x05, 0x39, 0x89, 0x25, 0xa9, 0x10, 0x29, 0xa5, 0x8b, 0x8c, 0x5c, 0xac, 0xce, 0x20, 0x09,
0xa3, 0x06, 0xb7, 0x91, 0x88, 0x1e, 0xc2, 0x78, 0x3d, 0x5f, 0xa8, 0x5c, 0x10, 0x5c, 0x95, 0x90, 0x21, 0x03, 0x2e, 0x0e, 0x98, 0x36, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x6e, 0x23, 0x11, 0x3d, 0x84,
0x31, 0x17, 0x27, 0xcc, 0xb4, 0x62, 0x09, 0x26, 0xb0, 0x16, 0x51, 0x64, 0x2d, 0x21, 0x30, 0xc9, 0xbd, 0x7a, 0xbe, 0x50, 0xb9, 0x20, 0xb8, 0x2a, 0x21, 0x63, 0x2e, 0x4e, 0x98, 0x69, 0xc5, 0x12,
0x20, 0x84, 0x3a, 0x21, 0x53, 0x2e, 0x9e, 0x94, 0xd4, 0x82, 0xd4, 0xbc, 0x94, 0xd4, 0xbc, 0xe4, 0x4c, 0x60, 0x2d, 0xa2, 0xc8, 0x5a, 0x42, 0x60, 0x92, 0x41, 0x08, 0x75, 0x42, 0xa6, 0x5c, 0x3c,
0x4c, 0xa0, 0x3e, 0x66, 0x05, 0x66, 0xa0, 0x3e, 0x41, 0x64, 0x7d, 0x60, 0xf7, 0x04, 0xa1, 0x28, 0x29, 0xa9, 0x05, 0xa9, 0x79, 0x29, 0xa9, 0x79, 0xc9, 0x99, 0x40, 0x7d, 0xcc, 0x0a, 0xcc, 0x40,
0x73, 0x62, 0x8f, 0x62, 0x05, 0x4b, 0x26, 0xb1, 0x81, 0xdd, 0x6d, 0x0c, 0x08, 0x00, 0x00, 0xff, 0x7d, 0x82, 0xc8, 0xfa, 0xc0, 0xee, 0x09, 0x42, 0x51, 0x26, 0xa4, 0xc5, 0xc5, 0x56, 0x96, 0x98,
0xff, 0xd3, 0xb1, 0x38, 0xe5, 0x13, 0x01, 0x00, 0x00, 0x53, 0x0a, 0xd4, 0xc0, 0x02, 0xb6, 0x48, 0x08, 0x45, 0x03, 0x38, 0x1c, 0x82, 0xa0, 0x2a, 0x9c,
0xd8, 0xa3, 0x58, 0xc1, 0xe2, 0x49, 0x6c, 0x60, 0x3f, 0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff,
0x12, 0xa6, 0x6a, 0xa8, 0x58, 0x01, 0x00, 0x00,
} }
...@@ -19,6 +19,7 @@ var _ = math.Inf ...@@ -19,6 +19,7 @@ var _ = math.Inf
// A config supplies values to the parametrizable templates of a chart. // A config supplies values to the parametrizable templates of a chart.
// //
type Config struct { type Config struct {
Raw string `protobuf:"bytes,1,opt,name=raw" json:"raw,omitempty"`
} }
func (m *Config) Reset() { *m = Config{} } func (m *Config) Reset() { *m = Config{} }
...@@ -31,10 +32,11 @@ func init() { ...@@ -31,10 +32,11 @@ func init() {
} }
var fileDescriptor1 = []byte{ var fileDescriptor1 = []byte{
// 74 bytes of a gzipped FileDescriptorProto // 89 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0xcf, 0x48, 0x2c, 0xc8, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0xcf, 0x48, 0x2c, 0xc8,
0xd4, 0x4f, 0xce, 0x48, 0x2c, 0x2a, 0xd1, 0x4f, 0xce, 0xcf, 0x4b, 0xcb, 0x4c, 0xd7, 0x2b, 0x28, 0xd4, 0x4f, 0xce, 0x48, 0x2c, 0x2a, 0xd1, 0x4f, 0xce, 0xcf, 0x4b, 0xcb, 0x4c, 0xd7, 0x2b, 0x28,
0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x02, 0x49, 0xe8, 0x81, 0x25, 0x94, 0x38, 0xb8, 0xd8, 0x9c, 0xc1, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x02, 0x49, 0xe8, 0x81, 0x25, 0x94, 0xa4, 0xb8, 0xd8, 0x9c, 0xc1,
0x72, 0x4e, 0xec, 0x51, 0xac, 0x60, 0xa1, 0x24, 0x36, 0xb0, 0x2a, 0x63, 0x40, 0x00, 0x00, 0x00, 0x72, 0x42, 0x02, 0x5c, 0xcc, 0x45, 0x89, 0xe5, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x20,
0xff, 0xff, 0x98, 0x3b, 0x34, 0xb8, 0x40, 0x00, 0x00, 0x00, 0xa6, 0x13, 0x7b, 0x14, 0x2b, 0x58, 0x51, 0x12, 0x1b, 0x58, 0x9f, 0x31, 0x20, 0x00, 0x00, 0xff,
0xff, 0xfe, 0xa0, 0x78, 0x2a, 0x52, 0x00, 0x00, 0x00,
} }
...@@ -7,6 +7,8 @@ package services ...@@ -7,6 +7,8 @@ package services
import proto "github.com/golang/protobuf/proto" import proto "github.com/golang/protobuf/proto"
import fmt "fmt" import fmt "fmt"
import math "math" import math "math"
import hapi_chart3 "github.com/deis/tiller/pkg/proto/hapi/chart"
import hapi_chart "github.com/deis/tiller/pkg/proto/hapi/chart"
import hapi_release2 "github.com/deis/tiller/pkg/proto/hapi/release" import hapi_release2 "github.com/deis/tiller/pkg/proto/hapi/release"
import hapi_release "github.com/deis/tiller/pkg/proto/hapi/release" import hapi_release "github.com/deis/tiller/pkg/proto/hapi/release"
...@@ -173,6 +175,10 @@ func (*UpdateReleaseResponse) Descriptor() ([]byte, []int) { return fileDescript ...@@ -173,6 +175,10 @@ func (*UpdateReleaseResponse) Descriptor() ([]byte, []int) { return fileDescript
// TODO // TODO
// //
type InstallReleaseRequest struct { type InstallReleaseRequest struct {
// Chart is the protobuf representation of a chart.
Chart *hapi_chart3.Chart `protobuf:"bytes,1,opt,name=chart" json:"chart,omitempty"`
// Values is a string containing (unparsed) TOML values.
Values *hapi_chart.Config `protobuf:"bytes,2,opt,name=values" json:"values,omitempty"`
} }
func (m *InstallReleaseRequest) Reset() { *m = InstallReleaseRequest{} } func (m *InstallReleaseRequest) Reset() { *m = InstallReleaseRequest{} }
...@@ -180,12 +186,27 @@ func (m *InstallReleaseRequest) String() string { return proto.Compac ...@@ -180,12 +186,27 @@ func (m *InstallReleaseRequest) String() string { return proto.Compac
func (*InstallReleaseRequest) ProtoMessage() {} func (*InstallReleaseRequest) ProtoMessage() {}
func (*InstallReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{8} } func (*InstallReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{8} }
func (m *InstallReleaseRequest) GetChart() *hapi_chart3.Chart {
if m != nil {
return m.Chart
}
return nil
}
func (m *InstallReleaseRequest) GetValues() *hapi_chart.Config {
if m != nil {
return m.Values
}
return nil
}
// //
// InstallReleaseResponse: // InstallReleaseResponse:
// //
// TODO // TODO
// //
type InstallReleaseResponse struct { type InstallReleaseResponse struct {
Release *hapi_release2.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
} }
func (m *InstallReleaseResponse) Reset() { *m = InstallReleaseResponse{} } func (m *InstallReleaseResponse) Reset() { *m = InstallReleaseResponse{} }
...@@ -193,6 +214,13 @@ func (m *InstallReleaseResponse) String() string { return proto.Compa ...@@ -193,6 +214,13 @@ func (m *InstallReleaseResponse) String() string { return proto.Compa
func (*InstallReleaseResponse) ProtoMessage() {} func (*InstallReleaseResponse) ProtoMessage() {}
func (*InstallReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{9} } func (*InstallReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{9} }
func (m *InstallReleaseResponse) GetRelease() *hapi_release2.Release {
if m != nil {
return m.Release
}
return nil
}
// //
// UninstallReleaseRequest: // UninstallReleaseRequest:
// //
...@@ -509,35 +537,39 @@ var _ReleaseService_serviceDesc = grpc.ServiceDesc{ ...@@ -509,35 +537,39 @@ var _ReleaseService_serviceDesc = grpc.ServiceDesc{
} }
var fileDescriptor1 = []byte{ var fileDescriptor1 = []byte{
// 469 bytes of a gzipped FileDescriptorProto // 529 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x54, 0xcd, 0xd2, 0xd2, 0x30, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x9c, 0x55, 0x4d, 0x73, 0xd3, 0x30,
0x14, 0xfd, 0x2a, 0x7e, 0x88, 0x97, 0x9f, 0xd1, 0x58, 0xa0, 0x64, 0x85, 0x59, 0xe1, 0x5f, 0xab, 0x10, 0x6d, 0x08, 0x0d, 0x65, 0xd3, 0x66, 0xa8, 0x70, 0x12, 0x47, 0xa7, 0xa2, 0x0b, 0xa5, 0x80,
0xb8, 0x54, 0x37, 0xb2, 0x70, 0x9c, 0x61, 0x5c, 0xd4, 0x61, 0xe3, 0xc6, 0xa9, 0x18, 0xc6, 0x38, 0x03, 0xe1, 0x08, 0x5c, 0xc8, 0x81, 0xe9, 0x4c, 0x87, 0x83, 0x99, 0x5e, 0xb8, 0x30, 0x26, 0x28,
0xa5, 0xad, 0x4d, 0x60, 0xe1, 0x3b, 0xf8, 0x3e, 0x3e, 0x9e, 0x34, 0x3f, 0x1d, 0x5a, 0x9a, 0xa1, 0x54, 0x8c, 0x62, 0x07, 0x4b, 0xc9, 0x81, 0xff, 0xc0, 0xff, 0xe1, 0xe7, 0x61, 0xeb, 0xc3, 0x13,
0xae, 0x98, 0xe4, 0x9c, 0x73, 0xef, 0xb9, 0xb9, 0xa7, 0x00, 0xfe, 0x11, 0x65, 0x2c, 0xe0, 0x34, 0x39, 0xd6, 0xd4, 0xf4, 0xe2, 0x8c, 0xf4, 0xde, 0xee, 0xdb, 0x5d, 0xbd, 0x9d, 0x00, 0xbe, 0x49,
0x3f, 0xb2, 0x2d, 0xe5, 0x81, 0x60, 0x71, 0x4c, 0x73, 0x3f, 0xcb, 0x53, 0x91, 0x22, 0xb7, 0xc0, 0xd6, 0x6c, 0x2a, 0x68, 0xbe, 0x65, 0x0b, 0x2a, 0xa6, 0x92, 0x71, 0x4e, 0xf3, 0x68, 0x9d, 0x67,
0x7c, 0x83, 0xf9, 0x0a, 0xc3, 0x4a, 0x91, 0xd3, 0x98, 0x46, 0x9c, 0x9a, 0x5f, 0xa5, 0xc0, 0xb3, 0x32, 0x43, 0x41, 0x89, 0x45, 0x16, 0x8b, 0x34, 0x86, 0x47, 0x2a, 0x62, 0x71, 0x93, 0xe4, 0x52,
0x0a, 0xc6, 0x45, 0x24, 0x0e, 0x5c, 0x41, 0x64, 0x05, 0x8f, 0xd6, 0x8c, 0x8b, 0x50, 0x61, 0x3c, 0x7f, 0x35, 0x1b, 0x8f, 0x77, 0xef, 0xb3, 0x74, 0xc9, 0x7e, 0x18, 0x40, 0x4b, 0xe4, 0x94, 0xd3,
0xa4, 0xbf, 0x0e, 0x94, 0x0b, 0xe4, 0xc2, 0x6d, 0xcc, 0xf6, 0x4c, 0x78, 0xce, 0xdc, 0x59, 0x74, 0x44, 0x50, 0xfb, 0x6b, 0xb0, 0x89, 0x83, 0x09, 0x99, 0xc8, 0x8d, 0xd0, 0x10, 0x99, 0xc3, 0xe3,
0x42, 0x75, 0x40, 0x13, 0xe8, 0xa6, 0xbb, 0x1d, 0xa7, 0xc2, 0xbb, 0x23, 0xaf, 0xf5, 0x89, 0xfc, 0x2b, 0x26, 0x64, 0xac, 0x31, 0x11, 0xd3, 0x5f, 0x1b, 0x2a, 0x24, 0x0a, 0xe0, 0x90, 0xb3, 0x15,
0x71, 0xc0, 0xad, 0x56, 0xe1, 0x59, 0x9a, 0x70, 0x5a, 0x94, 0xd9, 0xa6, 0x87, 0xa4, 0x2c, 0x23, 0x93, 0x61, 0xe7, 0xac, 0x73, 0xde, 0x8d, 0xf5, 0x01, 0x8d, 0xa0, 0x97, 0x2d, 0x97, 0x82, 0xca,
0x0f, 0xb6, 0x32, 0x05, 0x5b, 0xa4, 0x22, 0x8a, 0xbd, 0x8e, 0x62, 0xcb, 0x03, 0x7a, 0x05, 0x3d, 0xf0, 0x9e, 0xba, 0x36, 0x27, 0xf2, 0xa7, 0x03, 0x81, 0x9b, 0x45, 0xac, 0xb3, 0x54, 0xd0, 0x32,
0xed, 0x9c, 0x7b, 0x77, 0xe7, 0x9d, 0x45, 0x7f, 0x39, 0xf6, 0xe5, 0x0b, 0x98, 0x19, 0x75, 0xd7, 0xcd, 0x22, 0xdb, 0xa4, 0x55, 0x1a, 0x75, 0xf0, 0xa5, 0x29, 0xd9, 0x32, 0x93, 0x09, 0x0f, 0xbb,
0xb0, 0xa4, 0x91, 0xb7, 0x30, 0xfd, 0x40, 0x8d, 0x9b, 0xcf, 0x72, 0x5c, 0x33, 0xd8, 0x63, 0x18, 0x9a, 0xad, 0x0e, 0xe8, 0x35, 0x1c, 0x99, 0xca, 0x45, 0x78, 0xff, 0xac, 0x7b, 0xde, 0x9f, 0x0d,
0x68, 0xda, 0xd7, 0x24, 0xda, 0x53, 0x69, 0xec, 0x7e, 0xd8, 0xd7, 0x77, 0x9f, 0x4e, 0x57, 0xe4, 0x23, 0x35, 0x32, 0xdb, 0xa3, 0x51, 0x8d, 0x2b, 0x1a, 0x79, 0x07, 0xe3, 0x8f, 0xd4, 0x56, 0xf3,
0x37, 0x78, 0x97, 0x6a, 0x3d, 0xd0, 0x75, 0x39, 0x7a, 0x03, 0x23, 0x43, 0x51, 0x2f, 0x2d, 0xa7, 0x59, 0xb5, 0x6b, 0x1b, 0x7b, 0x02, 0xc7, 0x86, 0xf6, 0x35, 0x4d, 0x56, 0x54, 0x15, 0xf6, 0x30,
0xec, 0x2f, 0xdd, 0xaa, 0x6b, 0x5d, 0x78, 0x98, 0x9f, 0xf7, 0x21, 0xef, 0xce, 0x7b, 0xaf, 0xd2, 0xee, 0x9b, 0xbb, 0x4f, 0xc5, 0x15, 0xf9, 0x0d, 0xe1, 0x7e, 0xb4, 0x69, 0xe8, 0xf6, 0x70, 0xf4,
0x44, 0xd0, 0x44, 0xfc, 0x87, 0xf5, 0x35, 0xcc, 0x1a, 0xe4, 0xda, 0x7b, 0x00, 0xf7, 0x34, 0x57, 0x16, 0x06, 0x96, 0xa2, 0x27, 0xad, 0xba, 0xec, 0xcf, 0x02, 0xb7, 0x6a, 0x93, 0xf8, 0x24, 0xdf,
0x4a, 0xad, 0xef, 0x68, 0x58, 0x64, 0x02, 0xee, 0x26, 0xfb, 0x1e, 0x09, 0x6a, 0x10, 0x65, 0x84, 0xd5, 0x21, 0xef, 0x77, 0xb5, 0xe7, 0x59, 0x2a, 0x69, 0x2a, 0xff, 0xa3, 0xf4, 0x2b, 0x98, 0x34,
0x4c, 0x61, 0x5c, 0xbb, 0x57, 0x1d, 0x0a, 0xe0, 0x63, 0x72, 0x1a, 0x3a, 0x8e, 0x6b, 0x0a, 0x0f, 0x84, 0x9b, 0xda, 0xa7, 0xf0, 0xc0, 0x70, 0x55, 0xa8, 0x77, 0x8e, 0x96, 0x45, 0x46, 0x10, 0x5c,
0x26, 0x75, 0x40, 0x4b, 0x66, 0x30, 0xdd, 0x24, 0xac, 0x51, 0x84, 0xc1, 0xbb, 0x84, 0x94, 0x6c, 0xaf, 0xbf, 0x27, 0x92, 0x5a, 0x44, 0x17, 0x42, 0xc6, 0x30, 0xac, 0xdd, 0x6b, 0x05, 0xc2, 0x61,
0xf9, 0xf7, 0x16, 0x46, 0x66, 0x43, 0xea, 0x43, 0x40, 0x0c, 0x06, 0xe7, 0x19, 0x44, 0x4f, 0xfc, 0x78, 0x99, 0x16, 0x4d, 0x73, 0xee, 0x46, 0xa0, 0xa7, 0x85, 0x0f, 0x4a, 0xcb, 0x1a, 0xe1, 0x53,
0xa6, 0xef, 0xc4, 0x6f, 0x48, 0x3b, 0x7e, 0xda, 0x86, 0xaa, 0x0d, 0xdf, 0xbc, 0x74, 0x10, 0x87, 0x2d, 0xac, 0x7d, 0x3d, 0x2f, 0xbf, 0xb1, 0xc6, 0xd1, 0x05, 0xf4, 0xb6, 0x09, 0x2f, 0x62, 0xcc,
0x07, 0xf5, 0x84, 0xa0, 0x17, 0xcd, 0x35, 0x2c, 0x39, 0xc4, 0x7e, 0x5b, 0xba, 0x69, 0x8b, 0x8e, 0xd0, 0x90, 0xc3, 0x54, 0x7e, 0x8f, 0x0d, 0x83, 0x5c, 0xc2, 0xa8, 0xae, 0x76, 0xd7, 0x4e, 0x27,
0xf0, 0xf0, 0x62, 0xb7, 0xe8, 0x6a, 0x99, 0x6a, 0x86, 0x70, 0xd0, 0x9a, 0x5f, 0xf6, 0xfd, 0x09, 0x30, 0xbe, 0x4e, 0x59, 0x53, 0xe9, 0x04, 0x43, 0xb8, 0x0f, 0x69, 0x9d, 0xd9, 0xdf, 0x43, 0x18,
0xc3, 0xca, 0xb6, 0x91, 0xe5, 0xb5, 0x9a, 0xa2, 0x82, 0x9f, 0xb5, 0xe2, 0x96, 0xbd, 0xf6, 0x30, 0x58, 0x9f, 0xe8, 0xfd, 0x45, 0x0c, 0x8e, 0x77, 0x37, 0x01, 0x3d, 0x8b, 0x9a, 0xd6, 0x3b, 0x6a,
0xaa, 0xe6, 0x04, 0x59, 0x0a, 0x34, 0xc6, 0x0c, 0x3f, 0x6f, 0x47, 0x2e, 0xdb, 0x9d, 0xf6, 0x58, 0xd8, 0x39, 0x7c, 0xd1, 0x86, 0x6a, 0x26, 0x7d, 0xf0, 0xaa, 0x83, 0x04, 0x3c, 0xaa, 0xfb, 0x14,
0x4f, 0x98, 0x6d, 0x8f, 0x96, 0x90, 0xda, 0xf6, 0x68, 0x0b, 0x2e, 0xb9, 0x79, 0x0f, 0x5f, 0x7a, 0xbd, 0x6c, 0xce, 0xe1, 0xd9, 0x06, 0x1c, 0xb5, 0xa5, 0x5b, 0x59, 0xb4, 0x85, 0xd3, 0x3d, 0x87,
0x86, 0xfd, 0xad, 0x2b, 0xff, 0x84, 0x5f, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x35, 0x75, 0xc2, 0xa1, 0x5b, 0xd3, 0xb8, 0x4e, 0xc6, 0xd3, 0xd6, 0xfc, 0x4a, 0xf7, 0x27, 0x9c, 0x38, 0x9e, 0x43,
0x92, 0xef, 0x05, 0x00, 0x00, 0x9e, 0x69, 0x35, 0x19, 0x16, 0x3f, 0x6f, 0xc5, 0xad, 0xb4, 0x56, 0x30, 0x70, 0x8d, 0x85, 0x3c,
0x09, 0x1a, 0xcd, 0x8e, 0x5f, 0xb4, 0x23, 0x57, 0x72, 0xc5, 0x3b, 0xd6, 0x1d, 0xe6, 0x7b, 0x47,
0x8f, 0x49, 0x7d, 0xef, 0xe8, 0x33, 0x2e, 0x39, 0xf8, 0x00, 0x5f, 0x8e, 0x2c, 0xfb, 0x5b, 0x4f,
0xfd, 0x15, 0xbc, 0xf9, 0x17, 0x00, 0x00, 0xff, 0xff, 0x75, 0xe1, 0x2e, 0x4f, 0xa6, 0x06, 0x00,
0x00,
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment