From b1fb7cea7d915859330c1023cae19e2bd2186a05 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Thu, 19 May 2016 14:07:30 -0600 Subject: [PATCH] feat(helm): allow user to specify release name This makes it possible for the user to specify their own release name instead of accepting the generated one. --- _proto/hapi/services/tiller.proto | 5 ++ cmd/helm/helm.go | 3 + cmd/helm/install.go | 6 +- cmd/tiller/release_server.go | 16 ++++- pkg/helm/convert_test.go | 2 +- pkg/helm/helm.go | 3 +- pkg/proto/hapi/chart/chart.pb.go | 26 +++++--- pkg/proto/hapi/services/tiller.pb.go | 94 +++++++++++++++------------- 8 files changed, 94 insertions(+), 61 deletions(-) diff --git a/_proto/hapi/services/tiller.proto b/_proto/hapi/services/tiller.proto index 4cfdda8ba..4829633e8 100644 --- a/_proto/hapi/services/tiller.proto +++ b/_proto/hapi/services/tiller.proto @@ -156,6 +156,11 @@ message InstallReleaseRequest { // a release object nor deploy to Kubernetes. The release object returned // in the response will be fake. bool dry_run = 3; + + // Name is the candidate release name. This must be unique to the + // namespace, otherwise the server will return an error. If it is not + // supplied, the server will autogenerate one. + string name = 4; } // InstallReleaseResponse is the response from a release installation. diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go index 3bf0a904a..816ca455d 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -77,6 +77,9 @@ func main() { func bootstrap(c *cobra.Command, args []string) { // Set up the gRPC config. helm.Config.ServAddr = tillerHost + if flagVerbose { + fmt.Printf("Server: %q\n", helm.Config.ServAddr) + } } func checkArgsLength(expectedNum, actualNum int, requiredArgs ...string) error { diff --git a/cmd/helm/install.go b/cmd/helm/install.go index 0d31023a1..2d2ee255a 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -27,6 +27,8 @@ var ( installDryRun bool // installValues is the filename of supplied values. installValues string + // installRelName is the user-supplied release name. + installRelName string ) var installCmd = &cobra.Command{ @@ -38,8 +40,8 @@ var installCmd = &cobra.Command{ func init() { f := installCmd.Flags() - f.StringVar(&tillerHost, "host", "", "address of tiller server (default \":44134\")") f.StringVarP(&installValues, "values", "f", "", "path to a values TOML file") + f.StringVarP(&installRelName, "name", "n", "", "the release name. If unspecified, it will autogenerate one for you.") f.BoolVar(&installDryRun, "dry-run", false, "simulate an install") RootCommand.AddCommand(installCmd) @@ -56,7 +58,7 @@ func runInstall(cmd *cobra.Command, args []string) error { return err } - res, err := helm.InstallRelease(rawVals, installArg, installDryRun) + res, err := helm.InstallRelease(rawVals, installRelName, installArg, installDryRun) if err != nil { return prettyError(err) } diff --git a/cmd/tiller/release_server.go b/cmd/tiller/release_server.go index f08573128..933f0b318 100644 --- a/cmd/tiller/release_server.go +++ b/cmd/tiller/release_server.go @@ -156,7 +156,19 @@ func (s *releaseServer) UpdateRelease(c ctx.Context, req *services.UpdateRelease return nil, errNotImplemented } -func (s *releaseServer) uniqName() (string, error) { +func (s *releaseServer) uniqName(start string) (string, error) { + + // If a name is supplied, we check to see if that name is taken. Right now, + // we fail if it is already taken. We could instead fall-thru and allow + // an automatically generated name, but this seems to violate the principle + // of least surprise. + if start != "" { + if _, err := s.env.Releases.Read(start); err == storage.ErrNotFound { + return start, nil + } + return "", fmt.Errorf("a release named %q already exists", start) + } + maxTries := 5 for i := 0; i < maxTries; i++ { namer := moniker.New() @@ -176,7 +188,7 @@ func (s *releaseServer) InstallRelease(c ctx.Context, req *services.InstallRelea } ts := timeconv.Now() - name, err := s.uniqName() + name, err := s.uniqName(req.Name) if err != nil { return nil, err } diff --git a/pkg/helm/convert_test.go b/pkg/helm/convert_test.go index 64db7e725..514e0dd68 100644 --- a/pkg/helm/convert_test.go +++ b/pkg/helm/convert_test.go @@ -15,7 +15,7 @@ func TestInstallReleaseOverrides(t *testing.T) { vals := `name = "mariner"` ch := "./testdata/albatross" - ir, err := InstallRelease([]byte(vals), ch, true) + ir, err := InstallRelease([]byte(vals), "foo", ch, true) if err != nil { t.Fatalf("Failed to release: %s", err) } diff --git a/pkg/helm/helm.go b/pkg/helm/helm.go index ef8bbaff9..e6f2eaf1c 100644 --- a/pkg/helm/helm.go +++ b/pkg/helm/helm.go @@ -74,7 +74,7 @@ func UninstallRelease(name string) (*services.UninstallReleaseResponse, error) { } // InstallRelease installs a new chart and returns the release response. -func InstallRelease(rawVals []byte, chStr string, dryRun bool) (*services.InstallReleaseResponse, error) { +func InstallRelease(rawVals []byte, name string, chStr string, dryRun bool) (*services.InstallReleaseResponse, error) { chfi, err := chartutil.LoadChart(chStr) if err != nil { return nil, err @@ -91,5 +91,6 @@ func InstallRelease(rawVals []byte, chStr string, dryRun bool) (*services.Instal Chart: chpb, Values: vals, DryRun: dryRun, + Name: name, }) } diff --git a/pkg/proto/hapi/chart/chart.pb.go b/pkg/proto/hapi/chart/chart.pb.go index d1c8f1c4e..2f287ac75 100644 --- a/pkg/proto/hapi/chart/chart.pb.go +++ b/pkg/proto/hapi/chart/chart.pb.go @@ -45,6 +45,10 @@ type Chart struct { 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"` + // License is the text of the LICENSE file, if included. + License string `protobuf:"bytes,5,opt,name=license" json:"license,omitempty"` + // Readme is the text of the README.md file, if included. + Readme string `protobuf:"bytes,6,opt,name=readme" json:"readme,omitempty"` } func (m *Chart) Reset() { *m = Chart{} } @@ -85,18 +89,20 @@ func init() { } var fileDescriptor0 = []byte{ - // 197 bytes of a gzipped FileDescriptorProto + // 232 bytes of a gzipped FileDescriptorProto 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, 0x20, 0x71, 0x3d, 0xb0, 0x88, 0x94, 0x38, 0xb2, 0x9a, 0xfc, 0xbc, 0xb4, 0xcc, 0x74, 0x88, 0x22, 0x29, 0x49, 0x24, 0x89, 0xdc, 0xd4, 0x92, 0xc4, 0x94, 0xc4, 0x92, 0x44, 0x2c, 0x52, 0x25, 0xa9, - 0xb9, 0x05, 0x39, 0x89, 0x25, 0xa9, 0x10, 0x29, 0xa5, 0x0b, 0x8c, 0x5c, 0xac, 0xce, 0x20, 0x09, - 0x21, 0x03, 0x2e, 0x0e, 0x98, 0x36, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x6e, 0x23, 0x11, 0x3d, 0x84, - 0xbd, 0x7a, 0xbe, 0x50, 0xb9, 0x20, 0xb8, 0x2a, 0x21, 0x23, 0x2e, 0x4e, 0x98, 0x69, 0xc5, 0x12, - 0x4c, 0x0a, 0xcc, 0xe8, 0x5a, 0x42, 0xa0, 0x92, 0x41, 0x08, 0x65, 0x42, 0xa6, 0x5c, 0x3c, 0x29, - 0xa9, 0x05, 0xa9, 0x79, 0x29, 0xa9, 0x79, 0xc9, 0x99, 0x40, 0x6d, 0xcc, 0x60, 0x6d, 0x82, 0xc8, - 0xda, 0xc0, 0xce, 0x09, 0x42, 0x51, 0x26, 0xa4, 0xc5, 0xc5, 0x56, 0x96, 0x98, 0x53, 0x0a, 0xd4, - 0xc0, 0x02, 0x76, 0x9a, 0x10, 0x8a, 0x06, 0x70, 0x30, 0x04, 0x41, 0x55, 0x38, 0xb1, 0x47, 0xb1, - 0x82, 0xc5, 0x93, 0xd8, 0xc0, 0x5e, 0x34, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xb5, 0xff, 0x0f, - 0xec, 0x57, 0x01, 0x00, 0x00, + 0xb9, 0x05, 0x39, 0x89, 0x25, 0xa9, 0x10, 0x29, 0xa5, 0x26, 0x26, 0x2e, 0x56, 0x67, 0x90, 0x84, + 0x90, 0x01, 0x17, 0x07, 0x4c, 0x9b, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0xb7, 0x91, 0x88, 0x1e, 0xc2, + 0x5e, 0x3d, 0x5f, 0xa8, 0x5c, 0x10, 0x5c, 0x95, 0x90, 0x11, 0x17, 0x27, 0xcc, 0xb4, 0x62, 0x09, + 0x26, 0x05, 0x66, 0x74, 0x2d, 0x21, 0x50, 0xc9, 0x20, 0x84, 0x32, 0x21, 0x53, 0x2e, 0x9e, 0x94, + 0xd4, 0x82, 0xd4, 0xbc, 0x94, 0xd4, 0xbc, 0xe4, 0x4c, 0xa0, 0x36, 0x66, 0xb0, 0x36, 0x41, 0x64, + 0x6d, 0x60, 0xe7, 0x04, 0xa1, 0x28, 0x13, 0xd2, 0xe2, 0x62, 0x2b, 0x4b, 0xcc, 0x29, 0x05, 0x6a, + 0x60, 0x01, 0x3b, 0x4d, 0x08, 0x45, 0x03, 0x38, 0x18, 0x82, 0xa0, 0x2a, 0x84, 0x24, 0xb8, 0xd8, + 0x73, 0x32, 0x93, 0x53, 0xf3, 0x8a, 0x53, 0x25, 0x58, 0x81, 0x8a, 0x39, 0x83, 0x60, 0x5c, 0x21, + 0x31, 0x2e, 0xb6, 0xa2, 0xd4, 0xc4, 0x94, 0xdc, 0x54, 0x09, 0x36, 0xb0, 0x04, 0x94, 0xe7, 0xc4, + 0x1e, 0xc5, 0x0a, 0x36, 0x29, 0x89, 0x0d, 0x1c, 0x28, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xf4, 0x06, 0xe5, 0x14, 0x89, 0x01, 0x00, 0x00, } diff --git a/pkg/proto/hapi/services/tiller.pb.go b/pkg/proto/hapi/services/tiller.pb.go index 6217f67c9..0dd4b8f3b 100644 --- a/pkg/proto/hapi/services/tiller.pb.go +++ b/pkg/proto/hapi/services/tiller.pb.go @@ -104,9 +104,9 @@ type ListReleasesRequest struct { Limit int64 `protobuf:"varint,1,opt,name=limit" json:"limit,omitempty"` // Offset is the last release name that was seen. The next listing // operation will start with the name after this one. - // Example: If list one returns albert, bernie, carl and we supply - // carl as the offset, the next one should begin with the next release name - // after carl (e.g. dennis). + // Example: If list one returns albert, bernie, carl, and sets 'next: dennis'. + // dennis is the offset. Supplying 'dennis' for the next request should + // cause the next batch to return a set of results starting with 'dennis'. Offset string `protobuf:"bytes,2,opt,name=offset" json:"offset,omitempty"` // SortBy is the sort field that the ListReleases server should sort data before returning. SortBy ListSort_SortBy `protobuf:"varint,3,opt,name=sort_by,json=sortBy,enum=hapi.services.tiller.ListSort_SortBy" json:"sort_by,omitempty"` @@ -244,6 +244,10 @@ type InstallReleaseRequest struct { // a release object nor deploy to Kubernetes. The release object returned // in the response will be fake. DryRun bool `protobuf:"varint,3,opt,name=dry_run,json=dryRun" json:"dry_run,omitempty"` + // Name is the candidate release name. This must be unique to the + // namespace, otherwise the server will return an error. If it is not + // supplied, the server will autogenerate one. + Name string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"` } func (m *InstallReleaseRequest) Reset() { *m = InstallReleaseRequest{} } @@ -582,48 +586,48 @@ var _ReleaseService_serviceDesc = grpc.ServiceDesc{ } var fileDescriptor0 = []byte{ - // 682 bytes of a gzipped FileDescriptorProto + // 688 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x9c, 0x55, 0xdd, 0x4e, 0x13, 0x41, - 0x14, 0x66, 0x69, 0x69, 0xcb, 0x41, 0x48, 0x39, 0x96, 0xb6, 0xee, 0x85, 0x31, 0x93, 0xa8, 0x88, + 0x14, 0x66, 0x69, 0x69, 0xcb, 0x41, 0x48, 0x39, 0x96, 0xb6, 0xee, 0x85, 0x31, 0x9b, 0xa8, 0x88, 0xb2, 0xd5, 0x7a, 0x6f, 0x52, 0xa0, 0x21, 0x84, 0x5a, 0x92, 0xa9, 0x68, 0xe2, 0x85, 0x64, 0x81, - 0xa9, 0xac, 0x59, 0x76, 0xeb, 0xce, 0x94, 0xc8, 0x03, 0x78, 0xe1, 0x1b, 0xf9, 0x40, 0x3e, 0x88, - 0xb3, 0x33, 0x3b, 0x1b, 0xb6, 0xdd, 0xd5, 0x86, 0x9b, 0xdd, 0x39, 0xfb, 0x7d, 0xe7, 0x7c, 0x67, - 0xce, 0x4f, 0x0b, 0xf6, 0x95, 0x3b, 0xf1, 0x3a, 0x9c, 0x45, 0x37, 0xde, 0x05, 0xe3, 0x1d, 0xe1, - 0xf9, 0x3e, 0x8b, 0x9c, 0x49, 0x14, 0x8a, 0x10, 0x1b, 0x31, 0xe6, 0x18, 0xcc, 0xd1, 0x98, 0xdd, - 0x54, 0x1e, 0x17, 0x57, 0x6e, 0x24, 0xf4, 0x53, 0xb3, 0xed, 0xd6, 0xdd, 0xef, 0x61, 0x30, 0xf6, - 0xbe, 0x26, 0x80, 0x96, 0x88, 0x98, 0xcf, 0x5c, 0xce, 0xcc, 0x3b, 0xe3, 0x64, 0x30, 0x2f, 0x18, - 0x87, 0x1a, 0x20, 0x7f, 0x2c, 0x78, 0x38, 0xf0, 0xb8, 0xa0, 0x1a, 0xe2, 0x94, 0x7d, 0x9f, 0x32, - 0x2e, 0xb0, 0x01, 0x2b, 0xbe, 0x77, 0xed, 0x89, 0xb6, 0xf5, 0xc4, 0xda, 0x2e, 0x51, 0x6d, 0x60, - 0x13, 0x2a, 0xe1, 0x78, 0xcc, 0x99, 0x68, 0x2f, 0xcb, 0xcf, 0xab, 0x34, 0xb1, 0xf0, 0x1d, 0x54, - 0x79, 0x18, 0x89, 0xb3, 0xf3, 0xdb, 0x76, 0x49, 0x02, 0x1b, 0xdd, 0xa7, 0x4e, 0xde, 0x9d, 0x9c, - 0x58, 0x69, 0x24, 0x89, 0x4e, 0xfc, 0xd8, 0xbb, 0xa5, 0x15, 0xae, 0xde, 0x71, 0xdc, 0xb1, 0xe7, - 0x0b, 0x16, 0xb5, 0xcb, 0x3a, 0xae, 0xb6, 0xf0, 0x10, 0x40, 0xc5, 0x0d, 0xa3, 0x4b, 0x89, 0xad, - 0xa8, 0xd0, 0xdb, 0x0b, 0x84, 0x3e, 0x89, 0xf9, 0x74, 0x95, 0x9b, 0x23, 0xf9, 0x02, 0x35, 0x43, - 0x20, 0x5d, 0xa8, 0x68, 0x79, 0x5c, 0x83, 0xea, 0xe9, 0xf0, 0x78, 0x78, 0xf2, 0x69, 0x58, 0x5f, - 0xc2, 0x1a, 0x94, 0x87, 0xbd, 0xf7, 0xfd, 0xba, 0x85, 0x9b, 0xb0, 0x3e, 0xe8, 0x8d, 0x3e, 0x9c, - 0xd1, 0xfe, 0xa0, 0xdf, 0x1b, 0xf5, 0x0f, 0xea, 0xcb, 0xe4, 0x31, 0xac, 0xa6, 0x71, 0xb1, 0x0a, - 0xa5, 0xde, 0x68, 0x5f, 0xbb, 0x1c, 0xf4, 0xe5, 0xc9, 0x22, 0xbf, 0x2c, 0x68, 0x64, 0xcb, 0xc8, - 0x27, 0x61, 0xc0, 0x59, 0x5c, 0xc7, 0x8b, 0x70, 0x1a, 0xa4, 0x75, 0x54, 0x06, 0x22, 0x94, 0x03, - 0xf6, 0xc3, 0x54, 0x51, 0x9d, 0x63, 0xa6, 0x08, 0x85, 0xeb, 0xab, 0x0a, 0x4a, 0xa6, 0x32, 0xf0, - 0x0d, 0xd4, 0x92, 0xae, 0x71, 0x59, 0x9b, 0xd2, 0xf6, 0x5a, 0x77, 0x4b, 0xdf, 0xdf, 0xf4, 0x37, - 0x51, 0xa4, 0x29, 0x8d, 0xec, 0x42, 0xeb, 0x90, 0x99, 0x4c, 0x46, 0xc2, 0x15, 0xd3, 0xb4, 0xab, - 0xb1, 0xae, 0x7b, 0xcd, 0x54, 0x32, 0xb1, 0xae, 0x3c, 0x93, 0x8f, 0xd0, 0x9e, 0xa7, 0x27, 0xd9, - 0xe7, 0xf0, 0xf1, 0x19, 0x94, 0xe3, 0xf9, 0x51, 0xb9, 0xaf, 0x75, 0x31, 0x9b, 0xcd, 0x91, 0x44, - 0xa8, 0xc2, 0x89, 0x73, 0x37, 0xee, 0x7e, 0x18, 0x08, 0x16, 0x88, 0x7f, 0xe5, 0x31, 0x80, 0x47, - 0x39, 0xfc, 0x24, 0x91, 0x0e, 0x54, 0x13, 0x09, 0xe5, 0x53, 0x58, 0x05, 0xc3, 0x22, 0x4d, 0x68, - 0x9c, 0x4e, 0x2e, 0x5d, 0xc1, 0x0c, 0xa2, 0x95, 0x49, 0x0b, 0xb6, 0x66, 0xbe, 0x6b, 0x05, 0xf2, - 0xd3, 0x82, 0xad, 0xa3, 0x80, 0xcb, 0x9a, 0xfb, 0x59, 0x17, 0x7c, 0x2e, 0x5b, 0x18, 0x6f, 0x5b, - 0xa2, 0xbc, 0xa9, 0x95, 0xf5, 0x4a, 0xee, 0xc7, 0x4f, 0xaa, 0x71, 0xdc, 0x81, 0xca, 0x8d, 0xeb, - 0x4b, 0x9f, 0x6c, 0x6d, 0x12, 0xa6, 0x5a, 0x55, 0x9a, 0x30, 0xb0, 0x05, 0xd5, 0xcb, 0xe8, 0xf6, - 0x2c, 0x9a, 0x06, 0xaa, 0xdf, 0x35, 0x5a, 0x91, 0x26, 0x9d, 0x06, 0xe4, 0x08, 0x9a, 0xb3, 0x69, - 0xdc, 0xb7, 0x06, 0x72, 0x10, 0x4e, 0x03, 0x2f, 0xf7, 0x4e, 0x79, 0x0d, 0x38, 0x86, 0xf6, 0x3c, - 0xfd, 0x9e, 0xda, 0xdd, 0xdf, 0x2b, 0xb0, 0x61, 0x66, 0x4a, 0x6f, 0x2a, 0x7a, 0xf0, 0xe0, 0xee, - 0x8a, 0xe0, 0x8b, 0xe2, 0x45, 0x9e, 0xf9, 0x35, 0xb2, 0x77, 0x16, 0xa1, 0x26, 0x8d, 0x5c, 0x7a, - 0x6d, 0x21, 0x87, 0xfa, 0xec, 0x4c, 0xe3, 0x6e, 0x7e, 0x8c, 0x82, 0x55, 0xb1, 0x9d, 0x45, 0xe9, - 0x46, 0x16, 0x6f, 0x60, 0x73, 0x6e, 0x80, 0xf1, 0xbf, 0x61, 0xb2, 0x9b, 0x61, 0x77, 0x16, 0xe6, - 0xa7, 0xba, 0xdf, 0x60, 0x3d, 0x33, 0xd2, 0x58, 0x50, 0xad, 0xbc, 0x7d, 0xb0, 0x5f, 0x2e, 0xc4, - 0x4d, 0xb5, 0xae, 0x61, 0x23, 0x3b, 0x9d, 0x58, 0x10, 0x20, 0x77, 0x95, 0xec, 0x57, 0x8b, 0x91, - 0x53, 0x39, 0xd9, 0xc7, 0xd9, 0x91, 0x2c, 0xea, 0x63, 0xc1, 0xa4, 0x17, 0xf5, 0xb1, 0x68, 0xd2, - 0xc9, 0xd2, 0x1e, 0x7c, 0xae, 0x19, 0xf6, 0x79, 0x45, 0xfd, 0x4b, 0xbe, 0xfd, 0x1b, 0x00, 0x00, - 0xff, 0xff, 0x9a, 0xaa, 0x47, 0x7a, 0xbf, 0x07, 0x00, 0x00, + 0xa9, 0xac, 0x59, 0x76, 0xeb, 0xce, 0x94, 0xc8, 0x23, 0xf8, 0x08, 0xbe, 0x89, 0x0f, 0xe4, 0x83, + 0x38, 0x3f, 0x3b, 0x9b, 0x6e, 0xd9, 0xd5, 0x86, 0x9b, 0xdd, 0x99, 0xfd, 0xbe, 0x39, 0xdf, 0x99, + 0xef, 0x9c, 0xd3, 0x82, 0x7d, 0xe5, 0x4d, 0xfc, 0x0e, 0xa3, 0xf1, 0x8d, 0x7f, 0x41, 0x59, 0x87, + 0xfb, 0x41, 0x40, 0x63, 0x77, 0x12, 0x47, 0x3c, 0xc2, 0x86, 0xc4, 0x5c, 0x83, 0xb9, 0x1a, 0xb3, + 0x9b, 0xea, 0xc4, 0xc5, 0x95, 0x17, 0x73, 0xfd, 0xd4, 0x6c, 0xbb, 0x35, 0xfb, 0x3d, 0x0a, 0xc7, + 0xfe, 0xd7, 0x04, 0xd0, 0x12, 0x31, 0x0d, 0xa8, 0xc7, 0xa8, 0x79, 0x67, 0x0e, 0x19, 0xcc, 0x0f, + 0xc7, 0x91, 0x06, 0x9c, 0x3f, 0x16, 0x3c, 0x1c, 0xf8, 0x8c, 0x13, 0x0d, 0x31, 0x42, 0xbf, 0x4f, + 0x29, 0xe3, 0xd8, 0x80, 0x95, 0xc0, 0xbf, 0xf6, 0x79, 0xdb, 0x7a, 0x62, 0x6d, 0x97, 0x88, 0xde, + 0x60, 0x13, 0x2a, 0xd1, 0x78, 0xcc, 0x28, 0x6f, 0x2f, 0x8b, 0xcf, 0xab, 0x24, 0xd9, 0xe1, 0x3b, + 0xa8, 0xb2, 0x28, 0xe6, 0x67, 0xe7, 0xb7, 0xed, 0x92, 0x00, 0x36, 0xba, 0x4f, 0xdd, 0xbc, 0x3b, + 0xb9, 0x52, 0x69, 0x24, 0x88, 0xae, 0x7c, 0xec, 0xdd, 0x92, 0x0a, 0x53, 0x6f, 0x19, 0x77, 0xec, + 0x07, 0x9c, 0xc6, 0xed, 0xb2, 0x8e, 0xab, 0x77, 0x78, 0x08, 0xa0, 0xe2, 0x46, 0xf1, 0xa5, 0xc0, + 0x56, 0x54, 0xe8, 0xed, 0x05, 0x42, 0x9f, 0x48, 0x3e, 0x59, 0x65, 0x66, 0xe9, 0x7c, 0x81, 0x9a, + 0x21, 0x38, 0x5d, 0xa8, 0x68, 0x79, 0x5c, 0x83, 0xea, 0xe9, 0xf0, 0x78, 0x78, 0xf2, 0x69, 0x58, + 0x5f, 0xc2, 0x1a, 0x94, 0x87, 0xbd, 0xf7, 0xfd, 0xba, 0x85, 0x9b, 0xb0, 0x3e, 0xe8, 0x8d, 0x3e, + 0x9c, 0x91, 0xfe, 0xa0, 0xdf, 0x1b, 0xf5, 0x0f, 0xea, 0xcb, 0xce, 0x63, 0x58, 0x4d, 0xe3, 0x62, + 0x15, 0x4a, 0xbd, 0xd1, 0xbe, 0x3e, 0x72, 0xd0, 0x17, 0x2b, 0xcb, 0xf9, 0x69, 0x41, 0x23, 0x6b, + 0x23, 0x9b, 0x44, 0x21, 0xa3, 0xd2, 0xc7, 0x8b, 0x68, 0x1a, 0xa6, 0x3e, 0xaa, 0x0d, 0x22, 0x94, + 0x43, 0xfa, 0xc3, 0xb8, 0xa8, 0xd6, 0x92, 0xc9, 0x23, 0xee, 0x05, 0xca, 0x41, 0xc1, 0x54, 0x1b, + 0x7c, 0x03, 0xb5, 0xa4, 0x6a, 0x4c, 0x78, 0x53, 0xda, 0x5e, 0xeb, 0x6e, 0xe9, 0xfb, 0x9b, 0xfa, + 0x26, 0x8a, 0x24, 0xa5, 0x39, 0xbb, 0xd0, 0x3a, 0xa4, 0x26, 0x93, 0x11, 0xf7, 0xf8, 0x34, 0xad, + 0xaa, 0xd4, 0xf5, 0xae, 0xa9, 0x4a, 0x46, 0xea, 0x8a, 0xb5, 0xf3, 0x11, 0xda, 0x77, 0xe9, 0x49, + 0xf6, 0x39, 0x7c, 0x7c, 0x06, 0x65, 0xd9, 0x3f, 0x2a, 0xf7, 0xb5, 0x2e, 0x66, 0xb3, 0x39, 0x12, + 0x08, 0x51, 0xb8, 0xe3, 0xce, 0xc6, 0xdd, 0x8f, 0x42, 0x4e, 0x43, 0xfe, 0xaf, 0x3c, 0x06, 0xf0, + 0x28, 0x87, 0x9f, 0x24, 0xd2, 0x81, 0x6a, 0x22, 0xa1, 0xce, 0x14, 0xba, 0x60, 0x58, 0x4e, 0x13, + 0x1a, 0xa7, 0x93, 0x4b, 0x8f, 0x53, 0x83, 0x68, 0x65, 0xa7, 0x05, 0x5b, 0x73, 0xdf, 0xb5, 0x82, + 0xf3, 0xcb, 0x82, 0xad, 0xa3, 0x90, 0x09, 0xcf, 0x83, 0xec, 0x11, 0x7c, 0x2e, 0x4a, 0x28, 0xa7, + 0x2d, 0x51, 0xde, 0xd4, 0xca, 0x7a, 0x24, 0xf7, 0xe5, 0x93, 0x68, 0x1c, 0x77, 0xa0, 0x72, 0xe3, + 0x05, 0xe2, 0x4c, 0xd6, 0x9b, 0x84, 0xa9, 0x46, 0x95, 0x24, 0x0c, 0x6c, 0x41, 0xf5, 0x32, 0xbe, + 0x3d, 0x8b, 0xa7, 0xa1, 0xaa, 0x77, 0x8d, 0x54, 0xc4, 0x96, 0x4c, 0xc3, 0xd4, 0x9a, 0xf2, 0x8c, + 0x35, 0x47, 0xd0, 0x9c, 0x4f, 0xed, 0xbe, 0xbe, 0x88, 0xe6, 0x38, 0x0d, 0xfd, 0xdc, 0x7b, 0xe6, + 0x15, 0xe5, 0x18, 0xda, 0x77, 0xe9, 0xf7, 0xd4, 0xee, 0xfe, 0x5e, 0x81, 0x0d, 0xd3, 0x67, 0x7a, + 0x7a, 0xd1, 0x87, 0x07, 0xb3, 0x63, 0x83, 0x2f, 0x8a, 0x87, 0x7b, 0xee, 0x17, 0xca, 0xde, 0x59, + 0x84, 0x9a, 0x14, 0x77, 0xe9, 0xb5, 0x85, 0x0c, 0xea, 0xf3, 0x7d, 0x8e, 0xbb, 0xf9, 0x31, 0x0a, + 0xc6, 0xc7, 0x76, 0x17, 0xa5, 0x1b, 0x59, 0xbc, 0x81, 0xcd, 0x3b, 0x4d, 0x8d, 0xff, 0x0d, 0x93, + 0x9d, 0x16, 0xbb, 0xb3, 0x30, 0x3f, 0xd5, 0xfd, 0x06, 0xeb, 0x99, 0x36, 0xc7, 0x02, 0xb7, 0xf2, + 0x66, 0xc4, 0x7e, 0xb9, 0x10, 0x37, 0xd5, 0xba, 0x86, 0x8d, 0x6c, 0x77, 0x62, 0x41, 0x80, 0xdc, + 0xf1, 0xb2, 0x5f, 0x2d, 0x46, 0x4e, 0xe5, 0x44, 0x1d, 0xe7, 0x5b, 0xb2, 0xa8, 0x8e, 0x05, 0x9d, + 0x5e, 0x54, 0xc7, 0xa2, 0x4e, 0x77, 0x96, 0xf6, 0xe0, 0x73, 0xcd, 0xb0, 0xcf, 0x2b, 0xea, 0x9f, + 0xf3, 0xed, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x39, 0x3c, 0xcd, 0x3c, 0xd3, 0x07, 0x00, 0x00, }