feat(helm,tiller): add support for list filters
This adds support for filtering list results. Filter strings are passed from Helm to Tiller, where they are compiled as regular expressions and executed against the list of releases. Only matching releases are returned. Filters are applied before limits and sorts.
This commit is contained in:
parent
ea6b82a43c
commit
dfc9693afe
|
@ -66,6 +66,11 @@ message ListReleasesRequest {
|
|||
|
||||
// SortBy is the sort field that the ListReleases server should sort data before returning.
|
||||
ListSort.SortBy sort_by = 3;
|
||||
|
||||
// Filter is a regular expression used to filter which releases should be listed.
|
||||
//
|
||||
// Anything that matches the regexp will be included in the results.
|
||||
string filter = 4;
|
||||
}
|
||||
|
||||
message ListSort{
|
||||
|
|
|
@ -2,6 +2,7 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/gosuri/uitable"
|
||||
"github.com/kubernetes/helm/pkg/helm"
|
||||
|
@ -14,13 +15,28 @@ import (
|
|||
var listHelp = `
|
||||
This command lists all of the currently deployed releases.
|
||||
|
||||
By default, items are sorted alphabetically. Sorting is done client-side, so if
|
||||
the number of releases is less than the setting in '--max', some values will
|
||||
be omitted, and in no particular lexicographic order.
|
||||
By default, items are sorted alphabetically. Use the '-d' flag to sort by
|
||||
release date.
|
||||
|
||||
If an argument is provided, it will be treated as a filter. Filters are
|
||||
regular expressions (Perl compatible) that are applied to the list of releases.
|
||||
Only items that match the filter will be returned.
|
||||
|
||||
$ helm list -l 'ara[a-z]+'
|
||||
NAME UPDATED CHART
|
||||
maudlin-arachnid Mon May 9 16:07:08 2016 alpine-0.1.0
|
||||
|
||||
If no results are found, 'helm list' will exit 0, but with no output (or in
|
||||
the case of '-l', only headers).
|
||||
|
||||
By default, up to 256 items may be returned. To limit this, use the '--max' flag.
|
||||
Setting '--max' to 0 will not return all results. Rather, it will return the
|
||||
server's default, which may be much higher than 256. Pairing the '--max'
|
||||
flag with the '--offset' flag allows you to page through results.
|
||||
`
|
||||
|
||||
var listCommand = &cobra.Command{
|
||||
Use: "list [flags]",
|
||||
Use: "list [flags] [FILTER]",
|
||||
Short: "List releases",
|
||||
Long: listHelp,
|
||||
RunE: listCmd,
|
||||
|
@ -41,8 +57,9 @@ func init() {
|
|||
}
|
||||
|
||||
func listCmd(cmd *cobra.Command, args []string) error {
|
||||
var filter string
|
||||
if len(args) > 0 {
|
||||
fmt.Println("TODO: Implement filter.")
|
||||
filter = strings.Join(args, " ")
|
||||
}
|
||||
|
||||
sortBy := services.ListSort_NAME
|
||||
|
@ -50,14 +67,14 @@ func listCmd(cmd *cobra.Command, args []string) error {
|
|||
sortBy = services.ListSort_LAST_RELEASED
|
||||
}
|
||||
|
||||
res, err := helm.ListReleases(listMax, listOffset, sortBy)
|
||||
res, err := helm.ListReleases(listMax, listOffset, sortBy, filter)
|
||||
if err != nil {
|
||||
return prettyError(err)
|
||||
}
|
||||
|
||||
rels := res.Releases
|
||||
if res.Count+res.Offset < res.Total {
|
||||
fmt.Println("Not all values were fetched.")
|
||||
if flagVerbose && res.Count+res.Offset < res.Total {
|
||||
fmt.Println("==> Not all values were fetched.")
|
||||
}
|
||||
|
||||
// Purty output, ya'll
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"regexp"
|
||||
"sort"
|
||||
|
||||
"github.com/kubernetes/helm/cmd/tiller/environment"
|
||||
|
@ -48,12 +49,15 @@ func (s *releaseServer) ListReleases(req *services.ListReleasesRequest, stream s
|
|||
return err
|
||||
}
|
||||
|
||||
total := int64(len(rels))
|
||||
|
||||
if req.SortBy != services.ListSort_UNKNOWN {
|
||||
log.Printf("Sorting by %q", req.SortBy)
|
||||
if len(req.Filter) != 0 {
|
||||
rels, err = filterReleases(req.Filter, rels)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
total := int64(len(rels))
|
||||
|
||||
switch req.SortBy {
|
||||
case services.ListSort_NAME:
|
||||
sort.Sort(byName(rels))
|
||||
|
@ -89,6 +93,20 @@ func (s *releaseServer) ListReleases(req *services.ListReleasesRequest, stream s
|
|||
return nil
|
||||
}
|
||||
|
||||
func filterReleases(filter string, rels []*release.Release) ([]*release.Release, error) {
|
||||
preg, err := regexp.Compile(filter)
|
||||
if err != nil {
|
||||
return rels, err
|
||||
}
|
||||
matches := []*release.Release{}
|
||||
for _, r := range rels {
|
||||
if preg.MatchString(r.Name) {
|
||||
matches = append(matches, r)
|
||||
}
|
||||
}
|
||||
return matches, nil
|
||||
}
|
||||
|
||||
func (s *releaseServer) GetReleaseStatus(c ctx.Context, req *services.GetReleaseStatusRequest) (*services.GetReleaseStatusResponse, error) {
|
||||
if req.Name == "" {
|
||||
return nil, errMissingRelease
|
||||
|
|
|
@ -217,6 +217,86 @@ func TestListReleases(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestListReleasesSort(t *testing.T) {
|
||||
rs := rsFixture()
|
||||
|
||||
// Put them in by reverse order so that the mock doesn't "accidentally"
|
||||
// sort.
|
||||
num := 7
|
||||
for i := num; i > 0; i-- {
|
||||
rel := releaseMock()
|
||||
rel.Name = fmt.Sprintf("rel-%d", i)
|
||||
if err := rs.env.Releases.Create(rel); err != nil {
|
||||
t.Fatalf("Could not store mock release: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
limit := 6
|
||||
mrs := &mockListServer{}
|
||||
req := &services.ListReleasesRequest{
|
||||
Offset: 0,
|
||||
Limit: int64(limit),
|
||||
SortBy: services.ListSort_NAME,
|
||||
}
|
||||
if err := rs.ListReleases(req, mrs); err != nil {
|
||||
t.Fatalf("Failed listing: %s", err)
|
||||
}
|
||||
|
||||
if len(mrs.val.Releases) != limit {
|
||||
t.Errorf("Expected %d releases, got %d", limit, len(mrs.val.Releases))
|
||||
}
|
||||
|
||||
for i := 0; i < limit; i++ {
|
||||
n := fmt.Sprintf("rel-%d", i+1)
|
||||
if mrs.val.Releases[i].Name != n {
|
||||
t.Errorf("Expected %q, got %q", n, mrs.val.Releases[i].Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestListReleasesFilter(t *testing.T) {
|
||||
rs := rsFixture()
|
||||
names := []string{
|
||||
"axon",
|
||||
"dendrite",
|
||||
"neuron",
|
||||
"neuroglia",
|
||||
"synapse",
|
||||
"nucleus",
|
||||
"organelles",
|
||||
}
|
||||
num := 7
|
||||
for i := 0; i < num; i++ {
|
||||
rel := releaseMock()
|
||||
rel.Name = names[i]
|
||||
if err := rs.env.Releases.Create(rel); err != nil {
|
||||
t.Fatalf("Could not store mock release: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
mrs := &mockListServer{}
|
||||
req := &services.ListReleasesRequest{
|
||||
Offset: 0,
|
||||
Limit: 64,
|
||||
Filter: "neuro[a-z]+",
|
||||
SortBy: services.ListSort_NAME,
|
||||
}
|
||||
if err := rs.ListReleases(req, mrs); err != nil {
|
||||
t.Fatalf("Failed listing: %s", err)
|
||||
}
|
||||
|
||||
if len(mrs.val.Releases) != 2 {
|
||||
t.Errorf("Expected 2 releases, got %d", len(mrs.val.Releases))
|
||||
}
|
||||
|
||||
if mrs.val.Releases[0].Name != "neuroglia" {
|
||||
t.Errorf("Unexpected sort order: %v.", mrs.val.Releases)
|
||||
}
|
||||
if mrs.val.Releases[1].Name != "neuron" {
|
||||
t.Errorf("Unexpected sort order: %v.", mrs.val.Releases)
|
||||
}
|
||||
}
|
||||
|
||||
func mockEnvironment() *environment.Environment {
|
||||
e := environment.New()
|
||||
e.Releases = storage.NewMemory()
|
||||
|
|
|
@ -13,7 +13,7 @@ var Config = &config{
|
|||
}
|
||||
|
||||
// ListReleases lists the current releases.
|
||||
func ListReleases(limit, offset int, sort services.ListSort_SortBy) (*services.ListReleasesResponse, error) {
|
||||
func ListReleases(limit, offset int, sort services.ListSort_SortBy, filter string) (*services.ListReleasesResponse, error) {
|
||||
c := Config.client()
|
||||
if err := c.dial(); err != nil {
|
||||
return nil, err
|
||||
|
@ -24,6 +24,7 @@ func ListReleases(limit, offset int, sort services.ListSort_SortBy) (*services.L
|
|||
Limit: int64(limit),
|
||||
Offset: int64(offset),
|
||||
SortBy: sort,
|
||||
Filter: filter,
|
||||
}
|
||||
cli, err := c.impl.ListReleases(context.TODO(), req, c.cfg.CallOpts()...)
|
||||
if err != nil {
|
||||
|
|
|
@ -83,6 +83,10 @@ type ListReleasesRequest struct {
|
|||
Offset int64 `protobuf:"varint,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"`
|
||||
// Filter is a regular expression used to filter which releases should be listed.
|
||||
//
|
||||
// Anything that matches the regexp will be included in the results.
|
||||
Filter string `protobuf:"bytes,4,opt,name=filter" json:"filter,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ListReleasesRequest) Reset() { *m = ListReleasesRequest{} }
|
||||
|
@ -547,44 +551,45 @@ var _ReleaseService_serviceDesc = grpc.ServiceDesc{
|
|||
}
|
||||
|
||||
var fileDescriptor0 = []byte{
|
||||
// 623 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x9c, 0x55, 0x5d, 0x6f, 0xda, 0x3c,
|
||||
0x18, 0x6d, 0x5a, 0x1a, 0x78, 0x1f, 0xde, 0x22, 0xf0, 0xf8, 0xc8, 0x72, 0x55, 0x59, 0xda, 0xd6,
|
||||
0x75, 0x6b, 0xd8, 0xd8, 0x7d, 0x25, 0xda, 0xa1, 0x09, 0x95, 0x31, 0xc9, 0x8c, 0x4d, 0xda, 0x0d,
|
||||
0x4a, 0xa9, 0x59, 0x33, 0x85, 0x84, 0xc5, 0x06, 0x89, 0xeb, 0x69, 0x97, 0xfb, 0x3f, 0xfb, 0x79,
|
||||
0x4b, 0xec, 0x38, 0x22, 0x90, 0x6c, 0xa8, 0x37, 0x4e, 0xed, 0x73, 0xec, 0xf3, 0x7c, 0x9c, 0xa7,
|
||||
0x80, 0x79, 0x6f, 0x2f, 0x9c, 0x36, 0xa3, 0xc1, 0xca, 0x99, 0x52, 0xd6, 0xe6, 0x8e, 0xeb, 0xd2,
|
||||
0xc0, 0x5a, 0x04, 0x3e, 0xf7, 0x51, 0x3d, 0xc2, 0x2c, 0x85, 0x59, 0x12, 0x33, 0x9b, 0xe2, 0xc6,
|
||||
0xf4, 0xde, 0x0e, 0xb8, 0x5c, 0x25, 0xdb, 0x6c, 0x6d, 0x9e, 0xfb, 0xde, 0xcc, 0xf9, 0x1a, 0x03,
|
||||
0x52, 0x22, 0xa0, 0x2e, 0xb5, 0x19, 0x55, 0xdf, 0xd4, 0x25, 0x85, 0x39, 0xde, 0xcc, 0x97, 0x00,
|
||||
0xfe, 0xa1, 0xc1, 0xa3, 0x81, 0xc3, 0x38, 0x91, 0x10, 0x23, 0xf4, 0xfb, 0x92, 0x32, 0x8e, 0xea,
|
||||
0x70, 0xec, 0x3a, 0x73, 0x87, 0x1b, 0xda, 0xa9, 0x76, 0x76, 0x44, 0xe4, 0x06, 0x35, 0x41, 0xf7,
|
||||
0x67, 0x33, 0x46, 0xb9, 0x71, 0x28, 0x8e, 0xe3, 0x1d, 0xba, 0x84, 0x22, 0xf3, 0x03, 0x3e, 0xb9,
|
||||
0x5d, 0x1b, 0x47, 0x21, 0x50, 0xe9, 0x3c, 0xb1, 0xb2, 0x72, 0xb2, 0x22, 0xa5, 0x51, 0x48, 0xb4,
|
||||
0xa2, 0xe5, 0x6a, 0x4d, 0x74, 0x26, 0xbe, 0xf8, 0x12, 0x4a, 0x0a, 0xc2, 0x1d, 0xd0, 0x25, 0x8a,
|
||||
0xca, 0x50, 0x1c, 0x0f, 0x6f, 0x86, 0x1f, 0x3e, 0x0f, 0xab, 0x07, 0xa8, 0x04, 0x85, 0x61, 0xf7,
|
||||
0x7d, 0xaf, 0xaa, 0xa1, 0x1a, 0x9c, 0x0c, 0xba, 0xa3, 0x8f, 0x13, 0xd2, 0x1b, 0xf4, 0xba, 0xa3,
|
||||
0xde, 0xdb, 0xea, 0x21, 0xfe, 0xa5, 0x41, 0x3d, 0x9d, 0x05, 0x5b, 0xf8, 0x1e, 0xa3, 0x51, 0x1a,
|
||||
0x53, 0x7f, 0xe9, 0x25, 0x69, 0x88, 0x4d, 0x6e, 0x1a, 0x21, 0x9b, 0xfb, 0xdc, 0x76, 0x45, 0x12,
|
||||
0x21, 0x5b, 0x6c, 0xd0, 0x6b, 0x28, 0xc5, 0x85, 0x63, 0x46, 0xe1, 0xf4, 0xe8, 0xac, 0xdc, 0x69,
|
||||
0xc8, 0xec, 0x54, 0x89, 0x63, 0x55, 0x92, 0xd0, 0xf0, 0x05, 0xb4, 0xde, 0x51, 0x15, 0xcd, 0x88,
|
||||
0xdb, 0x7c, 0x99, 0x14, 0x16, 0x41, 0xc1, 0xb3, 0xe7, 0x54, 0x04, 0xf4, 0x1f, 0x11, 0x7f, 0xe3,
|
||||
0x4f, 0x60, 0xec, 0xd2, 0xe3, 0x0c, 0x32, 0xf8, 0xe8, 0x29, 0x14, 0xa2, 0x16, 0x8a, 0xe8, 0xcb,
|
||||
0x1d, 0x94, 0x8e, 0xa6, 0x1f, 0x22, 0x44, 0xe0, 0xd8, 0xda, 0x7c, 0xf7, 0xda, 0xf7, 0x38, 0xf5,
|
||||
0xf8, 0xdf, 0xe2, 0x18, 0xc0, 0xe3, 0x0c, 0x7e, 0x1c, 0x48, 0x1b, 0x8a, 0xb1, 0x84, 0xb8, 0x93,
|
||||
0x5b, 0x05, 0xc5, 0xc2, 0x4d, 0xa8, 0x8f, 0x17, 0x77, 0x36, 0xa7, 0x0a, 0x91, 0xca, 0xb8, 0x05,
|
||||
0x8d, 0xad, 0x73, 0xa9, 0x80, 0x7f, 0x6a, 0xd0, 0xe8, 0x7b, 0x2c, 0xac, 0xb9, 0x9b, 0xbe, 0x82,
|
||||
0x9e, 0x85, 0x6d, 0x8c, 0x0c, 0x1f, 0x2b, 0xd7, 0xa4, 0xb2, 0x9c, 0x8a, 0xeb, 0x68, 0x25, 0x12,
|
||||
0x47, 0xe7, 0xa0, 0xaf, 0x6c, 0x37, 0xbc, 0x93, 0xae, 0x4d, 0xcc, 0x14, 0xd3, 0x42, 0x62, 0x06,
|
||||
0x6a, 0x41, 0xf1, 0x2e, 0x58, 0x4f, 0x82, 0xa5, 0x27, 0xfa, 0x5d, 0x22, 0x7a, 0xb8, 0x25, 0x4b,
|
||||
0x0f, 0xf7, 0xa1, 0xb9, 0x1d, 0xc6, 0x43, 0x6b, 0x10, 0x1a, 0x61, 0xec, 0x39, 0x99, 0x39, 0x65,
|
||||
0x35, 0xe0, 0x06, 0x8c, 0x5d, 0xfa, 0x03, 0xb5, 0x3b, 0xbf, 0x8f, 0xa1, 0xa2, 0x3c, 0x25, 0xe7,
|
||||
0x10, 0x39, 0xf0, 0xff, 0xe6, 0x98, 0xa0, 0xe7, 0xf9, 0x63, 0xba, 0xf5, 0x0f, 0xc1, 0x3c, 0xdf,
|
||||
0x87, 0x1a, 0x37, 0xf2, 0xe0, 0x95, 0x86, 0x18, 0x54, 0xb7, 0x3d, 0x8d, 0x2e, 0xb2, 0xdf, 0xc8,
|
||||
0x19, 0x15, 0xd3, 0xda, 0x97, 0xae, 0x64, 0xd1, 0x0a, 0x6a, 0x3b, 0x06, 0x46, 0xff, 0x7c, 0x26,
|
||||
0x3d, 0x19, 0x66, 0x7b, 0x6f, 0x7e, 0xa2, 0xfb, 0x0d, 0x4e, 0x52, 0x96, 0x46, 0x39, 0xd5, 0xca,
|
||||
0x9a, 0x07, 0xf3, 0xc5, 0x5e, 0xdc, 0x44, 0x6b, 0x0e, 0x95, 0xb4, 0x3b, 0x51, 0xce, 0x03, 0x99,
|
||||
0xa3, 0x64, 0xbe, 0xdc, 0x8f, 0x9c, 0xc8, 0x85, 0x7d, 0xdc, 0xb6, 0x64, 0x5e, 0x1f, 0x73, 0x9c,
|
||||
0x9e, 0xd7, 0xc7, 0x3c, 0xa7, 0xe3, 0x83, 0x2b, 0xf8, 0x52, 0x52, 0xec, 0x5b, 0x5d, 0xfc, 0x50,
|
||||
0xbd, 0xf9, 0x13, 0x00, 0x00, 0xff, 0xff, 0xa2, 0xbb, 0x4a, 0x7d, 0x42, 0x07, 0x00, 0x00,
|
||||
// 637 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x9c, 0x55, 0xdf, 0x6e, 0xd3, 0x3e,
|
||||
0x14, 0x5e, 0xb6, 0x2e, 0xed, 0xce, 0x7e, 0x9b, 0x3a, 0xff, 0xba, 0x36, 0xe4, 0x0a, 0x59, 0x02,
|
||||
0xc6, 0x60, 0x29, 0x94, 0xfb, 0x49, 0xdd, 0xa8, 0x50, 0xb5, 0x52, 0x24, 0x97, 0x82, 0xc4, 0x4d,
|
||||
0x95, 0x75, 0x2e, 0x0b, 0x4a, 0x93, 0x12, 0xbb, 0x95, 0xfa, 0x00, 0x5c, 0xf2, 0x04, 0xbc, 0x08,
|
||||
0x8f, 0x87, 0x63, 0x3b, 0x51, 0xd3, 0x26, 0x50, 0xed, 0xc6, 0xd9, 0xf1, 0xf7, 0x1d, 0x7f, 0xe7,
|
||||
0xef, 0x0a, 0xf6, 0xbd, 0x3b, 0xf3, 0x9a, 0x8c, 0x46, 0x0b, 0x6f, 0x4c, 0x59, 0x93, 0x7b, 0xbe,
|
||||
0x4f, 0x23, 0x67, 0x16, 0x85, 0x3c, 0x44, 0xb5, 0x18, 0x73, 0x12, 0xcc, 0x51, 0x98, 0x5d, 0x97,
|
||||
0x1e, 0xe3, 0x7b, 0x37, 0xe2, 0xea, 0x54, 0x6c, 0xbb, 0xb1, 0x7a, 0x1f, 0x06, 0x13, 0xef, 0xab,
|
||||
0x06, 0x94, 0x44, 0x44, 0x7d, 0xea, 0x32, 0x9a, 0x7c, 0x33, 0x4e, 0x09, 0xe6, 0x05, 0x93, 0x50,
|
||||
0x01, 0xf8, 0x97, 0x01, 0xff, 0xf7, 0x3c, 0xc6, 0x89, 0x82, 0x18, 0xa1, 0xdf, 0xe7, 0x94, 0x71,
|
||||
0x54, 0x83, 0x7d, 0xdf, 0x9b, 0x7a, 0xdc, 0x32, 0x1e, 0x1b, 0x67, 0x7b, 0x44, 0x19, 0xa8, 0x0e,
|
||||
0x66, 0x38, 0x99, 0x30, 0xca, 0xad, 0x5d, 0x79, 0xad, 0x2d, 0x74, 0x09, 0x65, 0x16, 0x46, 0x7c,
|
||||
0x74, 0xbb, 0xb4, 0xf6, 0x04, 0x70, 0xdc, 0x7a, 0xe2, 0xe4, 0xe5, 0xe4, 0xc4, 0x4a, 0x03, 0x41,
|
||||
0x74, 0xe2, 0xe3, 0x6a, 0x49, 0x4c, 0x26, 0xbf, 0xf1, 0xbb, 0x13, 0xcf, 0xe7, 0x34, 0xb2, 0x4a,
|
||||
0xc2, 0xfd, 0x80, 0x68, 0x0b, 0x5f, 0x42, 0x25, 0x71, 0xc1, 0x2d, 0x30, 0x95, 0x17, 0x3a, 0x84,
|
||||
0xf2, 0xb0, 0x7f, 0xd3, 0xff, 0xf0, 0xb9, 0x5f, 0xdd, 0x41, 0x15, 0x28, 0xf5, 0xdb, 0xef, 0x3b,
|
||||
0x55, 0x03, 0x9d, 0xc0, 0x51, 0xaf, 0x3d, 0xf8, 0x38, 0x22, 0x9d, 0x5e, 0xa7, 0x3d, 0xe8, 0xbc,
|
||||
0xad, 0xee, 0xe2, 0x9f, 0x06, 0xd4, 0xb2, 0xd9, 0xb1, 0x59, 0x18, 0x30, 0x1a, 0xa7, 0x37, 0x0e,
|
||||
0xe7, 0x41, 0x9a, 0x9e, 0x34, 0x0a, 0xd3, 0x13, 0x6c, 0x1e, 0x72, 0xd7, 0x97, 0xc9, 0x09, 0xb6,
|
||||
0x34, 0xd0, 0x6b, 0xa8, 0xe8, 0x82, 0x32, 0x11, 0xf6, 0xde, 0xd9, 0x61, 0xeb, 0x54, 0x65, 0x9d,
|
||||
0x94, 0x5e, 0xab, 0x92, 0x94, 0x86, 0x2f, 0xa0, 0xf1, 0x8e, 0x26, 0xd1, 0x0c, 0xb8, 0xcb, 0xe7,
|
||||
0x69, 0xc1, 0x11, 0x94, 0x02, 0x77, 0x4a, 0x65, 0x40, 0x07, 0x44, 0xfe, 0x8d, 0x3f, 0x81, 0xb5,
|
||||
0x49, 0xd7, 0x19, 0xe4, 0xf0, 0xd1, 0x53, 0x28, 0xc5, 0xad, 0x95, 0xd1, 0x1f, 0xb6, 0x50, 0x36,
|
||||
0x9a, 0xae, 0x40, 0x88, 0xc4, 0xb1, 0xb3, 0xfa, 0xee, 0x75, 0x18, 0x70, 0x1a, 0xf0, 0xbf, 0xc5,
|
||||
0xd1, 0x83, 0x47, 0x39, 0x7c, 0x1d, 0x48, 0x13, 0xca, 0x5a, 0x42, 0xfa, 0x14, 0x56, 0x21, 0x61,
|
||||
0xe1, 0x3a, 0xd4, 0x86, 0xb3, 0x3b, 0x97, 0xd3, 0x04, 0x51, 0xca, 0xb8, 0x01, 0xa7, 0x6b, 0xf7,
|
||||
0x4a, 0x01, 0xff, 0x30, 0xe0, 0xb4, 0x1b, 0x30, 0x51, 0x73, 0x3f, 0xeb, 0x82, 0x9e, 0x89, 0x36,
|
||||
0xc6, 0x8b, 0xa0, 0x95, 0x4f, 0x94, 0xb2, 0xda, 0x96, 0xeb, 0xf8, 0x24, 0x0a, 0x47, 0xe7, 0x60,
|
||||
0x2e, 0x5c, 0x5f, 0xf8, 0x64, 0x6b, 0xa3, 0x99, 0x72, 0x8b, 0x88, 0x66, 0xa0, 0x06, 0x94, 0xef,
|
||||
0xa2, 0xe5, 0x28, 0x9a, 0x07, 0xb2, 0xdf, 0x15, 0x62, 0x0a, 0x93, 0xcc, 0x03, 0xdc, 0x85, 0xfa,
|
||||
0x7a, 0x18, 0x0f, 0xad, 0x81, 0x18, 0x84, 0x61, 0xe0, 0xe5, 0xe6, 0x94, 0xd7, 0x80, 0x1b, 0xb0,
|
||||
0x36, 0xe9, 0x0f, 0xd4, 0x6e, 0xfd, 0xde, 0x87, 0xe3, 0x64, 0xa6, 0xd4, 0x7e, 0x22, 0x0f, 0xfe,
|
||||
0x5b, 0x5d, 0x13, 0xf4, 0xbc, 0x78, 0x7d, 0xd7, 0xfe, 0x51, 0xd8, 0xe7, 0xdb, 0x50, 0x75, 0x23,
|
||||
0x77, 0x5e, 0x19, 0x88, 0x41, 0x75, 0x7d, 0xa6, 0xd1, 0x45, 0xfe, 0x1b, 0x05, 0xab, 0x62, 0x3b,
|
||||
0xdb, 0xd2, 0x13, 0x59, 0xb4, 0x80, 0x93, 0x8d, 0x01, 0x46, 0xff, 0x7c, 0x26, 0xbb, 0x19, 0x76,
|
||||
0x73, 0x6b, 0x7e, 0xaa, 0xfb, 0x0d, 0x8e, 0x32, 0x23, 0x8d, 0x0a, 0xaa, 0x95, 0xb7, 0x0f, 0xf6,
|
||||
0x8b, 0xad, 0xb8, 0xa9, 0xd6, 0x14, 0x8e, 0xb3, 0xd3, 0x89, 0x0a, 0x1e, 0xc8, 0x5d, 0x25, 0xfb,
|
||||
0xe5, 0x76, 0xe4, 0x54, 0x4e, 0xf4, 0x71, 0x7d, 0x24, 0x8b, 0xfa, 0x58, 0x30, 0xe9, 0x45, 0x7d,
|
||||
0x2c, 0x9a, 0x74, 0xbc, 0x73, 0x05, 0x5f, 0x2a, 0x09, 0xfb, 0xd6, 0x94, 0x3f, 0x60, 0x6f, 0xfe,
|
||||
0x04, 0x00, 0x00, 0xff, 0xff, 0xcf, 0x16, 0x42, 0xc7, 0x5a, 0x07, 0x00, 0x00,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue