diff --git a/cmd/cli/app/pflags.go b/cmd/cli/app/pflags.go index 4d7ced9410f1ef09b34827af58e6371aa65eb063..d39cb14706871cad145d12df8f7395a686a9270f 100644 --- a/cmd/cli/app/pflags.go +++ b/cmd/cli/app/pflags.go @@ -32,6 +32,7 @@ import ( "github.com/go-openapi/swag" "github.com/projectrekor/rekor/pkg/generated/models" rekord_v001 "github.com/projectrekor/rekor/pkg/types/rekord/v0.0.1" + rpm_v001 "github.com/projectrekor/rekor/pkg/types/rpm/v0.0.1" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -66,13 +67,14 @@ func validateSearchPFlags() error { func addArtifactPFlags(cmd *cobra.Command) error { cmd.Flags().Var(&fileOrURLFlag{}, "signature", "path or URL to detached signature file") + cmd.Flags().Var(&typeFlag{value: "rekord"}, "type", "type of entry") cmd.Flags().Var(&pkiFormatFlag{value: "pgp"}, "pki-format", "format of the signature and/or public key") cmd.Flags().Var(&fileOrURLFlag{}, "public-key", "path or URL to public key file") cmd.Flags().Var(&fileOrURLFlag{}, "artifact", "path or URL to artifact file") - cmd.Flags().Var(&fileOrURLFlag{}, "rekord", "path or URL to Rekor rekord file") + cmd.Flags().Var(&fileOrURLFlag{}, "entry", "path or URL to pre-formatted entry file") cmd.Flags().Var(&shaFlag{}, "sha", "the sha of the artifact") return nil @@ -104,7 +106,8 @@ func validateArtifactPFlags(uuidValid, indexValid bool) error { } } // we will need artifact, public-key, signature, and potentially SHA - rekord := viper.GetString("rekord") + typeStr := viper.GetString("type") + entry := viper.GetString("entry") artifact := fileOrURLFlag{} artifactStr := viper.GetString("artifact") @@ -118,18 +121,18 @@ func validateArtifactPFlags(uuidValid, indexValid bool) error { publicKey := viper.GetString("public-key") sha := viper.GetString("sha") - if rekord == "" && artifact.String() == "" { + if entry == "" && artifact.String() == "" { if (uuidGiven && uuidValid) || (indexGiven && indexValid) { return nil } - return errors.New("either 'rekord' or 'artifact' must be specified") + return errors.New("either 'entry' or 'artifact' must be specified") } - if rekord == "" { + if entry == "" { if artifact.IsURL && sha == "" { return errors.New("a valid SHA hash must be specified when specifying a URL for --artifact") } - if signature == "" { + if signature == "" && typeStr == "rekord" { return errors.New("--signature is required when --artifact is used") } if publicKey == "" { @@ -140,12 +143,91 @@ func validateArtifactPFlags(uuidValid, indexValid bool) error { return nil } +func CreateRpmFromPFlags() (models.ProposedEntry, error) { + //TODO: how to select version of item to create + returnVal := models.Rpm{} + re := new(rpm_v001.V001Entry) + + rpm := viper.GetString("entry") + if rpm != "" { + var rpmBytes []byte + rpmURL, err := url.Parse(rpm) + if err == nil && rpmURL.IsAbs() { + /* #nosec G107 */ + rpmResp, err := http.Get(rpm) + if err != nil { + return nil, fmt.Errorf("error fetching 'rpm': %w", err) + } + defer rpmResp.Body.Close() + rpmBytes, err = ioutil.ReadAll(rpmResp.Body) + if err != nil { + return nil, fmt.Errorf("error fetching 'rpm': %w", err) + } + } else { + rpmBytes, err = ioutil.ReadFile(filepath.Clean(rpm)) + if err != nil { + return nil, fmt.Errorf("error processing 'rpm' file: %w", err) + } + } + if err := json.Unmarshal(rpmBytes, &returnVal); err != nil { + return nil, fmt.Errorf("error parsing rpm file: %w", err) + } + } else { + // we will need artifact, public-key, signature, and potentially SHA + re.RPMModel = models.RpmV001Schema{} + re.RPMModel.Package = &models.RpmV001SchemaPackage{} + + artifact := viper.GetString("artifact") + dataURL, err := url.Parse(artifact) + if err == nil && dataURL.IsAbs() { + re.RPMModel.Package.URL = strfmt.URI(artifact) + re.RPMModel.Package.Hash = &models.RpmV001SchemaPackageHash{} + re.RPMModel.Package.Hash.Algorithm = swag.String(models.RpmV001SchemaPackageHashAlgorithmSha256) + re.RPMModel.Package.Hash.Value = swag.String(viper.GetString("sha")) + } else { + artifactBytes, err := ioutil.ReadFile(filepath.Clean(artifact)) + if err != nil { + return nil, fmt.Errorf("error reading artifact file: %w", err) + } + re.RPMModel.Package.Content = strfmt.Base64(artifactBytes) + } + + re.RPMModel.PublicKey = &models.RpmV001SchemaPublicKey{} + publicKey := viper.GetString("public-key") + keyURL, err := url.Parse(publicKey) + if err == nil && keyURL.IsAbs() { + re.RPMModel.PublicKey.URL = strfmt.URI(publicKey) + } else { + keyBytes, err := ioutil.ReadFile(filepath.Clean(publicKey)) + if err != nil { + return nil, fmt.Errorf("error reading public key file: %w", err) + } + re.RPMModel.PublicKey.Content = strfmt.Base64(keyBytes) + } + + if err := re.Validate(); err != nil { + return nil, err + } + + if re.HasExternalEntities() { + if err := re.FetchExternalEntities(context.Background()); err != nil { + return nil, fmt.Errorf("error retrieving external entities: %v", err) + } + } + + returnVal.APIVersion = swag.String(re.APIVersion()) + returnVal.Spec = re.RPMModel + } + + return &returnVal, nil +} + func CreateRekordFromPFlags() (models.ProposedEntry, error) { //TODO: how to select version of item to create returnVal := models.Rekord{} re := new(rekord_v001.V001Entry) - rekord := viper.GetString("rekord") + rekord := viper.GetString("entry") if rekord != "" { var rekordBytes []byte rekordURL, err := url.Parse(rekord) @@ -268,6 +350,30 @@ func (f *fileOrURLFlag) Type() string { return "fileOrURLFlag" } +type typeFlag struct { + value string +} + +func (t *typeFlag) Type() string { + return "typeFormat" +} + +func (t *typeFlag) String() string { + return t.value +} + +func (t *typeFlag) Set(s string) error { + set := map[string]struct{}{ + "rekord": {}, + "rpm": {}, + } + if _, ok := set[s]; ok { + t.value = s + return nil + } + return fmt.Errorf("value specified is invalid: [%s] supported values are: [rekord, rpm]", s) +} + type pkiFormatFlag struct { value string } diff --git a/cmd/cli/app/pflags_test.go b/cmd/cli/app/pflags_test.go index d18be1ee158b90d626e0301a877d7ea4810bc840..28b8f8c42a15a7f1e93b4e155b461b8d390407c9 100644 --- a/cmd/cli/app/pflags_test.go +++ b/cmd/cli/app/pflags_test.go @@ -23,6 +23,7 @@ import ( "net/http/httptest" "testing" + "github.com/projectrekor/rekor/pkg/generated/models" "github.com/spf13/viper" "github.com/spf13/cobra" @@ -31,7 +32,8 @@ import ( func TestArtifactPFlags(t *testing.T) { type test struct { caseDesc string - rekord string + typeStr string + entry string artifact string signature string publicKey string @@ -58,6 +60,12 @@ func TestArtifactPFlags(t *testing.T) { file, err = ioutil.ReadFile("../../../tests/test_public_key.key") case "/rekord": file, err = ioutil.ReadFile("../../../tests/rekor.json") + case "/rpmEntry": + file, err = ioutil.ReadFile("../../../tests/rpm.json") + case "/rpm": + file, err = ioutil.ReadFile("../../../tests/test.rpm") + case "/rpmPublicKey": + file, err = ioutil.ReadFile("../../../tests/test_rpm_public_key.key") case "/not_found": err = errors.New("file not found") } @@ -73,36 +81,72 @@ func TestArtifactPFlags(t *testing.T) { tests := []test{ { caseDesc: "valid rekord file", - rekord: "../../../tests/rekor.json", + entry: "../../../tests/rekor.json", expectParseSuccess: true, expectValidateSuccess: true, }, { caseDesc: "valid rekord URL", - rekord: testServer.URL + "/rekord", + entry: testServer.URL + "/rekord", expectParseSuccess: true, expectValidateSuccess: true, }, + { + caseDesc: "valid rekord file, wrong type", + typeStr: "rpm", + entry: "../../../tests/rekor.json", + expectParseSuccess: true, + expectValidateSuccess: false, + }, + { + caseDesc: "valid rpm file", + entry: "../../../tests/rpm.json", + typeStr: "rpm", + expectParseSuccess: true, + expectValidateSuccess: true, + }, + { + caseDesc: "valid rpm URL", + entry: testServer.URL + "/rpmEntry", + typeStr: "rpm", + expectParseSuccess: true, + expectValidateSuccess: true, + }, + { + caseDesc: "valid rpm file, wrong type", + typeStr: "rekord", + entry: "../../../tests/rpm.json", + expectParseSuccess: true, + expectValidateSuccess: false, + }, { caseDesc: "non-existant rekord file", - rekord: "../../../tests/not_there.json", + entry: "../../../tests/not_there.json", expectParseSuccess: false, expectValidateSuccess: false, }, { caseDesc: "non-existant rekord url", - rekord: testServer.URL + "/not_found", + entry: testServer.URL + "/not_found", expectParseSuccess: true, expectValidateSuccess: false, }, { - caseDesc: "valid local artifact with required flags", + caseDesc: "valid rekord - local artifact with required flags", artifact: "../../../tests/test_file.txt", signature: "../../../tests/test_file.sig", publicKey: "../../../tests/test_public_key.key", expectParseSuccess: true, expectValidateSuccess: true, }, + { + caseDesc: "valid rpm - local artifact with required flags", + typeStr: "rpm", + artifact: "../../../tests/test.rpm", + publicKey: "../../../tests/test_rpm_public_key.key", + expectParseSuccess: true, + expectValidateSuccess: true, + }, { caseDesc: "valid local artifact with incorrect length hex SHA value", artifact: "../../../tests/test_file.txt", @@ -113,7 +157,7 @@ func TestArtifactPFlags(t *testing.T) { expectValidateSuccess: false, }, { - caseDesc: "valid remote artifact with incorrect length hex SHA value", + caseDesc: "valid rekord - remote artifact with incorrect length hex SHA value", artifact: testServer.URL + "/artifact", sha: "12345abcde", signature: "../../../tests/test_file.sig", @@ -192,7 +236,7 @@ func TestArtifactPFlags(t *testing.T) { expectValidateSuccess: false, }, { - caseDesc: "valid remote artifact with required flags", + caseDesc: "valid rekord - remote artifact with required flags", artifact: testServer.URL + "/artifact", sha: "45c7b11fcbf07dec1694adecd8c5b85770a12a6c8dfdcf2580a2db0c47c31779", signature: "../../../tests/test_file.sig", @@ -200,6 +244,15 @@ func TestArtifactPFlags(t *testing.T) { expectParseSuccess: true, expectValidateSuccess: true, }, + { + caseDesc: "valid rpm - remote artifact with required flags", + typeStr: "rpm", + artifact: testServer.URL + "/rpm", + sha: "c8b0bc59708d74f53aab0089ac587d5c348d6ead143dab9f6d9c4b48c973bfd8", + publicKey: "../../../tests/test_rpm_public_key.key", + expectParseSuccess: true, + expectValidateSuccess: true, + }, { caseDesc: "remote artifact with invalid URL", artifact: "hteeteep%**/test_file.txt", @@ -309,8 +362,11 @@ func TestArtifactPFlags(t *testing.T) { args := []string{} - if tc.rekord != "" { - args = append(args, "--rekord", tc.rekord) + if tc.entry != "" { + args = append(args, "--entry", tc.entry) + } + if tc.typeStr != "" { + args = append(args, "--type", tc.typeStr) } if tc.artifact != "" { args = append(args, "--artifact", tc.artifact) @@ -345,8 +401,15 @@ func TestArtifactPFlags(t *testing.T) { continue } if !tc.uuidRequired && !tc.logIndexRequired { - if _, err := CreateRekordFromPFlags(); err != nil { - t.Errorf("unexpected result in '%v' building Rekord: %v", tc.caseDesc, err) + var createFn func() (models.ProposedEntry, error) + switch tc.typeStr { + case "", "rekord": + createFn = CreateRekordFromPFlags + case "rpm": + createFn = CreateRpmFromPFlags + } + if _, err := createFn(); err != nil { + t.Errorf("unexpected result in '%v' building entry: %v", tc.caseDesc, err) } } } diff --git a/cmd/cli/app/upload.go b/cmd/cli/app/upload.go index 0ec5da0c43eafad112e41668ed5221d899668be9..0198d68fb0c31d450b623017df45d86a6f0c6d4c 100644 --- a/cmd/cli/app/upload.go +++ b/cmd/cli/app/upload.go @@ -16,11 +16,13 @@ limitations under the License. package app import ( + "errors" "fmt" "os" "github.com/projectrekor/rekor/cmd/cli/app/format" "github.com/projectrekor/rekor/pkg/generated/client/entries" + "github.com/projectrekor/rekor/pkg/generated/models" "github.com/projectrekor/rekor/pkg/log" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -60,12 +62,23 @@ var uploadCmd = &cobra.Command{ } params := entries.NewCreateLogEntryParams() - rekordEntry, err := CreateRekordFromPFlags() - if err != nil { - return nil, err + var entry models.ProposedEntry + switch viper.GetString("type") { + case "rekord": + entry, err = CreateRekordFromPFlags() + if err != nil { + return nil, err + } + case "rpm": + entry, err = CreateRpmFromPFlags() + if err != nil { + return nil, err + } + default: + return nil, errors.New("unknown type specified") } - params.SetProposedEntry(rekordEntry) + params.SetProposedEntry(entry) resp, err := rekorClient.Entries.CreateLogEntry(params) if err != nil { diff --git a/cmd/cli/app/verify.go b/cmd/cli/app/verify.go index 0495f57180f230937fff88972deb07fce71b2e1a..0eb741ad2462a25c9af686dc0e7ef6772ab45028 100644 --- a/cmd/cli/app/verify.go +++ b/cmd/cli/app/verify.go @@ -105,12 +105,23 @@ var verifyCmd = &cobra.Command{ } searchLogQuery.LogIndexes = []*int64{&logIndexInt} } else { - rekordEntry, err := CreateRekordFromPFlags() - if err != nil { - return nil, err + var entry models.ProposedEntry + switch viper.GetString("type") { + case "rekord": + entry, err = CreateRekordFromPFlags() + if err != nil { + return nil, err + } + case "rpm": + entry, err = CreateRpmFromPFlags() + if err != nil { + return nil, err + } + default: + return nil, errors.New("invalid type specified") } - entries := []models.ProposedEntry{rekordEntry} + entries := []models.ProposedEntry{entry} searchLogQuery.SetEntries(entries) } searchParams.SetEntry(&searchLogQuery) diff --git a/cmd/server/app/serve.go b/cmd/server/app/serve.go index 2c85ee1746b33bb0678890a8ce3aff8b8c0aee37..b9b82893e153d10405998943e20c2474c02da5c6 100644 --- a/cmd/server/app/serve.go +++ b/cmd/server/app/serve.go @@ -25,6 +25,8 @@ import ( "github.com/projectrekor/rekor/pkg/log" "github.com/projectrekor/rekor/pkg/types/rekord" rekord_v001 "github.com/projectrekor/rekor/pkg/types/rekord/v0.0.1" + "github.com/projectrekor/rekor/pkg/types/rpm" + rpm_v001 "github.com/projectrekor/rekor/pkg/types/rpm/v0.0.1" "github.com/projectrekor/rekor/pkg/generated/restapi" "github.com/spf13/cobra" @@ -59,6 +61,7 @@ var serveCmd = &cobra.Command{ // these trigger loading of package and therefore init() methods to run pluggableTypeMap := map[string]string{ rekord.KIND: rekord_v001.APIVERSION, + rpm.KIND: rpm_v001.APIVERSION, } for k, v := range pluggableTypeMap { diff --git a/go.mod b/go.mod index dff93529397834d5f4448690363adae12e3d71cd..fc59e19411ac43e27be140e8cca404a46ccfeba1 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,8 @@ go 1.14 require ( github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef github.com/blang/semver v3.5.1+incompatible + github.com/cavaliercoder/badio v0.0.0-20160213150051-ce5280129e9e // indirect + github.com/cavaliercoder/go-rpm v0.0.0-20200122174316-8cb9fd9c31a8 github.com/coreos/bbolt v1.3.3 // indirect github.com/coreos/etcd v3.3.18+incompatible // indirect github.com/fsnotify/fsnotify v1.4.9 // indirect @@ -17,13 +19,11 @@ require ( github.com/go-openapi/strfmt v0.20.0 github.com/go-openapi/swag v0.19.13 github.com/go-openapi/validate v0.20.1 - github.com/go-swagger/go-swagger v0.25.0 // indirect github.com/golang/protobuf v1.4.3 github.com/google/certificate-transparency-go v1.1.0 // indirect + github.com/google/rpmpack v0.0.0-20210107155803-d6befbf05148 github.com/google/trillian v1.3.10 - github.com/gorilla/handlers v1.5.1 // indirect github.com/jedisct1/go-minisign v0.0.0-20210106175330-e54e81d562c7 - github.com/kr/pretty v0.2.1 // indirect github.com/magiconair/properties v1.8.4 // indirect github.com/mediocregopher/radix/v4 v4.0.0-beta.1 github.com/mitchellh/go-homedir v1.1.0 diff --git a/go.sum b/go.sum index f62ae2ec7e468d9dfc1e15926d9134d3021ed539..bb78ceaa6499266a6d7531a1682b11f23b424393 100644 --- a/go.sum +++ b/go.sum @@ -92,6 +92,12 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/cavaliercoder/badio v0.0.0-20160213150051-ce5280129e9e h1:YYUjy5BRwO5zPtfk+aa2gw255FIIoi93zMmuy19o0bc= +github.com/cavaliercoder/badio v0.0.0-20160213150051-ce5280129e9e/go.mod h1:V284PjgVwSk4ETmz84rpu9ehpGg7swlIH8npP9k2bGw= +github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e h1:hHg27A0RSSp2Om9lubZpiMgVbvn39bsUmW9U5h0twqc= +github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= +github.com/cavaliercoder/go-rpm v0.0.0-20200122174316-8cb9fd9c31a8 h1:jP7ki8Tzx9ThnFPLDhBYAhEpI2+jOURnHQNURgsMvnY= +github.com/cavaliercoder/go-rpm v0.0.0-20200122174316-8cb9fd9c31a8/go.mod h1:AZIh1CCnMrcVm6afFf96PBvE2MRpWFco91z8ObJtgDY= github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= @@ -112,7 +118,6 @@ github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc github.com/coreos/etcd v3.3.18+incompatible h1:Zz1aXgDrFFi1nadh58tA9ktt06cmPTwNNP3dXwIq1lE= github.com/coreos/etcd v3.3.18+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -151,8 +156,6 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= @@ -193,8 +196,6 @@ github.com/go-openapi/errors v0.19.7/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpX github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.19.9 h1:9SnKdGhiPZHF3ttwFMiCBEb8jQ4IDdrK+5+a0oTygA4= github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= -github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= @@ -205,7 +206,6 @@ github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3Hfo github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/jsonreference v0.19.4/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM= github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= @@ -224,7 +224,6 @@ github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98= -github.com/go-openapi/runtime v0.19.20/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk= github.com/go-openapi/runtime v0.19.24 h1:TqagMVlRAOTwllE/7hNKx6rQ10O6T8ZzeJdMjSTKaD4= github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk= github.com/go-openapi/runtime v0.19.26 h1:K/6PoVNj5WJXUnMk+VEbELeXjtBkCS1UxTDa04tdXE0= @@ -269,8 +268,6 @@ github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbN github.com/go-openapi/validate v0.19.12/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0waH08tGe6kAQ4= github.com/go-openapi/validate v0.19.15 h1:oUHZO8jD7p5oRLANlXF0U8ic9ePBUkDQyRZdN0EhL6M= github.com/go-openapi/validate v0.19.15/go.mod h1:tbn/fdOwYHgrhPBzidZfJC2MIVvs9GA7monOmWBbeCI= -github.com/go-openapi/validate v0.20.0 h1:pzutNCCBZGZlE+u8HD3JZyWdc/TVbtVwlWUp8/vgUKk= -github.com/go-openapi/validate v0.20.0/go.mod h1:b60iJT+xNNLfaQJUqLI7946tYiFEOuE9E4k54HpKcJ0= github.com/go-openapi/validate v0.20.1 h1:QGQ5CvK74E28t3DkegGweKR+auemUi5IdpMc4x3UW6s= github.com/go-openapi/validate v0.20.1/go.mod h1:b60iJT+xNNLfaQJUqLI7946tYiFEOuE9E4k54HpKcJ0= github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= @@ -279,9 +276,6 @@ github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gG github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-swagger/go-swagger v0.25.0 h1:FxhyrWWV8V/A9P6GtI5szWordAdbb6Y0nqdY/y9So2w= -github.com/go-swagger/go-swagger v0.25.0/go.mod h1:9639ioXrPX9E6BbnbaDklGXjNz7upAXoNBwL4Ok11Vk= -github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0= github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= @@ -410,6 +404,8 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/rpmpack v0.0.0-20210107155803-d6befbf05148 h1:vqARqWnIYTYLO4h9fRi9wfAfBPf3x6nWirg0jDNOafk= +github.com/google/rpmpack v0.0.0-20210107155803-d6befbf05148/go.mod h1:+y9lKiqDhR4zkLl+V9h4q0rdyrYVsWWm6LLCQP33DIk= github.com/google/trillian v1.2.2-0.20190612132142-05461f4df60a/go.mod h1:YPmUVn5NGwgnDUgqlVyFGMTgaWlnSvH7W5p+NdOG8UA= github.com/google/trillian v1.3.10 h1:Qcn4HEWdQka7ioLtJO4Umo1UwpvVZdejktNtjhnPGGk= github.com/google/trillian v1.3.10/go.mod h1:VmfwqXyIzUSuO0hNdtTrT57/MtixlNcdU7egfnkmhA4= @@ -423,10 +419,6 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= -github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg= -github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= -github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= -github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -477,8 +469,6 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jedisct1/go-minisign v0.0.0-20210106175330-e54e81d562c7 h1:qrPDNqqT76vs8oWL6Z1/D6hKvbXULvlD7FdNVTIUI8A= github.com/jedisct1/go-minisign v0.0.0-20210106175330-e54e81d562c7/go.mod h1:oPTyITpvr7hPx/9w76gWrgbZwbb+7gZ9/On8hFc+LNE= -github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jhump/protoreflect v1.6.1 h1:4/2yi5LyDPP7nN+Hiird1SAJ6YoxUm13/oxHGRnbPd8= github.com/jhump/protoreflect v1.6.1/go.mod h1:RZQ/lnuN+zqeRVpQigTwO6o0AJUkxbnSnpuG7toUTG4= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -517,10 +507,6 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= @@ -632,7 +618,6 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= github.com/pelletier/go-toml v1.7.0 h1:7utD74fnzVc/cpcyy8sjrlFr5vYpypUixARcHIMIGuI= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= -github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -645,7 +630,6 @@ github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v0.9.4/go.mod h1:oCXIBxdI62A4cR6aTRJCgetEjecSIYzOEaeAn4iYEpM= @@ -712,9 +696,6 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spf13/afero v1.1.0/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.3.2/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.5.0 h1:8Wb647pxgVlypPIdcDlffCLCHCElBZ1sCF6i85qNvRw= -github.com/spf13/afero v1.5.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.5.1 h1:VHu76Lk0LSP1x254maIu2bplkWpfBWI+B+6fdoZprcg= github.com/spf13/afero v1.5.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= @@ -740,7 +721,6 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -765,10 +745,10 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= -github.com/toqueteos/webbrowser v1.2.0 h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9rrstGQ= -github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ulikunitz/xz v0.5.7 h1:YvTNdFzX6+W5m9msiYg/zpkSURPPtOlzbqYjrFn7Yt4= +github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ultraware/funlen v0.0.1/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= @@ -801,7 +781,6 @@ go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= -go.mongodb.org/mongo-driver v1.3.5/go.mod h1:Ual6Gkco7ZGQw8wE1t4tLnvBsf6yVSM60qW6TgOeJ5c= go.mongodb.org/mongo-driver v1.4.3 h1:moga+uhicpVshTyaqY9L23E6QqwcHRUv1sqyOsoyOO8= go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= go.mongodb.org/mongo-driver v1.4.4 h1:bsPHfODES+/yx2PCWzUYMH8xj6PVniPI8DQrsJuSXSs= @@ -848,7 +827,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -881,8 +859,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20170915142106-8351a756f30f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -930,8 +906,6 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201207224615-747e23833adb h1:xj2oMIbduz83x7tzglytWT7spn6rP+9hvKjTpro6/pM= -golang.org/x/net v0.0.0-20201207224615-747e23833adb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -998,13 +972,10 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d h1:MiWWjyhUzZ+jvhZvloX6ZrUsdEghn8a64Upd8EMHglE= -golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78 h1:nVuTkr9L6Bq62qpUqKo/RnZCFfzDBL0bYo6w9OJUqZY= golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -1088,12 +1059,9 @@ golang.org/x/tools v0.0.0-20200527183253-8e7acdbce89d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200630154851-b2d8b0336632/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200717024301-6ddee64345a6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20201208062317-e652b2f42cc7 h1:2OSu5vYyX4LVqZAtqZXnFEcN26SDKIJYlEVIRl1tj8U= -golang.org/x/tools v0.0.0-20201208062317-e652b2f42cc7/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210115202250-e0d201561e39 h1:BTs2GMGSMWpgtCpv1CE7vkJTv7XcHdcLLnAMu7UbgTY= golang.org/x/tools v0.0.0-20210115202250-e0d201561e39/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1194,11 +1162,9 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/openapi.yaml b/openapi.yaml index 8090575ea37f11f2c0fb672a935289cd83c23702..23b021c23c4a85ce7a696ce75f142e150fa02dd4 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -259,6 +259,23 @@ definitions: - spec additionalProperties: false + rpm: + type: object + description: RPM object + allOf: + - $ref: '#/definitions/ProposedEntry' + - properties: + apiVersion: + type: string + pattern: ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$ + spec: + type: object + $ref: 'pkg/types/rpm/rpm_schema.json' + required: + - apiVersion + - spec + additionalProperties: false + LogEntry: type: object additionalProperties: diff --git a/pkg/generated/models/proposed_entry.go b/pkg/generated/models/proposed_entry.go index 81d4d8e1fed19a6cc82b2aa58353d45416ba615f..fcaae0b9a3aa0960c4380e1be426a8ba72af6be9 100644 --- a/pkg/generated/models/proposed_entry.go +++ b/pkg/generated/models/proposed_entry.go @@ -120,6 +120,12 @@ func unmarshalProposedEntry(data []byte, consumer runtime.Consumer) (ProposedEnt return nil, err } return &result, nil + case "rpm": + var result Rpm + if err := consumer.Consume(buf2, &result); err != nil { + return nil, err + } + return &result, nil } return nil, errors.New(422, "invalid kind value: %q", getType.Kind) } diff --git a/pkg/generated/models/rpm.go b/pkg/generated/models/rpm.go new file mode 100644 index 0000000000000000000000000000000000000000..67415ee5a203ce954f5844b9fa8faee672eb3b53 --- /dev/null +++ b/pkg/generated/models/rpm.go @@ -0,0 +1,200 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// /* +// Copyright The Rekor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// */ +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "bytes" + "encoding/json" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// Rpm RPM object +// +// swagger:model rpm +type Rpm struct { + + // api version + // Required: true + // Pattern: ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$ + APIVersion *string `json:"apiVersion"` + + // spec + // Required: true + Spec RpmSchema `json:"spec"` +} + +// Kind gets the kind of this subtype +func (m *Rpm) Kind() string { + return "rpm" +} + +// SetKind sets the kind of this subtype +func (m *Rpm) SetKind(val string) { +} + +// UnmarshalJSON unmarshals this object with a polymorphic type from a JSON structure +func (m *Rpm) UnmarshalJSON(raw []byte) error { + var data struct { + + // api version + // Required: true + // Pattern: ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$ + APIVersion *string `json:"apiVersion"` + + // spec + // Required: true + Spec RpmSchema `json:"spec"` + } + buf := bytes.NewBuffer(raw) + dec := json.NewDecoder(buf) + dec.UseNumber() + + if err := dec.Decode(&data); err != nil { + return err + } + + var base struct { + /* Just the base type fields. Used for unmashalling polymorphic types.*/ + + Kind string `json:"kind"` + } + buf = bytes.NewBuffer(raw) + dec = json.NewDecoder(buf) + dec.UseNumber() + + if err := dec.Decode(&base); err != nil { + return err + } + + var result Rpm + + if base.Kind != result.Kind() { + /* Not the type we're looking for. */ + return errors.New(422, "invalid kind value: %q", base.Kind) + } + + result.APIVersion = data.APIVersion + result.Spec = data.Spec + + *m = result + + return nil +} + +// MarshalJSON marshals this object with a polymorphic type to a JSON structure +func (m Rpm) MarshalJSON() ([]byte, error) { + var b1, b2, b3 []byte + var err error + b1, err = json.Marshal(struct { + + // api version + // Required: true + // Pattern: ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$ + APIVersion *string `json:"apiVersion"` + + // spec + // Required: true + Spec RpmSchema `json:"spec"` + }{ + + APIVersion: m.APIVersion, + + Spec: m.Spec, + }) + if err != nil { + return nil, err + } + b2, err = json.Marshal(struct { + Kind string `json:"kind"` + }{ + + Kind: m.Kind(), + }) + if err != nil { + return nil, err + } + + return swag.ConcatJSON(b1, b2, b3), nil +} + +// Validate validates this rpm +func (m *Rpm) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateAPIVersion(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSpec(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *Rpm) validateAPIVersion(formats strfmt.Registry) error { + + if err := validate.Required("apiVersion", "body", m.APIVersion); err != nil { + return err + } + + if err := validate.Pattern("apiVersion", "body", string(*m.APIVersion), `^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$`); err != nil { + return err + } + + return nil +} + +func (m *Rpm) validateSpec(formats strfmt.Registry) error { + + if err := validate.Required("spec", "body", m.Spec); err != nil { + return err + } + + return nil +} + +// MarshalBinary interface implementation +func (m *Rpm) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *Rpm) UnmarshalBinary(b []byte) error { + var res Rpm + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/pkg/generated/models/rpm_schema.go b/pkg/generated/models/rpm_schema.go new file mode 100644 index 0000000000000000000000000000000000000000..8bf7304a7764c099ce25d489a7a3ff6f725bdc4b --- /dev/null +++ b/pkg/generated/models/rpm_schema.go @@ -0,0 +1,30 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// /* +// Copyright The Rekor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// */ +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +// RpmSchema RPM Schema +// +// Schema for RPM objects +// +// swagger:model rpmSchema +type RpmSchema interface{} diff --git a/pkg/generated/models/rpm_v001_schema.go b/pkg/generated/models/rpm_v001_schema.go new file mode 100644 index 0000000000000000000000000000000000000000..5d6861c1fd20e3e9ab9468a1df5fc4d650fbbb19 --- /dev/null +++ b/pkg/generated/models/rpm_v001_schema.go @@ -0,0 +1,369 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// /* +// Copyright The Rekor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// */ +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "encoding/json" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// RpmV001Schema RPM v0.0.1 Schema +// +// Schema for RPM entries +// +// swagger:model rpmV001Schema +type RpmV001Schema struct { + + // Arbitrary content to be included in the verifiable entry in the transparency log + ExtraData interface{} `json:"extraData,omitempty"` + + // package + // Required: true + Package *RpmV001SchemaPackage `json:"package"` + + // public key + // Required: true + PublicKey *RpmV001SchemaPublicKey `json:"publicKey"` +} + +// Validate validates this rpm v001 schema +func (m *RpmV001Schema) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validatePackage(formats); err != nil { + res = append(res, err) + } + + if err := m.validatePublicKey(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *RpmV001Schema) validatePackage(formats strfmt.Registry) error { + + if err := validate.Required("package", "body", m.Package); err != nil { + return err + } + + if m.Package != nil { + if err := m.Package.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("package") + } + return err + } + } + + return nil +} + +func (m *RpmV001Schema) validatePublicKey(formats strfmt.Registry) error { + + if err := validate.Required("publicKey", "body", m.PublicKey); err != nil { + return err + } + + if m.PublicKey != nil { + if err := m.PublicKey.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("publicKey") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *RpmV001Schema) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *RpmV001Schema) UnmarshalBinary(b []byte) error { + var res RpmV001Schema + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} + +// RpmV001SchemaPackage Information about the package associated with the entry +// +// swagger:model RpmV001SchemaPackage +type RpmV001SchemaPackage struct { + + // Specifies the package inline within the document + // Format: byte + Content strfmt.Base64 `json:"content,omitempty"` + + // hash + Hash *RpmV001SchemaPackageHash `json:"hash,omitempty"` + + // Values of the RPM headers + Headers map[string]string `json:"headers,omitempty"` + + // Specifies the location of the package; if this is specified, a hash value must also be provided + // Format: uri + URL strfmt.URI `json:"url,omitempty"` +} + +// Validate validates this rpm v001 schema package +func (m *RpmV001SchemaPackage) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateHash(formats); err != nil { + res = append(res, err) + } + + if err := m.validateURL(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *RpmV001SchemaPackage) validateHash(formats strfmt.Registry) error { + + if swag.IsZero(m.Hash) { // not required + return nil + } + + if m.Hash != nil { + if err := m.Hash.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("package" + "." + "hash") + } + return err + } + } + + return nil +} + +func (m *RpmV001SchemaPackage) validateURL(formats strfmt.Registry) error { + + if swag.IsZero(m.URL) { // not required + return nil + } + + if err := validate.FormatOf("package"+"."+"url", "body", "uri", m.URL.String(), formats); err != nil { + return err + } + + return nil +} + +// MarshalBinary interface implementation +func (m *RpmV001SchemaPackage) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *RpmV001SchemaPackage) UnmarshalBinary(b []byte) error { + var res RpmV001SchemaPackage + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} + +// RpmV001SchemaPackageHash Specifies the hash algorithm and value for the package +// +// swagger:model RpmV001SchemaPackageHash +type RpmV001SchemaPackageHash struct { + + // The hashing function used to compute the hash value + // Required: true + // Enum: [sha256] + Algorithm *string `json:"algorithm"` + + // The hash value for the package + // Required: true + Value *string `json:"value"` +} + +// Validate validates this rpm v001 schema package hash +func (m *RpmV001SchemaPackageHash) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateAlgorithm(formats); err != nil { + res = append(res, err) + } + + if err := m.validateValue(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +var rpmV001SchemaPackageHashTypeAlgorithmPropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["sha256"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + rpmV001SchemaPackageHashTypeAlgorithmPropEnum = append(rpmV001SchemaPackageHashTypeAlgorithmPropEnum, v) + } +} + +const ( + + // RpmV001SchemaPackageHashAlgorithmSha256 captures enum value "sha256" + RpmV001SchemaPackageHashAlgorithmSha256 string = "sha256" +) + +// prop value enum +func (m *RpmV001SchemaPackageHash) validateAlgorithmEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, rpmV001SchemaPackageHashTypeAlgorithmPropEnum, true); err != nil { + return err + } + return nil +} + +func (m *RpmV001SchemaPackageHash) validateAlgorithm(formats strfmt.Registry) error { + + if err := validate.Required("package"+"."+"hash"+"."+"algorithm", "body", m.Algorithm); err != nil { + return err + } + + // value enum + if err := m.validateAlgorithmEnum("package"+"."+"hash"+"."+"algorithm", "body", *m.Algorithm); err != nil { + return err + } + + return nil +} + +func (m *RpmV001SchemaPackageHash) validateValue(formats strfmt.Registry) error { + + if err := validate.Required("package"+"."+"hash"+"."+"value", "body", m.Value); err != nil { + return err + } + + return nil +} + +// MarshalBinary interface implementation +func (m *RpmV001SchemaPackageHash) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *RpmV001SchemaPackageHash) UnmarshalBinary(b []byte) error { + var res RpmV001SchemaPackageHash + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} + +// RpmV001SchemaPublicKey The PGP public key that can verify the RPM signature +// +// swagger:model RpmV001SchemaPublicKey +type RpmV001SchemaPublicKey struct { + + // Specifies the content of the public key inline within the document + // Format: byte + Content strfmt.Base64 `json:"content,omitempty"` + + // Specifies the location of the public key + // Format: uri + URL strfmt.URI `json:"url,omitempty"` +} + +// Validate validates this rpm v001 schema public key +func (m *RpmV001SchemaPublicKey) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateURL(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *RpmV001SchemaPublicKey) validateURL(formats strfmt.Registry) error { + + if swag.IsZero(m.URL) { // not required + return nil + } + + if err := validate.FormatOf("publicKey"+"."+"url", "body", "uri", m.URL.String(), formats); err != nil { + return err + } + + return nil +} + +// MarshalBinary interface implementation +func (m *RpmV001SchemaPublicKey) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *RpmV001SchemaPublicKey) UnmarshalBinary(b []byte) error { + var res RpmV001SchemaPublicKey + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/pkg/generated/restapi/embedded_spec.go b/pkg/generated/restapi/embedded_spec.go index c04827e47885f24f6b3fb926e6ddb2dbcf56f669..cfc18085ab9447e5a98ab4b91066cd2b96c82eb7 100644 --- a/pkg/generated/restapi/embedded_spec.go +++ b/pkg/generated/restapi/embedded_spec.go @@ -593,6 +593,32 @@ func init() { "additionalProperties": false } ] + }, + "rpm": { + "description": "RPM object", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/ProposedEntry" + }, + { + "required": [ + "apiVersion", + "spec" + ], + "properties": { + "apiVersion": { + "type": "string", + "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$" + }, + "spec": { + "type": "object", + "$ref": "pkg/types/rpm/rpm_schema.json" + } + }, + "additionalProperties": false + } + ] } }, "responses": { @@ -1335,6 +1361,112 @@ func init() { } } }, + "RpmV001SchemaPackage": { + "description": "Information about the package associated with the entry", + "type": "object", + "oneOf": [ + { + "required": [ + "hash", + "url" + ] + }, + { + "required": [ + "content" + ] + } + ], + "properties": { + "content": { + "description": "Specifies the package inline within the document", + "type": "string", + "format": "byte" + }, + "hash": { + "description": "Specifies the hash algorithm and value for the package", + "type": "object", + "required": [ + "algorithm", + "value" + ], + "properties": { + "algorithm": { + "description": "The hashing function used to compute the hash value", + "type": "string", + "enum": [ + "sha256" + ] + }, + "value": { + "description": "The hash value for the package", + "type": "string" + } + } + }, + "headers": { + "description": "Values of the RPM headers", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "url": { + "description": "Specifies the location of the package; if this is specified, a hash value must also be provided", + "type": "string", + "format": "uri" + } + } + }, + "RpmV001SchemaPackageHash": { + "description": "Specifies the hash algorithm and value for the package", + "type": "object", + "required": [ + "algorithm", + "value" + ], + "properties": { + "algorithm": { + "description": "The hashing function used to compute the hash value", + "type": "string", + "enum": [ + "sha256" + ] + }, + "value": { + "description": "The hash value for the package", + "type": "string" + } + } + }, + "RpmV001SchemaPublicKey": { + "description": "The PGP public key that can verify the RPM signature", + "type": "object", + "oneOf": [ + { + "required": [ + "url" + ] + }, + { + "required": [ + "content" + ] + } + ], + "properties": { + "content": { + "description": "Specifies the content of the public key inline within the document", + "type": "string", + "format": "byte" + }, + "url": { + "description": "Specifies the location of the public key", + "type": "string", + "format": "uri" + } + } + }, "SearchIndex": { "type": "object", "properties": { @@ -1593,6 +1725,146 @@ func init() { }, "$schema": "http://json-schema.org/draft-07/schema", "$id": "http://rekor.dev/types/rekord/rekord_v0_0_1_schema.json" + }, + "rpm": { + "description": "RPM object", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/ProposedEntry" + }, + { + "required": [ + "apiVersion", + "spec" + ], + "properties": { + "apiVersion": { + "type": "string", + "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$" + }, + "spec": { + "$ref": "#/definitions/rpmSchema" + } + }, + "additionalProperties": false + } + ] + }, + "rpmSchema": { + "description": "Schema for RPM objects", + "type": "object", + "title": "RPM Schema", + "oneOf": [ + { + "$ref": "#/definitions/rpmV001Schema" + } + ], + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "http://rekor.dev/types/rpm/rpm_schema.json" + }, + "rpmV001Schema": { + "description": "Schema for RPM entries", + "type": "object", + "title": "RPM v0.0.1 Schema", + "required": [ + "publicKey", + "package" + ], + "properties": { + "extraData": { + "description": "Arbitrary content to be included in the verifiable entry in the transparency log", + "type": "object", + "additionalProperties": true + }, + "package": { + "description": "Information about the package associated with the entry", + "type": "object", + "oneOf": [ + { + "required": [ + "hash", + "url" + ] + }, + { + "required": [ + "content" + ] + } + ], + "properties": { + "content": { + "description": "Specifies the package inline within the document", + "type": "string", + "format": "byte" + }, + "hash": { + "description": "Specifies the hash algorithm and value for the package", + "type": "object", + "required": [ + "algorithm", + "value" + ], + "properties": { + "algorithm": { + "description": "The hashing function used to compute the hash value", + "type": "string", + "enum": [ + "sha256" + ] + }, + "value": { + "description": "The hash value for the package", + "type": "string" + } + } + }, + "headers": { + "description": "Values of the RPM headers", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "url": { + "description": "Specifies the location of the package; if this is specified, a hash value must also be provided", + "type": "string", + "format": "uri" + } + } + }, + "publicKey": { + "description": "The PGP public key that can verify the RPM signature", + "type": "object", + "oneOf": [ + { + "required": [ + "url" + ] + }, + { + "required": [ + "content" + ] + } + ], + "properties": { + "content": { + "description": "Specifies the content of the public key inline within the document", + "type": "string", + "format": "byte" + }, + "url": { + "description": "Specifies the location of the public key", + "type": "string", + "format": "uri" + } + } + } + }, + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "http://rekor.dev/types/rpm/rpm_v0_0_1_schema.json" } }, "responses": { diff --git a/pkg/pki/pgp/pgp.go b/pkg/pki/pgp/pgp.go index 5c2db19ef9e84b55dfc2826c47f3c1f5b2bf0eec..b28c168dc987398449ae9794a4b009b1d953c08b 100644 --- a/pkg/pki/pgp/pgp.go +++ b/pkg/pki/pgp/pgp.go @@ -20,6 +20,7 @@ import ( "bufio" "bytes" "context" + "errors" "fmt" "io" "net/http" @@ -270,3 +271,11 @@ func (k PublicKey) CanonicalValue() ([]byte, error) { return canonicalBuffer.Bytes(), nil } + +func (k PublicKey) KeyRing() (openpgp.KeyRing, error) { + if k.key == nil { + return nil, errors.New("PGP public key has not been initialized") + } + + return k.key, nil +} diff --git a/pkg/types/rekord/rekord.go b/pkg/types/rekord/rekord.go index 2229846930d02de9e896175f6e638b6edeca1dad..5336d741e8750bdfa025ee1f7ac3f7496bb6025e 100644 --- a/pkg/types/rekord/rekord.go +++ b/pkg/types/rekord/rekord.go @@ -18,12 +18,9 @@ package rekord import ( "errors" "fmt" - "sync" - "github.com/blang/semver" - - "github.com/projectrekor/rekor/pkg/log" "github.com/projectrekor/rekor/pkg/types" + "github.com/projectrekor/rekor/pkg/util" "github.com/go-openapi/swag" "github.com/projectrekor/rekor/pkg/generated/models" @@ -47,52 +44,7 @@ func New() types.TypeImpl { return &BaseRekordType{} } -type VersionFactory func() types.EntryImpl - -type versionFactoryMap struct { - versionFactories map[string]VersionFactory - - sync.RWMutex -} - -func (vfm *versionFactoryMap) Get(version string) (VersionFactory, bool) { - vfm.RLock() - defer vfm.RUnlock() - - semverToMatch, err := semver.Parse(version) - if err != nil { - log.Logger.Error(err) - return nil, false - } - - //will return first function that matches - for k, v := range vfm.versionFactories { - semverRange, err := semver.ParseRange(k) - if err != nil { - log.Logger.Error(err) - return nil, false - } - - if semverRange(semverToMatch) { - return v, true - } - } - return nil, false -} - -func (vfm *versionFactoryMap) Set(constraint string, vf VersionFactory) { - vfm.Lock() - defer vfm.Unlock() - - if _, err := semver.ParseRange(constraint); err != nil { - log.Logger.Error(err) - return - } - - vfm.versionFactories[constraint] = vf -} - -var SemVerToFacFnMap = &versionFactoryMap{versionFactories: make(map[string]VersionFactory)} +var SemVerToFacFnMap = &util.VersionFactoryMap{VersionFactories: make(map[string]util.VersionFactory)} func (rt BaseRekordType) UnmarshalEntry(pe models.ProposedEntry) (types.EntryImpl, error) { rekord, ok := pe.(*models.Rekord) diff --git a/pkg/types/rekord/rekord_test.go b/pkg/types/rekord/rekord_test.go index 42ff5f5e360da116580cd31b59360abc438f3f57..fa9b4e9e3e6e4adaa55f8fbc758aab9fa9f033e8 100644 --- a/pkg/types/rekord/rekord_test.go +++ b/pkg/types/rekord/rekord_test.go @@ -72,7 +72,7 @@ func (u UnmarshalFailsTester) Unmarshal(pe models.ProposedEntry) error { func TestRekordType(t *testing.T) { // empty to start - if len(SemVerToFacFnMap.versionFactories) != 0 { + if len(SemVerToFacFnMap.VersionFactories) != 0 { t.Error("semver range was not blank at start of test") } @@ -80,13 +80,13 @@ func TestRekordType(t *testing.T) { // ensure semver range parser is working invalidSemVerRange := "not a valid semver range" SemVerToFacFnMap.Set(invalidSemVerRange, u.NewEntry) - if len(SemVerToFacFnMap.versionFactories) > 0 { + if len(SemVerToFacFnMap.VersionFactories) > 0 { t.Error("invalid semver range was incorrectly added to SemVerToFacFnMap") } // valid semver range can be parsed SemVerToFacFnMap.Set(">= 1.2.3", u.NewEntry) - if len(SemVerToFacFnMap.versionFactories) != 1 { + if len(SemVerToFacFnMap.VersionFactories) != 1 { t.Error("valid semver range was not added to SemVerToFacFnMap") } diff --git a/pkg/types/rpm/rpm.go b/pkg/types/rpm/rpm.go new file mode 100644 index 0000000000000000000000000000000000000000..3ababa5469b57c81074e13caee14bf317802048b --- /dev/null +++ b/pkg/types/rpm/rpm.go @@ -0,0 +1,66 @@ +/* +Copyright © 2021 Bob Callaway <bcallawa@redhat.com> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package rpm + +import ( + "errors" + "fmt" + + "github.com/projectrekor/rekor/pkg/types" + "github.com/projectrekor/rekor/pkg/util" + + "github.com/go-openapi/swag" + "github.com/projectrekor/rekor/pkg/generated/models" +) + +const ( + KIND = "rpm" +) + +type BaseRPMType struct{} + +func (rt BaseRPMType) Kind() string { + return KIND +} + +func init() { + types.TypeMap.Set(KIND, New) +} + +func New() types.TypeImpl { + return &BaseRPMType{} +} + +var SemVerToFacFnMap = &util.VersionFactoryMap{VersionFactories: make(map[string]util.VersionFactory)} + +func (rt BaseRPMType) UnmarshalEntry(pe models.ProposedEntry) (types.EntryImpl, error) { + rpm, ok := pe.(*models.Rpm) + if !ok { + return nil, errors.New("cannot unmarshal non-RPM types") + } + + if genFn, found := SemVerToFacFnMap.Get(swag.StringValue(rpm.APIVersion)); found { + entry := genFn() + if entry == nil { + return nil, fmt.Errorf("failure generating RPM object for version '%v'", rpm.APIVersion) + } + if err := entry.Unmarshal(rpm); err != nil { + return nil, err + } + return entry, nil + } + return nil, fmt.Errorf("RPMType implementation for version '%v' not found", swag.StringValue(rpm.APIVersion)) +} diff --git a/pkg/types/rpm/rpm_schema.json b/pkg/types/rpm/rpm_schema.json new file mode 100644 index 0000000000000000000000000000000000000000..b5f017e3a80d911d14bf02e78aabdd05187b5595 --- /dev/null +++ b/pkg/types/rpm/rpm_schema.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://rekor.dev/types/rpm/rpm_schema.json", + "title": "RPM Schema", + "description": "Schema for RPM objects", + "type": "object", + "oneOf": [ + { + "$ref": "v0.0.1/rpm_v0_0_1_schema.json" + } + ] +} diff --git a/pkg/types/rpm/rpm_test.go b/pkg/types/rpm/rpm_test.go new file mode 100644 index 0000000000000000000000000000000000000000..f7dd4d52958a23341a8d3aaece222e8554f08a9c --- /dev/null +++ b/pkg/types/rpm/rpm_test.go @@ -0,0 +1,120 @@ +/* +Copyright © 2021 Bob Callaway <bcallawa@redhat.com> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package rpm + +import ( + "context" + "errors" + "testing" + + "github.com/go-openapi/swag" + "github.com/projectrekor/rekor/pkg/generated/models" + "github.com/projectrekor/rekor/pkg/types" +) + +type UnmarshalTester struct { + models.Rpm +} + +func (u UnmarshalTester) NewEntry() types.EntryImpl { + return &UnmarshalTester{} +} + +func (u UnmarshalTester) APIVersion() string { + return "2.0.1" +} + +func (u UnmarshalTester) IndexKeys() []string { + return []string{} +} + +func (u UnmarshalTester) Canonicalize(ctx context.Context) ([]byte, error) { + return nil, nil +} + +func (u UnmarshalTester) HasExternalEntities() bool { + return false +} + +func (u *UnmarshalTester) FetchExternalEntities(ctx context.Context) error { + return nil +} + +func (u UnmarshalTester) Unmarshal(pe models.ProposedEntry) error { + return nil +} + +type UnmarshalFailsTester struct { + UnmarshalTester +} + +func (u UnmarshalFailsTester) NewEntry() types.EntryImpl { + return &UnmarshalFailsTester{} +} + +func (u UnmarshalFailsTester) Unmarshal(pe models.ProposedEntry) error { + return errors.New("error") +} + +func TestRPMType(t *testing.T) { + // empty to start + if len(SemVerToFacFnMap.VersionFactories) != 0 { + t.Error("semver range was not blank at start of test") + } + + u := UnmarshalTester{} + // ensure semver range parser is working + invalidSemVerRange := "not a valid semver range" + SemVerToFacFnMap.Set(invalidSemVerRange, u.NewEntry) + if len(SemVerToFacFnMap.VersionFactories) > 0 { + t.Error("invalid semver range was incorrectly added to SemVerToFacFnMap") + } + + // valid semver range can be parsed + SemVerToFacFnMap.Set(">= 1.2.3", u.NewEntry) + if len(SemVerToFacFnMap.VersionFactories) != 1 { + t.Error("valid semver range was not added to SemVerToFacFnMap") + } + + u.Rpm.APIVersion = swag.String("2.0.1") + brt := BaseRPMType{} + + // version requested matches implementation in map + if _, err := brt.UnmarshalEntry(&u.Rpm); err != nil { + t.Errorf("unexpected error in Unmarshal: %v", err) + } + + // version requested fails to match implementation in map + u.Rpm.APIVersion = swag.String("1.2.2") + if _, err := brt.UnmarshalEntry(&u.Rpm); err == nil { + t.Error("unexpected success in Unmarshal for non-matching version") + } + + // error in Unmarshal call is raised appropriately + u.Rpm.APIVersion = swag.String("2.2.0") + u2 := UnmarshalFailsTester{} + SemVerToFacFnMap.Set(">= 1.2.3", u2.NewEntry) + if _, err := brt.UnmarshalEntry(&u.Rpm); err == nil { + t.Error("unexpected success in Unmarshal when error is thrown") + } + + // version requested fails to match implementation in map + u.Rpm.APIVersion = swag.String("not_a_version") + if _, err := brt.UnmarshalEntry(&u.Rpm); err == nil { + t.Error("unexpected success in Unmarshal for invalid version") + } +} diff --git a/pkg/types/rpm/v0.0.1/entry.go b/pkg/types/rpm/v0.0.1/entry.go new file mode 100644 index 0000000000000000000000000000000000000000..b0dc377353e3f6d22d2c87cc4fd2eb0acf40e5fa --- /dev/null +++ b/pkg/types/rpm/v0.0.1/entry.go @@ -0,0 +1,394 @@ +/* +Copyright © 2021 Bob Callaway <bcallawa@redhat.com> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package rpm + +import ( + "context" + "crypto/sha256" + "encoding/base64" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "io" + "io/ioutil" + "reflect" + "strconv" + "strings" + + "github.com/projectrekor/rekor/pkg/log" + "github.com/projectrekor/rekor/pkg/pki/pgp" + "github.com/projectrekor/rekor/pkg/types" + "github.com/projectrekor/rekor/pkg/types/rpm" + "github.com/projectrekor/rekor/pkg/util" + + "github.com/asaskevich/govalidator" + + "github.com/go-openapi/strfmt" + + "github.com/projectrekor/rekor/pkg/pki" + + rpmutils "github.com/cavaliercoder/go-rpm" + "github.com/go-openapi/swag" + "github.com/mitchellh/mapstructure" + "github.com/projectrekor/rekor/pkg/generated/models" + "golang.org/x/sync/errgroup" +) + +const ( + APIVERSION = "0.0.1" +) + +func init() { + rpm.SemVerToFacFnMap.Set(APIVERSION, NewEntry) +} + +type V001Entry struct { + RPMModel models.RpmV001Schema + fetchedExternalEntities bool + keyObj pki.PublicKey + rpmObj *rpmutils.PackageFile +} + +func (v V001Entry) APIVersion() string { + return APIVERSION +} + +func NewEntry() types.EntryImpl { + return &V001Entry{} +} + +func Base64StringtoByteArray() mapstructure.DecodeHookFunc { + return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { + if f.Kind() != reflect.String || t.Kind() != reflect.Slice { + return data, nil + } + + bytes, err := base64.StdEncoding.DecodeString(data.(string)) + if err != nil { + return []byte{}, fmt.Errorf("failed parsing base64 data: %v", err) + } + return bytes, nil + } +} + +func (v V001Entry) IndexKeys() []string { + var result []string + + if v.HasExternalEntities() { + if err := v.FetchExternalEntities(context.Background()); err != nil { + log.Logger.Error(err) + return result + } + } + + key, err := v.keyObj.CanonicalValue() + if err != nil { + log.Logger.Error(err) + } else { + hasher := sha256.New() + if _, err := hasher.Write(key); err != nil { + log.Logger.Error(err) + } else { + result = append(result, strings.ToLower(hex.EncodeToString(hasher.Sum(nil)))) + } + } + + if v.RPMModel.Package.Hash != nil { + result = append(result, strings.ToLower(swag.StringValue(v.RPMModel.Package.Hash.Value))) + } + + return result +} + +func (v *V001Entry) Unmarshal(pe models.ProposedEntry) error { + rpm, ok := pe.(*models.Rpm) + if !ok { + return errors.New("cannot unmarshal non RPM v0.0.1 type") + } + + cfg := mapstructure.DecoderConfig{ + DecodeHook: Base64StringtoByteArray(), + Result: &v.RPMModel, + } + + dec, err := mapstructure.NewDecoder(&cfg) + if err != nil { + return fmt.Errorf("error initializing decoder: %w", err) + } + + if err := dec.Decode(rpm.Spec); err != nil { + return err + } + // field validation + if err := v.RPMModel.Validate(strfmt.Default); err != nil { + return err + } + // cross field validation + return v.Validate() + +} + +func (v V001Entry) HasExternalEntities() bool { + if v.fetchedExternalEntities { + return false + } + + if v.RPMModel.Package != nil && v.RPMModel.Package.URL.String() != "" { + return true + } + if v.RPMModel.PublicKey != nil && v.RPMModel.PublicKey.URL.String() != "" { + return true + } + return false +} + +func (v *V001Entry) FetchExternalEntities(ctx context.Context) error { + if v.fetchedExternalEntities { + return nil + } + + if err := v.Validate(); err != nil { + return err + } + + g, ctx := errgroup.WithContext(ctx) + + hashR, hashW := io.Pipe() + sigR, sigW := io.Pipe() + rpmR, rpmW := io.Pipe() + defer hashR.Close() + defer sigR.Close() + defer rpmR.Close() + + closePipesOnError := func(err error) error { + pipeReaders := []*io.PipeReader{hashR, sigR, rpmR} + pipeWriters := []*io.PipeWriter{hashW, sigW, rpmW} + for idx := range pipeReaders { + if e := pipeReaders[idx].CloseWithError(err); e != nil { + log.Logger.Error(fmt.Errorf("error closing pipe: %w", e)) + } + if e := pipeWriters[idx].CloseWithError(err); e != nil { + log.Logger.Error(fmt.Errorf("error closing pipe: %w", e)) + } + } + return err + } + + oldSHA := "" + if v.RPMModel.Package.Hash != nil && v.RPMModel.Package.Hash.Value != nil { + oldSHA = swag.StringValue(v.RPMModel.Package.Hash.Value) + } + artifactFactory := pki.NewArtifactFactory("pgp") + + g.Go(func() error { + defer hashW.Close() + defer sigW.Close() + defer rpmW.Close() + + dataReadCloser, err := util.FileOrURLReadCloser(ctx, v.RPMModel.Package.URL.String(), v.RPMModel.Package.Content, true) + if err != nil { + return closePipesOnError(err) + } + defer dataReadCloser.Close() + + /* #nosec G110 */ + if _, err := io.Copy(io.MultiWriter(hashW, sigW, rpmW), dataReadCloser); err != nil { + return closePipesOnError(err) + } + return nil + }) + + hashResult := make(chan string) + + g.Go(func() error { + defer close(hashResult) + hasher := sha256.New() + + if _, err := io.Copy(hasher, hashR); err != nil { + return closePipesOnError(err) + } + + computedSHA := hex.EncodeToString(hasher.Sum(nil)) + if oldSHA != "" && computedSHA != oldSHA { + return closePipesOnError(fmt.Errorf("SHA mismatch: %s != %s", computedSHA, oldSHA)) + } + + select { + case <-ctx.Done(): + return ctx.Err() + case hashResult <- computedSHA: + return nil + } + }) + + g.Go(func() error { + keyReadCloser, err := util.FileOrURLReadCloser(ctx, v.RPMModel.PublicKey.URL.String(), + v.RPMModel.PublicKey.Content, false) + if err != nil { + return closePipesOnError(err) + } + defer keyReadCloser.Close() + + v.keyObj, err = artifactFactory.NewPublicKey(keyReadCloser) + if err != nil { + return closePipesOnError(err) + } + + keyring, err := v.keyObj.(*pgp.PublicKey).KeyRing() + if err != nil { + return closePipesOnError(err) + } + + if _, err := rpmutils.GPGCheck(sigR, keyring); err != nil { + return closePipesOnError(err) + } + + select { + case <-ctx.Done(): + return ctx.Err() + default: + return nil + } + }) + + g.Go(func() error { + + var err error + v.rpmObj, err = rpmutils.ReadPackageFile(rpmR) + if err != nil { + return closePipesOnError(err) + } + //ReadPackageFile does not drain the entire reader so we need to discard the rest + if _, err = io.Copy(ioutil.Discard, rpmR); err != nil { + return closePipesOnError(err) + } + + select { + case <-ctx.Done(): + return ctx.Err() + default: + return nil + } + }) + + computedSHA := <-hashResult + + if err := g.Wait(); err != nil { + return err + } + + // if we get here, all goroutines succeeded without error + if oldSHA == "" { + v.RPMModel.Package.Hash = &models.RpmV001SchemaPackageHash{} + v.RPMModel.Package.Hash.Algorithm = swag.String(models.RpmV001SchemaPackageHashAlgorithmSha256) + v.RPMModel.Package.Hash.Value = swag.String(computedSHA) + } + + v.fetchedExternalEntities = true + return nil +} + +func (v *V001Entry) Canonicalize(ctx context.Context) ([]byte, error) { + if err := v.FetchExternalEntities(ctx); err != nil { + return nil, err + } + if v.keyObj == nil { + return nil, errors.New("key object not initialized before canonicalization") + } + + canonicalEntry := models.RpmV001Schema{} + canonicalEntry.ExtraData = v.RPMModel.ExtraData + + var err error + // need to canonicalize key content + canonicalEntry.PublicKey = &models.RpmV001SchemaPublicKey{} + canonicalEntry.PublicKey.Content, err = v.keyObj.CanonicalValue() + if err != nil { + return nil, err + } + + canonicalEntry.Package = &models.RpmV001SchemaPackage{} + canonicalEntry.Package.Hash = &models.RpmV001SchemaPackageHash{} + canonicalEntry.Package.Hash.Algorithm = v.RPMModel.Package.Hash.Algorithm + canonicalEntry.Package.Hash.Value = v.RPMModel.Package.Hash.Value + // data content is not set deliberately + + // set NEVRA headers + canonicalEntry.Package.Headers = make(map[string]string) + canonicalEntry.Package.Headers["Name"] = v.rpmObj.Name() + canonicalEntry.Package.Headers["Epoch"] = strconv.Itoa(v.rpmObj.Epoch()) + canonicalEntry.Package.Headers["Version"] = v.rpmObj.Version() + canonicalEntry.Package.Headers["Release"] = v.rpmObj.Release() + canonicalEntry.Package.Headers["Architecture"] = v.rpmObj.Architecture() + if md5sum := v.rpmObj.GetBytes(0, 1004); md5sum != nil { + canonicalEntry.Package.Headers["RPMSIGTAG_MD5"] = hex.EncodeToString(md5sum) + } + if sha1sum := v.rpmObj.GetBytes(0, 1012); sha1sum != nil { + canonicalEntry.Package.Headers["RPMSIGTAG_SHA1"] = hex.EncodeToString(sha1sum) + } + if sha256sum := v.rpmObj.GetBytes(0, 1016); sha256sum != nil { + canonicalEntry.Package.Headers["RPMSIGTAG_SHA256"] = hex.EncodeToString(sha256sum) + } + + // ExtraData is copied through unfiltered + canonicalEntry.ExtraData = v.RPMModel.ExtraData + + // wrap in valid object with kind and apiVersion set + rpm := models.Rpm{} + rpm.APIVersion = swag.String(APIVERSION) + rpm.Spec = &canonicalEntry + + bytes, err := json.Marshal(&rpm) + if err != nil { + return nil, err + } + + return bytes, nil +} + +//Validate performs cross-field validation for fields in object +func (v V001Entry) Validate() error { + key := v.RPMModel.PublicKey + if key == nil { + return errors.New("missing public key") + } + if len(key.Content) == 0 && key.URL.String() == "" { + return errors.New("one of 'content' or 'url' must be specified for publicKey") + } + + pkg := v.RPMModel.Package + if pkg == nil { + return errors.New("missing package") + } + + if len(pkg.Content) == 0 && pkg.URL.String() == "" { + return errors.New("one of 'content' or 'url' must be specified for package") + } + + hash := pkg.Hash + if pkg.URL.String() != "" && hash == nil { + return errors.New("hash must be specified if 'url' is present for package") + } + + if hash != nil { + if !govalidator.IsHash(swag.StringValue(hash.Value), swag.StringValue(hash.Algorithm)) { + return errors.New("invalid value for hash") + } + } + + return nil +} diff --git a/pkg/types/rpm/v0.0.1/entry_test.go b/pkg/types/rpm/v0.0.1/entry_test.go new file mode 100644 index 0000000000000000000000000000000000000000..0fb39a96365d130f5c7d67107411da91a0524cf2 --- /dev/null +++ b/pkg/types/rpm/v0.0.1/entry_test.go @@ -0,0 +1,387 @@ +/* +Copyright © 2021 Bob Callaway <bcallawa@redhat.com> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package rpm + +import ( + "context" + "crypto/sha256" + "encoding/hex" + "errors" + "io/ioutil" + "net/http" + "net/http/httptest" + "reflect" + "testing" + + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/projectrekor/rekor/pkg/generated/models" + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + goleak.VerifyTestMain(m) +} + +func TestNewEntryReturnType(t *testing.T) { + entry := NewEntry() + if reflect.TypeOf(entry) != reflect.ValueOf(&V001Entry{}).Type() { + t.Errorf("invalid type returned from NewEntry: %T", entry) + } +} + +func TestCrossFieldValidation(t *testing.T) { + type TestCase struct { + caseDesc string + entry V001Entry + hasExtEntities bool + expectUnmarshalSuccess bool + expectCanonicalizeSuccess bool + } + + keyBytes, _ := ioutil.ReadFile("../../../../tests/test_rpm_public_key.key") + dataBytes, _ := ioutil.ReadFile("../../../../tests/test.rpm") + + h := sha256.New() + _, _ = h.Write(dataBytes) + dataSHA := hex.EncodeToString(h.Sum(nil)) + + testServer := httptest.NewServer(http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + file := &keyBytes + var err error + + switch r.URL.Path { + case "/key": + file = &keyBytes + case "/data": + file = &dataBytes + default: + err = errors.New("unknown URL") + } + if err != nil { + w.WriteHeader(http.StatusNotFound) + return + } + w.WriteHeader(http.StatusOK) + _, _ = w.Write(*file) + })) + defer testServer.Close() + + testCases := []TestCase{ + { + caseDesc: "empty obj", + entry: V001Entry{}, + expectUnmarshalSuccess: false, + }, + { + caseDesc: "public key without url or content", + entry: V001Entry{ + RPMModel: models.RpmV001Schema{ + PublicKey: &models.RpmV001SchemaPublicKey{}, + }, + }, + expectUnmarshalSuccess: false, + }, + { + caseDesc: "public key without package", + entry: V001Entry{ + RPMModel: models.RpmV001Schema{ + PublicKey: &models.RpmV001SchemaPublicKey{ + URL: strfmt.URI(testServer.URL + "/key"), + }, + }, + }, + hasExtEntities: true, + expectUnmarshalSuccess: false, + }, + { + caseDesc: "public key with empty package", + entry: V001Entry{ + RPMModel: models.RpmV001Schema{ + PublicKey: &models.RpmV001SchemaPublicKey{ + URL: strfmt.URI(testServer.URL + "/key"), + }, + Package: &models.RpmV001SchemaPackage{}, + }, + }, + hasExtEntities: true, + expectUnmarshalSuccess: false, + }, + { + caseDesc: "public key with data & url but no hash", + entry: V001Entry{ + RPMModel: models.RpmV001Schema{ + PublicKey: &models.RpmV001SchemaPublicKey{ + URL: strfmt.URI(testServer.URL + "/key"), + }, + Package: &models.RpmV001SchemaPackage{ + URL: strfmt.URI(testServer.URL + "/data"), + }, + }, + }, + hasExtEntities: true, + expectUnmarshalSuccess: false, + }, + { + caseDesc: "public key with data & url and empty hash", + entry: V001Entry{ + RPMModel: models.RpmV001Schema{ + PublicKey: &models.RpmV001SchemaPublicKey{ + URL: strfmt.URI(testServer.URL + "/key"), + }, + Package: &models.RpmV001SchemaPackage{ + Hash: &models.RpmV001SchemaPackageHash{}, + URL: strfmt.URI(testServer.URL + "/data"), + }, + }, + }, + hasExtEntities: true, + expectUnmarshalSuccess: false, + }, + { + caseDesc: "public key with data & url and hash missing value", + entry: V001Entry{ + RPMModel: models.RpmV001Schema{ + PublicKey: &models.RpmV001SchemaPublicKey{ + URL: strfmt.URI(testServer.URL + "/key"), + }, + Package: &models.RpmV001SchemaPackage{ + Hash: &models.RpmV001SchemaPackageHash{ + Algorithm: swag.String(models.RpmV001SchemaPackageHashAlgorithmSha256), + }, + URL: strfmt.URI(testServer.URL + "/data"), + }, + }, + }, + hasExtEntities: true, + expectUnmarshalSuccess: false, + }, + { + caseDesc: "public key with data & url with 404 error on key", + entry: V001Entry{ + RPMModel: models.RpmV001Schema{ + PublicKey: &models.RpmV001SchemaPublicKey{ + URL: strfmt.URI(testServer.URL + "/404"), + }, + Package: &models.RpmV001SchemaPackage{ + Hash: &models.RpmV001SchemaPackageHash{ + Algorithm: swag.String(models.RpmV001SchemaPackageHashAlgorithmSha256), + Value: swag.String(dataSHA), + }, + URL: strfmt.URI(testServer.URL + "/data"), + }, + }, + }, + hasExtEntities: true, + expectUnmarshalSuccess: true, + expectCanonicalizeSuccess: false, + }, + { + caseDesc: "public key with data & url with 404 error on data", + entry: V001Entry{ + RPMModel: models.RpmV001Schema{ + PublicKey: &models.RpmV001SchemaPublicKey{ + URL: strfmt.URI(testServer.URL + "/key"), + }, + Package: &models.RpmV001SchemaPackage{ + Hash: &models.RpmV001SchemaPackageHash{ + Algorithm: swag.String(models.RpmV001SchemaPackageHashAlgorithmSha256), + Value: swag.String(dataSHA), + }, + URL: strfmt.URI(testServer.URL + "/404"), + }, + }, + }, + hasExtEntities: true, + expectUnmarshalSuccess: true, + expectCanonicalizeSuccess: false, + }, + { + caseDesc: "public key with invalid key content & with data with content", + entry: V001Entry{ + RPMModel: models.RpmV001Schema{ + PublicKey: &models.RpmV001SchemaPublicKey{ + Content: strfmt.Base64(dataBytes), + }, + Package: &models.RpmV001SchemaPackage{ + Content: strfmt.Base64(dataBytes), + }, + }, + }, + hasExtEntities: false, + expectUnmarshalSuccess: true, + expectCanonicalizeSuccess: false, + }, + { + caseDesc: "public key with data & url and incorrect hash value", + entry: V001Entry{ + RPMModel: models.RpmV001Schema{ + PublicKey: &models.RpmV001SchemaPublicKey{ + URL: strfmt.URI(testServer.URL + "/key"), + }, + Package: &models.RpmV001SchemaPackage{ + Hash: &models.RpmV001SchemaPackageHash{ + Algorithm: swag.String(models.RpmV001SchemaPackageHashAlgorithmSha256), + Value: swag.String("3030303030303030303030303030303030303030303030303030303030303030"), + }, + URL: strfmt.URI(testServer.URL + "/data"), + }, + }, + }, + hasExtEntities: true, + expectUnmarshalSuccess: true, + expectCanonicalizeSuccess: false, + }, + { + caseDesc: "public key with data & url and complete hash value", + entry: V001Entry{ + RPMModel: models.RpmV001Schema{ + PublicKey: &models.RpmV001SchemaPublicKey{ + URL: strfmt.URI(testServer.URL + "/key"), + }, + Package: &models.RpmV001SchemaPackage{ + Hash: &models.RpmV001SchemaPackageHash{ + Algorithm: swag.String(models.RpmV001SchemaPackageHashAlgorithmSha256), + Value: swag.String(dataSHA), + }, + URL: strfmt.URI(testServer.URL + "/data"), + }, + }, + }, + hasExtEntities: true, + expectUnmarshalSuccess: true, + expectCanonicalizeSuccess: true, + }, + { + caseDesc: "public key with url key & with data with url and complete hash value", + entry: V001Entry{ + RPMModel: models.RpmV001Schema{ + PublicKey: &models.RpmV001SchemaPublicKey{ + URL: strfmt.URI(testServer.URL + "/key"), + }, + Package: &models.RpmV001SchemaPackage{ + Hash: &models.RpmV001SchemaPackageHash{ + Algorithm: swag.String(models.RpmV001SchemaPackageHashAlgorithmSha256), + Value: swag.String(dataSHA), + }, + URL: strfmt.URI(testServer.URL + "/data"), + }, + }, + }, + hasExtEntities: true, + expectUnmarshalSuccess: true, + expectCanonicalizeSuccess: true, + }, + { + caseDesc: "public key with key content & with data with url and complete hash value", + entry: V001Entry{ + RPMModel: models.RpmV001Schema{ + PublicKey: &models.RpmV001SchemaPublicKey{ + Content: strfmt.Base64(keyBytes), + }, + Package: &models.RpmV001SchemaPackage{ + Hash: &models.RpmV001SchemaPackageHash{ + Algorithm: swag.String(models.RpmV001SchemaPackageHashAlgorithmSha256), + Value: swag.String(dataSHA), + }, + URL: strfmt.URI(testServer.URL + "/data"), + }, + }, + }, + hasExtEntities: true, + expectUnmarshalSuccess: true, + expectCanonicalizeSuccess: true, + }, + { + caseDesc: "public key with key content & with data with url and complete hash value", + entry: V001Entry{ + RPMModel: models.RpmV001Schema{ + PublicKey: &models.RpmV001SchemaPublicKey{ + Content: strfmt.Base64(keyBytes), + }, + Package: &models.RpmV001SchemaPackage{ + Hash: &models.RpmV001SchemaPackageHash{ + Algorithm: swag.String(models.RpmV001SchemaPackageHashAlgorithmSha256), + Value: swag.String(dataSHA), + }, + URL: strfmt.URI(testServer.URL + "/data"), + }, + }, + }, + hasExtEntities: true, + expectUnmarshalSuccess: true, + expectCanonicalizeSuccess: true, + }, + { + caseDesc: "public key with key content & with data with content", + entry: V001Entry{ + RPMModel: models.RpmV001Schema{ + PublicKey: &models.RpmV001SchemaPublicKey{ + Content: strfmt.Base64(keyBytes), + }, + Package: &models.RpmV001SchemaPackage{ + Content: strfmt.Base64(dataBytes), + }, + }, + }, + hasExtEntities: false, + expectUnmarshalSuccess: true, + expectCanonicalizeSuccess: true, + }, + { + caseDesc: "valid obj with extradata", + entry: V001Entry{ + RPMModel: models.RpmV001Schema{ + PublicKey: &models.RpmV001SchemaPublicKey{ + Content: strfmt.Base64(keyBytes), + }, + Package: &models.RpmV001SchemaPackage{ + Content: strfmt.Base64(dataBytes), + }, + ExtraData: []byte("{\"something\": \"here\""), + }, + }, + hasExtEntities: false, + expectUnmarshalSuccess: true, + expectCanonicalizeSuccess: true, + }, + } + + for _, tc := range testCases { + if err := tc.entry.Validate(); (err == nil) != tc.expectUnmarshalSuccess { + t.Errorf("unexpected result in '%v': %v", tc.caseDesc, err) + } + + v := &V001Entry{} + r := models.Rpm{ + APIVersion: swag.String(tc.entry.APIVersion()), + Spec: tc.entry.RPMModel, + } + if err := v.Unmarshal(&r); (err == nil) != tc.expectUnmarshalSuccess { + t.Errorf("unexpected result in '%v': %v", tc.caseDesc, err) + } + + if tc.entry.HasExternalEntities() != tc.hasExtEntities { + t.Errorf("unexpected result from HasExternalEntities for '%v'", tc.caseDesc) + } + + if _, err := tc.entry.Canonicalize(context.TODO()); (err == nil) != tc.expectCanonicalizeSuccess { + t.Errorf("unexpected result from Canonicalize for '%v': %v", tc.caseDesc, err) + } + } +} diff --git a/pkg/types/rpm/v0.0.1/rpm_v0_0_1_schema.json b/pkg/types/rpm/v0.0.1/rpm_v0_0_1_schema.json new file mode 100644 index 0000000000000000000000000000000000000000..cacd8f66d13f5fb8ab0729421d7fb309a8649b38 --- /dev/null +++ b/pkg/types/rpm/v0.0.1/rpm_v0_0_1_schema.json @@ -0,0 +1,86 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://rekor.dev/types/rpm/rpm_v0_0_1_schema.json", + "title": "RPM v0.0.1 Schema", + "description": "Schema for RPM entries", + "type": "object", + "properties": { + "publicKey" : { + "description": "The PGP public key that can verify the RPM signature", + "type": "object", + "properties": { + "url": { + "description": "Specifies the location of the public key", + "type": "string", + "format": "uri" + }, + "content": { + "description": "Specifies the content of the public key inline within the document", + "type": "string", + "format": "byte" + } + }, + "oneOf": [ + { + "required": [ "url" ] + }, + { + "required": [ "content" ] + } + ] + }, + "package": { + "description": "Information about the package associated with the entry", + "type": "object", + "properties": { + "headers": { + "description": "Values of the RPM headers", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "hash": { + "description": "Specifies the hash algorithm and value for the package", + "type": "object", + "properties": { + "algorithm": { + "description": "The hashing function used to compute the hash value", + "type": "string", + "enum": [ "sha256" ] + }, + "value": { + "description": "The hash value for the package", + "type": "string" + } + }, + "required": [ "algorithm", "value" ] + }, + "url": { + "description": "Specifies the location of the package; if this is specified, a hash value must also be provided", + "type": "string", + "format": "uri" + }, + "content": { + "description": "Specifies the package inline within the document", + "type": "string", + "format": "byte" + } + }, + "oneOf": [ + { + "required": [ "hash", "url" ] + }, + { + "required": [ "content" ] + } + ] + }, + "extraData": { + "description": "Arbitrary content to be included in the verifiable entry in the transparency log", + "type": "object", + "additionalProperties": true + } + }, + "required": [ "publicKey", "package" ] +} diff --git a/pkg/util/types.go b/pkg/util/types.go new file mode 100644 index 0000000000000000000000000000000000000000..dc1a1f45a6e75f3c0a58a411817e46b3d7a72e1f --- /dev/null +++ b/pkg/util/types.go @@ -0,0 +1,69 @@ +/* +Copyright © 2021 Bob Callaway <bcallawa@redhat.com> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package util + +import ( + "sync" + + "github.com/blang/semver" + "github.com/projectrekor/rekor/pkg/log" + "github.com/projectrekor/rekor/pkg/types" +) + +type VersionFactory func() types.EntryImpl + +type VersionFactoryMap struct { + VersionFactories map[string]VersionFactory + + sync.RWMutex +} + +func (vfm *VersionFactoryMap) Get(version string) (VersionFactory, bool) { + vfm.RLock() + defer vfm.RUnlock() + + semverToMatch, err := semver.Parse(version) + if err != nil { + log.Logger.Error(err) + return nil, false + } + + //will return first function that matches + for k, v := range vfm.VersionFactories { + semverRange, err := semver.ParseRange(k) + if err != nil { + log.Logger.Error(err) + return nil, false + } + + if semverRange(semverToMatch) { + return v, true + } + } + return nil, false +} + +func (vfm *VersionFactoryMap) Set(constraint string, vf VersionFactory) { + vfm.Lock() + defer vfm.Unlock() + + if _, err := semver.ParseRange(constraint); err != nil { + log.Logger.Error(err) + return + } + + vfm.VersionFactories[constraint] = vf +} diff --git a/tests/e2e_test.go b/tests/e2e_test.go index 192d4b5e710233805ab345de7619bf60e4eff3a7..aba5d1397ebd1f85d32fad711f45638475e1e639 100644 --- a/tests/e2e_test.go +++ b/tests/e2e_test.go @@ -38,7 +38,7 @@ func TestDuplicates(t *testing.T) { outputContains(t, out, "Created entry at") } -func TestUploadVerify(t *testing.T) { +func TestUploadVerifyRekord(t *testing.T) { // Create a random artifact and sign it. artifactPath := filepath.Join(t.TempDir(), "artifact") @@ -67,6 +67,34 @@ func TestUploadVerify(t *testing.T) { outputContains(t, out, "Inclusion Proof:") } +func TestUploadVerifyRpm(t *testing.T) { + + // Create a random rpm and sign it. + rpmPath := filepath.Join("rpm") + + createSignedRpm(t, rpmPath) + + // Write the public key to a file + pubPath := filepath.Join(t.TempDir(), "pubKey.asc") + if err := ioutil.WriteFile(pubPath, []byte(publicKey), 0644); err != nil { + t.Fatal(err) + } + + // Verify should fail initially + runCliErr(t, "verify", "--type=rpm", "--artifact", rpmPath, "--public-key", pubPath) + + // It should upload successfully. + out := runCli(t, "upload", "--type=rpm", "--artifact", rpmPath, "--public-key", pubPath) + outputContains(t, out, "Created entry at") + + // We have to wait some time for the log to get signed and included. + time.Sleep(3 * time.Second) + + // Now we should be able to verify it. + out = runCli(t, "verify", "--type=rpm", "--artifact", rpmPath, "--public-key", pubPath) + outputContains(t, out, "Inclusion Proof:") +} + func TestLogInfo(t *testing.T) { // TODO: figure out some way to check the length, add something, and make sure the length increments! out := runCli(t, "loginfo") diff --git a/tests/pgp.go b/tests/pgp.go index 19a9b694fb1e685762704f2f6824eb142aa7e3a3..cdf0f2d9878961b380d5330aec6ced53529955e7 100644 --- a/tests/pgp.go +++ b/tests/pgp.go @@ -4,7 +4,6 @@ package e2e import ( "bytes" - "io" "io/ioutil" "strings" "testing" @@ -150,13 +149,12 @@ func init() { } } -func Sign(t *testing.T, m io.Reader) []byte { - t.Helper() - var b bytes.Buffer - if err := openpgp.ArmoredDetachSign(&b, keys[0], m, nil); err != nil { - t.Fatal(err) +func Sign(b []byte) ([]byte, error) { + var buf bytes.Buffer + if err := openpgp.DetachSign(&buf, keys[0], bytes.NewReader(b), nil); err != nil { + return nil, err } - return b.Bytes() + return buf.Bytes(), nil } // createdSignedArtifact gets the test dir setup correctly with some random artifacts and keys. @@ -165,7 +163,10 @@ func createdSignedArtifact(t *testing.T, artifactPath, sigPath string) { artifact := createArtifact(t, artifactPath) // Sign it with our key and write that to a file - signature := Sign(t, strings.NewReader(artifact)) + signature, err := Sign([]byte(artifact)) + if err != nil { + t.Fatal(err) + } if err := ioutil.WriteFile(sigPath, []byte(signature), 0644); err != nil { t.Fatal(err) } diff --git a/tests/rpm.go b/tests/rpm.go new file mode 100644 index 0000000000000000000000000000000000000000..b14fe5cc575d1ffd9ce982012b4feb2274180718 --- /dev/null +++ b/tests/rpm.go @@ -0,0 +1,77 @@ +// +build e2e + +/* +Copyright © 2021 Bob Callaway <bcallawa@redhat.com> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package e2e + +import ( + "bytes" + "io/ioutil" + "math/rand" + "os" + "testing" + + "github.com/google/rpmpack" +) + +func randomRpmSuffix() string { + const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + + b := make([]byte, 16) + for i := range b { + b[i] = letterBytes[rand.Intn(len(letterBytes))] + } + return string(b) +} + +func createSignedRpm(t *testing.T, artifactPath string) { + t.Helper() + + rpmMetadata := rpmpack.RPMMetaData{ + Name: "test-rpm-" + randomRpmSuffix(), + Epoch: 0, + Version: "1", + Release: "2", + Arch: "x86_64", + } + rpm, err := rpmpack.NewRPM(rpmMetadata) + if err != nil { + t.Error(err) + } + + rpm.SetPGPSigner(Sign) + + data, err := randomData(100) + if err != nil { + t.Fatal(err) + } + + rpm.AddFile(rpmpack.RPMFile{ + Name: randomRpmSuffix(), + Body: data, + Type: rpmpack.GenericFile, + Owner: "testOwner", + Group: "testGroup", + }) + + rpmBuf := bytes.Buffer{} + if err := rpm.Write(&rpmBuf); err != nil { + t.Fatal(err) + } + if err := ioutil.WriteFile(artifactPath, rpmBuf.Bytes(), os.ModePerm); err != nil { + t.Fatal(err) + } +} diff --git a/tests/rpm.json b/tests/rpm.json new file mode 100644 index 0000000000000000000000000000000000000000..836a307499cdea1cafcfb3c965328cb398b2bd2f --- /dev/null +++ b/tests/rpm.json @@ -0,0 +1 @@ +{"kind":"rpm","apiVersion":"0.0.1","spec":{"package":{"content":"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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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AAAQAAAAAAByb290AHJvb3QAcm9vdAByb290AHJvb3QAcm9vdAByb290AHJvb3QATmV0d29ya01hbmFnZXItMS4yNi4wLTguZWw4LnNyYy5ycG0A/////////////////////05ldHdvcmtNYW5hZ2VyLWJsdWV0b290aABOZXR3b3JrTWFuYWdlci1ibHVldG9vdGgoeDg2LTY0KQBsaWJubS1kZXZpY2UtcGx1Z2luLWJsdWV0b290aC5zbygpKDY0Yml0KQAAAAAIAAAACAAAAAwAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAABAAAKAQAACgEAAAoBAAAKAABAAE5ldHdvcmtNYW5hZ2VyKHg4Ni02NCkATmV0d29ya01hbmFnZXItd3dhbgBibHVlegBsaWJibHVldG9vdGguc28uMygpKDY0Yml0KQBsaWJjLnNvLjYoKSg2NGJpdCkAbGliYy5zby42KEdMSUJDXzIuMTQpKDY0Yml0KQBsaWJjLnNvLjYoR0xJQkNfMi4yLjUpKDY0Yml0KQBsaWJjLnNvLjYoR0xJQkNfMi40KSg2NGJpdCkAbGliZGwuc28uMigpKDY0Yml0KQBsaWJnY2Nfcy5zby4xKCkoNjRiaXQpAGxpYmdjY19zLnNvLjEoR0NDXzMuMCkoNjRiaXQpAGxpYmdjY19zLnNvLjEoR0NDXzMuMy4xKSg2NGJpdCkAbGliZ2lvLTIuMC5zby4wKCkoNjRiaXQpAGxpYmdsaWItMi4wLnNvLjAoKSg2NGJpdCkAbGliZ21vZHVsZS0yLjAuc28uMCgpKDY0Yml0KQBsaWJnb2JqZWN0LTIuMC5zby4wKCkoNjRiaXQpAGxpYm1tLWdsaWIuc28uMCgpKDY0Yml0KQBsaWJubS13d2FuLnNvKCkoNjRiaXQpAGxpYnB0aHJlYWQuc28uMCgpKDY0Yml0KQBsaWJwdGhyZWFkLnNvLjAoR0xJQkNfMi4yLjUpKDY0Yml0KQBsaWJzeXN0ZW1kLnNvLjAoKSg2NGJpdCkAcnBtbGliKENvbXByZXNzZWRGaWxlTmFtZXMpAHJwbWxpYihGaWxlRGlnZXN0cykAcnBtbGliKFBheWxvYWRGaWxl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IEhhbGxlciA8dGhhbGxlckByZWRoYXQuY29tPiAtIDE6MS4yNi4wLTEAQmVuaWFtaW5vIEdhbHZhbmkgPGJnYWx2YW5pQHJlZGhhdC5jb20+IC0gMToxLjI2LjAtMC4yLjEAQmVuaWFtaW5vIEdhbHZhbmkgPGJnYWx2YW5pQHJlZGhhdC5jb20+IC0gMToxLjI2LjAtMC4yAFRob21hcyBIYWxsZXIgPHRoYWxsZXJAcmVkaGF0LmNvbT4gLSAxOjEuMjYuMC0wLjEAQmVuaWFtaW5vIEdhbHZhbmkgPGJnYWx2YW5pQHJlZGhhdC5jb20+IC0gMToxLjI1LjItMQBUaG9tYXMgSGFsbGVyIDx0aGFsbGVyQHJlZGhhdC5jb20+IC0gMToxLjI1LjEtMQBUaG9tYXMgSGFsbGVyIDx0aGFsbGVyQHJlZGhhdC5jb20+IC0gMToxLjIyLjgtNABCZW5pYW1pbm8gR2FsdmFuaSA8YmdhbHZhbmlAcmVkaGF0LmNvbT4gLSAxOjEuMjIuOC0zAFRob21hcyBIYWxsZXIgPHRoYWxsZXJAcmVkaGF0LmNvbT4gLSAxOjEuMjIuOC0yAEFudG9uaW8gQ2FyZGFjZSA8YWNhcmRhY2VAcmVkaGF0LmNvbT4gLSAxOjEuMjIuOC0xAEFudG9uaW8gQ2FyZGFjZSA8YWNhcmRhY2VAcmVkaGF0LmNvbT4gLSAxOjEuMjIuNi0xAEJlbmlhbWlubyBHYWx2YW5pIDxiZ2FsdmFuaUByZWRoYXQuY29tPiAtIDE6MS4yMi40LTEAVGhvbWFzIEhhbGxlciA8dGhhbGxlckByZWRoYXQuY29tPiAtIDE6MS4yMi4yLTEAVGhvbWFzIEhhbGxlciA8dGhhbGxlckByZWRoYXQuY29tPiAtIDE6MS4yMi4wLTIAVGhvbWFzIEhhbGxlciA8dGhhbGxlckByZWRoYXQuY29tPiAtIDE6MS4yMi4wLTEAVGhvbWFzIEhhbGxlciA8dGhhbGxlckByZWRoYXQuY29tPiAtIDE6MS4yMi4wLTAuMgBCZW5pYW1pbm8gR2FsdmFuaSA8YmdhbHZhbmlAcmVkaGF0LmNvbT4gLSAxOjEuMjIuMC0wLjEATHVib21pciBSaW50ZWwgPGxyaW50ZWxAcmVkaGF0LmNvbT4gLSAxOjEuMjAuMC00AFRob21hcyBIYWxsZXIgPHRoYWxsZXJAcmVkaGF0LmNvbT4gLSAxOjEuMjAuMC0zAEx1Ym9taXIgUmludGVsIDxscmludGVsQHJlZGhhdC5jb20+IC0gMToxLjIwLjAtMgBUaG9tYXMgSGFsbGVyIDx0aGFsbGVyQHJlZGhhdC5jb20+IC0gMToxLjIwLjAtMQBUaG9tYXMgSGFsbGVyIDx0aGFsbGVyQHJlZGhhdC5jb20+IC0gMToxLjIwLjAtMC40AEx1Ym9taXIgUmludGVsIDxscmludGVsQHJlZGhhdC5jb20+IC0gMToxLjIwLjAtMC4zAEx1Ym9taXIgUmludGVsIDxscmludGVsQHJlZGhhdC5jb20+IC0gMToxLjIwLjAtMC4yAEx1Ym9taXIgUmludGVsIDxscmludGVsQHJlZGhhdC5jb20+IC0gMToxLjIwLjAtMC4xAEJlbmlhbWlubyBHYWx2YW5pIDxiZ2FsdmFuaUByZWRoYXQuY29tPiAtIDE6MS4xNC4wLTE0AEZyYW5jZXNjbyBHaXVkaWNpIDxmZ2l1ZGljaUByZWRoYXQuY29tPiAtIDE6MS4xNC4wLTEzAFRob21hcyBIYWxsZXIgPHRoYWxsZXJAcmVkaGF0LmNvbT4gLSAxOjEuMTQuMC0xMgBCZW5pYW1pbm8gR2FsdmFuaSA8YmdhbHZhbmlAcmVkaGF0LmNvbT4gLSAxOjEuMTQuMC0xMQBCZW5pYW1pbm8gR2FsdmFuaSA8YmdhbHZhbmlAcmVkaGF0LmNvbT4gLSAxOjEuMTQuMC0xMABUaG9tYXMgSGFsbGVyIDx0aGFsbGVyQHJlZGhhdC5jb20+IC0gMToxLjE0LjAtOQBMdWJvbWlyIFJpbnRlbCA8bGt1bmRyYWtAdjMuc2s+IC0gMToxLjE0LjAtOABUaG9tYXMgSGFsbGVyIDx0aGFsbGVyQHJlZGhhdC5jb20+IC0gMToxLjE0LjAtNwBUaG9tYXMgSGFsbGVyIDx0aGFsbGVyQHJlZGhhdC5jb20+IC0gMToxLjE0LjAtNgBMdWJvbWlyIFJpbnRlbCA8bGt1bmRyYWtAdjMuc2s+IC0gMToxLjE0LjAtNQBCZW5pYW1pbm8gR2FsdmFuaSA8YmdhbHZhbmlAcmVkaGF0LmNvbT4gLSAxOjEuMTQuMC00AFRob21hcyBIYWxsZXIgPHRoYWxsZXJAcmVkaGF0LmNvbT4gLSAxOjEuMTQuMC0zAFRob21hcyBIYWxsZXIgPHRoYWxsZXJAcmVkaGF0LmNvbT4gLSAxOjEuMTQuMC0yAFRob21hcyBIYWxsZXIgPHRoYWxsZXJAcmVkaGF0LmNvbT4gLSAxOjEuMTQuMC0xAFRob21hcyBIYWxsZXIgPHRoYWxsZXJAcmVkaGF0LmNvbT4gLSAxOjEuMTQuMC0wLjQAVGhvbWFzIEhhbGxlciA8dGhhbGxlckByZWRoYXQuY29tPiAtIDE6MS4xNC4wLTAuMwBMdWJvbWlyIFJpbnRlbCA8bGt1bmRyYWtAdjMuc2s+IC0gMToxLjE0LjAtMC4yAFRob21hcyBIYWxsZXIgPHRoYWxsZXJAcmVkaGF0LmNvbT4gLSAxOjEuMTQuMC0wLjEATHVib21pciBSaW50ZWwgPGxrdW5kcmFrQHYzLnNrPiAtIDE6MS4xMi4wLTAuNABUaG9tYXMgSGFsbGVyIDx0aGFsbGVyQHJlZGhhdC5jb20+IC0gMToxLjEyLjAtMC4zAFRob21hcyBIYWxsZXIgPHRoYWxsZXJAcmVkaGF0LmNvbT4gLSAxOjEuMTIuMC0wLjIAVGhvbWFzIEhhbGxlciA8dGhhbGxlckByZWRoYXQuY29tPiAtIDE6MS4xMi4wLTAuMQBUaG9tYXMgSGFsbGVyIDx0aGFsbGVyQHJlZGhhdC5jb20+IC0gMToxLjEwLjItMQBCasO2cm4gRXNzZXIgPGJlc3NlcjgyQGZlZG9yYXByb2plY3Qub3JnPiAtIDE6MS44LjQtNwBUaG9tYXMgSGFsbGVyIDx0aGFsbGVyQHJlZGhhdC5jb20+IC0gMToxLjguNC02AEx1Ym9taXIgUmludGVsIDxsa3VuZHJha0B2My5zaz4gLSAxOjEuOC40LTUAVGhvbWFzIEhhbGxlciA8dGhhbGxlckByZWRoYXQuY29tPiAtIDE6MS44LjQtNABUaG9tYXMgSGFsbGVyIDx0aGFsbGVyQHJlZGhhdC5jb20+IC0gMToxLjguNC0zAFRob21hcyBIYWxsZXIgPHRoYWxsZXJAcmVkaGF0LmNvbT4gLSAxOjEuOC40LTIAVGhvbWFzIEhhbGxlciA8dGhhbGxlckByZWRoYXQuY29tPiAtIDE6MS44LjQtMQBGZWRvcmEgUmVsZWFzZSBFbmdpbmVlcmluZyA8cmVsZW5nQGZlZG9yYXByb2plY3Qub3JnPiAtIDE6MS44LjItMy4yAEZlZG9yYSBSZWxlYXNlIEVuZ2luZWVyaW5nIDxyZWxlbmdAZmVkb3JhcHJvamVjdC5vcmc+IC0gMToxLjguMi0zLjEATHVib21pciBSaW50ZWwgPGxrdW5kcmFrQHYzLnNrPiAtIDE6MS44LjItMwBTdGVwaGVuIEdhbGxhZ2hlciA8c2dhbGxhZ2hAcmVkaGF0LmNvbT4gLSAxOjEuOC4yLTIAQmVuaWFtaW5vIEdhbHZhbmkgPGJnYWx2YW5pQHJlZGhhdC5jb20+IC0gMToxLjguMi0xAEx1Ym9taXIgUmludGVsIDxsa3VuZHJha0B2My5zaz4gLSAxOjEuOC4wLTYATHVib21pciBSaW50ZWwgPGxrdW5kcmFrQHYzLnNrPiAtIDE6MS44LjAtNQBUaG9tYXMgSGFsbGVyIDx0aGFsbGVyQHJlZGhhdC5jb20+IC0gMToxLjguMC00AFRob21hcyBIYWxsZXIgPHRoYWxsZXJAcmVkaGF0LmNvbT4gLSAxOjEuOC4wLTMAVGhvbWFzIEhhbGxlciA8dGhhbGxlckByZWRoYXQuY29tPiAtIDE6MS44LjAtMgBUaG9tYXMgSGFsbGVyIDx0aGFsbGVyQHJlZGhhdC5jb20+IC0gMToxLjguMC0xAEx1Ym9taXIgUmludGVsIDxsa3VuZHJha0B2My5zaz4gLSAxOjEuOC4wLTAuMi5yYzMATHVib21pciBSaW50ZWwgPGxrdW5kcmFrQHYzLnNrPiAtIDE6MS44LjAtMC4yLnJjMgBMdWJvbWlyIFJpbnRlbCA8bGt1bmRyYWtAdjMuc2s+IC0gMToxLjguMC0wLjEATHVib21pciBSaW50ZWwgPGxrdW5kcmFrQHYzLnNrPiAtIDE6MS42LjItMQBGZWRvcmEgUmVsZWFzZSBFbmdpbmVlcmluZyA8cmVsZW5nQGZlZG9yYXByb2plY3Qub3JnPiAtIDE6MS42LjAtMS4xAEx1Ym9taXIgUmludGVsIDxsa3VuZHJha0B2My5zaz4gLSAxOjEuNi4wLTEAVGhvbWFzIEhhbGxlciA8dGhhbGxlckByZWRoYXQuY29tPiAtIDE6MS42LTAuMi5yYzEATHVib21pciBSaW50ZWwgPGxrdW5kcmFrQHYzLnNrPiAtIDE6MS42LTAuMS5yYzEAVGhvbWFzIEhhbGxlciA8dGhhbGxlckByZWRoYXQuY29tPiAtIDE6MS41LjMtNQBJZ29yIEduYXRlbmtvIDxpZ25hdGVua29AcmVkaGF0LmNvbT4gLSAxOjEuNS4zLTQuMQBMdWJvbWlyIFJpbnRlbCA8bGt1bmRyYWtAdjMuc2s+IC0gMToxLjUuMy00AFRob21hcyBIYWxsZXIgPHRoYWxsZXJAcmVkaGF0LmNvbT4gLSAxOjEuNS4yLTQAVGhvbWFzIEhhbGxlciA8dGhhbGxlckByZWRoYXQuY29tPiAtIDE6MS41LjItMwBUaG9tYXMgSGFsbGVyIDx0aGFsbGVyQHJlZGhhdC5jb20+IC0gMToxLjUuMi0yAEx1Ym9taXIgUmludGVsIDxsa3VuZHJha0B2My5zaz4gLSAxOjEuNS4yLTEATHVib21pciBSaW50ZWwgPGxrdW5kcmFrQHYzLnNrPiAtIDE6MS40LjItMQBUaG9tYXMgSGFsbGVyIDx0aGFsbGVyQHJlZGhhdC5jb20+IC0gMToxLjQuMC00AFRob2FtcyBIYWxsZXIgPHRoYWxsZXJAcmVkaGF0LmNvbT4gLSAxOjEuNC4wLTMAVGhvbWFzIEhhbGxlciA8dGhhbGxlckByZWRoYXQuY29tPiAtIDE6MS40LjAtMgBMdWJvbWlyIFJpbnRlbCA8bGt1bmRyYWtAdjMuc2s+IC0gMToxLjQuMC0xAFRob21hcyBIYWxsZXIgPHRoYWxsZXJAcmVkaGF0LmNvbT4gLSAxOjEuNC4wLTAuNS5naXQyMDE2MDYyMS4wNzIzNThkYQBNYXR0aGlhcyBDbGFzZW4gPG1jbGFzZW5AcmVkaGF0LmNvbT4gLSAxOjEuNC4wLTAuNC5naXQyMDE2MDYyMS4wNzIzNThkYQBMdWJvbWlyIFJpbnRlbCA8bGt1bmRyYWtAdjMuc2s+IC0gMToxLjQuMC0wLjMuZ2l0MjAxNjA2MjEuMDcyMzU4ZGEAVGhvbWFzIEhhbGxlciA8dGhhbGxlckByZWRoYXQuY29tPiAtIDE6MS4yLjItMgBMdWJvbWlyIFJpbnRlbCA8bGt1bmRyYWtAdjMuc2s+IC0gMToxLjIuMi0xAEx1Ym9taXIgUmludGVsIDxsa3VuZHJha0B2My5zaz4gLSAxOjEuMi4wLTEATHVib21pciBSaW50ZWwgPGxrdW5kcmFrQHYzLnNrPiAtIDE6MS4yLjAtMC43LnJjMgBMdWJvbWlyIFJpbnRlbCA8bGt1bmRyYWtAdjMuc2s+IC0gMToxLjIuMC0wLjcucmMxAEx1Ym9taXIgUmludGVsIDxsa3VuZHJha0B2My5zaz4gLSAxOjEuMi4wLTAuOC5iZXRhMwBMdWJvbWlyIFJpbnRlbCA8bGt1bmRyYWtAdjMuc2s+IC0gMToxLjIuMC0wLjcuYmV0YTMATHVib21pciBSaW50ZWwgPGxrdW5kcmFrQHYzLnNrPiAtIDE6MS4yLjAtMC43LmJldGEyAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MS4yLjAtMC42LmJldGEyLjEATHVib21pciBSaW50ZWwgPGxrdW5kcmFrQHYzLnNrPiAtIDE6MS4yLjAtMC42LmJldGEyAFRob21hcyBIYWxsZXIgPHRoYWxsZXJAcmVkaGF0LmNvbT4gLSAxOjEuMi4wLTAuNi5iZXRhMQBGZWRvcmEgUmVsZWFzZSBFbmdpbmVlcmluZyA8cmVsZW5nQGZlZG9yYXByb2plY3Qub3JnPiAtIDE6MS4yLjAtMC41LmJldGExLjEATHVib21pciBSaW50ZWwgPGxrdW5kcmFrQHYzLnNrPiAtIDE6MS4yLjAtMC41LmJldGExAERhdmlkIEtpbmcgPGFtaWdhZGF2ZUBhbWlnYWRhdmUuY29tPiAtIDE6MS4yLjAtMC40LjIwMTUxMDA3Z2l0ZTczZTU1YwBMdWJvbWlyIFJpbnRlbCA8bGt1bmRyYWtAdjMuc2s+IC0gMToxLjIuMC0wLjMuMjAxNTExMTJnaXRlYzRkNjUzAEx1Ym9taXIgUmludGVsIDxsa3VuZHJha0B2My5zaz4gLSAxOjEuMi4wLTAuMy4yMDE1MTAyM2dpdGUwMWMxNzUATHVib21pciBSaW50ZWwgPGxrdW5kcmFrQHYzLnNrPiAtIDE6MS4yLjAtMC4yLjIwMTUxMDA3Z2l0ZTczZTU1YwBMdWJvbWlyIFJpbnRlbCA8bGt1bmRyYWtAdjMuc2s+IC0gMToxLjIuMC0wLjIuMjAxNTA5MDNnaXRkZTVkOTgxAEx1Ym9taXIgUmludGVsIDxsa3VuZHJha0B2My5zaz4gLSAxOjEuMi4wLTAuMS4yMDE1MDkwM2dpdGRlNWQ5ODEATHVib21pciBSaW50ZWwgPGxrdW5kcmFrQHYzLnNrPiAtIDE6MS4wLjYtMgBMdWJvbWlyIFJpbnRlbCA8bGt1bmRyYWtAdjMuc2s+IC0gMToxLjAuNi0xAFRob21hcyBIYWxsZXIgPHRoYWxsZXJAcmVkaGF0LmNvbT4gLSAxOjEuMC42LTAuMi4yMDE1MDgxM2dpdDdlMmNhYTIATHVib21pciBSaW50ZWwgPGxrdW5kcmFrQHYzLnNrPiAtIDE6MS4wLjYtMC4xLjIwMTUwODEzZ2l0N2UyY2FhMgBMdWJvbWlyIFJpbnRlbCA8bGt1bmRyYWtAdjMuc2s+IC0gMToxLjAuNC0yAEx1Ym9taXIgUmludGVsIDxsa3VuZHJha0B2My5zaz4gLSAxOjEuMC40LTEARGFuIEhvcsOhayA8ZGFuW2F0XWRhbm55LmN6PiAtIDE6MS4wLjQtMC41LmdpdDIwMTUwNzEzLjM4YmYyY2IwAEx1Ym9taXIgUmludGVsIDxsa3VuZHJha0B2My5zaz4gLSAxOjEuMC40LTAuNC5naXQyMDE1MDcxMy4zOGJmMmNiMABMdWJvbWlyIFJpbnRlbCA8bGt1bmRyYWtAdjMuc2s+IC0gMToxLjAuNC0wLjMuZ2l0MjAxNTA3MDcuZTNiZDRlMQBKacWZw60gS2xpbWXFoSA8amtsaW1lc0ByZWRoYXQuY29tPiAtIDE6MS4wLjQtMC4yLmdpdDIwMTUwNzA3LmNmMTVmMmEATHVib21pciBSaW50ZWwgPGxrdW5kcmFrQHYzLnNrPiAtIDE6MS4wLjQtMC4xLmdpdDIwMTYwNjI0LmYyNDViNDlhAEx1Ym9taXIgUmludGVsIDxsa3VuZHJha0B2My5zaz4gLSAxOjEuMC40LTAuMS5naXQyMDE1MDYxOC44Y2ZmYWYzYmY1AEZlZG9yYSBSZWxlYXNlIEVuZ2luZWVyaW5nIDxyZWwtZW5nQGxpc3RzLmZlZG9yYXByb2plY3Qub3JnPiAtIDE6MS4wLjItMS4xAEx1Ym9taXIgUmludGVsIDxsa3VuZHJha0B2My5zaz4gLSAxOjEuMC4yLTEASmnFmcOtIEtsaW1lxaEgPGprbGltZXNAcmVkaGF0LmNvbT4gLSAxOjEuMC4xLTIuZ2l0MjAxNTA0MjkARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMToxLjAuMS0xLmdpdDIwMTUwMzA1AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MS4wLjAtNwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjEuMC4wLTYARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMToxLjAuMC01AEFkYW0gV2lsbGlhbXNvbiA8YXdpbGxpYW1AcmVkaGF0LmNvbT4gLSAxOjEuMC4wLTQAVGhvbWFzIEhhbGxlciA8dGhhbGxlckByZWRoYXQuY29tPiAtIDE6MS4wLjAtMwBEYW4gV2luc2hpcCA8ZGFud0ByZWRoYXQuY29tPiAtIDE6MS4wLjAtMgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjEuMC4wLTEASmnFmcOtIEtsaW1lxaEgPGprbGltZXNAcmVkaGF0LmNvbT4gLSAxOjAuOS4xMC4wLTE0LmdpdDIwMTQwNzA0AEppxZnDrSBLbGltZcWhIDxqa2xpbWVzQHJlZGhhdC5jb20+IC0gMTowLjkuMTAuMC0xMy5naXQyMDE0MDcwNABEYW4gV2luc2hpcCA8ZGFud0ByZWRoYXQuY29tPiAtIDE6MC45LjEwLjAtMTIuZ2l0MjAxNDA3MDQATHVib21pciBSaW50ZWwgPGxrdW5kcmFrQHYzLnNrPiAxOjAuOS4xMC4wLTExLmdpdDIwMTQwNzA0AEx1Ym9taXIgUmludGVsIDxsa3VuZHJha0B2My5zaz4gMTowLjkuMTAuMC0xMC5naXQyMDE0MDcwNABBZGFtIFdpbGxpYW1zb24gPGF3aWxsaWFtQHJlZGhhdC5jb20+IC0gMTowLjkuMTAuMC05LmdpdDIwMTQwNzA0AEx1Ym9taXIgUmludGVsIDxsa3VuZHJha0B2My5zaz4gMTowLjkuMTAuMC04LmdpdDIwMTQwNzA0AFN0ZWYgV2FsdGVyIDxzdGVmd0ByZWRoYXQuY29tPiAtIDE6MC45LjEwLjAtNy5naXQyMDE0MDcwNABKacWZw60gS2xpbWXFoSA8amtsaW1lc0ByZWRoYXQuY29tPiAtIDE6MC45LjEwLjAtNi5naXQyMDE0MDcwNABQZXRlciBSb2JpbnNvbiA8cGJyb2JpbnNvbkBmZWRvcmFwcm9qZWN0Lm9yZz4gMTowLjkuMTAuMC01LmdpdDIwMTQwNzA0AERhbiBIb3LDoWsgPGRhblthdF1kYW5ueS5jej4gLSAxOjAuOS4xMC4wLTQuZ2l0MjAxNDA3MDQARmVkb3JhIFJlbGVhc2UgRW5naW5lZXJpbmcgPHJlbC1lbmdAbGlzdHMuZmVkb3JhcHJvamVjdC5vcmc+IC0gMTowLjkuMTAuMC0zLmdpdDIwMTQwNzA0LjEAS2FsZXYgTGVtYmVyIDxrYWxldmxlbWJlckBnbWFpbC5jb20+IC0gMTowLjkuMTAuMC0zLmdpdDIwMTQwNzA0AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC45LjEwLjAtMi5naXQyMDE0MDcwNABLYWxldiBMZW1iZXIgPGthbGV2bGVtYmVyQGdtYWlsLmNvbT4gLSAxOjAuOS4xMC4wLTEuZ2l0MjAxNDA3MDQuMQBUaG9tYXMgSGFsbGVyIDx0aGFsbGVyQHJlZGhhdC5jb20+IC0gMC45LjEwLjAtMS5naXQyMDE0MDcwNABUaG9tYXMgSGFsbGVyIDx0aGFsbGVyQHJlZGhhdC5jb20+IC0gMC45LjkuOTgtMS5naXQyMDE0MDYyMABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjkuOS45NS0xLmdpdDIwMTQwNjA5AEZlZG9yYSBSZWxlYXNlIEVuZ2luZWVyaW5nIDxyZWwtZW5nQGxpc3RzLmZlZG9yYXByb2plY3Qub3JnPiAtIDE6MC45LjkuMS02LmdpdDIwMTQwMzE5AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOS45LjEtNS5naXQyMDE0MDMxOQBEYW4gV2luc2hpcCA8ZGFud0ByZWRoYXQuY29tPiAtIDAuOS45LjEtNC5naXQyMDE0MDMxOQBKacWZw60gS2xpbWXFoSA8amtsaW1lc0ByZWRoYXQuY29tPiAtIDAuOS45LjEtMy5naXQyMDE0MDMxNwBKacWZw60gS2xpbWXFoSA8amtsaW1lc0ByZWRoYXQuY29tPiAtIDAuOS45LjEtMi5naXQyMDE0MDMxNABKacWZw60gS2xpbWXFoSA8amtsaW1lc0ByZWRoYXQuY29tPiAtIDAuOS45LjEtMS5naXQyMDE0MDMxMABUaG9tYXMgSGFsbGVyIDx0aGFsbGVyQHJlZGhhdC5jb20+IC0gMC45LjkuMS0wLmdpdDIwMTQwMjI4AFRob21hcyBIYWxsZXIgPHRoYWxsZXJAcmVkaGF0LmNvbT4gLSAwLjkuOS4wLTI4LmdpdDIwMTQwMTMxAFRob21hcyBIYWxsZXIgPHRoYWxsZXJAcmVkaGF0LmNvbT4gLSAwLjkuOS4wLTI3LmdpdDIwMTQwMTMxAEppxZnDrSBLbGltZcWhIDxqa2xpbWVzQHJlZGhhdC5jb20+IC0gMC45LjkuMC0yNi5naXQyMDE0MDEzMQBKacWZw60gS2xpbWXFoSA8amtsaW1lc0ByZWRoYXQuY29tPiAtIDAuOS45LjAtMjUuZ2l0MjAxNDAxMTcASmnFmcOtIEtsaW1lxaEgPGprbGltZXNAcmVkaGF0LmNvbT4gLSAwLjkuOS4wLTI0LmdpdDIwMTQwMTE0AERhbiBXaW5zaGlwIDxkYW53QHJlZGhhdC5jb20+IC0gMC45LjkuMC0yMy5naXQyMDEzMTAwMwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjkuOS4wLTIyLmdpdDIwMTMxMDAzAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOS45LjAtMjEuZ2l0MjAxMzEwMDMARGFuIFdpbnNoaXAgPGRhbndAcmVkaGF0LmNvbT4gLSAwLjkuOS4wLTIwLmdpdDIwMTMxMDAzAEppxZnDrSBLbGltZcWhIDxqa2xpbWVzQHJlZGhhdC5jb20+IC0gMC45LjkuMC0xOS5naXQyMDEzMTAwMwBEYW4gV2luc2hpcCA8ZGFud0ByZWRoYXQuY29tPiAtIDAuOS45LjAtMTguZ2l0MjAxMzEwMDMARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC45LjkuMC0xNy5naXQyMDEzMTAwMwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjkuOS4wLTE2LmdpdDIwMTMxMDAzAEppxZnDrSBLbGltZcWhIDxqa2xpbWVzQHJlZGhhdC5jb20+IC0gMC45LjkuMC0xNS5naXQyMDEzMTAwMwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjkuOS4wLTE0LmdpdDIwMTMxMDAzAERhbiBXaW5zaGlwIDxkYW53QHJlZGhhdC5jb20+IC0gMC45LjkuMC0xMy5naXQyMDEzMTAwMQBCaWxsIE5vdHRpbmdoYW0gPG5vdHRpbmdAcmVkaGF0LmNvbT4gLSAwLjkuOS4wLTEyLmdpdDIwMTMwOTEzAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOS45LjAtMTEuZ2l0MjAxMzA5MTMARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC45LjkuMC0xMC5naXQyMDEzMDkwNgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjkuOS4wLTkuZ2l0MjAxMzA4MDcARGFuIFdpbnNoaXAgPGRhbndAcmVkaGF0LmNvbT4gLSAwLjkuOS4wLTguZ2l0MjAxMzA3MjQARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC45LjkuMC03LmdpdDIwMTMwNzI0AERhbiBXaW5zaGlwIDxkYW53QHJlZGhhdC5jb20+IC0gMC45LjkuMC02AERhbiBXaW5zaGlwIDxkYW53QHJlZGhhdC5jb20+IC0gMC45LjkuMC01AEppxZnDrSBLbGltZcWhIDxqa2xpbWVzQHJlZGhhdC5jb20+IC0gMC45LjkuMC00LmdpdDIwMTMwNjAzAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOS45LjAtMy5naXQyMDEzMDYwMwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjkuOS4wLTIuZ2l0MjAxMzA1MTUARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC45LjkuMC0xLmdpdDIwMTMwNTE0AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOS44LjEtMi5naXQyMDEzMDUwNwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjkuOC4xLTEuZ2l0MjAxMzAzMjcASmnFmcOtIEtsaW1lxaEgPGprbGltZXNAcmVkaGF0LmNvbT4gLSAwLjkuOC4wLTEARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC45LjcuOTk3LTIARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC45LjcuOTk3LTEARGFuIFdpbnNoaXAgPGRhbndAcmVkaGF0LmNvbT4gLSAwLjkuNy4wLTEyLmdpdDIwMTIxMDA0AEppxZnDrSBLbGltZcWhIDxqa2xpbWVzQHJlZGhhdC5jb20+IC0gMC45LjcuMC0xMS5naXQyMDEyMTAwNABEYW4gV2luc2hpcCA8ZGFud0ByZWRoYXQuY29tPiAtIDAuOS43LjAtMTAuZ2l0MjAxMjEwMDQARGFuIFdpbnNoaXAgPGRhbndAcmVkaGF0LmNvbT4gLSAwLjkuNy4wLTkuZ2l0MjAxMjEwMDQASmnFmcOtIEtsaW1lxaEgPGprbGltZXNAcmVkaGF0LmNvbT4gLSAwLjkuNy4wLTguZ2l0MjAxMjEwMDQARGFuaWVsIERyYWtlIDxkc2RAbGFwdG9wLm9yZz4gLSAwLjkuNy4wLTcuZ2l0MjAxMjEwMDQARGFuIFdpbnNoaXAgPGRhbndAcmVkaGF0LmNvbT4gLSAwLjkuNy4wLTYuZ2l0MjAxMjEwMDQARGFuIFdpbnNoaXAgPGRhbndAcmVkaGF0LmNvbT4gLSAwLjkuNy4wLTUuZ2l0MjAxMjEwMDQARGFuIFdpbnNoaXAgPGRhbndAcmVkaGF0LmNvbT4gLSAwLjkuNy4wLTQuZ2l0MjAxMjEwMDQARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC45LjcuMC0zLmdpdDIwMTIxMDA0AERhbiBXaW5zaGlwIDxkYW53QHJlZGhhdC5jb20+IC0gMC45LjcuMC0yLmdpdDIwMTIxMDA0AERhbiBXaW5zaGlwIDxkYW53QHJlZGhhdC5jb20+IC0gMC45LjcuMC0xLmdpdDIwMTIwODIwAEZlZG9yYSBSZWxlYXNlIEVuZ2luZWVyaW5nIDxyZWwtZW5nQGxpc3RzLmZlZG9yYXByb2plY3Qub3JnPiAtIDE6MC45LjUuOTYtMgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjkuNS45Ni0xAEppxZnDrSBLbGltZcWhIDxqa2xpbWVzQHJlZGhhdC5jb20+IC0gMC45LjUuOTUtMS5naXQyMDEyMDcxMwBKacWZw60gS2xpbWXFoSA8amtsaW1lc0ByZWRoYXQuY29tPiAtIDAuOS40LTUuZ2l0MjAxMjA1MjEARGFuIFdpbnNoaXAgPGRhbndAcmVkaGF0LmNvbT4gLSAwLjkuNC00LmdpdDIwMTIwNTAyAEppxZnDrSBLbGltZcWhIDxqa2xpbWVzQHJlZGhhdC5jb20+IC0gMC45LjQtMy5naXQyMDEyMDUwMgBDb2xpbiBXYWx0ZXJzIDx3YWx0ZXJzQHZlcmJ1bS5vcmc+IC0gMTowLjkuNC0yLmdpdDIwMTIwMzI4XzIASmnFmcOtIEtsaW1lxaEgPGprbGltZXNAcmVkaGF0LmNvbT4gLSAwLjkuNC0xLmdpdDIwMTIwMzI4XzIARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC45LjMuOTk3LTIARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC45LjMuOTk3LTEARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC45LjMuOTk3LTAuNwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjkuMy45OTUtMC42AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOS4zLjk5NS0wLjUARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC45LjMuOTk1LTAuNABEYW4gSG9yw6FrIDxkYW5bYXRdZGFubnkuY3o+IC0gMC45LjMtMC4zAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOS4zLTAuMgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjkuMy0wLjEATWF0dGhpYXMgQ2xhc2VuIDxtY2xhc2VuQHJlZGhhdC5jb20+IC0gMC45LjItNABGZWRvcmEgUmVsZWFzZSBFbmdpbmVlcmluZyA8cmVsLWVuZ0BsaXN0cy5mZWRvcmFwcm9qZWN0Lm9yZz4gLSAxOjAuOS4yLTMARGFuaWVsIERyYWtlIDxkc2RAbGFwdG9wLm9yZz4gLSAwLjkuMi0yAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOS4yLTEAQWRhbSBXaWxsaWFtc29uIDxhd2lsbGlhbUByZWRoYXQuY29tPiAtIDE6MC45LjEuOTAtNS5naXQyMDExMDkyNwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjkuMS45MC0zLmdpdDIwMTEwOTI3AEppxZnDrSBLbGltZcWhIDxqa2xpbWVzQHJlZGhhdC5jb20+IC0gMC45LjEuOTAtMi5naXQyMDExMDkyNwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjkuMS45MC0xAFRvbSBDYWxsYXdheSA8c3BvdEBmZWRvcmFwcm9qZWN0Lm9yZz4gLSAwLjkuMC0yAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOS4wLTEAUmF5IFN0cm9kZSA8cnN0cm9kZUByZWRoYXQuY29tPiAwLjguOTk5Ny03LmdpdDIwMTEwNzIxAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOC45OTk3LTYuZ2l0MjAxMTA3MjEARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC44Ljk5OTctNS5naXQyMDExMDcwMgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjguOTk5Ny00LmdpdDIwMTEwNjIwAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOC45OTk3LTMuZ2l0MjAxMTA2MTMARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC44Ljk5OTctMi5naXQyMDExMDUzMQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjguOTk5Ny0xLmdpdDIwMTEwNTMxAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOC45OTktMy5naXQyMDExMDUyNgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjguOTk5LTIuZ2l0MjAxMTA1MDkARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC44Ljk5OS0xAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOC45OTgtNC5naXQyMDExMDQyNwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjguOTk4LTMuZ2l0MjAxMTA0MTkARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC44Ljk5OC0yLmdpdDIwMTEwNDA2AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOC45OTgtMQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjguOTk3LTguZ2l0MjAxMTAzMzEARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC44Ljk5Ny03LmdpdDIwMTEwMzMwAENocmlzdG9waGVyIEFpbGxvbiA8Y2FpbGxvbkByZWRoYXQuY29tPiAtIDAuOC45OTctNi5naXQyMDExMDMyOABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjguOTk3LTUuZ2l0MjAxMTAzMjgARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC44Ljk5Ny00LmdpdDIwMTEwMzI1AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOC45OTctMy5naXQyMDExMDMyNABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjguOTk3LTIuZ2l0MjAxMTAzMjQARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC44Ljk5Ny0xAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOC45OTYtMQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjguOTk1LTQuZ2l0MjAxMTAzMDgARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC44Ljk5NS0zLmdpdDIwMTEwMzA4AE1hdHRoaWFzIENsYXNlbiA8bWNsYXNlbkByZWRoYXQuY29tPiAtIDAuOC45OTUtMi5naXQyMDExMDMwOABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjguOTk1LTEuZ2l0MjAxMTAzMDgATWF0dGhpYXMgQ2xhc2VuIDxtY2xhc2VuQHJlZGhhdC5jb20+IC0gMC44LjItOC5naXQyMDEwMTExNwBGZWRvcmEgUmVsZWFzZSBFbmdpbmVlcmluZyA8cmVsLWVuZ0BsaXN0cy5mZWRvcmFwcm9qZWN0Lm9yZz4gLSAxOjAuOC4yLTcuZ2l0MjAxMDExMTcATWF0dGhpYXMgQ2xhc2VuIDxtY2xhc2VuQHJlZGhhdC5jb20+IC0gMC44LjItNi5naXQyMDEwMTExNwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjguMi01LmdpdDIwMTAxMTE3AE1hdHRoaWFzIENsYXNlbiA8bWNsYXNlbkByZWRoYXQuY29tPiAtIDAuOC4yLTQuZ2l0MjAxMDExMTcARGFuIEhvcsOhayA8ZGFuW2F0XWRhbm55LmN6PiAtIDAuOC4yLTMuZ2l0MjAxMDExMTcATWF0dGhpYXMgQ2xhc2VuIDxtY2xhc2VuQHJlZGhhdC5jb20+IC0gMC44LjItMi5naXQyMDEwMTExNwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjguMi0xLmdpdDIwMTAxMTE3AE1hdHRoaWFzIENsYXNlbiA8bWNsYXNlbkByZWRoYXQuY29tPiAtIDAuOC4xLTEwLjEARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC44LjEtMTAARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC44LjEtOQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjguMS04AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOC4xLTcARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC44LjEtNgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjguMS01AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOC4xLTQARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC44LjEtMwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjguMS0yAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOC4xLTEATWF0dGhpYXMgQ2xhc2VuIDxtY2xhc2VuQHJlZGhhdGNvbT4gLSAwLjguMS0wLjUARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC44LjEtMC40AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOC4xLTAuMwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjguMS0wLjIuZ2l0MjAxMDA1MTkARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC44LjEtMC4xLmdpdDIwMTAwNTEwAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOC0xMy5naXQyMDEwMDUwOQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjgtMTIuZ2l0MjAxMDA1MDQARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC44LTExLmdpdDIwMTAwNTAzAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOC0xMC5naXQyMDEwMDUwMgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjgtOS5naXQyMDEwMDQyOQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjgtOC5naXQyMDEwMDQyNgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjgtNy5naXQyMDEwMDQyMgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjgtNi5naXQyMDEwMDQwOABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjgtNS5naXQyMDEwMDQwOABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjgtNC5naXQyMDEwMDMyNQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjgtMy5naXQyMDEwMDMyMwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjgtMi5naXQyMDEwMDMxNwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjgtMS5naXQyMDEwMDIxOQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjgtMC40LmdpdDIwMTAwMjExAEtldmluIEtvZmxlciA8S2V2aW5AdGlnY2MudGljYWxjLm9yZz4gLSAwLjgtMC4zLmdpdDIwMTAwMTI5AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuOC0wLjIuZ2l0MjAxMDAxMjkARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC44LTAuMS5naXQyMDEwMDEyMgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjcuOTk5LTIuZ2l0MjAxMDAxMjAARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC43Ljk5OS0xLmdpdDIwMTAwMTIwAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuNy45OTgtMS5naXQyMDEwMDEwNgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjcuOTk3LTIuZ2l0MjAwOTEyMTQARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC43Ljk5Ny0xAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuNy45OTYtNy5naXQyMDA5MTExMwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjcuOTk2LTYuZ2l0MjAwOTEwMjEARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC43Ljk5Ni01LmdpdDIwMDkxMDIxAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuNy45OTYtNC5naXQyMDA5MTAwMgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjcuOTk2LTMuZ2l0MjAwOTA5MjgATWF0dGhpYXMgQ2xhc2VuIDxtY2xhc2VuQHJlZGhhdC5jb20+IC0gMC43Ljk5Ni0zLmdpdDIwMDkwOTIxAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuNy45OTYtMi5naXQyMDA5MDkyMQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjcuOTk2LTEuZ2l0MjAwOTA4MjYARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC43Ljk5NS0zLmdpdDIwMDkwODEzAEJhc3RpZW4gTm9jZXJhIDxibm9jZXJhQHJlZGhhdC5jb20+IDAuNy45OTUtMi5naXQyMDA5MDgwNABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjcuOTk1LTEuZ2l0MjAwOTA4MDQATWF0dGhpYXMgQ2xhc2VuIDxtY2xhc2VuQHJlZGhhdC5jb20+IC0gMC43Ljk5NS0xLmdpdDIwMDkwNzI4AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuNy45OTUtMC5naXQyMDA5MDcyOABGZWRvcmEgUmVsZWFzZSBFbmdpbmVlcmluZyA8cmVsLWVuZ0BsaXN0cy5mZWRvcmFwcm9qZWN0Lm9yZz4gLSAxOjAuNy4xLTkuZ2l0MjAwOTA3MDgARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC43LjEtOC5naXQyMDA5MDcwOABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjcuMS03LmdpdDIwMDkwNzA4AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuNy4xLTYuZ2l0MjAwOTA2MTcARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC43LjEtNS5naXQyMDA5MDYxNwBLYXJzdGVuIEhvcHAgPGthcnN0ZW5AcmVkaGF0LmNvbT4gMC43LjEtNC5naXQyMDA5MDQxNC4xAEFkYW0gSmFja3NvbiA8YWpheEByZWRoYXQuY29tPiAxOjAuNy4xLTQuZ2l0MjAwOTA0MTQARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMS0zLmdpdDIwMDkwNDE0AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjEtMi5naXQyMDA5MDQxNABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4xLTEARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC4xMDAtMi5naXQyMDA5MDQwOABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLjEwMC0xAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAuOTktNQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLjk5LTQARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC45OS0zLjUARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC45OS0zAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAuOTktMgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLjk5LTEARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC45OC0xLmdpdDIwMDkwMjI1AEZlZG9yYSBSZWxlYXNlIEVuZ2luZWVyaW5nIDxyZWwtZW5nQGxpc3RzLmZlZG9yYXByb2plY3Qub3JnPiAtIDE6MC43LjAuOTctNi5naXQyMDA5MDIyMABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLjk3LTUuZ2l0MjAwOTAyMjAARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC45Ny00LmdpdDIwMDkwMjE5AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAuOTctMgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLjk3LTEARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0yLmdpdDIwMDkwMjA3AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMS5naXQyMDA5MDEwMgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuMTIuc3ZuNDMyNgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuMTIuc3ZuNDI5NgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuMTIuc3ZuNDI5NQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuMTIuc3ZuNDI5MwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuMTEuc3ZuNDIyOQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuMTEuc3ZuNDIwMQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuMTEuc3ZuNDE3NQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuMTEuc3ZuNDE3NABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuMTEuc3ZuNDAyMi40AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC4xMS5zdm40MDIyLjMARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjExLnN2bjQwMjIuMgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuMTEuc3ZuNDAyMi4xAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC4xMS5zdm40MDIyAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC4xMS5zdm4zOTMwAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC4xMS5zdm4zOTI3AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC4xMS5zdm4zODQ2AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC4xMS5zdm4zODMwAE1hdHRoaWFzIENsYXNlbiA8bWNsYXNlbkByZWRoYXQuY29tPiAtIDE6MC43LjAtMC4xMC5zdm4zODAxAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC4xMC5zdm4zODAxAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC4xMC5zdm4zNzQ3AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC45LjQuc3ZuMzY3NQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuOS4zLnN2bjM2NzUARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjkuMy5zdm4zNjY5AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC45LjMuc3ZuMzY2NwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuOS4zLnN2bjM2NjUARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjkuMy5zdm4zNjIzAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC45LjIuc3ZuMzYyMwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuOS4yLnN2bjM2MjIARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjkuMi5zdm4zNjIwAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC45LjIuc3ZuMzYxOQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuOS4yLnN2bjM2MTQARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjkuMi5zdm4zNTkwAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC45LjIuc3ZuMzU3OABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuOS4yLnN2bjM1NzEARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjkuMi5zdm4zNTcwAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC45LjIuc3ZuMzU2NgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuOS4xLnN2bjM1NjYARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjkuMS5zdm4zNTQ5AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC45LjEuc3ZuMzU0OABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuOS4xLnN2bjM1NDcARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjkuMS5zdm4zNTI3AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC45LjEuc3ZuMzUyMQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuOS4xLnN2bjM0NzYARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjkuMS5zdm4zNDczAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC45LjEuc3ZuMzQ3MgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuOS4xLnN2bjM0NDAARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjkuMS5zdm4zNDE3AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC44LnN2bjM0MTcARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjguc3ZuMzM3MABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuOC5zdm4zMzY5AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC44LnN2bjMzMTkARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjguc3ZuMzMxMgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuOC5zdm4zMzAyAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC44LnN2bjMyNjEARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjguc3ZuMzIzNQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuOC5zdm4zMjA0AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC44LnN2bjMxODEARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjguc3ZuMzE4MABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuOC5zdm4zMTM4AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC44LnN2bjMxMzQARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjguc3ZuMzEzMwBKZXJlbXkgS2F0eiA8a2F0empAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuOC5zdm4zMTA5AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC42LjYuc3ZuMzEwOQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuNi41LnN2bjMxMDkARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjYuNS5zdm4zMDk2AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC42LjQuc3ZuMzA5NgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuNi4zLnN2bjMwOTYARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjYuMy5zdm4zMDk0AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC42LjIuc3ZuMzA4MABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuNi4xLnN2bjMwMzAARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjUuc3ZuMzAzMABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuNC5zdm4zMDMwAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC40LnN2bjMwMjAARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjMuc3ZuMzAyMABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuMy5zdm4zMDE2AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC4zLnN2bjMwMTQARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjMuc3ZuMzAwOABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuMy5zdm4yOTk1AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC4zLnN2bjI5OTQARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjMuc3ZuMjk4MwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuMy5zdm4yOTcwAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC4zLnN2bjI5NjIARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjMuc3ZuMjk2MQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuMy5zdm4yOTE0AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC4zLnN2bjI5MDcARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjMuc3ZuMjg4NgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuMy5zdm4yODgwAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC4zLnN2bjI4NTIARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjMuc3ZuMjg0OQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNy4wLTAuMy5zdm4yODQ0AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC43LjAtMC4yLnN2bjI4MzMARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjcuMC0wLjEuc3ZuMjczNgBDaHJpc3RvcGhlciBBaWxsb24gPGNhaWxsb25AcmVkaGF0LmNvbT4gMTowLjYuNS05AENocmlzdG9waGVyIEFpbGxvbiA8Y2FpbGxvbkByZWRoYXQuY29tPiAxOjAuNi41LTgARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IDE6MC42LjUtNwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gMTowLjYuNS02AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAxOjAuNi41LTUARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IDE6MC42LjUtNABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gMTowLjYuNS0zAENocmlzdG9waGVyIEFpbGxvbiA8Y2FpbGxvbkByZWRoYXQuY29tPiAxOjAuNi41LTIAQ2hyaXN0b3BoZXIgQWlsbG9uIDxjYWlsbG9uQHJlZGhhdC5jb20+IDE6MC42LjUtMQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNi41LTAuNy5zdm4yNTQ3AE1hdHRoZXcgQmFybmVzICA8bWJhcm5lc0ByZWRoYXQuY29tPiAxOjAuNi41LTAuNi5zdm4yNDc0AE1hdHRoaWFzIENsYXNlbiA8bWNsYXNlbkByZWRoYXQuY29tPiAxOjAuNi41LTAuNS5zdm4yNDc0AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC42LjUtMC40LnN2bjI0NzQAQ2hyaXN0b3BoZXIgQWlsbG9uIDxjYWlsbG9uQHJlZGhhdC5jb20+IC0gMTowLjYuNS0wLjMuY3ZzMjAwNjEwMjUAQ2hyaXN0b3BoZXIgQWlsbG9uIDxjYWlsbG9uQHJlZGhhdC5jb20+IC0gMTowLjYuNS0wLjIuY3ZzMjAwNjEwMjUATWF0dGhpYXMgQ2xhc2VuIDxtY2xhc2VuQHJlZGhhdC5jb20+AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDE6MC42LjUtMC5jdnMyMDA2MTAyNQBDaHJpc3RvcGhlciBBaWxsb24gPGNhaWxsb25AcmVkaGF0LmNvbT4gLSAxOjAuNi40LTYAQ2hyaXN0b3BoZXIgQWlsbG9uIDxjYWlsbG9uQHJlZGhhdC5jb20+IC0gMTowLjYuNC01AEJpbGwgTm90dGluZ2hhbSA8bm90dGluZ0ByZWRoYXQuY29tPiAtIDE6MC42LjQtNABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAxOjAuNi40LTMARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMTowLjYuNC0yAENocmlzdG9waGVyIEFpbGxvbiA8Y2FpbGxvbkByZWRoYXQuY29tPiAtIDAuNy4wLTAuY3ZzMjAwNjA1MjkuNwBSYXkgU3Ryb2RlIDxyc3Ryb2RlQHJlZGhhdC5jb20+IC0gMC43LjAtMC5jdnMyMDA2MDUyOS42AFJheSBTdHJvZGUgPHJzdHJvZGVAcmVkaGF0LmNvbT4gLSAwLjcuMC0wLmN2czIwMDYwNTI5LjUAUmF5IFN0cm9kZSA8cnN0cm9kZUByZWRoYXQuY29tPiAtIDAuNy4wLTAuY3ZzMjAwNjA1MjkuNABKb2huIChKNSkgUGFsbWllcmkgPGpvaG5wQHJlZGhhdC5jb20+IC0gMC43LjAtMC5jdnMyMDA2MDUyOS4zAEpvaG4gKEo1KSBQYWxtaWVyaSA8am9obnBAcmVkaGF0LmNvbT4gLSAwLjcuMC0wLmN2czIwMDYwNTI5LjIASmVzc2UgS2VhdGluZyA8amtlYXRpbmdAcmVkaGF0LmNvbT4gLSAwLjcuMC0wLmN2czIwMDYwNTI5LjEuMQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjcuMC0wLmN2czIwMDYwNTI5AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuNy4wLTAuY3ZzMjAwNjA1MjEAQmlsbCBOb3R0aW5naGFtIDxub3R0aW5nQHJlZGhhdC5jb20+IC0gMC42LjItMy5mYzYASmVyZW15IEthdHogPGthdHpqQHJlZGhhdC5jb20+IC0gMC42LjItMi5mYzYARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC42LjItMQBQZXRlciBKb25lcyA8cGpvbmVzQHJlZGhhdC5jb20+IC0gMC42LjAtMwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gMC42LjAtMgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gMC42LjAtMQBKZXJlbXkgS2F0eiA8a2F0empAcmVkaGF0LmNvbT4gLSAwLjUuMS0xOC5jdnMyMDA2MDMwMgBDaHJpc3RvcGhlciBBaWxsb24gPGNhaWxsb25AcmVkaGF0LmNvbT4ARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IDAuNS4xLTE4LmN2czIwMDYwMzAxAENocmlzdG9waGVyIEFpbGxvbiA8Y2FpbGxvbkByZWRoYXQuY29tPiAwLjUuMS0xNy5jdnMyMDA2MDIyOABDaHJpc3RvcGhlciBBaWxsb24gPGNhaWxsb25AcmVkaGF0LmNvbT4gMC41LjEtMTYuY3ZzMjAwNjAyMjcAQ2hyaXN0b3BoZXIgQWlsbG9uIDxjYWlsbG9uQHJlZGhhdC5jb20+IDAuNS4xLTE1LmN2czIwMDYwMjI3AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29NPiAwLjUuMS0xNC5jdnMyMDA2MDIyMQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gMC41LjEtMTMuY3ZzMjAwNjAyMjEARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IDAuNS4xLTEyLmN2czIwMDYwMjEzAENocmlzdG9waGVyIEFpbGxvbiA8Y2FpbGxvbkByZWRoYXQuY29tPiAwLjUuMS0xMS5jdnMyMDA2MDIwNQBKZXNzZSBLZWF0aW5nIDxqa2VhdGluZ0ByZWRoYXQuY29tPiAwLjUuMS0xMC5jdnMyMDA2MDIwNS4xAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAwLjUuMS0xMC5jdnMyMDA2MDIwNQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gMC41LjEtOS5jdnMyMDA2MDIwMgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gMC41LjEtOC5jdnMyMDA2MDEzMQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gMC41LjEtNy5jdnMyMDA2MDEzMQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gMC41LjEtNi5jdnMyMDA2MDEyNwBKZXNzZSBLZWF0aW5nIDxqa2VhdGluZ0ByZWRoYXQuY29tPgBKb2huIChKNSkgUGFsbWllcmkgPGpvaG5wQHJlZGhhdC5jb20+IC0gMC41LjEtNQBQZXRlciBKb25lcyA8cGpvbmVzQHJlZGhhdC5jb20+IC0gMC41LjEtNABDaHJpc3RvcGhlciBBaWxsb24gPGNhaWxsb25AcmVkaGF0LmNvbT4gLSAwLjUuMS0zAENocmlzdG9waGVyIEFpbGxvbiA8Y2FpbGxvbkByZWRoYXQuY29tPiAtIDAuNS4xLTIAQ2hyaXN0b3BoZXIgQWlsbG9uIDxjYWlsbG9uQHJlZGhhdC5jb20+IC0gMC41LjAtMgBEYW4gV2lsbGlhbXMgPGRjYndAcmVkYWh0LmNvbT4gLSAwLjQuMS01LmN2czIwMDUxMDEwAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuNC4xLTQuY3ZzMjAwNTEwMDkARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC40LjEtMy5jdnMyMDA1MDkyMgBKZXJlbXkgS2F0eiA8a2F0empAcmVkaGF0LmNvbT4gLSAwLjQuMS0yLmN2czIwMDUwOTEyAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuNC4xLTIuY3ZzMjAwNTA4MTkARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC40LjEARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC40LTM2LmN2czIwMDUwODExAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuNC0zNS5jdnMyMDA1MDgxMQBSYXkgU3Ryb2RlICA8cnN0cm9kZUByZWRoYXQuY29tPiAtIDAuNC0zNC5jdnMyMDA1MDcyOQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjQtMzQuY3ZzMjAwNTA2MjkARGF2aWQgWmV1dGhlbiA8ZGF2aWR6QHJlZGhhdC5jb20+IC0gMC40LTMzLmN2czIwMDUwNjI5AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuNC0zMi5jdnMyMDA1MDYxNwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjQtMzEuY3ZzMjAwNTA2MTYARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC40LTMwLmN2czIwMDUwNjE1AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuNC0xNS5jdnMzMDA1MDQwNABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjQtMTQuY3ZzMzAwNTA0MDQARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC40LTEzLmN2czMwMDUwNDA0AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuNC0xMi5jdnMyMDA1MDQwNABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gLSAwLjQtMTEuY3ZzMjAwNTA0MDQARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IC0gMC40LTEwLmN2czIwMDUwNDA0AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAtIDAuNC05LmN2czIwMDUwNDA0AEplcmVteSBLYXR6IDxrYXR6akByZWRoYXQuY29tPiAtIDAuNC04LmN2czIwMDUwNDA0AEplcmVteSBLYXR6IDxrYXR6akByZWRoYXQuY29tPiAtIDAuNC03LmN2czIwMDUwNDA0AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAwLjQtNi5jdnMyMDA1MDQwNABEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gMC40LTUuY3ZzMjAwNTA0MDIAQ2hyaXN0b3BoZXIgQWlsbG9uIDxjYWlsbG9uQHJlZGhhdC5jb20+IDAuNC00LmN2czIwMDUwMzE1AFJheSBTdHJvZGUgPHJzdHJvZGVAcmVkaGF0LmNvbT4gMC40LTMuY3ZzMjAwNTAzMTUAUmF5IFN0cm9kZSA8cnN0cm9kZUByZWRoYXQuY29tPiAwLjQtMi5jdnMyMDA1MDMxNQBSYXkgU3Ryb2RlIDxyc3Ryb2RlQHJlZGhhdC5jb20+IDAuNC0xLmN2czIwMDUwMzE1AFJheSBTdHJvZGUgPHJzdHJvZGVAcmVkaGF0LmNvbT4gMC40LTEuY3ZzMjAwNTAzMDcARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IDAuMy40LTEuY3ZzMjAwNTAzMDQARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IDAuMy4zLTIuY3ZzMjAwNTAyMjIARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IDAuMy4zLTIuY3ZzMjAwNTAyMTQueC4xAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAwLjMuMy0yLmN2czIwMDUwMjE0AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAwLjMuMy0xLmN2czIwMDUwMjAyAERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAwLjMuMy0xLmN2czIwMDUwMTI1AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAwLjMuMy0xLmN2czIwMDUwMTI0AFRoYW4gTmdvIDx0aGFuQHJlZGhhdC5jb20+IDAuMy4zLTEuY3ZzMjAwNTAxMTIuNAA8ZGNid0ByZWRoYXQuY29tPiAtIDAuMy4zLTEuY3ZzMjAwNTAxMTgAPGRjYndAcmVkaGF0LmNvbT4gLSAwLjMuMy0xLmN2czIwMDUwMTEyADxkY2J3QHJlZGhhdC5jb20+IC0gMC4zLjItNC4zLmN2czIwMDQxMjA4ADxkY2J3QHJlZGhhdC5jb20+IC0gMC4zLjItMy5jdnMyMDA0MTExNwA8ZGNid0ByZWRoYXQuY29tPiAtIDAuMy4yLTIuY3ZzMjAwNDExMTUAPGRjYndAcmVkaGF0LmNvbT4gLSAwLjMuMi0yLmN2czIwMDQxMDI5ADxkY2J3QHJlZGhhdC5jb20+IC0gMC4zLjEtMgA8anJiQHJlZGhhdC5jb20+IC0gMC4zLjEtMQBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gMC4zLTEARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IDAuMi00AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAwLjItMwBEYW4gV2lsbGlhbXMgPGRjYndAcmVkaGF0LmNvbT4gMC4yLTIARGFuIFdpbGxpYW1zIDxkY2J3QHJlZGhhdC5jb20+IDAuMi0xAEZsb3JpYW4gTGEgUm9jaGUgPEZsb3JpYW4uTGFSb2NoZUByZWRoYXQuZGU+AERhbiBXaWxsaWFtcyA8ZGNid0ByZWRoYXQuY29tPiAwLjEtMwAtIGluaXRyZDogYWNjZXB0IG1hYyBhZGRyZXNzIGFzIGludGVyZmFjZSBzcGVjaWZpZXIgKHJoICMxODc5Nzk1KQotIGluaXRyZDogZml4IHBhcnNpbmcgSVB2NiBwcmVmaXggbGVuZ3RoIChyaCAjMTg3OTc5NSkALSBkaGNwOiBhZGQgZGhjcC12ZW5kb3ItY2xhc3MtaWRlbnRpZmllciBvcHRpb24gKHJoICMxODcxMDQyKQotIGluaXRyZDogcGFyc2UgJ3JkLm5ldC5kaGNwLnZlbmRvci1jbGFzcycga2VybmVsIGNtZGxpbmUgYXJnIChyaCAjMTg3MjI5OSkALSBjb3JlOiBmaXggaGFuZGxpbmcgb2YgbG9jYWwgcm91dGVzIGFzIGRlZmF1bHQgcm91dGUgYW5kIG9uIEQtQnVzIChyaCAjMTg2ODk4MikALSBjb3JlOiBmaXggd2FpdC1kZXZpY2UtdGltZW91dCByYWNlIGFuZCBzdXBwb3J0IGdlbmVyYWwgZGV2aWNlIG1hdGNoZXMgKHJoICMxODUzMzQ4KQAtIGJvbmQ6IGZpeCBSZWFwcGx5IGRvZXMgbm90IHVwZGF0ZSBib25kIG9wdGlvbnMgKHJoICMxODQ3ODE0KQotIGRoY3A6IHN1cHBvcnQgREhDUHY2IGZxZG5fZnFkbiBvcHRpb24gZm9yIGhvc3RuYW1lIChyaCAjMTg1ODM0NCkALSBjb3JlOiBmaXggbWFuYWdpbmcgZGV2aWNlcyBhZnRlciByZXN1bWluZyBmcm9tIHNsZWVwIChyaCAjMTg1NTU2MykKLSBkaGNwOiBmaXggQlBGIGZpbHRlciBmb3IgaW50ZXJuYWwgY2xpZW50IG9uIGJpZyBlbmRpYW4gYXJjaCAocmggIzE4NjE0ODgpCi0gY29yZTogc3VwcG9ydCB3YXJuaW5nIGxvZyBzZXR0aW5nIElQdjYgTVRVIHdpdGggSVB2NiBkaXNhYmxlZCAocmggIzE4NDA5ODkpCi0gd2lmaTogZml4IGNyYXNoIHBhcnNpbmcgaW5jb21wbGV0ZSBCU1MgaW5mbyAocmggIzE4NjYzOTUpAC0gY29yZTogZml4IGdlbmVyYXRpb24gb2YgbG9jYWwgcm91dGVzIGZvciBWUkYgZGV2aWNlcyAocmggIzE4NTcxMzMpCi0gdGVhbTogZml4IGNyYXNoIG9uIGZhaWx1cmUgdG8gY29ubmVjdCB0byB0ZWFtZCAocmggIzE4NTY3MjMpCi0gY29yZTogZml4IGRldGVjdGluZyBmYWlsdXJlIG9mIG1hc3RlciBhY3RpdmUtY29ubmVjdGlvbiAocmggIzE4NDUwMTgpCi0gY29yZTogZml4IHdhcm5pbmcgYWJvdXQgc2V0dGluZyBhY3RpdmVfc2xhdmUgb2YgYm9uZCB3aGVuIGFjdGl2YXRpbmcgbWFzdGVyIChyaCAjMTg1ODMyNikKLSBpbXBvcnQgdHJhbnNsYXRpb25zIChyaCAjMTgyMDU1MikALSB1cGRhdGUgdG8gMS4yNi4wCi0gZGV2aWNlOiByZXNldCBTUi1JT1YgcGFyYW1ldGVycyBvbiBhY3RpdmF0aW9uIGZhaWx1cmUgKHJoICMxODE5NTg3KQotIGluaXRyZDogZW5hYmxlIGlwdjYubWV0aG9kPWF1dG8gd2l0aCBpcD1kaGNwNiAocmggIzE4NTQzMjMpCi0gY29yZTogYWRkICJubS1zaGFyZWQiIHpvbmUgZm9yIGZpcmV3YWxsZCBmb3Igc2hhcmVkIG1vZGUgKHJoICMxODM0OTA3KQotIHBwcDogZml4IHRha2luZyBjb250cm9sIG9mIGxpbmsgKHJoICMxODQ5Mzg2KQAtIGRldmljZTogcmVzdGFydCBESENQIG9ubHkgZm9yIGRldmljZXMgdGhhdCBhcmUgYWN0aXZlIG9yIGFjdGl2YXRpbmcgKHJoICMxODUyNjEyKQotIGluaXRyZDogZml4IGdlbmVyYXRpbmcgZGVmYXVsdCBCT09USUY9IGNvbm5lY3Rpb24gKHJoICMxODUzMjc3KQotIG92czogZml4IHJhY2UgY29uZGl0aW9uIHdoZW4gc2V0dGluZyBNQUMgYWRkcmVzcyBmb3Igb3ZzIGludGVyZmFjZXMgKHJoICMxODUyMTA2KQAtIHVwZGF0ZSB0byAxLjI2LXJjMiAoMS4yNS45MSkKLSBpbml0cmQ6IHNldCBpcHY2Lm1ldGhvZD1hdXRvIHdoZW4gdXNpbmcgSVB2NCBzdGF0aWMgY29uZmlndXJhdGlvbiAocmggIzE4NDg5NDMpCi0gY2xvdWQtc2V0dXA6IGFkZCBzdXBwb3J0IGZvciBHb29nbGUgQ2xvdWQgbG9hZC1iYWxhbmNpbmcgcm91dGVzIChyaCAjMTgyMTc4NykALSB1cGRhdGUgdG8gMS4yNi1yYzEgKDEuMjUuOTApCi0gY29yZTogc3VwcG9ydCBtb3JlIHRjIHFkaXNjcyAodGJmIGFuZCBzZnEpIChyaCAjMTU0NjgwMikKLSBjb3JlOiBzdXBwb3J0IG1hdGNoIGRldmljZXMgZm9yIGNvbm5lY3Rpb24gcHJvZmlsZSBieSBQQ0kgYWRkcmVzcyAoSURfUEFUSCkgKHJoICMxNjczMzIxKQotIG92czogZml4IHBlZXIgcHJvcGVydHkgZm9yIE9WUyBwYXRjaCBpbnRlcmZhY2UgKHJoICMxODQ1MjE2KQotIGRvYzogYWRkIG1hbnVhbCBwYWdlcyBubS1zZXR0aW5ncy1kYnVzIGFuZCBubS1zZXR0aW5ncy1ubWNsaSAocmggIzE2MTQ3MjYpCi0gd2lmaTogZG9uJ3QgYmxvY2sgYXV0b2Nvbm5lY3QgZm9yIHByb2ZpbGVzIHRoYXQgbmV2ZXIgc3VjY2VlZGVkIHRvIGNvbm5lY3QgKHJoICMxNzgxMjUzKQotIGRidXMsbm1jbGk6IGhpZ2hsaWdodCBleHRlcm5hbGx5IG1hbmFnZWQgZGV2aWNlcyAocmggIzE4MTYyMDIpAC0gdXBkYXRlIHRvIDEuMjUuMiAoZGV2ZWxvcG1lbnQpCi0gc3VwcG9ydCBldGh0b29sIGNvYWxlc2NlIGFuZCByaW5nIG9wdGlvbnMgKHJoICMxNjE0NzAwKQotIGNvcmU6IGltcHJvdmUgc3luY2hyb25pemF0aW9uIG9mIHFkaXNjcyB3aXRoIGtlcm5lbCAocmggIzE4MTU4NzUpCi0gdGVhbTogc3VwcG9ydCBydW5uaW5nIHdpdGhvdXQgRC1CdXMgKHJoICMxNzg0MzYzKQotIGNvcmU6IGZpeCBwb3RlbnRpYWwgY3Jhc2ggd2hlbiBhdXRvYWN0aXZhdGluZyBjaGlsZCBjb25uZWN0aW9ucyAocmggIzE3NzgwNzMpCi0gZXRoZXJuZXQ6IHJlc2V0IG9yaWdpbmFsIGF1dG9uZWdvdGlhdGlvbi9zcGVlZC9kdXBsZXggc2V0dGluZ3Mgb24gZGVhY3RpdmF0aW9uIChyaCAjMTgwNzE3MSkKLSBjb3JlOiBmaXggc2V0dGluZyBJUHY2IHRva2VuIGluIGtlcm5lbCAocmggIzE4MTk2ODApAC0gdXBkYXRlIHRvIDEuMjUuMSAoZGV2ZWxvcG1lbnQpCi0gaW1wcm92ZSBkb2N1bWVudGF0aW9uIChyaCAjMTY1MTU5NCwgcmggIzE4MTkyNTkpCi0gdnJmOiBhZGQgc3VwcG9ydCAocmggIzE3NzM5MDgpCi0gYm9uZDogaW1wcm92ZSBzZXR0aW5nIGRlZmF1bHQgb3B0aW9ucyBmb3IgbWlpbW9uIGFuZCB1cGRlbGF5IChyaCAjMTgwNTE4NCwgcmggIzE4MDY1NDkpCi0gYmx1ZXRvb3RoOiBmaXggY3Jhc2ggaGFuZGxpbmcgRFVOIG1vZGVtIChyaCAjMTgyNjYzNSkKLSBjb3JlOiBmaXggcG90ZW50aWFsIGluZmluaXRlIGxvb3Agd2l0aCBwcmVmaXggZGVsZWdhdGlvbiAocmggIzE0ODgwMzApCi0gaW5pdHJkOiBmaXhlcyBmb3IgcnVubmluZyBOZXR3b3JrTWFuYWdlciBpbiBpbml0cmQgKHJoICMxNjI3ODIwLCAjMTcxMDkzNSwgIzE3NDQ5MzUsICMxNzcxNzkyKQotIGNvcmU6IHByZXZlbnQgbXVsdGlwbGUgYXR0ZW1wdHMgdG8gY3JlYXRlIGRlZmF1bHQgd2lyZWQgY29ubmVjdGlvbiAocmggIzE2ODc5MzcpCi0gYnJpZGdlOiBzdXBwb3J0IG1vcmUgb3B0aW9ucyAocmggIzE3NTU3NjgpCi0gbGlibm0sZGJ1czogZXhwb3NlIEh3QWRkcmVzcyBmb3IgYWxsIGRldmljZSB0eXBlcyAocmggIzE3ODY5MzcpCi0gY29yZTogZml4IHJvdXRlIHByaW9yaXR5IGZvciBJUHY2IChyaCAjMTgxNDU1NykKLSBjb3JlOiBmaXggY3Jhc2ggZHVyaW5nIHJlYXBwbHkgKHJoICMxODE2MDY3KQotIGNvcmU6IGNsZWFyIElQIGFkZHJlc3MgZnJvbSBicmlkZ2Ugc2xhdmUgKHJoICMxODE2NTE3KQotIG92czogc3VwcG9ydCBjaGFuZ2luZyBNVFUgb2YgT1ZTIGludGVyZmFjZXMgKHJoICMxODIwMDUyKQotIG5tLW9ubGluZTogc3VwcG9ydCBzZXR0aW5nIHRpbWVvdXQgZm9yIE5ldHdvcmtNYW5hZ2VyLXdhaXQtb25saW5lIChyaCAjMTgyODQ1OCkALSBjb3JlOiBmaXggbGVha2luZyBkZXZpY2Ugc3RhdGUgZmlsZXMgaW4gL3J1biAocmggIzE4MTAxNTMpCi0gZGhjcDogZml4IGNyYXNoIGluIG5ldHRvb2xzIGNsaWVudCB3aGVuIGxlYWtpbmcgR1NvdXJjZSAocmggIzE4MTAxODgpAC0gZGhjcDoga2VlcCB0cnlpbmcgYWZ0ZXIgYSBzZW5kIGZhaWx1cmUgKHJoICMxODA2NTE2KQotIG92czogZmFpbCBwb3J0IGVuc2xhdmVtZW50IHdoZW4gdGhlIGJyaWRnZSBpcyBub3QgZm91bmQgKHJoICMxNzk3Njk2KQAtIGJvbmQ6IGZpeCBzZXR0aW5nIGFycF92YWxpZGF0ZSBvcHRpb24gZm9yIG90aGVyIGJvbmRpbmcgbW9kZXMgKHJoICMxNzg5NDM3KQAtIFVwZGF0ZSB0byAxLjIyLjgKLSBBZGRlZCBjb25maWd1cmF0aW9uIG9wdGlvbiB0byBjdXN0b21pemUgSVB2NiBSQSB0aW1lb3V0IChyaCAjMTgwMTE1OCkKLSBSZW1vdmVkIGxlbmd0aCBsaW1pdGF0aW9uIGZvciBPVlMgQnJpZGdlLCBQYXRjaGVzIGFuZCBJbnRlcmZhY2VzIChvbmx5IFBhdGNoIHR5cGVzKSBuYW1lcyAocmggIzE3ODg0MzIpCi0gUmV3b3JrZWQgYXN5bmNocm9ub3VzIGRlYWN0aXZhdGlvbiBvZiBPVlMgaW50ZXJmYWNlcyAocmggIzE3ODc5ODksIHJoICMxNzgyNzAxKQotIEZpeGVkIGZhaWx1cmUgd2hlbiBjcmVhdGluZyB0ZWFtIGludGVyZmFjZXMgKHJoICMxNzk4OTQ3KQotIGlmY2ZnLXJoOiBmaXggY2xlYXJpbmcgb3ZzIHNsYXZlIHR5cGUgZnJvbSBpZmNmZy1yaCBmaWxlIChyaCAjMTgwNDE2NykKLSBGaXhlZCBidWcgY2F1c2luZyB2aXJ0dWFsIGRldmljZXMgdG8gbm90IGJlIGF2YWlsYWJsZSBhZnRlciBBZGRDb25uZWN0aW9uKCkvVXBkYXRlKCkgKHJoICMxODA0MzUwKQAtIFVwZGF0ZSB0byAxLjIyLjYKLSBubS1kZXZpY2U6IGFkZCBuZXcgcGVuZGluZyBhY3Rpb24gdG8ga2VlcCB0aGUgZGV2aWNlIGJ1c3kgd2hlbiBpbiBiZXR3ZWVuIHN0YXRlcyAocmggIzE3NTk5NTYpCi0gY2xvdWQtc2V0dXA6IGF2b2lkIHVuc3VwcG9ydGVkIHNldHRpbmdzIGluIHN5c3RlbWQgc2VydmljZSB1bml0IChyaCAjMTc5MTc1OCkKLSBkbyBub3QgY3JlYXRlIHZpcnR1YWwgZGV2aWNlIGlmIG1hc3RlciBpcyBub3QgcHJlc2VudCAocmggIzE3OTU5MTkpCi0gYWxsb3cgSVB2NiBSQSB0aW1lb3V0IHRvIGJlIHNldCB0byBhIHZhbHVlIGhpZ2hlciB0aGFuIDEyMCBzZWNvbmRzIChyaCAjMTc5NTk1NykKLSBmaXggYmVoYXZpb3VyIHdoZW4gJ2lwdjQuZGhjcC10aW1lb3V0JyBvcHRpb24gaXMgc2V0IHRvICdpbmZpbml0eScgKHJoICMxNzkxMzc4KQAtIFVwZGF0ZSB0byAxLjIyLjQKLSBkaGNwOiBmaXggYmVoYXZpb3Igb2YgaW50ZXJuYWwgREhDUCBjbGllbnQgd2hlbiB0aGUgc2VydmVyIHNlbmRzIGEgTkFLIChyaCAjMTc4NzIxOSkALSBVcGRhdGUgdG8gMS4yMi4yCi0gY29yZSxsaWJubTogZXhwb3NlIGNhcGFiaWxpdHkgZm9yIE9WUyBzdXBwb3J0IChyaCAjMTc4NTE0NykKLSBkaGNwOiB2YXJpb3VzIGJ1Z2ZpeGVzIGZvciBuZXR0b29scyBuLWRoY3A0IHBsdWdpbgAtIGRoY3A6IGZpeCBwYXJzaW5nIG9mIEROUyBzZWFyY2ggZG9tYWluIHdpdGggbmV0dG9vbHMgcGx1Z2luIChyaCAjMTc4Mzk4MSkALSBVcGRhdGUgdG8gMS4yMi4wCi0gc3VwcG9ydCBtYWluLmF1dGgtcG9sa2l0PXJvb3Qtb25seSBzZXR0aW5nIHRvIGFsbG93IHJvb3Qgb25seSAocmggIzE3NjIwMTEpAC0gVXBkYXRlIHRvIDEuMjItcmMxICgxLjIxLjkwKQotIGxhcmdlIGludGVybmFsIHJld29yayBvZiBsaWJubSdzIE5NQ2xpZW50Ci0gZGhjcDogc3dpdGNoIGltcGxlbWVudGF0aW9uIG9mICJpbnRlcm5hbCIgREhDUCB0byBuZXR0b29scycgbi1kaGNwNAotIGFkZCBzdXBwb3J0IGZvciBjYXJyaWVyIHN0YXRlIG9mIGRldmljZXMgb24gRC1CdXMvbGlibm0gKHJoICMxNzIyMDI0KQotIGNsb3VkLXNldHVwOiBhZGQgaW5pdGlhbCBhbmQgZXhwZXJpbWVudGFsIHRvb2wgZm9yIGNvbmZpZ3VyaW5nIGluIGNsb3VkIChyaCAjMTY0MjQ2MSkKLSBkaGNwOiBzdXBwb3J0IGNvbmZpZ3VyaW5nIEZRRE4gaG9zdG5hbWUgZmxhZ3MgKHJoICMxNjQ5MzY4KQAtIFVwZGF0ZSB0byAxLjIxLjMsIGEgZGV2ZWxvcG1lbnQgc25hcHNob3Qgb2YgTmV0d29ya01hbmFnZXIgMS4yMgotIHN1cHBvcnQgY29uZmlndXJpbmcgZGVmYXVsdCByb3V0ZSBhcyBhIHJlZ3VsYXIsIHN0YXRpYyByb3V0ZSAocmggIzE3MTQ0MzgpAC0gaW5pdHJkOiByZS1lbmFibGUgdGhlIGdlbmVyYXRvciAocmggIzE2MjYzNDgpAC0gd2lmaTogZGV0ZWN0IEZUIHN1cHBvcnQgcGVyIGRldmljZSB0byBmaXggaXNzdWVzIHdpdGggZHJpdmVyIHN1cHBvcnQgKHJoICMxNzQzNzMwKQotIGRvYzogZml4IGRlZmF1bHQgdmFsdWVzIGluIHByZS1nZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiAocmggIzE3Mzc5NDUpAC0gSW1wb3J0IHRyYW5zbGF0aW9ucyAocmggIzE2ODk5OTkpAC0gVXBkYXRlIHRvIDEuMjAuMCByZWxlYXNlCi0gZml4IGxpY2Vuc2UgY29tbWVudHMgZm9yIFJQTSBwYWNrYWdlIChyaCAjMTcyMzM5NSkKLSBkaGNwOiBkaXNhYmxlIGV4cGVyaW1lbnRhbCBuZXR0b29scyBESENQIHBsdWdpbgAtIFVwZGF0ZSB0byAxLjIwLXJjMSBzbmFwc2hvdAotIHNldHRpbmdzOiBzdXBwb3J0IHJlYWQtb25seSBkaXJlY3RvcnkgZm9yIGtleWZpbGUgcHJvZmlsZXMgKHJoICMxNjc0NTQ1KQotIHNldHRpbmdzOiBhZGQgQWRkQ29ubmVjdGlvbjIgRC1CdXMgQVBJIHRvIHN1cHByZXNzIGF1dG9jb25uZWN0IChyaCAjMTY3NzA2OCkKLSBzZXR0aW5nczogYWRkIG5vLXJlYXBwbHkgZmxhdCB0byBVcGRhdGUyIEQtQnVzIEFQSSAocmggIzE2NzcwNzApCi0gb3BlbnZzd2l0Y2g6IGRvbid0IHJlbGVhc2Ugc2xhdmVzIG9uIHF1aXQgKHJoICMxNzMzNzA5KQotIGRoY3A6IGV4cG9zZSBwcml2YXRlIG9wdGlvbnMgZm9yIGludGVybmFsIERIQ1AgcGx1Z2luIChyaCAjMTY2MzI1MykKLSBkZXZpY2U6IGZpeCByb3V0ZSB0YWJsZSBzZXR0aW5nIHdoZW4gcmUtYWN0aXZhdGluZyBkZXZpY2UgKHJoICMxNzE5MzE4KQotIG1hbjogY2xhcmlmeSBleGFtcGxlIGluIG5tLW9wZW52c3dpdGNoIG1hbnVhbCBwYWdlIChyaCAjMTYzODAzOCkKLSBtYW46IHZhcmlvdXMgaW1wcm92ZW1lbnRzIG9mIG1hbnVhbCBwYWdlcyAocmggIzE2MTI1NTQpAC0gaW5pdHJkOiBkaXNhYmxlIHRoZSBnZW5lcmF0b3IgYWdhaW4ALSBVcGRhdGUgdG8gYSBuZXdlciAxLjIwIHNuYXBzaG90Ci0gb3ZzOiBzdXBwb3J0IGRwZGsgaW50ZXJmYWNlcyAocmggIzE2MTI1MDMpCi0gbGlibm0tY29yZTogY2hhbmdlIHVuc3VwcG9ydGVkIG1vZGVzIGZvciBhcnBfaXBfdGFyZ2V0cyBib25kIG9wdGlvbiAocmggIzE3MTgxNzMpCi0gaXB2NjogYWRkICdkaXNhYmxlZCcgbWV0aG9kIChyaCAjMTY0Mzg0MSkKLSBkZXZpY2U6IGZpeCBtYXRjaGluZyBwYXJlbnQgZGV2aWNlIGJ5IGNvbm5lY3Rpb24gVVVJRCAocmggIzE3MTY0MzgpCi0gY2xpOiBmaXggZGVmYXVsdCB2YWx1ZSBmb3IgdGVhbS5ydW5uZXItbWluLXBvcnRzIChyaCAjMTcxNjk4NykKLSBpbml0cmQ6IHJlLWVuYWJsZSB0aGUgZ2VuZXJhdG9yIChyaCAjMTYyNjM0OCkALSBVcGRhdGUgdG8gYSAxLjIwIHNuYXBzaG90Ci0gY29yZTogZml4IGEgcG9zc2libGUgY3Jhc2ggb24gZGV2aWNlIHJlbW92YWwgKHJoICMxNjU5NzkwKQotIGNvcmU6IGZpeCBhdXRvbWF0aWMgYWN0aXZhdGlvbiBvZiBzb2Z0d2FyZSBkZXZpZWNzIChyaCAjMTY2Nzg3NCkKLSB0ZWFtOiB1c2Ugc3RyaWN0IEpTT04gcGFyc2luZyBmb3IgY29uZmlndXJhdGlvbiAocmggIzE2OTE2MTkpCi0gdGVhbTogZG9uJ3Qga2lsbCB0ZWFtZCBmb3IgZXh0ZXJuYWwgZGV2aWNlcyAocmggIzE2OTMxNDIpCi0gbG9nZ2luZzogZG9uJ3QgbWlzdXNlIFNZU0xPR19GQUNJTElUWSBmaWVsZCBpbiBqb3VybmFsIChyaCAjMTcwOTc0MSkALSBjbGllbnRzOiBmaXggc3RyaW5nIGxpc3Qgc2V0dGVyIChyaCAjMTY3MTIwMCkALSBkZXZpY2U6IGltcHJvdmUgYXNzdW1pbmcgYnJpZGdlcyBvbiBzdGFydHVwIChyaCAjMTU5MzkzOSkALSBkaGNwOiBmaXggY2xpZW50LWlkIGFuZCBEVUlEIGZvciBpbmZpbmliYW5kICgyKSAocmggIzE2NTgwNTcpAC0gZGV2aWNlOiBlbnN1cmUgSVAgY29uZmlndXJhdGlvbiBpcyByZXN0b3JlZCB3aGVuIGxpbmsgZ29lcyB1cCAocmggIzE2MzY3MTUpCi0gZGhjcDogZml4IGNsaWVudC1pZCBhbmQgRFVJRCBmb3IgaW5maW5pYmFuZCAocmggIzE2NTgwNTcpCi0gZGhjcDogY2hhbmdlIGludGVybmFsIERIQ1AgcGx1Z2luJ3MgaXB2NC5kaGNwLWNsaWVudC1pZCBzZXR0aW5nIHRvICJtYWMiIChyaCAjMTY2MTE2NSkALSBpZmNmZy1yaDogZml4IHJlYWRpbmcgU1ItSU9WIHNldHRpbmdzCi0gZGhjcDogc3VwcG9ydCBjbGllbnQtaWQgYW5kIERVSUQgZm9yIGluZmluaWJhbmQgKHJoICMxNjU4MDU3KQAtIGRoY3A6IGZpeCBkZWZhdWx0IGNsaWVudC1pZCBmb3IgTmV0d29ya01hbmFnZXItY29uZmlnLXNlcnZlciAocmggIzE2NTgwNTcpCi0gY29ubmVjdGl2aXR5OiBmaXggY3Jhc2ggYW5kIHBvcnRhbCBkZXRlY3Rpb24gKHJoICMxNjU4MjE3KQotIGNvcmU6IGNvbWJpbmUgc2VjcmV0LWtleSB3aXRoIG1hY2hpbmUtaWQgZm9yIGhvc3QgaWRlbnRpdHkgKHJoICMxNjQyMDIzKQotIFNSLUlPViByZWxhdGVkIGZpeGVzIChyaCAjMTY1MTU3OCwgcmggIzE2NTE1NzYsIHJoICMxNjUxOTc5KQotIGNvcmU6IGZpeCB1cGRhdGluZyBhZ2VudC1vd25lZCBzZWNyZXRzIChyaCAjMTY1ODc3MSkKLSBjb3JlOiBubyBsb25nZXIgc2V0IHJwX2ZpbHRlciBzeXNjdGwgKHJoICMxNjUxMDk3KQotIGRldmljZTogZG9uJ3QgdGFrZSBkZXZpY2UgZG93biB3aGVuIGNoYW5naW5nIE1BQyBhZGRyZXNzIChyaCAjMTY1OTA2MykKLSBkb2M6IHVzZSBwcmVnZW5lcmF0ZWQgbWFudWFsIHBhZ2VzIGFuZCBndGstZG9jIGZyb20gc291cmNlIHRhcmJhbGwALSBVcGRhdGUgdHJhbnNsYXRpb25zIChyaCAjMTYwODMyMykALSBkZXZpY2U6IGltcHJvdmUgYXV0byBzZWxlY3Rpb24gb2YgZGV2aWNlIHdoZW4gYWN0aXZhdGluZyBwcm9maWxlIChyaCAjMTYzOTI1NCkALSBkaGNwOiBmaXggb3V0LW9mLWJvdW5kcyBoZWFwIHdyaXRlIGZvciBESENQdjYgd2l0aCBpbnRlcm5hbCBwbHVnaW4gKENWRS0yMDE4LTE1Njg4KQotIGRoY3A6IHJldmVydCBsZXR0aW5nIGludGVybmFsIERIQ1AgZ2VuZXJhdGUgZGVmYXVsdCBjbGllbnQtaWQgYmFzZWQgb24gTUFDIGFkZHJlc3MgKHJoICMxNjQwNDY0KQotIGRoY3A6IHN1cHBvcnQgImR1aWQiIHNldHRpbmcgZm9yIGlwdjQuZGhjcC1jbGllbnQtaWQKLSBkaGNwOiBzdXBwb3J0ICIke01BQ30iIGlkZW50aWZpZXIgZm9yIGNvbm5lY3Rpb24uc3RhYmxlLWlkCi0gZGhjcDogc3VwcG9ydCBkaGNwLXBsdWdpbiBkZXZpY2Ugc3BlYyBmb3IgbWF0Y2hpbmcgZGV2aWNlcyBpbiBOZXR3b3JrTWFuYWdlci5jb25mCi0gZGhjcDogaW5zdGFsbCBjb25maWd1cmF0aW9uIHNuaXBwZXQgaW4gY29uZmlnLXNlcnZlciBwYWNrYWdlIGZvciBpcHY0LmRoY3AtY2xpZW50LWlkPW1hYyAocmggIzE2NDA0OTQpCi0gZG5zOiByZW1vdmUgbGltaXRhdGlvbiBmb3Igc2l4IEROUyBzZWFyY2ggZW50cmllcyAocmggIzE2NDk3MDQpCi0gbGlibm06IGZpeCBjcmFzaCBjYW5jZWxsaW5nIGFjdGl2YXRpb24gZnJvbSB3aXRoaW4gY2FsbGJhY2sgKHJoICMxNjQzMDg1KQAtIFVwZGF0ZSB0cmFuc2xhdGlvbnMgKHJoICMxNjA4MzIzKQAtIERvbid0IGRlcGVuZCBvbiBvcGVudnN3aXRjaCAocmggIzE2MjkxNzgpCi0gZGV2aWNlOiBkb24ndCByZW1vdmUgcm91dGVzIHdoZW4gdGhlIGludGVyZmFjZSBpcyBkb3duIChyaCAjMTYzNjcxNSkALSBkaGNwOiBsZXQgaW50ZXJuYWwgREhDUCBnZW5lcmF0ZSBkZWZhdWx0IGNsaWVudC1pZCBiYXNlZCBvbiBNQUMgYWRkcmVzcyAoMikALSBkaGNwOiBsZXQgaW50ZXJuYWwgREhDUCBnZW5lcmF0ZSBkZWZhdWx0IGNsaWVudC1pZCBiYXNlZCBvbiBNQUMgYWRkcmVzcwAtIFVwZGF0ZSB0byAxLjE0LjAgcmVsZWFzZQAtIGRoY3A6IHN3aXRjaCBkZWZhdWx0IERIQ1AgcGx1Z2luIGZyb20gZGhjbGllbnQgdG8gaW50ZXJuYWwgKHJoICMxNTcxNjU1KQAtIFVwZGF0ZSB0byAxLjEzLjMsIGEgZGV2ZWxvcG1lbnQgc25hcHNob3Qgb2YgTmV0d29ya01hbmFnZXIgMS4xNAAtIFVwZGF0ZSB0byAxLjEzLjIsIGEgZGV2ZWxvcG1lbnQgc25hcHNob3Qgb2YgTmV0d29ya01hbmFnZXIgMS4xNAAtIFVwZGF0ZSB0byAxLjEzLjAsIGEgZGV2ZWxvcG1lbnQgc25hcHNob3Qgb2YgTmV0d29ya01hbmFnZXIgMS4xNAAtIFVwZGF0ZSB0byAxLjExLjQsIGEgZGV2ZWxvcG1lbnQgc25hcHNob3Qgb2YgTmV0d29ya01hbmFnZXIgMS4xMgotIFN3aXRjaCB0byBQeXRob24gMy1vbmx5IGJ1aWxkIHJvb3QALSBjb3JlOiB1c2UgZ251dGxzIGNyeXB0byBsaWJyYXJ5IGluc3RlYWQgb2YgbnNzIChyaCAjMTU4MTY5MykALSBjb3JlOiBmaXggZXJyb3IgZGVzdHJveWluZyBjaGVja3BvaW50cyAocmgjMTU3NDU2NSkALSBVcGRhdGUgdG8gMS4xMS4zIHJlbGVhc2UALSBVcGRhdGUgdG8gMS4xMC4yIHJlbGVhc2UALSBBcHBseSBwYXRjaCBmcm9tIHByZXZpb3VzIGNvbW1pdAAtIHN5c3RlbWQ6IGxldCBOTS13LW8uc2VydmljZSByZXF1aXJlIE5ldHdvcmtNYW5hZ2VyIHNlcnZpY2UgKHJoICMxNDUyODY2KQotIHBsYXRmb3JtOiByZWFsbHkgdHJlYXQgZHNhIGRldmljZXMgYXMgcmVndWxhciB3aXJlZCBldGhlcm5ldCAocmggIzEzNzEyODkpCi0gbGlibm06IGZpeCBhY2Nlc3NpbmcgZW5hYmxlZCBhbmQgbWV0ZXJlZCBwcm9wZXJ0aWVzAC0gcGxhdGZvcm06IHRyZWF0IGRzYSBkZXZpY2VzIGFzIHJlZ3VsYXIgd2lyZWQgZXRoZXJuZXQgKHJoICMxMzcxMjg5KQAtIGRldmljZTogZml4IGZyb3plbiBub3RpZnkgc2lnbmFscyBvbiB1bnJlYWxpemUgZXJyb3IgcGF0aAotIGRldmljZTogZml4IGRlbGF5IHN0YXJ0dXAgY29tcGxldGUgZm9yIHVucmVhbGl6ZWQgZGV2aWNlcwotIGtleWZpbGU6IGZpeCBoYW5kbGluZyByb3V0ZXMgd2l0aCBtZXRyaWMgemVybwAtIGNsaTogZml4IGNyYXNoIGluIGludGVyYWN0aXZlIG1vZGUgZm9yICJkZXNjcmliZSAuIgotIGxpYm5tL3t2cG4scmVtb3RlfS1jb25uZWN0aW9uOiBkaXNjb25uZWN0IHNpZ25hbCBoYW5kbGVycyB3aGVuIGRpc3Bvc2VkCi0gbGlibm0vbWFuYWdlcjogZGlzY29ubmVjdCBmcm9tIHNpZ25hbHMgb24gdGhlIHByb3h5IHdoZW4gd2UncmUgZGlzcG9zZWQALSBlbmFibGUgTmV0d29ya01hbmFnZXItd2FpdC1vbmxpbmUuc2VydmljZSBvbiBwYWNrYWdlIHVwZ3JhZGUgKHJoIzE0NTU3MDQpAC0gVXBkYXRlIHRvIDEuOC40IHJlbGVhc2UKLSBkb24ndCBpbnN0YWxsIE5ldHdvcmtNYW5hZ2VyLXdhaXQtb25saW5lIGluIG5ldHdvcmstb25saW5lLnRhcmdldC53YW50cyAocmgjMTQ1NTcwNCkALSBSZWJ1aWx0IGZvciBodHRwczovL2ZlZG9yYXByb2plY3Qub3JnL3dpa2kvRmVkb3JhXzI3X0JpbnV0aWxzX01hc3NfUmVidWlsZAAtIFJlYnVpbHQgZm9yIGh0dHBzOi8vZmVkb3JhcHJvamVjdC5vcmcvd2lraS9GZWRvcmFfMjdfTWFzc19SZWJ1aWxkAC0gcHJvdmlkZSBOZXR3b3JrTWFuYWdlci1kZXZlbAAtIE5ldHdvcmtNYW5hZ2VyLXdpZmkgYW5kIE5ldHdvcmtNYW5hZ2VyLWdsaWItZGV2ZWwgc2hvdWxkIHJlcXVpcmUKICBOZXR3b3JrTWFuYWdlciwgbm90IHByb3ZpZGUgaXQuAC0gVXBkYXRlIHRvIDEuOC4yIHJlbGVhc2UKLSBkaGNwL2RoY2xpZW50OiBpbXByb3ZlICJpbnRlcmZhY2UiIHN0YXRlbWVudCBwYXJzaW5nCi0gZG5zOiBmaXggcHVibGljIHN1ZmZpeCBjaGVjayBvbiBzZWFyY2ggZG9tYWlucyAocmggIzE0MDQzNTApAC0gZGV2aWNlOiBkb24ndCBjaGFuZ2UgTVRVIHVubGVzcyBleHBsaWNpdGx5IGNvbmZpZ3VyZWQgKHJoICMxNDYwNzYwKQotIGNvcmU6IGRvbid0IHJlbW92ZSBleHRlcm5hbCBJUHY0IGFkZHJlc3NlcyAocmggIzE0NTk4MTMpCi0gY2xpOiBmaXggb3V0cHV0IG9mIGlmYWNlIGluIG92ZXJ2aWV3IG91dHB1dCAocmgjMTQ2MDIxOSkKLSBwcHA6IHVuZXhwb3J0IE5NUFBQTWFuYWdlciBpbnN0YW5jZSBvbiBkaXNwb3NlIChyaCMxNDU5NTc5KQotIGNsaTogcmVtb3ZlIHNwdXJpb3VzIGRldmljZSBuYW1lcyBmcm9tIHdpZmkgc3ViY29tbWFuZHMgb3V0cHV0IChyaCMxNDYwNTI3KQAtIGJvbmQ6IGZpeCBjcmFzaCBjb21wYXJpbmcgbW9kZSB3aGlsZSBnZW5lcmF0aW5nIGJvbmQgY29ubmVjdGlvbiAocmggIzE0NTk1ODApCi0gY29ubmVjdGl2aXR5OiBmaXggcm91dGUgcGVuYWx0eSBpZiBXV0FOIGFuZCBCVCBkZXZpY2UgdXNpbmcgaXAtaWZpbmRleCAocmggIzE0NTk5MzIpCi0gZGV2aWNlOiBwZXJzaXN0IG5tLW93bmVkIGluIHJ1biBzdGF0ZSAocmggIzEzNzYxOTkpCi0gZGV2aWNlOiBmaXggYXNzdW1pbmcgbWFzdGVyIGRldmljZSBvbiByZXN0YXJ0IChyaCAjMTQ1MjA2MikKLSBkZXZpY2U6IGFwcGx5IHJvdXRlIG1ldHJpYyBwZW5hbGl0eSBvbmx5IHdoZW4gdGhlIGRlZmF1bHQgcm91dGUgZXhpc3RzIChyaCAjMTQ1OTYwNCkKLSBjb25uZWN0aXZpdHk6IGZpeCBwZXJpb2RpYyBjb25uZWN0aXZpdHkgY2hlY2sgKHJoICMxNDU4Mzk5KQotIGJvbmQ6IGltcHJvdmUgb3B0aW9uIG1hdGNoaW5nIG9uIGRhZW1vbiByZXN0YXJ0IChyaCAjMTQ1NzkwOSkKLSBkZXZpY2U6IGZpeCB0b3VjaGluZyBkZXZpY2UgYWZ0ZXIgZXh0ZXJuYWwgYWN0aXZhdGlvbiAocmggIzE0NTcyNDIpAC0gaWZjZmctcmg6IGZpeCB3cml0aW5nIGxlZ2FjeSBORVRNQVNLIHZhbHVlIChyaCAjMTQ0NTQxNCkKLSB0dWk6IGZpeCBjcmFzaCBkdXJpbmcgY29ubmVjdCAocmggIzE0NTY4MjYpCi0gbGlibm06IGZpeCBsaWJubSByZWplY3RpbmcgVkxBTiBJRCA0MDk1IChyaCAjMTQ1NjkxMSkKLSBibHVldG9vdGg6IGZpeCBjcmFzaCBvbiBjb25uZWN0aW5nIHRvIGEgTkFQIChyaCAjMTQ1NDM4NSkKLSBkZXZpY2U6IHJlbGVhc2UgcmVtb3ZlZCBkZXZpY2VzIGZyb20gbWFzdGVyIG9uIGNsZWFudXAgKHJoICMxNDQ4OTA3KQotIG5tY2xpOiBmaXggY3Jhc2ggd2hlbiBzZXR0aW5nIDgwMi0xeC5wYXNzd29yZC1yYXcgKHJoICMxNDU2MzYyKQAtIGRldmljZTogdXBkYXRlIGV4dGVybmFsIGNvbmZpZ3VyYXRpb24gYmVmb3JlIGNvbW1pdCAoZml4IGJ1ZykgKHJoICMxNDQ5ODczKQAtIGRoY3A6IGRvbid0IGFkZCByb3V0ZSB0byBESENQNCBzZXJ2ZXIgKHJoICMxNDQ4OTg3KQotIGRldmljZTogdXBkYXRlIGV4dGVybmFsIGNvbmZpZ3VyYXRpb24gYmVmb3JlIGNvbW1pdCAocmggIzE0NDk4NzMpCi0gbGlibm06IGZpeCBOVUwgdGVybWluYXRpb24gb2YgZGV2aWNlJ3MgZGVzY3JpcHRpb24gKHJoICMxNDQzMTE0KQotIGxpYm5tLCBjb3JlOiBlbnN1cmUgdmFsaWQgVVRGLTggaW4gZGV2aWNlIHByb3BlcnRpZXMgKHJoICMxNDQzMTE0KQotIGNvcmU6IGZpeCBkZXZpY2UncyBVREkgcHJvcGVydHkgb24gRC1CdXMgKHJoICMxNDQzMTE0KQotIGlmY2ZnLXJoOiBvbWl0IGVtcHR5IG5leHQgaG9wIGZvciByb3V0ZXMgaW4gbGVnYWN5IGZvcm1hdCAocmggIzE0NTI2NDgpCi0gY29yZTogZml4IHBlcnNpc3RpbmcgbWFuYWdlZCBzdGF0ZSBvZiBkZXZpY2UgKHJoICMxNDQwMTcxKQotIHByb3h5OiBmaXggdXNlLWFmdGVyLWZyZWUgKHJoICMxNDUwNDU5KQotIGRldmljZTogZG9uJ3Qgd3JvbmdseSBkZWxheSBzdGFydHVwIGNvbXBsZXRlIHdhaXRpbmcgZm9yIGNhcnJpZXIgKHJoICMxNDUwNDQ0KQAtIFVwZGF0ZSB0byAxLjguMCByZWxlYXNlAC0gVXBkYXRlIHRvIHRoaXJkIFJlbGVhc2UgQ2FuZGlkYXRlIG9mIE5ldHdvcmtNYW5hZ2VyIDEuOAAtIFVwZGF0ZSB0byBzZWNvbmQgUmVsZWFzZSBDYW5kaWRhdGUgb2YgTmV0d29ya01hbmFnZXIgMS44AC0gVXBkYXRlIHRvIGEgc25hcHNob3Qgb2YgMS44Lnggc2VyaWVzAC0gVXBkYXRlIHRvIGEgMS42LjIgcmVsZWFzZQAtIFJlYnVpbHQgZm9yIGh0dHBzOi8vZmVkb3JhcHJvamVjdC5vcmcvd2lraS9GZWRvcmFfMjZfTWFzc19SZWJ1aWxkAC0gVXBkYXRlIHRvIGEgMS42LjAgcmVsZWFzZQAtIFVwZGF0ZSB3aXRoIGZpeGVzIGZyb20gdXBzdHJlYW0gbm0tMS02IGJyYW5jaAotIGJ1aWxkOiBsZXQgbGlibm0gYW5kIGdsaWIgcGFja2FnZSBjb25mbGljdCAocmggIzE0MDY0NTQpAC0gVXBkYXRlIHRvIGEgMS42LXJjMQAtIGZpeCBidWlsZCBmYWlsdXJlIGR1ZSB0byBjbGFzaCBvZiBiaXR3aXNlIGRlZmluZXMALSBSZWJ1aWxkIGZvciByZWFkbGluZSA3LngALSBVcGRhdGUgdG8gYSBuZXdlciBkZXZlbG9wbWVudCBzbmFwc2hvdAAtIFJlYnVpbGQgcGFja2FnZSBmb3IgdmFsYSBnZW5lcmF0aW9uIGVycm9yIChyaCMxMzk4NzM4KQAtIGZpeCBlbmFibGluZyBpZmNmZy1yaCBwbHVnaW4gYnkgZGVmYXVsdCBmb3IgKz0vLT0gb3BlcmF0aW9ucyAocmgjMTM5NzkzOCkKLSBmaXggbWlzc2luZyBzeW1ib2wgX25tX2RldmljZV9mYWN0b3J5X25vX2RlZmF1bHRfc2V0dGluZ3MALSBmaXggZW5hYmxpbmcgaWZjZmctcmggcGx1Z2luIGJ5IGRlZmF1bHQgKHJoIzEzOTc5MzgpCi0gbW92ZSB0cmFuc2xhdGlvbiBmaWxlcyBmcm9tIGNvcmUgdG8gbGlibm0vZ2xpYiBzdWJwYWNrYWdlcwAtIFVwZGF0ZSB0byBhIGRldmVsb3BtZW50IHNuYXBzaG90AC0gVXBkYXRlIHRvIDEuNC4yAC0gd2lmaTogZml4IGFub3RoZXIgYWN0aXZhdGlvbiBmYWlsdXJlIHdoZW4gY2hhbmdpbmcgTUFDIGFkZHJlc3MgKHJoIzEzNzE0NzgsIGJnbyM3NzA0NTYsIGJnbyM3NzA1MDQpAC0gZGhjcDogZml4IHJhY2UgdG8gbWlzcyBESENQIGxlYXNlIGV2ZW50IChyaCMxMzcyODU0KQAtIHdpZmk6IGZpeCBhY3RpdmF0aW9uIGZhaWx1cmUgZHVlIHRvIGVycm9yIGNoYW5naW5nIE1BQyBhZGRyZXNzIChyaCMxMzcxNDc4LCBiZ28jNzcwNDU2KQAtIFVwZGF0ZSB0byBOZXR3b3JrTWFuYWdlciAxLjQuMCByZWxlYXNlAC0gZml4IHN0YWxlIFdpLUZpIGFmdGVyIHJlc3VtZSBmcm9tIHN1c3BlbmQgKHJoIzEzNjIxNjUpAC0gUmVidWlsZCBhZ2FpbnN0IG5ld2VyIEdMaWIgdG8gb3ZlcmNvbWUgbG9nZ2luZyBwcm9ibGVtcyBvbiBpNjg2AC0gVXBkYXRlIHRvIGEgbGF0ZXIgR2l0IHNuYXBzaG90AC0gZG5zOiBjbGVhciBjYWNoZSBvZiBkbnNtYXNxIHdoZW4gdXBkYXRpbmcgRE5TIGNvbmZpZ3VyYXRpb24gKHJoIzEzMzg3MzEpCi0gZG5zOiBmaXggcmVzdGFydGluZyBkbnNtYXNxIGluc3RhbmNlCi0gc3BlYzogZGVwZW5kIGJsdWV0b290aCBzdWJwYWNrYWdlIG9uIGV4YWN0IHd3YW4gdmVyc2lvbgotIGFsbDogZml4IHNvbWUgbWVtbGVha3MALSBVcGRhdGUgdG8gTmV0d29ya01hbmFnZXIgMS4yLjIgcmVsZWFzZQAtIFVwZGF0ZSB0byBOZXR3b3JrTWFuYWdlciAxLjIuMCByZWxlYXNlAC0gVXBkYXRlIHRvIE5ldHdvcmtNYW5hZ2VyIDEuMi1yYzIALSBVcGRhdGUgdG8gTmV0d29ya01hbmFnZXIgMS4yLXJjMQAtIEZpeCBsaW5rIGRldGVjdGlvbiBvbiA0LjUgd2hlbiBidWlsZCB3aXRoIDQuNiBrZXJuZWwALSBVcGRhdGUgdG8gTmV0d29ya01hbmFnZXIgMS4yLWJldGEzAC0gRml4IG9idGFpbmluZyB0aGUgaG9zdG5hbWUgZnJvbSBETlMgKHJoICMxMzA4OTc0KQAtIEZpeCBhY3RpdmF0aW5nIGNvbm5lY3Rpb25zIGluIHNvbWUgY2FzZXMgKHJoICMxMzE2NDg4KQAtIFVwZGF0ZSB0byBOZXR3b3JrTWFuYWdlciAxLjItYmV0YTIKLSBSZXN5bmMgd2l0aCBjb250cmliL3JwbQAtIHNwZWNmaWxlOiByZW1vdmUgbm8gbG9uZ2VyIG5lZWRlZCAxMC1pYmZ0LXBsdWdpbi5jb25mIGFuZCBzeW5jIHdpdGggY29udHJpYi9ycG0KLSBjb3JlOiBiYWNrcG9ydCBmaXggZm9yIG1pc3NpbmcgYnJhY2VzIGJ1ZyBpbiBwbGF0Zm9ybQAtIFJlYnVpbHQgZm9yIGh0dHBzOi8vZmVkb3JhcHJvamVjdC5vcmcvd2lraS9GZWRvcmFfMjRfTWFzc19SZWJ1aWxkAC0gVXBkYXRlIHRvIE5ldHdvcmtNYW5hZ2VyIDEuMi1iZXRhMQAtIEFkZCB1cHN0cmVhbSBmaXggZm9yIEFQIGxpc3QgaGFzaCBmdW5jdGlvbiAoIzEyODg4NjcpAC0gVXBkYXRlIHRvIGEgbGF0ZXIgc25hcHNob3QKLSBFbmFibGVzIFJGQzcyMTcgYWRkcmVzc2luZyBmb3IgbmV3IElQdjYgY29ubmVjdGlvbnMALSBEcm9wIHRoZSBOZXR3b3JrTWFuYWdlci1kZXZlbCBzdWJwYWNrYWdlIChmb2xkZWQgaW50byBsaWJubS1nbGliLWRldmVsKQotIFVwZGF0ZSB0byBhIGxhdGVyIHNuYXBzaG90AC0gSW1wb3J0IGEgbmV3ZXIgMS4yIGdpdCBzbmFwc2hvdAAtIEZpeCB0ZXN0IHJ1bgAtIEltcG9ydCBhIDEuMiBnaXQgc25hcHNob3QALSBGaXggY29tbWFuZCBsaW5lIHBhcnNpbmcALSBVcGRhdGUgdG8gMS4wLjYgcmVsZWFzZQAtIGZpeCBjcmFzaCB3aGVuIGRlYWN0aXZhdGluZyBhc3N1bWVkIGRldmljZSAocmggIzEyNTM5NDkpCi0gYmFja3BvcnQgd2lmaSBzY2FuIG9wdGlvbnMgZm9yIHNzaWQKLSB1c2UgcGxhaW4gSFRUUCBVUkkgZm9yIGNvbm5lY3Rpdml0eSBjaGVjawAtIFVwZGF0ZSB0byBhIEdpdCBzbmFwc2hvdAAtIEZpeCBhbiBhc3NlcnRpb24gZmFpbHVyZSBpbiBubWNsaSAocmggIzEyNDQwNDgpCi0gRml4IGRlZmF1bHQgcm91dGUgaGFuZGxpbmcgb24gYXNzdW1lZCBjb25uZWN0aW9ucyAocmggIzEyNDU2NDgpAC0gVXBkYXRlIHRvIDEuMC40IHJlbGVhc2UALSBXRVhUIGRlcGVuZHMgb24gZW5hYmxlZCB3aWZpAC0gQSBiaXQgbW9yZSByZWNlbnQgR2l0IHNuYXBzaG90AC0gQSBiaXQgbW9yZSByZWNlbnQgR2l0IHNuYXBzaG90Ci0gVGhpcyBvbmUgZml4ZXMgYSByZWdyZXNzaW9uIHdpdGggZGVmYXVsdCByb3V0ZSBtYW5hZ2VtZW50AC0gVXBkYXRlIHRvIGEgbmV3IDEuMC4zIGRldmVsb3BtZW50IHNuYXBzaG90IChnaXQyMDE1MDcwNykKLSBjb3JlOiBmaXggaGFuZGxpbmcgb2YgaWdub3JlLWF1dG8tKiBwcm9wZXJ0aWVzIChyaCAjMTIzOTE4NCkALSBBIGJpdCBtb3JlIHJlY2VudCBHaXQgc25hcHNob3QALSBVcGRhdGUgdG8gYSByZWNlbnQgR2l0IHNuYXBzaG90AC0gUmVidWlsdCBmb3IgaHR0cHM6Ly9mZWRvcmFwcm9qZWN0Lm9yZy93aWtpL0ZlZG9yYV8yM19NYXNzX1JlYnVpbGQALSBVcGRhdGUgdG8gMS4wLjIgcmVsZWFzZQAtIFVwZGF0ZSB0byAxLjAuMiBkZXZlbG9wbWVudCBzbmFwc2hvdCAoZ2l0MjAxNTA0MjkpAC0gVXBkYXRlIHRvIDEuMC4yIGRldmVsb3BtZW50IHNuYXBzaG90AC0gZG5zOiByZXZlcnQgcmVzb2x2LmNvbmYgc3ltbGluayBzdHVmZiAoc2hvdWxkIG9ubHkgYmUgaW4gRjIzKywgbm90IEYyMikALSBjb25uZWN0aXZpdHk6IGZpeCBjaGVja2luZyB3aGVuIG5vIHZhbGlkIEROUyBzZXJ2ZXJzIGFyZSBwcmVzZW50IChyaCAjMTE5OTA5OCkALSBjb3JlOiBmbHVzaCBJUHY2TEwgYWRkcmVzcyB3aGVuIGRlY29uZmlndXJpbmcgbWFuYWdlZCBkZXZpY2VzIChyaCAjMTE5MzEyNykgKHJoICMxMTg0OTk3KQAtIGNvcmU6IHJlc3VtZSBicmlkZ2VkIGNvbm5lY3Rpb25zIHByb3Blcmx5IChyaCAjMTE2MjYzNiwgYmFja3BvcnQgZnJvbSBtYXN0ZXIpAC0gZG5zOiBtYW5hZ2UgcmVzb2x2LmNvbmYgYXMgc3ltbGluayB0byBwcml2YXRlIGZpbGUgaW4gL3J1biBkaXJlY3RvcnkgKHJoICMxMTE2OTk5KQAtIGJ1aWxkOiBmaXggTmV0d29ya01hbmFnZXItYmx1ZXRvb3RoIGRlcCBvbiBOZXR3b3JrTWFuYWdlci13d2FuCi0gYnVpbGQ6IHJlLWVuYWJsZSBoYXJkd2FyZSBwbHVnaW5zIG9uIHMzOTAALSBVcGRhdGUgdG8gMS4wAC0gdnBuOiBwcm9wYWdhdGUgZGFlbW9uIGV4ZWMgZXJyb3IgY29ycmVjdGx5IChiZ28gIzczOTQzNikKLSBjb3JlOiBkbyBub3QgYXNzZXJ0IHdoZW4gYSBkZXZpY2UgaXMgZW5zbGF2ZWQgZXh0ZXJuYWxseSAocmggIzExNjczNDUpAC0gY2xpOiBmaXggY3Jhc2ggaW4gYG5tY2xpIGRldmljZSB3aWZpYCB3aXRoIG11bHRpcGxlIHdpZmkgZGV2aWNlcyAocmggIzExNTk0MDgpAC0gcGxhdGZvcm06IGZpeCBhIHJvdXRpbmctcmVsYXRlZCBidWcgdGhhdCBjb3VsZCBjYXVzZSBOTSBhbmQgb3RoZXIgYXBwcyB0byBzcGluIChyaCAjMTE1MTY2NSkALSBGaXggSVB2NiBuZXh0IGhvcCBkZWZhdWx0IHNldHRpbmcALSBBdm9pZCB1bm93bmVkIC9ldGMvTmV0d29ya01hbmFnZXIgaW4gY29uZmlnLWNvbm5lY3Rpdml0eS1mZWRvcmEALSBjb25uZWN0aXZpdHktZmVkb3JhOiBkb24ndCByZXF1aXJlIE5ldHdvcmtNYW5hZ2VyICgjMTE1NjE5OCkALSBibHVldG9vdGg6IFJlc3RvcmUgRFVOIHN1cHBvcnQgKHJoICMxMDU1NjI4KQAtIEFsbG93IG5vbi1sb2NhbCB1c2VycyBuZXR3b3JrIGNvbnRyb2wgYWZ0ZXIgUG9saWN5S2l0IGF1dGhlbnRpY2F0aW9uIChyaCAjMTE0NTY0NikALSBjb25uZWN0aXZpdHk6IHVzZSBIVFRQUyBmb3IgY29ubmVjdGl2aXR5IGNoZWNraW5nIChyaCAjMTEzNTc3KQAtIGFkc2wgcGx1Z2luIG5lZWRzIHJwLXBwcG9lIHRvIHdvcmsALSBhbHdheXMgaW5jbHVkZSBNb2RlbU1hbmFnZXItZ2xpYi1kZXZlbCAoIzExMjk2MzIpAC0gUmVidWlsdCBmb3IgaHR0cHM6Ly9mZWRvcmFwcm9qZWN0Lm9yZy93aWtpL0ZlZG9yYV8yMV8yMl9NYXNzX1JlYnVpbGQALSBSZWJ1aWx0IGZvciBwcHAgMi40LjcALSBjb25uZWN0aXZpdHk6IGVuc3VyZSBpbnRlcnZhbCBpcyBzZXQgdG8gZW5hYmxlIGNvbm5lY3Rpdml0eSBjaGVja2luZyAocmggIzExMjM3NzIpAC0gUmVidWlsdCBmb3IgZ29iamVjdC1pbnRyb3NwZWN0aW9uIDEuNDEuNAAtIFVwZGF0ZSB0byB1cHN0cmVhbSAwLjkuMTAuMCByZWxlYXNlIHNuYXBzaG90AC0gVXBkYXRlIHRvIHVwc3RyZWFtIDAuOS45Ljk4ICgwLjkuMTAtcmMxKSByZWxlYXNlIHNuYXBzaG90AC0gVXBkYXRlIHRvIHVwc3RyZWFtIDAuOS45Ljk1ICgwLjkuMTAtYmV0YTEpIHJlbGVhc2Ugc25hcHNob3QALSBSZWJ1aWx0IGZvciBodHRwczovL2ZlZG9yYXByb2plY3Qub3JnL3dpa2kvRmVkb3JhXzIxX01hc3NfUmVidWlsZAAtIFJlYnVpbGQgYWdhaW5zdCBwcHBkIDIuNC42AC0gVXBkYXRlIHRvIGEgZ2l0IHNuYXBzaG90IChnaXQyMDE0MDMxOSBnaXQ6Mzk4MDgwNikKLSBSZW5hbWUgTmV0d29ya01hbmFnZXItYXRtIHBhY2thZ2UgdG8gTmV0d29ya01hbmFnZXItYWRzbAotIFJlbmFtZSBOZXR3b3JrTWFuYWdlci1idCBwYWNrYWdlIHRvIE5ldHdvcmtNYW5hZ2VyLWJsdWV0b290aAAtIFVwZGF0ZSB0byBhIGdpdCBzbmFwc2hvdCAoZ2l0MjAxNDAzMTcgZ2l0OmExZTg5YjQpCi0gcGxhdGZvcm06IGZpeCBOTSBjcmFzaCBpZiBsaW5rIGhhcyBubyBuYW1lIChlLmcuIGZvciBmYWlsZWQgVlBOIGNvbm5lY3Rpb24pCi0gbGlibm0tdXRpbC9jbGk6IGZpeCBicmlkZ2UgcHJpb3JpdHkgZGVmYXVsdCB2YWx1ZSAocmggIzEwNzM2NjQpAC0gVXBkYXRlIHRvIGEgZ2l0IHNuYXBzaG90IChnaXQyMDE0MDMxNCBnaXQ6NDVhMzI2ZCkKLSBGaXggT2Jzb2xldGVzIGFuZCBSZXF1aXJlcyB0byBwZXJmb3JtIHVwZGF0ZXMgY29ycmVjdGx5AC0gVXBkYXRlIHRvIGEgZ2l0IHNuYXBzaG90IChnaXQyMDE0MDMxMCBnaXQ6MzUwYjZkNikALSBuZXcgdXBzdHJlYW0gc25hcHNob3Qgd2l0aCBkZXZlbG9wbWVudCB2ZXJzaW9uIDAuOS45LjEALSBhZGQgbm10dWkgcGFja2FnZQotIGJ1Z2ZpeCBjYWNoaW5nIG9mIGxpYm5sIG9iamVjdHMgKGNhdXNlZCBlcnJvciB3aXRoIG5ldyBsaWJubDMgdmVyc2lvbiB3aGVuIGFjdGl2YXRpbmcgYnJpZGdlcykgKHJoICMxMDYzMjkwKQotIGZpeCBOTU1hbmFnZXI6c3RhcnR1cCB0cmFja2luZyAocGVuZGluZyBhY3Rpb24pIChyaCAjMTAzMDU4MykALSBjb3JlOiBmaXggY3Jhc2ggZ2V0dGluZyBzZWNyZXRzIGluIGxpYm5tLWdsaWIALSBVcGRhdGUgdG8gYSBnaXQgc25hcHNob3QgKGdpdDIwMTQwMTMxKQAtIFVwZGF0ZSB0byBhIGdpdCBzbmFwc2hvdCAoZ2l0MjAxNDAxMTcpAC0gVXBkYXRlIHRvIGEgZ2l0IHNuYXBzaG90IChnaXQyMDE0MDExNCkALSBibHVlei1tYW5hZ2VyOiBmaXggYSBjcmFzaCAocmggIzEwNDg3MTEpAC0gY29yZTogZml4IElQdjYgcm91dGVyIHNvbGljaXRhdGlvbiBsb29wIChyaCAjMTA0NDc1NykALSBjb3JlOiB3YWl0IGZvciBsaW5rIGJlZm9yZSBkZWNsYXJpbmcgc3RhcnR1cCBjb21wbGV0ZSAocmggIzEwMzQ5MjEpCi0gY29yZTogaWdub3JlIFJBLXByb3ZpZGVkIElQdjYgZGVmYXVsdCByb3V0ZXMgKHJoICMxMDI5MjEzKQotIGNvcmU6IHNldCBJUHY0IGJyb2FkY2FzdCBhZGRyZXNzIGNvcnJlY3RseSAocmggIzEwMzI4MTkpAC0gY29yZTogRml4IFB0UC9wZWVyIGFkZHJlc3Mgc3VwcG9ydCwgZm9yIE9wZW5WUE4gKHJoICMxMDE4MzE3KQAtIGRpc3BhdGNoZXI6IGZpeCBjcmFzaCBvbiBleGl0IHdoaWxlIGxvZ2dpbmcgZnJvbSBzaWduYWwgaGFuZGxlciAocmggIzEwMTc4ODQpCi0gY29yZTogd29ya2Fyb3VuZCBjcmFzaCB3aGVuIGNvbm5lY3RpbmcgdG8gd2lmaSAocmggIzEwMjUzNzEpCi0gZXRoZXJuZXQ6IGRvbid0IGNyYXNoIGlmIGRldmljZSBkb2Vzbid0IGhhdmUgYSBNQUMgYWRkcmVzcyAocmggIzEwMjkwNTMpCi0gbGlibm0tZ2xpYjogZml4IGNyYXNoIGJ5IHRha2luZyBhZGRpdGlvbmFsIHJlZiBpbiByZXN1bHRfY2IoKSAocmggIzEwMzA0MDMpCi0gaWZjZmctcmg6IGZpeCBpZ25vcmluZyB1cGRhdGVzIHRoYXQgZG9uJ3QgY2hhbmdlIGFueXRoaW5nAC0gbm1jbGk6IGFkZCAiY29uIGxvYWQiIHRvIG1hbnVhbGx5IGxvYWQgYW4gaWZjZmcgZmlsZQotIHZwbjogZml4IGxvZ2dpbmcgdG8gaGVscCBkZWJ1ZyByaCAjMTAxODMxNwotIGJyaWRnZTogZml4IGNyYXNoIHdpdGggYnJpZGdlIHBvcnRzIHdpdGggZW1wdHkgc2V0dGluZ3MgKHJoICMxMDMxMTcwKQAtIGNvcmU6IGZpeCBkZXRlY3Rpb24gb2Ygbm9uLW1hYzgwMjExIGRldmljZXMgdGhhdCBkbyBub3Qgc2V0IERFVlRZUEUgKHJoICMxMDE1NTk4KQAtIGNvcmU6IGFkZCBzb21lIGRlYnVnZ2luZyB0byBoZWxwIGRpYWdub3NlIG5ldGxpbmsgZXJyb3JzIChyaCAjMTAyOTIxMykALSBpZmNmZy1yaDogZml4IGNyYXNoIGluIGlmY2ZnLXJoIHBsdWdpbiB3aGVuIHJlbG9hZGluZyBjb25uZWN0aW9ucyAocmggIzEwMjM1NzEpCi0gaWZjZmctcmg6IGZpeCBjcmFzaCB3aGVuIGhhdmluZyBjb25uZWN0aW9ucyB3aXRoIE5FVkVSX0RFRkFVTFQgKHJoICMxMDIxMTEyKQotIGNvcmU6IGZpeCBzZWdmYXVsdCBpbiBubS1wb2xpY3kgd2hlbiBzZXR0aW5nIGRlZmF1bHQgcm91dGUgZm9yIHZwbiAocmggIzEwMTkwMjEpCi0gaWZjZmctcmg6IGZpeCBjcmFzaCB3aGVuIHJlYWRpbmcgY29ubmVjdGlvbiAoYXNzZXJ0KSAocmggIzEwMjUwMDcpCi0gY29yZTogYWxsb3cgSVB2NCB0byBwcm9jZWVkIGlmIElQdjYgaXMgZ2xvYmFsbHkgZGlzYWJsZWQgYnV0IHNldCB0byAiYXV0byIgKHJoICMxMDEyMTUxKQAtIGNvcmU6IGZpeCBESENQdjYgYWRkcmVzcyBwcmVmaXggbGVuZ3RoIChyaCAjMTAxMzU4MykKLSBjbGk6IGVuaGFuY2UgYm9uZGluZyBxdWVzdGlvbmFpcmUgKHJoICMxMDA3MzU1KQotIGNvcmU6IGZpeCBjcmFzaCB3aXRoIEJsdWV6NSBpZiBQQU4gY29ubmVjdGlvbiBpcyBub3QgZGVmaW5lZCAocmggIzEwMTQ3NzApCi0gbGlibm0tZ2xpYjogZml4IHZhcmlvdXMgbWVtb3J5IGxlYWtzIHRoYXQgY291bGQgY2F1c2UgVUlzIHRvIG1pcy1yZXBvcnQgc3RhdGUKLSBjb3JlOiBmaXggaXNzdWVzIHdpdGggbWlzLWNvbmZpZ3VyZWQgSVB2NiByb3V0ZXIgYWR2ZXJ0aXNlbWVudHMgKHJoICMxMDA4MTA0KQotIGNsaTogZml4IHBvdGVudGlhbCBjcmFzaCBlZGl0aW5nIGNvbm5lY3Rpb25zIChyaCAjMTAxMTk0MikALSBjb3JlOiBmaXggYnJpZGdlIGRldmljZSBjcmVhdGlvbiAoIzEwMTI1MzIpCi0gY29yZSxzZXR0aW5nczogZG8gbm90IGNhbGwgZnVuY3Rpb25zIHdpdGggY29ubmVjdGlvbj09TlVMTCAocmggIzEwMDgxNTEpCi0gY2xpOiBhY2NlcHQgZ2F0ZXdheSBpbiB0aGUgSVAgcXVlc3Rpb25uYWlyZSBvZiAnbm1jbGkgLWEgY29uIGFkZCcgKHJoICMxMDA3MzY4KQotIGNsaTogYWx3YXlzIHByaW50IHN1Y2Nlc3MgbWVzc2FnZSAobm90IG9ubHkgaW4gLS1wcmV0dHkgbW9kZSkgKHJoICMxMDA2NDQ0KQotIGNsaTogZml4IGJvbmQgcXVlc3Rpb25uYWlyZSB0byBiZSBhYmxlIHRvIHNldCBtaWltb24gKHJoICMxMDA3MzU1KQotIGlmY2ZnLXJoOiBpZiBJUHY0IGlzIGRpc2FibGVkIHB1dCBETlMgZG9tYWlucyAoRE9NQUlOKSBpbnRvIElQdjYgKHJoICMxMDA0ODY2KQotIHBsYXRmb3JtOiBmaXggYSBjcmFzaCB3aGVuIG5tX3BsYXRmb3JtX3N5c2N0bF9nZXQoKSByZXR1cm5zIE5VTEwgKHJoICMxMDEwNTIyKQotIHBsYXRmb3JtOiBmaXggSW5maW5pQmFuZCBwYXJ0aXRpb24gaGFuZGxpbmcgKHJoICMxMDA4NTY4KQotIGluZmluaWJhbmQ6IG9ubHkgY2hlY2sgdGhlIGxhc3QgOCBieXRlcyB3aGVuIGRvaW5nIGh3YWRkciBtYXRjaGVzIChyaCAjMTAwODU2NikKLSBibHVlejogbWVyZ2UgYWRkaW5nIHN1cHBvcnQgZm9yIEJsdWVaIDUgKGJnbyAjNzAxMDc4KQotIGFwaTogY2xhcmlmeSBsaWZldGltZSBhbmQgYmVoYXZpb3Igb2YgQWN0aXZlQ29ubmVjdGlvbidzIFNwZWNpZmljT2JqZWN0IHByb3BlcnR5IChyaCAjMTAxMjMwOSkKLSB2cG46IGZpeCBjb25uZWN0aW5nIHRvIFZQTiAoYmdvICM3MDgyNTUpIChyaCAjMTAxNDcxNikKLSByZGlzYzogZG8gbm90IGNyYXNoIG9uIE5EUCBpbml0IGZhaWx1cmVzIChyaCAjMTAxMjE1MSkKLSBjbGk6IGJlIG1vcmUgdmVyYm9zZSB3aGVuIGFkZGluZyBJUCBhZGRyZXNzZXMgaW4gcXVlc3Rpb25uYWlyZSAocmggIzEwMDY0NTApCi0gdGVhbTogY2hhaW4gdXAgcGFyZW50IGRpc3Bvc2UoKSBpbiBOTURldmljZVRlYW0gZGlzcG9zZSgpIChyaCAjMTAxMzU5MykKLSB0cmFuc2xhdGlvbiB1cGRhdGVzAC0gZHJvcCB3aW1heCBzdWJwYWNrYWdlAC0gY29yZTogYWN0dWFsbHkgZW5hYmxlIE1vZGVtTWFuYWdlciAxLjAgc3VwcG9ydAotIGxpYm5tLWdsaWI6IGZpeCBubV9yZW1vdGVfY29ubmVjdGlvbl9kZWxldGUoKSBub3QgY2FsbGluZyBjYWxsYmFjayAocmggIzk5NzU2OCkKLSBjbGk6IGVuc3VyZSB0ZXJtaW5hbCBpcyByZXNldCBhZnRlciBxdWl0dGluZwotIGNsaTogc2V0IHdlcC1rZXktdHlwZSBwcm9wZXJseSB3aGVuIGVkaXRpbmcgKHJoICMxMDAzOTQ1KQotIG1hbjogZml4IHR5cG8gaW4gbm1jbGkgZXhhbXBsZXMgbWFucGFnZSAocmggIzEwMDQxMTcpCi0gY29yZTogZml4IHNldHRpbmcgVkxBTiBpbmdyZXNzL2VncmVzcyBtYXBwaW5ncwotIGNvcmU6IGFsbG93IGNyZWF0aW5nIFZMQU5zIGZyb20gaW50ZXJmYWNlcyBvdGhlciB0aGFuIEV0aGVybmV0IChyaCAjMTAwMzE4MCkKLSBjbGk6IGZpeCBpbnB1dC9vdXRwdXQgZm9ybWF0IGNvbnZlcnNpb24gKHJoICM5OTg5MjkpAC0gY29yZTogZml4IGJ1ZyB3aGljaCBkaXNhbGxvd2VkIGRlbGV0aW5nIGNvbm5lY3Rpb25zIChyaCAjOTk3NTY4KQotIGNvcmU6IGFkZCBzdXBwb3J0IGZvciBUZWFtIGRldmljZXMKLSBjb3JlOiBlbmFibGUgTmV0d29ya01hbmFnZXItd2FpdC1vbmxpbmUgYnkgZGVmYXVsdCAocmggIzgxNjY1NSkKLSBjb3JlOiBmaXggY3Jhc2ggd2hlbiAnZ3JlJyBhbmQgJ21hY3ZsYW4nIGxpbmtzIGNoYW5nZSAocmggIzk5NzM5NikKLSBjb3JlOiBmYWlsIGFjdGl2YXRpb24gd2hlbiBpbnZhbGlkIHN0YXRpYyByb3V0ZXMgYXJlIGNvbmZpZ3VyZWQgKHJoICM5OTk1NDQpCi0gY29yZTogZW5oYW5jZSBjb25uZWN0aXZpdHkgY2hlY2tpbmcgdG8gaW5jbHVkZSBwb3J0YWwgZGV0ZWN0aW9uCi0gY29yZTogYWxsb3cgaHlwaGVucyBmb3IgTUFDIGFkZHJlc3NlcyAocmggIzEwMDI1NTMpCi0gY29yZTogcmVtb3ZlIE5ldHdvcmtNYW5hZ2VyLWNyZWF0ZWQgc29mdHdhcmUgZGV2aWNlcyB3aGVuIHRoZXkgYXJlIGRlYWN0aXZhdGVkIChyaCAjOTUzMzAwKQotIGNvcmU6IGZpeCBoYW5kbGluZyBvZiBzb21lIERIQ1AgY2xpZW50IGlkZW50aWZpZXJzIChyaCAjOTk5NTAzKQotIGNvcmU6IGNvcnJlY3RseSBoYW5kbGUgT3BlbiB2U3dpdGNoIGludGVyZmFjZXMgYXMgZ2VuZXJpYyBpbnRlcmZhY2VzIChyaCAjMTAwNDM1NikKLSBjb3JlOiBiZXR0ZXIgaGFuZGxlIExheWVyLTItb25seSBjb25uZWN0aW9ucyAocmggIzk3OTI4OCkKLSBjbGk6IGVuaGFuY2VkIGJhc2ggY29tcGxldGlvbgotIGNsaTogbWFrZSB0aGUgJ2Rlc2NyaWJlJyBjb21tYW5kIG1vcmUgdmlzaWJsZSAocmggIzk5ODAwMikKLSBjbGk6IGZpeCBidWcgcmVqZWN0aW5nIGNoYW5nZXMgdG8gV2ktRmkgY2hhbm5lbHMgKHJoICM5OTk5OTkpCi0gY2xpOiB1cGRhdGUgYmFzaCBjb21wbGV0aW9uIHRvIHN1Z2dlc3QgY29ubmVjdGlvbiBuYW1lcyAocmggIzk5Nzk5NykKLSBjbGk6IGZpeCB0YWIgY29tcGxldGlvbiBmb3IgYWxpYXNlcyBpbiBlZGl0IG1vZGUKLSBjbGk6IGFzayB3aGV0aGVyIHRvIHN3aXRjaCBJUCBtZXRob2QgdG8gJ2F1dG8nIHdoZW4gYWxsIGFkZHJlc3NlcyBhcmUgZGVsZXRlZCAocmggIzk5ODEzNykKLSBjbGk6IHJlcXVlc3QgbWlzc2luZyBpbmZvcm1hdGlvbiB3aGVuIC0tYXNrIGlzIHBhc3NlZCAocmggIzk1MzI5MSkKLSBjbGk6IGFkZCAncmVtb3ZlJyBjb21tYW5kIHRvIGVkaXQgbW9kZQotIGNsaTogZml4IGNyZWF0aW9uIG9mIHNlY3VyZSBXaS1GaSBjb25uZWN0aW9ucyAocmggIzk5Nzk2OSkgKHJoICM5OTc1NTUpCi0gY2xpOiBkZWZhdWx0IGF1dG9jb25uZWN0IHRvIG5vIGFuZCBhc2sgd2hldGhlciB0byBhY3RpdmF0ZSBvbiBzYXZlIChyaCAjOTUzMjk2KQotIG1hbjogY2xhcmlmeSBtYW5wYWdlIHRleHQgKHJoICM5NjAwNzEpIChyaCAjOTUzMjk5KQotIG1hbjogZml4IGVycm9ycyBpbiB0aGUgbm1jbGkgaGVscCBvdXRwdXQgYW5kIG1hbnBhZ2UgKHJoICM5OTc1NjYpCi0gaWZjZmctcmg6IG9ubHkgd3JpdGUgSVBWNl9ERUZBVUxUR1cgd2hlbiB0aGVyZSdzIGFjdHVhbGx5IGEgZGVmYXVsdCBnYXRld2F5IChyaCAjOTk3NzU5KQotIGlmY2ZnLXJoOiBmaXggaGFuZGxpbmcgb2YgbGVnYWN5LWZvcm1hdCByb3V0ZXMgZmlsZSB3aXRoIG1pc3NpbmcgZ2F0ZXdheQAtIGNvcmU6IGZpeCBhc3NlcnQgb24gbXVsdGktaG9wIHJvdXRlcyAocmggIzk4OTAyMikKLSBjb3JlOiBmaXggZGlzcGF0Y2hlciBzeXN0ZW1kIHVuaXQgZW5hYmxpbmcgKHJoICM5NDg0MzMpCi0gaWZjZmctcmg6IGlnbm9yZSBlbWFjcyB0ZW1wb3JhcnkgbG9ja2ZpbGVzIChyaCAjOTg3NjI5KQotIGNvcmU6IGZpeCB2YXJpb3VzIHJvdXRpbmcgaXNzdWVzIGFuZCBpbnRlcmFjdGlvbiB3aXRoIGtlcm5lbCBldmVudHMKLSBjbGk6IGNvbmZpcm0gc2F2aW5nIGNvbm5lY3Rpb25zIHdoZW4gYXV0b2Nvbm5lY3QgaXMgZW5hYmxlZCAocmggIzk1MzI5NikKLSBjbGk6IGF1dG9tYXRpY2FsbHkgY2hhbmdlIG1ldGhvZCB3aGVuIHN0YXRpYyBJUCBhZGRyZXNzZXMgYXJlIGFkZGVkCi0gY29yZTogcHJlc2VydmUgZXh0ZXJuYWxseSBhZGRlZCBJUHY0IHJvdXRlcyBhbmQgYWRkcmVzc2VzAC0gQ3JlYXRlIE5ldHdvcmtNYW5hZ2VyLWNvbmZpZy1zZXJ2ZXIgcGFja2FnZQAtIFVwZGF0ZSB0byBnaXQgc25hcHNob3QALSBCZWxhdGVkbHkgdXBkYXRlIHVkZXYgZGlyZWN0b3J5IGZvciBVc3JNb3ZlCi0gRml4IGluY29ycmVjdCBkYXRlcyBpbiBvbGQgY2hhbmdlbG9nIGVudHJpZXMgdG8gYXZvaWQgcnBtIHdhcm5pbmdzAC0gYnVpbGQgc3VwcG9ydCBmb3IgY29ubmVjdGl2aXR5IGNoZWNraW5nIChyaCAjODEwNDU3KQAtIGRpc2FibGUgYnVpbGRpbmcgV2lNYXggZm9yIFJIRUwALSBVcGRhdGUgdG8gbmV3IDAuOS4xMCBzbmFwc2hvdAAtIFVwZGF0ZSBmb3Igc3lzdGVtZCBuZXR3b3JrLW9ubGluZS50YXJnZXQgKHJoICM3ODczMTQpCi0gQWRkIHN5c3RlbSBzZXJ2aWNlIGZvciB0aGUgc2NyaXB0IGRpc3BhdGNoZXIgKHJoICM5NDg0MzMpAC0gRW5hYmxlIGhhcmRlbmVkIGJ1aWxkCi0gVXBkYXRlIHRvIDAuOS4xMCBzbmFwc2hvdAotIGNsaTogbmV3IGNhcGFiaWxpdGllcyBhbmQgc29tZXdoYXQgcmUtYXJyYW5nZWQgc3ludGF4Ci0gY29yZTogZ2VuZXJpYyBpbnRlcmZhY2Ugc3VwcG9ydAotIGNvcmU6IHNwbGl0IGNvbmZpZyBzdXBwb3J0OyBuZXcgInNlcnZlciBtb2RlIiBvcHRpb25zCi0gY29yZTogYWxsb3cgbG9ja2luZyBjb25uZWN0aW9ucyB0byBpbnRlcmZhY2UgbmFtZXMALSBjb3JlOiBmaXggaXNzdWUgd2l0aCBVSSBub3Qgc2hvd2luZyBkaXNjb25uZWN0ZWQgb24gcmZraWxsCi0gY29yZTogbWVtb3J5IGxlYWsgZml4ZXMKLSBjb3JlOiBzaWxlbmNlIHdhcm5pbmcgYWJvdXQgZmFpbHVyZSByZWFkaW5nIHBlcm1hbmVudCBNQUMgYWRkcmVzcyAocmggIzkwNzkxMikKLSBjb3JlOiB3YWl0IHVwIHRvIDEyMHMgZm9yIHNsb3ctY29ubmVjdGluZyBtb2RlbXMKLSBjb3JlOiBkb24ndCBjcmFzaCBvbiBQUFBvRSBjb25uZWN0aW9ucyB3aXRob3V0IGEgd2lyZWQgc2V0dGluZwotIGNvcmU6IGVuc3VyZSB0aGUgQXZhaWxhYmxlQ29ubmVjdGlvbnMgcHJvcGVydHkgaXMgYWx3YXlzIGNvcnJlY3QKLSBrZXlmaWxlOiBlbnN1cmUgYWxsLWRlZmF1bHQgVkxBTiBjb25uZWN0aW9ucyBhcmUgcmVhZCBjb3JyZWN0bHkKLSBjb3JlOiBzdXBwcmVzcyBrZXJuZWwncyBhdXRvbWF0aWMgY3JlYXRpb24gb2YgYm9uZDAgKHJoICM5NTM0NjYpCi0gbGlibm0tZ2xpYjogbWFrZSBOTVNlY3JldEFnZW50IHVzYWJsZSB3aXRoIEdPYmplY3QgSW50cm9zcGVjdGlvbgotIGxpYm5tLXV0aWw6IGZpeCBHT2JqZWN0IEludHJvc3BlY3Rpb24gYW5ub3RhdGlvbnMgb2Ygbm1fY29ubmVjdGlvbl9uZWVkX3NlY3JldHMoKQotIGNvcmU6IGRvY3VtZW50YXRpb24gdXBkYXRlcwAtIFVwZGF0ZSB0byAwLjkuOC4yIHNuYXBzaG90Ci0gY29yZTogZml4IFZMQU4gcGFyZW50IGhhbmRsaW5nIHdoZW4gaWRlbnRpZmllZCBieSBVVUlECi0gY29yZTogcXVpZXQgd2FybmluZyBhYm91dCBpbnZhbGlkIGludGVyZmFjZSBpbmRleCAocmggIzkyMDE0NSkKLSBjb3JlOiByZXF1ZXN0ICdzdGF0aWMtcm91dGVzJyBmcm9tIERIQ1Agc2VydmVycyAocmggIzkyMjU1OCkKLSBjb3JlOiBmaXggY3Jhc2ggd2hlbiBkYnVzLWRhZW1vbiBpcyByZXN0YXJ0ZWQgKHJoICM5MTgyNzMpCi0gY29yZTogY29weSBsZWFzZWZpbGVzIGZyb20gL3Zhci9saWIvZGhjbGllbnQgdG8gZml4IG5ldGJvb3QgKHJoICM5MTYyMzMpCi0gY29yZTogbWVtb3J5IGxlYWsgYW5kIHBvdGVudGlhbCBjcmFzaCBmaXhlcwotIGlmY2ZnLXJoOiBlbnN1cmUgbWlzc2luZyBTVFAgcHJvcGVydHkgaXMgaW50ZXJwcmV0ZWQgYXMgb2ZmIChyaCAjOTIyNzAyKQAtIFVwZGF0ZSB0byB0aGUgMC45LjguMCByZWxlYXNlCi0gY2xpOiBmaXggYSBwb3NzaWJsZSBjcmFzaAAtIGNvcmU6IHVzZSBzeXN0ZW1kIGZvciBzdXNwZW5kL3Jlc3VtZSwgbm90IHVwb3dlcgAtIFVwZGF0ZSB0byAwLjkuOC1iZXRhMgotIGNvcmU6IGlnbm9yZSBicmlkZ2VzIG1hbmFnZWQgYnkgb3RoZXIgdG9vbHMgKHJoICM5MDUwMzUpCi0gY29yZTogZml4IGxpYm5sIGFzc2VydCAocmggIzg5NDY1MykKLSB3aWZpOiBhbHdheXMgdXNlIFByb2FjdGl2ZSBLZXkgQ2FjaGluZyB3aXRoIFdQQSBFbnRlcnByaXNlIChyaCAjODM0NDQ0KQotIGNvcmU6IGRvbid0IGNyYXNoIHdoZW4gSW50ZXJuZXQgY29ubmVjdGlvbiBzaGFyaW5nIGZhaWxzIHRvIHN0YXJ0IChyaCAjODgzMTQyKQAtIFNldCBjb3JyZWN0IHN5c3RlbWQgS2lsbE1vZGUgdG8gZml4IGFuYWNvbmRhIHNodXRkb3duIGhhbmdzIChyaCAjODc2MjE4KQAtIGlmY2ZnLXJoOiB3cml0ZSBtaXNzaW5nIElQdjYgc2V0dGluZyBhcyBJUHY2IHdpdGggImF1dG8iIG1ldGhvZCAocmggIzgzMDQzNCkALSBCdWlsZCB2YXBpIGZpbGVzIGFuZCBhZGQgdGhlbSB0byB0aGUgZGV2ZWwgcGFja2FnZQAtIEFwcGx5IHBhdGNoIGZyb20gbWFzdGVyIHRvIHJlYWQgaG9zdG5hbWUgZnJvbSAvZXRjL2hvc3RuYW1lIChyaCAjODMxNzM1KQAtIEFwcGx5IHBhdGNoIGZyb20gbWFzdGVyIHRvIHVwZGF0ZSBob3N0bmFtZSAocmggIzg3NTA4NSkKLSBzcGVjOiBjcmVhdGUgL2V0Yy9OZXR3b3JrTWFuYWdlci9kbnNtYXNxLmQgKHJoICM4NzM2MjEpAC0gRG9uJ3QgYnJpbmcgdXAgdW5pbml0aWFsaXplZCBkZXZpY2VzIChmZCAjNTY5MjkpAC0gQWN0dWFsbHkgYXBwbHkgdGhlIHBhdGNoIGZyb20gdGhlIHByZXZpb3VzIGNvbW1pdC4uLgAtIEFwcGx5IHBhdGNoIGZyb20gbWFzdGVyIHRvIGZpeCBhIGNyYXNoIChyaCAjODY1MDA5KQAtIEFwcGx5IHBhdGNoIGZyb20gbWFzdGVyIHNvIGNvbm5lY3Rpb25zIGZpbmlzaCBjb25uZWN0aW5nIHByb3Blcmx5IChiZ28gIzY4NTU4MSkALSBGb3J3YXJkLXBvcnQgc29tZSBmb3Jnb3R0ZW4gZml4ZXMgZnJvbSBGMTcKLSBGaXggbmV0d29ya2VkLWZpbGVzeXN0ZW0gc3lzdGVtZCBkZXBlbmRlbmNpZXMgKHJoICM3ODczMTQpCi0gRG9uJ3QgcmVzdGFydCBOTSBvbiB1cGdyYWRlLCBkb24ndCBzdG9wIE5NIG9uIHVuaW5zdGFsbCAocmggIzgxMTIwMCkALSBVcGRhdGUgdG8gZ2l0IHNuYXBzaG90AC0gVXBkYXRlIHRvIDAuOS43LjAgc25hcHNob3QALSBSZWJ1aWx0IGZvciBodHRwczovL2ZlZG9yYXByb2plY3Qub3JnL3dpa2kvRmVkb3JhXzE4X01hc3NfUmVidWlsZAAtIFVwZGF0ZSB0byAwLjkuNi1yYzIKLSBjb3JlOiBmaXggcmFjZSBiZXR3ZWVuIHBhcmFsbGVsIERIQ1AgY2xpZW50IGludm9jYXRpb25zCi0gY29yZTogc3VwcHJlc3MgYSB1c2VsZXNzIHdhcm5pbmcgKHJoICM4NDA1ODApCi0gaWZjZmctcmg6IGZpeCBzZWdmYXVsdCB3aXRoIG1hbGZvcm1lZCB2YWx1ZXMgKHJoICM4NDEzOTEpCi0gaWZjZmctcmg6IGlnbm9yZSBJUCBjb25maWcgb24gYm9uZCBzbGF2ZSBjb25maWd1cmF0aW9ucyAocmggIzgzODkwNykALSBVcGRhdGUgdG8gMC45LjUuOTUgKDAuOS42LXJjMSkgc25hcHNob3QKLSBjb3JlOiBhZGQgYXV0b2Nvbm5lY3QsIGRyaXZlci12ZXJzaW9uaSBhbmQgZmlybXdhcmUtdmVyc2lvbiBwcm9wZXJ0aWVzIHRvIE5NRGV2aWNlCi0gY29yZTogdmFyaW91cyBJUHY2IGltcHJvdmVtZW50cwotIGNvcmU6IHJlZHVjZSBudW1iZXIgb2YgY2hhbmdlcyBtYWRlIHRvIEROUyBpbmZvcm1hdGlvbiBkdXJpbmcgY29ubmVjdGlvbiBzZXR1cAotIGNvcmU6IGFkZCBWYWxhIGxhbmd1YWdlIGJpbmRpbmdzCi0gdnBuOiBzdXBwb3J0IElQdjYgb3ZlciBWUE5zCi0gd2lmaTogYWRkIG9uLWRlbWFuZCBXaUZpIHNjYW4gc3VwcG9ydAAtIFVwZGF0ZSB0byBnaXQgc25hcHNob3QALSBOTSBubyBsb25nZXIgdXNlcyAvdmFyL3J1bi9OZXR3b3JrTWFuYWdlciwgc28gZG9uJ3QgY2xhaW0gdG8gb3duIGl0LgogIChyaCAjNjU2NjM4KQAtIFVwZGF0ZSB0byBnaXQgc25hcHNob3QALSBBZGQgX2lzYSBmb3IgaW50ZXJuYWwgcmVxdWlyZXM7IG90aGVyd2lzZSBkZXBzb2x2aW5nIG1heSBwdWxsIGluIGFuCiAgYXJiaXRyYXJ5IGFyY2hpdGVjdHVyZS4ALSBVcGRhdGUgdG8gMC45LjQALSBsaWJubS1nbGliOiB1cGRhdGVkIGZvciBuZXcgc3ltYm9scyB0aGUgYXBwbGV0IHdhbnRzAC0gYXBwbGV0OiBtb3ZlIHRvIG5ldHdvcmstbWFuYWdlci1hcHBsZXQgUlBNCi0gZWRpdG9yOiBtb3ZlIHRvIG5tLWNvbm5lY3Rpb24tZWRpdG9yIFJQTQotIGxpYm5tLWd0azogbW92ZSB0byBsaWJubS1ndGsgUlBNAC0gVXBkYXRlIHRvIDAuOS4zLjk5NyAoMC45LjQtcmMxKQotIGNvcmU6IGZpeCBwb3NzaWJsZSBXaUZpIGhhbmcgd2hlbiBjb25uZWN0aW5nIHRvIEFkLUhvYyBuZXR3b3JrcwotIGNvcmU6IGVuaGFuY2VkIElQdjYgY29tcGF0aWJpbGl0eQotIGNvcmU6IHByb3h5IEROU1NFQyBkYXRhIHdoZW4gdXNpbmcgdGhlICdkbnNtYXNxJyBjYWNoaW5nIG5hbWVzZXJ2ZXIgcGx1Z2luCi0gY29yZTogYWxsb3cgVlBOcyB0byBzcGVjaWZ5IG11bHRpcGxlIGRvbWFpbiBuYW1lcyBnaXZlbiBieSB0aGUgc2VydmVyCi0gY29yZTogZml4IGFuIGlzc3VlIGNyZWF0aW5nIG5ldyBJbmZpbmlCYW5kIGNvbm5lY3Rpb25zCi0gY29yZS9hcHBsZXQvZWRpdG9yOiBkaXNhYmxlIFdpRmkgQWQtSG9jIFdQQSBjb25uZWN0aW9ucyB1bnRpbCBrZXJuZWwgYnVncyBhcmUgZml4ZWQALSBjb3JlOiBmaXggaXNzdWUgd2l0aCBjYXJyaWVyIGNoYW5nZXMgbm90IGJlaW5nIHJlY29nbml6ZWQgKHJoICM4MDA2OTApCi0gZWRpdG9yOiB3YXJuIHVzZXIgaWYgQ0EgY2VydGlmaWNhdGUgaXMgbGVmdCBibGFuawAtIGNvcmU6IGZpeCBhIGNyYXNoIHdpdGggaXB3MjIwMCBkZXZpY2VzIGFuZCBhZGhvYyBuZXR3b3JrcwotIGNvcmU6IGZpeCBJUHY2IGFkZHJlc3Npbmcgb24gbmV3ZXIga2VybmVscwotIGNvcmU6IGZpeCBpc3N1ZSB3aXRoIFZQTiBwbHVnaW4gcGFzc3dvcmRzIChyaCAjODAyNTQwKQotIGNsaTogZW5oYW5jZW1lbnRzIGZvciBCb25kaW5nLCBWTEFOLCBhbmQgT0xQQyBtZXNoIGRldmljZXMKLSBpZmNmZy1yaDogZml4IHF1b3RpbmcgV1BBIHBhc3NwaHJhc2VzIHRoYXQgaW5jbHVkZSBxdW90ZXMgKHJoICM3OTgxMDIpCi0gbGlibm0tZ2xpYjogZml4IHNvbWUgaXNzdWVzIHdpdGggZHVwbGljYXRlIGRldmljZXMgc2hvd24gaW4gbWVudXMALSBVcGRhdGUgdG8gMC45LjMuOTk1ICgwLjkuNC1iZXRhMSkKLSBjb3JlOiBhZGQgc3VwcG9ydCBmb3IgYm9uZGluZyBhbmQgVkxBTiBpbnRlcmZhY2VzCi0gY29yZTogYWRkIHN1cHBvcnQgZm9yIEludGVybmV0IGNvbm5lY3Rpdml0eSBkZXRlY3Rpb24KLSBjb3JlOiBhZGQgc3VwcG9ydCBmb3IgSVB2NiBQcml2YWN5IEV4dGVuc2lvbnMKLSBjb3JlOiBmaXggaW50ZXJhY3Rpb24gd2l0aCBmaXJld2FsbGQgcmVzdGFydHMALSBkaXNhYmxlIFdpTUFYIHBsdWdpbiBvbiBzMzkwKHgpAC0gUHV0IFdpTUFYIHBsdWdpbiBmaWxlcyBpbiB0aGUgcmlnaHQgc3VicGFja2FnZQAtIFVwZGF0ZSB0byAwLjkuNCBzbmFwc2hvdAotIHdpbWF4OiBlbmFibGUgb3B0aW9uYWwgc3VwcG9ydCBmb3IgSW50ZWwgV2lNQVggZGV2aWNlcwotIGNvcmU6IHVzZSBubDgwMjExIGZvciBXaUZpIGRldmljZSBjb250cm9sCi0gY29yZTogYWRkIGJhc2ljIHN1cHBvcnQgZm9yIEluZmluaWJhbmQgSVAgaW50ZXJmYWNlcwotIGNvcmU6IGFkZCBiYXNpYyBzdXBwb3J0IGZvciBib25kZWQgaW50ZXJmYWNlcwotIGNvcmU6IGluLXByb2Nlc3MgSVAgY29uZmlndXJhdGlvbiBubyBsb25nZXIgYmxvY2tzIGNvbm5lY3RlZCBzdGF0ZQAtIFJlYnVpbGQALSBSZWJ1aWx0IGZvciBodHRwczovL2ZlZG9yYXByb2plY3Qub3JnL3dpa2kvRmVkb3JhXzE3X01hc3NfUmVidWlsZAAtIFJlYnVpbGQgZm9yIGxpYmdub21lLWJsdWV0b290aC5zby45AC0gY29yZTogZml4IHBvc3NpYmxlIGNyYXNoIHdoZW4gdGFsa2luZyB0byBNb2RlbU1hbmFnZXIKLSBjb3JlOiBpbXByb3ZlIGhhbmRsaW5nIG9mIHJma2lsbCBvbiBzb21lIG1hY2hpbmVzIChlZWVwYyAxMDA1SEEgYW5kIG90aGVycykKLSBpZmNmZy1yaDogZG9uJ3QgdXNlIHNwYWNlcyBpbiBpZmNmZyBmaWxlIG5hbWVzIChyaCAjNzQyMjczKQotIGNvcmU6IGFjY2VwdCBJUHY2IFJvdXRlciBBZHZlcnRpc2VtZW50cyB3aGVuIGZvcndhcmRpbmcgaXMgb24KLSBjb3JlOiBidW1wIGRuc21hc3EgY2FjaGUgc2l6ZSB0byA0MDAgZW50cmllcwotIGNvcmU6IGVuc3VyZSBJUHY2IHN0YXRpYyByb3V0ZXMgYXJlIGZsdXNoZWQgd2hlbiBkZXZpY2UgaXMgZGVhY3RpdmF0ZWQKLSBpZmNmZy1yaDogZml4IGNoYW5naW5nIFdQQSBjb25uZWN0aW9ucyB0byBXRVAKLSBjb3JlOiBmaXggc2V0dGluZyBob3N0bmFtZSBmcm9tIERIQ1AgKHJoICM3MTkxMDApCi0gbGlibm0tZ2xpYjogZml4IHZhcmlvdXMgR09iamVjdCBpbnRyb3NwZWN0aW9uIGlzc3VlcyAocmggIzc0NzMwMikKLSBjb3JlOiBkb24ndCBjaGFuZ2Ugcm91dGluZyBvciBETlMgaWYgbm8gZGV2aWNlcyBhcmUgbWFuYWdlZAotIGNvcmU6IGVuc3VyZSBJUHY2IFJBLXByb3ZpZGVkIHJvdXRlcyBhcmUgaG9ub3JlZAAtIFJlYnVpbHQgZm9yIGdsaWJjIChyaCAjNzQ3Mzc3KQotIGNvcmU6IGZpeCBzZXR0aW5nIGhvc3RuYW1lIGZyb20gREhDUCBvcHRpb25zIChyaCAjNzE5MTAwKQotIHNraXAgYSByZWxlYXNlIHRvIGtlZXAgdXAgd2l0aCBGMTYALSBjb3JlOiBmaXggbG9jYXRpb24gb2Ygd2lmaS51aSAocmggIzc0MTQ0OCkALSBjb3JlOiBpZmNmZy1yaDogcmVtb3ZlIG5ld2xpbmVzIHdoZW4gd3JpdGluZyB0byBpZmNmZyBmaWxlcyAoQ1ZFLTIwMTEtMzM2NCkgKHJoICM3MzczMzgpCi0gY29yZTogY2hhbmdlIGlzY3NpYWRtIHBhdGggdG8gL3NiaW4vaXNjc2lhZG0gaW4gaWZjZmctcmggcGx1Z2luIChyaCAjNzQwNzUzKQotIGNvcmU6IGZpeCByZWZjb3VudGluZyB3aGVuIGRlbGV0aW5nIGEgZGVmYXVsdCB3aXJlZCBjb25uZWN0aW9uIChscDo3OTc4NjgpAC0gVXBkYXRlIHRvIDAuOS4xLjkwICgwLjkuMi1iZXRhMSkKLSBjb3JlOiBmaXggSVB2NiBsaW5rLWxvY2FsIEROUyBzZXJ2ZXJzIGluIHRoZSBkbnNtYXNxIEROUyBwbHVnaW4KLSBjbGk6IGFkZCBhYmlsaXR5IHRvIGRlbGV0ZSBjb25uZWN0aW9ucwotIGtleWZpbGU6IGZpeCBhbiBpc3N1ZSB3aXRoIGR1cGxpY2F0ZWQga2V5ZmlsZSBjb25uZWN0aW9ucwotIGNvcmU6IGVuc3VyZSB0aGUgJ25vdmonIG9wdGlvbiBpcyBwYXNzZWQgdGhyb3VnaCB0byBwcHBkCi0gY29yZTogc3RvcmUgdGltZXN0YW1wcyBmb3IgVlBOIGNvbm5lY3Rpb25zIHRvbyAocmggIzcyNTM1MykALSBmaXggc3lzdGVtZCBzY3JpcHRsZXRzIGFuZCB0cmlnZ2VyAC0gVXBkYXRlIHRvIDAuOSByZWxlYXNlCi0gY29yZTogZml4IGlzc3VlIHdoZXJlIHNjYW4gcmVzdWx0cyBjb3VsZCBiZSBpZ25vcmVkCi0gY29yZTogZW5zdXJlIGFnZW50IHNlY3JldHMgYXJlIHByZXNlcnZlZCB3aGVuIHVwZGF0aW5nIGNvbm5lY3Rpb25zCi0gY29yZTogZG9uJ3QgYXV0b2Nvbm5lY3QgZGlzYWJsZWQgbW9kZW1zCi0gY29yZTogZml4IHJhY2Ugd2hlbiBjaGVja2luZyBtb2RlbSBlbmFibGVkL2Rpc2FibGVkIHN0YXR1cyBhZnRlciBkaXNhYmxpbmcKLSBjb3JlOiBlbnN1cmUgbmV3bHkgaW5zdGFsbGVkIFZQTiBwbHVnaW5zIGNhbiBhY3R1YWxseSB0YWxrIHRvIE5NCi0gY29yZTogYWRkIHN1cHBvcnQgZm9yIDgwMi4xWCBjZXJ0aWZpY2F0ZSBzdWJqZWN0IG1hdGNoaW5nCi0gbGlibm0tZ2xpYjogdmFyaW91cyBpbnRyb3NwZWN0aW9uIGZpeGVzCi0gYXBwbGV0L2VkaXRvcjogdXBkYXRlZCB0cmFuc2xhdGlvbnMALSBBZGQgc29tZSBwYXRjaGVzIGZvciBzb21lIGJsb2NrZXIgKHJoICM3Mjc1MDEpAC0gY29yZTogdXBkYXRlZCBSdXNzaWFuIHRyYW5zbGF0aW9uIChyaCAjNjUyOTA0KQotIGNvcmU6IGZpeCBwb3NzaWJsZSBjcmFzaCBpZiBzZWNyZXRzIGFyZSBtaXNzaW5nCi0gY29yZTogYXBwZW5kIGludGVyZmFjZSBuYW1lIGZvciBJUHY2IGxpbmstbG9jYWwgRE5TIHNlcnZlciBhZGRyZXNzZXMgKHJoICM3MjAwMDEpCi0gY29yZTogZml4IHNldHRpbmcgaG9zdG5hbWUgZnJvbSBESENQIG9wdGlvbnMgKHJoICM3MTkxMDApCi0gbGlibm0tdXRpbDogR09iamVjdCBpbnRyb3NwZWN0aW9uIGFubm90YXRpb24gZml4ZXMKLSBsaWJubS11dGlsOiBlbnN1cmUgSVAgYWRkcmVzcy9yb3V0ZSBwcmVmaXhlcyBhcmUgdmFsaWQKLSBpZmNmZy1yaDogcmVhZCBhbm9ueW1vdXMgaWRlbnRpdHkgZm9yIDgwMi4xeCBQRUFQIGNvbm5lY3Rpb25zIChyaCAjNzA4NDM2KQotIGFwcGxldDogc2hvdyBub3RpZmljYXRpb25zIG9uIENETUEgaG9tZS9yb2FtaW5nIGNoYW5nZXMKLSBhcHBsZXQ6IGZpeCB2YXJpb3VzIGlzc3VlcyBzYXZpbmcgVlBOIHNlY3JldHMKLSBlZGl0b3I6IGFsbG93IGV4cG9ydGluZyBWUE4gc2VjcmV0cwotIGVkaXRvcjogZGVmYXVsdCB0byBJUHY2ICJhdXRvbWF0aWMiIGFkZHJlc3NpbmcgbW9kZQAtIGNvcmU6IGVuc3VyZSB1c2VycyBhcmUgYXV0aG9yaXplZCBmb3Igc2hhcmVkIHdpZmkgY29ubmVjdGlvbnMgKENWRS0yMDExLTIxNzYpIChyaCAjNzE1NDkyKQotIGNvcmU6IHJldHJ5IGZhaWxlZCBjb25uZWN0aW9ucyBhZnRlciA1IG1pbnV0ZSB0aW1lb3V0Ci0gY29yZTogaW1tZWRpYXRlbHkgcmVxdWVzdCBuZXcgODAyLjF4ICdhbHdheXMgYXNrJyBwYXNzd29yZHMgaWYgdGhleSBmYWlsCi0gY29yZTogYWRkIE1BQyBibGFja2xpc3RpbmcgY2FwYWJpbGl0eSBmb3IgV2lGaSBhbmQgV2lyZWQgY29ubmVjdGlvbnMKLSBjb3JlOiByZXRyeSBmYWlsZWQgY29ubmVjdGlvbnMgd2hlbiBuZXcgdXNlcnMgbG9nIGluIChyaCAjNzA2MjA0KQotIGFwcGxldDogdXBkYXRlZCB0cmFuc2xhdGlvbnMKLSBjb3JlOiBkcm9wIGNvbXBhdCBpbnRlcmZhY2Ugbm93IHRoYXQgS0RFIGJpdHMgYXJlIHVwZGF0ZWQgdG8gTk0gMC45IEFQSQAtIGNvcmU6IGRvbid0IGNhY2hlICIobm9uZSkiIGhvc3RuYW1lIGF0IHN0YXJ0dXAgKHJoICM3MDYwOTQpCi0gY29yZTogZml4IGhhbmRsaW5nIG9mIFZQTiBjb25uZWN0aW9ucyB3aXRoIG9ubHkgc3lzdGVtLW93bmVkIHNlY3JldHMKLSBjb3JlOiBmaXggb3B0aW9uYWwgd2FpdGluZyBmb3IgbmV0d29ya2luZyBhdCBzdGFydHVwIGJlaGF2aW9yIChyaCAjNzEwNTAyKQotIGlmY2ZnLXJoOiBmaXggcG9zc2libGUgY3Jhc2hlcyBpbiBlcnJvciBjYXNlcwotIGlmY2ZnLXJoOiBmaXggdmFyaW91cyBJUHY0IGFuZCBJUHY2IGhhbmRsaW5nIGlzc3VlcwotIGFwcGxldDogYWRkIG5vdGlmaWNhdGlvbnMgb2YgR1NNIG1vYmlsZSBicm9hZGJhbmQgcmVnaXN0cmF0aW9uIHN0YXR1cwotIGVkaXRvcjogbW92ZSBzZWNyZXRzIHdoZW4gbWFraW5nIGNvbm5lY3Rpb25zIGF2YWlsYWJsZSB0byBhbGwgdXNlcnMgb3IgcHJpdmF0ZQotIGFwcGxldDogZG9uJ3Qgc2hvdyBpcnJlbGV2YW50IG9wdGlvbnMgd2hlbiBhc2tpbmcgZm9yIHBhc3N3b3JkcwAtIGtleWZpbGU6IGJldHRlciBoYW5kbGluZyBvZiBtaXNzaW5nIGNlcnRpZmljYXRlcy9wcml2YXRlIGtleXMKLSBjb3JlOiBmaXggaXNzdWVzIGhhbmRsaW5nICJhbHdheXMtYXNrIiB3aXJlZCBhbmQgV2lGaSA4MDIuMXggY29ubmVjdGlvbnMgKHJoICM3MDM3ODUpCi0gY29yZTogZml4IGF1dG9tYXRpYyBoYW5kbGluZyBvZiBoaWRkZW4gV2lGaSBuZXR3b3JrcyAocmggIzcwNzQwNikKLSBlZGl0b3I6IGZpeCBwb3NzaWJsZSBjcmFzaCBhZnRlciByZWFkaW5nIG5ldHdvcmsgY29ubmVjdGlvbnMgKHJoICM3MDY5MDYpCi0gZWRpdG9yOiBtYWtlIEVudGVyL1JldHVybiBrZXkgY2xvc2UgV2lGaSBwYXNzd29yZCBkaWFsb2dzIChyaCAjNzA4NjY2KQAtIEJ1bXAgZm9yIENWRS0yMDExLTE5NDMgKG5vIGNoYW5nZXMsIG9ubHkgYSByZWJ1aWxkKQAtIGVkaXRvcjogZml4IHJlc2l6aW5nIG9mIFVJIGVsZW1lbnRzIChyaCAjNzA3MjY5KQotIGNvcmU6IHJldHJ5IHdpcmVkIGNvbm5lY3Rpb25zIHdoZW4gY2FibGUgaXMgcmVwbHVnZ2VkCi0gY29yZTogZml4IGEgZmV3IHdhcm5pbmdzIGFuZCByZW1vdmUgc29tZSBsZWZ0LW92ZXIgZGVidWdnaW5nIGNvZGUALSBjb21wYXQ6IGZpeCBhY3RpdmF0aW9uL2RlYWN0aXZhdGlvbiBvZiBWUE4gY29ubmVjdGlvbnMgKHJoICM2OTk3ODYpCi0gY29yZTogZml4IGF1dG9kZXRlY3Rpb24gb2YgcHJldmlvdXNseS11c2VkIGhpZGRlbiB3aWZpIG5ldHdvcmtzCi0gY29yZTogc2lsZW5jZSBlcnJvciBpZiBDb25zb2xlS2l0IGRhdGFiYXNlIGRvZXMgbm90IHlldCBleGlzdCAocmggIzY5NTYxNykKLSBjb3JlOiBmaXggQWQtSG9jIGZyZXF1ZW5jeSBoYW5kbGluZyAocmggIzY5OTIwMykKLSBjb3JlOiBmaXhlcyBmb3IgbWlncmF0ZWQgT3BlbkNvbm5lY3QgVlBOIHBsdWdpbiBjb25uZWN0aW9ucwotIGNvcmU6IHZhcmlvdXMgZml4ZXMgZm9yIFZQTiBjb25uZWN0aW9uIHNlY3JldHMgaGFuZGxpbmcKLSBjb3JlOiBzZW5kIG9ubHkgc2hvcnQgaG9zdG5hbWUgdG8gREhDUCBzZXJ2ZXJzIChyaCAjNjk0NzU4KQotIGNvcmU6IGJldHRlciBoYW5kbGluZyBvZiBQS0NTIzggcHJpdmF0ZSBrZXlzCi0gY29yZTogZml4IGRpc3BhdGNoZXIgc2NyaXB0IGludGVyZmFjZSBuYW1lIGhhbmRsaW5nCi0gZWRpdG9yOiBmaXggcG90ZW50aWFsIGNyYXNoIHdoZW4gY29ubmVjdGlvbiBpcyBpbnZhbGlkIChyaCAjNzA0ODQ4KQotIGVkaXRvcjogYWxsb3cgXyBhcyBhIHZhbGlkIGNoYXJhY3RlciBmb3IgR1NNIEFQTnMALSBjb3JlOiBmaXggcG9zc2libGUgY3Jhc2ggd2hlbiBjb25uZWN0aW9ucyBhcmUgZGVsZXRlZAotIGNvcmU6IGZpeCBleHBvcnRlZCBzeW1ib2xzIGluIGxpYm5tLXV0aWwgYW5kIGxpYm5tLWdsaWIKLSBjb3JlL2FwcGxldDogdXBkYXRlZCB0cmFuc2xhdGlvbnMALSBjb3JlOiBlbnN1cmUgREVSIGZvcm1hdCBjZXJ0aWZpY2F0ZXMgYXJlIGNvcnJlY3RseSByZWNvZ25pemVkIChyaCAjNjk5NTkxKQotIGNvcmU6IGZpeCBXSU5TIHNlcnZlciBoYW5kbGluZyBpbiBjbGllbnQgaGVscGVyIGxpYnJhcmllcwotIGNvcmU6IGVuaGFuY2UgZGlzcGF0Y2hlciBzY3JpcHQgZW52aXJvbm1lbnQgdG8gaW5jbHVkZSBJUHY2IGFuZCBWUE4gZGV0YWlscwotIGFwcGxldDogbWlncmF0ZSBvcGVuc3dhbiBjb25uZWN0aW9ucyB0byAwLjkKLSBlZGl0b3I6IGltcHJvdmUgdXNhYmlsaXR5IG9mIGVkaXRpbmcgSVAgYWRkcmVzc2VzIChyaCAjNjk4MTk5KQAtIGNvcmU6IGVuYWJsZSBvcHRpbWl6ZWQgYmFja2dyb3VuZCByb2FtaW5nIGZvciBXUEEgRW50ZXJwcmlzZSBjb25maWdzCi0gY29yZTogYmV0dGVyIGhhbmRsaW5nIG9mIFdpRmkgYW5kIFdpTUFYIHJma2lsbCAocmggIzU5OTAwMikKLSBhcHBsZXQ6IGZpeCBjcmFzaCBkZXRlY3RpbmcgQmx1ZXRvb3RoIERVTiBkZXZpY2VzIGEgc2Vjb25kIHRpbWUKLSBpZmNmZy1yaDogZml4IG1hbmFnZWQvdW5tYW5hZ2VkIGNoYW5nZXMgd2hlbiByZW1vdmluZyBjb25uZWN0aW9ucyAocmggIzY5ODIwMikALSBjb3JlOiBzeXN0ZW1kIGFuZCBzdGFydHVwIGVuaGFuY2VtZW50cyBmb3IgTkZTIG1vdW50cwotIGNvcmU6IG1vcmUgZWZmaWNpZW50IHN0YXJ0dXAgcHJvY2VzcwotIGNvcmU6IGZpeCBoYW5kbGluZyBvZiBtdWx0aXBsZSBsb2dpbnMgd2hlbiBvbmUgaXMgaW5hY3RpdmUKLSBjb3JlOiBmaXggaGFuZGxpbmcgb2YgUzM5MC9IZXJjdWxlcyBDVEMgbmV0d29yayBpbnRlcmZhY2VzIChyaCAjNjQxOTg2KQotIGNvcmU6IHN1cHBvcnQgRWFzeXRldGhlciBpbnRlcmZhY2VzIGZvciBBbmRyb2lkIHBob25lcwotIGNvcmU6IGZpeCBoYW5kbGluZyBvZiBXV0FOIGVuYWJsZS9kaXNhYmxlIHN0YXRlcwotIGlmY2ZnLXJoOiBoYXJtb25pemUgaGFuZGxpbmcgaWYgSVBBRERSL1BSRUZJWC9ORVRNQVNLIHdpdGggaW5pdHNjcmlwdHMgKHJoICM2NTg5MDcpCi0gYXBwbGV0OiBmaXggY29ubmVjdGlvbiB0byBXUEEgRW50ZXJwcmlzZSBuZXR3b3JrcyAocmggIzY5NDc2NSkALSBjb3JlOiBmaXggaGFuZGxpbmcgb2YgaW5maW5pdGUgSVB2NiBSRE5TUyB0aW1lb3V0cyAocmggIzY4OTI5MSkALSBVcGRhdGUgdG8gMC44Ljk5OCAoMC45LjAtcmMxKQotIGNvcmU6IGZpeCBuZWFyLWluZmluaXRlIHJlcXVlc3RzIGZvciBwYXNzd29yZHMgKHJoICM2OTI3ODMpCi0gY29yZTogZml4IGhhbmRsaW5nIG9mIHdpcmVkIDgwMi4xeCBjb25uZWN0aW9ucwotIGNvcmU6IGlnbm9yZSBOb2tpYSBQQy1TdWl0ZSBldGhlcm5ldCBkZXZpY2VzIHdlIGNhbid0IHVzZSB5ZXQKLSBhcHBsZXQ6IG1pZ3JhdGUgMC44IE9wZW5WUE4gcGFzc3dvcmRzIHRvIDAuOSBmb3JtYXRzAC0gY29yZTogcmVzdXJyZWN0IGRlZmF1bHQgVlBOIHVzZXJuYW1lCi0gY29yZTogZG9uJ3Qgc3RvbXAgb24gY3J5cHRvIGxpYnJhcnkgdXNlcnMgYnkgZGUtaW5pdGluZyB0aGUgY3J5cHRvIGxpYnJhcnkALSBjb3JlOiBmaXggY3JlYXRpb24gb2YgZGVmYXVsdCB3aXJlZCBjb25uZWN0aW9ucwotIGNvcmU6IGZpeCByZXF1ZXN0aW5nIG5ldyBzZWNyZXRzIHdoZW4gb2xkIG9uZXMgZmFpbCAoZXggY2hhbmdpbmcgV0VQIGtleXMpCi0gZWRpdG9yOiBlbnN1cmUgYWxsIHBhZ2VzIGFyZSBzZW5zaXRpdmUgYWZ0ZXIgcmV0cmlldmluZyBzZWNyZXRzCi0gZWRpdG9yOiBmaXggY3Jhc2ggd2hlbiBzY3JvbGxpbmcgdGhyb3VnaCBjb25uZWN0aW9uIGxpc3RzIChyaCAjNjkzNDQ2KQotIGFwcGxldDogZml4IGNyYXNoIGFmdGVyIHVzaW5nIHRoZSB3aWZpIG9yIHdpcmVkIHNlY3JldHMgZGlhbG9ncyAocmggIzY5MzQ0NikALSBGaXggdHJpZ2dlciB0byBlbmFibGUgdGhlIHN5c3RlbWQgc2VydmljZSBmb3IgdXBncmFkZXMgKHJoICM2Nzg1NTMpAC0gY29yZTogZml4IGNvbm5lY3Rpb24gZGVhY3RpdmF0aW9uIG9uIHRoZSBjb21wYXQgaW50ZXJmYWNlCi0gY29yZTogZ2l2ZSBkZWZhdWx0IHdpcmVkIGNvbm5lY3Rpb25zIGEgbW9yZSBmcmllbmRseSBuYW1lCi0gY29yZTogZml4IGJhc2UgdHlwZSBvZiBuZXdseSBjcmVhdGVkIHdpcmVkIGNvbm5lY3Rpb25zCi0gYXBwbGV0OiBtYW55IHVwZGF0ZWQgdHJhbnNsYXRpb25zAC0gY29yZTogZml4IHBvc3NpYmxlIGxpYm5tLWdsaWIgY3Jhc2ggd2hlbiBhY3RpdmF0aW5nIGNvbm5lY3Rpb25zCi0gYXBwbGV0OiBmaXggdmFyaW91cyBuYW1pbmcgYW5kIGRpYWxvZyB0aXRsZSBpc3N1ZXMALSBubS12ZXJzaW9uLmggc2hvdWxkIGJlIGluIE5ldHdvcmtNYW5hZ2VyLWRldmVsLCBub3QgLWdsaWItZGV2ZWwgKHJoICM2ODU0NDIpAC0gY29yZTogYWRkIGNvbXBhdGliaWxpdHkgbGF5ZXIgZm9yIEtERSBQbGFzbWEgbmV0d29yayBpbmZyYXN0cnVjdHVyZQAtIFVwZGF0ZSB0byAwLjguOTk3ICgwLjktYmV0YTMpCi0gaWZjZmctcmg6IGZpeCByZWFkaW5nIGFuZCB3cml0aW5nIG9mIER5bmFtaWMgV0VQIGNvbm5lY3Rpb25zIHVzaW5nIExFQVAgYXMgdGhlIGVhcCBtZXRob2QKLSB3aWZpOiBmaXggc2lnbmFsIHN0cmVuZ3RoIGZvciBzY2FubmVkIGFjY2VzcyBwb2ludHMgd2l0aCBzb21lIGRyaXZlcnMKLSBhcHBsZXQ6IHRyYW5zbGF0aW9uIHVwZGF0ZXMALSBVcGRhdGUgdG8gMC44Ljk5NiAoMC45LWJldGEyKQAtIGFwcGxldDogZml4IGJ1cyBuYW1lIG1vcmUALSBhcHBsZXQ6IGZpeCBidXMgbmFtZQAtIEZpeCBzeXN0ZW1kIHJlcXVpcmVzAC0gVXBkYXRlIHRvIE5ldHdvcmtNYW5hZ2VyIDAuOS1iZXRhMQotIGNvcmU6IGNvbnNvbGlkYXRlIHVzZXIgYW5kIHN5c3RlbSBzZXR0aW5ncyBzZXJ2aWNlcyBpbnRvIE5NIGl0c2VsZgotIGNvcmU6IGFkZCBXaU1BWCBzdXBwb3J0Ci0gYXBwbGV0OiBzdXBwb3J0IEZhc3QgVXNlciBTd2l0Y2hpbmcALSBSZWJ1aWxkIGFnYWluc3QgbmV3ZXIgZ3RrAC0gUmVidWlsdCBmb3IgaHR0cHM6Ly9mZWRvcmFwcm9qZWN0Lm9yZy93aWtpL0ZlZG9yYV8xNV9NYXNzX1JlYnVpbGQALSBSZWJ1aWxkIGFnYWluc3QgbmV3IGd0awAtIEhhbmRsZSBtb2RlbSBJUCBpbnRlcmZhY2UgY2hhbmdlcyBhZnRlciBkZXZpY2UgaXMgcmVjb2duaXplZAAtIFJlYnVpbGQgYWdhaW5zdCBuZXcgZ3RrMwAtIHVzZSAtLWZvcmNlIGluIGF1dG9yZWNvbmYgdG8gZml4IEZUQkZTAC0gUmVidWlsZCBhZ2FpbnN0IG5ld2VyIGd0awAtIFVwZGF0ZSB0byAwLjguMgAtIFJlYnVpbGQgYWdhaW5zdCBsaWJub3RpZnkgMC43Ci0gbWlzYyBndGsgYnVpbGQgZml4ZXMALSBjb3JlOiBwcmVzZXJ2ZSBXaUZpIEVuYWJsZWQgc3RhdGUgYWNyb3NzIHJlYm9vdCBhbmQgc3VzcGVuZC9yZXN1bWUALSBjb3JlOiBmaXggc3VzcGVuZC9yZXN1bWUgcmVncmVzc2lvbiAocmggIzYzODY0MCkKLSBjb3JlOiBmaXggaXNzdWUgY2F1c2luZyBzb21lIG5tY2xpIHJlcXVlc3RzIHRvIGJlIGlnbm9yZWQALSBjb3JlOiBwcmVzZXJ2ZSBjdXN0b20gbG9jYWwtbWFwcGVkIGhvc3RuYW1lcyBpbiAvZXRjL2hvc3RzIChyaCAjNjI3MjY5KQAtIGNvcmU6IHJlbW92ZSBzdGFsZSAvZXRjL2hvc3RzIG1hcHBpbmdzIChyaCAjNjMwMTQ2KQAtIGNvcmU6IGFkZCBkaXNwYXRjaGVyIGV2ZW50cyBvbiBESENQdjQgYW5kIERIQ1B2NiBsZWFzZSBjaGFuZ2VzCi0gY29yZTogZW5mb3JjZSBhY2Nlc3MgcGVybWlzc2lvbnMgd2hlbiBlbmFibGluZy9kaXNhYmxpbmcgV2lGaSBhbmQgV1dBTiAocmggIzYyNjMzNykKLSBjb3JlOiBsaXN0ZW4gZm9yIFVQb3dlciBzdXNwZW5kL3Jlc3VtZSBzaWduYWxzCi0gYXBwbGV0OiBmaXggZGlzYWJsZWQgRW5hYmxlIE5ldHdvcmtpbmcgYW5kIEVuYWJsZSBXaXJlbGVzcyBtZW51IGl0ZW1zIChyaCAjNjI3MzY1KQotIGFwcGxldDogdXBkYXRlZCB0cmFuc2xhdGlvbnMKLSBhcHBsZXQ6IG9ic2N1cmUgTW9iaWxlIEJyb2FkYmFuZCBQSU4gaW4gc2Vjb25kYXJ5IHVubG9jayBkaWFsb2cALSBjb3JlOiBmaXggc29tZSBzeXN0ZW1kIGludGVyYWN0aW9uIGlzc3VlcwAtIGNvcmU6IHJlYnVpbGQgdG8gZml4IHBvbGtpdCAwLjk3IGJ1aWxkIGlzc3VlCi0gYXBwbGV0OiB1cGRhdGVkIHRyYW5zbGF0aW9ucwAtIGNvcmU6IHJlYnVpbGQgdG8gZml4IGRidXMtZ2xpYiBzZWN1cml0eSBpc3N1ZSAoQ1ZFLTIwMTAtMTE3MikgKHJoICM1ODUzOTQpAC0gY29yZTogcXVpZXQgYW5ub3lpbmcgd2FybmluZ3MgKHJoICM2MTI5OTEpCi0gY29yZTogZml4IHJldHJpZXZhbCBvZiB2YXJpb3VzIElQIG9wdGlvbnMgaW4gbGlibm0tZ2xpYiAocmggIzYxMTE0MSkKLSBjb3JlOiBzaGlwIE5ldHdvcmtNYW5hZ2VyLmNvbmYgaW5zdGVhZCBvZiBkZXByZWNhdGVkIG5tLXN5c3RlbS1zZXR0aW5ncy5jb25mIChyaCAjNjA2MTYwKQotIGNvcmU6IGFkZCBzaG9ydCBob3N0bmFtZSB0byAvZXRjL2hvc3RzIHRvbyAocmggIzYyMTkxMCkKLSBjb3JlOiByZWNoZWNrIGF1dG9hY3RpdmF0aW9uIHdoZW4gbmV3IHN5c3RlbSBjb25uZWN0aW9ucyBhcHBlYXIKLSBjb3JlOiBlbmFibGUgREhDUHY2LW9ubHkgY29uZmlndXJhdGlvbnMgKHJoICM2MTI0NDUpCi0gY29yZTogZG9uJ3QgZmFpbCBjb25uZWN0aW9uIGltbWVkaWF0ZWx5IGlmIERIQ1AgbGVhc2UgZXhwaXJlcyAocmggIzYxNjA4NCkgKHJoICM1OTA4NzQpCi0gY29yZTogZml4IGVkaXRpbmcgb2YgUFBQb0Ugc3lzdGVtIGNvbm5lY3Rpb25zCi0gY29yZTogd29yayBhcm91bmQgdHdpdGNoeSBmcmVxdWVuY3kgcmVwb3J0aW5nIG9mIHZhcmlvdXMgd2lmaSBkcml2ZXJzCi0gY29yZTogZG9uJ3QgdGVhciBkb3duIHVzZXIgY29ubmVjdGlvbnMgb24gY29uc29sZSBjaGFuZ2VzIChyaCAjNjE0NTU2KQotIGNsaTogd2FpdCBhIGJpdCBmb3IgTk0ncyBwZXJtaXNzaW9ucyBjaGVjayB0byBjb21wbGV0ZSAocmggIzYxNDg2NikKLSBpZmNmZy1yaDogaWdub3JlIEJSSURHRSBhbmQgVkxBTiBjb25maWdzIGFuZCB0cmVhdCBhcyB1bm1hbmFnZWQgKHJoICM2MTk4NjMpCi0gbWFuOiBhZGQgbWFucGFnZSBmb3Igbm0tb25saW5lCi0gYXBwbGV0OiBmaXggY3Jhc2ggc2F2aW5nIGlnbm9yZS1taXNzaW5nLUNBLWNlcnQgcHJlZmVyZW5jZSAocmggIzYxOTc3NSkKLSBhcHBsZXQ6IGhpZGUgUElOL1BVSyBieSBkZWZhdWx0IGluIHRoZSBtb2JpbGUgUElOL1BVSyBkaWFsb2cgKHJoICM2MTUwODUpCi0gYXBwbGV0OiBlbnN1cmUgRW50ZXIgY2xvc2VzIHRoZSBQSU4vUFVLIGRpYWxvZyAocmggIzYxMTgzMSkKLSBhcHBsZXQ6IGZpeCBhbm90aGVyIGNyYXNoIGluIGlnbm9yZS1DQS1jZXJ0aWZpY2F0ZSBoYW5kbGluZyAocmggIzU1NzQ5NSkKLSBlZGl0b3I6IGZpeCBoYW5kbGluZyBvZiBXaXJlZC9zMzkwIGNvbm5lY3Rpb25zIChyaCAjNjE4NjIwKQotIGVkaXRvcjogZml4IGNyYXNoIHdoZW4gY2FuY2VsaW5nIGVkaXRpbmcgaW4gSVAgYWRkcmVzcyBwYWdlcyAocmggIzYxMDg5MSkKLSBlZGl0b3I6IGZpeCBoYW5kbGluZyBvZiBzMzkwLXNwZWNpZmljIG9wdGlvbnMKLSBlZGl0b3I6IHJlYWxseSBmaXggY3Jhc2ggd2hlbiBjaGFuZ2luZyBzeXN0ZW0gY29ubmVjdGlvbnMgKHJoICM2MDM1NjYpAC0gY29yZTogcmVhZCBubS1zeXN0ZW0tc2V0dGluZ3MuY29uZiBiZWZvcmUgTmV0d29ya01hbmFnZXIuY29uZiAocmggIzYwNjE2MCkKLSBjb3JlOiBmaXggZWRpdGluZyBzeXN0ZW0gRFNMIGNvbm5lY3Rpb25zIHdoZW4gdXNpbmcga2V5ZmlsZSBwbHVnaW4KLSBjb3JlOiB3b3JrIGFyb3VuZCBpbmNvbnNpc3RlbnQgcHJvcHJpZXRhcnkgZHJpdmVyIGFzc29jaWF0ZWQgQVAgcmVwb3J0aW5nCi0gY29yZTogZW5zdXJlIGVtcHR5IFZQTiBzZWNyZXRzIGFyZSBub3QgdXNlZCAocmggIzU4Nzc4NCkKLSBjb3JlOiBkb24ndCByZXF1ZXN0IFdpRmkgc2NhbnMgd2hlbiBjb25uZWN0aW9uIGlzIGxvY2tlZCB0byBhIHNwZWNpZmljIEJTU0lECi0gY2xpOiBzaG93IElQdjYgc2V0dGluZ3MgYW5kIGNvbmZpZ3VyYXRpb24KLSBhcHBsZXQ6IHVwZGF0ZWQgdHJhbnNsYXRpb25zCi0gZWRpdG9yOiBmaXggYSBQb2xpY3lLaXQtcmVsYXRlZCBjcmFzaCBlZGl0aW5nIGNvbm5lY3Rpb25zIChyaCAjNjAzNTY2KQotIGFwcGxldDogZml4IHNhdmluZyB0aGUgaWdub3JlLW1pc3NpbmctQ0EtY2VydCBwcmVmZXJlbmNlIChyaCAjNjEwMDg0KQotIGVkaXRvcjogZml4IGxpc3RpbmcgY29ubmVjdGlvbnMgb24gUFBDNjQgKHJoICM2MDg2NjMpCi0gZWRpdG9yOiBlbnN1cmUgZWRpdG9yIHdpbmRvd3MgYXJlIGRlc3Ryb3llZCB3aGVuIGNsb3NlZCAocmggIzU3MjQ2NikALSBSZWJ1aWxkIGFnYWluc3QgbmV3IGdub21lLWJsdWV0b290aAAtIFVwZGF0ZSB0byAwLjguMSByZWxlYXNlIGNhbmRpZGF0ZQotIGNvcmU6IGZpeCBXV0FOIGhhcmR3YXJlIGVuYWJsZSBzdGF0ZSB0cmFja2luZyAocmggIzU5MTYyMikKLSBjb3JlOiBmaXggUmVkIEhhdCBpbml0c2NyaXB0IHJldHVybiB2YWx1ZSBvbiBkb3VibGUtc3RhcnQgKHJoICM1ODQzMjEpCi0gY29yZTogYWRkIG11bHRpY2FzdCByb3V0ZSBlbnRyeSBmb3IgSVB2NCBsaW5rLWxvY2FsIGNvbm5lY3Rpb25zCi0gY29yZTogZml4IGNvbm5lY3Rpb24gc2hhcmluZyBpbiBjYXNlcyB3aGVyZSBhIGRuc21hc3EgY29uZmlnIGZpbGUgZXhpc3RzCi0gY29yZTogZml4IGhhbmRsaW5nIG9mIEFkLUhvYyB3aWZpIGNvbm5lY3Rpb25zIHRvIGluZGljYXRlIGNvcnJlY3QgbmV0d29yawotIGNvcmU6IGVuc3VyZSBWUE4gaW50ZXJmYWNlIG5hbWUgaXMgcGFzc2VkIHRvIGRpc3BhdGNoZXIgd2hlbiBWUE4gZ29lcyBkb3duCi0gaWZjZmctcmg6IGZpeCBoYW5kbGluZyBvZiBBU0NJSSBXRVAga2V5cwotIGlmY2ZnLXJoOiBmaXggZG91YmxlLXF1b3Rpbmcgb2Ygc29tZSBTU0lEcyAocmggIzYwNjUxOCkKLSBhcHBsZXQ6IGVuc3VyZSBkZWxldGVkIGNvbm5lY3Rpb25zIGFyZSBhY3R1YWxseSBmb3Jnb3R0ZW4gKHJoICM2MTg5NzMpCi0gYXBwbGV0OiBkb24ndCBjcmFzaCBpZiB0aGUgQVAncyBCU1NJRCBpc24ndCBhdmFpbGFiZSAocmggIzYwMzIzNikKLSBlZGl0b3I6IGRvbid0IGNyYXNoIG9uIFBvbGljeUtpdCBldmVudHMgYWZ0ZXIgd2luZG93cyBhcmUgY2xvc2VkIChyaCAjNTcyNDY2KQAtIGNvcmU6IGZpeCBubS1vbmxpbmUgY3Jhc2ggKHJoICM1OTM2NzcpCi0gY29yZTogZml4IGZhaWxlZCBzdXNwZW5kIGRpc2FibGVzIG5ldHdvcmsgKHJoICM1ODkxMDgpCi0gY29yZTogcHJpbnQgb3V0IG1pc3NpbmcgZmlybXdhcmUgZXJyb3JzIChyaCAjNTk0NTc4KQotIGFwcGxldDogZml4IGRldmljZSBkZXNjcmlwdGlvbnMgZm9yIHNvbWUgbW9iaWxlIGJyb2FkYmFuZCBkZXZpY2VzCi0ga2V5ZmlsZTogYmx1ZXRvb3RoIGZpeGVzCi0gYXBwbGV0OiB1cGRhdGVkIHRyYW5zbGF0aW9ucyAocmggIzU4OTIzMCkALSBjb3JlOiB1c2UgR0lPIGluIGxvY2FsIG1vZGUgb25seSAocmggIzU4ODc0NSkKLSBjb3JlOiB1cGRhdGVkIHRyYW5zbGF0aW9ucyAocmggIzU4OTIzMCkKLSBjb3JlOiBiZSBtb3JlIGxlbmllbnQgaW4gSVB2NiBSRE5TUyBzZXJ2ZXIgZXhwaXJ5IChyaCAjNTkwMjAyKQotIGNvcmU6IGZpeCBoZWFkZXJzIHRvIGJlIEMrKyBjb21wYXRpYmxlIChyaCAjNTkyNzgzKQotIGFwcGxldDogdXBkYXRlZCB0cmFuc2xhdGlvbnMgKHJoICM1ODkyMzApCi0gYXBwbGV0OiBsb2NrIGNvbm5lY3Rpb25zIHdpdGggd2VsbC1rbm93biBTU0lEcyB0byB0aGVpciBzcGVjaWZpYyBBUAAtIGNvcmU6IGZpeCBoYW5kbGluZyBvZiBJUHY2IFJBIGZsYWdzIHdoZW4gcm91dGVyIGdvZXMgYXdheSAocmggIzU4ODU2MCkKLSBibHVldG9vdGg6IGZpeCBjcmFzaCBjb25maWd1cmluZyBEVU4gY29ubmVjdGlvbnMgZnJvbSB0aGUgd2l6YXJkIChyaCAjNTkwNjY2KQAtIGNvcmU6IHJlc3RvcmUgaW5pdGlhbCBhY2NlcHRfcmEgdmFsdWUgZm9yIElQdjYgaWdub3JlZCBjb25uZWN0aW9ucyAocmggIzU4ODYxOSkKLSBibHVldG9vdGg6IGZpeCBiYWQgdGltZW91dCBvbiBQQU4gY29ubmVjdGlvbnMgKHJoICM1ODY5NjEpCi0gYXBwbGV0OiB1cGRhdGVkIHRyYW5zbGF0aW9ucwAtIGNvcmU6IHRyZWF0IG1pc3NpbmcgSVB2NiBjb25maWd1cmF0aW9uIGFzIGlnbm9yZWQgKHJoICM1ODg4MTQpCi0gY29yZTogZG9uJ3QgZmx1c2ggSVB2NiBsaW5rLWxvY2FsIHJvdXRlcyAocmggIzU4NzgzNikKLSBjbGk6IHVwZGF0ZSBvdXRwdXQgZm9ybWF0dGluZwAtIGNvcmU6IGFsbG93IElQIGNvbmZpZ3VyYXRpb24gYXMgbG9uZyBhcyBvbmUgbWV0aG9kIGNvbXBsZXRlcyAocmggIzU2Nzk3OCkKLSBjb3JlOiBkb24ndCBwcmVtYXR1cmVseSByZW1vdmUgSVB2NiBSRE5TUyBuYW1lc2VydmVycyAocmggIzU4ODE5MikKLSBjb3JlOiBlbnN1cmUgcm91dGVyIGFkdmVydGlzZW1lbnRzIGFyZSBvbmx5IHVzZWQgd2hlbiBuZWVkZWQgKHJoICM1ODg2MTMpCi0gZWRpdG9yOiBhZGQgSVB2NiBnYXRld2F5IGVkaXRpbmcgY2FwYWJpbGl0eQAtIGNvcmU6IElQdjYgYXV0b2NvbmYsIERIQ1AsIGxpbmstbG9jYWwsIGFuZCBtYW51YWwgbW9kZSBmaXhlcwotIGVkaXRvcjogZml4IHNhdmluZyBJUHY2IGFkZHJlc3MgaW4gdXNlciBjb25uZWN0aW9ucwAtIGNvcmU6IGZpeCBjcmFzaCB3aGVuIElQdjYgaXMgZW5hYmxlZCBhbmQgaW50ZXJmYWNlIGlzIGRlYWN0aXZhdGVkAC0gY29yZTogZml4IGlzc3VlcyB3aXRoIElQdjYgcm91dGVyIGFkdmVydGlzZW1lbnQgbWlzaGFuZGxpbmcgKHJoICM1MzA2NzApCi0gY29yZTogbWFueSBmaXhlcyBmb3IgSVB2NiBSQSBhbmQgREhDUCBoYW5kbGluZyAocmggIzUzODQ5OSkKLSBjb3JlOiBpZ25vcmUgV1dBTiBldGhlcm5ldCBkZXZpY2VzIHVudGlsIHVzYWJsZSAocmggIzU4NTIxNCkKLSBpZmNmZy1yaDogZml4IGhhbmRsaW5nIG9mIFdFUCBwYXNzcGhyYXNlcyAocmggIzU4MTcxOCkKLSBhcHBsZXQ6IGZpeCBjcmFzaGVzIChyaCAjNTgyOTM4KSAocmggIzU4MjQyOCkKLSBhcHBsZXQ6IGZpeCBjcmFzaCB3aXRoIG11bHRpcGxlIGNvbmN1cnJlbnQgYXV0aG9yaXphdGlvbiByZXF1ZXN0cyAocmggIzU4NTQwNSkKLSBlZGl0b3I6IGFsbG93IGRpc2FibGluZyBJUHY0IG9uIGEgcGVyLWNvbm5lY3Rpb24gYmFzaXMKLSBlZGl0b3I6IGFkZCBzdXBwb3J0IGZvciBJUHY2IERIQ1Atb25seSBjb25maWd1cmF0aW9ucwAtIGNvcmU6IGZpeCBjcmFzaCBkdXJpbmcgaW5zdGFsbCAocmggIzU4MTc5NCkKLSB3aWZpOiBmaXggY3Jhc2ggd2hlbiBzdXBwbGljYW50IHNlZ2ZhdWx0cyBhZnRlciByZXN1bWUgKHJoICM1Mzg3MTcpCi0gaWZjZmctcmg6IGZpeCBNVFUgaGFuZGxpbmcgZm9yIHdpcmVkIGNvbm5lY3Rpb25zIChyaCAjNTY5MzE5KQotIGFwcGxldDogZml4IGRpc3BsYXkgb2YgZGlzYWJsZWQgbW9iaWxlIGJyb2FkYmFuZCBkZXZpY2VzAC0gY29yZTogZml4IGF1dG9tYXRpYyBXaUZpIGNvbm5lY3Rpb25zIG9uIHJlc3VtZSAocmggIzU3ODE0MSkALSBjb3JlOiBtb3JlIGZsZXhpYmxlIGxvZ2dpbmcKLSBjb3JlOiBmaXggY3Jhc2ggd2l0aCBPTFBDIG1lc2ggZGV2aWNlcyBhZnRlciBzdXNwZW5kCi0gYXBwbGV0OiB1cGRhdGVkIHRyYW5zbGF0aW9ucwotIGFwcGxldDogc2hvdyBtb2JpbGUgYnJvYWRiYW5kIHNpZ25hbCBzdHJlbmd0aCBhbmQgdGVjaG5vbG9neSBpbiB0aGUgaWNvbgotIGFwcGxldDogZml4IGNvbnRpbnVvdXMgcGFzc3dvcmQgcmVxdWVzdHMgZm9yIDgwMi4xeCBjb25uZWN0aW9ucyAocmggIzU3NjkyNSkKLSBhcHBsZXQ6IG1hbnkgdXBkYXRlZCB0cmFuc2xhdGlvbnMALSBjb3JlOiBmaXggbW9kZW0gZW5hYmxlL2Rpc2FibGUKLSBjb3JlOiBmaXggbW9kZW0gZGVmYXVsdCByb3V0ZSBoYW5kbGluZwAtIGNvcmU6IGRvbid0IGV4aXQgZWFybHkgb24gbm9uLWZhdGFsIHN0YXRlIGZpbGUgZXJyb3JzCi0gY29yZTogZml4IEJsdWV0b290aCBjb25uZWN0aW9uIGlzc3VlcyAocmggIzU3MjM0MCkKLSBhcHBsZXQ6IGZpeCBzb21lIHRyYW5zbGF0aW9ucyAocmggIzU3NjA1NikKLSBhcHBsZXQ6IGJldHRlciBmZWVkYmFjayB3aGVuIHdyb25nIFBJTi9QVUsgaXMgZW50ZXJlZAotIGFwcGxldDogbWFueSB1cGRhdGVkIHRyYW5zbGF0aW9ucwotIGFwcGxldDogUElOMiB1bmxvY2sgbm90IHJlcXVpcmVkIGZvciBub3JtYWwgbW9kZW0gZnVuY3Rpb25hbGl0eQotIGFwcGxldDogZml4IHdpcmVsZXNzIHNlY3JldHMgZGlhbG9nIGRpc3BsYXkALSBtYW46IG1hbnkgbWFucGFnZSB1cGRhdGVzCi0gY29yZTogZGV0ZXJtaW5lIGNsYXNzZnVsIHByZWZpeCBpZiBub24gaXMgZ2l2ZW4gdmlhIERIQ1AKLSBjb3JlOiBlbnN1cmUgL2V0Yy9ob3N0cyBpcyBhbHdheXMgdXAtdG8tZGF0ZSBhbmQgY29ycmVjdCAocmggIzU2OTkxNCkKLSBjb3JlOiBzdXBwb3J0IEdTTSBuZXR3b3JrIGFuZCByb2FtaW5nIHByZWZlcmVuY2VzCi0gYXBwbGV0OiBzdGFydHVwIHNwZWVkIGVuaGFuY2VtZW50cwotIGFwcGxldDogYmV0dGVyIHN1cHBvcnQgZm9yIE9UUC90b2tlbi1iYXNlZCBXaUZpIGNvbm5lY3Rpb25zIChyaCAjNTI2MzgzKQotIGFwcGxldDogc2hvdyBHU00gYW5kIENETUEgcmVnaXN0cmF0aW9uIHN0YXR1cyBhbmQgc2lnbmFsIHN0cmVuZ3RoIHdoZW4gYXZhaWxhYmxlCi0gYXBwbGV0OiBmaXggem9tYmllIEdTTSBhbmQgQ0RNQSBkZXZpY2VzIGluIHRoZSBtZW51Ci0gYXBwbGV0OiByZW1vdmUgNC1jaGFyYWN0ZXIgR1NNIFBJTi9QVUsgY29kZSBsaW1pdAotIGFwcGxldDogZml4IGluc2Vuc2l0aXZlIFdpRmkgQ3JlYXRlLi4uIGJ1dHRvbiAocmggIzU0MTE2MykKLSBhcHBsZXQ6IGFsbG93IHVubG9ja2luZyBvZiBtb2JpbGUgZGV2aWNlcyBpbW1lZGlhdGVseSB3aGVuIHBsdWdnZWQgaW4ALSBjb3JlOiB1cGRhdGUgdG8gZmluYWwgMC44IHJlbGVhc2UKLSBjb3JlOiBmaXggQmx1ZXRvb3RoIERVTiBjb25uZWN0aW9ucyB3aGVuIHNlY3JldHMgYXJlIG5lZWRlZAotIGlmY2ZnLXJoOiBhZGQgaGVscGVyIGZvciBpbml0c2NyaXB0cyB0byBkZXRlcm1pbmUgaWZjZmcgY29ubmVjdGlvbiBVVUlEcwotIGFwcGxldDogZml4IEJsdWV0b290aCBjb25uZWN0aW9uIHNlY3JldHMgcmVxdWVzdHMKLSBhcHBsZXQ6IGZpeCByYXJlIGNvbmZsaWN0IHdpdGggb3RoZXIgZ25vbWUtYmx1ZXRvb3RoIHBsdWdpbnMALSBjb3JlOiBmaXggbW9iaWxlIGJyb2FkYmFuZCBQSU4gaGFuZGxpbmcgKHJoICM1NDMwODgpIChyaCAjNTYwNzQyKQotIGNvcmU6IGJldHRlciBoYW5kbGluZyBvZiAvZXRjL2hvc3RzIGlmIGhvc3RuYW1lIHdhcyBhbHJlYWR5IGFkZGVkIGJ5IHRoZSB1c2VyCi0gYXBwbGV0OiBjcmFzaCBsZXNzIG9uIEQtQnVzIHByb3BlcnR5IGVycm9ycyAocmggIzU1NzAwNykKLSBhcHBsZXQ6IGZpeCBjcmFzaCBlbnRlcmluZyB3aXJlZCA4MDIuMXggY29ubmVjdGlvbiBkZXRhaWxzIChyaCAjNTU2NzYzKQAtIGNvcmU6IHZhbGlkYXRlIHRoZSBhdXRvc3RhcnQgLmRlc2t0b3AgZmlsZQotIGJ1aWxkOiBmaXggbm1jbGkgZm9yIHRoZSBzdHJpY3RlciBsZCAoZml4ZXMgRlRCRlMpCi0gYnVpbGQ6IGZpeCBubS1jb25uZWN0aW9uLWVkaXRvciBmb3IgdGhlIHN0cmljdGVyIGxkIChmaXhlcyBGVEJGUykKLSBhcHBsZXQ6IGRvbid0IGF1dG9zdGFydCBpbiBLREUgb24gRjEzKyAoIzU0MTM1MykALSBjb3JlOiBhZGQgQmx1ZXRvb3RoIERpYWwtVXAgTmV0d29ya2luZyAoRFVOKSBzdXBwb3J0IChyaCAjMTM2NjYzKQotIGNvcmU6IHN0YXJ0IERIQ1B2NiBvbiByZWNlaXB0IG9mIFJBICdvdGhlcmNvbmYnLydtYW5hZ2VkJyBiaXRzCi0gbm1jbGk6IGFsbG93IGVuYWJsZS9kaXNhYmxlIG9mIFdpRmkgYW5kIFdXQU4ALSBpZmNmZy1yaDogcmVhZCBhbmQgd3JpdGUgREhDUHY2IGVuYWJsZWQgY29ubmVjdGlvbnMgKHJoICM0Mjk3MTApCi0gbm1jbGk6IHVwZGF0ZQAtIGNvcmU6IGNsZWFuIE5TUyB1cCBsYXRlciB0byBwcmVzZXJ2ZSBlcnJvcnMgZnJvbSBjcnlwdG9faW5pdCgpAC0gY29yZTogc3VwcG9ydCBmb3IgbWFuYWdlZC1tb2RlIERIQ1B2NiAocmggIzQyOTcxMCkKLSBpZmNmZy1yaDogZ3JhY2VmdWxseSBoYW5kbGUgbWlzc2luZyBQUkVGSVgvTkVUTUFTSwotIGNsaTogaW5pdGlhbCBwcmV2aWV3IG9mIGNvbW1hbmQtbGluZSBjbGllbnQKLSBhcHBsZXQ6IGFkZCAtLWhlbHAgdG8gZXhwbGFpbiB3aGF0IHRoZSBhcHBsZXQgaXMgKHJoICM0OTQ2NDEpAC0gYnVpbGQ6IGZpeCBmb3IgbmV3IHBwcGQgKHJoICM1NDg1MjApCi0gY29yZTogYWRkIFdXQU4gZW5hYmxlL2Rpc2FibGUgZnVuY3Rpb25hbGl0eQotIGlmY2ZnLXJoOiBJUHY2IGFkZHJlc3NpbmcgYW5kIHJvdXRlcyBzdXBwb3J0IChyaCAjNTIzMjg4KQotIGlmY2ZnLXJoOiBlbnN1cmUgY29ubmVjdGlvbiBpcyB1cGRhdGVkIHdoZW4gcm91dGUva2V5IGZpbGVzIGNoYW5nZQotIGFwcGxldDogZml4IGNyYXNoIHdoZW4gYWN0aXZlIEFQIGlzbid0IGZvdW5kIChyaCAjNTQ2OTAxKQotIGVkaXRvcjogZml4IGNyYXNoIHdoZW4gZWRpdGluZyBjb25uZWN0aW9ucyAocmggIzU0OTU3OSkALSBjb3JlOiBmaXggcmVjb2duaXRpb24gb2Ygc3RhbmRhbG9uZSA4MDIuMXggcHJpdmF0ZSBrZXlzCi0gYXBwbGV0OiBjbGVhbiBub3RpZmljYXRpb24gdGV4dCB0byBlbnN1cmUgaXQgcGFzc2VzIGxpYm5vdGlmeSB2YWxpZGF0aW9uAC0gY29yZTogcmVtb3ZlIGhhbGRhZW1vbiBmcm9tIGluaXRzY3JpcHQgZGVwZW5kZW5jaWVzIChyaCAjNTQyMDc4KQotIGNvcmU6IGhhbmRsZSBQRU0gY2VydGlmaWNhdGVzIHdpdGhvdXQgYW4gZW5kaW5nIG5ld2xpbmUgKHJoICM1MDczMTUpCi0gY29yZTogZml4IHJma2lsbCByZXBvcnRpbmcgZm9yIGlwdzJ4MDAgZGV2aWNlcwotIGNvcmU6IGluY3JlYXNlIFBQUG9FIHRpbWVvdXQgdG8gMzAgc2Vjb25kcwotIGNvcmU6IGZpeCByZS1hY3RpdmF0aW5nIHN5c3RlbSBjb25uZWN0aW9ucyB3aXRoIHNlY3JldHMKLSBjb3JlOiBmaXggY3Jhc2ggd2hlbiBkZWxldGluZyBhdXRvbWF0aWNhbGx5IGNyZWF0ZWQgd2lyZWQgY29ubmVjdGlvbnMKLSBjb3JlOiBlbnN1cmUgdGhhdCBhIFZQTidzIEROUyBzZXJ2ZXJzIGFyZSB1c2VkIHdoZW4gc2hhcmluZyB0aGUgVlBOIGNvbm5lY3Rpb24KLSBpZmNmZy1yaDogc3VwcG9ydCByb3V0ZXMgZmlsZXMgKHJoICM1MDczMDcpCi0gaWZjZmctcmg6IHdhcm4gd2hlbiBkZXZpY2Ugd2lsbCBiZSBtYW5hZ2VkIGR1ZSB0byBtaXNzaW5nIEhXQUREUiAocmggIzU0NTAwMykKLSBpZmNmZy1yaDogaW50ZXJwcmV0IERFRlJPVVRFIGFzIG5ldmVyLWRlZmF1bHQgKHJoICM1MjgyODEpCi0gaWZjZmctcmg6IGhhbmRsZSBNT0RFPUF1dG8gY29ycmVjdGx5Ci0gcnBtOiBmaXggcnBtbGludCBlcnJvcnMKLSBhcHBsZXQ6IGRvbid0IGNyYXNoIG9uIHZhcmlvdXMgRC1CdXMgYW5kIG90aGVyIGVycm9ycyAocmggIzU0NTAxMSkgKHJoICM1NDI2MTcpCi0gZWRpdG9yOiBmaXggdmFyaW91cyBQb2xpY3lLaXQtcmVsYXRlZCBjcmFzaGVzIChyaCAjNDYyOTQ0KQotIGFwcGxldCtlZGl0b3I6IG5vdGlmeSB1c2VyIHRoYXQgcHJpdmF0ZSBrZXlzIG11c3QgYmUgcHJvdGVjdGVkAC0gbm06IGJldHRlciBwaWRmaWxlIGhhbmRpbmcgKHJoICM1MTczNjIpCi0gbm06IHNhdmUgV2lGaSBhbmQgTmV0d29ya2luZyBlbmFibGVkL2Rpc2FibGVkIHN0YXRlcyBhY3Jvc3MgcmVib290Ci0gbm06IGZpeCBjcmFzaCB3aXRoIG1pc3NpbmcgVlBOIHNlY3JldHMgKHJoICM1MzIwODQpCi0gYXBwbGV0OiBmaXggc3lzdGVtIGNvbm5lY3Rpb24gdXNhZ2UgZnJvbSB0aGUgIkNvbm5lY3QgdG8gaGlkZGVuLi4uIiBkaWFsb2cKLSBhcHBsZXQ6IHNob3cgQmx1ZXRvb3RoIGNvbm5lY3Rpb25zIHdoZW4gbm8gb3RoZXIgZGV2aWNlcyBhcmUgYXZhaWxhYmxlIChyaCAjNTMyMDQ5KQotIGFwcGxldDogZG9uJ3QgZGllIHdoZW4gYXV0b2NvbmZpZ3VyZWQgY29ubmVjdGlvbnMgY2FuJ3QgYmUgbWFkZSAocmggIzUzMjY4MCkKLSBhcHBsZXQ6IGFsbG93IHN5c3RlbSBhZG1pbmlzdHJhdG9ycyB0byBkaXNhYmxlIHRoZSAiQ3JlYXRlIG5ldyB3aXJlbGVzcyBuZXR3b3JrLi4uIiBtZW51IGl0ZW0KLSBhcHBsZXQ6IGZpeCBtaXNzaW5nIHVzZXJuYW1lIGNvbm5lY3RpbmcgdG8gVlBOcyB0aGUgc2Vjb25kIHRpbWUKLSBhcHBsZXQ6IHJlYWxseSBmaXggYW5pbWF0aW9uIHN0dXR0ZXJpbmcKLSBlZGl0b3I6IGZpeCBJUCBjb25maWcgd2lkZ2V0IHRvb2x0aXBzCi0gZWRpdG9yOiBhbGxvdyB1bmxpc3RlZCBjb3VudHJpZXMgaW4gdGhlIG1vYmlsZSBicm9hZGJhbmQgd2l6YXJkIChyaCAjNTMwOTgxKQotIGlmY2ZnLXJoOiBpZ25vcmUgLnJwbW5ldyBmaWxlcyAocmggIzUwOTYyMSkALSBubTogZml4IFBQUG9FIGNvbm5lY3Rpb24gYXV0aGVudGljYXRpb24gKHJoICM1MzI4NjIpAC0gaW5zdGFsbDogYmV0dGVyIGZpeCBmb3IgKHJoICM1MjY1MTkpCi0gaW5zdGFsbDogZG9uJ3QgYnVpbGQgQmx1ZXRvb3RoIGJpdHMgb24gczM5MCAocmggIzUyOTg1NCkKLSBubTogd2lyZWQgODAyLjF4IGNvbm5lY3Rpb24gYWN0aXZhdGlvbiBmaXhlcwotIG5tOiBmaXggY3Jhc2ggYWZ0ZXIgbW9kaWZ5aW5nIGRlZmF1bHQgd2lyZWQgY29ubmVjdGlvbnMgbGlrZSAiQXV0byBldGgwIgotIG5tOiBlbnN1cmUgVlBOIHNlY3JldHMgYXJlIHJlcXVlc3RlZCBhZ2FpbiBhZnRlciBjb25uZWN0aW9uIGZhaWx1cmUKLSBubTogcmVzZXQgJ2FjY2VwdF9yYScgdG8gcHJldmlvdXMgdmFsdWUgYWZ0ZXIgZGVhY3RpdmF0aW5nIElQdjYgY29ubmVjdGlvbnMKLSBubTogZW5zdXJlIHJhbmRvbSBuZXRsaW5rIGV2ZW50cyBkb24ndCBpbnRlcmZlcmUgd2l0aCBJUHY2IGNvbm5lY3Rpb24gYWN0aXZhdGlvbgotIGlmY2ZnLXJoOiBmaXggd3JpdGluZyBvdXQgTEVBUCBjb25uZWN0aW9ucwotIGlmY2ZnLXJoOiByZWNvZ25pemUgJ3N0YXRpYycgYXMgYSB2YWxpZCBCT09UUFJPVE8gKHJoICM1MjgwNjgpCi0gYXBwbGV0OiBmaXggImNvdWxkIG5vdCBmaW5kIHJlcXVpcmVkIHJlc291cmNlcyIgZXJyb3IgKHJoICM1Mjk3NjYpAC0gaW5zdGFsbDogZml4IC1nbm9tZSBwYWNrYWdlIHByZSBzY3JpcHQgZmFpbHVyZXMgKHJoICM1MjY1MTkpCi0gbm06IGZpeCBmYWlsdXJlcyB2YWxpZGF0aW5nIHByaXZhdGUga2V5cyB3aGVuIHVzaW5nIHRoZSBOU1MgY3J5cHRvIGJhY2tlbmQKLSBhcHBsZXQ6IGZpeCBjcmFzaGVzIHdoZW4gY2xpY2tpbmcgb24gbWVudSBidXQgbm90IGFzc29jaWF0ZWQgKHJoICM1MjY1MzUpCi0gZWRpdG9yOiBmaXggY3Jhc2ggZWRpdGluZyB3aXJlZCA4MDIuMXggc2V0dGluZ3MKLSBlZGl0b3I6IGZpeCBzZWNyZXRzIHJldHJpZXZhbCB3aGVuIGVkaXRpbmcgY29ubmVjdGlvbnMALSBubTogZml4IGNvbm5lY3Rpb24gdGFrZW92ZXIgd2hlbiBjYXJyaWVyIGlzIG5vdCBvbgotIG5tOiBoYW5kbGUgY2VydGlmaWNhdGUgcGF0aHMgKENBIGNoYWluIFBFTSBmaWxlcyBhcmUgbm93IGZ1bGx5IHVzYWJsZSkKLSBubTogZGVmZXIgYWN0aW9uIGZvciA0IHNlY29uZHMgd2hlbiB3aXJlZCBjYXJyaWVyIGRyb3BzCi0gaWZjZmctcmg6IGZpeCB3cml0aW5nIFdQQSBwYXNzcGhyYXNlcyB3aXRoIG9kZCBjaGFyYWN0ZXJzCi0gZWRpdG9yOiBmaXggZWRpdGluZyBvZiBJUHY0IHNldHRpbmdzIHdpdGggbmV3IGNvbm5lY3Rpb25zIChyaCAjNTI1ODE5KQotIGVkaXRvcjogZml4IHJhbmRvbSBjcmFzaGVzIHdoZW4gZWRpdGluZyBkdWUgdG8gYmFkIHdpZGdldCByZWZjb3VudGluZwotIGFwcGxldDogZGVidXQgcmV3b3JrZWQgbWVudSBsYXlvdXQgKG5vdCBmaW5hbCB5ZXQuLi4pAC0gSW5zdGFsbCBHQ29uZiBzY2hlbWFzAC0gbm06IGFsbG93IGRpc2Nvbm5lY3Rpb24gb2YgYWxsIGRldmljZSB0eXBlcwotIG5tOiBlbnN1cmUgdGhhdCB3aXJlZCBjb25uZWN0aW9ucyBhcmUgdG9ybiBkb3duIHdoZW4gdGhlaXIgaGFyZHdhcmUgZ29lcyBhd2F5Ci0gbm06IGZpeCBjcmFzaCB3aGVuIGNhbmNlbGluZyBhIFZQTidzIHJlcXVlc3QgZm9yIHNlY3JldHMKLSBlZGl0b3I6IGZpeCBpc3N1ZXMgY2hhbmdpbmcgY29ubmVjdGlvbnMgYmV0d2VlbiBzeXN0ZW0gYW5kIHVzZXIgc2NvcGVzCi0gZWRpdG9yOiBlbnN1cmUgY2hhbmdlcyBhcmUgdGhyb3duIGF3YXkgd2hlbiBlZGl0aW5nIGlzIGNhbmNlbGVkCi0gYXBwbGV0OiBlbnN1cmUgY29ubmVjdGlvbiBjaGFuZ2VzIGFyZSBub3RpY2VkIGJ5IE5ldHdvcmtNYW5hZ2VyCi0gYXBwbGV0OiBmaXggY3Jhc2ggd2hlbiBjcmVhdGluZyBuZXcgY29ubmVjdGlvbnMKLSBhcHBsZXQ6IGFjdHVhbGx5IHVzZSB3aXJlZCA4MDIuMXggc2VjcmV0cyBhZnRlciB0aGV5IGFyZSByZXF1ZXN0ZWQALSBubTogSVB2NiB6ZXJvY29uZiBzdXBwb3J0IGFuZCBmaXhlcwotIG5tOiBwb3J0IHRvIHBvbGtpdCAocmggIzQ5OTk2NSkKLSBubTogZml4ZXMgZm9yIGVoZWEgZGV2aWNlcyAocmggIzUxMTMwNCkgKHJoICM1MTY1OTEpCi0gbm06IHdvcmsgYXJvdW5kIFBQUCBidWcgY2F1c2luZyBib2d1cyBuYW1lc2VydmVycyBmb3IgbW9iaWxlIGJyb2FkYmFuZCBjb25uZWN0aW9ucwotIGVkaXRvcjogZml4IHNlZ2ZhdWx0IHdpdGggIlVubGlzdGVkIiBwbGFucyBpbiB0aGUgbW9iaWxlIGJyb2FkYmFuZCBhc3Npc3RhbnQALSBubTogYWRkIGlTQ1NJIHN1cHBvcnQKLSBubTogYWRkIGNvbm5lY3Rpb24gYXNzdW1lL3Rha2VvdmVyIHN1cHBvcnQgZm9yIGV0aGVybmV0IChyaCAjNTE3MzMzKQotIG5tOiBJUHY2IGZpeGVzCi0gbm06IHJlLWFkZCBPTFBDIFhPLTEgbWVzaCBkZXZpY2Ugc3VwcG9ydCAocmVtb3ZlZCB3aXRoIDAuNy4wKQotIGFwcGxldDogYmV0dGVyIFdpRmkgZGlhbG9nIGZvY3VzIGhhbmRsaW5nAC0gQWRkIHBhdGNoIHRvIGZpeCBzZXJ2aWNlIGRldGVjdGlvbiBvbiBwaG9uZXMALSBubTogSVB2NiBzdXBwb3J0IGZvciBtYW51YWwgJiByb3V0ZXItYWR2ZXJ0aXNlbWVudCBtb2RlcwAtIE1vdmUgc29tZSBiaWcgZG9jcyB0byAtZGV2ZWwgdG8gc2F2ZSBzcGFjZQAtIFVwZGF0ZSB0byB1cHN0cmVhbSAnbWFzdGVyJyBicmFuY2gKLSBVc2UgbW9kZW0tbWFuYWdlciBmb3IgYmV0dGVyIDNHIG1vZGVtIHN1cHBvcnQKLSBJbnRlZ3JhdGVkIHN5c3RlbSBzZXR0aW5ncyB3aXRoIE5ldHdvcmtNYW5hZ2VyIGl0c2VsZgotIFVzZSB1ZGV2IGluc3RlYWQgb2YgSEFMAC0gUmVidWlsdCBmb3IgaHR0cHM6Ly9mZWRvcmFwcm9qZWN0Lm9yZy93aWtpL0ZlZG9yYV8xMl9NYXNzX1JlYnVpbGQALSBhcHBsZXQ6IGZpeCBjZXJ0aWZpY2F0ZSB2YWxpZGF0aW9uIGluIGhpZGRlbiB3aWZpIG5ldHdvcmtzIGRpYWxvZyAocmggIzUwODIwNykALSBubTogZml4ZXMgZm9yIFpURS9PbmRhIG1vZGVtIGRldGVjdGlvbgotIG5tOiBwcmV2ZW50IHJlLW9wZW5pbmcgc2VyaWFsIHBvcnQgd2hlbiB0aGUgU0lNIGhhcyBhIFBJTgotIGFwcGxldDogdXBkYXRlZCB0cmFuc2xhdGlvbnMKLSBlZGl0b3I6IHNob3cgbGlzdCBjb2x1bW4gaGVhZGVycwAtIG5tOiBmaXggc2VyaWFsIHBvcnQgc2V0dGluZ3MALSBubTogZml4IEFUJlQgUXVpY2tzaWx2ZXIgbW9kZW0gY29ubmVjdGlvbnMgKHJoICM1MDIwMDIpCi0gbm06IGZpeCBzdXBwb3J0IGZvciBzMzkwIGJ1cyB0eXBlcyAocmggIzQ5NjgyMCkKLSBubTogZml4IGRldGVjdGlvbiBvZiBzb21lIENNT3RlY2ggbW9kZW1zCi0gbm06IGhhbmRsZSB1bnNvbGljaXRlZCB3aWZpIHNjYW5zIGJldHRlcgotIG5tOiByZXNvbHYuY29uZiBmaXhlcyB3aGVuIHVzaW5nIERIQ1AgYW5kIG92ZXJyaWRpbmcgc2VhcmNoIGRvbWFpbnMKLSBubTogaGFuZGxlIFdFUCBhbmQgV1BBIHBhc3NwaHJhc2VzIChyaCAjNDQxMDcwKQotIG5tOiBmaXggcmVtb3ZhbCBvZiBvbGQgQVBzIHdoZW4gbm9uZSBhcmUgc2Nhbm5lZAotIG5tOiBmaXggSHVhd2VpIEVDMTIxIGFuZCBFQzE2OEMgZGV0ZWN0aW9uIGFuZCBoYW5kbGluZyAocmggIzQ5NjQyNikKLSBhcHBsZXQ6IHNhdmUgV0VQIGFuZCBXUEEgcGFzc3BocmFzZXMgaW5zdGVhZCBvZiBoYXNoZWQga2V5cyAocmggIzQ0MTA3MCkKLSBhcHBsZXQ6IGZpeCBicm9rZW4gbm90aWZpY2F0aW9uIGJ1YmJsZSBhY3Rpb25zCi0gYXBwbGV0OiBkZWZhdWx0IHRvIFdFUCBlbmNyeXB0aW9uIGZvciBBZC1Ib2MgbmV0d29yayBjcmVhdGlvbgotIGFwcGxldDogZml4IGNyYXNoIHdoZW4gY29ubmVjdGlvbiBlZGl0b3IgZGlhbG9ncyBhcmUgY2FuY2VsZWQKLSBhcHBsZXQ6IGFkZCBhIG1vYmlsZSBicm9hZGJhbmQgcHJvdmlkZXIgd2l6YXJkAC0gZHJvcCBFeGNsdWRlQXJjaCBzMzkwIHMzOTB4LCB3ZSBuZWVkIGF0IGxlYXN0IHRoZSBoZWFkZXIgZmlsZXMALSBubS1zYXZlLXRoZS1sZWFzZXMucGF0Y2g6IFVzZSBwZXItY29ubmVjdGlvbiBsZWFzZSBmaWxlcywgYW5kIGRvbid0IGRlbGV0ZQogIHRoZW0gb24gaW50ZXJmYWNlIGRlYWN0aXZhdGUuAC0gaWZjZmctcmg6IGZpeCBwcm9ibGVtcyBub3RpY2luZyBjaGFuZ2VzIHZpYSBpbm90aWZ5IChyaCAjNDk1ODg0KQAtIGlmY2ZnLXJoOiBlbmFibGUgd3JpdGUgc3VwcG9ydCBmb3Igd2lyZWQgYW5kIHdpZmkgY29ubmVjdGlvbnMALSBubTogdXBkYXRlIHRvIDAuNy4xCi0gbm06IGZpeCBzdGFydHVwIHJhY2Ugd2l0aCBIQUwgY2F1c2luZyB1bm1hbmFnZWQgZGV2aWNlcyB0byBzb21ldGltZXMgYmUgbWFuYWdlZCAocmggIzQ5NDUyNykALSBubTogZml4IHJlY29nbml0aW9uIG9mIE9wdGlvbiBHVCBGdXNpb24gYW5kIE9wdGlvbiBHVCBIU0RQQSAobm96b21pKSBkZXZpY2VzIChyaCAjNDk0MDY5KQotIG5tOiBmaXggaGFuZGxpbmcgb2Ygc3BhY2VzIGluIERIQ1AgJ2RvbWFpbi1zZWFyY2gnIG9wdGlvbgotIG5tOiBmaXggZGV0ZWN0aW9uIG9mIG5ld2VyIE9wdGlvbiAnaHNvJyBkZXZpY2VzCi0gbm06IGlnbm9yZSBsb3cgTVRVcyByZXR1cm5lZCBieSBicm9rZW4gREhDUCBzZXJ2ZXJzAC0gVXBkYXRlIHRvIDAuNy4xLXJjNAotIG5tOiB1c2UgUG9saWN5S2l0IGZvciBzeXN0ZW0gY29ubmVjdGlvbiBzZWNyZXRzIHJldHJpZXZhbAotIG5tOiBjb3JyZWN0bHkgaW50ZXJwcmV0IGVycm9ycyByZXR1cm5lZCBmcm9tIGNobW9kKDIpIHdoZW4gc2F2aW5nIGtleWZpbGUgc3lzdGVtIGNvbm5lY3Rpb25zCi0gZWRpdG9yOiB1c2UgUG9saWN5S2l0IHRvIGdldCBzeXN0ZW0gY29ubmVjdGlvbiBzZWNyZXRzAC0gbm06IGZpeCBjcmFzaGVzIHdpdGggb3V0LW9mLXRyZWUgbW9kdWxlcyB0aGF0IHByb3ZpZGUgbm8gZHJpdmVyIGxpbmsgKHJoICM0OTIyNDYpCi0gbm06IGZpeCBVU0IgbW9kZW0gcHJvYmluZyBvbiByZWNlbnQgdWRldiB2ZXJzaW9ucwAtIG5tOiBmaXggY29tbXVuaWNhdGlvbiB3aXRoIE9wdGlvbiBHVCBNYXggMy42IG1vYmlsZSBicm9hZGJhbmQgY2FyZHMKLSBubTogZml4IGNvbW11bmljYXRpb24gd2l0aCBIdWF3ZWkgbW9iaWxlIGJyb2FkYmFuZCBjYXJkcyAocmggIzQ4NzY2MykKLSBubTogZG9uJ3QgbG9vayB1cCBob3N0bmFtZSB3aGVuIEhPU1ROQU1FPWxvY2FsaG9zdCB1bmxlc3MgYXNrZWQgKHJoICM0OTAxODQpCi0gbm06IGZpeCBjcmFzaCBkdXJpbmcgSVA0IGNvbmZpZ3VyYXRpb24gKHJoICM0OTE2MjApCi0gbm06IGlnbm9yZSBPTkJPT1Q9bm8gZm9yIG1pbmltYWwgaWZjZmcgZmlsZXMgKGY5ICYgZjEwIG9ubHkpIChyaCAjNDg5Mzk4KQotIGFwcGxldDogdXBkYXRlZCB0cmFuc2xhdGlvbnMALSBubTogd29yayBhcm91bmQgdW5oYW5kbGVkIGRldmljZSByZW1vdmFscyBkdWUgdG8gbWlzc2luZyBIQUwgZXZlbnRzIChyaCAjNDg0NTMwKQotIG5tOiBpbXByb3ZlIGhhbmRsaW5nIG9mIG11bHRpcGxlIG1vZGVtIHBvcnRzCi0gbm06IHN1cHBvcnQgZm9yIFNvbnkgRXJpY3Nzb24gRjM1MDdnIC8gTUQzMDAgYW5kIERlbGwgNTUzMAotIGFwcGxldDogdXBkYXRlZCB0cmFuc2xhdGlvbnMALSBNaXNzaW5nIE9OQk9PVCBzaG91bGQgYWN0dWFsbHkgbWVhbiBPTkJPT1Q9eWVzIChyaCAjNDg5NDIyKQAtIEZpeCBjb25mbGljdCB3aXRoIE5ldHdvcmtNYW5hZ2VyLW9wZW5jb25uZWN0IChyaCAjNDg5MjcxKQotIEZpeCBwb3NzaWJsZSBjcmFzaCB3aGVuIHJlc3luY2hyb25pemluZyBkZXZpY2VzIGlmIEhBTCByZXN0YXJ0cwAtIG5tOiBtYWtlIGRlZmF1bHQgd2lyZWQgIkF1dG8gZXRoWCIgY29ubmVjdGlvbiBtb2RpZmlhYmxlIGlmIGFuIGVuYWJsZWQgc3lzdGVtIHNldHRpbmdzCiAgICBwbHVnaW4gc3VwcG9ydHMgbW9kaWZ5aW5nIGNvbm5lY3Rpb25zIChyaCAjNDg1NTU1KQotIG5tOiBtYW5wYWdlIGZpeGVzIChyaCAjNDQ3MjMzKQotIG5tOiBDVkUtMjAwOS0wMzY1IC0gR2V0U2VjcmV0cyBkaXNjbG9zdXJlCi0gYXBwbGV0OiBDVkUtMjAwOS0wNTc4IC0gbG9jYWwgdXNlcnMgY2FuIG1vZGlmeSB0aGUgY29ubmVjdGlvbiBzZXR0aW5ncwotIGFwcGxldDogZml4IGluYWJpbGl0eSB0byBjaG9vc2UgV1BBIEFkLUhvYyBuZXR3b3JrcyBmcm9tIHRoZSBtZW51Ci0gaWZjZmctcmg6IGFkZCByZWFkLW9ubHkgc3VwcG9ydCBmb3IgV1BBLVBTSyBjb25uZWN0aW9ucwAtIEZpeCBnZXR0aW5nIHNlY3JldHMgZm9yIHN5c3RlbSBjb25uZWN0aW9ucyAocmggIzQ4NjY5NikKLSBNb3JlIGNvbXBhdGlibGUgbW9kZW0gYXV0b2RldGVjdGlvbgotIEJldHRlciBoYW5kbGUgbWluaW1hbCBpZmNmZyBmaWxlcwAtIFJlYnVpbHQgZm9yIGh0dHBzOi8vZmVkb3JhcHJvamVjdC5vcmcvd2lraS9GZWRvcmFfMTFfTWFzc19SZWJ1aWxkAC0gVXNlIElGRl9MT1dFUl9VUCBmb3IgY2FycmllciBkZXRlY3QgaW5zdGVhZCBvZiBJRkZfUlVOTklORwotIEFkZCBzbWFsbCBkZWxheSBiZWZvcmUgcHJvYmluZyBjZGMtYWNtIGRyaXZlbiBtb2JpbGUgYnJvYWRiYW5kIGRldmljZXMALSBGaXggUEVBUCB2ZXJzaW9uIHNlbGVjdGlvbiBpbiB0aGUgYXBwbGV0IChyaCAjNDY4ODQ0KQotIE1hdGNoIGhvc3RuYW1lIGJlaGF2aW9yIHRvICduZXR3b3JrJyBzZXJ2aWNlIHdoZW4gaG9zdG5hbWUgaXMgbG9jYWxob3N0IChyaCAjNDQxNDUzKQAtIEZpeCAnbm9yZXBsYWNlJyBmb3Igbm0tc3lzdGVtLXNldHRpbmdzLmNvbmYALSBVcGRhdGUgdG8gMC43LjFyYzEKLSBubTogc3VwcG9ydCBmb3IgSHVhd2VpIEUxNjBHIG1vYmlsZSBicm9hZGJhbmQgZGV2aWNlcyAocmggIzQ2NjE3NykKLSBubTogZml4IG1pc2xlYWRpbmcgcm91dGluZyBlcnJvciBtZXNzYWdlIChyaCAjNDc3OTE2KQotIG5tOiBmaXggaXNzdWVzIHdpdGggMzItY2hhcmFjdGVyIFNTSURzIChyaCAjNDg1MzEyKQotIG5tOiBhbGxvdyByb290IHRvIGFjdGl2YXRlIHVzZXIgY29ubmVjdGlvbnMKLSBubTogYXV0b21hdGljIG1vZGVtIGRldGVjdGlvbiB3aXRoIHVkZXYtZXh0cmFzCi0gbm06IG1hc3NpdmUgbWFucGFnZSByZXdyaXRlCi0gYXBwbGV0OiBmaXggY3Jhc2ggd2hlbiBzaG93aW5nIHRoZSBDQSBjZXJ0aWZpY2F0ZSBpZ25vcmUgZGlhbG9nIGEgc2Vjb25kIHRpbWUKLSBhcHBsZXQ6IGNsZWFyIGtleXJpbmcgaXRlbXMgd2hlbiBkZWxldGluZyBhIGNvbm5lY3Rpb24KLSBhcHBsZXQ6IGZpeCBtYXggc2lnbmFsIHN0cmVuZ3RoIGNhbGN1bGF0aW9uIGluIG1lbnUgKHJoICM0NzUxMjMpCi0gYXBwbGV0OiBmaXggVlBOIGV4cG9ydCAocmggIzQ4MDQ5NikALSBhcHBsZXQ6IGZpeCBibGFuayBWUE4gY29ubmVjdGlvbiBtZXNzYWdlIGJ1YmJsZXMKLSBhcHBsZXQ6IGJldHRlciBoYW5kbGluZyBvZiBWUE4gcm91dGluZyBvbiB1cGRhdGUKLSBhcHBsZXQ6IHNpbGVuY2UgcG9pbnRsZXNzIHdhcm5pbmcgKHJoICM0ODQxMzYpCi0gYXBwbGV0OiBkZXNlbnNpdGl6ZSBkZXZpY2VzIGluIHRoZSBtZW51IHVudGlsIHRoZXkgYXJlIHJlYWR5IChyaCAjNDgzODc5KQotIG5tOiBFeHBvc2UgV0lOUyBzZXJ2ZXJzIGluIHRoZSBJUDRDb25maWcgb3ZlciBELUJ1cwotIG5tOiBCZXR0ZXIgaGFuZGxpbmcgb2YgR1NNIE1vYmlsZSBCcm9hZGJhbmQgbW9kZW0gaW5pdGlhbGl6YXRpb24KLSBubTogSGFuZGxlIERIQ1AgQ2xhc3NsZXNzIFN0YXRpYyBSb3V0ZXMgKFJGQyAzNDQyKQotIG5tOiBGaXggTW9iaWxlIEJyb2FkYmFuZCBhbmQgUFBQb0UgdG8gYWx3YXlzIHVzZSAnbm9hdXRoJwotIG5tOiBCZXR0ZXIgY29tcGF0aWJpbGl0eSB3aXRoIG9sZGVyIGR1YWwtU1NJRCBBUCBjb25maWd1cmF0aW9ucyAocmggIzQ0NTM2OSkKLSBubTogTWFyayBubS1zeXN0ZW0tc2V0dGluZ3MuY29uZiBhcyBjb25maWcgKHJoICM0NjU2MzMpCi0gbm0tdG9vbDogU2hvdyBWUE4gY29ubmVjdGlvbiBpbmZvcm1hdGlvbgotIGlmY2ZnLXJoOiBTaWxlbmNlIG1lc3NhZ2UgYWJvdXQgaWdub3JpbmcgbG9vcGJhY2sgY29uZmlnIChyaCAjNDg0MDYwKQotIGlmY2ZnLXJoOiBGaXggaXNzdWUgd2l0aCB3cm9uZyBnYXRld2F5IGZvciBzeXN0ZW0gY29ubmVjdGlvbnMgKHJoICM0NzYwODkpAC0gVXBkYXRlIHRvIDAuNy4xIHByZS1yZWxlYXNlCi0gQWxsb3cgY29ubmVjdGlvbnMgdG8gYmUgaWdub3JlZCB3aGVuIGRldGVybWluaW5nIHRoZSBkZWZhdWx0IHJvdXRlIChyaCAjNDc2MDg5KQotIE93biAvdXNyL3NoYXJlL2dub21lLXZwbi1wcm9wZXJ0aWVzIChyaCAjNDc3MTU1KQotIEZpeCBsb2cgZmxvb2RpbmcgZHVlIHRvIG5ldGxpbmsgZXJyb3JzIChyaCAjNDU5MjA1KQotIFBhc3MgY29ubmVjdGlvbiBVVUlEIHRvIGRpc3BhdGNoZXIgc2NyaXB0cyB2aWEgdGhlIGVudmlyb25tZW50Ci0gRml4IHBvc3NpYmxlIGNyYXNoIGFmdGVyIGRlYWN0aXZhdGluZyBhIFZQTiBjb25uZWN0aW9uCi0gRml4IGlzc3VlcyB3aXRoIGVkaXRpbmcgd2lyZWQgODAyLjF4IGNvbm5lY3Rpb25zCi0gRml4IGlzc3VlcyB3aGVuIHVzaW5nIFBLQ1MjMTIgY2VydGlmaWNhdGVzIHdpdGggODAyLjF4IGNvbm5lY3Rpb25zAC0gQVBJIGFuZCBkb2N1bWVudGF0aW9uIHVwZGF0ZXMKLSBGaXggUElOIGhhbmRsaW5nIG9uICdoc28nIG1vYmlsZSBicm9hZGJhbmQgZGV2aWNlcwAtIEZpeCBQSU4vUFVLIGlzc3VlcyB3aXRoIGhpZ2gtc3BlZWQgT3B0aW9uIEhTRFBBIG1vYmlsZSBicm9hZGJhbmQgY2FyZHMKLSBGaXggZGVzZW5zaXRpemVkIE9LIGJ1dHRvbiB3aGVuIGFza2luZyBmb3Igd2lyZWxlc3Mga2V5cwAtIEZpeCBpc3N1ZXMgcmVhZGluZyBpZmNmZyBmaWxlcwotIFByZXZpb3VzbHkgZml4ZWQ6Ci0gRG9lc24ndCBzZW5kIERIQ1AgaG9zdG5hbWUgKHJoICM0NjkzMzYpCi0gJ0F1dG8gZXRoMCcgZm9yZ2V0cyBzZXR0aW5ncyAocmggIzQ2ODYxMikKLSBESENQIHJlbmV3YWwgc29tZXRpbWVzIGJyZWFrcyBWUE4gKHJoICM0NzE4NTIpCi0gQ29ubmVjdGlvbiBlZGl0b3IgbWVudSBpdGVtIGluIHRoZSB3cm9uZyBwbGFjZSAocmggIzQ3MTQ5NSkKLSBDYW5ub3QgbWFrZSBzeXN0ZW0td2lkZSBjb25uZWN0aW9ucyAocmggIzQ3MTMwOCkALSBVcGRhdGUgdG8gTmV0d29ya01hbmFnZXIgMC43LjAgUkMyCi0gSGFuZGxlIGdhdGV3YXlzIG9uIGEgZGlmZmVyZW50IHN1Ym5ldCBmcm9tIHRoZSBpbnRlcmZhY2UKLSBDbGVhciBWUE4gc2VjcmV0cyBvbiBjb25uZWN0aW9uIGZhaWx1cmUgdG8gZW5zdXJlIHRoZXkgYXJlIHJlcXVlc3RlZCBhZ2FpbiAocmggIzQyOTI4NykKLSBBZGQgc3VwcG9ydCBmb3IgUEtDUyMxMiBwcml2YXRlIGtleXMgKHJoICM0NjI3MDUpCi0gRml4IG1hbmdsaW5nIG9mIFZQTidzIGRlZmF1bHQgcm91dGUgb24gREhDUCByZW5ldwotIEZpeCB0eXBlIGRldGVjdGlvbiBvZiBxZW11L2t2bSBuZXR3b3JrIGRldmljZXMgKHJoICM0NjYzNDApCi0gQ2xlYXIgdXAgbmV0bWFzay9wcmVmaXggY29uZnVzaW9uIGluIHRoZSBjb25uZWN0aW9uIGVkaXRvcgotIE1ha2UgdGhlIHNlY3JldHMgZGlhbG9nIGdvIGF3YXkgd2hlbiBpdCdzIG5vdCBuZWVkZWQKLSBGaXggaW5hYmlsaXR5IHRvIGFkZCBzeXN0ZW0gY29ubmVjdGlvbnMgKHJoICM0NzEzMDgpAC0gTW9yZSByZWxpYWJsZSBtb2JpbGUgYnJvYWRiYW5kIGNhcmQgaW5pdGlhbGl6YXRpb24KLSBIYW5kbGUgbW9iaWxlIGJyb2FkYmFuZCBQSU5zIGNvcnJlY3RseSB3aGVuIFBQUCBwYXNzd29yZHMgYXJlIGFsc28gdXNlZAotIEFkZGl0aW9uYWwgUG9saWN5S2l0IGludGVncmF0aW9uIGZvciBlZGl0aW5nIHN5c3RlbSBjb25uZWN0aW9ucwotIENsb3NlIHRoZSBhcHBsZXQgbWVudSBpZiBhIGtleXJpbmcgcGFzc3dvcmQgaXMgbmVlZGVkIChyaCAjMzUzNDUxKQAtIEZpeCBpc3N1ZXMgd2l0aCBob3N0bmFtZSBkdXJpbmcgYW5hY29uZGEgaW5zdGFsbGF0aW9uIChyaCAjNDYxOTMzKQotIEZpeCBBZC1Ib2MgV1BBIGNvbm5lY3Rpb25zIChyaCAjNDYxMTk3KQotIERvbid0IHJlcXVpcmUgZ25vbWUtcGFuZWwgb3IgZ25vbWUtcGFuZWwtZGV2ZWwgKHJoICM0Mjc4MzQpCi0gRml4IGRldGVybWluYXRpb24gb2YgV1BBIGVuY3J5cHRpb24gY2FwYWJpbGl0aWVzIG9uIHNvbWUgY2FyZHMKLSBGaXggY29uZmxpY3RzIHdpdGggUFBUUCBhbmQgdnBuYyBwbHVnaW5zCi0gQWxsb3cgLmNlciBmaWxlIGV4dGVuc2lvbnMgd2hlbiBjaG9vc2luZyBjZXJ0aWZpY2F0ZXMALSBGaXggY29uZmxpY3RzIGZvciBvbGRlciBQUFRQIFZQTiBwbHVnaW5zAC0gRW5zdXJlIHRoYXQgbW9iaWxlIGJyb2FkYmFuZCBjYXJkcyBhcmUgcG93ZXJlZCB1cCBiZWZvcmUgdHJ5aW5nIHRvIHVzZSB0aGVtCi0gSG9zdG5hbWUgY2hhbmdpbmcgc3VwcG9ydCAocmggIzQ0MTQ1MykKLSBGaXggbW9iaWxlIGJyb2FkYmFuZCBzZWNyZXQgcmVxdWVzdHMgdG8gaGFwcGVuIGxlc3Mgb2Z0ZW4KLSBCZXR0ZXIgaGFuZGxpbmcgb2YgZGVmYXVsdCBkZXZpY2VzIGFuZCBkZWZhdWx0IHJvdXRlcwotIEJldHRlciBpbmZvcm1hdGlvbiBpbiB0b29sdGlwcyBhbmQgbm90aWZpY2F0aW9ucwotIFZhcmlvdXMgVUkgY2xlYW51cHM7IGhpZGUgd2lkZ2V0cyB0aGF0IGFyZW4ndCB1c2VkIChyaCAjNDY1Mzk3LCByaCAjNDY1Mzk1KQotIEFjY2VwdCBkaWZmZXJlbnQgc2VwYXJhdG9ycyBmb3IgRE5TIHNlcnZlcnMgYW5kIHNlYXJjaGVzCi0gTWFrZSBhcHBsZXQncyBpY29uIGFjY3VyYXRlbHkgcmVmbGVjdCBzaWduYWwgc3RyZW5ndGggb2YgdGhlIGN1cnJlbnQgQVAALSBGaXggY29ubmVjdGlvbiBjb21wYXJpc29uIHRoYXQgY291bGQgY2F1c2UgY2hhbmdlcyB0byBnZXQgb3ZlcndyaXR0ZW4gKHJoICM0NjQ0MTcpAC0gRml4IGhhbmRsaW5nIG9mIFZQTiBzZXR0aW5ncyBvbiB1cGdyYWRlIChyaCAjNDYwNzMwLCBiZ28gIzU1MzQ2NSkALSBGaXggaGFuZyB3aGVuIHJlYWRpbmcgc3lzdGVtIGNvbm5lY3Rpb25zIGZyb20gaWZjZmcgZmlsZXMALSBGaXggV1BBIEFkLUhvYyBjb25uZWN0aW9ucwAtIEZpeCBwYXJzaW5nIG9mIERPTUFJTiBpbiBpZmNmZyBmaWxlcyAocmggIzQ1OTM3MCkKLSBGaXggcmVjb25uZWN0aW9uIHRvIG1vYmlsZSBicm9hZGJhbmQgbmV0d29ya3MgYWZ0ZXIgYW4gYXV0aCBmYWlsdXJlCi0gRml4IHJlY29nbml0aW9uIG9mIHRpbWVvdXRzIG9mIFBQUCBkdXJpbmcgbW9iaWxlIGJyb2FkYmFuZCBjb25uZWN0aW9uCi0gTW9yZSBjb21wYXRpYmxlIGNvbm5lY3Rpb24gc2hhcmluZyAocmggIzQ1ODYyNSkKLSBGaXggREhDUCBpbiBtaW5pbWFsIGVudmlyb25tZW50cyB3aXRob3V0IGdsaWJjIGxvY2FsZSBpbmZvcm1hdGlvbiBpbnN0YWxsZWQKLSBBZGQgc3VwcG9ydCBmb3IgT3B0aW9uIG1vYmlsZSBicm9hZGJhbmQgZGV2aWNlcyAobGlrZSBpQ09OIDIyNSBhbmQgaUNPTiA3LjIpCi0gQWRkIElQNCBjb25maWcgaW5mb3JtYXRpb24gdG8gZGlzcGF0Y2hlciBzY3JpcHQgZW52aXJvbm1lbnQKLSBNZXJnZSBXRVAgQVNDSUkgYW5kIEhleCBrZXkgdHlwZXMgZm9yIGNsZWFuZXIgVUkKLSBQcmUtZmlsbCBQUFBvRSBwYXNzd29yZCB3aGVuIGF1dGhlbnRpY2F0aW9uIGZhaWxzCi0gRml4ZWQgc29tZSBjaGFuZ2VzIG5vdCBnZXR0aW5nIHNhdmVkIGluIHRoZSBjb25uZWN0aW9uIGVkaXRvcgotIEFjY2VwdCBib3RoIHByZWZpeCBhbmQgbmV0bWFzayBpbiB0aGUgY29uZWN0aW9uIGVkaXRvcidzIElQdjQgcGFnZQAtIEZpeCBpc3N1ZSB3aXRoIG1vYmlsZSBicm9hZGJhbmQgY29ubmVjdGlvbnMgdGhhdCBkb24ndCByZXF1aXJlIGF1dGhlbnRpY2F0aW9uAC0gRXhwb3NlIERIQ1AtcmV0dXJuZWQgb3B0aW9ucyBvdmVyIEQtQnVzIGFuZCB0byBkaXNwYXRjaGVyIHNjcmlwdHMKLSBBZGQgc3VwcG9ydCBmb3IgY3VzdG9taXplZCBzdGF0aWMgcm91dGVzCi0gSGFuZGxlIG11bHRpcGxlIGNvbmN1cnJlbnQgM0cgb3IgUFBQb0UgY29ubmVjdGlvbnMKLSBGaXggR1NNL0NETUEgdXNlcm5hbWUgYW5kIHBhc3N3b3JkIGlzc3VlcwotIEJldHRlciBoYW5kbGluZyBvZiB1bm1hbmFnZWQgZGV2aWNlcyBmcm9tIGlmY2ZnIGZpbGVzCi0gRml4IHRpbWVvdXQgaGFuZGxpbmcgb2YgZXJyb3JzIGR1cmluZyAzRyBjb25uZWN0aW9ucwotIEZpeCBzb21lIHJvdXRpbmcgaXNzdWVzIChyaCAjNDU2Njg1KQotIEZpeCBhcHBsZXQgY3Jhc2hlcyBhZnRlciByZW1vdmluZyBhIGRldmljZSAocmggIzQ1NzM4MCkALSBDb252ZXJ0IHN0b3JlZCBJUHY0IHN0YXRpYyBJUCBhZGRyZXNzZXMgdG8gbmV3IHByZWZpeC1iYXNlZCBzY2hlbWUgYXV0b21hdGljYWxseQotIEZpeCBwcHBkIGNvbm5lY3Rpb25zIHRvIHNvbWUgM0cgcHJvdmlkZXJzIChyaCAjNDU1MzQ4KQotIE1ha2UgUFBQb0UgIlNob3cgUGFzc3dvcmQiIG9wdGlvbiB3b3JrCi0gSGlkZSBJUHY0IGNvbmZpZyBvcHRpb25zIHRoYXQgZG9uJ3QgbWFrZSBzZW5zZSBpbiBjZXJ0YWluIGNvbmZpZ3VyYXRpb25zAC0gRXhwb3NlIHNlcnZlci1yZXR1cm5lZCBESENQIG9wdGlvbnMgdmlhIEQtQnVzCi0gVXNlIGF2YWhpLWF1dG9pcGQgcmF0aGVyIHRoYW4gb2xkIGJ1aWx0LWluIElQdjRMTCBpbXBsZW1lbnRhdGlvbgotIFNlbmQgaG9zdG5hbWUgdG8gREhDUCBzZXJ2ZXIgaWYgcHJvdmlkZWQgKERIQ1BfSE9TVE5BTUUgaWZjZmcgb3B0aW9uKQotIFN1cHBvcnQgc2VuZGluZyBESENQIENsaWVudCBJZGVudGlmaWVyIHRvIERIQ1Agc2VydmVyCi0gQWxsb3cgZm9yY2luZyA4MDIuMXggUEVBUCBMYWJlbCB0byAnMCcKLSBNYWtlIGNvbm5lY3Rpb24gc2hhcmluZyBtb3JlIHJvYnVzdAotIFNob3cgc3RhdHVzIGZvciBzaGFyZWQgYW5kIEFkLUhvYyBjb25uZWN0aW9ucyBpZiBubyBvdGhlciBjb25uZWN0aW9uIGlzIGFjdGl2ZQAtIERyb3AgZXhwbGljaXQgaGFsIGRlcCBpbiAtZ25vbWUALSBNb3ZlIFZQTiBjb25maWd1cmF0aW9uIGludG8gY29ubmVjdGlvbiBlZGl0b3IKLSBGaXggbW9iaWxlIGJyb2FkYmFuZCB1c2VybmFtZS9wYXNzd29yZCBpc3N1ZXMKLSBGaXggaXNzdWVzIHdpdGggYnJva2VuIHJma2lsbCBzZXR1cHMgKHJoICM0NDg4ODkpCi0gSG9ub3IgQVBOIHNldHRpbmcgZm9yIEdTTSBtb2JpbGUgYnJvYWRiYW5kIGNvbmZpZ3VyYXRpb25zCi0gRml4IGFkZGluZyBDRE1BIGNvbm5lY3Rpb25zIGluIHRoZSBjb25uZWN0aW9uIGVkaXRvcgAtIFVwZGF0ZSB0byBsYXRlc3QgU1ZOCi0gRW5hYmxlIGNvbm5lY3Rpb24gc2hhcmluZwotIFJlc3BlY3QgVlBOLXByb3ZpZGVkIHJvdXRlcwAtIE1vdmUgTk0gbGF0ZXIgaW4gdGhlIHNodXRkb3duIHByb2Nlc3MgKHJoICM0NDkwNzApCi0gTW92ZSBsaWJubS11dGlsIGludG8gYSBzdWJwYWNrYWdlIHRvIGFsbG93IE5NIHRvIGJlIHJlbW92ZWQgbW9yZSBlYXNpbHkgKHJoICMzNTExMDEpAC0gUmVhZCBnbG9iYWwgZ2F0ZXdheSBmcm9tIC9ldGMvc3lzY29uZmlnL25ldHdvcmsgaWYgbWlzc2luZyAocmggIzQ0NjUyNykKLSBubS1zeXN0ZW0tc2V0dGluZ3Mgbm93IHRlcm1pbmF0ZXMgd2hlbiBkYnVzIGdvZXMgYXdheSAocmggIzQ0NDk3NikALSBGaXggaW5pdGlhbCBjYXJyaWVyIHN0YXRlIGRldGVjdGlvbiBvbiBkZXZpY2VzIHRoYXQgYXJlIGFscmVhZHkgdXAgKHJoICMxMzQ4ODYpAC0gUmVzdG9yZSBiZWhhdmlvciBvZiBtYXJraW5nIHdpZmkgZGV2aWNlcyBhcyAiZG93biIgd2hlbiBkaXNhYmxpbmcgd2lyZWxlc3MKLSBGaXggYSBjcmFzaCBvbiByZXN1bWUgd2hlbiBhIFZQTiB3YXMgYWN0aXZlIHdoZW4gZ29pbmcgdG8gc2xlZXAALSBGaXggaXNzdWVzIHdpdGggdGhlIEZlZG9yYSBwbHVnaW4gbm90IG5vdGljaW5nIGNoYW5nZXMgbWFkZSBieQogICAgc3lzdGVtLWNvbmZpZy1uZXR3b3JrIChyaCAjNDQ0NTAyKQotIEFsbG93IGF1dG9jb25uZWN0aW9uIG9mIEdTTSBhbmQgQ0RNQSBjb25uZWN0aW9ucwotIE11bHRpcGxlIElQIGFkZHJlc3Mgc3VwcG9ydCBmb3IgdXNlciBjb25uZWN0aW9ucwotIEZpeGVzIGZvciBNb2JpbGUgQnJvYWRiYW5kIGNhcmRzIHRoYXQgcmV0dXJuIGxpbmUgc3BlZWQgb24gY29ubmVjdAotIEltcGxlbWVudCBQSU4gZW50cnkgZm9yIEdTTSBtb2JpbGUgYnJvYWRiYW5kIGNvbm5lY3Rpb25zCi0gRml4IGNyYXNoIHdoZW4gZWRpdGluZyB1bmVuY3J5cHRlZCBXaUZpIGNvbm5lY3Rpb25zIGluIHRoZSBjb25uZWN0aW9uIGVkaXRvcgAtIENsZWFuIHVwIHRoZSBkaXNwYXRjaGVyIG5vdyB0aGF0IGl0J3Mgc2VydmljZSBpcyBnb25lIChyaCAjNDQ0Nzk4KQAtIEZpeCBhc2tpbmcgYXBwbGV0cyBmb3IgdGhlIEdTTSBQSU4vUFVLAC0gR3Vlc3MgV0VQIGtleSB0eXBlIGluIGFwcGxldCB3aGVuIGFza2luZyBmb3IgbmV3IGtleXMKLSBDb3JyZWN0IE9LIGJ1dHRvbiBzZW5zaXRpdml0eSBpbiBhcHBsZXQgd2hlbiBhc2tpbmcgZm9yIG5ldyBXRVAga2V5cwAtIEZpeCBpc3N1ZXMgd2l0aCBNb2JpbGUgQnJvYWRiYW5kIGNvbm5lY3Rpb25zIGNhdXNlZCBieSBkZXZpY2UgaW5pdCByYWNlIHBhdGNoAC0gRml4IGRldmljZSBpbml0aWFsaXphdGlvbiByYWNlIHRoYXQgY2F1c2VkIGV0aGVybmV0IGRldmljZXMgdG8gZ2V0IHN0dWNrIG9uCiAgICBzdGFydHVwCi0gRml4IFBQUG9FIGNvbm5lY3Rpb25zIG5vdCBzaG93aW5nIHVwIGluIHRoZSBhcHBsZXQKLSBGaXggZGlzYWJsZWQgT0sgYnV0dG9uIGluIGNvbm5lY3Rpb24gZWRpdG9yIHNvbWUgd2lyZWxlc3MgYW5kIElQNCBzZXR0aW5ncwotIERvbid0IGV4aXQgaWYgSEFMIGlzbid0IHVwIHlldDsgd2FpdCBmb3IgaXQKLSBGaXggYSBzdXNwZW5kL3Jlc3VtZSBjcmFzaAAtIERvbid0IGFzayBmb3Igd2lyZWxlc3Mga2V5cyB3aGVuIHRoZSBkcml2ZXIgc2VuZHMgZGlzY29ubmVjdCBldmVudHMgZHVyaW5nCglhc3NvY2lhdGlvbjsgd2FpdCB1bnRpbCB0aGUgZW50aXJlIGFzc29jYXRpb24gdGltZXMgb3V0Ci0gUmVwbGFjZSBkaXNwYXRjaGVyIGRhZW1vbiB3aXRoIEQtQnVzIGFjdGl2YXRlZCBjYWxsb3V0Ci0gRml4IHBhcnNpbmcgb2YgRE5TMiBhbmQgRE5TMyBpZmNmZyBmaWxlIGl0ZW1zCi0gRXhlY3V0ZSBkaXNwYXRjaGVyIHNjcmlwdHMgaW4gYWxwaGFiZXRpY2FsIG9yZGVyCi0gQmUgYWN0aXZlIGF0IHJ1bmxldmVsIDIKLSBIb29rIHVwIE1BQyBhZGRyZXNzIHdpZGdldHMgZm9yIHdpcmVkICYgd2lyZWxlc3M7IGFuZCBCU1NJRCB3aWRnZXQgZm9yIHdpcmVsZXNzCi0gUHJlLXBvcHVsYXRlIGFub255bW91cyBpZGVudGl0eSBhbmQgcGhhc2UyIHdpZGdldHMgY29ycmVjdGx5Ci0gQ2xlYXIgb3V0IHVudXNlZCBjb25uZWN0aW9uIGtleXMgZnJvbSBHQ29uZgAtIERvbid0IHNlbGVjdCBkZXZpY2VzIHdpdGhvdXQgYSBkZWZhdWx0IGdhdGV3YXkgYXMgdGhlIGRlZmF1bHQgcm91dGUgKHJoICM0MzczMzgpCi0gRmlsbCBpbiBicm9hZGNhc3QgYWRkcmVzcyBpZiBub3Qgc3BlY2lmaWVkIChyaCAjNDQzNDc0KQotIFJlc3BlY3QgbWFudWFsIFZQTiBJUHY0IGNvbmZpZ3VyYXRpb24gb3B0aW9ucwotIFNob3cgQ29ubmVjdGlvbiBJbmZvcm1hdGlvbiBmb3IgdGhlIGRldmljZSB3aXRoIHRoZSBkZWZhdWx0IHJvdXRlIG9ubHkALSBBZGQgZGJ1cy1nbGliLWRldmVsIEJ1aWxkUmVxdWlyZXMgZm9yIE5ldHdvcmtNYW5hZ2VyLWdsaWItZGV2ZWwgKHJoICM0NDI5NzgpCi0gQWRkIFBQUCBzZXR0aW5ncyBwYWdlIHRvIGNvbm5lY3Rpb24gZWRpdG9yCi0gRml4IGEgZmV3IGNyYXNoZXMgd2l0aCBQUFBvRQotIEZpeCBhY3RpdmUgY29ubmVjdGlvbiBzdGF0ZSBjaGFuZ2VzIHRoYXQgY29uZnVzZWQgY2xpZW50cwAtIEZpeCBidWlsZCBpbiBwcHBkLXBsdWdpbgAtIFBQUG9FIGF1dGhlbnRpY2F0aW9uIGZpeGVzCi0gTW9yZSByb2J1c3QgaGFuZGluZyBvZiBtb2JpbGUgYnJvYWRiYW5kIGRldmljZSBjb21tdW5pY2F0aW9ucwAtIEhvbm9yIG9wdGlvbnMgZnJvbSAvZXRjL3N5c2NvbmZpZy9uZXR3b3JrIGZvciBibG9ja2luZyB1bnRpbCBuZXR3b3JrIGlzIHVwAC0gVHVybiBvbiBBZGQvRWRpdCBpbiB0aGUgY29ubmVjdGlvbiBlZGl0b3IKLSBEb24ndCBmbHVzaCBvciBjaGFuZ2UgSVB2NiBhZGRyZXNzZXMgb3Igcm91dGVzCi0gRW5oYW5jZSBubS1vbmxpbmUgdG9vbAotIFNvbWUgc2VyaWFsIGNvbW11bmljYXRpb24gZml4ZXMgZm9yIG1vYmlsZSBicm9hZGJhbmQALSBGaXggaXNzdWVzIHdpdGggVlBOIHBhc3N3b3JkcyBub3QgZ2V0dGluZyBmb3VuZAAtIEZpeCBidWlsZHMgZHVlIHRvIGdsaWIyIGJyZWFrYWdlIG9mIEdTdGF0aWNNdXRleCB3aXRoIGdjYyA0LjMALSBGaXggV0VQIGtleSBpbmRleCBoYW5kbGluZyBpbiBVSQotIEZpeCBoYW5kbGluZyBvZiBOTV9DT05UUk9MTEVEIGluIGlmY2ZnIGZpbGVzCi0gU2hvdyBkZXZpY2UgbWFuYWdlZCBzdGF0ZSBpbiBhcHBsZXQgbWVudQotIFNob3cgd2lyZWxlc3MgZW5hYmxlZCBzdGF0ZSBpbiBhcHBsZXQgbWVudQotIEJldHRlciBoYW5kbGluZyBvZiBkZWZhdWx0IERIQ1AgY29ubmVjdGlvbnMgZm9yIHdpcmVkIGRldmljZXMKLSBGaXggbG9hZGluZyBvZiBjb25uZWN0aW9uIGVkaXRvciBvbiBLREUgKHJoICM0MzUzNDQpAC0gSG9ub3IgTUFDIGFkZHJlc3MgbG9ja2luZyBmb3Igd2lyZWQgJiB3aXJlbGVzcyBkZXZpY2VzAC0gU2hvdyBWUE4gZmFpbHVyZXMKLSBTdXBwb3J0IFN0YXRpYyBXRVAga2V5IGluZGV4ZXMKLSBGaXggcGFyc2luZyBvZiBXRVAga2V5cyBmcm9tIGlmY2ZnIGZpbGVzCi0gUHJlLWZpbGwgd2lyZWxlc3Mgc2VjdXJpdHkgVUkgYml0cyBpbiBjb25uZWN0aW9uIGVkaXRvciBhbmQgYXBwbGV0AC0gR3JhYiBzeXN0ZW0gc2V0dGluZ3MgZnJvbSAvZXRjL3N5c2NvbmZpZy9uZXR3b3JrLXNjcmlwdHMsIG5vdCBmcm9tIHByb2ZpbGVzAC0gRml4IGNyYXNoZXMgd2hlbiByZXR1cm5pbmcgVlBOIHNlY3JldHMgZnJvbSB0aGUgYXBwbGV0IHRvIE5NAC0gRml4IGNyYXNoZXMgb24gc3VzcGVuZC9yZXN1bWUgYW5kIGV4aXQgKHJoICM0Mzc0MjYpCi0gRW5zdXJlIHRoZXJlJ3MgYWx3YXlzIGFuIG9wdGlvbiB0byBjaG9zZSB0aGUgd2lyZWQgZGV2aWNlCi0gTmV2ZXIgc2V0IGRlZmF1bHQgcm91dGUgdmlhIGFuIElQdjQgbGluay1sb2NhbCBhZGRyZXNzZWQgZGV2aWNlIChyaCAjNDM3MzM4KQAtIEZpeCBESENQIHJlYmluZCBiZWhhdmlvcgotIFByZWxpbWluYXJ5IFBQUG9FIHN1cHBvcnQALSBGaXggZ25vbWUtaWNvbi10aGVtZSBSZXF1aXJlcywgc2hvdWxkIGJlIG9uIGdub21lIHN1YnBhY2thZ2UALSBIb25vciBESENQIHJlYmluZHMKLSBNdWx0aXBsZSBhY3RpdmUgZGV2aWNlIHN1cHBvcnQKLSBCZXR0ZXIgZXJyb3IgaGFuZGxpbmcgb2YgbW9iaWxlIGJyb2FkYmFuZCBjb25uZWN0aW9uIGZhaWx1cmVzCi0gQWxsb3cgdXNlIG9mIGludGVyZmFjZS1zcGVjaWZpYyBkaGNsaWVudCBjb25maWcgZmlsZXMKLSBSZWNvZ25pemUgc3lzdGVtIHNldHRpbmdzIHdoaWNoIGhhdmUgbm8gVFlQRSBpdGVtAC0gRml4IGNyYXNoIG9mIG5tLXN5c3RlbS1zZXR0aW5ncyBvbiBtYWxmb3JtZWQgaWZjZmcgZmlsZXMgKHJoICM0MzQ5MTkpCi0gUmVxdWlyZSBnbm9tZS1pY29uLXRoZW1lIHRvIHBpY2sgdXAgbG9jay5wbmcgKHJoICM0MzUzNDQpCi0gRml4IGFwcGxldCBzZWdmYXVsdCBhZnRlciBjb25uZWN0aW9uIHJlbW92YWwgdmlhIGNvbm5lY3Rpb24gZWRpdG9yIG9yIEdDb25mAC0gRG9uJ3QgY3JlYXRlIG11bHRpcGxlIGNvbm5lY3Rpb25zIGZvciBoaWRkZW4gYWNjZXNzIHBvaW50cwotIEZpeCBzY2FubmluZyBiZWhhdmlvcgAtIFJld29yayBjb25uZWN0aW9uIGVkaXRvciBjb25uZWN0aW9uIGxpc3QALSBCZXR0ZXIgaGFuZGxpbmcgb2YgY2hhbmdlcyBpbiB0aGUgcHJvZmlsZSBkaXJlY3RvcnkgYnkgdGhlIHN5c3RlbSBzZXR0aW5ncwoJc2VyaXZjZQAtIEVuYWJsZSBzeXN0ZW0gc2V0dGluZ3Mgc2VydmljZQotIEFsbG93IGV4cGxpY2l0IGRpc2Nvbm5lY3Rpb24gb2YgbW9iaWxlIGJyb2FkYmFuZCBkZXZpY2VzCi0gRml4IGFwcGxldCBtZW1vcnkgbGVha3MgKHJoICM0MzAxNzgpCi0gQXBwbGV0IENvbm5lY3Rpb24gSW5mb3JtYXRpb24gZGlhbG9nIHR3ZWFrcyAoZ25vbWUub3JnICM1MDU4OTkpCi0gRmlsdGVyIGlucHV0IGNoYXJhY3RlcnMgdG8gcGFzc3BocmFzZS9rZXkgZW50cnkgKGdub21lLm9yZyAjMzMyOTUxKQotIEZpeCBhcHBsZXQgZm9jdXMgc3RlYWxpbmcgcHJldmVudGlvbiBiZWhhdmlvcgAtIEFkZCBDRE1BIG1vYmlsZSBicm9hZGJhbmQgc3VwcG9ydCAoaWYgc3VwcG9ydGVkIGJ5IEhBTCkKLSBSZXdvcmsgYXBwbGV0IGNvbm5lY3Rpb24gYW5kIGljb24gaGFuZGxpbmcKLSBFbmFibGUgY29ubmVjdGlvbiBlZGl0b3IgKG9ubHkgZm9yIGRlbGV0aW5nIGNvbm5lY3Rpb25zKQAtIEZpeCBjcmFzaCB3aGVuIGFjdGl2YXRpbmcgYSBtb2JpbGUgYnJvYWRiYW5kIGNvbm5lY3Rpb24KLSBCZXR0ZXIgaGFuZGxpbmcgb2Ygbm9uLVNTSUQtYnJvYWRjYXN0aW5nIEFQcyBvbiBrZXJuZWxzIHRoYXQgc3VwcG9ydCBpdAogICAgKGdub21lLm9yZyAjNDY0MjE1KSAocmggIzM3Mzg0MSkKLSBIb25vciBESENQLXNlcnZlciBwcm92aWRlZCBNVFUgaWYgcHJlc2VudCAoZ25vbWUub3JnICMzMzI5NTMpCi0gVXNlIHByZXZpb3VzIEROUyBzZXR0aW5ncyBpZiB0aGUgVlBOIGNvbmNlbnRyYXRvciBkb2Vzbid0IHByb3ZpZGUgYW55CiAgICAoZ25vbWUub3JnICMzNDY4MzMpAC0gRml4IFdQQSBwYXNzcGhyYXNlIGhhc2hpbmcgb24gYmlnIGVuZGlhbiAoUFBDLCBTcGFyYywgZXRjKSAocmggIzQyNjIzMykALSBGaXhlcyB0byB3b3JrIGJldHRlciB3aXRoIG5ldyBsaWJubCAocmggIzQwMTc2MSkALSBGaXggV1BBL1dQQTIgRW50ZXJwcmlzZSBQaGFzZTIgY29ubmVjdGlvbnMgKHJoICMzODg0NzEpAC0gRml4IGFwcGxldCBjb25uZWN0aW9uIGNvbXBhcmlzb24gd2hpY2ggZmFpbGVkIHRvIHNlbmQgY29ubmVjdGlvbiB1cGRhdGVkCiAgICBzaWduYWxzIHRvIE5NIGluIHNvbWUgY2FzZXMKLSBNYWtlIFZQTiBjb25uZWN0aW9uIGFwcGxldCBtb3JlIHJvYnVzdCBhZ2FpbnN0IHBsdWdpbiBmYWlsdXJlcwAtIDY0LWJpdCAtV2FsbCBjb21waWxlIGZpeGVzAC0gRml4IGFwcGxldCBjcmFzaCB3aGVuIGNob29zaW5nIHRvIGlnbm9yZSB0aGUgQ0EgY2VydGlmaWNhdGUgKHJoICMzNTkwMDEpCi0gRml4IGFwcGxldCBjcmFzaCB3aGVuIGVkaXRpbmcgVlBOIHByb3BlcnRpZXMgYW5kIFZQTiBjb25uZWN0aW9uIGZhaWx1cmVzIChyaCAjNDA5MzUxKQotIEFkZCBmaWxlIGZpbHRlciBuYW1lIGluIGNlcnRpZmljYXRlIGZpbGUgcGlja2VyIGRpYWxvZyAocmggIzQxMDIwMSkKLSBObyBsb25nZXIgc3RhcnQgbmFtZWQgd2hlbiBzdGFydGluZyBOTSAocmggIzM4MTU3MSkALSBGaXggdXBncmFkaW5nIGZyb20gYW4gZWFybGllciByYXdoaWRlIHNuYXAALSBGaXggZGV2aWNlIGRlc2NyaXB0aW9ucyBzaG93biBpbiBhcHBsZXQgbWVudQAtIEZpeCBjcmFzaCB3aGVuIGRlYWN0aXZhdGluZyBWUE4gY29ubmVjdGlvbnMALSBGaXggY3Jhc2ggYW5kIHBvdGVudGlhbCBpbmZpbml0ZSBuYWcgZGlhbG9nIGxvb3Agd2hlbiBpZ25vcmluZyBDQSBjZXJ0aWZpY2F0ZXMALSBGaXggY3Jhc2ggd2hlbiBpZ25vcmluZyBDQSBjZXJ0aWZpY2F0ZSBmb3IgRUFQLVRMUywgRUFQLVRUTFMsIGFuZCBFQVAtUEVBUAAtIEZpeCBjb25uZWN0aW9ucyB3aGVuIHBpY2tpbmcgYSBXUEEgRW50ZXJwcmlzZSBBUCBmcm9tIHRoZSBtZW51Ci0gRml4IGlzc3VlIHdoZXJlIGFwcGxldCB3b3VsZCBwcm92aWRlIG11bHRpcGxlIHNhbWUgY29ubmVjdGlvbnMgdG8gTk0ALSBBZGQgc3VwcG9ydCBmb3IgRUFQLVBFQVAgKHJoICMzNjIyNTEpCi0gRml4IEVBUC1UTFMgcHJpdmF0ZSBrZXkgaGFuZGxpbmcALSBDbGFyaWZ5IG5hbWluZyBvZiBXUEEgJiBXUEEyIFBlcnNvbmFsIGVuY3J5cHRpb24gb3B0aW9ucyAocmggIzM3NDg2MSwgcmggIzM3MzgzMSkKLSBEb24ndCByZXF1aXJlIGEgQ0EgY2VydGlmaWNhdGUgZm9yIGFwcGxpY2FibGUgRUFQIG1ldGhvZHMgKHJoICMzNTkwMDEpCi0gRml4IGNlcnRpZmljYXRlIGFuZCBwcml2YXRlIGtleSBoYW5kbGluZyBmb3IgRUFQLVRUTFMgYW5kIEVBUC1UTFMgKHJoICMzMjMzNzEpCi0gRml4IGFwcGxldCBjcmFzaCB3aXRoIFVTQiBkZXZpY2VzIChyaCAjMzM3MTkxKQotIFN1cHBvcnQgdXBncmFkZXMgZnJvbSBOTSAwLjYueCBHQ29uZiBzZXR0aW5ncwAtIEZpeCBhcHBsZXQgY3Jhc2ggd2l0aCBVU0IgZGV2aWNlcyB0aGF0IGRvbid0IGFkdmVydGlzZSBhIHByb2R1Y3Qgb3IgdmVuZG9yCiAgICAocmggIzMzNzE5MSkALSBGaXggY3Jhc2ggd2hlbiBnZXR0aW5nIFdQQSBzZWNyZXRzIChyaCAjMzU1MDQxKQAtIEJyaW5nIHVwIGV0aGVybmV0IGRldmljZXMgYnkgZGVmYXVsdCBpZiBubyBjb25uZWN0aW9ucyBhcmUgZGVmaW5lZCAocmggIzMzOTIwMSkKLSBGaXggY3Jhc2ggd2hlbiBzd2l0Y2hpbmcgbmV0d29ya3Mgb3IgYnJpbmdpbmcgdXAgc2VjcmV0cyBkaWFsb2cgKHJoICMzNTMwOTEpCi0gRml4IGNyYXNoIHdoZW4gZWRpdGluZyBWUE4gY29ubmVjdGlvbiBwcm9wZXJ0aWVzIGEgc2Vjb25kIHRpbWUKLSBGaXggY3Jhc2ggd2hlbiBjYW5jZWxsaW5nIHRoZSBzZWNyZXRzIGRpYWxvZyBpZiBhbm90aGVyIGNvbm5lY3Rpb24gd2FzCiAgICBhY3RpdmF0ZWQgaW4gdGhlIG1lYW4gdGltZQotIEZpeCBkaXNlbWJvZGllZCBub3RpZmljYXRpb24gYnViYmxlcyAocmggIzMzMzM5MSkALSBIYW5kbGUgUEVNIGNlcnRpZmljYXRlcwotIEhpZGUgV1BBLVBTSyBUeXBlIGNvbWJvIHNpbmNlIGl0J3MgYXMgeWV0IHVudXNlZAotIEZpeCBhcHBsZXQgY3Jhc2ggd2hlbiBBUCBzZWN1cml0eSBvcHRpb25zIGNoYW5nZWQgYW5kIG9sZCBzZWNyZXRzIGFyZSBzdGlsbAogICAgaW4gdGhlIGtleXJpbmcKLSBGaXggYXBwbGV0IGNyYXNoIGNvbm5lY3RpbmcgdG8gdW5lbmNyeXB0ZWQgQVBzIHZpYSB0aGUgb3RoZXIgbmV0d29yayBkaWFsb2cALSBGaXggV1BBIEVudGVycHJpc2UgY29ubmVjdGlvbnMgdGhhdCB1c2UgY2VydGlmaWNhdGVzCi0gQmV0dGVyIGRpc3BsYXkgb2YgU1NJRHMgaW4gdGhlIG1lbnUALSBGaXggZ2V0dGluZyBjdXJyZW50IGFjY2VzcyBwb2ludAotIEZpeCBXUEEgRW50ZXJwcmlzZSBjb25uZWN0aW9ucwotIFdpcmVsZXNzIGRpYWxvZyBub3cgZGVmYXVsdHMgdG8gc2Vuc2libGUgY2hvaWNlcyBiYXNlZCBvbiB0aGUgY29ubmVjdGlvbgotIFRlbGwgbnNjZCB0byByZXN0YXJ0IGlmIG5lZWRlZCwgZG9uJ3Qgc2lsZW50bHkga2lsbCBpdAAtIFN1cHByZXNzIGV4Y2Vzc2l2ZSBHQ29uZiB1cGRhdGVzIHdoaWNoIHNvbWV0aW1lcyBjYXVzZWQgc2VjcmV0cyB0byBiZSBjbGVhcmVkCiAgICBhdCB0aGUgd3JvbmcgdGltZXMsIGNhdXNpbmcgY29ubmVjdGlvbnMgdG8gZmFpbAotIFZhcmlvdXMgRUFQIGFuZCBMRUFQIHJlbGF0ZWQgZml4ZXMALSBNYWtlIFdQQS1FQVAgYW5kIER5bmFtaWMgV0VQIG9wdGlvbnMgY29ubmVjdCBzdWNjZXNzZnVsbHkKLSBTdGF0aWMgSVBzIGFyZSBub3cgaGFuZGxlZCBjb3JyZWN0bHkgaW4gTk0gaXRzZWxmAC0gQWRkIER5bmFtaWMgV0VQIGFzIGEgc3VwcG9ydGVkIGF1dGhlbnRpY2F0aW9uL3NlY3VyaXR5IG9wdGlvbgAtIFJlLWVuYWJsZSAiQ29ubmVjdCB0byBvdGhlciBuZXR3b3JrIgotIFN3aXRjaCB0byBuZXcgR1VJIGJpdHMgZm9yIHdpcmVsZXNzIHNlY3VyaXR5IGNvbmZpZyBhbmQgcGFzc3dvcmQgZW50cnkALSBBZGQgcmZraWxsIGZ1bmN0aW9uYWxpdHkKLSBGaXggYXBwbGV0IGNyYXNoIHdoZW4gY2hvb3Npbmcgd2lyZWQgbmV0d29ya3MgZnJvbSB0aGUgbWVudQAtIEZpeCBzZWdmYXVsdCB3aXRoIGRlZmVycmVkIGNvbm5lY3Rpb25zCi0gRml4IGRlZmF1bHQgdXNlcm5hbWUgd2l0aCB2cG5jIFZQTiBwbHVnaW4KLSBIaWRkZW4gU1NJRCBmaXhlcwAtIEZpeCBtZXJnaW5nIG9mIG5vbi1TU0lELWJyb2FkY2FzdGluZyBBUHMgaW50byBhIGRldmljZSdzIHNjYW4gbGlzdAotIFNwZWVkIHVwIG9wZW5pbmcgb2YgdGhlIGFwcGxldCBtZW51AC0gTmV3IHNuYXBzaG90CgktIEFkZCB0aW1lc3RhbXBzIHRvIG5ldHdvcmtzIHRvIGNvbm5lY3QgdG8gbGFzdCB1c2VkIHdpcmVsZXNzIG5ldHdvcmsKCS0gVHVybiBhdXRvY29ubmVjdCBvbiBpbiB0aGUgYXBwbGV0CgktIEhpZGRlbiBTU0lEIHN1cHBvcnQKCS0gSW52YWxpZGF0ZSBmYWlsZWQgb3IgY2FuY2VsbGVkIGNvbm5lY3Rpb25zIGFnYWluCgktIEZpeCBpc3N1ZXMgd2l0aCByZWFjdGl2YXRpb24gb2YgdGhlIHNhbWUgZGV2aWNlCgktIEhhbmRsZSBjb25uZWN0aW9uIHVwZGF0ZXMgaW4gdGhlIGFwcGxldCAoZXguIGZpbmQgbmV3IFZQTiBjb25uZWN0aW9ucykKCS0gRml4IHZlcnRpY2FsIHNpemluZyBvZiBtZW51IGl0ZW1zCgktIEZpeCBBUCBsaXN0IG9uIHdpcmVsZXNzIGRldmljZXMgb3RoZXIgdGhhbiB0aGUgZmlyc3QgZGV2aWNlIGluIHRoZSBhcHBsZXQKCS0gRml4IG1hdGNoaW5nIG9mIGN1cnJlbnQgQVAgd2l0aCB0aGUgcmlnaHQgbWVudSBpdGVtAC0gTmV3IHNuYXBzaG90CgktIEFkZCBXUEEgcGFzc3BocmFzZSBzdXBwb3J0IHRvIHBhc3N3b3JkIGRpYWxvZwoJLSBBcHBsZXQgbm93IHJlZmxlY3RzIGFjdHVhbCBWUE4gYmVoYXZpb3Igb2Ygb25lIGFjdGl2ZSBjb25uZWN0aW9uCgktIEFwcGxldCBub3cgbm90aWNlcyBWUE4gYWN0aXZlIGNvbm5lY3Rpb25zIG9uIHN0YXJ0dXAKCS0gRml4IGNvbm5lY3Rpb25zIHdpdGggc29tZSBXUEEgYW5kIFdFUCBrZXlzAC0gTmV3IHNuYXBzaG90CgktIFZQTiBzdXBwb3J0IChvbmx5IHZwbmMgcGx1Z2luIHBvcnRlZCBhdCB0aGlzIHRpbWUpAC0gTmV3IHNuYXBzaG90CgktIE1ha2Ugd2lyZWQgZGV2aWNlIGNhcnJpZXIgc3RhdGUgd29yayBpbiB0aGUgYXBwbGV0CgktIEZpeCBoYW5kbGluZyBvZiBlcnJvcnMgd2l0aCB1bmVuY3J5cHRlZCBBUHMKCS0gRml4ICJmcm96ZW4iIGFwcGxldCBpY29uIGJ5IHJlcG9ydGluZyBOTSBzdGF0ZSBiZXR0ZXIKCS0gRml4IG91dHB1dCBvZiBBUCBmcmVxdWVuY3kgaW4gbm0tdG9vbAAtIE5ldyBzbmFwc2hvdAoJLSBGaXggYXBwbGV0IGljb24gc2l6aW5nIG9uIHN0YXJ0IChtY2xhc2VuKQoJLSBGaXggbm0tdG9vbCBpbnN0YWxsYXRpb24gKG1jbGFzZW4pCgktIEZpeCAnc3RhdGUnIG1ldGhvZCBjYWxsIHJldHVybiAoIzMwMzI3MSkKCS0gRml4IDQwLWJpdCBXRVAga2V5cyAoYWdhaW4pCgktIEZpeCBsb29wIHdoZW4gc2VjcmV0cyB3ZXJlIHdyb25nL2ludmFsaWQKCS0gRml4IGFwcGxldCBjcmFzaCB3aGVuIGNsaWNraW5nIENhbmNlbCBpbiB0aGUgcGFzc3dvcmQgZGlhbG9nCgktIEVuc3VyZSBOTSBkb2Vzbid0IGdldCBzdHVjayB3YWl0aW5nIGZvciB0aGUgc3VwcGxpY2FudCB0byByZS1hcHBlYXIKCQlpZiBpdCBjcmFzaGVzIG9yIGdvZXMgYXdheQoJLSBNYWtlIFZQTiBwcm9wZXJ0aWVzIGFwcGxldCB3b3JrIGFnYWluCgktIEluY3JlYXNlIHRpbWVvdXQgZm9yIG5ldHdvcmsgcGFzc3dvcmQgZW50cnkALSBOZXcgc25hcHNob3QgKGZpeCB1bmVuY3J5cHRlZCAmIDQwIGJpdCBXRVApAC0gTmV3IHNuYXBzaG90AC0gTmV3IHNuYXBzaG90AC0gTmV3IFNWTiBzbmFwc2hvdCBvZiAwLjcgdGhhdCBzdWNrcyBsZXNzAC0gVXBkYXRlIHRvIFNWTiBzbmFwc2hvdCBvZiAwLjcALSBVcGRhdGUgdGhlIGxpY2Vuc2UgdGFnAC0gT3duIC9ldGMvTmV0d29ya01hbmFnZXIvZGlzcGF0Y2hlci5kIGFuZCAvZXRjL05ldHdvcmtNYW5hZ2VyL1ZQTiAoIzIzNDAwNCkALSBGaXggV2lyZWxlc3MgRW5hYmxlZCBjaGVja2JveCB3aGVuIG5vIGtpbGxzd2l0Y2hlcyBhcmUgcHJlc2VudAAtIFVwZGF0ZSB0byBzdGFibGUgYnJhbmNoIHNuYXBzaG90OgogICAgLSBNb3JlIGZpeGVzIGZvciBldGhlcm5ldCBsaW5rIGRldGVjdGlvbiAoZ25vbWUgIzM1NDU2NSwgcmggIzE5NDEyNCkKICAgIC0gU3VwcG9ydCBmb3IgSEFMLWRldGVjdGVkIHJma2lsbCBzd2l0Y2hlcwAtIEZpeCBhcHBsZXQgY3Jhc2ggb24gNjQtYml0IHBsYXRmb3JtcyB3aGVuIGNob29zaW5nCiAgICAiQ29ubmVjdCB0byBvdGhlciB3aXJlbGVzcyBuZXR3b3JrLi4uIiAoZ25vbWUub3JnICM0MzUwMzYpCi0gQWRkIGRlYnVnIG91dHB1dCBmb3IgZXRoZXJuZXQgZGV2aWNlIGxpbmsgY2hhbmdlcwAtIEZpeCBldGhlcm5ldCBsaW5rIGRldGVjdGlvbiAoZ25vbWUgIzM1NDU2NSwgcmggIzE5NDEyNCkKLSBGaXggcGVycGV0dWFsIGNyZWRlbnRpYWxzIHJlcXVlc3Qgd2l0aCBwcml2YXRlIGtleSBwYXNzd29yZHMgaW4gdGhlIGFwcGxldAotIFNsZWVwIGEgYml0IGJlZm9yZSBhY3RpdmF0aW5nIHdpcmVsZXNzIGNhcmRzIHRvIHdvcmsgYXJvdW5kIGRyaXZlciBidWdzAC0gRG9uJ3Qgc3Bhd24gd3BhX3N1cHBsaWNhbnQgd2l0aCAtbwAtIEZpeCByZXF1aXJlcyBtYWNybyAoMjM3ODA2KQAtIFVwZGF0ZSB0byAwLjYuNSBmaW5hbAotIERvbid0IGxvc2Ugc2Nhbm5lZCBzZWN1cml0eSBpbmZvcm1hdGlvbgAtIFVwZGF0ZSBmcm9tIHRydW5rCgkqIFVwZGF0ZWQgdHJhbnNsYXRpb25zCgkqIENsZWFuZWQtdXAgVlBOIHByb3BlcnRpZXMgZGlhbG9ncwoJKiBGaXggNjQtYml0IGtlcm5lbCBsZWFrYWdlIGlzc3VlcyBpbiBXRVhUCgkqIERvbid0IGNhcHR1cmUgYW5kIHJlZGlyZWN0IHdwYV9zdXBwbGljYW50IGxvZyBvdXRwdXQALSBDbG9zZSBwcml2YXRlIEQtQnVzIGNvbm5lY3Rpb25zLiAoIzIzMjY5MSkALSBGaXggYSBkaXJlY3Rvcnkgb3duZXJzaGlwIGlzc3VlLiAgKCMyMzM3NjMpAC0gVXBkYXRlIHRvIHByZS0wLjYuNSBzbmFwc2hvdAAtIEd1YXJkIGFnYWluc3QgRC1CdXMgTGltaXRFeGNlZWRlZCBtZXNzYWdlcwAtIE1vdmUgLnNvIGZpbGUgdG8gLWRldmVsIHBhY2thZ2UALSBPd24gdGhlIC9ldGMvTmV0d29ya01hbmFnZXIvZGlzcGF0Y2hlci5kIGRpcmVjdG9yeQotIFJlcXVpcmUgcGtnY29uZmlnIGZvciB0aGUgLWRldmVsIHBhY2thZ2VzCi0gRml4IGNvbXBpbGF0aW9uIHdpdGggZGJ1cyAxLjAALSBVcGRhdGUgdG8gYSBzdGFibGUgYnJhbmNoIHNuYXBzaG90CiAgICAtIEdub21lIGFwcGxldCB0aW1lb3V0L3JlZHJhdyBzdXBwcmVzc2lvbiB3aGVuIGlkbGUKICAgIC0gQmFja3BvcnQgb2YgTEVBUCBwYXRjaCBmcm9tIEhFQUQgKGZyb20gVGhpYWdvIEJhdWVybWFubikKICAgIC0gQmFja3BvcnQgb2YgYXN5bmNocm9ub3VzIHNjYW5uaW5nIHBhdGNoIGZyb20gSEVBRAogICAgLSBNYWtlIHJlbmFtaW5nIG9mIFZQTiBjb25uZWN0aW9ucyB3b3JrIChmcm9tIFRhbWJldCBJbmdvKQogICAgLSBEaWFsIGRvd24gd3BhX3N1cHBsaWNhbnQgZGVidWcgc3BldwogICAgLSBDbGVhbnVwIG9mIGtleS9wYXNzcGhyYXNlIHJlcXVlc3Qgc2NlbmFyaW9zIChmcm9tIFZhbGVudGluZSBTaW5pdHN5bikKICAgIC0gU2h1dCBkb3duIFZQTiBjb25uZWN0aW9ucyBvbiBsb2dvdXQgKGZyb20gUm9iZXJ0IExvdmUpCiAgICAtIEZpeCBXUEEgcGFzc3BocmFzZSBoYXNoaW5nIG9uIFBQQwAtIE93biAvdXNyL3NoYXJlL05ldHdvcmtNYW5hZ2VyIGFuZCAvdXNyL2luY2x1ZGUvTmV0d29ya01hbmFnZXIALSBEb24ndCB3YWtlIHVwIHRvIHJlZHJhdyBpZiBOTSBpcyBpbmFjdGl2ZSAoIzIwNDg1MCkALSBhZGQgZXBvY2hzIGluIHJlcXVpcmVtZW50cwAtIEZpeCBGQy01IGJ1aWxkcmVxcwAtIFJldmVydCBGQzYgdG8gbGF0ZXN0IHN0YWJsZSBOTQotIFVwZGF0ZSB0byBzdGFibGUgc25hcHNob3QKLSBSZW1vdmUgYmluZC9jYWNoaW5nLW5hbWVzZXJ2ZXIgaGFyZCByZXF1aXJlbWVudAAtIEJ1aWxkUmVxdWlyZSB3aXJlbGVzcy10b29scy1kZXZlbCBhbmQgcGVybC1YTUwtUGFyc2VyCi0gVXBkYXRlIHRoZSBCdWlsZFJvb3QgdGFnAC0gYWRkIHBhdGNoIHRvIG1ha2UgbmV0d29ya21hbmFnZXIgbGVzcyB2ZXJib3NlIChidWcgMjAyODMyKQAtIGFjdHVhbGx5IG1ha2UgdGhlIHBhdGNoIGluIDAuNy4wLTAuY3ZzMjAwNjA1MjkuNCBhcHBseQAtIERvbid0IGV2ZXIgZWxlY3QgaW5hY3RpdmUgd2lyZWQgZGV2aWNlcyAoYnVnIDE5NDEyNCkuAC0gQWRkIHBhdGNoIHRvIGZpeCBkZXByZWNhdGVkIGRidXMgZnVuY3Rpb25zAC0gQWRkIEJSIGZvciBkYnVzLWdsaWItZGV2ZWwALSByZWJ1aWxkAC0gVXBkYXRlIHRvIGxhdGVzdCBDVlMKCW8gR25vbWUub3JnICMzMzM0MjA6IGRpYWxvZyBkbyBub3QgaGF2ZSB3aW5kb3cgaWNvbnMKCW8gR25vbWUub3JnICMzMzY5MTM6IEhJRyB0d2Vha3MgZm9yIHZwbiBwcm9wZXJ0aWVzIHBhZ2VzCglvIEdub21lLm9yZyAjMzM2ODQ2OiBISUcgdHdlYWtzIGZvciBubS12cG4tcHJvcGVydGllcwoJbyBHbm9tZS5vcmcgIzMzNjg0Nzogc29tZSBidWdzIGluIG5tLXZwbi1wcm9wZXJ0aWVzIGFyZ3MgcGFyc2luZwoJbyBHbm9tZS5vcmcgIzM0MTMwNjogbm0tdnBuLXByb3BlcnRpZXMgY3Jhc2hlcyBvbiBzdGFydHVwCglvIEdub21lLm9yZyAjMzQxMjYzOiBWZXJzaW9uIDAuNi4yLTB1YnVudHU1IGNyYXNoZXMgb24gbm1fZGV2aWNlXzgwMl8xMV93aXJlbGVzc19nZXRfdHlwZQoJbyBHbm9tZS5vcmcgIzM0MTI5NzogZGlzcGxheXMgcmVwZWF0ZWQga2V5cmluZyBkaWFsb2dzIG9uIHJlc3VtZSBmcm9tIHN1c3BlbmQKCW8gR25vbWUub3JnICMzNDI0MDA6IEJ1aWxkaW5nIGxpYm5tLXV0aWwgLS13aXRob3V0LWdjcnlwdCByZXN1bHRzIGluIGxpbmtlciBlcnJvcgoJbyBHbm9tZS5vcmcgIzM0MjM5ODogRWxlbWluYXRlIEdub21lIGRlcGVuZGVuY3kgZm9yIE5ldHdvcmtNYW5hZ2VyCglvIEdub21lLm9yZyAjMzM2NTMyOiBkZWNsYXJhdGlvbiBvZiAnbGluaycgc2hhZG93cyBhIGdsb2JhbCBkZWNsYXJhdGlvbgotIFNwZWNmaWxlIGZpeGVzICgjcmgxODc0ODkjKQAtIFVwZGF0ZSB0byBsYXRlc3QgQ1ZTCi0gRHJvcCBzcGVjaWFsLWNhc2UtbWFkd2lmaS5wYXRjaCwgc2luY2UgV0VYVCBjb2RlIGlzIGluIG1hZHdpZmktbmcgdHJ1bmsgbm93AC0gdXNlIHRoZSBzYW1lIDAuNi4yIHRhcmJhbGwgYXMgRkM1LCBzbyB3ZSBoYXZlIHRoZSBzYW1lIFZQTiBpbnRlcmZhY2UKICAoZGlkIGhlIGZpcmUgdGVuIGFyZ3MsIG9yIG9ubHkgbmluZT8pAC0gdXNlIHRoZSBoYWwgZGV2aWNlIHR5cGUgaW5zdGVhZCBvZiBwb2tpbmcgdmlhIGlvY3RsIHNvIHRoYXQgd2lyZWxlc3MKICBkZXZpY2VzIGFyZSBwcm9wZXJseSBkZXRlY3RlZCBldmVuIGlmIHRoZSBraWxsIHN3aXRjaCBoYXMgYmVlbiB1c2VkAC0gVXBkYXRlIHRvIDAuNi4yOgoJKiBGaXggdmFyaW91cyBXUEEtcmVsYXRlZCBidWdzCgkqIENsZWFuIHVwIGxlYWtzCgkqIEluY3JlYXNlZCBESENQIHRpbWVvdXQgdG8gYWNjb3VudCBmb3Igc2xvdyBESENQIHNlcnZlcnMsIG9yIFNUUC1lbmFibGVkCgkJc3dpdGNoZXMKCSogQWxsb3cgYXBwbGV0IHRvIHJlY29ubmVjdCBvbiBkYnVzIHJlc3RhcnRzCgkqIEFkZCAiRHluYW1pYyBXRVAiIHN1cHBvcnQKCSogQWxsb3cgaGlkaW5nIG9mIHBhc3N3b3JkL2tleSBlbnRyeSB0ZXh0CgkqIE1vcmUgcmVzcG9uc2l2ZSBjb25uZWN0aW9uIHN3aXRjaGluZwAtIEZpeCBkZXZpY2UgYnJpbmd1cCBvbiByZXN1bWUALSBEb24ndCBsZXQgd3BhX3N1cHBsaWNhbnQgcGVyZm9ybSBzY2FubmluZyB3aXRoIG5vbi1XUEEgZHJpdmVycwAtIFVwZGF0ZSB0byAwLjYuMCByZWxlYXNlCi0gTW92ZSBhdXRvc3RhcnQgZmlsZSB0byAvdXNyL3NoYXJlL2dub21lL2F1dG9zdGFydAAtIHVwZGF0ZWQgY3ZzIHNuYXBzaG90LiAgc2VlbXMgdG8gbWFrZSBhaXJvIG11Y2ggbGVzcyBuZXVyb3RpYwAtIE1vdmUgdGhlIHVudmVyc2lvbmVkIGxpYm5tX2dsaWIuc28gdG8gdGhlIC1kZXZlbCBwYWNrYWdlAC0gRml4IFZQTi1yZWxhdGVkIGNyYXNoCi0gRml4IGlzc3VlIHdoZXJlIE5NIHdvdWxkIHJlZnVzZSB0byBhY3RpdmF0ZSBhIFZQTiBjb25uZWN0aW9uIG9uY2UgaXQgaGFkIHRpbWVkIG91dAotIExvZyB3cGFfc3VwcGxpY2FudCBvdXRwdXQgZm9yIGJldHRlciBkZWJ1Z2dpbmcALSBUd2VhayB0aHJlZS1zY2FuLXBydW5lLnBhdGNoAC0gRG9uJ3QgcHJ1bmUgbmV0d29ya3MgdW50aWwgdGhleSd2ZSBnb25lIE1JQSBmb3IgdGhyZWUgc2NhbnMsIG5vdCBvbmUuAC0gVXBkYXRlIHNuYXBzaG90LCB3aGljaCBmaXhlcyB1cCB0aGUgbGlibm90aWZ5IHN0dWZmLgAtIE1vdmUgbGlibm90aWZ5IHJlcXVpcmVzIHRvIE5ldHdvcmtNYW5hZ2VyLWdub21lLCBub3QgY29yZSBOTSBwYWNrYWdlAC0gQWRkIEJ1aWxkUmVxdWlyZXM6IGxpYm5sLWRldmVsICgjcmgxNzk0MzgjKQotIEZpeCBsaWJubV9nbGliIHRvIG5vdCBjbG9iYmVyIGFuIGFwcGxpY2F0aW9uJ3MgZXhpc3RpbmcgZGJ1cyBjb25uZWN0aW9uCgkoI3JoMTc3NTQ2IywgZ25vbWUub3JnICMzMjY1NzIpCi0gbGlibm90aWZ5IHN1cHBvcnQKLSBBUCBjb21wYXRpYmlsaXR5IGZpeGVzAC0gTWlub3IgYnVnIGZpeGVzCi0gVXBkYXRlIHRvIFZQTiBkYnVzIEFQSSBmb3IgcGFzc2luZyB1c2VyLWRlZmluZWQgcm91dGVzIHRvIHZwbiBzZXJ2aWNlAC0gUmVidWlsZAAtIHJlYnVpbHQgZm9yIG5ldyBnY2M0LjEgc25hcHNob3QgYW5kIGdsaWJjIGNoYW5nZXMALSBXb3JrYXJvdW5kcyBmb3IgbWFkd2lmaS9BdGhlcm9zIGNhcmRzCi0gRG8gYmV0dGVyIHdpdGggbm9uLVNTSUQtYnJvYWRjYXN0aW5nIGFjY2VzcyBwb2ludHMKLSBGaXggaGFuZ3Mgd2hlbiBhY2Nlc3MgcG9pbnRzIGNoYW5nZSBzZXR0aW5ncwAtIE93biAvdmFyL3J1bi9OZXR3b3JrTWFuYWdlciwgZml4IFNFTGludXggaXNzdWVzAC0gU3dpdGNoIHRvIGF1dG9zdGFydGluZyB0aGUgYXBwbGV0IGluc3RlYWQgb2YgaGF2aW5nIGl0IGJlIHNlc3Npb24tbWFuYWdlZAotIFdvcmsgYmV0dGVyIHdpdGggbm9uLWJyb2FkY2FzdGluZyBhY2Nlc3MgcG9pbnRzCi0gQWRkIG1vcmUgbWFudWZhY3R1cmVyIGRlZmF1bHQgU1NJRHMgdG8gdGhlIGJsYWNrbGlzdAAtIExvbmdlciBhc3NvY2lhdGlvbiB0aW1lb3V0Ci0gRml4IHNvbWUgU0VMaW51eCBpc3N1ZXMKLSBHZW5lcmFsIGJ1ZyBhbmQgY29zbWV0aWMgZml4ZXMALSBTbmFwc2hvdCBmcm9tIENWUwotIFdQQSBTdXBwb3J0ISAgV29vaG9vIQAtIHJlYnVpbHQALSByZWJ1aWxkIGZvciBuZXcgZGJ1cwAtIERvbid0IGtpbGwgdGhlIG5ldHdvcmsgY29ubmVjdGlvbiB3aGVuIHlvdSB1cGdyYWRlIHRoZSBwYWNrYWdlLgAtIFNwbGl0IG91dCB0aGUgLWdsaWIgc3VicGFja2FnZSB0byBoYXZlIGEgLWdsaWItZGV2ZWwgcGFja2FnZSBhcyB3ZWxsCi0gQWRkIGVwb2NoIHRvIHZlcnNpb24gcmVxdWlyZW1lbnRzIGZvciBiaW5kIGFuZCB3aXJlbGVzcy10b29scwotIFVwZGF0ZSBVUkwgb2YgcHJvamVjdAAtIE5ldHdvcmtNYW5hZ2VyIDAuNS4xAC0gTmV0d29ya01hbmFnZXIgMC41LjAALSBGaXggYXV0b21hdGljIHdpcmVsZXNzIGNvbm5lY3Rpb25zCi0gUmVtb3ZlIHVzYWdlIG9mIE5NTG9hZE1vZHVsZXMgY2FsbG91dCwgbm8gbG9uZ2VyIG5lZWRlZAotIFRyeSB0byBmaXggZGVhZGxvY2sgd2hlbiBtZW51IGlzIGRvd24gYW5kIGtleXJpbmcgZGlhbG9nIHBvcHMgdXAALSBVcGRhdGUgdG8gbGF0ZXN0IENWUwoJbyBJbnRlZ3JhdGUgY29ubmVjdGlvbiBwcm9ncmVzcyB3aXRoIGFwcGxldCBpY29uIChDaHJpcyBBaWxsb24pCglvIE1vcmUgaW5mb3JtYXRpb24gaW4gIkNvbm5lY3Rpb24gSW5mb3JtYXRpb24iIGRpYWxvZyAoUm9iZXJ0IExvdmUpCglvIFNob3J0ZW4gdGltZSB0YWtlbiB0byBzbGVlcAoJbyBNYWtlIGFwcGxldCBpY29uIHdpcmVsZXNzIHN0cmVuZ3RoIGxldmVscyBhIGJpdCBtb3JlIHJlYWxpc3RpYwoJbyBUYWxrIHRvIG5hbWVkIHVzaW5nIERCVVMgcmF0aGVyIHRoYW4gc3Bhd25pbmcgb3VyIG93bgoJCS0gWW91IG5lZWQgdG8gYWRkICItRCIgdG8gdGhlIE9QVElPTlMgbGluZSBpbiAvZXRjL3N5c2NvbmZpZy9uYW1lZAoJCS0gWW91IG5lZWQgdG8gc2V0IG5hbWVkIHRvIHN0YXJ0IGFzIGEgc2VydmljZSBvbiBzdGFydHVwAC0gVXBkYXRlIHRvIGN1cnJlbnQgQ1ZTIHRvIGZpeCBpc3N1ZXMgd2l0aCByb3V0aW5nIHRhYmxlIGFuZCAvc2Jpbi9pcAAtIHVwZGF0ZSB0byBjdXJyZW50IENWUyBhbmQgcmVidWlsZCAod29ya2Fyb3VuZCBmb3IgIzE2ODEyMCkALSBGaXggb2NjYXNpb25hbCBoYW5nIGluIE5NIGNhdXNlZCBieSB0aGUgYXBwbGV0AC0gVXBkYXRlIHRvIE5ldHdvcmtNYW5hZ2VyIDAuNC4xAC0gUmVidWlsZCBhZ2FpbnN0IG5ldyBjYWlyby9ndGsALSBVcGRhdGUgdG8gbGF0ZXN0IENWUwoJbyBVc2UgREhDUCBzZXJ2ZXIgYWRkcmVzcyBhcyBnYXRld2F5IGFkZHJlc3MgaWYgdGhlIERIQ1Agc2VydmVyIGRvZXNuJ3QgZ2l2ZQoJCXVzIGEgZ2F0ZXdheSBhZGRyZXNzICNyaDE2NTY5OCMKCW8gRml4ZXMgdG8gdGhlIGFwcGxldCAoUm9iZXJ0IExvdmUpCglvIEJldHRlciBjYWNoaW5nIG9mIGluZm9ybWF0aW9uIGluIHRoZSBhcHBsZXQgKEJpbGwgTW9zcykKCW8gR2VuZXJhdGUgYXV0b21hdGljIHN1Z2dlc3RlZCBBZC1Ib2MgbmV0d29yayBuYW1lIGZyb20gbWFjaGluZSdzIGhvc3RuYW1lCgkJKFJvYmVydCBMb3ZlKQoJbyBVcGRhdGUgYWxsIG5ldHdvcmsgaW5mb3JtYXRpb24gb24gc3VjY2Vzc2Z1bGwgY29ubmVjdCwgbm90IGp1c3QKCQlhdXRoZW50aWNhdGlvbiBtZXRob2QALSBVcGRhdGUgdG8gbGF0ZXN0IENWUyB0byBnZXQgZml4IGZvciBidWcgMTY1NjgzLgAtIE1vdmUgcGtnY29uZmlnIGZpbGUgdG8gZGV2ZWwgcGFja2FnZSAoIzE2MjMxNiwgdGhhbmtzIHRvIE1pY2hhZWwgU2Nod2VuZHQpAC0gVXBkYXRlIHRvIGxhdGVzdCBDVlMgdG8gZ2V0IGxhdGVzdCBWUE4gaW50ZXJmYWNlIHNldHRpbmdzIHRvIHNhdGlzZnkKICBCdWlsZFJlcSBmb3IgTmV0d29ya01hbmFnZXItdnBuYyBpbiBGZWRvcmEgRXh0cmFzIERldmVsb3BtZW50Ci0gTGF0ZXN0IENWUyBhbHNvIGNvbnRhaW5zIHZhcmlvdXMgYnVnLSBhbmQgVUktZml4ZXMALSBVcGRhdGUgdG8gbGF0ZXN0IENWUwoJbyBWUE4gY29ubmVjdGlvbiBpbXBvcnQvZXhwb3J0IGNhcGFiaWxpdHkKCW8gRml4IHVwIHNvbWUgbWVudSBpdGVtIG5hbWVzCi0gTW92ZSBubS12cG4tcHJvcGVydGllcy5nbGFkZSB0byB0aGUgZ25vbWUgc3VicGFja2FnZQAtIFVwZGF0ZSB0byBsYXRlc3QgQ1ZTCglvIENsZWFuIHVwIHdvcmRpbmcgaW4gV2lyZWxlc3MgTmV0d29yayBEaXNjb3ZlcnkgbWVudQoJbyBSb2JlcnQgTG92ZSdzIGFwcGxldCBiZWF1dGlmeSBwYXRjaAAtIFVwZGF0ZSB0byBsYXRlc3QgQ1ZTAC0gRml4IGRpc3BhdGNoZXIgYW5kIGFwcGxldCBDRkxBR1Mgc28gdGhleSBnZXRzIGNvbXBpbGVkIHdpdGggRk9SVElGWV9TT1VSQ0UALSBGaXggc2VnZmF1bHQgaW4gTmV0d29ya01hbmFnZXJEaXNwYXRjaGVyLCBhZGQgYW4gaW5pdHNjcmlwdCBmb3IgaXQALSBGaXggY29uZGl0aW9uIHRoYXQgbWF5IGhhdmUgcmVzdWx0ZWQgaW4gREhDUCBjbGllbnQgcmV0dXJuaW5nIHN1Y2Nlc3MKCXdoZW4gaXQgcmVhbGx5IHRpbWVkIG91dAAtIEVuYWJsZSBPSyBidXR0b24gY29ycmVjdGx5IGluIFBhc3NwaHJhc2UgYW5kIE90aGVyIE5ldHdvcmtzIGRpYWxvZ3Mgd2hlbgoJdXNpbmcgQVNDSUkgb3IgSGV4IFdFUCBrZXlzAC0gI3JoMTU0MzkxIyBOZXR3b3JrTWFuYWdlciBkaWVzIG9uIHN0YXJ0dXAgKGRvbid0IGZvcmNlLWtpbGwgbmlmZCkALSBGaXggbGVhayBvZiBhIHNvY2tldCBpbiBESENQIGNvZGUALSBGaXggc29tZSBtZW1vcnkgbGVha3MgKFRvbSBQYXJrZXIpCi0gSm9pbiB0byB0aHJlYWRzIHJhdGhlciB0aGFuIHNwaW5uaW5nIGZvciB0aGVpciBjb21wbGV0aW9uIChUb20gUGFya2VyKQotIEZpeCBtaXN1c2Ugb2YgYSBnX2Fzc2VydCgpIChDb2xpbiBXYWx0ZXJzKQotIEZpeCByZXR1cm4gY2hlY2tpbmcgb2YgYW4gaW9jdGwoKSAoQmlsbCBNb3NzKQotIEJldHRlciBkZXRlY3Rpb24gYW5kIG1hdGNoaW5nIG9mIGhpZGRlbiBhY2Nlc3MgcG9pbnRzIChCaWxsIE1vc3MpCi0gRG9uJ3QgdXNlIHZhcmFyZ3MsIGFuZCB0aGVyZWZvcmUgZG9uJ3QgY3Jhc2ggb24gUFBDIChQZXRlciBKb25lcykALSBmaXggYnVpbGQgd2l0aCBuZXdlciBkYnVzAC0gc2lsZW5jZSAlcG9zdAAtICNyaDE1MzIzNCMgTmV0d29ya01hbmFnZXIgcXVpdHMvY29yZXMganVzdCBhcyBhIGNvbm5lY3Rpb24gaXMgbWFkZQAtIFVwZGF0ZSBmcm9tIGxhdGVzdCBDVlMgSEVBRAAtIFVwZGF0ZSB0aGUgR1RLKyB0aGVtZSBpY29uIGNhY2hlIG9uICh1bilpbnN0YWxsAC0gUHVsbCBmcm9tIGxhdGVzdCBDVlMgSEVBRAAtIFVwbG9hZCBuZXcgc291cmNlIHRhcmJhbGwgKHdvb3BzKQAtIFB1bGwgZnJvbSBsYXRlc3QgQ1ZTIEhFQUQgKGhvcGVmdWxseSB3b3JrcyBhZ2FpbikALSBQdWxsIGZyb20gbGF0ZXN0IENWUyBIRUFECi0gQ29tbWl0IGJyb2tlbiBOZXR3b3JrTWFuYWdlciB0byBzYXRpc2Z5IHRvIGRidXMgZGVwZW5kZW5jeQAtIFB1bGwgZnJvbSBsYXRlc3QgQ1ZTIEhFQUQKLSBSZWJ1aWxkIGZvciBnY2MgNC4wAC0gVXBkYXRlIGZyb20gQ1ZTAC0gRml4IGZyZWUgb2YgaW52YWxpZCBwb2ludGVyIGZvciBtdWx0aXBsZSBzZWFyY2ggZG9tYWlucwAtIE5ldmVyIGF1dG9tYXRpY2FsbHkgY2hvb3NlIGEgZGV2aWNlIHRoYXQgZG9lc24ndCBzdXBwb3J0IGNhcnJpZXIgZGV0ZWN0aW9uCi0gQWRkIHJpZ2h0LWNsaWNrIG1lbnUgdG8gYXBwbGV0LCBjYW4gbm93ICJQYXVzZS9SZXN1bWUiIHNjYW5uaW5nIHRocm91Z2ggaXQKLSBGaXggREhDUCBSZW5ldy9SZWJpbmQgdGltZW91dHMKLSBGaXggZnJlcXVlbmN5IGN5Y2xpbmcgcHJvYmxlbSBvbiBzb21lIGNhcmRzLCBldmVuIHdoZW4gc2Nhbm5pbmcgd2FzIG9mZgotIFBsYXkgYmV0dGVyIHdpdGggSVB2NgotIERvbid0IHNlbmQga2VybmVsIHZlcnNpb24gaW4gREhDUCBwYWNrZXRzLCBhbmQgZW5zdXJlIERIQ1AgcGFja2V0cyBhcmUgYXQKCWxlYXN0IDMwMCBieXRlcyBpbiBsZW5ndGggdG8gd29yayBhcm91bmQgYnJva2VuIHJvdXRlcgotIE5ldyBESENQIG9wdGlvbnMgRC1CVVMgQVBJIGJ5IERhbiBSZWVkCi0gSGFuZGxlIG11bHRpcGxlIGRvbWFpbiBzZWFyY2ggb3B0aW9ucyBpbiBESENQIHJlc3BvbnNlcwAtIERpc3BsYXkgd2lyZWxlc3MgbmV0d29yayBuYW1lIGluIGFwcGxldCB0b29sdGlwCi0gSG9wZWZ1bGx5IGZpeCBkb3VibGUtZGVmYXVsdC1yb3V0ZSBwcm9ibGVtCi0gV3JpdGUgb3V0IHZhbGlkIHJlc29sdi5jb25mIHdoZW4gd2UgZXhpdAotIE1ha2UgbXVsdGktZG9tYWluIHNlYXJjaCBvcHRpb25zIHdvcmsKLSBSZXdvcmsgc2lnbmFsIHN0cmVuZ3RoIGNvZGUgdG8gYmUgV0VYVCBjb25mb3JtYW50LCBpZiBzdHJlbmd0aCBpcwoJc3RpbGwgd2llcmQgdGhlbiBpdHMgOTUlIHN1cmVseSBhIGRyaXZlciBwcm9ibGVtCi0gRml4IGFubm95aW5nIGluc3RhbmNlcyBvZiBzdWRkZW5seSBkcm9wcGluZyBhbmQgcmVhY3RpdmF0aW5nIGEKCXdpcmVsZXNzIGRldmljZSAoQ2lzY28gY2FyZHMgd2VyZSB3b3JzdCBvZmZlbmRlcnMgaGVyZSkKLSBGaXggc29tZSBpbnN0YW5jZXMgb2YgTmV0d29ya01hbmFnZXIgbm90IHJlbWVtYmVyaW5nIHlvdXIgV0VQIGtleQotIEZpeCBzb21lIHJhY2VzIGJldHdlZW4gTmV0d29ya01hbmFnZXIgYW5kIE5ldHdvcmtNYW5hZ2VySW5mbyB3aGVyZQoJTmV0d29ya01hbmFnZXIgd291bGRuJ3QgcmVjb2duaXplIGNoYW5nZXMgaW4gdGhlIGFsbG93ZWQgbGlzdAotIERvbid0IHNob3ZlIEFkLUhvYyBBY2Nlc3MgUG9pbnQgTUFDIGFkZHJlc3NlcyBpbnRvIEdDb25mAC0gUGxheSBuaWNlIHdpdGggZGJ1cyAwLjIzCi0gVXBkYXRlIG91ciBsaXN0IG9mIEFsbG93ZWQgV2lyZWxlc3MgTmV0d29ya3MgbW9yZSBxdWlja2x5AC0gVXBkYXRlIHRvIGxhdGVzdCBDVlMKLSBNYWtlIHN1cmUgd2Ugc3RhcnQgYXMgbGF0ZSBhcyBwb3NzaWJsZSBzbyB0aGF0IHdlIGVuc3VyZSBkYnVzICYgSEFMCglhcmUgYWxyZWFkeSBhcm91bmQKLSBGaXggcmFjZSBpbiBpbml0aWFsIGRldmljZSBhY3RpdmF0aW9uAC0gcmVidWlsdCBhZ2FpbnN0IG5ldyB3aXJlbGVzcyB0b29sAC0gRml4IGlzc3VlIHdoZXJlIE5NIHdvdWxkbid0IHJlY29nbml6ZSB0aGF0IGFjY2VzcyBwb2ludHMgd2VyZQoJZW5jcnlwdGVkLCBhbmQgdGhlbiB3b3VsZCB0cnkgdG8gY29ubmVjdCB3aXRob3V0IGVuY3J5cHRpb24KLSBSZWZpbmUgcGFja2FnaW5nIHRvIHB1dCBjbGllbnQgbGlicmFyeSBpbiBzZXBhcmF0ZSBwYWNrYWdlCi0gUmVtb3ZlIGJpbmQrY2FjaGluZy1uYW1lc2VydmVyIGRlcCBmb3IgRkMtMywgdXNlICduc2NkIC1pIGhvc3RzJwoJaW5zdGVhZC4gIEROUyBxdWVyaWVzIG1heSB0aW1lb3V0IG5vdyByaWdodCBhZnRlciBkZXZpY2UKCWFjdGl2YXRpb24gZHVlIHRvIHRoaXMgY2hhbmdlLgAtIFVwZGF0ZSB0byBsYXRlc3QgQ1ZTCi0gRml4ZXMgdG8gREhDUCBjb2RlCi0gTGluay1Mb2NhbCAoWmVyb0NvbmYvUmVuZGV6dm91cykgc3VwcG9ydAotIFVzZSBiaW5kIGluICJjYWNoaW5nLW5hbWVzZXJ2ZXIiIG1vZGUgdG8gd29yayBhcm91bmQgc3R1cGlkaXR5CglpbiBnbGliYydzIHJlc29sdmVyIGxpYnJhcnkgbm90IHJlY29nbml6aW5nIHJlc29sdi5jb25mIGNoYW5nZXMKLSAjcmgxNDQ4MTgjIENsZWFuIHVwIHRoZSBzcGVjZmlsZSAoUGF0Y2ggZnJvbSBNYXR0aGlhcyBTYW91KQotIEFkLUhvYyBtb2RlIHN1cHBvcnQgd2l0aCBMaW5rLUxvY2FsIGFkZHJlc3Npbmcgb25seSAoZm9yIG5vdykKLSBGaXhlcyBmb3IgZGV2aWNlIGFjdGl2YXRpb24gcmFjZSBjb25kaXRpb25zCi0gV2lyZWxlc3Mgc2Nhbm5pbmcgaW4gc2VwYXJhdGUgdGhyZWFkAC0gVXBkYXRlIHRvIENWUwotIFVwZGF0ZXMgdG8gbGluayBkZXRlY3Rpb24sIERIQ1AgY29kZQotIFJlbW92ZSBOTUxhdW5jaEhlbHBlciBzbyB3ZSBzdGFydCB1cCBmYXN0ZXIgYW5kIGRvbid0CglibG9jayBmb3IgYSBjb25uZWN0aW9uLiAgVGhpcyBtZWFucyBzZXJ2aWNlcyB0aGF0IGRlcGVuZAoJb24gdGhlIG5ldHdvcmsgbWF5IGZhaWwgaWYgdGhleSBzdGFydCByaWdodCBhZnRlciBOTQotIE1ha2Ugc3VyZSBESENQIHJlbmV3L3JlYmluZGluZyB3b3JrcwAtIFVwZGF0ZSB0byBDVlMKLSBGaXhlcyB0byBsaW5rIGRldGVjdGlvbgotIEJldHRlciBkZXRlY3Rpb24gb2Ygbm9uLUVTU0lELWJyb2FkY2FzdGluZyBhY2Nlc3MgcG9pbnRzCi0gRG9uJ3QgZGlhbG9nLXNwYW0gdGhlIHVzZXIgaWYgYSBjb25uZWN0aW9uIGZhaWxzAC0gVXBkYXRlIHRvIENWUwotIE11Y2ggYmV0dGVyIGxpbmsgZGV0ZWN0aW9uLCB3b3JrcyB3aXRoIE9wZW4gU3lzdGVtIGF1dGhlbnRpY2F0aW9uCi0gQmxhY2tsaXN0IHdpcmVsZXNzIGNhcmRzIHJhdGhlciB0aGFuIHdoaXRlbGlzdGluZyB0aGVtAC0gI3JoMTM0ODkzIyBOZXR3b3JrTWFuYWdlckluZm8gYW5kIHRoZSBwYW5lbC1pY29uIGxpZmUtY3ljbGUKLSAjcmgxMzQ4OTUjIFN0YXR1cyBpY29uIHNob3VsZCBoaWRlIHdoZW4gaW4gV2lyZWQtb25seSBtb2RlCi0gI3JoMTM0ODk2IyBJY29uIGNvZGUgbmVlZHMgcmV3cml0ZQotICNyaDEzNDg5NyMgIk90aGVyIE5ldHdvcmtzLi4uIiBkaWFsb2cgbmVlZHMgaW1wbGVtZW50aW5nCi0gI3JoMTM1MDU1IyBNZW51IGhpZ2hsaWdodHMgaW5jb3JyZWN0bHkgaW4gTk0KLSAjcmgxMzU2NDgjIHNlZ2ZhdWx0IHdpdGggY2lwc2VjMAotICNyaDEzNTcyMiMgTmV0d29ya01hbmFnZXIgd2lsbCBub3QgYWxsb3cgemF1cnVzIHRvIHN5bmMgdmlhIHVzYjAKLSAjcmgxMzU5OTkjIE5ldHdvcmtNYW5hZ2VyLTAuMy4xIHdpbGwgbm90IGNvbm5lY3QgdG8gMTI4IHdlcAotICNyaDEzNjg2NiMgYXBwbGV0IG5lZWRzIHRvb2x0aXBzCi0gI3JoMTM3MDQ3IyBsb3RzIG9mIGFwcGxldHMsIHlheSEKLSAjcmgxMzczNDEjIE5ldHdvcmsgTWFuYWdlciBkaWVzIGFmdGVyIGRpc2Nvbm5lY3RpbmcgZnJvbSB3aXJlZCBuZXR3b3JrIHNlY29uZCB0aW1lCi0gQmV0dGVyIGNoZWNraW5nIGZvciB3aXJlbGVzcyBkZXZpY2VzCi0gRml4IHNvbWUgbWVtbGVha3MKLSBGaXggaXNzdWVzIHdpdGggZGhjbGllbnQgZGVjbGluaW5nIGFuIG9mZmVyZWQgYWRkcmVzcwotIEZpeCBhbiBhY3RpdmF0aW9uIHRocmVhZCBkZWFkbG9jawotIE1vcmUgYWNjdXJhdGVseSBkZXRlY3QgIk90aGVyIHdpcmVsZXNzIG5ldHdvcmtzIiB0aGF0IGFyZSBlbmNyeXB0ZWQKLSBEb24ndCBicmluZyBkZXZpY2VzIGRvd24gYXMgbXVjaCwgd29uJ3QgaG90cGx1Zy1zcGFtIGFzIG11Y2ggYW55bW9yZQoJYWJvdXQgZmlybXdhcmUKLSBBZGQgYSAibmV0d29yayBub3QgZm91bmQiIGRpYWxvZyB3aGVuIHRoZSB1c2VyIGNob29zZXMgYSBuZXR3b3JrIHRoYXQgY291bGQKCW5vdCBiZSBjb25uZWN0ZWQgdG8ALSBGaXggZXNjYXBpbmcgb2YgRVNTSURzIGluIGdjb25mAC0gbWlub3IgcG9pbnQgcmVsZWFzZSB0byBpbXByb3ZlIGVycm9yIGhhbmRsaW5nIGFuZCB0cmFuc2xhdGlvbnMALSBVcGRhdGUgZnJvbSBDVlMsIHZlcnNpb24gMC4zAC0gVXBkYXRlIGZyb20gQ1ZTCi0gSW1wcm92ZW1lbnRzOgoJbyBCZXR0ZXIgbGluayBjaGVja2luZyBvbiB3aXJlbGVzcyBjYXJkcwoJbyBQYW5lbCBhcHBsZXQgbm93IGEgTm90aWZpY2F0aW9uIEFyZWEgaWNvbgoJbyBTdGF0aWMgSVAgY29uZmlndXJhdGlvbiBzdXBwb3J0AC0gVXBkYXRlIGZyb20gQ1ZTAC0gUmVxdWlyZSBnbm9tZS1wYW5lbCwgbm90IGdub21lLXBhbmVsLWRldmVsCi0gVHVybiBvZmYgYnkgZGVmYXVsdAAtIFVwZGF0ZSB0byAwLjIALSBzcGVjLWNoYW5nZXMgdG8gcmVxIGdsaWIyIGluc3RlYWQgb2YgZ2xpYgAtIEZpcnN0IHB1YmxpYyByZWxlYXNlAE5ldHdvcmtNYW5hZ2VyAE5ldHdvcmtNYW5hZ2VyLWJ0AAAAAAABAAAAAQAAAAEAAAABAAAAAQAAAAIAAAADAAAABAAAAAAAAAAIAAAACAAAgAAxOjEuMjYuMC04LmVsOAAxOjEuMjYuMC04LmVsOAAAAAAAAAIAAAAAMTowLjkuOS45NS0xAAAAAAAAAAAAAAABAAAAAgAAAAMuYnVpbGQtaWQAODcAMDI5MjViZTRmMDczN2VjODczOWYyMmZkZDQ3Y2VmZjVjMjgyMDAAbGlibm0tZGV2aWNlLXBsdWdpbi1ibHVldG9vdGguc28AL3Vzci9saWIvAC91c3IvbGliLy5idWlsZC1pZC8AL3Vzci9saWIvLmJ1aWxkLWlkLzg3LwAvdXNyL2xpYjY0L05ldHdvcmtNYW5hZ2VyLzEuMjYuMC04LmVsOC8ALU8yIC1nIC1waXBlIC1XYWxsIC1XZXJyb3I9Zm9ybWF0LXNlY3VyaXR5IC1XcCwtRF9GT1JUSUZZX1NPVVJDRT0yIC1XcCwtRF9HTElC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"},"publicKey":{"content":"LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tClZlcnNpb246IEdudVBHIHYyLjAuMjIgKEdOVS9MaW51eCkKCm1RSU5CRnpNV3hrQkVBREhyc2twQmdOOU9waG1oUmtjN1AvWXJzQUdTdnZsN2tmdStlOUtBYVU2ZjVNZUFWeW4KcklvTTQzc3l5R2tnRnlXZ2paTTgvcnVyN0VNUFkyeXQrMnEvMVpmTFZDUm45ODU2SnFUSXEwWFJwRFVlNG5LUQo4QmxBN3dEVlpvU0R4VVprU3VUSXlFeGJEZjBjcHc4OVRjZjYyTXhtaThqaDc0dlJsUHkxUGdqV0w1NDk0YjNYCjVmeERpZEg0YnFQWnl4VEJxUHJVRnVvK0VmVVZFcWlHRjk0UHBxNlpVdnJCR09WbzFWMStJZm05Q0dFSzU5N2MKYWV2Y0djMVJGbGd4SWdOODRVcHVEalBSOS96U25kd0o3WHNYWXZaNkhYY0tHYWdSS3NmWURXR1BrQTVjT0wvZQpmK3lPYk9uQzQzeVBVdnBnZ1E0S2FOSjYrU01UWk9LaWtNOHljaXlCd0xxd3JqbzhGbEpna3Y4VmZhZy8yVVI3CkpJTmJ5cUhIb0xVaFEybTZIWFN3SzRZanR3aWRGOUVVa2FCWldycnNrWVIzSVJaTFhsV3FlT2kvK2V6WU9XMG0KdnVmcmtjdnNoK1RLbFZWbnV3bUVQako4bXdVU3BzTGRmUEpvMURIc2Q4RlMwM1NDS1BhWEZkRDdlUGZFamlZawpuSHBRYUtFMDFhV1ZTTFVpeWduN0Y3clllbUdxVjlWdDd0Qnc1cHowdnFTQzcyYTVFM3pGeklJdUh4NmFBTnJ5CkdhdDNhcVUzcXRCWE9yQS9kUGtYOWNXRStVUjV3by9BMlVkS0paTGxHaE0yV1JKM2x0bUdUNDhWOUNlUzZOOVkKbTRDS2R6dmc3RVdqbFRsRnJkLzhXSjJLb3FPRTlsZURQZVhSUG5jdWJKZko2TExJSHlHMDloOWtLUUFSQVFBQgp0RHBEWlc1MFQxTWdLRU5sYm5SUFV5QlBabVpwWTJsaGJDQlRhV2R1YVc1bklFdGxlU2tnUEhObFkzVnlhWFI1ClFHTmxiblJ2Y3k1dmNtYytpUUkzQkJNQkFnQWhCUUpjekZzWkFoc0RCZ3NKQ0FjREFnWVZDQUlKQ2dzREZnSUIKQWg0QkFoZUFBQW9KRUFXMVZiT0VnOFpkak9zUC8yeWdTeEg5anFmZk9VOVNLeUpEbHJhTDJnSXV0cVozQjhwbApHeS9RbmI5UUQxRUpWYjRaeE9FaGNZMlc5VkpmSXBuZjN5QnVBdG83enZLZS9HMW54SDRCdDZXVEpRQ2tVamNzCk4zcVBXc3gxVnNsc0FFejdiWEdpSHltNkF5NHhGMjhiUTlYWUlva0lRWGQwVDJyRDMvbE5HeE50T1JaMmJLakQKdk96WXp2aDJpZFVJWTFEZ0dXSjExZ3RIRklBOUN2SGNXK1NNUEVoa2NLWkpBTzUxYXlGQnFUU1NwaW9yVndUcQphMGNCK2NnbUNRT0k0L01ZK2tJdnpvZXhmRzd4aGtVcWUwd3htcGg5UlFReGxUYk5RRENkYXhTZ3diRjJUK2d3CmJ5YUR2a1M0eHRSNlNvajdCS2pLQW1jbmY1Zm40QzVPcjBLTFVxTXpCdERNYmZRUWlobjYyaVpKTjZaWi80ZGcKcTRIVHF5VnB5dXpNWHNGcEo5TC9GcUgyREo0ZXhHR3BCdjAwYmEvWmF1eTdHc3FPYzVQbk5Cc1lhSENwbHkwWAo0MDdEUng1MXQ5WXdZSS90dFZhbHVlaHE5K2dSSnBPVFRLcDZBalpuL2E1WXQzaDZqRGdwTmZNL0V5TEZJWTl6ClY2Q1hxUVEvOEpSdmFpay9Kc0dDZitlZUxaT3c0a29JalpHRUFnMDRpdXlOVGpoeDBlL1FIRVZjWUFxTkxoWEcKckNUVGJDbjNOU1VPOXF4RVhDK0svMW0xa2FYb0NHQTBVV2xWR1oxSlNpZmJiTXgweXhxL2JycEVaUFVZbSszMgpvOFhmYm9jQldsakZVSis2YWxqVHZaM0xRTEtUU1BXN1RGTytHWHljQU9tQ0dobFhoMnRsYzZpVGM0MVBBQ3F5Cnl5K21IbVN2Cj1ra0g3Ci0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS0K"}}} diff --git a/tests/test.rpm b/tests/test.rpm new file mode 100644 index 0000000000000000000000000000000000000000..051b6ccb54574a8bdfdf106e14b50a92981127d0 Binary files /dev/null and b/tests/test.rpm differ diff --git a/tests/test_rpm_public_key.key b/tests/test_rpm_public_key.key new file mode 100644 index 0000000000000000000000000000000000000000..30235a8647634c1706cfde7095c82c5a821e4bab --- /dev/null +++ b/tests/test_rpm_public_key.key @@ -0,0 +1,30 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2.0.22 (GNU/Linux) + +mQINBFzMWxkBEADHrskpBgN9OphmhRkc7P/YrsAGSvvl7kfu+e9KAaU6f5MeAVyn +rIoM43syyGkgFyWgjZM8/rur7EMPY2yt+2q/1ZfLVCRn9856JqTIq0XRpDUe4nKQ +8BlA7wDVZoSDxUZkSuTIyExbDf0cpw89Tcf62Mxmi8jh74vRlPy1PgjWL5494b3X +5fxDidH4bqPZyxTBqPrUFuo+EfUVEqiGF94Ppq6ZUvrBGOVo1V1+Ifm9CGEK597c +aevcGc1RFlgxIgN84UpuDjPR9/zSndwJ7XsXYvZ6HXcKGagRKsfYDWGPkA5cOL/e +f+yObOnC43yPUvpggQ4KaNJ6+SMTZOKikM8yciyBwLqwrjo8FlJgkv8Vfag/2UR7 +JINbyqHHoLUhQ2m6HXSwK4YjtwidF9EUkaBZWrrskYR3IRZLXlWqeOi/+ezYOW0m +vufrkcvsh+TKlVVnuwmEPjJ8mwUSpsLdfPJo1DHsd8FS03SCKPaXFdD7ePfEjiYk +nHpQaKE01aWVSLUiygn7F7rYemGqV9Vt7tBw5pz0vqSC72a5E3zFzIIuHx6aANry +Gat3aqU3qtBXOrA/dPkX9cWE+UR5wo/A2UdKJZLlGhM2WRJ3ltmGT48V9CeS6N9Y +m4CKdzvg7EWjlTlFrd/8WJ2KoqOE9leDPeXRPncubJfJ6LLIHyG09h9kKQARAQAB +tDpDZW50T1MgKENlbnRPUyBPZmZpY2lhbCBTaWduaW5nIEtleSkgPHNlY3VyaXR5 +QGNlbnRvcy5vcmc+iQI3BBMBAgAhBQJczFsZAhsDBgsJCAcDAgYVCAIJCgsDFgIB +Ah4BAheAAAoJEAW1VbOEg8ZdjOsP/2ygSxH9jqffOU9SKyJDlraL2gIutqZ3B8pl +Gy/Qnb9QD1EJVb4ZxOEhcY2W9VJfIpnf3yBuAto7zvKe/G1nxH4Bt6WTJQCkUjcs +N3qPWsx1VslsAEz7bXGiHym6Ay4xF28bQ9XYIokIQXd0T2rD3/lNGxNtORZ2bKjD +vOzYzvh2idUIY1DgGWJ11gtHFIA9CvHcW+SMPEhkcKZJAO51ayFBqTSSpiorVwTq +a0cB+cgmCQOI4/MY+kIvzoexfG7xhkUqe0wxmph9RQQxlTbNQDCdaxSgwbF2T+gw +byaDvkS4xtR6Soj7BKjKAmcnf5fn4C5Or0KLUqMzBtDMbfQQihn62iZJN6ZZ/4dg +q4HTqyVpyuzMXsFpJ9L/FqH2DJ4exGGpBv00ba/Zauy7GsqOc5PnNBsYaHCply0X +407DRx51t9YwYI/ttValuehq9+gRJpOTTKp6AjZn/a5Yt3h6jDgpNfM/EyLFIY9z +V6CXqQQ/8JRvaik/JsGCf+eeLZOw4koIjZGEAg04iuyNTjhx0e/QHEVcYAqNLhXG +rCTTbCn3NSUO9qxEXC+K/1m1kaXoCGA0UWlVGZ1JSifbbMx0yxq/brpEZPUYm+32 +o8XfbocBWljFUJ+6aljTvZ3LQLKTSPW7TFO+GXycAOmCGhlXh2tlc6iTc41PACqy +yy+mHmSv +=kkH7 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tests/util.go b/tests/util.go index d9f98300c062918065ca6be4869e77f4b9a810ee..84668de4124cd138e1d5ab61d5e485b016014846 100644 --- a/tests/util.go +++ b/tests/util.go @@ -62,12 +62,20 @@ func readFile(t *testing.T, p string) string { return strings.TrimSpace(string(b)) } +func randomData(n int) ([]byte, error) { + rand.Seed(time.Now().UnixNano()) + data := make([]byte, n) + if _, err := rand.Read(data[:]); err != nil { + return nil, err + } + return data, nil +} + func createArtifact(t *testing.T, artifactPath string) string { t.Helper() // First let's generate some random data so we don't have to worry about dupes. - rand.Seed(time.Now().UnixNano()) - data := [100]byte{} - if _, err := rand.Read(data[:]); err != nil { + data, err := randomData(100) + if err != nil { t.Fatal(err) }